Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/certdb/polcyxtn.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 /* | |
6 * Support for various policy related extensions | |
7 */ | |
8 | |
9 #include "seccomon.h" | |
10 #include "secport.h" | |
11 #include "secder.h" | |
12 #include "cert.h" | |
13 #include "secoid.h" | |
14 #include "secasn1.h" | |
15 #include "secerr.h" | |
16 #include "nspr.h" | |
17 | |
18 SEC_ASN1_MKSUB(SEC_IntegerTemplate) | |
19 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) | |
20 | |
21 const SEC_ASN1Template CERT_DisplayTextTypeTemplate[] = { | |
22 { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) }, | |
23 { SEC_ASN1_IA5_STRING, 0, 0, siAsciiString}, | |
24 { SEC_ASN1_VISIBLE_STRING , 0, 0, siVisibleString}, | |
25 { SEC_ASN1_BMP_STRING , 0, 0, siBMPString }, | |
26 { SEC_ASN1_UTF8_STRING , 0, 0, siUTF8String }, | |
27 { 0 } | |
28 }; | |
29 | |
30 const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = { | |
31 { SEC_ASN1_SEQUENCE, | |
32 0, NULL, sizeof(CERTNoticeReference) }, | |
33 { SEC_ASN1_INLINE, | |
34 offsetof(CERTNoticeReference, organization), | |
35 CERT_DisplayTextTypeTemplate, 0 }, | |
36 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, | |
37 offsetof(CERTNoticeReference, noticeNumbers), | |
38 SEC_ASN1_SUB(SEC_IntegerTemplate) }, | |
39 { 0 } | |
40 }; | |
41 | |
42 const SEC_ASN1Template CERT_UserNoticeTemplate[] = { | |
43 { SEC_ASN1_SEQUENCE, | |
44 0, NULL, sizeof(CERTUserNotice) }, | |
45 { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, | |
46 offsetof(CERTUserNotice, noticeReference), | |
47 CERT_NoticeReferenceTemplate, 0 }, | |
48 { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, | |
49 offsetof(CERTUserNotice, displayText), | |
50 CERT_DisplayTextTypeTemplate, 0 }, | |
51 { 0 } | |
52 }; | |
53 | |
54 const SEC_ASN1Template CERT_PolicyQualifierTemplate[] = { | |
55 { SEC_ASN1_SEQUENCE, | |
56 0, NULL, sizeof(CERTPolicyQualifier) }, | |
57 { SEC_ASN1_OBJECT_ID, | |
58 offsetof(CERTPolicyQualifier, qualifierID) }, | |
59 { SEC_ASN1_ANY, | |
60 offsetof(CERTPolicyQualifier, qualifierValue) }, | |
61 { 0 } | |
62 }; | |
63 | |
64 const SEC_ASN1Template CERT_PolicyInfoTemplate[] = { | |
65 { SEC_ASN1_SEQUENCE, | |
66 0, NULL, sizeof(CERTPolicyInfo) }, | |
67 { SEC_ASN1_OBJECT_ID, | |
68 offsetof(CERTPolicyInfo, policyID) }, | |
69 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL, | |
70 offsetof(CERTPolicyInfo, policyQualifiers), | |
71 CERT_PolicyQualifierTemplate }, | |
72 { 0 } | |
73 }; | |
74 | |
75 const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = { | |
76 { SEC_ASN1_SEQUENCE_OF, | |
77 offsetof(CERTCertificatePolicies, policyInfos), | |
78 CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) } | |
79 }; | |
80 | |
81 const SEC_ASN1Template CERT_PolicyMapTemplate[] = { | |
82 { SEC_ASN1_SEQUENCE, | |
83 0, NULL, sizeof(CERTPolicyMap) }, | |
84 { SEC_ASN1_OBJECT_ID, | |
85 offsetof(CERTPolicyMap, issuerDomainPolicy) }, | |
86 { SEC_ASN1_OBJECT_ID, | |
87 offsetof(CERTPolicyMap, subjectDomainPolicy) }, | |
88 { 0 } | |
89 }; | |
90 | |
91 const SEC_ASN1Template CERT_PolicyMappingsTemplate[] = { | |
92 { SEC_ASN1_SEQUENCE_OF, | |
93 offsetof(CERTCertificatePolicyMappings, policyMaps), | |
94 CERT_PolicyMapTemplate, sizeof(CERTPolicyMap) } | |
95 }; | |
96 | |
97 const SEC_ASN1Template CERT_PolicyConstraintsTemplate[] = { | |
98 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificatePolicyConstraints) }, | |
99 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, | |
100 offsetof(CERTCertificatePolicyConstraints, explicitPolicySkipCerts), | |
101 SEC_ASN1_SUB(SEC_IntegerTemplate) }, | |
102 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, | |
103 offsetof(CERTCertificatePolicyConstraints, inhibitMappingSkipCerts), | |
104 SEC_ASN1_SUB(SEC_IntegerTemplate) }, | |
105 { 0 } | |
106 }; | |
107 | |
108 const SEC_ASN1Template CERT_InhibitAnyTemplate[] = { | |
109 { SEC_ASN1_INTEGER, | |
110 offsetof(CERTCertificateInhibitAny, inhibitAnySkipCerts), | |
111 NULL, sizeof(CERTCertificateInhibitAny) } | |
112 }; | |
113 | |
114 static void | |
115 breakLines(char *string) | |
116 { | |
117 char *tmpstr; | |
118 char *lastspace = NULL; | |
119 int curlen = 0; | |
120 int c; | |
121 | |
122 tmpstr = string; | |
123 | |
124 while ( ( c = *tmpstr ) != '\0' ) { | |
125 switch ( c ) { | |
126 case ' ': | |
127 lastspace = tmpstr; | |
128 break; | |
129 case '\n': | |
130 lastspace = NULL; | |
131 curlen = 0; | |
132 break; | |
133 } | |
134 | |
135 if ( ( curlen >= 55 ) && ( lastspace != NULL ) ) { | |
136 *lastspace = '\n'; | |
137 curlen = ( tmpstr - lastspace ); | |
138 lastspace = NULL; | |
139 } | |
140 | |
141 curlen++; | |
142 tmpstr++; | |
143 } | |
144 | |
145 return; | |
146 } | |
147 | |
148 CERTCertificatePolicies * | |
149 CERT_DecodeCertificatePoliciesExtension(const SECItem *extnValue) | |
150 { | |
151 PLArenaPool *arena = NULL; | |
152 SECStatus rv; | |
153 CERTCertificatePolicies *policies; | |
154 CERTPolicyInfo **policyInfos, *policyInfo; | |
155 CERTPolicyQualifier **policyQualifiers, *policyQualifier; | |
156 SECItem newExtnValue; | |
157 | |
158 /* make a new arena */ | |
159 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
160 | |
161 if ( !arena ) { | |
162 goto loser; | |
163 } | |
164 | |
165 /* allocate the certificate policies structure */ | |
166 policies = (CERTCertificatePolicies *) | |
167 PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies)); | |
168 | |
169 if ( policies == NULL ) { | |
170 goto loser; | |
171 } | |
172 | |
173 policies->arena = arena; | |
174 | |
175 /* copy the DER into the arena, since Quick DER returns data that points | |
176 into the DER input, which may get freed by the caller */ | |
177 rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); | |
178 if ( rv != SECSuccess ) { | |
179 goto loser; | |
180 } | |
181 | |
182 /* decode the policy info */ | |
183 rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate, | |
184 &newExtnValue); | |
185 | |
186 if ( rv != SECSuccess ) { | |
187 goto loser; | |
188 } | |
189 | |
190 /* initialize the oid tags */ | |
191 policyInfos = policies->policyInfos; | |
192 while (*policyInfos != NULL ) { | |
193 policyInfo = *policyInfos; | |
194 policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID); | |
195 policyQualifiers = policyInfo->policyQualifiers; | |
196 while ( policyQualifiers != NULL && *policyQualifiers != NULL ) { | |
197 policyQualifier = *policyQualifiers; | |
198 policyQualifier->oid = | |
199 SECOID_FindOIDTag(&policyQualifier->qualifierID); | |
200 policyQualifiers++; | |
201 } | |
202 policyInfos++; | |
203 } | |
204 | |
205 return(policies); | |
206 | |
207 loser: | |
208 if ( arena != NULL ) { | |
209 PORT_FreeArena(arena, PR_FALSE); | |
210 } | |
211 | |
212 return(NULL); | |
213 } | |
214 | |
215 void | |
216 CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies) | |
217 { | |
218 if ( policies != NULL ) { | |
219 PORT_FreeArena(policies->arena, PR_FALSE); | |
220 } | |
221 return; | |
222 } | |
223 | |
224 CERTCertificatePolicyMappings * | |
225 CERT_DecodePolicyMappingsExtension(SECItem *extnValue) | |
226 { | |
227 PLArenaPool *arena = NULL; | |
228 SECStatus rv; | |
229 CERTCertificatePolicyMappings *mappings; | |
230 SECItem newExtnValue; | |
231 | |
232 /* make a new arena */ | |
233 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
234 if ( !arena ) { | |
235 goto loser; | |
236 } | |
237 | |
238 /* allocate the policy mappings structure */ | |
239 mappings = (CERTCertificatePolicyMappings *) | |
240 PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicyMappings)); | |
241 if ( mappings == NULL ) { | |
242 goto loser; | |
243 } | |
244 mappings->arena = arena; | |
245 | |
246 /* copy the DER into the arena, since Quick DER returns data that points | |
247 into the DER input, which may get freed by the caller */ | |
248 rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); | |
249 if ( rv != SECSuccess ) { | |
250 goto loser; | |
251 } | |
252 | |
253 /* decode the policy mappings */ | |
254 rv = SEC_QuickDERDecodeItem | |
255 (arena, mappings, CERT_PolicyMappingsTemplate, &newExtnValue); | |
256 if ( rv != SECSuccess ) { | |
257 goto loser; | |
258 } | |
259 | |
260 return(mappings); | |
261 | |
262 loser: | |
263 if ( arena != NULL ) { | |
264 PORT_FreeArena(arena, PR_FALSE); | |
265 } | |
266 | |
267 return(NULL); | |
268 } | |
269 | |
270 SECStatus | |
271 CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings) | |
272 { | |
273 if ( mappings != NULL ) { | |
274 PORT_FreeArena(mappings->arena, PR_FALSE); | |
275 } | |
276 return SECSuccess; | |
277 } | |
278 | |
279 SECStatus | |
280 CERT_DecodePolicyConstraintsExtension | |
281 (CERTCertificatePolicyConstraints *decodedValue, | |
282 const SECItem *encodedValue) | |
283 { | |
284 CERTCertificatePolicyConstraints decodeContext; | |
285 PLArenaPool *arena = NULL; | |
286 SECStatus rv = SECSuccess; | |
287 | |
288 /* initialize so we can tell when an optional component is omitted */ | |
289 PORT_Memset(&decodeContext, 0, sizeof(decodeContext)); | |
290 | |
291 /* make a new arena */ | |
292 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | |
293 if (!arena) { | |
294 return SECFailure; | |
295 } | |
296 | |
297 do { | |
298 /* decode the policy constraints */ | |
299 rv = SEC_QuickDERDecodeItem(arena, | |
300 &decodeContext, CERT_PolicyConstraintsTemplate, encodedValue); | |
301 | |
302 if ( rv != SECSuccess ) { | |
303 break; | |
304 } | |
305 | |
306 if (decodeContext.explicitPolicySkipCerts.len == 0) { | |
307 *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = -1; | |
308 } else { | |
309 *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = | |
310 DER_GetInteger(&decodeContext.explicitPolicySkipCerts); | |
311 } | |
312 | |
313 if (decodeContext.inhibitMappingSkipCerts.len == 0) { | |
314 *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = -1; | |
315 } else { | |
316 *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = | |
317 DER_GetInteger(&decodeContext.inhibitMappingSkipCerts); | |
318 } | |
319 | |
320 if ((*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data == | |
321 PR_INT32_MIN) || | |
322 (*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data == | |
323 PR_INT32_MAX) || | |
324 (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data == | |
325 PR_INT32_MIN) || | |
326 (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data == | |
327 PR_INT32_MAX)) { | |
328 rv = SECFailure; | |
329 } | |
330 | |
331 } while (0); | |
332 | |
333 PORT_FreeArena(arena, PR_FALSE); | |
334 return(rv); | |
335 } | |
336 | |
337 SECStatus CERT_DecodeInhibitAnyExtension | |
338 (CERTCertificateInhibitAny *decodedValue, SECItem *encodedValue) | |
339 { | |
340 CERTCertificateInhibitAny decodeContext; | |
341 PLArenaPool *arena = NULL; | |
342 SECStatus rv = SECSuccess; | |
343 | |
344 /* make a new arena */ | |
345 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | |
346 if ( !arena ) { | |
347 return SECFailure; | |
348 } | |
349 | |
350 do { | |
351 | |
352 /* decode the policy mappings */ | |
353 decodeContext.inhibitAnySkipCerts.type = siUnsignedInteger; | |
354 rv = SEC_QuickDERDecodeItem(arena, | |
355 &decodeContext, CERT_InhibitAnyTemplate, encodedValue); | |
356 | |
357 if ( rv != SECSuccess ) { | |
358 break; | |
359 } | |
360 | |
361 *(PRInt32 *)decodedValue->inhibitAnySkipCerts.data = | |
362 DER_GetInteger(&decodeContext.inhibitAnySkipCerts); | |
363 | |
364 } while (0); | |
365 | |
366 PORT_FreeArena(arena, PR_FALSE); | |
367 return(rv); | |
368 } | |
369 | |
370 CERTUserNotice * | |
371 CERT_DecodeUserNotice(SECItem *noticeItem) | |
372 { | |
373 PLArenaPool *arena = NULL; | |
374 SECStatus rv; | |
375 CERTUserNotice *userNotice; | |
376 SECItem newNoticeItem; | |
377 | |
378 /* make a new arena */ | |
379 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
380 | |
381 if ( !arena ) { | |
382 goto loser; | |
383 } | |
384 | |
385 /* allocate the userNotice structure */ | |
386 userNotice = (CERTUserNotice *)PORT_ArenaZAlloc(arena, | |
387 sizeof(CERTUserNotice)); | |
388 | |
389 if ( userNotice == NULL ) { | |
390 goto loser; | |
391 } | |
392 | |
393 userNotice->arena = arena; | |
394 | |
395 /* copy the DER into the arena, since Quick DER returns data that points | |
396 into the DER input, which may get freed by the caller */ | |
397 rv = SECITEM_CopyItem(arena, &newNoticeItem, noticeItem); | |
398 if ( rv != SECSuccess ) { | |
399 goto loser; | |
400 } | |
401 | |
402 /* decode the user notice */ | |
403 rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate, | |
404 &newNoticeItem); | |
405 | |
406 if ( rv != SECSuccess ) { | |
407 goto loser; | |
408 } | |
409 | |
410 if (userNotice->derNoticeReference.data != NULL) { | |
411 | |
412 rv = SEC_QuickDERDecodeItem(arena, &userNotice->noticeReference, | |
413 CERT_NoticeReferenceTemplate, | |
414 &userNotice->derNoticeReference); | |
415 if (rv == SECFailure) { | |
416 goto loser; | |
417 } | |
418 } | |
419 | |
420 return(userNotice); | |
421 | |
422 loser: | |
423 if ( arena != NULL ) { | |
424 PORT_FreeArena(arena, PR_FALSE); | |
425 } | |
426 | |
427 return(NULL); | |
428 } | |
429 | |
430 void | |
431 CERT_DestroyUserNotice(CERTUserNotice *userNotice) | |
432 { | |
433 if ( userNotice != NULL ) { | |
434 PORT_FreeArena(userNotice->arena, PR_FALSE); | |
435 } | |
436 return; | |
437 } | |
438 | |
439 static CERTPolicyStringCallback policyStringCB = NULL; | |
440 static void *policyStringCBArg = NULL; | |
441 | |
442 void | |
443 CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg) | |
444 { | |
445 policyStringCB = cb; | |
446 policyStringCBArg = cbarg; | |
447 return; | |
448 } | |
449 | |
450 char * | |
451 stringFromUserNotice(SECItem *noticeItem) | |
452 { | |
453 SECItem *org; | |
454 unsigned int len, headerlen; | |
455 char *stringbuf; | |
456 CERTUserNotice *userNotice; | |
457 char *policystr; | |
458 char *retstr = NULL; | |
459 SECItem *displayText; | |
460 SECItem **noticeNumbers; | |
461 unsigned int strnum; | |
462 | |
463 /* decode the user notice */ | |
464 userNotice = CERT_DecodeUserNotice(noticeItem); | |
465 if ( userNotice == NULL ) { | |
466 return(NULL); | |
467 } | |
468 | |
469 org = &userNotice->noticeReference.organization; | |
470 if ( (org->len != 0 ) && ( policyStringCB != NULL ) ) { | |
471 /* has a noticeReference */ | |
472 | |
473 /* extract the org string */ | |
474 len = org->len; | |
475 stringbuf = (char*)PORT_Alloc(len + 1); | |
476 if ( stringbuf != NULL ) { | |
477 PORT_Memcpy(stringbuf, org->data, len); | |
478 stringbuf[len] = '\0'; | |
479 | |
480 noticeNumbers = userNotice->noticeReference.noticeNumbers; | |
481 while ( *noticeNumbers != NULL ) { | |
482 /* XXX - only one byte integers right now*/ | |
483 strnum = (*noticeNumbers)->data[0]; | |
484 policystr = (* policyStringCB)(stringbuf, | |
485 strnum, | |
486 policyStringCBArg); | |
487 if ( policystr != NULL ) { | |
488 if ( retstr != NULL ) { | |
489 retstr = PR_sprintf_append(retstr, "\n%s", policystr); | |
490 } else { | |
491 retstr = PR_sprintf_append(retstr, "%s", policystr); | |
492 } | |
493 | |
494 PORT_Free(policystr); | |
495 } | |
496 | |
497 noticeNumbers++; | |
498 } | |
499 | |
500 PORT_Free(stringbuf); | |
501 } | |
502 } | |
503 | |
504 if ( retstr == NULL ) { | |
505 if ( userNotice->displayText.len != 0 ) { | |
506 displayText = &userNotice->displayText; | |
507 | |
508 if ( displayText->len > 2 ) { | |
509 if ( displayText->data[0] == SEC_ASN1_VISIBLE_STRING ) { | |
510 headerlen = 2; | |
511 if ( displayText->data[1] & 0x80 ) { | |
512 /* multibyte length */ | |
513 headerlen += ( displayText->data[1] & 0x7f ); | |
514 } | |
515 | |
516 len = displayText->len - headerlen; | |
517 retstr = (char*)PORT_Alloc(len + 1); | |
518 if ( retstr != NULL ) { | |
519 PORT_Memcpy(retstr, &displayText->data[headerlen],len); | |
520 retstr[len] = '\0'; | |
521 } | |
522 } | |
523 } | |
524 } | |
525 } | |
526 | |
527 CERT_DestroyUserNotice(userNotice); | |
528 | |
529 return(retstr); | |
530 } | |
531 | |
532 char * | |
533 CERT_GetCertCommentString(CERTCertificate *cert) | |
534 { | |
535 char *retstring = NULL; | |
536 SECStatus rv; | |
537 SECItem policyItem; | |
538 CERTCertificatePolicies *policies = NULL; | |
539 CERTPolicyInfo **policyInfos; | |
540 CERTPolicyQualifier **policyQualifiers, *qualifier; | |
541 | |
542 policyItem.data = NULL; | |
543 | |
544 rv = CERT_FindCertExtension(cert, SEC_OID_X509_CERTIFICATE_POLICIES, | |
545 &policyItem); | |
546 if ( rv != SECSuccess ) { | |
547 goto nopolicy; | |
548 } | |
549 | |
550 policies = CERT_DecodeCertificatePoliciesExtension(&policyItem); | |
551 if ( policies == NULL ) { | |
552 goto nopolicy; | |
553 } | |
554 | |
555 policyInfos = policies->policyInfos; | |
556 /* search through policyInfos looking for the verisign policy */ | |
557 while (*policyInfos != NULL ) { | |
558 if ( (*policyInfos)->oid == SEC_OID_VERISIGN_USER_NOTICES ) { | |
559 policyQualifiers = (*policyInfos)->policyQualifiers; | |
560 /* search through the policy qualifiers looking for user notice */ | |
561 while ( policyQualifiers != NULL && *policyQualifiers != NULL ) { | |
562 qualifier = *policyQualifiers; | |
563 if ( qualifier->oid == SEC_OID_PKIX_USER_NOTICE_QUALIFIER ) { | |
564 retstring = | |
565 stringFromUserNotice(&qualifier->qualifierValue); | |
566 break; | |
567 } | |
568 | |
569 policyQualifiers++; | |
570 } | |
571 break; | |
572 } | |
573 policyInfos++; | |
574 } | |
575 | |
576 nopolicy: | |
577 if ( policyItem.data != NULL ) { | |
578 PORT_Free(policyItem.data); | |
579 } | |
580 | |
581 if ( policies != NULL ) { | |
582 CERT_DestroyCertificatePoliciesExtension(policies); | |
583 } | |
584 | |
585 if ( retstring == NULL ) { | |
586 retstring = CERT_FindNSStringExtension(cert, | |
587 SEC_OID_NS_CERT_EXT_COMMENT); | |
588 } | |
589 | |
590 if ( retstring != NULL ) { | |
591 breakLines(retstring); | |
592 } | |
593 | |
594 return(retstring); | |
595 } | |
596 | |
597 | |
598 const SEC_ASN1Template CERT_OidSeqTemplate[] = { | |
599 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, | |
600 offsetof(CERTOidSequence, oids), | |
601 SEC_ASN1_SUB(SEC_ObjectIDTemplate) } | |
602 }; | |
603 | |
604 CERTOidSequence * | |
605 CERT_DecodeOidSequence(const SECItem *seqItem) | |
606 { | |
607 PLArenaPool *arena = NULL; | |
608 SECStatus rv; | |
609 CERTOidSequence *oidSeq; | |
610 SECItem newSeqItem; | |
611 | |
612 /* make a new arena */ | |
613 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
614 | |
615 if ( !arena ) { | |
616 goto loser; | |
617 } | |
618 | |
619 /* allocate the userNotice structure */ | |
620 oidSeq = (CERTOidSequence *)PORT_ArenaZAlloc(arena, | |
621 sizeof(CERTOidSequence)); | |
622 | |
623 if ( oidSeq == NULL ) { | |
624 goto loser; | |
625 } | |
626 | |
627 oidSeq->arena = arena; | |
628 | |
629 /* copy the DER into the arena, since Quick DER returns data that points | |
630 into the DER input, which may get freed by the caller */ | |
631 rv = SECITEM_CopyItem(arena, &newSeqItem, seqItem); | |
632 if ( rv != SECSuccess ) { | |
633 goto loser; | |
634 } | |
635 | |
636 /* decode the user notice */ | |
637 rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem); | |
638 | |
639 if ( rv != SECSuccess ) { | |
640 goto loser; | |
641 } | |
642 | |
643 return(oidSeq); | |
644 | |
645 loser: | |
646 if (arena) { | |
647 PORT_FreeArena(arena, PR_FALSE); | |
648 } | |
649 return(NULL); | |
650 } | |
651 | |
652 | |
653 void | |
654 CERT_DestroyOidSequence(CERTOidSequence *oidSeq) | |
655 { | |
656 if ( oidSeq != NULL ) { | |
657 PORT_FreeArena(oidSeq->arena, PR_FALSE); | |
658 } | |
659 return; | |
660 } | |
661 | |
662 PRBool | |
663 CERT_GovtApprovedBitSet(CERTCertificate *cert) | |
664 { | |
665 SECStatus rv; | |
666 SECItem extItem; | |
667 CERTOidSequence *oidSeq = NULL; | |
668 PRBool ret; | |
669 SECItem **oids; | |
670 SECItem *oid; | |
671 SECOidTag oidTag; | |
672 | |
673 extItem.data = NULL; | |
674 rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem); | |
675 if ( rv != SECSuccess ) { | |
676 goto loser; | |
677 } | |
678 | |
679 oidSeq = CERT_DecodeOidSequence(&extItem); | |
680 if ( oidSeq == NULL ) { | |
681 goto loser; | |
682 } | |
683 | |
684 oids = oidSeq->oids; | |
685 while ( oids != NULL && *oids != NULL ) { | |
686 oid = *oids; | |
687 | |
688 oidTag = SECOID_FindOIDTag(oid); | |
689 | |
690 if ( oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED ) { | |
691 goto success; | |
692 } | |
693 | |
694 oids++; | |
695 } | |
696 | |
697 loser: | |
698 ret = PR_FALSE; | |
699 goto done; | |
700 success: | |
701 ret = PR_TRUE; | |
702 done: | |
703 if ( oidSeq != NULL ) { | |
704 CERT_DestroyOidSequence(oidSeq); | |
705 } | |
706 if (extItem.data != NULL) { | |
707 PORT_Free(extItem.data); | |
708 } | |
709 return(ret); | |
710 } | |
711 | |
712 | |
713 SECStatus | |
714 CERT_EncodePolicyConstraintsExtension(PLArenaPool *arena, | |
715 CERTCertificatePolicyConstraints *constr, | |
716 SECItem *dest) | |
717 { | |
718 SECStatus rv = SECSuccess; | |
719 | |
720 PORT_Assert(constr != NULL && dest != NULL); | |
721 if (constr == NULL || dest == NULL) { | |
722 return SECFailure; | |
723 } | |
724 | |
725 if (SEC_ASN1EncodeItem (arena, dest, constr, | |
726 CERT_PolicyConstraintsTemplate) == NULL) { | |
727 rv = SECFailure; | |
728 } | |
729 return(rv); | |
730 } | |
731 | |
732 SECStatus | |
733 CERT_EncodePolicyMappingExtension(PLArenaPool *arena, | |
734 CERTCertificatePolicyMappings *mapping, | |
735 SECItem *dest) | |
736 { | |
737 SECStatus rv = SECSuccess; | |
738 | |
739 PORT_Assert(mapping != NULL && dest != NULL); | |
740 if (mapping == NULL || dest == NULL) { | |
741 return SECFailure; | |
742 } | |
743 | |
744 if (SEC_ASN1EncodeItem (arena, dest, mapping, | |
745 CERT_PolicyMappingsTemplate) == NULL) { | |
746 rv = SECFailure; | |
747 } | |
748 return(rv); | |
749 } | |
750 | |
751 | |
752 | |
753 SECStatus | |
754 CERT_EncodeCertPoliciesExtension(PLArenaPool *arena, | |
755 CERTPolicyInfo **info, | |
756 SECItem *dest) | |
757 { | |
758 SECStatus rv = SECSuccess; | |
759 | |
760 PORT_Assert(info != NULL && dest != NULL); | |
761 if (info == NULL || dest == NULL) { | |
762 return SECFailure; | |
763 } | |
764 | |
765 if (SEC_ASN1EncodeItem (arena, dest, info, | |
766 CERT_CertificatePoliciesTemplate) == NULL) { | |
767 rv = SECFailure; | |
768 } | |
769 return(rv); | |
770 } | |
771 | |
772 SECStatus | |
773 CERT_EncodeUserNotice(PLArenaPool *arena, | |
774 CERTUserNotice *notice, | |
775 SECItem *dest) | |
776 { | |
777 SECStatus rv = SECSuccess; | |
778 | |
779 PORT_Assert(notice != NULL && dest != NULL); | |
780 if (notice == NULL || dest == NULL) { | |
781 return SECFailure; | |
782 } | |
783 | |
784 if (SEC_ASN1EncodeItem(arena, dest, | |
785 notice, CERT_UserNoticeTemplate) == NULL) { | |
786 rv = SECFailure; | |
787 } | |
788 | |
789 return(rv); | |
790 } | |
791 | |
792 SECStatus | |
793 CERT_EncodeNoticeReference(PLArenaPool *arena, | |
794 CERTNoticeReference *reference, | |
795 SECItem *dest) | |
796 { | |
797 SECStatus rv = SECSuccess; | |
798 | |
799 PORT_Assert(reference != NULL && dest != NULL); | |
800 if (reference == NULL || dest == NULL) { | |
801 return SECFailure; | |
802 } | |
803 | |
804 if (SEC_ASN1EncodeItem (arena, dest, reference, | |
805 CERT_NoticeReferenceTemplate) == NULL) { | |
806 rv = SECFailure; | |
807 } | |
808 | |
809 return(rv); | |
810 } | |
811 | |
812 SECStatus | |
813 CERT_EncodeInhibitAnyExtension(PLArenaPool *arena, | |
814 CERTCertificateInhibitAny *certInhibitAny, | |
815 SECItem *dest) | |
816 { | |
817 SECStatus rv = SECSuccess; | |
818 | |
819 PORT_Assert(certInhibitAny != NULL && dest != NULL); | |
820 if (certInhibitAny == NULL || dest == NULL) { | |
821 return SECFailure; | |
822 } | |
823 | |
824 if (SEC_ASN1EncodeItem (arena, dest, certInhibitAny, | |
825 CERT_InhibitAnyTemplate) == NULL) { | |
826 rv = SECFailure; | |
827 } | |
828 return(rv); | |
829 } |