security/nss/lib/util/oidstring.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include <string.h>
michael@0 6 #include "secitem.h"
michael@0 7 #include "secport.h"
michael@0 8 #include "secerr.h"
michael@0 9
michael@0 10 /* if to->data is not NULL, and to->len is large enough to hold the result,
michael@0 11 * then the resultant OID will be copyed into to->data, and to->len will be
michael@0 12 * changed to show the actual OID length.
michael@0 13 * Otherwise, memory for the OID will be allocated (from the caller's
michael@0 14 * PLArenaPool, if pool is non-NULL) and to->data will receive the address
michael@0 15 * of the allocated data, and to->len will receive the OID length.
michael@0 16 * The original value of to->data is not freed when a new buffer is allocated.
michael@0 17 *
michael@0 18 * The input string may begin with "OID." and this still be ignored.
michael@0 19 * The length of the input string is given in len. If len == 0, then
michael@0 20 * len will be computed as strlen(from), meaning it must be NUL terminated.
michael@0 21 * It is an error if from == NULL, or if *from == '\0'.
michael@0 22 */
michael@0 23
michael@0 24 SECStatus
michael@0 25 SEC_StringToOID(PLArenaPool *pool, SECItem *to, const char *from, PRUint32 len)
michael@0 26 {
michael@0 27 PRUint32 decimal_numbers = 0;
michael@0 28 PRUint32 result_bytes = 0;
michael@0 29 SECStatus rv;
michael@0 30 PRUint8 result[1024];
michael@0 31
michael@0 32 static const PRUint32 max_decimal = (0xffffffff / 10);
michael@0 33 static const char OIDstring[] = {"OID."};
michael@0 34
michael@0 35 if (!from || !to) {
michael@0 36 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 37 return SECFailure;
michael@0 38 }
michael@0 39 if (!len) {
michael@0 40 len = PL_strlen(from);
michael@0 41 }
michael@0 42 if (len >= 4 && !PL_strncasecmp(from, OIDstring, 4)) {
michael@0 43 from += 4; /* skip leading "OID." if present */
michael@0 44 len -= 4;
michael@0 45 }
michael@0 46 if (!len) {
michael@0 47 bad_data:
michael@0 48 PORT_SetError(SEC_ERROR_BAD_DATA);
michael@0 49 return SECFailure;
michael@0 50 }
michael@0 51 do {
michael@0 52 PRUint32 decimal = 0;
michael@0 53 while (len > 0 && isdigit(*from)) {
michael@0 54 PRUint32 addend = (*from++ - '0');
michael@0 55 --len;
michael@0 56 if (decimal > max_decimal) /* overflow */
michael@0 57 goto bad_data;
michael@0 58 decimal = (decimal * 10) + addend;
michael@0 59 if (decimal < addend) /* overflow */
michael@0 60 goto bad_data;
michael@0 61 }
michael@0 62 if (len != 0 && *from != '.') {
michael@0 63 goto bad_data;
michael@0 64 }
michael@0 65 if (decimal_numbers == 0) {
michael@0 66 if (decimal > 2)
michael@0 67 goto bad_data;
michael@0 68 result[0] = decimal * 40;
michael@0 69 result_bytes = 1;
michael@0 70 } else if (decimal_numbers == 1) {
michael@0 71 if (decimal > 40)
michael@0 72 goto bad_data;
michael@0 73 result[0] += decimal;
michael@0 74 } else {
michael@0 75 /* encode the decimal number, */
michael@0 76 PRUint8 * rp;
michael@0 77 PRUint32 num_bytes = 0;
michael@0 78 PRUint32 tmp = decimal;
michael@0 79 while (tmp) {
michael@0 80 num_bytes++;
michael@0 81 tmp >>= 7;
michael@0 82 }
michael@0 83 if (!num_bytes )
michael@0 84 ++num_bytes; /* use one byte for a zero value */
michael@0 85 if (num_bytes + result_bytes > sizeof result)
michael@0 86 goto bad_data;
michael@0 87 tmp = num_bytes;
michael@0 88 rp = result + result_bytes - 1;
michael@0 89 rp[tmp] = (PRUint8)(decimal & 0x7f);
michael@0 90 decimal >>= 7;
michael@0 91 while (--tmp > 0) {
michael@0 92 rp[tmp] = (PRUint8)(decimal | 0x80);
michael@0 93 decimal >>= 7;
michael@0 94 }
michael@0 95 result_bytes += num_bytes;
michael@0 96 }
michael@0 97 ++decimal_numbers;
michael@0 98 if (len > 0) { /* skip trailing '.' */
michael@0 99 ++from;
michael@0 100 --len;
michael@0 101 }
michael@0 102 } while (len > 0);
michael@0 103 /* now result contains result_bytes of data */
michael@0 104 if (to->data && to->len >= result_bytes) {
michael@0 105 PORT_Memcpy(to->data, result, to->len = result_bytes);
michael@0 106 rv = SECSuccess;
michael@0 107 } else {
michael@0 108 SECItem result_item = {siBuffer, NULL, 0 };
michael@0 109 result_item.data = result;
michael@0 110 result_item.len = result_bytes;
michael@0 111 rv = SECITEM_CopyItem(pool, to, &result_item);
michael@0 112 }
michael@0 113 return rv;
michael@0 114 }

mercurial