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 /* | 5 /* |
6 * Certificate Extensions handling code | 6 * Certificate Extensions handling code |
7 * | 7 * |
8 */ | 8 */ |
9 | 9 |
10 #include "cert.h" | 10 #include "cert.h" |
11 #include "secitem.h" | 11 #include "secitem.h" |
12 #include "secoid.h" | 12 #include "secoid.h" |
13 #include "secder.h" | 13 #include "secder.h" |
14 #include "secasn1.h" | 14 #include "secasn1.h" |
15 #include "certxutl.h" | 15 #include "certxutl.h" |
16 #include "secerr.h" | 16 #include "secerr.h" |
17 | 17 |
18 #ifdef OLD | 18 #ifdef OLD |
19 #include "ocspti.h"» /* XXX a better extensions interface would not | 19 #include "ocspti.h" /* XXX a better extensions interface would not |
20 * require knowledge of data structures of callers */ | 20 * require knowledge of data structures of callers */ |
21 #endif | 21 #endif |
22 | 22 |
23 static CERTCertExtension * | 23 static CERTCertExtension * |
24 GetExtension (CERTCertExtension **extensions, SECItem *oid) | 24 GetExtension(CERTCertExtension **extensions, SECItem *oid) |
25 { | 25 { |
26 CERTCertExtension **exts; | 26 CERTCertExtension **exts; |
27 CERTCertExtension *ext = NULL; | 27 CERTCertExtension *ext = NULL; |
28 SECComparison comp; | 28 SECComparison comp; |
29 | 29 |
30 exts = extensions; | 30 exts = extensions; |
31 | 31 |
32 if (exts) { | 32 if (exts) { |
33 » while ( *exts ) { | 33 while (*exts) { |
34 » ext = *exts; | 34 ext = *exts; |
35 » comp = SECITEM_CompareItem(oid, &ext->id); | 35 comp = SECITEM_CompareItem(oid, &ext->id); |
36 » if ( comp == SECEqual ) | 36 if (comp == SECEqual) |
37 » » break; | 37 break; |
38 | 38 |
39 » exts++; | 39 exts++; |
40 » } | 40 } |
41 » return (*exts ? ext : NULL); | 41 return (*exts ? ext : NULL); |
42 } | 42 } |
43 return (NULL); | 43 return (NULL); |
44 } | 44 } |
45 | 45 |
46 SECStatus | 46 SECStatus |
47 cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *
value) | 47 cert_FindExtensionByOID(CERTCertExtension **extensions, SECItem *oid, |
| 48 SECItem *value) |
48 { | 49 { |
49 CERTCertExtension *ext; | 50 CERTCertExtension *ext; |
50 SECStatus rv = SECSuccess; | 51 SECStatus rv = SECSuccess; |
51 | 52 |
52 ext = GetExtension (extensions, oid); | 53 ext = GetExtension(extensions, oid); |
53 if (ext == NULL) { | 54 if (ext == NULL) { |
54 » PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND); | 55 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); |
55 » return (SECFailure); | 56 return (SECFailure); |
56 } | 57 } |
57 if (value) | 58 if (value) |
58 » rv = SECITEM_CopyItem(NULL, value, &ext->value); | 59 rv = SECITEM_CopyItem(NULL, value, &ext->value); |
59 return (rv); | 60 return (rv); |
60 } | 61 } |
61 | |
62 | 62 |
63 SECStatus | 63 SECStatus |
64 CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCri
tical) | 64 CERT_GetExtenCriticality(CERTCertExtension **extensions, int tag, |
| 65 PRBool *isCritical) |
65 { | 66 { |
66 CERTCertExtension *ext; | 67 CERTCertExtension *ext; |
67 SECOidData *oid; | 68 SECOidData *oid; |
68 | 69 |
69 if (!isCritical) | 70 if (!isCritical) |
70 » return (SECSuccess); | 71 return (SECSuccess); |
71 | 72 |
72 /* find the extension in the extensions list */ | 73 /* find the extension in the extensions list */ |
73 oid = SECOID_FindOIDByTag((SECOidTag)tag); | 74 oid = SECOID_FindOIDByTag((SECOidTag)tag); |
74 if ( !oid ) { | 75 if (!oid) { |
75 » return(SECFailure); | 76 return (SECFailure); |
76 } | 77 } |
77 ext = GetExtension (extensions, &oid->oid); | 78 ext = GetExtension(extensions, &oid->oid); |
78 if (ext == NULL) { | 79 if (ext == NULL) { |
79 » PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND); | 80 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); |
80 » return (SECFailure); | 81 return (SECFailure); |
81 } | 82 } |
82 | 83 |
83 /* If the criticality is omitted, then it is false by default. | 84 /* If the criticality is omitted, then it is false by default. |
84 ex->critical.data is NULL */ | 85 ex->critical.data is NULL */ |
85 if (ext->critical.data == NULL) | 86 if (ext->critical.data == NULL) |
86 » *isCritical = PR_FALSE; | 87 *isCritical = PR_FALSE; |
87 else | 88 else |
88 » *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE; | 89 *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE; |
89 return (SECSuccess); | 90 return (SECSuccess); |
90 } | 91 } |
91 | 92 |
92 SECStatus | 93 SECStatus |
93 cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value) | 94 cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value) |
94 { | 95 { |
95 SECOidData *oid; | 96 SECOidData *oid; |
96 | 97 |
97 oid = SECOID_FindOIDByTag((SECOidTag)tag); | 98 oid = SECOID_FindOIDByTag((SECOidTag)tag); |
98 if ( !oid ) { | 99 if (!oid) { |
99 » return(SECFailure); | 100 return (SECFailure); |
100 } | 101 } |
101 | 102 |
102 return(cert_FindExtensionByOID(extensions, &oid->oid, value)); | 103 return (cert_FindExtensionByOID(extensions, &oid->oid, value)); |
103 } | 104 } |
104 | 105 |
105 | |
106 typedef struct _extNode { | 106 typedef struct _extNode { |
107 struct _extNode *next; | 107 struct _extNode *next; |
108 CERTCertExtension *ext; | 108 CERTCertExtension *ext; |
109 } extNode; | 109 } extNode; |
110 | 110 |
111 typedef struct { | 111 typedef struct { |
112 void (*setExts)(void *object, CERTCertExtension **exts); | 112 void (*setExts)(void *object, CERTCertExtension **exts); |
113 void *object; | 113 void *object; |
114 PLArenaPool *ownerArena; | 114 PLArenaPool *ownerArena; |
115 PLArenaPool *arena; | 115 PLArenaPool *arena; |
116 extNode *head; | 116 extNode *head; |
117 int count; | 117 int count; |
118 }extRec; | 118 } extRec; |
119 | 119 |
120 /* | 120 /* |
121 * cert_StartExtensions | 121 * cert_StartExtensions |
122 * | 122 * |
123 * NOTE: This interface changed significantly to remove knowledge | 123 * NOTE: This interface changed significantly to remove knowledge |
124 * about callers data structures (owner objects) | 124 * about callers data structures (owner objects) |
125 */ | 125 */ |
126 void * | 126 void * |
127 cert_StartExtensions(void *owner, PLArenaPool *ownerArena, | 127 cert_StartExtensions(void *owner, PLArenaPool *ownerArena, |
128 void (*setExts)(void *object, CERTCertExtension **exts)) | 128 void (*setExts)(void *object, CERTCertExtension **exts)) |
129 { | 129 { |
130 PLArenaPool *arena; | 130 PLArenaPool *arena; |
131 extRec *handle; | 131 extRec *handle; |
132 | 132 |
133 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 133 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
134 if ( !arena ) { | 134 if (!arena) { |
135 » return(0); | 135 return (0); |
136 } | 136 } |
137 | 137 |
138 handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec)); | 138 handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec)); |
139 if ( !handle ) { | 139 if (!handle) { |
140 » PORT_FreeArena(arena, PR_FALSE); | 140 PORT_FreeArena(arena, PR_FALSE); |
141 » return(0); | 141 return (0); |
142 } | 142 } |
143 | 143 |
144 handle->object = owner; | 144 handle->object = owner; |
145 handle->ownerArena = ownerArena; | 145 handle->ownerArena = ownerArena; |
146 handle->setExts = setExts; | 146 handle->setExts = setExts; |
147 | 147 |
148 handle->arena = arena; | 148 handle->arena = arena; |
149 handle->head = 0; | 149 handle->head = 0; |
150 handle->count = 0; | 150 handle->count = 0; |
151 | 151 |
152 return(handle); | 152 return (handle); |
153 } | 153 } |
154 | 154 |
155 static unsigned char hextrue = 0xff; | 155 static unsigned char hextrue = 0xff; |
156 | 156 |
157 /* | 157 /* |
158 * Note - assumes that data pointed to by oid->data will not move | 158 * Note - assumes that data pointed to by oid->data will not move |
159 */ | 159 */ |
160 SECStatus | 160 SECStatus |
161 CERT_AddExtensionByOID (void *exthandle, SECItem *oid, SECItem *value, | 161 CERT_AddExtensionByOID(void *exthandle, SECItem *oid, SECItem *value, |
162 » » » PRBool critical, PRBool copyData) | 162 PRBool critical, PRBool copyData) |
163 { | 163 { |
164 CERTCertExtension *ext; | 164 CERTCertExtension *ext; |
165 SECStatus rv; | 165 SECStatus rv; |
166 extNode *node; | 166 extNode *node; |
167 extRec *handle; | 167 extRec *handle; |
168 | 168 |
169 handle = (extRec *)exthandle; | 169 handle = (extRec *)exthandle; |
170 | 170 |
171 /* allocate space for extension and list node */ | 171 /* allocate space for extension and list node */ |
172 ext = (CERTCertExtension*)PORT_ArenaZAlloc(handle->ownerArena, | 172 ext = (CERTCertExtension *)PORT_ArenaZAlloc(handle->ownerArena, |
173 sizeof(CERTCertExtension)); | 173 sizeof(CERTCertExtension)); |
174 if ( !ext ) { | 174 if (!ext) { |
175 » return(SECFailure); | 175 return (SECFailure); |
176 } | 176 } |
177 | 177 |
178 node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode)); | 178 node = (extNode *)PORT_ArenaAlloc(handle->arena, sizeof(extNode)); |
179 if ( !node ) { | 179 if (!node) { |
180 » return(SECFailure); | 180 return (SECFailure); |
181 } | 181 } |
182 | 182 |
183 /* add to list */ | 183 /* add to list */ |
184 node->next = handle->head; | 184 node->next = handle->head; |
185 handle->head = node; | 185 handle->head = node; |
186 | 186 |
187 /* point to ext struct */ | 187 /* point to ext struct */ |
188 node->ext = ext; | 188 node->ext = ext; |
189 | 189 |
190 /* the object ID of the extension */ | 190 /* the object ID of the extension */ |
191 ext->id = *oid; | 191 ext->id = *oid; |
192 | 192 |
193 /* set critical field */ | 193 /* set critical field */ |
194 if ( critical ) { | 194 if (critical) { |
195 » ext->critical.data = (unsigned char*)&hextrue; | 195 ext->critical.data = (unsigned char *)&hextrue; |
196 » ext->critical.len = 1; | 196 ext->critical.len = 1; |
197 } | 197 } |
198 | 198 |
199 /* set the value */ | 199 /* set the value */ |
200 if ( copyData ) { | 200 if (copyData) { |
201 » rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value); | 201 rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value); |
202 » if ( rv ) { | 202 if (rv) { |
203 » return(SECFailure); | 203 return (SECFailure); |
204 » } | 204 } |
205 } else { | 205 } else { |
206 » ext->value = *value; | 206 ext->value = *value; |
207 } | 207 } |
208 | 208 |
209 handle->count++; | 209 handle->count++; |
210 | |
211 return(SECSuccess); | |
212 | 210 |
| 211 return (SECSuccess); |
213 } | 212 } |
214 | 213 |
215 SECStatus | 214 SECStatus |
216 CERT_AddExtension(void *exthandle, int idtag, SECItem *value, | 215 CERT_AddExtension(void *exthandle, int idtag, SECItem *value, PRBool critical, |
217 » » PRBool critical, PRBool copyData) | 216 PRBool copyData) |
218 { | 217 { |
219 SECOidData *oid; | 218 SECOidData *oid; |
220 | 219 |
221 oid = SECOID_FindOIDByTag((SECOidTag)idtag); | 220 oid = SECOID_FindOIDByTag((SECOidTag)idtag); |
222 if ( !oid ) { | 221 if (!oid) { |
223 » return(SECFailure); | 222 return (SECFailure); |
224 } | 223 } |
225 | 224 |
226 return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyDat
a)); | 225 return (CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, |
| 226 copyData)); |
227 } | 227 } |
228 | 228 |
229 SECStatus | 229 SECStatus |
230 CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value, | 230 CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value, |
231 » » » PRBool critical, const SEC_ASN1Template *atemplate) | 231 PRBool critical, const SEC_ASN1Template *atemplate) |
232 { | 232 { |
233 extRec *handle; | 233 extRec *handle; |
234 SECItem *encitem; | 234 SECItem *encitem; |
235 | 235 |
236 handle = (extRec *)exthandle; | 236 handle = (extRec *)exthandle; |
237 | 237 |
238 encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate); | 238 encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate); |
239 if ( encitem == NULL ) { | 239 if (encitem == NULL) { |
240 » return(SECFailure); | 240 return (SECFailure); |
241 } | 241 } |
242 | 242 |
243 return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE); | 243 return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE); |
244 } | 244 } |
245 | 245 |
246 void | 246 void |
247 PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value) | 247 PrepareBitStringForEncoding(SECItem *bitsmap, SECItem *value) |
248 { | 248 { |
249 unsigned char onebyte; | 249 unsigned char onebyte; |
250 unsigned int i, len = 0; | 250 unsigned int i, len = 0; |
251 | 251 |
252 /* to prevent warning on some platform at compile time */ | 252 /* to prevent warning on some platform at compile time */ |
253 onebyte = '\0'; | 253 onebyte = '\0'; |
254 /* Get the position of the right-most turn-on bit */ | 254 /* Get the position of the right-most turn-on bit */ |
255 for (i = 0; i < (value->len ) * 8; ++i) { | 255 for (i = 0; i < (value->len) * 8; ++i) { |
256 if (i % 8 == 0) | 256 if (i % 8 == 0) |
257 » onebyte = value->data[i/8]; | 257 onebyte = value->data[i / 8]; |
258 if (onebyte & 0x80) | 258 if (onebyte & 0x80) |
259 » len = i; | 259 len = i; |
260 onebyte <<= 1; | 260 onebyte <<= 1; |
261 | 261 } |
262 } | 262 bitsmap->data = value->data; |
263 bitsmap->data = value->data; | 263 /* Add one here since we work with base 1 */ |
264 /* Add one here since we work with base 1 */ | 264 bitsmap->len = len + 1; |
265 bitsmap->len = len + 1; | |
266 } | 265 } |
267 | 266 |
268 SECStatus | 267 SECStatus |
269 CERT_EncodeAndAddBitStrExtension (void *exthandle, int idtag, | 268 CERT_EncodeAndAddBitStrExtension(void *exthandle, int idtag, SECItem *value, |
270 » » » » SECItem *value, PRBool critical) | 269 PRBool critical) |
271 { | 270 { |
272 SECItem bitsmap; | 271 SECItem bitsmap; |
273 | 272 |
274 PrepareBitStringForEncoding (&bitsmap, value); | 273 PrepareBitStringForEncoding(&bitsmap, value); |
275 return (CERT_EncodeAndAddExtension | 274 return (CERT_EncodeAndAddExtension(exthandle, idtag, &bitsmap, critical, |
276 » (exthandle, idtag, &bitsmap, critical, | 275 SEC_ASN1_GET(SEC_BitStringTemplate))); |
277 SEC_ASN1_GET(SEC_BitStringTemplate))); | |
278 } | 276 } |
279 | 277 |
280 SECStatus | 278 SECStatus |
281 CERT_FinishExtensions(void *exthandle) | 279 CERT_FinishExtensions(void *exthandle) |
282 { | 280 { |
283 extRec *handle; | 281 extRec *handle; |
284 extNode *node; | 282 extNode *node; |
285 CERTCertExtension **exts; | 283 CERTCertExtension **exts; |
286 SECStatus rv = SECFailure; | 284 SECStatus rv = SECFailure; |
287 | 285 |
288 handle = (extRec *)exthandle; | 286 handle = (extRec *)exthandle; |
289 | 287 |
290 /* allocate space for extensions array */ | 288 /* allocate space for extensions array */ |
291 exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *, | 289 exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *, |
292 » » » handle->count + 1); | 290 handle->count + 1); |
293 if (exts == NULL) { | 291 if (exts == NULL) { |
294 » goto loser; | 292 goto loser; |
295 } | 293 } |
296 | 294 |
297 /* put extensions in owner object and update its version number */ | 295 /* put extensions in owner object and update its version number */ |
298 | 296 |
299 #ifdef OLD | 297 #ifdef OLD |
300 switch (handle->type) { | 298 switch (handle->type) { |
301 case CertificateExtensions: | 299 case CertificateExtensions: |
302 » handle->owner.cert->extensions = exts; | 300 handle->owner.cert->extensions = exts; |
303 » DER_SetUInteger (ownerArena, &(handle->owner.cert->version), | 301 DER_SetUInteger(ownerArena, &(handle->owner.cert->version), |
304 » » » SEC_CERTIFICATE_VERSION_3); | 302 SEC_CERTIFICATE_VERSION_3); |
305 » break; | 303 break; |
306 case CrlExtensions: | 304 case CrlExtensions: |
307 » handle->owner.crl->extensions = exts; | 305 handle->owner.crl->extensions = exts; |
308 » DER_SetUInteger (ownerArena, &(handle->owner.crl->version), | 306 DER_SetUInteger(ownerArena, &(handle->owner.crl->version), |
309 » » » SEC_CRL_VERSION_2); | 307 SEC_CRL_VERSION_2); |
310 » break; | 308 break; |
311 case OCSPRequestExtensions: | 309 case OCSPRequestExtensions: |
312 » handle->owner.request->tbsRequest->requestExtensions = exts; | 310 handle->owner.request->tbsRequest->requestExtensions = exts; |
313 » break; | 311 break; |
314 case OCSPSingleRequestExtensions: | 312 case OCSPSingleRequestExtensions: |
315 » handle->owner.singleRequest->singleRequestExtensions = exts;» | 313 handle->owner.singleRequest->singleRequestExtensions = exts; |
316 » break; | 314 break; |
317 case OCSPResponseSingleExtensions: | 315 case OCSPResponseSingleExtensions: |
318 » handle->owner.singleResponse->singleExtensions = exts;» | 316 handle->owner.singleResponse->singleExtensions = exts; |
319 » break; | 317 break; |
320 } | 318 } |
321 #endif | 319 #endif |
322 | 320 |
323 handle->setExts(handle->object, exts); | 321 handle->setExts(handle->object, exts); |
324 » | 322 |
325 /* update the version number */ | 323 /* update the version number */ |
326 | 324 |
327 /* copy each extension pointer */ | 325 /* copy each extension pointer */ |
328 node = handle->head; | 326 node = handle->head; |
329 while ( node ) { | 327 while (node) { |
330 » *exts = node->ext; | 328 *exts = node->ext; |
331 » | 329 |
332 » node = node->next; | 330 node = node->next; |
333 » exts++; | 331 exts++; |
334 } | 332 } |
335 | 333 |
336 /* terminate the array of extensions */ | 334 /* terminate the array of extensions */ |
337 *exts = 0; | 335 *exts = 0; |
338 | 336 |
339 rv = SECSuccess; | 337 rv = SECSuccess; |
340 | 338 |
341 loser: | 339 loser: |
342 /* free working arena */ | 340 /* free working arena */ |
343 PORT_FreeArena(handle->arena, PR_FALSE); | 341 PORT_FreeArena(handle->arena, PR_FALSE); |
344 return rv; | 342 return rv; |
345 } | 343 } |
346 | 344 |
347 SECStatus | 345 SECStatus |
348 CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions) | 346 CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions) |
349 { | 347 { |
350 CERTCertExtension *ext; | 348 CERTCertExtension *ext; |
351 SECStatus rv = SECSuccess; | 349 SECStatus rv = SECSuccess; |
352 SECOidTag tag; | 350 SECOidTag tag; |
353 extNode *node; | 351 extNode *node; |
354 extRec *handle = exthandle; | 352 extRec *handle = exthandle; |
355 | 353 |
356 if (!exthandle || !extensions) { | 354 if (!exthandle || !extensions) { |
357 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 355 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
358 return SECFailure; | 356 return SECFailure; |
359 } | 357 } |
360 while ((ext = *extensions++) != NULL) { | 358 while ((ext = *extensions++) != NULL) { |
361 tag = SECOID_FindOIDTag(&ext->id); | 359 tag = SECOID_FindOIDTag(&ext->id); |
362 for (node=handle->head; node != NULL; node=node->next) { | 360 for (node = handle->head; node != NULL; node = node->next) { |
363 if (tag == 0) { | 361 if (tag == 0) { |
364 if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id)) | 362 if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id)) |
365 break; | 363 break; |
366 } | 364 } else { |
367 else { | |
368 if (SECOID_FindOIDTag(&node->ext->id) == tag) { | 365 if (SECOID_FindOIDTag(&node->ext->id) == tag) { |
369 break; | 366 break; |
370 } | 367 } |
371 } | 368 } |
372 } | 369 } |
373 if (node == NULL) { | 370 if (node == NULL) { |
374 PRBool critical = (ext->critical.len != 0 && | 371 PRBool critical = (ext->critical.len != 0 && |
375 ext->critical.data[ext->critical.len - 1] != 0); | 372 ext->critical.data[ext->critical.len - 1] != 0); |
376 if (critical && tag == SEC_OID_UNKNOWN) { | 373 if (critical && tag == SEC_OID_UNKNOWN) { |
377 PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); | 374 PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); |
378 rv = SECFailure; | 375 rv = SECFailure; |
379 break; | 376 break; |
380 } | 377 } |
381 /* add to list */ | 378 /* add to list */ |
382 rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value, | 379 rv = CERT_AddExtensionByOID(exthandle, &ext->id, &ext->value, |
383 critical, PR_TRUE); | 380 critical, PR_TRUE); |
384 if (rv != SECSuccess) | 381 if (rv != SECSuccess) |
385 break; | 382 break; |
386 } | 383 } |
387 } | 384 } |
388 return rv; | 385 return rv; |
389 } | 386 } |
390 | 387 |
391 /* | 388 /* |
392 * get the value of the Netscape Certificate Type Extension | 389 * get the value of the Netscape Certificate Type Extension |
393 */ | 390 */ |
394 SECStatus | 391 SECStatus |
395 CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag, | 392 CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag, |
396 » » » SECItem *retItem) | 393 SECItem *retItem) |
397 { | 394 { |
398 SECItem wrapperItem, tmpItem = {siBuffer,0}; | 395 SECItem wrapperItem, tmpItem = { siBuffer, 0 }; |
399 SECStatus rv; | 396 SECStatus rv; |
400 PLArenaPool *arena = NULL; | 397 PLArenaPool *arena = NULL; |
401 | 398 |
402 wrapperItem.data = NULL; | 399 wrapperItem.data = NULL; |
403 tmpItem.data = NULL; | 400 tmpItem.data = NULL; |
404 | 401 |
405 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 402 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
406 | 403 |
407 if ( ! arena ) { | 404 if (!arena) { |
408 » return(SECFailure); | 405 return (SECFailure); |
409 } | |
410 | |
411 rv = cert_FindExtension(extensions, tag, &wrapperItem); | |
412 if ( rv != SECSuccess ) { | |
413 » goto loser; | |
414 } | 406 } |
415 | 407 |
416 rv = SEC_QuickDERDecodeItem(arena, &tmpItem, | 408 rv = cert_FindExtension(extensions, tag, &wrapperItem); |
417 SEC_ASN1_GET(SEC_BitStringTemplate), | 409 if (rv != SECSuccess) { |
418 &wrapperItem); | 410 goto loser; |
419 | |
420 if ( rv != SECSuccess ) { | |
421 » goto loser; | |
422 } | 411 } |
423 | 412 |
424 retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 ); | 413 rv = SEC_QuickDERDecodeItem( |
425 if ( retItem->data == NULL ) { | 414 arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem); |
426 » goto loser; | 415 |
| 416 if (rv != SECSuccess) { |
| 417 goto loser; |
427 } | 418 } |
428 | 419 |
429 PORT_Memcpy(retItem->data, tmpItem.data, ( tmpItem.len + 7 ) >> 3); | 420 retItem->data = (unsigned char *)PORT_Alloc((tmpItem.len + 7) >> 3); |
| 421 if (retItem->data == NULL) { |
| 422 goto loser; |
| 423 } |
| 424 |
| 425 PORT_Memcpy(retItem->data, tmpItem.data, (tmpItem.len + 7) >> 3); |
430 retItem->len = tmpItem.len; | 426 retItem->len = tmpItem.len; |
431 | 427 |
432 rv = SECSuccess; | 428 rv = SECSuccess; |
433 goto done; | 429 goto done; |
434 | 430 |
435 loser: | 431 loser: |
436 rv = SECFailure; | 432 rv = SECFailure; |
437 | 433 |
438 done: | 434 done: |
439 if ( arena ) { | 435 if (arena) { |
440 » PORT_FreeArena(arena, PR_FALSE); | 436 PORT_FreeArena(arena, PR_FALSE); |
441 } | |
442 | |
443 if ( wrapperItem.data ) { | |
444 » PORT_Free(wrapperItem.data); | |
445 } | 437 } |
446 | 438 |
447 return(rv); | 439 if (wrapperItem.data) { |
| 440 PORT_Free(wrapperItem.data); |
| 441 } |
| 442 |
| 443 return (rv); |
448 } | 444 } |
449 | 445 |
450 PRBool | 446 PRBool |
451 cert_HasCriticalExtension (CERTCertExtension **extensions) | 447 cert_HasCriticalExtension(CERTCertExtension **extensions) |
452 { | 448 { |
453 CERTCertExtension **exts; | 449 CERTCertExtension **exts; |
454 CERTCertExtension *ext = NULL; | 450 CERTCertExtension *ext = NULL; |
455 PRBool hasCriticalExten = PR_FALSE; | 451 PRBool hasCriticalExten = PR_FALSE; |
456 | 452 |
457 exts = extensions; | 453 exts = extensions; |
458 | 454 |
459 if (exts) { | 455 if (exts) { |
460 » while ( *exts ) { | 456 while (*exts) { |
461 » ext = *exts; | 457 ext = *exts; |
462 » /* If the criticality is omitted, it's non-critical */ | 458 /* If the criticality is omitted, it's non-critical */ |
463 » if (ext->critical.data && ext->critical.data[0] == 0xff) { | 459 if (ext->critical.data && ext->critical.data[0] == 0xff) { |
464 » » hasCriticalExten = PR_TRUE; | 460 hasCriticalExten = PR_TRUE; |
465 » » break; | 461 break; |
466 » } | 462 } |
467 » exts++; | 463 exts++; |
468 » } | 464 } |
469 } | 465 } |
470 return (hasCriticalExten); | 466 return (hasCriticalExten); |
471 } | 467 } |
472 | 468 |
473 PRBool | 469 PRBool |
474 cert_HasUnknownCriticalExten (CERTCertExtension **extensions) | 470 cert_HasUnknownCriticalExten(CERTCertExtension **extensions) |
475 { | 471 { |
476 CERTCertExtension **exts; | 472 CERTCertExtension **exts; |
477 CERTCertExtension *ext = NULL; | 473 CERTCertExtension *ext = NULL; |
478 PRBool hasUnknownCriticalExten = PR_FALSE; | 474 PRBool hasUnknownCriticalExten = PR_FALSE; |
479 | 475 |
480 exts = extensions; | 476 exts = extensions; |
481 | 477 |
482 if (exts) { | 478 if (exts) { |
483 » while ( *exts ) { | 479 while (*exts) { |
484 » ext = *exts; | 480 ext = *exts; |
485 » /* If the criticality is omitted, it's non-critical. | 481 /* If the criticality is omitted, it's non-critical. |
486 » If an extension is critical, make sure that we know | 482 If an extension is critical, make sure that we know |
487 » how to process the extension. | 483 how to process the extension. |
488 */ | 484 */ |
489 » if (ext->critical.data && ext->critical.data[0] == 0xff) { | 485 if (ext->critical.data && ext->critical.data[0] == 0xff) { |
490 » » if (SECOID_KnownCertExtenOID (&ext->id) == PR_FALSE) { | 486 if (SECOID_KnownCertExtenOID(&ext->id) == PR_FALSE) { |
491 » » hasUnknownCriticalExten = PR_TRUE; | 487 hasUnknownCriticalExten = PR_TRUE; |
492 » » break; | 488 break; |
493 » » } | 489 } |
494 » } | 490 } |
495 » exts++; | 491 exts++; |
496 » } | 492 } |
497 } | 493 } |
498 return (hasUnknownCriticalExten); | 494 return (hasUnknownCriticalExten); |
499 } | 495 } |
OLD | NEW |