| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 #include "cert.h" | 5 #include "cert.h" |
| 6 #include "secoid.h" | 6 #include "secoid.h" |
| 7 #include "secder.h"» /* XXX remove this when remove the DERTemplates */ | 7 #include "secder.h" /* XXX remove this when remove the DERTemplates */ |
| 8 #include "secasn1.h" | 8 #include "secasn1.h" |
| 9 #include "secitem.h" | 9 #include "secitem.h" |
| 10 #include <stdarg.h> | 10 #include <stdarg.h> |
| 11 #include "secerr.h" | 11 #include "secerr.h" |
| 12 #include "certi.h" | 12 #include "certi.h" |
| 13 | 13 |
| 14 static const SEC_ASN1Template cert_AVATemplate[] = { | 14 static const SEC_ASN1Template cert_AVATemplate[] = { |
| 15 { SEC_ASN1_SEQUENCE, | 15 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAVA) }, |
| 16 » 0, NULL, sizeof(CERTAVA) }, | 16 { SEC_ASN1_OBJECT_ID, offsetof(CERTAVA, type) }, |
| 17 { SEC_ASN1_OBJECT_ID, | 17 { SEC_ASN1_ANY, offsetof(CERTAVA, value) }, |
| 18 » offsetof(CERTAVA,type), }, | 18 { 0 } |
| 19 { SEC_ASN1_ANY, | |
| 20 » offsetof(CERTAVA,value), }, | |
| 21 { 0, } | |
| 22 }; | 19 }; |
| 23 | 20 |
| 24 const SEC_ASN1Template CERT_RDNTemplate[] = { | 21 const SEC_ASN1Template CERT_RDNTemplate[] = { |
| 25 { SEC_ASN1_SET_OF, | 22 { SEC_ASN1_SET_OF, offsetof(CERTRDN, avas), cert_AVATemplate, |
| 26 » offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) } | 23 sizeof(CERTRDN) } |
| 27 }; | 24 }; |
| 28 | 25 |
| 29 | |
| 30 static int | 26 static int |
| 31 CountArray(void **array) | 27 CountArray(void **array) |
| 32 { | 28 { |
| 33 int count = 0; | 29 int count = 0; |
| 34 if (array) { | 30 if (array) { |
| 35 » while (*array++) { | 31 while (*array++) { |
| 36 » count++; | 32 count++; |
| 37 » } | 33 } |
| 38 } | 34 } |
| 39 return count; | 35 return count; |
| 40 } | 36 } |
| 41 | 37 |
| 42 static void ** | 38 static void ** |
| 43 AddToArray(PLArenaPool *arena, void **array, void *element) | 39 AddToArray(PLArenaPool *arena, void **array, void *element) |
| 44 { | 40 { |
| 45 unsigned count; | 41 unsigned count; |
| 46 void **ap; | 42 void **ap; |
| 47 | 43 |
| 48 /* Count up number of slots already in use in the array */ | 44 /* Count up number of slots already in use in the array */ |
| 49 count = 0; | 45 count = 0; |
| 50 ap = array; | 46 ap = array; |
| 51 if (ap) { | 47 if (ap) { |
| 52 » while (*ap++) { | 48 while (*ap++) { |
| 53 » count++; | 49 count++; |
| 54 » } | 50 } |
| 55 } | 51 } |
| 56 | 52 |
| 57 if (array) { | 53 if (array) { |
| 58 » array = (void**) PORT_ArenaGrow(arena, array, | 54 array = |
| 59 » » » » » (count + 1) * sizeof(void *), | 55 (void **)PORT_ArenaGrow(arena, array, (count + 1) * sizeof(void *), |
| 60 » » » » » (count + 2) * sizeof(void *)); | 56 (count + 2) * sizeof(void *)); |
| 61 } else { | 57 } else { |
| 62 » array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *)); | 58 array = (void **)PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *)); |
| 63 } | 59 } |
| 64 if (array) { | 60 if (array) { |
| 65 » array[count] = element; | 61 array[count] = element; |
| 66 » array[count+1] = 0; | 62 array[count + 1] = 0; |
| 67 } | 63 } |
| 68 return array; | 64 return array; |
| 69 } | 65 } |
| 70 | 66 |
| 71 | |
| 72 SECOidTag | 67 SECOidTag |
| 73 CERT_GetAVATag(CERTAVA *ava) | 68 CERT_GetAVATag(CERTAVA *ava) |
| 74 { | 69 { |
| 75 SECOidData *oid; | 70 SECOidData *oid; |
| 76 if (!ava->type.data) return (SECOidTag)-1; | 71 if (!ava->type.data) |
| 72 return (SECOidTag)-1; |
| 77 | 73 |
| 78 oid = SECOID_FindOID(&ava->type); | 74 oid = SECOID_FindOID(&ava->type); |
| 79 | 75 |
| 80 if ( oid ) { | 76 if (oid) { |
| 81 » return(oid->offset); | 77 return (oid->offset); |
| 82 } | 78 } |
| 83 return (SECOidTag)-1; | 79 return (SECOidTag)-1; |
| 84 } | 80 } |
| 85 | 81 |
| 86 static SECStatus | 82 static SECStatus |
| 87 SetupAVAType(PLArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp) | 83 SetupAVAType(PLArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp) |
| 88 { | 84 { |
| 89 unsigned char *oid; | 85 unsigned char *oid; |
| 90 unsigned oidLen; | 86 unsigned oidLen; |
| 91 unsigned char *cp; | 87 unsigned char *cp; |
| 92 int maxLen; | 88 int maxLen; |
| 93 SECOidData *oidrec; | 89 SECOidData *oidrec; |
| 94 | 90 |
| 95 oidrec = SECOID_FindOIDByTag(type); | 91 oidrec = SECOID_FindOIDByTag(type); |
| 96 if (oidrec == NULL) | 92 if (oidrec == NULL) |
| 97 » return SECFailure; | 93 return SECFailure; |
| 98 | 94 |
| 99 oid = oidrec->oid.data; | 95 oid = oidrec->oid.data; |
| 100 oidLen = oidrec->oid.len; | 96 oidLen = oidrec->oid.len; |
| 101 | 97 |
| 102 maxLen = cert_AVAOidTagToMaxLen(type); | 98 maxLen = cert_AVAOidTagToMaxLen(type); |
| 103 if (maxLen < 0) { | 99 if (maxLen < 0) { |
| 104 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 100 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 105 » return SECFailure; | 101 return SECFailure; |
| 106 } | 102 } |
| 107 | 103 |
| 108 it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen); | 104 it->data = cp = (unsigned char *)PORT_ArenaAlloc(arena, oidLen); |
| 109 if (cp == NULL) { | 105 if (cp == NULL) { |
| 110 » return SECFailure; | 106 return SECFailure; |
| 111 } | 107 } |
| 112 it->len = oidLen; | 108 it->len = oidLen; |
| 113 PORT_Memcpy(cp, oid, oidLen); | 109 PORT_Memcpy(cp, oid, oidLen); |
| 114 *maxLenp = (unsigned)maxLen; | 110 *maxLenp = (unsigned)maxLen; |
| 115 return SECSuccess; | 111 return SECSuccess; |
| 116 } | 112 } |
| 117 | 113 |
| 118 static SECStatus | 114 static SECStatus |
| 119 SetupAVAValue(PLArenaPool *arena, int valueType, const SECItem *in, | 115 SetupAVAValue(PLArenaPool *arena, int valueType, const SECItem *in, |
| 120 SECItem *out, unsigned maxLen) | 116 SECItem *out, unsigned maxLen) |
| 121 { | 117 { |
| 122 PRUint8 *value, *cp, *ucs4Val; | 118 PRUint8 *value, *cp, *ucs4Val; |
| 123 unsigned valueLen, valueLenLen, total; | 119 unsigned valueLen, valueLenLen, total; |
| 124 unsigned ucs4Len = 0, ucs4MaxLen; | 120 unsigned ucs4Len = 0, ucs4MaxLen; |
| 125 | 121 |
| 126 value = in->data; | 122 value = in->data; |
| 127 valueLen = in->len; | 123 valueLen = in->len; |
| 128 switch (valueType) { | 124 switch (valueType) { |
| 129 case SEC_ASN1_PRINTABLE_STRING: | 125 case SEC_ASN1_PRINTABLE_STRING: |
| 130 case SEC_ASN1_IA5_STRING: | 126 case SEC_ASN1_IA5_STRING: |
| 131 case SEC_ASN1_T61_STRING: | 127 case SEC_ASN1_T61_STRING: |
| 132 case SEC_ASN1_UTF8_STRING: /* no conversion required */ | 128 case SEC_ASN1_UTF8_STRING: /* no conversion required */ |
| 133 » break; | 129 break; |
| 134 case SEC_ASN1_UNIVERSAL_STRING: | 130 case SEC_ASN1_UNIVERSAL_STRING: |
| 135 » ucs4MaxLen = valueLen * 6; | 131 ucs4MaxLen = valueLen * 6; |
| 136 » ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen); | 132 ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen); |
| 137 » if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen, | 133 if (!ucs4Val || |
| 138 » » » » » ucs4Val, ucs4MaxLen, &ucs4Len)) { | 134 !PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen, ucs4Val, |
| 139 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 135 ucs4MaxLen, &ucs4Len)) { |
| 140 » return SECFailure; | 136 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 141 » } | 137 return SECFailure; |
| 142 » value = ucs4Val; | 138 } |
| 143 » valueLen = ucs4Len; | 139 value = ucs4Val; |
| 144 » maxLen *= 4; | 140 valueLen = ucs4Len; |
| 145 » break; | 141 maxLen *= 4; |
| 146 default: | 142 break; |
| 147 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 143 default: |
| 148 » return SECFailure; | 144 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 145 return SECFailure; |
| 149 } | 146 } |
| 150 | 147 |
| 151 if (valueLen > maxLen) { | 148 if (valueLen > maxLen) { |
| 152 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 149 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 153 » return SECFailure; | 150 return SECFailure; |
| 154 } | 151 } |
| 155 | 152 |
| 156 valueLenLen = DER_LengthLength(valueLen); | 153 valueLenLen = DER_LengthLength(valueLen); |
| 157 total = 1 + valueLenLen + valueLen; | 154 total = 1 + valueLenLen + valueLen; |
| 158 cp = (PRUint8*)PORT_ArenaAlloc(arena, total); | 155 cp = (PRUint8 *)PORT_ArenaAlloc(arena, total); |
| 159 if (!cp) { | 156 if (!cp) { |
| 160 » return SECFailure; | 157 return SECFailure; |
| 161 } | 158 } |
| 162 out->data = cp; | 159 out->data = cp; |
| 163 out->len = total; | 160 out->len = total; |
| 164 cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen); | 161 cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen); |
| 165 PORT_Memcpy(cp, value, valueLen); | 162 PORT_Memcpy(cp, value, valueLen); |
| 166 return SECSuccess; | 163 return SECSuccess; |
| 167 } | 164 } |
| 168 | 165 |
| 169 CERTAVA * | 166 CERTAVA * |
| 170 CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem * OID, | 167 CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem *OID, |
| 171 const SECItem * value) | 168 const SECItem *value) |
| 172 { | 169 { |
| 173 CERTAVA *ava; | 170 CERTAVA *ava; |
| 174 int rv; | 171 int rv; |
| 175 | 172 |
| 176 ava = PORT_ArenaZNew(pool, CERTAVA); | 173 ava = PORT_ArenaZNew(pool, CERTAVA); |
| 177 if (ava) { | 174 if (ava) { |
| 178 » rv = SECITEM_CopyItem(pool, &ava->type, OID); | 175 rv = SECITEM_CopyItem(pool, &ava->type, OID); |
| 179 » if (rv) | 176 if (rv) |
| 180 » return NULL; | 177 return NULL; |
| 181 | 178 |
| 182 » rv = SECITEM_CopyItem(pool, &ava->value, value); | 179 rv = SECITEM_CopyItem(pool, &ava->value, value); |
| 183 » if (rv) | 180 if (rv) |
| 184 » return NULL; | 181 return NULL; |
| 185 } | 182 } |
| 186 return ava; | 183 return ava; |
| 187 } | 184 } |
| 188 | 185 |
| 189 CERTAVA * | 186 CERTAVA * |
| 190 CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, int valueType, | 187 CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, int valueType, |
| 191 SECItem *value) | 188 SECItem *value) |
| 192 { | 189 { |
| 193 CERTAVA *ava; | 190 CERTAVA *ava; |
| 194 int rv; | 191 int rv; |
| 195 unsigned maxLen; | 192 unsigned maxLen; |
| 196 | 193 |
| 197 ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); | 194 ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); |
| 198 if (ava) { | 195 if (ava) { |
| 199 » rv = SetupAVAType(arena, kind, &ava->type, &maxLen); | 196 rv = SetupAVAType(arena, kind, &ava->type, &maxLen); |
| 200 » if (rv) { | 197 if (rv) { |
| 201 » /* Illegal AVA type */ | 198 /* Illegal AVA type */ |
| 202 » return NULL; | 199 return NULL; |
| 203 » } | 200 } |
| 204 » rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen); | 201 rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen); |
| 205 » if (rv) { | 202 if (rv) { |
| 206 » /* Illegal value type */ | 203 /* Illegal value type */ |
| 207 » return NULL; | 204 return NULL; |
| 208 » } | 205 } |
| 209 } | 206 } |
| 210 return ava; | 207 return ava; |
| 211 } | 208 } |
| 212 | 209 |
| 213 CERTAVA * | 210 CERTAVA * |
| 214 CERT_CreateAVA(PLArenaPool *arena, SECOidTag kind, int valueType, char *value) | 211 CERT_CreateAVA(PLArenaPool *arena, SECOidTag kind, int valueType, char *value) |
| 215 { | 212 { |
| 216 SECItem item = { siBuffer, NULL, 0 }; | 213 SECItem item = { siBuffer, NULL, 0 }; |
| 217 | 214 |
| 218 item.data = (PRUint8 *)value; | 215 item.data = (PRUint8 *)value; |
| 219 item.len = PORT_Strlen(value); | 216 item.len = PORT_Strlen(value); |
| 220 | 217 |
| 221 return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item); | 218 return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item); |
| 222 } | 219 } |
| 223 | 220 |
| 224 CERTAVA * | 221 CERTAVA * |
| 225 CERT_CopyAVA(PLArenaPool *arena, CERTAVA *from) | 222 CERT_CopyAVA(PLArenaPool *arena, CERTAVA *from) |
| 226 { | 223 { |
| 227 CERTAVA *ava; | 224 CERTAVA *ava; |
| 228 int rv; | 225 int rv; |
| 229 | 226 |
| 230 ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); | 227 ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); |
| 231 if (ava) { | 228 if (ava) { |
| 232 » rv = SECITEM_CopyItem(arena, &ava->type, &from->type); | 229 rv = SECITEM_CopyItem(arena, &ava->type, &from->type); |
| 233 » if (rv) goto loser; | 230 if (rv) |
| 234 » rv = SECITEM_CopyItem(arena, &ava->value, &from->value); | 231 goto loser; |
| 235 » if (rv) goto loser; | 232 rv = SECITEM_CopyItem(arena, &ava->value, &from->value); |
| 233 if (rv) |
| 234 goto loser; |
| 236 } | 235 } |
| 237 return ava; | 236 return ava; |
| 238 | 237 |
| 239 loser: | 238 loser: |
| 240 return 0; | 239 return 0; |
| 241 } | 240 } |
| 242 | 241 |
| 243 CERTRDN * | 242 CERTRDN * |
| 244 CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...) | 243 CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...) |
| 245 { | 244 { |
| 246 CERTAVA *ava; | 245 CERTAVA *ava; |
| 247 CERTRDN *rdn; | 246 CERTRDN *rdn; |
| 248 va_list ap; | 247 va_list ap; |
| 249 unsigned count; | 248 unsigned count; |
| 250 CERTAVA **avap; | 249 CERTAVA **avap; |
| 251 | 250 |
| 252 rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN)); | 251 rdn = (CERTRDN *)PORT_ArenaAlloc(arena, sizeof(CERTRDN)); |
| 253 if (rdn) { | 252 if (rdn) { |
| 254 » /* Count number of avas going into the rdn */ | 253 /* Count number of avas going into the rdn */ |
| 255 » count = 0; | 254 count = 0; |
| 256 » if (ava0) { | 255 if (ava0) { |
| 257 » count++; | 256 count++; |
| 258 » va_start(ap, ava0); | 257 va_start(ap, ava0); |
| 259 » while ((ava = va_arg(ap, CERTAVA*)) != 0) { | 258 while ((ava = va_arg(ap, CERTAVA *)) != 0) { |
| 260 » » count++; | 259 count++; |
| 261 » } | 260 } |
| 262 » va_end(ap); | 261 va_end(ap); |
| 263 » } | 262 } |
| 264 | 263 |
| 265 » /* Now fill in the pointers */ | 264 /* Now fill in the pointers */ |
| 266 » rdn->avas = avap = | 265 rdn->avas = avap = |
| 267 » (CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*)); | 266 (CERTAVA **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTAVA *)); |
| 268 » if (!avap) { | 267 if (!avap) { |
| 269 » return 0; | 268 return 0; |
| 270 » } | 269 } |
| 271 » if (ava0) { | 270 if (ava0) { |
| 272 » *avap++ = ava0; | 271 *avap++ = ava0; |
| 273 » va_start(ap, ava0); | 272 va_start(ap, ava0); |
| 274 » while ((ava = va_arg(ap, CERTAVA*)) != 0) { | 273 while ((ava = va_arg(ap, CERTAVA *)) != 0) { |
| 275 » » *avap++ = ava; | 274 *avap++ = ava; |
| 276 » } | 275 } |
| 277 » va_end(ap); | 276 va_end(ap); |
| 278 » } | 277 } |
| 279 » *avap++ = 0; | 278 *avap++ = 0; |
| 280 } | 279 } |
| 281 return rdn; | 280 return rdn; |
| 282 } | 281 } |
| 283 | 282 |
| 284 SECStatus | 283 SECStatus |
| 285 CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava) | 284 CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava) |
| 286 { | 285 { |
| 287 rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava); | 286 rdn->avas = (CERTAVA **)AddToArray(arena, (void **)rdn->avas, ava); |
| 288 return rdn->avas ? SECSuccess : SECFailure; | 287 return rdn->avas ? SECSuccess : SECFailure; |
| 289 } | 288 } |
| 290 | 289 |
| 291 SECStatus | 290 SECStatus |
| 292 CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from) | 291 CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from) |
| 293 { | 292 { |
| 294 CERTAVA **avas, *fava, *tava; | 293 CERTAVA **avas, *fava, *tava; |
| 295 SECStatus rv = SECSuccess; | 294 SECStatus rv = SECSuccess; |
| 296 | 295 |
| 297 /* Copy each ava from from */ | 296 /* Copy each ava from from */ |
| 298 avas = from->avas; | 297 avas = from->avas; |
| 299 if (avas) { | 298 if (avas) { |
| 300 » if (avas[0] == NULL) { | 299 if (avas[0] == NULL) { |
| 301 » rv = CERT_AddAVA(arena, to, NULL); | 300 rv = CERT_AddAVA(arena, to, NULL); |
| 302 » return rv; | 301 return rv; |
| 303 » } | 302 } |
| 304 » while ((fava = *avas++) != 0) { | 303 while ((fava = *avas++) != 0) { |
| 305 » tava = CERT_CopyAVA(arena, fava); | 304 tava = CERT_CopyAVA(arena, fava); |
| 306 » if (!tava) { | 305 if (!tava) { |
| 307 » » rv = SECFailure; | 306 rv = SECFailure; |
| 308 » » break; | 307 break; |
| 309 » } | 308 } |
| 310 » rv = CERT_AddAVA(arena, to, tava); | 309 rv = CERT_AddAVA(arena, to, tava); |
| 311 » if (rv != SECSuccess) | 310 if (rv != SECSuccess) |
| 312 » » break; | 311 break; |
| 313 » } | 312 } |
| 314 } | 313 } |
| 315 return rv; | 314 return rv; |
| 316 } | 315 } |
| 317 | 316 |
| 318 /************************************************************************/ | 317 /************************************************************************/ |
| 319 | 318 |
| 320 const SEC_ASN1Template CERT_NameTemplate[] = { | 319 const SEC_ASN1Template CERT_NameTemplate[] = { |
| 321 { SEC_ASN1_SEQUENCE_OF, | 320 { SEC_ASN1_SEQUENCE_OF, offsetof(CERTName, rdns), CERT_RDNTemplate, |
| 322 » offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) } | 321 sizeof(CERTName) } |
| 323 }; | 322 }; |
| 324 | 323 |
| 325 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate) | 324 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate) |
| 326 | 325 |
| 327 CERTName * | 326 CERTName * |
| 328 CERT_CreateName(CERTRDN *rdn0, ...) | 327 CERT_CreateName(CERTRDN *rdn0, ...) |
| 329 { | 328 { |
| 330 CERTRDN *rdn; | 329 CERTRDN *rdn; |
| 331 CERTName *name; | 330 CERTName *name; |
| 332 va_list ap; | 331 va_list ap; |
| 333 unsigned count; | 332 unsigned count; |
| 334 CERTRDN **rdnp; | 333 CERTRDN **rdnp; |
| 335 PLArenaPool *arena; | 334 PLArenaPool *arena; |
| 336 | 335 |
| 337 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 336 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 338 if ( !arena ) { | 337 if (!arena) { |
| 339 » return(0); | 338 return (0); |
| 340 } | 339 } |
| 341 | 340 |
| 342 name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName)); | 341 name = (CERTName *)PORT_ArenaAlloc(arena, sizeof(CERTName)); |
| 343 if (name) { | 342 if (name) { |
| 344 » name->arena = arena; | 343 name->arena = arena; |
| 345 » | |
| 346 » /* Count number of RDNs going into the Name */ | |
| 347 » if (!rdn0) { | |
| 348 » count = 0; | |
| 349 » } else { | |
| 350 » count = 1; | |
| 351 » va_start(ap, rdn0); | |
| 352 » while ((rdn = va_arg(ap, CERTRDN*)) != 0) { | |
| 353 » » count++; | |
| 354 » } | |
| 355 » va_end(ap); | |
| 356 » } | |
| 357 | 344 |
| 358 » /* Allocate space (including space for terminal null ptr) */ | 345 /* Count number of RDNs going into the Name */ |
| 359 » name->rdns = rdnp = | 346 if (!rdn0) { |
| 360 » (CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*)); | 347 count = 0; |
| 361 » if (!name->rdns) { | 348 } else { |
| 362 » goto loser; | 349 count = 1; |
| 363 » } | 350 va_start(ap, rdn0); |
| 351 while ((rdn = va_arg(ap, CERTRDN *)) != 0) { |
| 352 count++; |
| 353 } |
| 354 va_end(ap); |
| 355 } |
| 364 | 356 |
| 365 » /* Now fill in the pointers */ | 357 /* Allocate space (including space for terminal null ptr) */ |
| 366 » if (count > 0) { | 358 name->rdns = rdnp = |
| 367 » *rdnp++ = rdn0; | 359 (CERTRDN **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN *)); |
| 368 » va_start(ap, rdn0); | 360 if (!name->rdns) { |
| 369 » while ((rdn = va_arg(ap, CERTRDN*)) != 0) { | 361 goto loser; |
| 370 » » *rdnp++ = rdn; | 362 } |
| 371 » } | |
| 372 » va_end(ap); | |
| 373 » } | |
| 374 | 363 |
| 375 » /* null terminate the list */ | 364 /* Now fill in the pointers */ |
| 376 » *rdnp++ = 0; | 365 if (count > 0) { |
| 366 *rdnp++ = rdn0; |
| 367 va_start(ap, rdn0); |
| 368 while ((rdn = va_arg(ap, CERTRDN *)) != 0) { |
| 369 *rdnp++ = rdn; |
| 370 } |
| 371 va_end(ap); |
| 372 } |
| 373 |
| 374 /* null terminate the list */ |
| 375 *rdnp++ = 0; |
| 377 } | 376 } |
| 378 return name; | 377 return name; |
| 379 | 378 |
| 380 loser: | 379 loser: |
| 381 PORT_FreeArena(arena, PR_FALSE); | 380 PORT_FreeArena(arena, PR_FALSE); |
| 382 return(0); | 381 return (0); |
| 383 } | 382 } |
| 384 | 383 |
| 385 void | 384 void |
| 386 CERT_DestroyName(CERTName *name) | 385 CERT_DestroyName(CERTName *name) |
| 387 { | 386 { |
| 388 if (name) | 387 if (name) { |
| 389 { | |
| 390 PLArenaPool *arena = name->arena; | 388 PLArenaPool *arena = name->arena; |
| 391 name->rdns = NULL; | 389 name->rdns = NULL; |
| 392 » name->arena = NULL; | 390 name->arena = NULL; |
| 393 » if (arena) PORT_FreeArena(arena, PR_FALSE); | 391 if (arena) |
| 392 PORT_FreeArena(arena, PR_FALSE); |
| 394 } | 393 } |
| 395 } | 394 } |
| 396 | 395 |
| 397 SECStatus | 396 SECStatus |
| 398 CERT_AddRDN(CERTName *name, CERTRDN *rdn) | 397 CERT_AddRDN(CERTName *name, CERTRDN *rdn) |
| 399 { | 398 { |
| 400 name->rdns = (CERTRDN**) AddToArray(name->arena, (void**) name->rdns, rdn); | 399 name->rdns = (CERTRDN **)AddToArray(name->arena, (void **)name->rdns, rdn); |
| 401 return name->rdns ? SECSuccess : SECFailure; | 400 return name->rdns ? SECSuccess : SECFailure; |
| 402 } | 401 } |
| 403 | 402 |
| 404 SECStatus | 403 SECStatus |
| 405 CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from) | 404 CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from) |
| 406 { | 405 { |
| 407 CERTRDN **rdns, *frdn, *trdn; | 406 CERTRDN **rdns, *frdn, *trdn; |
| 408 SECStatus rv = SECSuccess; | 407 SECStatus rv = SECSuccess; |
| 409 | 408 |
| 410 if (!to || !from) { | 409 if (!to || !from) { |
| 411 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 410 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 412 » return SECFailure; | 411 return SECFailure; |
| 413 } | 412 } |
| 414 | 413 |
| 415 CERT_DestroyName(to); | 414 CERT_DestroyName(to); |
| 416 to->arena = arena; | 415 to->arena = arena; |
| 417 | 416 |
| 418 /* Copy each rdn from from */ | 417 /* Copy each rdn from from */ |
| 419 rdns = from->rdns; | 418 rdns = from->rdns; |
| 420 if (rdns) { | 419 if (rdns) { |
| 421 » if (rdns[0] == NULL) { | 420 if (rdns[0] == NULL) { |
| 422 » rv = CERT_AddRDN(to, NULL); | 421 rv = CERT_AddRDN(to, NULL); |
| 423 » return rv; | 422 return rv; |
| 424 » } | 423 } |
| 425 » while ((frdn = *rdns++) != NULL) { | 424 while ((frdn = *rdns++) != NULL) { |
| 426 » trdn = CERT_CreateRDN(arena, NULL); | 425 trdn = CERT_CreateRDN(arena, NULL); |
| 427 » if (!trdn) { | 426 if (!trdn) { |
| 428 » » rv = SECFailure; | 427 rv = SECFailure; |
| 429 » » break; | 428 break; |
| 430 » } | 429 } |
| 431 » rv = CERT_CopyRDN(arena, trdn, frdn); | 430 rv = CERT_CopyRDN(arena, trdn, frdn); |
| 432 » if (rv != SECSuccess) | 431 if (rv != SECSuccess) |
| 433 » break; | 432 break; |
| 434 » rv = CERT_AddRDN(to, trdn); | 433 rv = CERT_AddRDN(to, trdn); |
| 435 » if (rv != SECSuccess) | 434 if (rv != SECSuccess) |
| 436 » break; | 435 break; |
| 437 » } | 436 } |
| 438 } | 437 } |
| 439 return rv; | 438 return rv; |
| 440 } | 439 } |
| 441 | 440 |
| 442 /************************************************************************/ | 441 /************************************************************************/ |
| 443 | 442 |
| 444 static void | 443 static void |
| 445 canonicalize(SECItem * foo) | 444 canonicalize(SECItem *foo) |
| 446 { | 445 { |
| 447 int ch, lastch, len, src, dest; | 446 int ch, lastch, len, src, dest; |
| 448 | 447 |
| 449 /* strip trailing whitespace. */ | 448 /* strip trailing whitespace. */ |
| 450 len = foo->len; | 449 len = foo->len; |
| 451 while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || | 450 while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || ch == '\t' || |
| 452 ch == '\t' || ch == '\r' || ch == '\n')) { | 451 ch == '\r' || ch == '\n')) { |
| 453 » len--; | 452 len--; |
| 454 } | 453 } |
| 455 | 454 |
| 456 src = 0; | 455 src = 0; |
| 457 /* strip leading whitespace. */ | 456 /* strip leading whitespace. */ |
| 458 while (src < len && ((ch = foo->data[src]) == ' ' || | 457 while (src < len && ((ch = foo->data[src]) == ' ' || ch == '\t' || |
| 459 ch == '\t' || ch == '\r' || ch == '\n')) { | 458 ch == '\r' || ch == '\n')) { |
| 460 » src++; | 459 src++; |
| 461 } | 460 } |
| 462 dest = 0; lastch = ' '; | 461 dest = 0; |
| 462 lastch = ' '; |
| 463 while (src < len) { | 463 while (src < len) { |
| 464 ch = foo->data[src++]; | 464 ch = foo->data[src++]; |
| 465 » if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { | 465 if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { |
| 466 » ch = ' '; | 466 ch = ' '; |
| 467 » if (ch == lastch) | 467 if (ch == lastch) |
| 468 » continue; | 468 continue; |
| 469 » } else if (ch >= 'A' && ch <= 'Z') { | 469 } else if (ch >= 'A' && ch <= 'Z') { |
| 470 » ch |= 0x20; /* downshift */ | 470 ch |= 0x20; /* downshift */ |
| 471 » } | 471 } |
| 472 » foo->data[dest++] = lastch = ch; | 472 foo->data[dest++] = lastch = ch; |
| 473 } | 473 } |
| 474 foo->len = dest; | 474 foo->len = dest; |
| 475 } | 475 } |
| 476 | 476 |
| 477 /* SECItems a and b contain DER-encoded printable strings. */ | 477 /* SECItems a and b contain DER-encoded printable strings. */ |
| 478 SECComparison | 478 SECComparison |
| 479 CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b) | 479 CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b) |
| 480 { | 480 { |
| 481 SECComparison rv = SECLessThan; | 481 SECComparison rv = SECLessThan; |
| 482 SECItem * aVal = CERT_DecodeAVAValue(a); | 482 SECItem *aVal = CERT_DecodeAVAValue(a); |
| 483 SECItem * bVal = CERT_DecodeAVAValue(b); | 483 SECItem *bVal = CERT_DecodeAVAValue(b); |
| 484 | 484 |
| 485 if (aVal && aVal->len && aVal->data && | 485 if (aVal && aVal->len && aVal->data && bVal && bVal->len && bVal->data) { |
| 486 » bVal && bVal->len && bVal->data) { | 486 canonicalize(aVal); |
| 487 » canonicalize(aVal); | 487 canonicalize(bVal); |
| 488 » canonicalize(bVal); | 488 rv = SECITEM_CompareItem(aVal, bVal); |
| 489 » rv = SECITEM_CompareItem(aVal, bVal); | |
| 490 } | 489 } |
| 491 SECITEM_FreeItem(aVal, PR_TRUE); | 490 SECITEM_FreeItem(aVal, PR_TRUE); |
| 492 SECITEM_FreeItem(bVal, PR_TRUE); | 491 SECITEM_FreeItem(bVal, PR_TRUE); |
| 493 return rv; | 492 return rv; |
| 494 } | 493 } |
| 495 | 494 |
| 496 SECComparison | 495 SECComparison |
| 497 CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b) | 496 CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b) |
| 498 { | 497 { |
| 499 SECComparison rv; | 498 SECComparison rv; |
| 500 | 499 |
| 501 rv = SECITEM_CompareItem(&a->type, &b->type); | 500 rv = SECITEM_CompareItem(&a->type, &b->type); |
| 502 if (SECEqual != rv) | 501 if (SECEqual != rv) |
| 503 » return rv; /* Attribute types don't match. */ | 502 return rv; /* Attribute types don't match. */ |
| 504 /* Let's be optimistic. Maybe the values will just compare equal. */ | 503 /* Let's be optimistic. Maybe the values will just compare equal. */ |
| 505 rv = SECITEM_CompareItem(&a->value, &b->value); | 504 rv = SECITEM_CompareItem(&a->value, &b->value); |
| 506 if (SECEqual == rv) | 505 if (SECEqual == rv) |
| 507 return rv; /* values compared exactly. */ | 506 return rv; /* values compared exactly. */ |
| 508 if (a->value.len && a->value.data && b->value.len && b->value.data) { | 507 if (a->value.len && a->value.data && b->value.len && b->value.data) { |
| 509 » /* Here, the values did not match. | 508 /* Here, the values did not match. |
| 510 » ** If the values had different encodings, convert them to the same | 509 ** If the values had different encodings, convert them to the same |
| 511 » ** encoding and compare that way. | 510 ** encoding and compare that way. |
| 512 » */ | 511 */ |
| 513 » if (a->value.data[0] != b->value.data[0]) { | 512 if (a->value.data[0] != b->value.data[0]) { |
| 514 » /* encodings differ. Convert both to UTF-8 and compare. */ | 513 /* encodings differ. Convert both to UTF-8 and compare. */ |
| 515 » SECItem * aVal = CERT_DecodeAVAValue(&a->value); | 514 SECItem *aVal = CERT_DecodeAVAValue(&a->value); |
| 516 » SECItem * bVal = CERT_DecodeAVAValue(&b->value); | 515 SECItem *bVal = CERT_DecodeAVAValue(&b->value); |
| 517 » if (aVal && aVal->len && aVal->data && | 516 if (aVal && aVal->len && aVal->data && bVal && bVal->len && |
| 518 » bVal && bVal->len && bVal->data) { | 517 bVal->data) { |
| 519 » » rv = SECITEM_CompareItem(aVal, bVal); | 518 rv = SECITEM_CompareItem(aVal, bVal); |
| 520 » } | 519 } |
| 521 » SECITEM_FreeItem(aVal, PR_TRUE); | 520 SECITEM_FreeItem(aVal, PR_TRUE); |
| 522 » SECITEM_FreeItem(bVal, PR_TRUE); | 521 SECITEM_FreeItem(bVal, PR_TRUE); |
| 523 » } else if (a->value.data[0] == 0x13) { /* both are printable strings. */ | 522 } else if (a->value.data[0] == 0x13) { /* both are printable strings. */ |
| 524 » /* printable strings */ | 523 /* printable strings */ |
| 525 » rv = CERT_CompareDERPrintableStrings(&a->value, &b->value); | 524 rv = CERT_CompareDERPrintableStrings(&a->value, &b->value); |
| 526 » } | 525 } |
| 527 } | 526 } |
| 528 return rv; | 527 return rv; |
| 529 } | 528 } |
| 530 | 529 |
| 531 SECComparison | 530 SECComparison |
| 532 CERT_CompareRDN(const CERTRDN *a, const CERTRDN *b) | 531 CERT_CompareRDN(const CERTRDN *a, const CERTRDN *b) |
| 533 { | 532 { |
| 534 CERTAVA **aavas, *aava; | 533 CERTAVA **aavas, *aava; |
| 535 CERTAVA **bavas, *bava; | 534 CERTAVA **bavas, *bava; |
| 536 int ac, bc; | 535 int ac, bc; |
| 537 SECComparison rv = SECEqual; | 536 SECComparison rv = SECEqual; |
| 538 | 537 |
| 539 aavas = a->avas; | 538 aavas = a->avas; |
| 540 bavas = b->avas; | 539 bavas = b->avas; |
| 541 | 540 |
| 542 /* | 541 /* |
| 543 ** Make sure array of ava's are the same length. If not, then we are | 542 ** Make sure array of ava's are the same length. If not, then we are |
| 544 ** not equal | 543 ** not equal |
| 545 */ | 544 */ |
| 546 ac = CountArray((void**) aavas); | 545 ac = CountArray((void **)aavas); |
| 547 bc = CountArray((void**) bavas); | 546 bc = CountArray((void **)bavas); |
| 548 if (ac < bc) return SECLessThan; | 547 if (ac < bc) |
| 549 if (ac > bc) return SECGreaterThan; | 548 return SECLessThan; |
| 549 if (ac > bc) |
| 550 return SECGreaterThan; |
| 550 | 551 |
| 551 while (NULL != (aava = *aavas++)) { | 552 while (NULL != (aava = *aavas++)) { |
| 552 » for (bavas = b->avas; NULL != (bava = *bavas++); ) { | 553 for (bavas = b->avas; NULL != (bava = *bavas++);) { |
| 553 » rv = SECITEM_CompareItem(&aava->type, &bava->type); | 554 rv = SECITEM_CompareItem(&aava->type, &bava->type); |
| 554 » if (SECEqual == rv) { | 555 if (SECEqual == rv) { |
| 555 » » rv = CERT_CompareAVA(aava, bava); | 556 rv = CERT_CompareAVA(aava, bava); |
| 556 » » if (SECEqual != rv) | 557 if (SECEqual != rv) |
| 557 » » return rv; | 558 return rv; |
| 558 » » break; | 559 break; |
| 559 » } | 560 } |
| 560 » } | 561 } |
| 561 » if (!bava) /* didn't find a match */ | 562 if (!bava) /* didn't find a match */ |
| 562 » return SECGreaterThan; | 563 return SECGreaterThan; |
| 563 } | 564 } |
| 564 return rv; | 565 return rv; |
| 565 } | 566 } |
| 566 | 567 |
| 567 SECComparison | 568 SECComparison |
| 568 CERT_CompareName(const CERTName *a, const CERTName *b) | 569 CERT_CompareName(const CERTName *a, const CERTName *b) |
| 569 { | 570 { |
| 570 CERTRDN **ardns, *ardn; | 571 CERTRDN **ardns, *ardn; |
| 571 CERTRDN **brdns, *brdn; | 572 CERTRDN **brdns, *brdn; |
| 572 int ac, bc; | 573 int ac, bc; |
| 573 SECComparison rv = SECEqual; | 574 SECComparison rv = SECEqual; |
| 574 | 575 |
| 575 ardns = a->rdns; | 576 ardns = a->rdns; |
| 576 brdns = b->rdns; | 577 brdns = b->rdns; |
| 577 | 578 |
| 578 /* | 579 /* |
| 579 ** Make sure array of rdn's are the same length. If not, then we are | 580 ** Make sure array of rdn's are the same length. If not, then we are |
| 580 ** not equal | 581 ** not equal |
| 581 */ | 582 */ |
| 582 ac = CountArray((void**) ardns); | 583 ac = CountArray((void **)ardns); |
| 583 bc = CountArray((void**) brdns); | 584 bc = CountArray((void **)brdns); |
| 584 if (ac < bc) return SECLessThan; | 585 if (ac < bc) |
| 585 if (ac > bc) return SECGreaterThan; | 586 return SECLessThan; |
| 587 if (ac > bc) |
| 588 return SECGreaterThan; |
| 586 | 589 |
| 587 for (;;) { | 590 for (;;) { |
| 588 » ardn = *ardns++; | 591 ardn = *ardns++; |
| 589 » brdn = *brdns++; | 592 brdn = *brdns++; |
| 590 » if (!ardn) { | 593 if (!ardn) { |
| 591 » break; | 594 break; |
| 592 » } | 595 } |
| 593 » rv = CERT_CompareRDN(ardn, brdn); | 596 rv = CERT_CompareRDN(ardn, brdn); |
| 594 » if (rv) return rv; | 597 if (rv) |
| 598 return rv; |
| 595 } | 599 } |
| 596 return rv; | 600 return rv; |
| 597 } | 601 } |
| 598 | 602 |
| 599 /* Moved from certhtml.c */ | 603 /* Moved from certhtml.c */ |
| 600 SECItem * | 604 SECItem * |
| 601 CERT_DecodeAVAValue(const SECItem *derAVAValue) | 605 CERT_DecodeAVAValue(const SECItem *derAVAValue) |
| 602 { | 606 { |
| 603 SECItem *retItem; | 607 SECItem *retItem; |
| 604 const SEC_ASN1Template *theTemplate = NULL; | 608 const SEC_ASN1Template *theTemplate = NULL; |
| 605 enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv
_none; | 609 enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none; |
| 606 SECItem avaValue = {siBuffer, 0}; | 610 SECItem avaValue = { siBuffer, 0 }; |
| 607 PLArenaPool *newarena = NULL; | 611 PLArenaPool *newarena = NULL; |
| 608 | 612 |
| 609 if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) { | 613 if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) { |
| 610 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 614 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 611 » return NULL; | 615 return NULL; |
| 612 } | 616 } |
| 613 | 617 |
| 614 switch(derAVAValue->data[0]) { | 618 switch (derAVAValue->data[0]) { |
| 615 » case SEC_ASN1_UNIVERSAL_STRING: | 619 case SEC_ASN1_UNIVERSAL_STRING: |
| 616 » convert = conv_ucs4; | 620 convert = conv_ucs4; |
| 617 » theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate); | 621 theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate); |
| 618 » break; | 622 break; |
| 619 » case SEC_ASN1_IA5_STRING: | 623 case SEC_ASN1_IA5_STRING: |
| 620 » theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate); | 624 theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate); |
| 621 » break; | 625 break; |
| 622 » case SEC_ASN1_PRINTABLE_STRING: | 626 case SEC_ASN1_PRINTABLE_STRING: |
| 623 » theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate); | 627 theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate); |
| 624 » break; | 628 break; |
| 625 » case SEC_ASN1_T61_STRING: | 629 case SEC_ASN1_T61_STRING: |
| 626 » /* | 630 /* |
| 627 » * Per common practice, we're not decoding actual T.61, but instead | 631 * Per common practice, we're not decoding actual T.61, but instead |
| 628 » * treating T61-labeled strings as containing ISO-8859-1. | 632 * treating T61-labeled strings as containing ISO-8859-1. |
| 629 » */ | 633 */ |
| 630 » convert = conv_iso88591; | 634 convert = conv_iso88591; |
| 631 » theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate); | 635 theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate); |
| 632 » break; | 636 break; |
| 633 » case SEC_ASN1_BMP_STRING: | 637 case SEC_ASN1_BMP_STRING: |
| 634 » convert = conv_ucs2; | 638 convert = conv_ucs2; |
| 635 » theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate); | 639 theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate); |
| 636 » break; | 640 break; |
| 637 » case SEC_ASN1_UTF8_STRING: | 641 case SEC_ASN1_UTF8_STRING: |
| 638 » /* No conversion needed ! */ | 642 /* No conversion needed ! */ |
| 639 » theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate); | 643 theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate); |
| 640 » break; | 644 break; |
| 641 » default: | 645 default: |
| 642 » PORT_SetError(SEC_ERROR_INVALID_AVA); | 646 PORT_SetError(SEC_ERROR_INVALID_AVA); |
| 643 » return NULL; | 647 return NULL; |
| 644 } | 648 } |
| 645 | 649 |
| 646 PORT_Memset(&avaValue, 0, sizeof(SECItem)); | 650 PORT_Memset(&avaValue, 0, sizeof(SECItem)); |
| 647 newarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 651 newarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 648 if (!newarena) { | 652 if (!newarena) { |
| 649 return NULL; | 653 return NULL; |
| 650 } | 654 } |
| 651 if(SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) | 655 if (SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) != |
| 652 » » » » != SECSuccess) { | 656 SECSuccess) { |
| 653 » PORT_FreeArena(newarena, PR_FALSE); | 657 PORT_FreeArena(newarena, PR_FALSE); |
| 654 » return NULL; | 658 return NULL; |
| 655 } | 659 } |
| 656 | 660 |
| 657 if (convert != conv_none) { | 661 if (convert != conv_none) { |
| 658 » unsigned int utf8ValLen = avaValue.len * 3; | 662 unsigned int utf8ValLen = avaValue.len * 3; |
| 659 » unsigned char *utf8Val = (unsigned char*) | 663 unsigned char *utf8Val = |
| 660 » » » » PORT_ArenaZAlloc(newarena, utf8ValLen); | 664 (unsigned char *)PORT_ArenaZAlloc(newarena, utf8ValLen); |
| 661 | 665 |
| 662 switch (convert) { | 666 switch (convert) { |
| 663 case conv_ucs4: | 667 case conv_ucs4: |
| 664 if(avaValue.len % 4 != 0 || | 668 if (avaValue.len % 4 != 0 || |
| 665 !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, | 669 !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, |
| 666 » » » » » utf8Val, utf8ValLen, &utf8ValLen)) { | 670 avaValue.len, utf8Val, utf8ValLen, |
| 667 PORT_FreeArena(newarena, PR_FALSE); | 671 &utf8ValLen)) { |
| 668 PORT_SetError(SEC_ERROR_INVALID_AVA); | 672 PORT_FreeArena(newarena, PR_FALSE); |
| 669 » » return NULL; | 673 PORT_SetError(SEC_ERROR_INVALID_AVA); |
| 670 » } | 674 return NULL; |
| 671 » break; | 675 } |
| 672 » case conv_ucs2: | 676 break; |
| 673 if(avaValue.len % 2 != 0 || | 677 case conv_ucs2: |
| 674 !PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, | 678 if (avaValue.len % 2 != 0 || |
| 675 » » » » » utf8Val, utf8ValLen, &utf8ValLen)) { | 679 !PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, |
| 676 PORT_FreeArena(newarena, PR_FALSE); | 680 avaValue.len, utf8Val, utf8ValLen, |
| 677 PORT_SetError(SEC_ERROR_INVALID_AVA); | 681 &utf8ValLen)) { |
| 678 » » return NULL; | 682 PORT_FreeArena(newarena, PR_FALSE); |
| 679 » } | 683 PORT_SetError(SEC_ERROR_INVALID_AVA); |
| 680 » break; | 684 return NULL; |
| 681 » case conv_iso88591: | 685 } |
| 682 if(!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len, | 686 break; |
| 683 » » » » » utf8Val, utf8ValLen, &utf8ValLen)) { | 687 case conv_iso88591: |
| 684 PORT_FreeArena(newarena, PR_FALSE); | 688 if (!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len, |
| 685 PORT_SetError(SEC_ERROR_INVALID_AVA); | 689 utf8Val, utf8ValLen, |
| 686 » » return NULL; | 690 &utf8ValLen)) { |
| 687 » } | 691 PORT_FreeArena(newarena, PR_FALSE); |
| 688 » break; | 692 PORT_SetError(SEC_ERROR_INVALID_AVA); |
| 689 » case conv_none: | 693 return NULL; |
| 690 » PORT_Assert(0); /* not reached */ | 694 } |
| 691 » break; | 695 break; |
| 692 » } | 696 case conv_none: |
| 693 » | 697 PORT_Assert(0); /* not reached */ |
| 694 » avaValue.data = utf8Val; | 698 break; |
| 695 » avaValue.len = utf8ValLen; | 699 } |
| 700 |
| 701 avaValue.data = utf8Val; |
| 702 avaValue.len = utf8ValLen; |
| 696 } | 703 } |
| 697 | 704 |
| 698 retItem = SECITEM_DupItem(&avaValue); | 705 retItem = SECITEM_DupItem(&avaValue); |
| 699 PORT_FreeArena(newarena, PR_FALSE); | 706 PORT_FreeArena(newarena, PR_FALSE); |
| 700 return retItem; | 707 return retItem; |
| 701 } | 708 } |
| OLD | NEW |