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