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 |