Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * pkix_pl_cert.c
6 *
7 * Certificate Object Functions
8 *
9 */
10
11 #include "pkix_pl_cert.h"
12
13 extern PKIX_PL_HashTable *cachedCertSigTable;
14
15 /* --Private-Cert-Functions------------------------------------- */
16
17 /*
18 * FUNCTION: pkix_pl_Cert_IsExtensionCritical
19 * DESCRIPTION:
20 *
21 * Checks the Cert specified by "cert" to determine whether the extension
22 * whose tag is the UInt32 value given by "tag" is marked as a critical
23 * extension, and stores the result in "pCritical".
24 *
25 * Tags are the index into the table "oids" of SECOidData defined in the
26 * file secoid.c. Constants, such as SEC_OID_X509_CERTIFICATE_POLICIES, are
27 * are defined in secoidt.h for most of the table entries.
28 *
29 * If the specified tag is invalid (not in the list of tags) or if the
30 * extension is not found in the certificate, PKIX_FALSE is stored.
31 *
32 * PARAMETERS
33 * "cert"
34 * Address of Cert whose extensions are to be examined. Must be non-NULL.
35 * "tag"
36 * The UInt32 value of the tag for the extension whose criticality is
37 * to be determined
38 * "pCritical"
39 * Address where the Boolean value will be stored. Must be non-NULL.
40 * "plContext"
41 * Platform-specific context pointer.
42 * THREAD SAFETY:
43 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
44 * RETURNS:
45 * Returns NULL if the function succeeds.
46 * Returns a Fatal Error if the function fails in an unrecoverable way.
47 */
48 static PKIX_Error *
49 pkix_pl_Cert_IsExtensionCritical(
50 PKIX_PL_Cert *cert,
51 PKIX_UInt32 tag,
52 PKIX_Boolean *pCritical,
53 void *plContext)
54 {
55 PKIX_Boolean criticality = PKIX_FALSE;
56 CERTCertExtension **extensions = NULL;
57 SECStatus rv;
58
59 PKIX_ENTER(CERT, "pkix_pl_Cert_IsExtensionCritical");
60 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCritical);
61
62 extensions = cert->nssCert->extensions;
63 PKIX_NULLCHECK_ONE(extensions);
64
65 PKIX_CERT_DEBUG("\t\tCalling CERT_GetExtenCriticality).\n");
66 rv = CERT_GetExtenCriticality(extensions, tag, &criticality);
67 if (SECSuccess == rv) {
68 *pCritical = criticality;
69 } else {
70 *pCritical = PKIX_FALSE;
71 }
72
73 PKIX_RETURN(CERT);
74 }
75
76 /*
77 * FUNCTION: pkix_pl_Cert_DecodePolicyInfo
78 * DESCRIPTION:
79 *
80 * Decodes the contents of the CertificatePolicy extension in the
81 * CERTCertificate pointed to by "nssCert", to create a List of
82 * CertPolicyInfos, which is stored at the address "pCertPolicyInfos".
83 * A CERTCertificate contains the DER representation of the Cert.
84 * If this certificate does not have a CertificatePolicy extension,
85 * NULL will be stored. If a List is returned, it will be immutable.
86 *
87 * PARAMETERS
88 * "nssCert"
89 * Address of the Cert data whose extension is to be examined. Must be
90 * non-NULL.
91 * "pCertPolicyInfos"
92 * Address where the List of CertPolicyInfos will be stored. Must be
93 * non-NULL.
94 * "plContext"
95 * Platform-specific context pointer.
96 * THREAD SAFETY:
97 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
98 * RETURNS:
99 * Returns NULL if the function succeeds.
100 * Returns a Cert Error if the function fails in a non-fatal way.
101 * Returns a Fatal Error if the function fails in an unrecoverable way.
102 */
103 static PKIX_Error *
104 pkix_pl_Cert_DecodePolicyInfo(
105 CERTCertificate *nssCert,
106 PKIX_List **pCertPolicyInfos,
107 void *plContext)
108 {
109
110 SECStatus rv;
111 SECItem encodedCertPolicyInfo;
112
113 /* Allocated in the arena; freed in CERT_Destroy... */
114 CERTCertificatePolicies *certPol = NULL;
115 CERTPolicyInfo **policyInfos = NULL;
116
117 /* Holder for the return value */
118 PKIX_List *infos = NULL;
119
120 PKIX_PL_OID *pkixOID = NULL;
121 PKIX_List *qualifiers = NULL;
122 PKIX_PL_CertPolicyInfo *certPolicyInfo = NULL;
123 PKIX_PL_CertPolicyQualifier *certPolicyQualifier = NULL;
124 PKIX_PL_ByteArray *qualifierArray = NULL;
125
126 PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyInfo");
127 PKIX_NULLCHECK_TWO(nssCert, pCertPolicyInfos);
128
129 /* get PolicyInfo as a SECItem */
130 PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
131 rv = CERT_FindCertExtension
132 (nssCert,
133 SEC_OID_X509_CERTIFICATE_POLICIES,
134 &encodedCertPolicyInfo);
135 if (SECSuccess != rv) {
136 *pCertPolicyInfos = NULL;
137 goto cleanup;
138 }
139
140 /* translate PolicyInfo to CERTCertificatePolicies */
141 PKIX_CERT_DEBUG("\t\tCERT_DecodeCertificatePoliciesExtension).\n");
142 certPol = CERT_DecodeCertificatePoliciesExtension
143 (&encodedCertPolicyInfo);
144
145 PORT_Free(encodedCertPolicyInfo.data);
146
147 if (NULL == certPol) {
148 PKIX_ERROR(PKIX_CERTDECODECERTIFICATEPOLICIESEXTENSIONFAILED);
149 }
150
151 /*
152 * Check whether there are any policyInfos, so we can
153 * avoid creating an unnecessary List
154 */
155 policyInfos = certPol->policyInfos;
156 if (!policyInfos) {
157 *pCertPolicyInfos = NULL;
158 goto cleanup;
159 }
160
161 /* create a List of CertPolicyInfo Objects */
162 PKIX_CHECK(PKIX_List_Create(&infos, plContext),
163 PKIX_LISTCREATEFAILED);
164
165 /*
166 * Traverse the CERTCertificatePolicies structure,
167 * building each PKIX_PL_CertPolicyInfo object in turn
168 */
169 while (*policyInfos != NULL) {
170 CERTPolicyInfo *policyInfo = *policyInfos;
171 CERTPolicyQualifier **policyQualifiers =
172 policyInfo->policyQualifiers;
173 if (policyQualifiers) {
174 /* create a PKIX_List of PKIX_PL_CertPolicyQualifiers */
175 PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
176 PKIX_LISTCREATEFAILED);
177
178 while (*policyQualifiers != NULL) {
179 CERTPolicyQualifier *policyQualifier =
180 *policyQualifiers;
181
182 /* create the qualifier's OID object */
183 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
184 (&policyQualifier->qualifierID,
185 &pkixOID, plContext),
186 PKIX_OIDCREATEFAILED);
187
188 /* create qualifier's ByteArray object */
189
190 PKIX_CHECK(PKIX_PL_ByteArray_Create
191 (policyQualifier->qualifierValue.data,
192 policyQualifier->qualifierValue.len,
193 &qualifierArray,
194 plContext),
195 PKIX_BYTEARRAYCREATEFAILED);
196
197 /* create a CertPolicyQualifier object */
198
199 PKIX_CHECK(pkix_pl_CertPolicyQualifier_Create
200 (pkixOID,
201 qualifierArray,
202 &certPolicyQualifier,
203 plContext),
204 PKIX_CERTPOLICYQUALIFIERCREATEFAILED);
205
206 PKIX_CHECK(PKIX_List_AppendItem
207 (qualifiers,
208 (PKIX_PL_Object *)certPolicyQualifier,
209 plContext),
210 PKIX_LISTAPPENDITEMFAILED);
211
212 PKIX_DECREF(pkixOID);
213 PKIX_DECREF(qualifierArray);
214 PKIX_DECREF(certPolicyQualifier);
215
216 policyQualifiers++;
217 }
218
219 PKIX_CHECK(PKIX_List_SetImmutable
220 (qualifiers, plContext),
221 PKIX_LISTSETIMMUTABLEFAILED);
222 }
223
224
225 /*
226 * Create an OID object pkixOID from policyInfo->policyID.
227 * (The CERTPolicyInfo structure has an oid field, but it
228 * is of type SECOidTag. This function wants a SECItem.)
229 */
230 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
231 (&policyInfo->policyID, &pkixOID, plContext),
232 PKIX_OIDCREATEFAILED);
233
234 /* Create a CertPolicyInfo object */
235 PKIX_CHECK(pkix_pl_CertPolicyInfo_Create
236 (pkixOID, qualifiers, &certPolicyInfo, plContext),
237 PKIX_CERTPOLICYINFOCREATEFAILED);
238
239 /* Append the new CertPolicyInfo object to the list */
240 PKIX_CHECK(PKIX_List_AppendItem
241 (infos, (PKIX_PL_Object *)certPolicyInfo, plContext),
242 PKIX_LISTAPPENDITEMFAILED);
243
244 PKIX_DECREF(pkixOID);
245 PKIX_DECREF(qualifiers);
246 PKIX_DECREF(certPolicyInfo);
247
248 policyInfos++;
249 }
250
251 /*
252 * If there were no policies, we went straight to
253 * cleanup, so we don't have to NULLCHECK infos.
254 */
255 PKIX_CHECK(PKIX_List_SetImmutable(infos, plContext),
256 PKIX_LISTSETIMMUTABLEFAILED);
257
258 *pCertPolicyInfos = infos;
259 infos = NULL;
260
261 cleanup:
262 if (certPol) {
263 PKIX_CERT_DEBUG
264 ("\t\tCalling CERT_DestroyCertificatePoliciesExtension).\n");
265 CERT_DestroyCertificatePoliciesExtension(certPol);
266 }
267
268 PKIX_DECREF(infos);
269 PKIX_DECREF(pkixOID);
270 PKIX_DECREF(qualifiers);
271 PKIX_DECREF(certPolicyInfo);
272 PKIX_DECREF(certPolicyQualifier);
273 PKIX_DECREF(qualifierArray);
274
275 PKIX_RETURN(CERT);
276 }
277
278 /*
279 * FUNCTION: pkix_pl_Cert_DecodePolicyMapping
280 * DESCRIPTION:
281 *
282 * Decodes the contents of the PolicyMapping extension of the CERTCertificate
283 * pointed to by "nssCert", storing the resulting List of CertPolicyMaps at
284 * the address pointed to by "pCertPolicyMaps". If this certificate does not
285 * have a PolicyMapping extension, NULL will be stored. If a List is returned,
286 * it will be immutable.
287 *
288 * PARAMETERS
289 * "nssCert"
290 * Address of the Cert data whose extension is to be examined. Must be
291 * non-NULL.
292 * "pCertPolicyMaps"
293 * Address where the List of CertPolicyMaps will be stored. Must be
294 * non-NULL.
295 * "plContext"
296 * Platform-specific context pointer.
297 * THREAD SAFETY:
298 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
299 * RETURNS:
300 * Returns NULL if the function succeeds.
301 * Returns a Cert Error if the function fails in a non-fatal way.
302 * Returns a Fatal Error if the function fails in an unrecoverable way.
303 */
304 static PKIX_Error *
305 pkix_pl_Cert_DecodePolicyMapping(
306 CERTCertificate *nssCert,
307 PKIX_List **pCertPolicyMaps,
308 void *plContext)
309 {
310 SECStatus rv;
311 SECItem encodedCertPolicyMaps;
312
313 /* Allocated in the arena; freed in CERT_Destroy... */
314 CERTCertificatePolicyMappings *certPolMaps = NULL;
315 CERTPolicyMap **policyMaps = NULL;
316
317 /* Holder for the return value */
318 PKIX_List *maps = NULL;
319
320 PKIX_PL_OID *issuerDomainOID = NULL;
321 PKIX_PL_OID *subjectDomainOID = NULL;
322 PKIX_PL_CertPolicyMap *certPolicyMap = NULL;
323
324 PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyMapping");
325 PKIX_NULLCHECK_TWO(nssCert, pCertPolicyMaps);
326
327 /* get PolicyMappings as a SECItem */
328 PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
329 rv = CERT_FindCertExtension
330 (nssCert, SEC_OID_X509_POLICY_MAPPINGS, &encodedCertPolicyMaps);
331 if (SECSuccess != rv) {
332 *pCertPolicyMaps = NULL;
333 goto cleanup;
334 }
335
336 /* translate PolicyMaps to CERTCertificatePolicyMappings */
337 certPolMaps = CERT_DecodePolicyMappingsExtension
338 (&encodedCertPolicyMaps);
339
340 PORT_Free(encodedCertPolicyMaps.data);
341
342 if (!certPolMaps) {
343 PKIX_ERROR(PKIX_CERTDECODEPOLICYMAPPINGSEXTENSIONFAILED);
344 }
345
346 PKIX_NULLCHECK_ONE(certPolMaps->policyMaps);
347
348 policyMaps = certPolMaps->policyMaps;
349
350 /* create a List of CertPolicyMap Objects */
351 PKIX_CHECK(PKIX_List_Create(&maps, plContext),
352 PKIX_LISTCREATEFAILED);
353
354 /*
355 * Traverse the CERTCertificatePolicyMappings structure,
356 * building each CertPolicyMap object in turn
357 */
358 do {
359 CERTPolicyMap *policyMap = *policyMaps;
360
361 /* create the OID for the issuer Domain Policy */
362 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
363 (&policyMap->issuerDomainPolicy,
364 &issuerDomainOID, plContext),
365 PKIX_OIDCREATEFAILED);
366
367 /* create the OID for the subject Domain Policy */
368 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
369 (&policyMap->subjectDomainPolicy,
370 &subjectDomainOID, plContext),
371 PKIX_OIDCREATEFAILED);
372
373 /* create the CertPolicyMap */
374
375 PKIX_CHECK(pkix_pl_CertPolicyMap_Create
376 (issuerDomainOID,
377 subjectDomainOID,
378 &certPolicyMap,
379 plContext),
380 PKIX_CERTPOLICYMAPCREATEFAILED);
381
382 PKIX_CHECK(PKIX_List_AppendItem
383 (maps, (PKIX_PL_Object *)certPolicyMap, plContext),
384 PKIX_LISTAPPENDITEMFAILED);
385
386 PKIX_DECREF(issuerDomainOID);
387 PKIX_DECREF(subjectDomainOID);
388 PKIX_DECREF(certPolicyMap);
389
390 policyMaps++;
391 } while (*policyMaps != NULL);
392
393 PKIX_CHECK(PKIX_List_SetImmutable(maps, plContext),
394 PKIX_LISTSETIMMUTABLEFAILED);
395
396 *pCertPolicyMaps = maps;
397 maps = NULL;
398
399 cleanup:
400 if (certPolMaps) {
401 PKIX_CERT_DEBUG
402 ("\t\tCalling CERT_DestroyPolicyMappingsExtension).\n");
403 CERT_DestroyPolicyMappingsExtension(certPolMaps);
404 }
405
406 PKIX_DECREF(maps);
407 PKIX_DECREF(issuerDomainOID);
408 PKIX_DECREF(subjectDomainOID);
409 PKIX_DECREF(certPolicyMap);
410
411 PKIX_RETURN(CERT);
412 }
413
414 /*
415 * FUNCTION: pkix_pl_Cert_DecodePolicyConstraints
416 * DESCRIPTION:
417 *
418 * Decodes the contents of the PolicyConstraints extension in the
419 * CERTCertificate pointed to by "nssCert", to obtain SkipCerts values
420 * which are stored at the addresses "pExplicitPolicySkipCerts" and
421 * "pInhibitMappingSkipCerts", respectively. If this certificate does
422 * not have an PolicyConstraints extension, or if either of the optional
423 * components is not supplied, this function stores a value of -1 for any
424 * missing component.
425 *
426 * PARAMETERS
427 * "nssCert"
428 * Address of the Cert data whose extension is to be examined. Must be
429 * non-NULL.
430 * "pExplicitPolicySkipCerts"
431 * Address where the SkipCert value for the requireExplicitPolicy
432 * component will be stored. Must be non-NULL.
433 * "pInhibitMappingSkipCerts"
434 * Address where the SkipCert value for the inhibitPolicyMapping
435 * component will be stored. Must be non-NULL.
436 * "plContext"
437 * Platform-specific context pointer.
438 * THREAD SAFETY:
439 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
440 * RETURNS:
441 * Returns NULL if the function succeeds.
442 * Returns a Cert Error if the function fails in a non-fatal way.
443 * Returns a Fatal Error if the function fails in an unrecoverable way.
444 */
445 static PKIX_Error *
446 pkix_pl_Cert_DecodePolicyConstraints(
447 CERTCertificate *nssCert,
448 PKIX_Int32 *pExplicitPolicySkipCerts,
449 PKIX_Int32 *pInhibitMappingSkipCerts,
450 void *plContext)
451 {
452 CERTCertificatePolicyConstraints policyConstraints;
453 SECStatus rv;
454 SECItem encodedCertPolicyConstraints;
455 PKIX_Int32 explicitPolicySkipCerts = -1;
456 PKIX_Int32 inhibitMappingSkipCerts = -1;
457
458 PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyConstraints");
459 PKIX_NULLCHECK_THREE
460 (nssCert, pExplicitPolicySkipCerts, pInhibitMappingSkipCerts);
461
462 /* get the two skipCert values as SECItems */
463 PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
464 rv = CERT_FindCertExtension
465 (nssCert,
466 SEC_OID_X509_POLICY_CONSTRAINTS,
467 &encodedCertPolicyConstraints);
468
469 if (rv == SECSuccess) {
470
471 policyConstraints.explicitPolicySkipCerts.data =
472 (unsigned char *)&explicitPolicySkipCerts;
473 policyConstraints.inhibitMappingSkipCerts.data =
474 (unsigned char *)&inhibitMappingSkipCerts;
475
476 /* translate DER to CERTCertificatePolicyConstraints */
477 rv = CERT_DecodePolicyConstraintsExtension
478 (&policyConstraints, &encodedCertPolicyConstraints);
479
480 PORT_Free(encodedCertPolicyConstraints.data);
481
482 if (rv != SECSuccess) {
483 PKIX_ERROR
484 (PKIX_CERTDECODEPOLICYCONSTRAINTSEXTENSIONFAILED);
485 }
486 }
487
488 *pExplicitPolicySkipCerts = explicitPolicySkipCerts;
489 *pInhibitMappingSkipCerts = inhibitMappingSkipCerts;
490
491 cleanup:
492 PKIX_RETURN(CERT);
493 }
494
495 /*
496 * FUNCTION: pkix_pl_Cert_DecodeInhibitAnyPolicy
497 * DESCRIPTION:
498 *
499 * Decodes the contents of the InhibitAnyPolicy extension in the
500 * CERTCertificate pointed to by "nssCert", to obtain a SkipCerts value,
501 * which is stored at the address "pSkipCerts". If this certificate does
502 * not have an InhibitAnyPolicy extension, -1 will be stored.
503 *
504 * PARAMETERS
505 * "nssCert"
506 * Address of the Cert data whose InhibitAnyPolicy extension is to be
507 * processed. Must be non-NULL.
508 * "pSkipCerts"
509 * Address where the SkipCert value from the InhibitAnyPolicy extension
510 * will be stored. Must be non-NULL.
511 * "plContext"
512 * Platform-specific context pointer.
513 * THREAD SAFETY:
514 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
515 * RETURNS:
516 * Returns NULL if the function succeeds.
517 * Returns a Cert Error if the function fails in a non-fatal way.
518 * Returns a Fatal Error if the function fails in an unrecoverable way.
519 */
520 PKIX_Error *
521 pkix_pl_Cert_DecodeInhibitAnyPolicy(
522 CERTCertificate *nssCert,
523 PKIX_Int32 *pSkipCerts,
524 void *plContext)
525 {
526 CERTCertificateInhibitAny inhibitAny;
527 SECStatus rv;
528 SECItem encodedCertInhibitAny;
529 PKIX_Int32 skipCerts = -1;
530
531 PKIX_ENTER(CERT, "pkix_pl_Cert_DecodeInhibitAnyPolicy");
532 PKIX_NULLCHECK_TWO(nssCert, pSkipCerts);
533
534 /* get InhibitAny as a SECItem */
535 PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
536 rv = CERT_FindCertExtension
537 (nssCert, SEC_OID_X509_INHIBIT_ANY_POLICY, &encodedCertInhibitAn y);
538
539 if (rv == SECSuccess) {
540 inhibitAny.inhibitAnySkipCerts.data =
541 (unsigned char *)&skipCerts;
542
543 /* translate DER to CERTCertificateInhibitAny */
544 rv = CERT_DecodeInhibitAnyExtension
545 (&inhibitAny, &encodedCertInhibitAny);
546
547 PORT_Free(encodedCertInhibitAny.data);
548
549 if (rv != SECSuccess) {
550 PKIX_ERROR(PKIX_CERTDECODEINHIBITANYEXTENSIONFAILED);
551 }
552 }
553
554 *pSkipCerts = skipCerts;
555
556 cleanup:
557 PKIX_RETURN(CERT);
558 }
559
560 /*
561 * FUNCTION: pkix_pl_Cert_GetNssSubjectAltNames
562 * DESCRIPTION:
563 *
564 * Retrieves the Subject Alternative Names of the certificate specified by
565 * "cert" and stores it at "pNssSubjAltNames". If the Subject Alternative
566 * Name extension is not present, NULL is returned at "pNssSubjAltNames".
567 * If the Subject Alternative Names has not been previously decoded, it is
568 * decoded here with lock on the "cert" unless the flag "hasLock" indicates
569 * the lock had been obtained at a higher call level.
570 *
571 * PARAMETERS
572 * "cert"
573 * Address of the certificate whose Subject Alternative Names extensions
574 * is retrieved. Must be non-NULL.
575 * "hasLock"
576 * Boolean indicates caller has acquired a lock.
577 * Must be non-NULL.
578 * "pNssSubjAltNames"
579 * Address where the returned Subject Alternative Names will be stored.
580 * Must be non-NULL.
581 * "plContext"
582 * Platform-specific context pointer.
583 * THREAD SAFETY:
584 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
585 * RETURNS:
586 * Returns NULL if the function succeeds.
587 * Returns a Cert Error if the function fails in a non-fatal way.
588 * Returns a Fatal Error if the function fails in an unrecoverable way.
589 */
590 static PKIX_Error *
591 pkix_pl_Cert_GetNssSubjectAltNames(
592 PKIX_PL_Cert *cert,
593 PKIX_Boolean hasLock,
594 CERTGeneralName **pNssSubjAltNames,
595 void *plContext)
596 {
597 CERTCertificate *nssCert = NULL;
598 CERTGeneralName *nssOriginalAltName = NULL;
599 PLArenaPool *arena = NULL;
600 SECItem altNameExtension = {siBuffer, NULL, 0};
601 SECStatus rv = SECFailure;
602
603 PKIX_ENTER(CERT, "pkix_pl_Cert_GetNssSubjectAltNames");
604 PKIX_NULLCHECK_THREE(cert, pNssSubjAltNames, cert->nssCert);
605
606 nssCert = cert->nssCert;
607
608 if ((cert->nssSubjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
609
610 if (!hasLock) {
611 PKIX_OBJECT_LOCK(cert);
612 }
613
614 if ((cert->nssSubjAltNames == NULL) &&
615 (!cert->subjAltNamesAbsent)){
616
617 PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
618 (nssCert,
619 SEC_OID_X509_SUBJECT_ALT_NAME,
620 &altNameExtension));
621
622 if (rv != SECSuccess) {
623 *pNssSubjAltNames = NULL;
624 cert->subjAltNamesAbsent = PKIX_TRUE;
625 goto cleanup;
626 }
627
628 if (cert->arenaNameConstraints == NULL) {
629 PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
630 (DER_DEFAULT_CHUNKSIZE));
631
632 if (arena == NULL) {
633 PKIX_ERROR(PKIX_OUTOFMEMORY);
634 }
635 cert->arenaNameConstraints = arena;
636 }
637
638 PKIX_PL_NSSCALLRV
639 (CERT,
640 nssOriginalAltName,
641 (CERTGeneralName *) CERT_DecodeAltNameExtension,
642 (cert->arenaNameConstraints, &altNameExtension));
643
644 PKIX_PL_NSSCALL(CERT, PORT_Free, (altNameExtension.data));
645
646 if (nssOriginalAltName == NULL) {
647 PKIX_ERROR(PKIX_CERTDECODEALTNAMEEXTENSIONFAILED);
648 }
649 cert->nssSubjAltNames = nssOriginalAltName;
650
651 }
652
653 if (!hasLock) {
654 PKIX_OBJECT_UNLOCK(cert);
655 }
656 }
657
658 *pNssSubjAltNames = cert->nssSubjAltNames;
659
660 cleanup:
661 PKIX_OBJECT_UNLOCK(lockedObject);
662 PKIX_RETURN(CERT);
663 }
664
665 /*
666 * FUNCTION: pkix_pl_Cert_CheckExtendKeyUsage
667 * DESCRIPTION:
668 *
669 * For each of the ON bit in "requiredExtendedKeyUsages" that represents its
670 * SECCertUsageEnum type, this function checks "cert"'s certType (extended
671 * key usage) and key usage with what is required for SECCertUsageEnum type.
672 *
673 * PARAMETERS
674 * "cert"
675 * Address of the certificate whose Extended Key Usage extensions
676 * is retrieved. Must be non-NULL.
677 * "requiredExtendedKeyUsages"
678 * An unsigned integer, its bit location is ON based on the required key
679 * usage value representing in SECCertUsageEnum.
680 * "pPass"
681 * Address where the return value, indicating key usage check passed, is
682 * stored. Must be non-NULL.
683 * "plContext"
684 * Platform-specific context pointer.
685 * THREAD SAFETY:
686 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
687 * RETURNS:
688 * Returns NULL if the function succeeds.
689 * Returns a Cert Error if the function fails in a non-fatal way.
690 * Returns a Fatal Error if the function fails in an unrecoverable way.
691 */
692 PKIX_Error *
693 pkix_pl_Cert_CheckExtendedKeyUsage(
694 PKIX_PL_Cert *cert,
695 PKIX_UInt32 requiredExtendedKeyUsages,
696 PKIX_Boolean *pPass,
697 void *plContext)
698 {
699 PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
700 PKIX_UInt32 certType = 0;
701 PKIX_UInt32 requiredKeyUsage = 0;
702 PKIX_UInt32 requiredCertType = 0;
703 PKIX_UInt32 requiredExtendedKeyUsage = 0;
704 PKIX_UInt32 i;
705 PKIX_Boolean isCA = PKIX_FALSE;
706 SECStatus rv = SECFailure;
707
708 PKIX_ENTER(CERT, "pkix_pl_Cert_CheckExtendKeyUsage");
709 PKIX_NULLCHECK_THREE(cert, pPass, cert->nssCert);
710
711 *pPass = PKIX_FALSE;
712
713 PKIX_CERT_DEBUG("\t\tCalling cert_GetCertType).\n");
714 cert_GetCertType(cert->nssCert);
715 certType = cert->nssCert->nsCertType;
716
717 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
718 (cert,
719 &basicConstraints,
720 plContext),
721 PKIX_CERTGETBASICCONSTRAINTFAILED);
722
723 if (basicConstraints != NULL) {
724 PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
725 (basicConstraints, &isCA, plContext),
726 PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
727 }
728
729 i = 0;
730 while (requiredExtendedKeyUsages != 0) {
731
732 /* Find the bit location of the right-most non-zero bit */
733 while (requiredExtendedKeyUsages != 0) {
734 if (((1 << i) & requiredExtendedKeyUsages) != 0) {
735 requiredExtendedKeyUsage = 1 << i;
736 break;
737 }
738 i++;
739 }
740 requiredExtendedKeyUsages ^= requiredExtendedKeyUsage;
741
742 requiredExtendedKeyUsage = i;
743
744 PKIX_PL_NSSCALLRV(CERT, rv, CERT_KeyUsageAndTypeForCertUsage,
745 (requiredExtendedKeyUsage,
746 isCA,
747 &requiredKeyUsage,
748 &requiredCertType));
749
750 if (!(certType & requiredCertType)) {
751 goto cleanup;
752 }
753
754 PKIX_PL_NSSCALLRV(CERT, rv, CERT_CheckKeyUsage,
755 (cert->nssCert, requiredKeyUsage));
756 if (rv != SECSuccess) {
757 goto cleanup;
758 }
759 i++;
760
761 }
762
763 *pPass = PKIX_TRUE;
764
765 cleanup:
766 PKIX_DECREF(basicConstraints);
767 PKIX_RETURN(CERT);
768 }
769
770 /*
771 * FUNCTION: pkix_pl_Cert_ToString_Helper
772 * DESCRIPTION:
773 *
774 * Helper function that creates a string representation of the Cert pointed
775 * to by "cert" and stores it at "pString", where the value of
776 * "partialString" determines whether a full or partial representation of
777 * the Cert is stored.
778 *
779 * PARAMETERS
780 * "cert"
781 * Address of Cert whose string representation is desired.
782 * Must be non-NULL.
783 * "partialString"
784 * Boolean indicating whether a partial Cert representation is desired.
785 * "pString"
786 * Address where object pointer will be stored. Must be non-NULL.
787 * "plContext"
788 * Platform-specific context pointer.
789 * THREAD SAFETY:
790 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
791 * RETURNS:
792 * Returns NULL if the function succeeds.
793 * Returns a Cert Error if the function fails in a non-fatal way.
794 * Returns a Fatal Error if the function fails in an unrecoverable way.
795 */
796 PKIX_Error *
797 pkix_pl_Cert_ToString_Helper(
798 PKIX_PL_Cert *cert,
799 PKIX_Boolean partialString,
800 PKIX_PL_String **pString,
801 void *plContext)
802 {
803 PKIX_PL_String *certString = NULL;
804 char *asciiFormat = NULL;
805 PKIX_PL_String *formatString = NULL;
806 PKIX_UInt32 certVersion;
807 PKIX_PL_BigInt *certSN = NULL;
808 PKIX_PL_String *certSNString = NULL;
809 PKIX_PL_X500Name *certIssuer = NULL;
810 PKIX_PL_String *certIssuerString = NULL;
811 PKIX_PL_X500Name *certSubject = NULL;
812 PKIX_PL_String *certSubjectString = NULL;
813 PKIX_PL_String *notBeforeString = NULL;
814 PKIX_PL_String *notAfterString = NULL;
815 PKIX_List *subjAltNames = NULL;
816 PKIX_PL_String *subjAltNamesString = NULL;
817 PKIX_PL_ByteArray *authKeyId = NULL;
818 PKIX_PL_String *authKeyIdString = NULL;
819 PKIX_PL_ByteArray *subjKeyId = NULL;
820 PKIX_PL_String *subjKeyIdString = NULL;
821 PKIX_PL_PublicKey *nssPubKey = NULL;
822 PKIX_PL_String *nssPubKeyString = NULL;
823 PKIX_List *critExtOIDs = NULL;
824 PKIX_PL_String *critExtOIDsString = NULL;
825 PKIX_List *extKeyUsages = NULL;
826 PKIX_PL_String *extKeyUsagesString = NULL;
827 PKIX_PL_CertBasicConstraints *basicConstraint = NULL;
828 PKIX_PL_String *certBasicConstraintsString = NULL;
829 PKIX_List *policyInfo = NULL;
830 PKIX_PL_String *certPolicyInfoString = NULL;
831 PKIX_List *certPolicyMappings = NULL;
832 PKIX_PL_String *certPolicyMappingsString = NULL;
833 PKIX_Int32 certExplicitPolicy = 0;
834 PKIX_Int32 certInhibitMapping = 0;
835 PKIX_Int32 certInhibitAnyPolicy = 0;
836 PKIX_PL_CertNameConstraints *nameConstraints = NULL;
837 PKIX_PL_String *nameConstraintsString = NULL;
838 PKIX_List *authorityInfoAccess = NULL;
839 PKIX_PL_String *authorityInfoAccessString = NULL;
840 PKIX_List *subjectInfoAccess = NULL;
841 PKIX_PL_String *subjectInfoAccessString = NULL;
842
843 PKIX_ENTER(CERT, "pkix_pl_Cert_ToString_Helper");
844 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pString);
845
846 /*
847 * XXX Add to this format as certificate components are developed.
848 */
849
850 if (partialString){
851 asciiFormat =
852 "\t[Issuer: %s\n"
853 "\t Subject: %s]";
854 } else {
855 asciiFormat =
856 "[\n"
857 "\tVersion: v%d\n"
858 "\tSerialNumber: %s\n"
859 "\tIssuer: %s\n"
860 "\tSubject: %s\n"
861 "\tValidity: [From: %s\n"
862 "\t To: %s]\n"
863 "\tSubjectAltNames: %s\n"
864 "\tAuthorityKeyId: %s\n"
865 "\tSubjectKeyId: %s\n"
866 "\tSubjPubKeyAlgId: %s\n"
867 "\tCritExtOIDs: %s\n"
868 "\tExtKeyUsages: %s\n"
869 "\tBasicConstraint: %s\n"
870 "\tCertPolicyInfo: %s\n"
871 "\tPolicyMappings: %s\n"
872 "\tExplicitPolicy: %d\n"
873 "\tInhibitMapping: %d\n"
874 "\tInhibitAnyPolicy:%d\n"
875 "\tNameConstraints: %s\n"
876 "\tAuthorityInfoAccess: %s\n"
877 "\tSubjectInfoAccess: %s\n"
878 "\tCacheFlag: %d\n"
879 "]\n";
880 }
881
882
883
884 PKIX_CHECK(PKIX_PL_String_Create
885 (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
886 PKIX_STRINGCREATEFAILED);
887
888 /* Issuer */
889 PKIX_CHECK(PKIX_PL_Cert_GetIssuer
890 (cert, &certIssuer, plContext),
891 PKIX_CERTGETISSUERFAILED);
892
893 PKIX_CHECK(PKIX_PL_Object_ToString
894 ((PKIX_PL_Object *)certIssuer, &certIssuerString, plContext),
895 PKIX_X500NAMETOSTRINGFAILED);
896
897 /* Subject */
898 PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &certSubject, plContext),
899 PKIX_CERTGETSUBJECTFAILED);
900
901 PKIX_TOSTRING(certSubject, &certSubjectString, plContext,
902 PKIX_X500NAMETOSTRINGFAILED);
903
904 if (partialString){
905 PKIX_CHECK(PKIX_PL_Sprintf
906 (&certString,
907 plContext,
908 formatString,
909 certIssuerString,
910 certSubjectString),
911 PKIX_SPRINTFFAILED);
912
913 *pString = certString;
914 goto cleanup;
915 }
916
917 /* Version */
918 PKIX_CHECK(PKIX_PL_Cert_GetVersion(cert, &certVersion, plContext),
919 PKIX_CERTGETVERSIONFAILED);
920
921 /* SerialNumber */
922 PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber(cert, &certSN, plContext),
923 PKIX_CERTGETSERIALNUMBERFAILED);
924
925 PKIX_CHECK(PKIX_PL_Object_ToString
926 ((PKIX_PL_Object *)certSN, &certSNString, plContext),
927 PKIX_BIGINTTOSTRINGFAILED);
928
929 /* Validity: NotBefore */
930 PKIX_CHECK(pkix_pl_Date_ToString_Helper
931 (&(cert->nssCert->validity.notBefore),
932 &notBeforeString,
933 plContext),
934 PKIX_DATETOSTRINGHELPERFAILED);
935
936 /* Validity: NotAfter */
937 PKIX_CHECK(pkix_pl_Date_ToString_Helper
938 (&(cert->nssCert->validity.notAfter),
939 &notAfterString,
940 plContext),
941 PKIX_DATETOSTRINGHELPERFAILED);
942
943 /* SubjectAltNames */
944 PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
945 (cert, &subjAltNames, plContext),
946 PKIX_CERTGETSUBJECTALTNAMESFAILED);
947
948 PKIX_TOSTRING(subjAltNames, &subjAltNamesString, plContext,
949 PKIX_LISTTOSTRINGFAILED);
950
951 /* AuthorityKeyIdentifier */
952 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
953 (cert, &authKeyId, plContext),
954 PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
955
956 PKIX_TOSTRING(authKeyId, &authKeyIdString, plContext,
957 PKIX_BYTEARRAYTOSTRINGFAILED);
958
959 /* SubjectKeyIdentifier */
960 PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
961 (cert, &subjKeyId, plContext),
962 PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
963
964 PKIX_TOSTRING(subjKeyId, &subjKeyIdString, plContext,
965 PKIX_BYTEARRAYTOSTRINGFAILED);
966
967 /* SubjectPublicKey */
968 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
969 (cert, &nssPubKey, plContext),
970 PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
971
972 PKIX_CHECK(PKIX_PL_Object_ToString
973 ((PKIX_PL_Object *)nssPubKey, &nssPubKeyString, plContext),
974 PKIX_PUBLICKEYTOSTRINGFAILED);
975
976 /* CriticalExtensionOIDs */
977 PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
978 (cert, &critExtOIDs, plContext),
979 PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED);
980
981 PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
982 PKIX_LISTTOSTRINGFAILED);
983
984 /* ExtendedKeyUsages */
985 PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
986 (cert, &extKeyUsages, plContext),
987 PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
988
989 PKIX_TOSTRING(extKeyUsages, &extKeyUsagesString, plContext,
990 PKIX_LISTTOSTRINGFAILED);
991
992 /* CertBasicConstraints */
993 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
994 (cert, &basicConstraint, plContext),
995 PKIX_CERTGETBASICCONSTRAINTSFAILED);
996
997 PKIX_TOSTRING(basicConstraint, &certBasicConstraintsString, plContext,
998 PKIX_CERTBASICCONSTRAINTSTOSTRINGFAILED);
999
1000 /* CertPolicyInfo */
1001 PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
1002 (cert, &policyInfo, plContext),
1003 PKIX_CERTGETPOLICYINFORMATIONFAILED);
1004
1005 PKIX_TOSTRING(policyInfo, &certPolicyInfoString, plContext,
1006 PKIX_LISTTOSTRINGFAILED);
1007
1008 /* Advanced Policies */
1009 PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings
1010 (cert, &certPolicyMappings, plContext),
1011 PKIX_CERTGETPOLICYMAPPINGSFAILED);
1012
1013 PKIX_TOSTRING(certPolicyMappings, &certPolicyMappingsString, plContext,
1014 PKIX_LISTTOSTRINGFAILED);
1015
1016 PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
1017 (cert, &certExplicitPolicy, plContext),
1018 PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
1019
1020 PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited
1021 (cert, &certInhibitMapping, plContext),
1022 PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED);
1023
1024 PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy
1025 (cert, &certInhibitAnyPolicy, plContext),
1026 PKIX_CERTGETINHIBITANYPOLICYFAILED);
1027
1028 /* Name Constraints */
1029 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
1030 (cert, &nameConstraints, plContext),
1031 PKIX_CERTGETNAMECONSTRAINTSFAILED);
1032
1033 PKIX_TOSTRING(nameConstraints, &nameConstraintsString, plContext,
1034 PKIX_LISTTOSTRINGFAILED);
1035
1036 /* Authority Information Access */
1037 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
1038 (cert, &authorityInfoAccess, plContext),
1039 PKIX_CERTGETAUTHORITYINFOACCESSFAILED);
1040
1041 PKIX_TOSTRING(authorityInfoAccess, &authorityInfoAccessString, plContext ,
1042 PKIX_LISTTOSTRINGFAILED);
1043
1044 /* Subject Information Access */
1045 PKIX_CHECK(PKIX_PL_Cert_GetSubjectInfoAccess
1046 (cert, &subjectInfoAccess, plContext),
1047 PKIX_CERTGETSUBJECTINFOACCESSFAILED);
1048
1049 PKIX_TOSTRING(subjectInfoAccess, &subjectInfoAccessString, plContext,
1050 PKIX_LISTTOSTRINGFAILED);
1051
1052 PKIX_CHECK(PKIX_PL_Sprintf
1053 (&certString,
1054 plContext,
1055 formatString,
1056 certVersion + 1,
1057 certSNString,
1058 certIssuerString,
1059 certSubjectString,
1060 notBeforeString,
1061 notAfterString,
1062 subjAltNamesString,
1063 authKeyIdString,
1064 subjKeyIdString,
1065 nssPubKeyString,
1066 critExtOIDsString,
1067 extKeyUsagesString,
1068 certBasicConstraintsString,
1069 certPolicyInfoString,
1070 certPolicyMappingsString,
1071 certExplicitPolicy, /* an Int32, not a String */
1072 certInhibitMapping, /* an Int32, not a String */
1073 certInhibitAnyPolicy, /* an Int32, not a String */
1074 nameConstraintsString,
1075 authorityInfoAccessString,
1076 subjectInfoAccessString,
1077 cert->cacheFlag), /* a boolean */
1078 PKIX_SPRINTFFAILED);
1079
1080 *pString = certString;
1081
1082 cleanup:
1083 PKIX_DECREF(certSN);
1084 PKIX_DECREF(certSNString);
1085 PKIX_DECREF(certIssuer);
1086 PKIX_DECREF(certIssuerString);
1087 PKIX_DECREF(certSubject);
1088 PKIX_DECREF(certSubjectString);
1089 PKIX_DECREF(notBeforeString);
1090 PKIX_DECREF(notAfterString);
1091 PKIX_DECREF(subjAltNames);
1092 PKIX_DECREF(subjAltNamesString);
1093 PKIX_DECREF(authKeyId);
1094 PKIX_DECREF(authKeyIdString);
1095 PKIX_DECREF(subjKeyId);
1096 PKIX_DECREF(subjKeyIdString);
1097 PKIX_DECREF(nssPubKey);
1098 PKIX_DECREF(nssPubKeyString);
1099 PKIX_DECREF(critExtOIDs);
1100 PKIX_DECREF(critExtOIDsString);
1101 PKIX_DECREF(extKeyUsages);
1102 PKIX_DECREF(extKeyUsagesString);
1103 PKIX_DECREF(basicConstraint);
1104 PKIX_DECREF(certBasicConstraintsString);
1105 PKIX_DECREF(policyInfo);
1106 PKIX_DECREF(certPolicyInfoString);
1107 PKIX_DECREF(certPolicyMappings);
1108 PKIX_DECREF(certPolicyMappingsString);
1109 PKIX_DECREF(nameConstraints);
1110 PKIX_DECREF(nameConstraintsString);
1111 PKIX_DECREF(authorityInfoAccess);
1112 PKIX_DECREF(authorityInfoAccessString);
1113 PKIX_DECREF(subjectInfoAccess);
1114 PKIX_DECREF(subjectInfoAccessString);
1115 PKIX_DECREF(formatString);
1116
1117 PKIX_RETURN(CERT);
1118 }
1119
1120 /*
1121 * FUNCTION: pkix_pl_Cert_Destroy
1122 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
1123 */
1124 static PKIX_Error *
1125 pkix_pl_Cert_Destroy(
1126 PKIX_PL_Object *object,
1127 void *plContext)
1128 {
1129 PKIX_PL_Cert *cert = NULL;
1130
1131 PKIX_ENTER(CERT, "pkix_pl_Cert_Destroy");
1132 PKIX_NULLCHECK_ONE(object);
1133
1134 PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
1135 PKIX_OBJECTNOTCERT);
1136
1137 cert = (PKIX_PL_Cert*)object;
1138
1139 PKIX_DECREF(cert->subject);
1140 PKIX_DECREF(cert->issuer);
1141 PKIX_DECREF(cert->subjAltNames);
1142 PKIX_DECREF(cert->publicKeyAlgId);
1143 PKIX_DECREF(cert->publicKey);
1144 PKIX_DECREF(cert->serialNumber);
1145 PKIX_DECREF(cert->critExtOids);
1146 PKIX_DECREF(cert->authKeyId);
1147 PKIX_DECREF(cert->subjKeyId);
1148 PKIX_DECREF(cert->extKeyUsages);
1149 PKIX_DECREF(cert->certBasicConstraints);
1150 PKIX_DECREF(cert->certPolicyInfos);
1151 PKIX_DECREF(cert->certPolicyMappings);
1152 PKIX_DECREF(cert->nameConstraints);
1153 PKIX_DECREF(cert->store);
1154 PKIX_DECREF(cert->authorityInfoAccess);
1155 PKIX_DECREF(cert->subjectInfoAccess);
1156 PKIX_DECREF(cert->crldpList);
1157
1158 if (cert->arenaNameConstraints){
1159 /* This arena was allocated for SubjectAltNames */
1160 PKIX_PL_NSSCALL(CERT, PORT_FreeArena,
1161 (cert->arenaNameConstraints, PR_FALSE));
1162
1163 cert->arenaNameConstraints = NULL;
1164 cert->nssSubjAltNames = NULL;
1165 }
1166
1167 CERT_DestroyCertificate(cert->nssCert);
1168 cert->nssCert = NULL;
1169
1170 cleanup:
1171 PKIX_RETURN(CERT);
1172 }
1173
1174 /*
1175 * FUNCTION: pkix_pl_Cert_ToString
1176 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
1177 */
1178 static PKIX_Error *
1179 pkix_pl_Cert_ToString(
1180 PKIX_PL_Object *object,
1181 PKIX_PL_String **pString,
1182 void *plContext)
1183 {
1184 PKIX_PL_String *certString = NULL;
1185 PKIX_PL_Cert *pkixCert = NULL;
1186
1187 PKIX_ENTER(CERT, "pkix_pl_Cert_toString");
1188 PKIX_NULLCHECK_TWO(object, pString);
1189
1190 PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
1191 PKIX_OBJECTNOTCERT);
1192
1193 pkixCert = (PKIX_PL_Cert *)object;
1194
1195 PKIX_CHECK(pkix_pl_Cert_ToString_Helper
1196 (pkixCert, PKIX_FALSE, &certString, plContext),
1197 PKIX_CERTTOSTRINGHELPERFAILED);
1198
1199 *pString = certString;
1200
1201 cleanup:
1202 PKIX_RETURN(CERT);
1203 }
1204
1205 /*
1206 * FUNCTION: pkix_pl_Cert_Hashcode
1207 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
1208 */
1209 static PKIX_Error *
1210 pkix_pl_Cert_Hashcode(
1211 PKIX_PL_Object *object,
1212 PKIX_UInt32 *pHashcode,
1213 void *plContext)
1214 {
1215 PKIX_PL_Cert *pkixCert = NULL;
1216 CERTCertificate *nssCert = NULL;
1217 unsigned char *derBytes = NULL;
1218 PKIX_UInt32 derLength;
1219 PKIX_UInt32 certHash;
1220
1221 PKIX_ENTER(CERT, "pkix_pl_Cert_Hashcode");
1222 PKIX_NULLCHECK_TWO(object, pHashcode);
1223
1224 PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
1225 PKIX_OBJECTNOTCERT);
1226
1227 pkixCert = (PKIX_PL_Cert *)object;
1228
1229 nssCert = pkixCert->nssCert;
1230 derBytes = (nssCert->derCert).data;
1231 derLength = (nssCert->derCert).len;
1232
1233 PKIX_CHECK(pkix_hash(derBytes, derLength, &certHash, plContext),
1234 PKIX_HASHFAILED);
1235
1236 *pHashcode = certHash;
1237
1238 cleanup:
1239 PKIX_RETURN(CERT);
1240 }
1241
1242
1243 /*
1244 * FUNCTION: pkix_pl_Cert_Equals
1245 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
1246 */
1247 static PKIX_Error *
1248 pkix_pl_Cert_Equals(
1249 PKIX_PL_Object *firstObject,
1250 PKIX_PL_Object *secondObject,
1251 PKIX_Boolean *pResult,
1252 void *plContext)
1253 {
1254 CERTCertificate *firstCert = NULL;
1255 CERTCertificate *secondCert = NULL;
1256 PKIX_UInt32 secondType;
1257 PKIX_Boolean cmpResult;
1258
1259 PKIX_ENTER(CERT, "pkix_pl_Cert_Equals");
1260 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
1261
1262 /* test that firstObject is a Cert */
1263 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CERT_TYPE, plContext),
1264 PKIX_FIRSTOBJECTNOTCERT);
1265
1266 /*
1267 * Since we know firstObject is a Cert, if both references are
1268 * identical, they must be equal
1269 */
1270 if (firstObject == secondObject){
1271 *pResult = PKIX_TRUE;
1272 goto cleanup;
1273 }
1274
1275 /*
1276 * If secondObject isn't a Cert, we don't throw an error.
1277 * We simply return a Boolean result of FALSE
1278 */
1279 *pResult = PKIX_FALSE;
1280 PKIX_CHECK(PKIX_PL_Object_GetType
1281 (secondObject, &secondType, plContext),
1282 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
1283 if (secondType != PKIX_CERT_TYPE) goto cleanup;
1284
1285 firstCert = ((PKIX_PL_Cert *)firstObject)->nssCert;
1286 secondCert = ((PKIX_PL_Cert *)secondObject)->nssCert;
1287
1288 PKIX_NULLCHECK_TWO(firstCert, secondCert);
1289
1290 /* CERT_CompareCerts does byte comparison on DER encodings of certs */
1291 PKIX_CERT_DEBUG("\t\tCalling CERT_CompareCerts).\n");
1292 cmpResult = CERT_CompareCerts(firstCert, secondCert);
1293
1294 *pResult = cmpResult;
1295
1296 cleanup:
1297 PKIX_RETURN(CERT);
1298 }
1299
1300 /*
1301 * FUNCTION: pkix_pl_Cert_RegisterSelf
1302 * DESCRIPTION:
1303 * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
1304 * THREAD SAFETY:
1305 * Not Thread Safe - for performance and complexity reasons
1306 *
1307 * Since this function is only called by PKIX_PL_Initialize, which should
1308 * only be called once, it is acceptable that this function is not
1309 * thread-safe.
1310 */
1311 PKIX_Error *
1312 pkix_pl_Cert_RegisterSelf(void *plContext)
1313 {
1314
1315 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
1316 pkix_ClassTable_Entry entry;
1317
1318 PKIX_ENTER(CERT, "pkix_pl_Cert_RegisterSelf");
1319
1320 entry.description = "Cert";
1321 entry.objCounter = 0;
1322 entry.typeObjectSize = sizeof(PKIX_PL_Cert);
1323 entry.destructor = pkix_pl_Cert_Destroy;
1324 entry.equalsFunction = pkix_pl_Cert_Equals;
1325 entry.hashcodeFunction = pkix_pl_Cert_Hashcode;
1326 entry.toStringFunction = pkix_pl_Cert_ToString;
1327 entry.comparator = NULL;
1328 entry.duplicateFunction = pkix_duplicateImmutable;
1329
1330 systemClasses[PKIX_CERT_TYPE] = entry;
1331
1332 PKIX_RETURN(CERT);
1333 }
1334
1335 /*
1336 * FUNCTION: pkix_pl_Cert_CreateWithNSSCert
1337 * DESCRIPTION:
1338 *
1339 * Creates a new certificate using the CERTCertificate pointed to by "nssCert"
1340 * and stores it at "pCert". Once created, a Cert is immutable.
1341 *
1342 * This function is primarily used as a convenience function for the
1343 * performance tests that have easy access to a CERTCertificate.
1344 *
1345 * PARAMETERS:
1346 * "nssCert"
1347 * Address of CERTCertificate representing the NSS certificate.
1348 * Must be non-NULL.
1349 * "pCert"
1350 * Address where object pointer will be stored. Must be non-NULL.
1351 * "plContext"
1352 * Platform-specific context pointer.
1353 * THREAD SAFETY:
1354 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1355 * RETURNS:
1356 * Returns NULL if the function succeeds.
1357 * Returns a Cert Error if the function fails in a non-fatal way.
1358 * Returns a Fatal Error if the function fails in an unrecoverable way.
1359 */
1360 PKIX_Error *
1361 pkix_pl_Cert_CreateWithNSSCert(
1362 CERTCertificate *nssCert,
1363 PKIX_PL_Cert **pCert,
1364 void *plContext)
1365 {
1366 PKIX_PL_Cert *cert = NULL;
1367
1368 PKIX_ENTER(CERT, "pkix_pl_Cert_CreateWithNSSCert");
1369 PKIX_NULLCHECK_TWO(pCert, nssCert);
1370
1371 /* create a PKIX_PL_Cert object */
1372 PKIX_CHECK(PKIX_PL_Object_Alloc
1373 (PKIX_CERT_TYPE,
1374 sizeof (PKIX_PL_Cert),
1375 (PKIX_PL_Object **)&cert,
1376 plContext),
1377 PKIX_COULDNOTCREATEOBJECT);
1378
1379 /* populate the nssCert field */
1380 cert->nssCert = nssCert;
1381
1382 /* initialize remaining fields */
1383 /*
1384 * Fields ending with Absent are initialized to PKIX_FALSE so that the
1385 * first time we need the value we will look for it. If we find it is
1386 * actually absent, the flag will at that time be set to PKIX_TRUE to
1387 * prevent searching for it later.
1388 * Fields ending with Processed are those where a value is defined
1389 * for the Absent case, and a value of zero is possible. When the
1390 * flag is still true we have to look for the field, set the default
1391 * value if necessary, and set the Processed flag to PKIX_TRUE.
1392 */
1393 cert->subject = NULL;
1394 cert->issuer = NULL;
1395 cert->subjAltNames = NULL;
1396 cert->subjAltNamesAbsent = PKIX_FALSE;
1397 cert->publicKeyAlgId = NULL;
1398 cert->publicKey = NULL;
1399 cert->serialNumber = NULL;
1400 cert->critExtOids = NULL;
1401 cert->subjKeyId = NULL;
1402 cert->subjKeyIdAbsent = PKIX_FALSE;
1403 cert->authKeyId = NULL;
1404 cert->authKeyIdAbsent = PKIX_FALSE;
1405 cert->extKeyUsages = NULL;
1406 cert->extKeyUsagesAbsent = PKIX_FALSE;
1407 cert->certBasicConstraints = NULL;
1408 cert->basicConstraintsAbsent = PKIX_FALSE;
1409 cert->certPolicyInfos = NULL;
1410 cert->policyInfoAbsent = PKIX_FALSE;
1411 cert->policyMappingsAbsent = PKIX_FALSE;
1412 cert->certPolicyMappings = NULL;
1413 cert->policyConstraintsProcessed = PKIX_FALSE;
1414 cert->policyConstraintsExplicitPolicySkipCerts = 0;
1415 cert->policyConstraintsInhibitMappingSkipCerts = 0;
1416 cert->inhibitAnyPolicyProcessed = PKIX_FALSE;
1417 cert->inhibitAnySkipCerts = 0;
1418 cert->nameConstraints = NULL;
1419 cert->nameConstraintsAbsent = PKIX_FALSE;
1420 cert->arenaNameConstraints = NULL;
1421 cert->nssSubjAltNames = NULL;
1422 cert->cacheFlag = PKIX_FALSE;
1423 cert->store = NULL;
1424 cert->authorityInfoAccess = NULL;
1425 cert->subjectInfoAccess = NULL;
1426 cert->isUserTrustAnchor = PKIX_FALSE;
1427 cert->crldpList = NULL;
1428
1429 *pCert = cert;
1430
1431 cleanup:
1432 PKIX_RETURN(CERT);
1433 }
1434
1435 /*
1436 * FUNCTION: pkix_pl_Cert_CreateToList
1437 * DESCRIPTION:
1438 *
1439 * Creates a new certificate using the DER-encoding pointed to by "derCertItem"
1440 * and appends it to the list pointed to by "certList". If Cert creation fails,
1441 * the function returns with certList unchanged, but any decoding Error is
1442 * discarded.
1443 *
1444 * PARAMETERS:
1445 * "derCertItem"
1446 * Address of SECItem containing the DER representation of a certificate.
1447 * Must be non-NULL.
1448 * "certList"
1449 * Address of List to which the Cert will be appended, if successfully
1450 * created. May be empty, but must be non-NULL.
1451 * "plContext"
1452 * Platform-specific context pointer.
1453 * THREAD SAFETY:
1454 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1455 * RETURNS:
1456 * Returns NULL if the function succeeds.
1457 * Returns a Cert Error if the function fails in a non-fatal way.
1458 * Returns a Fatal Error if the function fails in an unrecoverable way.
1459 */
1460 PKIX_Error *
1461 pkix_pl_Cert_CreateToList(
1462 SECItem *derCertItem,
1463 PKIX_List *certList,
1464 void *plContext)
1465 {
1466 CERTCertificate *nssCert = NULL;
1467 PKIX_PL_Cert *cert = NULL;
1468 CERTCertDBHandle *handle;
1469
1470 PKIX_ENTER(CERT, "pkix_pl_Cert_CreateToList");
1471 PKIX_NULLCHECK_TWO(derCertItem, certList);
1472
1473 handle = CERT_GetDefaultCertDB();
1474 nssCert = CERT_NewTempCertificate(handle, derCertItem,
1475 /* nickname */ NULL,
1476 /* isPerm */ PR_FALSE,
1477 /* copyDer */ PR_TRUE);
1478 if (!nssCert) {
1479 goto cleanup;
1480 }
1481
1482 PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
1483 (nssCert, &cert, plContext),
1484 PKIX_CERTCREATEWITHNSSCERTFAILED);
1485
1486 nssCert = NULL;
1487
1488 PKIX_CHECK(PKIX_List_AppendItem
1489 (certList, (PKIX_PL_Object *) cert, plContext),
1490 PKIX_LISTAPPENDITEMFAILED);
1491
1492 cleanup:
1493 if (nssCert) {
1494 CERT_DestroyCertificate(nssCert);
1495 }
1496
1497 PKIX_DECREF(cert);
1498 PKIX_RETURN(CERT);
1499 }
1500
1501 /* --Public-Functions------------------------------------------------------- */
1502
1503 /*
1504 * FUNCTION: PKIX_PL_Cert_Create (see comments in pkix_pl_pki.h)
1505 * XXX We may want to cache the cert after parsing it, so it can be reused
1506 * XXX Are the NSS/NSPR functions thread safe
1507 */
1508 PKIX_Error *
1509 PKIX_PL_Cert_Create(
1510 PKIX_PL_ByteArray *byteArray,
1511 PKIX_PL_Cert **pCert,
1512 void *plContext)
1513 {
1514 CERTCertificate *nssCert = NULL;
1515 SECItem *derCertItem = NULL;
1516 void *derBytes = NULL;
1517 PKIX_UInt32 derLength;
1518 PKIX_PL_Cert *cert = NULL;
1519 CERTCertDBHandle *handle;
1520
1521 PKIX_ENTER(CERT, "PKIX_PL_Cert_Create");
1522 PKIX_NULLCHECK_TWO(pCert, byteArray);
1523
1524 PKIX_CHECK(PKIX_PL_ByteArray_GetPointer
1525 (byteArray, &derBytes, plContext),
1526 PKIX_BYTEARRAYGETPOINTERFAILED);
1527
1528 PKIX_CHECK(PKIX_PL_ByteArray_GetLength
1529 (byteArray, &derLength, plContext),
1530 PKIX_BYTEARRAYGETLENGTHFAILED);
1531
1532 derCertItem = SECITEM_AllocItem(NULL, NULL, derLength);
1533 if (derCertItem == NULL){
1534 PKIX_ERROR(PKIX_OUTOFMEMORY);
1535 }
1536
1537 (void) PORT_Memcpy(derCertItem->data, derBytes, derLength);
1538
1539 /*
1540 * setting copyDER to true forces NSS to make its own copy of the DER,
1541 * allowing us to free our copy without worrying about whether NSS
1542 * is still using it
1543 */
1544 handle = CERT_GetDefaultCertDB();
1545 nssCert = CERT_NewTempCertificate(handle, derCertItem,
1546 /* nickname */ NULL,
1547 /* isPerm */ PR_FALSE,
1548 /* copyDer */ PR_TRUE);
1549 if (!nssCert){
1550 PKIX_ERROR(PKIX_CERTDECODEDERCERTIFICATEFAILED);
1551 }
1552
1553 PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
1554 (nssCert, &cert, plContext),
1555 PKIX_CERTCREATEWITHNSSCERTFAILED);
1556
1557 *pCert = cert;
1558
1559 cleanup:
1560 if (derCertItem){
1561 SECITEM_FreeItem(derCertItem, PKIX_TRUE);
1562 }
1563
1564 if (nssCert && PKIX_ERROR_RECEIVED){
1565 PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
1566 CERT_DestroyCertificate(nssCert);
1567 nssCert = NULL;
1568 }
1569
1570 PKIX_FREE(derBytes);
1571 PKIX_RETURN(CERT);
1572 }
1573
1574
1575 /*
1576 * FUNCTION: PKIX_PL_Cert_CreateFromCERTCertificate
1577 * (see comments in pkix_pl_pki.h)
1578 */
1579 PKIX_Error *
1580 PKIX_PL_Cert_CreateFromCERTCertificate(
1581 const CERTCertificate *nssCert,
1582 PKIX_PL_Cert **pCert,
1583 void *plContext)
1584 {
1585 void *buf = NULL;
1586 PKIX_UInt32 len;
1587 PKIX_PL_ByteArray *byteArray = NULL;
1588
1589 PKIX_ENTER(CERT, "PKIX_PL_Cert_CreateWithNssCert");
1590 PKIX_NULLCHECK_TWO(pCert, nssCert);
1591
1592 buf = (void*)nssCert->derCert.data;
1593 len = nssCert->derCert.len;
1594
1595 PKIX_CHECK(
1596 PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext),
1597 PKIX_BYTEARRAYCREATEFAILED);
1598
1599 PKIX_CHECK(
1600 PKIX_PL_Cert_Create(byteArray, pCert, plContext),
1601 PKIX_CERTCREATEWITHNSSCERTFAILED);
1602
1603 #ifdef PKIX_UNDEF
1604 /* will be tested and used as a patch for bug 391612 */
1605 nssCert = CERT_DupCertificate(nssInCert);
1606
1607 PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
1608 (nssCert, &cert, plContext),
1609 PKIX_CERTCREATEWITHNSSCERTFAILED);
1610 #endif /* PKIX_UNDEF */
1611
1612 cleanup:
1613
1614 #ifdef PKIX_UNDEF
1615 if (nssCert && PKIX_ERROR_RECEIVED){
1616 PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
1617 CERT_DestroyCertificate(nssCert);
1618 nssCert = NULL;
1619 }
1620 #endif /* PKIX_UNDEF */
1621
1622 PKIX_DECREF(byteArray);
1623 PKIX_RETURN(CERT);
1624 }
1625
1626
1627 /*
1628 * FUNCTION: PKIX_PL_Cert_GetVersion (see comments in pkix_pl_pki.h)
1629 */
1630 PKIX_Error *
1631 PKIX_PL_Cert_GetVersion(
1632 PKIX_PL_Cert *cert,
1633 PKIX_UInt32 *pVersion,
1634 void *plContext)
1635 {
1636 CERTCertificate *nssCert = NULL;
1637 PKIX_UInt32 myVersion = 0; /* v1 */
1638
1639 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetVersion");
1640 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pVersion);
1641
1642 nssCert = cert->nssCert;
1643 if (nssCert->version.len != 0) {
1644 myVersion = *(nssCert->version.data);
1645 }
1646
1647 if (myVersion > 2){
1648 PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1V2ORV3);
1649 }
1650
1651 *pVersion = myVersion;
1652
1653 cleanup:
1654 PKIX_RETURN(CERT);
1655 }
1656
1657 /*
1658 * FUNCTION: PKIX_PL_Cert_GetSerialNumber (see comments in pkix_pl_pki.h)
1659 */
1660 PKIX_Error *
1661 PKIX_PL_Cert_GetSerialNumber(
1662 PKIX_PL_Cert *cert,
1663 PKIX_PL_BigInt **pSerialNumber,
1664 void *plContext)
1665 {
1666 CERTCertificate *nssCert = NULL;
1667 SECItem serialNumItem;
1668 PKIX_PL_BigInt *serialNumber = NULL;
1669 char *bytes = NULL;
1670 PKIX_UInt32 length;
1671
1672 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSerialNumber");
1673 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSerialNumber);
1674
1675 if (cert->serialNumber == NULL){
1676
1677 PKIX_OBJECT_LOCK(cert);
1678
1679 if (cert->serialNumber == NULL){
1680
1681 nssCert = cert->nssCert;
1682 serialNumItem = nssCert->serialNumber;
1683
1684 length = serialNumItem.len;
1685 bytes = (char *)serialNumItem.data;
1686
1687 PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
1688 (bytes, length, &serialNumber, plContext),
1689 PKIX_BIGINTCREATEWITHBYTESFAILED);
1690
1691 /* save a cached copy in case it is asked for again */
1692 cert->serialNumber = serialNumber;
1693 }
1694
1695 PKIX_OBJECT_UNLOCK(cert);
1696 }
1697
1698 PKIX_INCREF(cert->serialNumber);
1699 *pSerialNumber = cert->serialNumber;
1700
1701 cleanup:
1702 PKIX_OBJECT_UNLOCK(lockedObject);
1703 PKIX_RETURN(CERT);
1704 }
1705
1706 /*
1707 * FUNCTION: PKIX_PL_Cert_GetSubject (see comments in pkix_pl_pki.h)
1708 */
1709 PKIX_Error *
1710 PKIX_PL_Cert_GetSubject(
1711 PKIX_PL_Cert *cert,
1712 PKIX_PL_X500Name **pCertSubject,
1713 void *plContext)
1714 {
1715 PKIX_PL_X500Name *pkixSubject = NULL;
1716 CERTName *subjName = NULL;
1717 SECItem *derSubjName = NULL;
1718
1719 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubject");
1720 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertSubject);
1721
1722 /* if we don't have a cached copy from before, we create one */
1723 if (cert->subject == NULL){
1724
1725 PKIX_OBJECT_LOCK(cert);
1726
1727 if (cert->subject == NULL){
1728
1729 subjName = &cert->nssCert->subject;
1730 derSubjName = &cert->nssCert->derSubject;
1731
1732 /* if there is no subject name */
1733 if (derSubjName->data == NULL) {
1734
1735 pkixSubject = NULL;
1736
1737 } else {
1738 PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
1739 (derSubjName, subjName, &pkixSubject,
1740 plContext),
1741 PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
1742
1743 }
1744 /* save a cached copy in case it is asked for again */
1745 cert->subject = pkixSubject;
1746 }
1747
1748 PKIX_OBJECT_UNLOCK(cert);
1749 }
1750
1751 PKIX_INCREF(cert->subject);
1752 *pCertSubject = cert->subject;
1753
1754 cleanup:
1755 PKIX_OBJECT_UNLOCK(lockedObject);
1756 PKIX_RETURN(CERT);
1757 }
1758
1759 /*
1760 * FUNCTION: PKIX_PL_Cert_GetIssuer (see comments in pkix_pl_pki.h)
1761 */
1762 PKIX_Error *
1763 PKIX_PL_Cert_GetIssuer(
1764 PKIX_PL_Cert *cert,
1765 PKIX_PL_X500Name **pCertIssuer,
1766 void *plContext)
1767 {
1768 PKIX_PL_X500Name *pkixIssuer = NULL;
1769 SECItem *derIssuerName = NULL;
1770 CERTName *issuerName = NULL;
1771
1772 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetIssuer");
1773 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertIssuer);
1774
1775 /* if we don't have a cached copy from before, we create one */
1776 if (cert->issuer == NULL){
1777
1778 PKIX_OBJECT_LOCK(cert);
1779
1780 if (cert->issuer == NULL){
1781
1782 issuerName = &cert->nssCert->issuer;
1783 derIssuerName = &cert->nssCert->derIssuer;
1784
1785 /* if there is no subject name */
1786 PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
1787 (derIssuerName, issuerName,
1788 &pkixIssuer, plContext),
1789 PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
1790
1791 /* save a cached copy in case it is asked for again */
1792 cert->issuer = pkixIssuer;
1793 }
1794
1795 PKIX_OBJECT_UNLOCK(cert);
1796 }
1797
1798 PKIX_INCREF(cert->issuer);
1799 *pCertIssuer = cert->issuer;
1800
1801 cleanup:
1802 PKIX_RETURN(CERT);
1803 }
1804
1805 /*
1806 * FUNCTION: PKIX_PL_Cert_GetSubjectAltNames (see comments in pkix_pl_pki.h)
1807 */
1808 PKIX_Error *
1809 PKIX_PL_Cert_GetSubjectAltNames(
1810 PKIX_PL_Cert *cert,
1811 PKIX_List **pSubjectAltNames, /* list of PKIX_PL_GeneralName */
1812 void *plContext)
1813 {
1814 PKIX_PL_GeneralName *pkixAltName = NULL;
1815 PKIX_List *altNamesList = NULL;
1816
1817 CERTGeneralName *nssOriginalAltName = NULL;
1818 CERTGeneralName *nssTempAltName = NULL;
1819
1820 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectAltNames");
1821 PKIX_NULLCHECK_TWO(cert, pSubjectAltNames);
1822
1823 /* if we don't have a cached copy from before, we create one */
1824 if ((cert->subjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
1825
1826 PKIX_OBJECT_LOCK(cert);
1827
1828 if ((cert->subjAltNames == NULL) &&
1829 (!cert->subjAltNamesAbsent)){
1830
1831 PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
1832 (cert,
1833 PKIX_TRUE,
1834 &nssOriginalAltName,
1835 plContext),
1836 PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
1837
1838 if (nssOriginalAltName == NULL) {
1839 cert->subjAltNamesAbsent = PKIX_TRUE;
1840 pSubjectAltNames = NULL;
1841 goto cleanup;
1842 }
1843
1844 nssTempAltName = nssOriginalAltName;
1845
1846 PKIX_CHECK(PKIX_List_Create(&altNamesList, plContext),
1847 PKIX_LISTCREATEFAILED);
1848
1849 do {
1850 PKIX_CHECK(pkix_pl_GeneralName_Create
1851 (nssTempAltName, &pkixAltName, plContext),
1852 PKIX_GENERALNAMECREATEFAILED);
1853
1854 PKIX_CHECK(PKIX_List_AppendItem
1855 (altNamesList,
1856 (PKIX_PL_Object *)pkixAltName,
1857 plContext),
1858 PKIX_LISTAPPENDITEMFAILED);
1859
1860 PKIX_DECREF(pkixAltName);
1861
1862 PKIX_CERT_DEBUG
1863 ("\t\tCalling CERT_GetNextGeneralName).\n");
1864 nssTempAltName = CERT_GetNextGeneralName
1865 (nssTempAltName);
1866
1867 } while (nssTempAltName != nssOriginalAltName);
1868
1869 /* save a cached copy in case it is asked for again */
1870 cert->subjAltNames = altNamesList;
1871 PKIX_CHECK(PKIX_List_SetImmutable
1872 (cert->subjAltNames, plContext),
1873 PKIX_LISTSETIMMUTABLEFAILED);
1874
1875 }
1876
1877 PKIX_OBJECT_UNLOCK(cert);
1878 }
1879
1880 PKIX_INCREF(cert->subjAltNames);
1881
1882 *pSubjectAltNames = cert->subjAltNames;
1883
1884 cleanup:
1885 PKIX_DECREF(pkixAltName);
1886 if (PKIX_ERROR_RECEIVED){
1887 PKIX_DECREF(altNamesList);
1888 }
1889 PKIX_RETURN(CERT);
1890 }
1891
1892 /*
1893 * FUNCTION: PKIX_PL_Cert_GetAllSubjectNames (see comments in pkix_pl_pki.h)
1894 */
1895 PKIX_Error *
1896 PKIX_PL_Cert_GetAllSubjectNames(
1897 PKIX_PL_Cert *cert,
1898 PKIX_List **pAllSubjectNames, /* list of PKIX_PL_GeneralName */
1899 void *plContext)
1900 {
1901 CERTGeneralName *nssOriginalSubjectName = NULL;
1902 CERTGeneralName *nssTempSubjectName = NULL;
1903 PKIX_List *allSubjectNames = NULL;
1904 PKIX_PL_GeneralName *pkixSubjectName = NULL;
1905 PLArenaPool *arena = NULL;
1906
1907 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAllSubjectNames");
1908 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAllSubjectNames);
1909
1910
1911 if (cert->nssCert->subjectName == NULL){
1912 /* if there is no subject DN, just get altnames */
1913
1914 PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
1915 (cert,
1916 PKIX_FALSE, /* hasLock */
1917 &nssOriginalSubjectName,
1918 plContext),
1919 PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
1920
1921 } else { /* get subject DN and altnames */
1922
1923 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1924 if (arena == NULL) {
1925 PKIX_ERROR(PKIX_OUTOFMEMORY);
1926 }
1927
1928 /* This NSS call returns both Subject and Subject Alt Names */
1929 PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
1930 nssOriginalSubjectName =
1931 CERT_GetCertificateNames(cert->nssCert, arena);
1932 }
1933
1934 if (nssOriginalSubjectName == NULL) {
1935 pAllSubjectNames = NULL;
1936 goto cleanup;
1937 }
1938
1939 nssTempSubjectName = nssOriginalSubjectName;
1940
1941 PKIX_CHECK(PKIX_List_Create(&allSubjectNames, plContext),
1942 PKIX_LISTCREATEFAILED);
1943
1944 do {
1945 PKIX_CHECK(pkix_pl_GeneralName_Create
1946 (nssTempSubjectName, &pkixSubjectName, plContext),
1947 PKIX_GENERALNAMECREATEFAILED);
1948
1949 PKIX_CHECK(PKIX_List_AppendItem
1950 (allSubjectNames,
1951 (PKIX_PL_Object *)pkixSubjectName,
1952 plContext),
1953 PKIX_LISTAPPENDITEMFAILED);
1954
1955 PKIX_DECREF(pkixSubjectName);
1956
1957 PKIX_CERT_DEBUG
1958 ("\t\tCalling CERT_GetNextGeneralName).\n");
1959 nssTempSubjectName = CERT_GetNextGeneralName
1960 (nssTempSubjectName);
1961 } while (nssTempSubjectName != nssOriginalSubjectName);
1962
1963 *pAllSubjectNames = allSubjectNames;
1964
1965 cleanup:
1966 if (PKIX_ERROR_RECEIVED){
1967 PKIX_DECREF(allSubjectNames);
1968 }
1969
1970 if (arena){
1971 PORT_FreeArena(arena, PR_FALSE);
1972 }
1973 PKIX_DECREF(pkixSubjectName);
1974 PKIX_RETURN(CERT);
1975 }
1976
1977 /*
1978 * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKeyAlgId
1979 * (see comments in pkix_pl_pki.h)
1980 */
1981 PKIX_Error *
1982 PKIX_PL_Cert_GetSubjectPublicKeyAlgId(
1983 PKIX_PL_Cert *cert,
1984 PKIX_PL_OID **pSubjKeyAlgId,
1985 void *plContext)
1986 {
1987 PKIX_PL_OID *pubKeyAlgId = NULL;
1988
1989 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKeyAlgId");
1990 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyAlgId);
1991
1992 /* if we don't have a cached copy from before, we create one */
1993 if (cert->publicKeyAlgId == NULL){
1994 PKIX_OBJECT_LOCK(cert);
1995 if (cert->publicKeyAlgId == NULL){
1996 CERTCertificate *nssCert = cert->nssCert;
1997 SECAlgorithmID *algorithm;
1998 SECItem *algBytes;
1999
2000 algorithm = &nssCert->subjectPublicKeyInfo.algorithm;
2001 algBytes = &algorithm->algorithm;
2002 if (!algBytes->data || !algBytes->len) {
2003 PKIX_ERROR_FATAL(PKIX_ALGORITHMBYTESLENGTH0);
2004 }
2005 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
2006 (algBytes, &pubKeyAlgId, plContext),
2007 PKIX_OIDCREATEFAILED);
2008
2009 /* save a cached copy in case it is asked for again */
2010 cert->publicKeyAlgId = pubKeyAlgId;
2011 pubKeyAlgId = NULL;
2012 }
2013 PKIX_OBJECT_UNLOCK(cert);
2014 }
2015
2016 PKIX_INCREF(cert->publicKeyAlgId);
2017 *pSubjKeyAlgId = cert->publicKeyAlgId;
2018
2019 cleanup:
2020 PKIX_DECREF(pubKeyAlgId);
2021 PKIX_RETURN(CERT);
2022 }
2023
2024 /*
2025 * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKey (see comments in pkix_pl_pki.h)
2026 */
2027 PKIX_Error *
2028 PKIX_PL_Cert_GetSubjectPublicKey(
2029 PKIX_PL_Cert *cert,
2030 PKIX_PL_PublicKey **pPublicKey,
2031 void *plContext)
2032 {
2033 PKIX_PL_PublicKey *pkixPubKey = NULL;
2034 SECStatus rv;
2035
2036 CERTSubjectPublicKeyInfo *from = NULL;
2037 CERTSubjectPublicKeyInfo *to = NULL;
2038 SECItem *fromItem = NULL;
2039 SECItem *toItem = NULL;
2040
2041 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKey");
2042 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPublicKey);
2043
2044 /* if we don't have a cached copy from before, we create one */
2045 if (cert->publicKey == NULL){
2046
2047 PKIX_OBJECT_LOCK(cert);
2048
2049 if (cert->publicKey == NULL){
2050
2051 /* create a PKIX_PL_PublicKey object */
2052 PKIX_CHECK(PKIX_PL_Object_Alloc
2053 (PKIX_PUBLICKEY_TYPE,
2054 sizeof (PKIX_PL_PublicKey),
2055 (PKIX_PL_Object **)&pkixPubKey,
2056 plContext),
2057 PKIX_COULDNOTCREATEOBJECT);
2058
2059 /* initialize fields */
2060 pkixPubKey->nssSPKI = NULL;
2061
2062 /* populate the SPKI field */
2063 PKIX_CHECK(PKIX_PL_Malloc
2064 (sizeof (CERTSubjectPublicKeyInfo),
2065 (void **)&pkixPubKey->nssSPKI,
2066 plContext),
2067 PKIX_MALLOCFAILED);
2068
2069 to = pkixPubKey->nssSPKI;
2070 from = &cert->nssCert->subjectPublicKeyInfo;
2071
2072 PKIX_NULLCHECK_TWO(to, from);
2073
2074 PKIX_CERT_DEBUG
2075 ("\t\tCalling SECOID_CopyAlgorithmID).\n");
2076 rv = SECOID_CopyAlgorithmID
2077 (NULL, &to->algorithm, &from->algorithm);
2078 if (rv != SECSuccess) {
2079 PKIX_ERROR(PKIX_SECOIDCOPYALGORITHMIDFAILED);
2080 }
2081
2082 /*
2083 * NSS stores the length of subjectPublicKey in bits.
2084 * Therefore, we use that length converted to bytes
2085 * using ((length+7)>>3) before calling PORT_Memcpy
2086 * in order to avoid "read from uninitialized memory"
2087 * errors.
2088 */
2089
2090 toItem = &to->subjectPublicKey;
2091 fromItem = &from->subjectPublicKey;
2092
2093 PKIX_NULLCHECK_TWO(toItem, fromItem);
2094
2095 toItem->type = fromItem->type;
2096
2097 toItem->data =
2098 (unsigned char*) PORT_ZAlloc(fromItem->len);
2099 if (!toItem->data){
2100 PKIX_ERROR(PKIX_OUTOFMEMORY);
2101 }
2102
2103 (void) PORT_Memcpy(toItem->data,
2104 fromItem->data,
2105 (fromItem->len + 7)>>3);
2106 toItem->len = fromItem->len;
2107
2108 /* save a cached copy in case it is asked for again */
2109 cert->publicKey = pkixPubKey;
2110 }
2111
2112 PKIX_OBJECT_UNLOCK(cert);
2113 }
2114
2115 PKIX_INCREF(cert->publicKey);
2116 *pPublicKey = cert->publicKey;
2117
2118 cleanup:
2119
2120 if (PKIX_ERROR_RECEIVED && pkixPubKey){
2121 PKIX_DECREF(pkixPubKey);
2122 cert->publicKey = NULL;
2123 }
2124 PKIX_RETURN(CERT);
2125 }
2126
2127 /*
2128 * FUNCTION: PKIX_PL_Cert_GetCriticalExtensionOIDs
2129 * (see comments in pkix_pl_pki.h)
2130 */
2131 PKIX_Error *
2132 PKIX_PL_Cert_GetCriticalExtensionOIDs(
2133 PKIX_PL_Cert *cert,
2134 PKIX_List **pList, /* list of PKIX_PL_OID */
2135 void *plContext)
2136 {
2137 PKIX_List *oidsList = NULL;
2138 CERTCertExtension **extensions = NULL;
2139 CERTCertificate *nssCert = NULL;
2140
2141 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCriticalExtensionOIDs");
2142 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pList);
2143
2144 /* if we don't have a cached copy from before, we create one */
2145 if (cert->critExtOids == NULL) {
2146
2147 PKIX_OBJECT_LOCK(cert);
2148
2149 if (cert->critExtOids == NULL) {
2150
2151 nssCert = cert->nssCert;
2152
2153 /*
2154 * ASN.1 for Extension
2155 *
2156 * Extension ::= SEQUENCE {
2157 * extnID OBJECT IDENTIFIER,
2158 * critical BOOLEAN DEFAULT FALSE,
2159 * extnValue OCTET STRING }
2160 *
2161 */
2162
2163 extensions = nssCert->extensions;
2164
2165 PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
2166 (extensions, &oidsList, plContext),
2167 PKIX_GETCRITICALEXTENSIONOIDSFAILED);
2168
2169 /* save a cached copy in case it is asked for again */
2170 cert->critExtOids = oidsList;
2171 }
2172
2173 PKIX_OBJECT_UNLOCK(cert);
2174 }
2175
2176 /* We should return a copy of the List since this list changes */
2177 PKIX_DUPLICATE(cert->critExtOids, pList, plContext,
2178 PKIX_OBJECTDUPLICATELISTFAILED);
2179
2180 cleanup:
2181 PKIX_OBJECT_UNLOCK(lockedObject);
2182 PKIX_RETURN(CERT);
2183 }
2184
2185 /*
2186 * FUNCTION: PKIX_PL_Cert_GetAuthorityKeyIdentifier
2187 * (see comments in pkix_pl_pki.h)
2188 */
2189 PKIX_Error *
2190 PKIX_PL_Cert_GetAuthorityKeyIdentifier(
2191 PKIX_PL_Cert *cert,
2192 PKIX_PL_ByteArray **pAuthKeyId,
2193 void *plContext)
2194 {
2195 PKIX_PL_ByteArray *authKeyId = NULL;
2196 CERTCertificate *nssCert = NULL;
2197 CERTAuthKeyID *authKeyIdExtension = NULL;
2198 PLArenaPool *arena = NULL;
2199 SECItem retItem;
2200
2201 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityKeyIdentifier");
2202 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAuthKeyId);
2203
2204 /* if we don't have a cached copy from before, we create one */
2205 if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
2206
2207 PKIX_OBJECT_LOCK(cert);
2208
2209 if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
2210
2211 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
2212 if (arena == NULL) {
2213 PKIX_ERROR(PKIX_OUTOFMEMORY);
2214 }
2215
2216 nssCert = cert->nssCert;
2217
2218 authKeyIdExtension =
2219 CERT_FindAuthKeyIDExten(arena, nssCert);
2220 if (authKeyIdExtension == NULL){
2221 cert->authKeyIdAbsent = PKIX_TRUE;
2222 *pAuthKeyId = NULL;
2223 goto cleanup;
2224 }
2225
2226 retItem = authKeyIdExtension->keyID;
2227
2228 if (retItem.len == 0){
2229 cert->authKeyIdAbsent = PKIX_TRUE;
2230 *pAuthKeyId = NULL;
2231 goto cleanup;
2232 }
2233
2234 PKIX_CHECK(PKIX_PL_ByteArray_Create
2235 (retItem.data,
2236 retItem.len,
2237 &authKeyId,
2238 plContext),
2239 PKIX_BYTEARRAYCREATEFAILED);
2240
2241 /* save a cached copy in case it is asked for again */
2242 cert->authKeyId = authKeyId;
2243 }
2244
2245 PKIX_OBJECT_UNLOCK(cert);
2246 }
2247
2248 PKIX_INCREF(cert->authKeyId);
2249 *pAuthKeyId = cert->authKeyId;
2250
2251 cleanup:
2252 PKIX_OBJECT_UNLOCK(lockedObject);
2253 if (arena){
2254 PORT_FreeArena(arena, PR_FALSE);
2255 }
2256 PKIX_RETURN(CERT);
2257 }
2258
2259 /*
2260 * FUNCTION: PKIX_PL_Cert_GetSubjectKeyIdentifier
2261 * (see comments in pkix_pl_pki.h)
2262 */
2263 PKIX_Error *
2264 PKIX_PL_Cert_GetSubjectKeyIdentifier(
2265 PKIX_PL_Cert *cert,
2266 PKIX_PL_ByteArray **pSubjKeyId,
2267 void *plContext)
2268 {
2269 PKIX_PL_ByteArray *subjKeyId = NULL;
2270 CERTCertificate *nssCert = NULL;
2271 SECItem *retItem = NULL;
2272 SECStatus status;
2273
2274 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectKeyIdentifier");
2275 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyId);
2276
2277 /* if we don't have a cached copy from before, we create one */
2278 if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
2279
2280 PKIX_OBJECT_LOCK(cert);
2281
2282 if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
2283
2284 retItem = SECITEM_AllocItem(NULL, NULL, 0);
2285 if (retItem == NULL){
2286 PKIX_ERROR(PKIX_OUTOFMEMORY);
2287 }
2288
2289 nssCert = cert->nssCert;
2290
2291 status = CERT_FindSubjectKeyIDExtension
2292 (nssCert, retItem);
2293 if (status != SECSuccess) {
2294 cert->subjKeyIdAbsent = PKIX_TRUE;
2295 *pSubjKeyId = NULL;
2296 goto cleanup;
2297 }
2298
2299 PKIX_CHECK(PKIX_PL_ByteArray_Create
2300 (retItem->data,
2301 retItem->len,
2302 &subjKeyId,
2303 plContext),
2304 PKIX_BYTEARRAYCREATEFAILED);
2305
2306 /* save a cached copy in case it is asked for again */
2307 cert->subjKeyId = subjKeyId;
2308 }
2309
2310 PKIX_OBJECT_UNLOCK(cert);
2311 }
2312
2313 PKIX_INCREF(cert->subjKeyId);
2314 *pSubjKeyId = cert->subjKeyId;
2315
2316 cleanup:
2317 PKIX_OBJECT_UNLOCK(lockedObject);
2318 if (retItem){
2319 SECITEM_FreeItem(retItem, PKIX_TRUE);
2320 }
2321 PKIX_RETURN(CERT);
2322 }
2323
2324 /*
2325 * FUNCTION: PKIX_PL_Cert_GetExtendedKeyUsage (see comments in pkix_pl_pki.h)
2326 */
2327 PKIX_Error *
2328 PKIX_PL_Cert_GetExtendedKeyUsage(
2329 PKIX_PL_Cert *cert,
2330 PKIX_List **pKeyUsage, /* list of PKIX_PL_OID */
2331 void *plContext)
2332 {
2333 CERTOidSequence *extKeyUsage = NULL;
2334 CERTCertificate *nssCert = NULL;
2335 PKIX_PL_OID *pkixOID = NULL;
2336 PKIX_List *oidsList = NULL;
2337 SECItem **oids = NULL;
2338 SECItem encodedExtKeyUsage;
2339 SECStatus rv;
2340
2341 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetExtendedKeyUsage");
2342 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pKeyUsage);
2343
2344 /* if we don't have a cached copy from before, we create one */
2345 if ((cert->extKeyUsages == NULL) && (!cert->extKeyUsagesAbsent)){
2346
2347 PKIX_OBJECT_LOCK(cert);
2348
2349 if ((cert->extKeyUsages == NULL) &&
2350 (!cert->extKeyUsagesAbsent)){
2351
2352 nssCert = cert->nssCert;
2353
2354 rv = CERT_FindCertExtension
2355 (nssCert, SEC_OID_X509_EXT_KEY_USAGE,
2356 &encodedExtKeyUsage);
2357 if (rv != SECSuccess){
2358 cert->extKeyUsagesAbsent = PKIX_TRUE;
2359 *pKeyUsage = NULL;
2360 goto cleanup;
2361 }
2362
2363 extKeyUsage =
2364 CERT_DecodeOidSequence(&encodedExtKeyUsage);
2365 if (extKeyUsage == NULL){
2366 PKIX_ERROR(PKIX_CERTDECODEOIDSEQUENCEFAILED);
2367 }
2368
2369 PORT_Free(encodedExtKeyUsage.data);
2370
2371 oids = extKeyUsage->oids;
2372
2373 if (!oids){
2374 /* no extended key usage extensions found */
2375 cert->extKeyUsagesAbsent = PKIX_TRUE;
2376 *pKeyUsage = NULL;
2377 goto cleanup;
2378 }
2379
2380 PKIX_CHECK(PKIX_List_Create(&oidsList, plContext),
2381 PKIX_LISTCREATEFAILED);
2382
2383 while (*oids){
2384 SECItem *oid = *oids++;
2385
2386 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
2387 (oid, &pkixOID, plContext),
2388 PKIX_OIDCREATEFAILED);
2389
2390 PKIX_CHECK(PKIX_List_AppendItem
2391 (oidsList,
2392 (PKIX_PL_Object *)pkixOID,
2393 plContext),
2394 PKIX_LISTAPPENDITEMFAILED);
2395 PKIX_DECREF(pkixOID);
2396 }
2397
2398 PKIX_CHECK(PKIX_List_SetImmutable
2399 (oidsList, plContext),
2400 PKIX_LISTSETIMMUTABLEFAILED);
2401
2402 /* save a cached copy in case it is asked for again */
2403 cert->extKeyUsages = oidsList;
2404 oidsList = NULL;
2405 }
2406
2407 PKIX_OBJECT_UNLOCK(cert);
2408 }
2409
2410 PKIX_INCREF(cert->extKeyUsages);
2411 *pKeyUsage = cert->extKeyUsages;
2412
2413 cleanup:
2414 PKIX_OBJECT_UNLOCK(lockedObject);
2415
2416 PKIX_DECREF(pkixOID);
2417 PKIX_DECREF(oidsList);
2418 CERT_DestroyOidSequence(extKeyUsage);
2419
2420 PKIX_RETURN(CERT);
2421 }
2422
2423 /*
2424 * FUNCTION: PKIX_PL_Cert_GetBasicConstraints
2425 * (see comments in pkix_pl_pki.h)
2426 */
2427 PKIX_Error *
2428 PKIX_PL_Cert_GetBasicConstraints(
2429 PKIX_PL_Cert *cert,
2430 PKIX_PL_CertBasicConstraints **pBasicConstraints,
2431 void *plContext)
2432 {
2433 CERTCertificate *nssCert = NULL;
2434 CERTBasicConstraints nssBasicConstraint;
2435 SECStatus rv;
2436 PKIX_PL_CertBasicConstraints *basic;
2437 PKIX_Int32 pathLen = 0;
2438 PKIX_Boolean isCA = PKIX_FALSE;
2439 enum {
2440 realBC, synthBC, absentBC
2441 } constraintSource = absentBC;
2442
2443 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetBasicConstraints");
2444 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pBasicConstraints);
2445
2446 /* if we don't have a cached copy from before, we create one */
2447 if ((cert->certBasicConstraints == NULL) &&
2448 (!cert->basicConstraintsAbsent)) {
2449
2450 PKIX_OBJECT_LOCK(cert);
2451
2452 if ((cert->certBasicConstraints == NULL) &&
2453 (!cert->basicConstraintsAbsent)) {
2454
2455 nssCert = cert->nssCert;
2456
2457 PKIX_CERT_DEBUG(
2458 "\t\tCalling Cert_FindBasicConstraintExten\n");
2459 rv = CERT_FindBasicConstraintExten
2460 (nssCert, &nssBasicConstraint);
2461 if (rv == SECSuccess) {
2462 constraintSource = realBC;
2463 }
2464
2465 if (constraintSource == absentBC) {
2466 /* can we deduce it's a CA and create a
2467 synthetic constraint?
2468 */
2469 CERTCertTrust trust;
2470 rv = CERT_GetCertTrust(nssCert, &trust);
2471 if (rv == SECSuccess) {
2472 int anyWantedFlag = CERTDB_TRUSTED_CA | CERTDB_V ALID_CA;
2473 if ((trust.sslFlags & anyWantedFlag)
2474 || (trust.emailFlags & anyWantedFlag)
2475 || (trust.objectSigningFlags & anyWantedFlag )) {
2476
2477 constraintSource = synthBC;
2478 }
2479 }
2480 }
2481
2482 if (constraintSource == absentBC) {
2483 cert->basicConstraintsAbsent = PKIX_TRUE;
2484 *pBasicConstraints = NULL;
2485 goto cleanup;
2486 }
2487 }
2488
2489 if (constraintSource == synthBC) {
2490 isCA = PKIX_TRUE;
2491 pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
2492 } else {
2493 isCA = (nssBasicConstraint.isCA)?PKIX_TRUE:PKIX_FALSE;
2494
2495 /* The pathLen has meaning only for CAs */
2496 if (isCA) {
2497 if (CERT_UNLIMITED_PATH_CONSTRAINT ==
2498 nssBasicConstraint.pathLenConstraint) {
2499 pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
2500 } else {
2501 pathLen = nssBasicConstraint.pathLenConstraint;
2502 }
2503 }
2504 }
2505
2506 PKIX_CHECK(pkix_pl_CertBasicConstraints_Create
2507 (isCA, pathLen, &basic, plContext),
2508 PKIX_CERTBASICCONSTRAINTSCREATEFAILED);
2509
2510 /* save a cached copy in case it is asked for again */
2511 cert->certBasicConstraints = basic;
2512 }
2513
2514 PKIX_INCREF(cert->certBasicConstraints);
2515 *pBasicConstraints = cert->certBasicConstraints;
2516
2517 cleanup:
2518 PKIX_OBJECT_UNLOCK(lockedObject);
2519 PKIX_RETURN(CERT);
2520 }
2521
2522 /*
2523 * FUNCTION: PKIX_PL_Cert_GetPolicyInformation
2524 * (see comments in pkix_pl_pki.h)
2525 */
2526 PKIX_Error *
2527 PKIX_PL_Cert_GetPolicyInformation(
2528 PKIX_PL_Cert *cert,
2529 PKIX_List **pPolicyInfo,
2530 void *plContext)
2531 {
2532 PKIX_List *policyList = NULL;
2533
2534 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyInformation");
2535 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyInfo);
2536
2537 /* if we don't have a cached copy from before, we create one */
2538 if ((cert->certPolicyInfos == NULL) &&
2539 (!cert->policyInfoAbsent)) {
2540
2541 PKIX_OBJECT_LOCK(cert);
2542
2543 if ((cert->certPolicyInfos == NULL) &&
2544 (!cert->policyInfoAbsent)) {
2545
2546 PKIX_CHECK(pkix_pl_Cert_DecodePolicyInfo
2547 (cert->nssCert, &policyList, plContext),
2548 PKIX_CERTDECODEPOLICYINFOFAILED);
2549
2550 if (!policyList) {
2551 cert->policyInfoAbsent = PKIX_TRUE;
2552 *pPolicyInfo = NULL;
2553 goto cleanup;
2554 }
2555 }
2556
2557 PKIX_OBJECT_UNLOCK(cert);
2558
2559 /* save a cached copy in case it is asked for again */
2560 cert->certPolicyInfos = policyList;
2561 policyList = NULL;
2562 }
2563
2564 PKIX_INCREF(cert->certPolicyInfos);
2565 *pPolicyInfo = cert->certPolicyInfos;
2566
2567 cleanup:
2568 PKIX_OBJECT_UNLOCK(lockedObject);
2569
2570 PKIX_DECREF(policyList);
2571 PKIX_RETURN(CERT);
2572 }
2573
2574 /*
2575 * FUNCTION: PKIX_PL_Cert_GetPolicyMappings (see comments in pkix_pl_pki.h)
2576 */
2577 PKIX_Error *
2578 PKIX_PL_Cert_GetPolicyMappings(
2579 PKIX_PL_Cert *cert,
2580 PKIX_List **pPolicyMappings, /* list of PKIX_PL_CertPolicyMap */
2581 void *plContext)
2582 {
2583 PKIX_List *policyMappings = NULL; /* list of PKIX_PL_CertPolicyMap */
2584
2585 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappings");
2586 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyMappings);
2587
2588 /* if we don't have a cached copy from before, we create one */
2589 if (!(cert->certPolicyMappings) && !(cert->policyMappingsAbsent)) {
2590
2591 PKIX_OBJECT_LOCK(cert);
2592
2593 if (!(cert->certPolicyMappings) &&
2594 !(cert->policyMappingsAbsent)) {
2595
2596 PKIX_CHECK(pkix_pl_Cert_DecodePolicyMapping
2597 (cert->nssCert, &policyMappings, plContext),
2598 PKIX_CERTDECODEPOLICYMAPPINGFAILED);
2599
2600 if (!policyMappings) {
2601 cert->policyMappingsAbsent = PKIX_TRUE;
2602 *pPolicyMappings = NULL;
2603 goto cleanup;
2604 }
2605 }
2606
2607 PKIX_OBJECT_UNLOCK(cert);
2608
2609 /* save a cached copy in case it is asked for again */
2610 cert->certPolicyMappings = policyMappings;
2611 policyMappings = NULL;
2612 }
2613
2614 PKIX_INCREF(cert->certPolicyMappings);
2615 *pPolicyMappings = cert->certPolicyMappings;
2616
2617 cleanup:
2618 PKIX_OBJECT_UNLOCK(lockedObject);
2619
2620 PKIX_DECREF(policyMappings);
2621 PKIX_RETURN(CERT);
2622 }
2623
2624 /*
2625 * FUNCTION: PKIX_PL_Cert_GetRequireExplicitPolicy
2626 * (see comments in pkix_pl_pki.h)
2627 */
2628 PKIX_Error *
2629 PKIX_PL_Cert_GetRequireExplicitPolicy(
2630 PKIX_PL_Cert *cert,
2631 PKIX_Int32 *pSkipCerts,
2632 void *plContext)
2633 {
2634 PKIX_Int32 explicitPolicySkipCerts = 0;
2635 PKIX_Int32 inhibitMappingSkipCerts = 0;
2636
2637 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetRequireExplicitPolicy");
2638 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
2639
2640 if (!(cert->policyConstraintsProcessed)) {
2641 PKIX_OBJECT_LOCK(cert);
2642
2643 if (!(cert->policyConstraintsProcessed)) {
2644
2645 /*
2646 * If we can't process it now, we probably will be
2647 * unable to process it later. Set the default value.
2648 */
2649 cert->policyConstraintsProcessed = PKIX_TRUE;
2650 cert->policyConstraintsExplicitPolicySkipCerts = -1;
2651 cert->policyConstraintsInhibitMappingSkipCerts = -1;
2652
2653 PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
2654 (cert->nssCert,
2655 &explicitPolicySkipCerts,
2656 &inhibitMappingSkipCerts,
2657 plContext),
2658 PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
2659
2660 cert->policyConstraintsExplicitPolicySkipCerts =
2661 explicitPolicySkipCerts;
2662 cert->policyConstraintsInhibitMappingSkipCerts =
2663 inhibitMappingSkipCerts;
2664 }
2665
2666 PKIX_OBJECT_UNLOCK(cert);
2667 }
2668
2669 *pSkipCerts = cert->policyConstraintsExplicitPolicySkipCerts;
2670
2671 cleanup:
2672 PKIX_OBJECT_UNLOCK(lockedObject);
2673 PKIX_RETURN(CERT);
2674 }
2675
2676 /*
2677 * FUNCTION: PKIX_PL_Cert_GetPolicyMappingInhibited
2678 * (see comments in pkix_pl_pki.h)
2679 */
2680 PKIX_Error *
2681 PKIX_PL_Cert_GetPolicyMappingInhibited(
2682 PKIX_PL_Cert *cert,
2683 PKIX_Int32 *pSkipCerts,
2684 void *plContext)
2685 {
2686 PKIX_Int32 explicitPolicySkipCerts = 0;
2687 PKIX_Int32 inhibitMappingSkipCerts = 0;
2688
2689 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappingInhibited");
2690 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
2691
2692 if (!(cert->policyConstraintsProcessed)) {
2693 PKIX_OBJECT_LOCK(cert);
2694
2695 if (!(cert->policyConstraintsProcessed)) {
2696
2697 /*
2698 * If we can't process it now, we probably will be
2699 * unable to process it later. Set the default value.
2700 */
2701 cert->policyConstraintsProcessed = PKIX_TRUE;
2702 cert->policyConstraintsExplicitPolicySkipCerts = -1;
2703 cert->policyConstraintsInhibitMappingSkipCerts = -1;
2704
2705 PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
2706 (cert->nssCert,
2707 &explicitPolicySkipCerts,
2708 &inhibitMappingSkipCerts,
2709 plContext),
2710 PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
2711
2712 cert->policyConstraintsExplicitPolicySkipCerts =
2713 explicitPolicySkipCerts;
2714 cert->policyConstraintsInhibitMappingSkipCerts =
2715 inhibitMappingSkipCerts;
2716 }
2717
2718 PKIX_OBJECT_UNLOCK(cert);
2719 }
2720
2721 *pSkipCerts = cert->policyConstraintsInhibitMappingSkipCerts;
2722
2723 cleanup:
2724 PKIX_OBJECT_UNLOCK(lockedObject);
2725 PKIX_RETURN(CERT);
2726 }
2727
2728 /*
2729 * FUNCTION: PKIX_PL_Cert_GetInhibitAnyPolicy (see comments in pkix_pl_pki.h)
2730 */
2731 PKIX_Error *
2732 PKIX_PL_Cert_GetInhibitAnyPolicy(
2733 PKIX_PL_Cert *cert,
2734 PKIX_Int32 *pSkipCerts,
2735 void *plContext)
2736 {
2737 PKIX_Int32 skipCerts = 0;
2738
2739 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetInhibitAnyPolicy");
2740 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
2741
2742 if (!(cert->inhibitAnyPolicyProcessed)) {
2743
2744 PKIX_OBJECT_LOCK(cert);
2745
2746 if (!(cert->inhibitAnyPolicyProcessed)) {
2747
2748 /*
2749 * If we can't process it now, we probably will be
2750 * unable to process it later. Set the default value.
2751 */
2752 cert->inhibitAnyPolicyProcessed = PKIX_TRUE;
2753 cert->inhibitAnySkipCerts = -1;
2754
2755 PKIX_CHECK(pkix_pl_Cert_DecodeInhibitAnyPolicy
2756 (cert->nssCert, &skipCerts, plContext),
2757 PKIX_CERTDECODEINHIBITANYPOLICYFAILED);
2758
2759 cert->inhibitAnySkipCerts = skipCerts;
2760 }
2761
2762 PKIX_OBJECT_UNLOCK(cert);
2763 }
2764
2765 cleanup:
2766 PKIX_OBJECT_UNLOCK(lockedObject);
2767 *pSkipCerts = cert->inhibitAnySkipCerts;
2768 PKIX_RETURN(CERT);
2769 }
2770
2771 /*
2772 * FUNCTION: PKIX_PL_Cert_AreCertPoliciesCritical
2773 * (see comments in pkix_pl_pki.h)
2774 */
2775 PKIX_Error *
2776 PKIX_PL_Cert_AreCertPoliciesCritical(
2777 PKIX_PL_Cert *cert,
2778 PKIX_Boolean *pCritical,
2779 void *plContext)
2780 {
2781 PKIX_Boolean criticality = PKIX_FALSE;
2782
2783 PKIX_ENTER(CERT, "PKIX_PL_Cert_AreCertPoliciesCritical");
2784 PKIX_NULLCHECK_TWO(cert, pCritical);
2785
2786 PKIX_CHECK(pkix_pl_Cert_IsExtensionCritical(
2787 cert,
2788 SEC_OID_X509_CERTIFICATE_POLICIES,
2789 &criticality,
2790 plContext),
2791 PKIX_CERTISEXTENSIONCRITICALFAILED);
2792
2793 *pCritical = criticality;
2794
2795 cleanup:
2796 PKIX_RETURN(CERT);
2797 }
2798
2799 /*
2800 * FUNCTION: PKIX_PL_Cert_VerifySignature (see comments in pkix_pl_pki.h)
2801 */
2802 PKIX_Error *
2803 PKIX_PL_Cert_VerifySignature(
2804 PKIX_PL_Cert *cert,
2805 PKIX_PL_PublicKey *pubKey,
2806 void *plContext)
2807 {
2808 CERTCertificate *nssCert = NULL;
2809 SECKEYPublicKey *nssPubKey = NULL;
2810 CERTSignedData *tbsCert = NULL;
2811 PKIX_PL_Cert *cachedCert = NULL;
2812 PKIX_Error *verifySig = NULL;
2813 PKIX_Error *cachedSig = NULL;
2814 SECStatus status;
2815 PKIX_Boolean certEqual = PKIX_FALSE;
2816 PKIX_Boolean certInHash = PKIX_FALSE;
2817 void* wincx = NULL;
2818
2819 PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifySignature");
2820 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pubKey);
2821
2822 verifySig = PKIX_PL_HashTable_Lookup
2823 (cachedCertSigTable,
2824 (PKIX_PL_Object *) pubKey,
2825 (PKIX_PL_Object **) &cachedCert,
2826 plContext);
2827
2828 if (cachedCert != NULL && verifySig == NULL) {
2829 /* Cached Signature Table lookup succeed */
2830 PKIX_EQUALS(cert, cachedCert, &certEqual, plContext,
2831 PKIX_OBJECTEQUALSFAILED);
2832 if (certEqual == PKIX_TRUE) {
2833 goto cleanup;
2834 }
2835 /* Different PubKey may hash to same value, skip add */
2836 certInHash = PKIX_TRUE;
2837 }
2838
2839 nssCert = cert->nssCert;
2840 tbsCert = &nssCert->signatureWrap;
2841
2842 PKIX_CERT_DEBUG("\t\tCalling SECKEY_ExtractPublicKey).\n");
2843 nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI);
2844 if (!nssPubKey){
2845 PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED);
2846 }
2847
2848 PKIX_CERT_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey).\n");
2849
2850 PKIX_CHECK(pkix_pl_NssContext_GetWincx
2851 ((PKIX_PL_NssContext *)plContext, &wincx),
2852 PKIX_NSSCONTEXTGETWINCXFAILED);
2853
2854 status = CERT_VerifySignedDataWithPublicKey(tbsCert, nssPubKey, wincx);
2855
2856 if (status != SECSuccess) {
2857 if (PORT_GetError() != SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABL ED) {
2858 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
2859 }
2860 PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY);
2861 }
2862
2863 if (certInHash == PKIX_FALSE) {
2864 cachedSig = PKIX_PL_HashTable_Add
2865 (cachedCertSigTable,
2866 (PKIX_PL_Object *) pubKey,
2867 (PKIX_PL_Object *) cert,
2868 plContext);
2869
2870 if (cachedSig != NULL) {
2871 PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed \n");
2872 }
2873 }
2874
2875 cleanup:
2876 if (nssPubKey){
2877 PKIX_CERT_DEBUG("\t\tCalling SECKEY_DestroyPublicKey).\n");
2878 SECKEY_DestroyPublicKey(nssPubKey);
2879 }
2880
2881 PKIX_DECREF(cachedCert);
2882 PKIX_DECREF(verifySig);
2883 PKIX_DECREF(cachedSig);
2884
2885 PKIX_RETURN(CERT);
2886 }
2887
2888 /*
2889 * FUNCTION: PKIX_PL_Cert_CheckValidity (see comments in pkix_pl_pki.h)
2890 */
2891 PKIX_Error *
2892 PKIX_PL_Cert_CheckValidity(
2893 PKIX_PL_Cert *cert,
2894 PKIX_PL_Date *date,
2895 void *plContext)
2896 {
2897 SECCertTimeValidity val;
2898 PRTime timeToCheck;
2899 PKIX_Boolean allowOverride;
2900 SECCertificateUsage requiredUsages;
2901
2902 PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckValidity");
2903 PKIX_NULLCHECK_ONE(cert);
2904
2905 /* if the caller supplies a date, we use it; else, use current time */
2906 if (date != NULL){
2907 PKIX_CHECK(pkix_pl_Date_GetPRTime
2908 (date, &timeToCheck, plContext),
2909 PKIX_DATEGETPRTIMEFAILED);
2910 } else {
2911 timeToCheck = PR_Now();
2912 }
2913
2914 requiredUsages = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
2915 allowOverride =
2916 (PRBool)((requiredUsages & certificateUsageSSLServer) ||
2917 (requiredUsages & certificateUsageSSLServerWithStepUp));
2918 val = CERT_CheckCertValidTimes(cert->nssCert, timeToCheck, allowOverride );
2919 if (val != secCertTimeValid){
2920 PKIX_ERROR(PKIX_CERTCHECKCERTVALIDTIMESFAILED);
2921 }
2922
2923 cleanup:
2924 PKIX_RETURN(CERT);
2925 }
2926
2927 /*
2928 * FUNCTION: PKIX_PL_Cert_GetValidityNotAfter (see comments in pkix_pl_pki.h)
2929 */
2930 PKIX_Error *
2931 PKIX_PL_Cert_GetValidityNotAfter(
2932 PKIX_PL_Cert *cert,
2933 PKIX_PL_Date **pDate,
2934 void *plContext)
2935 {
2936 PRTime prtime;
2937 SECStatus rv = SECFailure;
2938
2939 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetValidityNotAfter");
2940 PKIX_NULLCHECK_TWO(cert, pDate);
2941
2942 PKIX_DATE_DEBUG("\t\tCalling DER_DecodeTimeChoice).\n");
2943 rv = DER_DecodeTimeChoice(&prtime, &(cert->nssCert->validity.notAfter));
2944 if (rv != SECSuccess){
2945 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED);
2946 }
2947
2948 PKIX_CHECK(pkix_pl_Date_CreateFromPRTime
2949 (prtime, pDate, plContext),
2950 PKIX_DATECREATEFROMPRTIMEFAILED);
2951
2952 cleanup:
2953 PKIX_RETURN(CERT);
2954 }
2955
2956 /*
2957 * FUNCTION: PKIX_PL_Cert_VerifyCertAndKeyType (see comments in pkix_pl_pki.h)
2958 */
2959 PKIX_Error *
2960 PKIX_PL_Cert_VerifyCertAndKeyType(
2961 PKIX_PL_Cert *cert,
2962 PKIX_Boolean isChainCert,
2963 void *plContext)
2964 {
2965 PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
2966 SECCertificateUsage certificateUsage;
2967 SECCertUsage certUsage = 0;
2968 unsigned int requiredKeyUsage;
2969 unsigned int requiredCertType;
2970 unsigned int certType;
2971 SECStatus rv = SECSuccess;
2972
2973 PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyCertType");
2974 PKIX_NULLCHECK_TWO(cert, plContext);
2975
2976 certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
2977
2978 /* ensure we obtained a single usage bit only */
2979 PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
2980
2981 /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
2982 while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
2983
2984 /* check key usage and netscape cert type */
2985 cert_GetCertType(cert->nssCert);
2986 certType = cert->nssCert->nsCertType;
2987 if (isChainCert ||
2988 (certUsage != certUsageVerifyCA && certUsage != certUsageAnyCA)) {
2989 rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, isChainCert,
2990 &requiredKeyUsage,
2991 &requiredCertType);
2992 if (rv == SECFailure) {
2993 PKIX_ERROR(PKIX_UNSUPPORTEDCERTUSAGE);
2994 }
2995 } else {
2996 /* use this key usage and cert type for certUsageAnyCA and
2997 * certUsageVerifyCA. */
2998 requiredKeyUsage = KU_KEY_CERT_SIGN;
2999 requiredCertType = NS_CERT_TYPE_CA;
3000 }
3001 if (CERT_CheckKeyUsage(cert->nssCert, requiredKeyUsage) != SECSuccess) {
3002 PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED);
3003 }
3004 if (!(certType & requiredCertType)) {
3005 PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED);
3006 }
3007 cleanup:
3008 PKIX_DECREF(basicConstraints);
3009 PKIX_RETURN(CERT);
3010 }
3011
3012 /*
3013 * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h)
3014 */
3015 PKIX_Error *
3016 PKIX_PL_Cert_VerifyKeyUsage(
3017 PKIX_PL_Cert *cert,
3018 PKIX_UInt32 keyUsage,
3019 void *plContext)
3020 {
3021 CERTCertificate *nssCert = NULL;
3022 PKIX_UInt32 nssKeyUsage = 0;
3023 SECStatus status;
3024
3025 PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyKeyUsage");
3026 PKIX_NULLCHECK_TWO(cert, cert->nssCert);
3027
3028 nssCert = cert->nssCert;
3029
3030 /* if cert doesn't have keyUsage extension, all keyUsages are valid */
3031 if (!nssCert->keyUsagePresent){
3032 goto cleanup;
3033 }
3034
3035 if (keyUsage & PKIX_DIGITAL_SIGNATURE){
3036 nssKeyUsage = nssKeyUsage | KU_DIGITAL_SIGNATURE;
3037 }
3038
3039 if (keyUsage & PKIX_NON_REPUDIATION){
3040 nssKeyUsage = nssKeyUsage | KU_NON_REPUDIATION;
3041 }
3042
3043 if (keyUsage & PKIX_KEY_ENCIPHERMENT){
3044 nssKeyUsage = nssKeyUsage | KU_KEY_ENCIPHERMENT;
3045 }
3046
3047 if (keyUsage & PKIX_DATA_ENCIPHERMENT){
3048 nssKeyUsage = nssKeyUsage | KU_DATA_ENCIPHERMENT;
3049 }
3050
3051 if (keyUsage & PKIX_KEY_AGREEMENT){
3052 nssKeyUsage = nssKeyUsage | KU_KEY_AGREEMENT;
3053 }
3054
3055 if (keyUsage & PKIX_KEY_CERT_SIGN){
3056 nssKeyUsage = nssKeyUsage | KU_KEY_CERT_SIGN;
3057 }
3058
3059 if (keyUsage & PKIX_CRL_SIGN){
3060 nssKeyUsage = nssKeyUsage | KU_CRL_SIGN;
3061 }
3062
3063 if (keyUsage & PKIX_ENCIPHER_ONLY){
3064 nssKeyUsage = nssKeyUsage | 0x01;
3065 }
3066
3067 if (keyUsage & PKIX_DECIPHER_ONLY){
3068 /* XXX we should support this once it is fixed in NSS */
3069 PKIX_ERROR(PKIX_DECIPHERONLYKEYUSAGENOTSUPPORTED);
3070 }
3071
3072 status = CERT_CheckKeyUsage(nssCert, nssKeyUsage);
3073 if (status != SECSuccess) {
3074 PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED);
3075 }
3076
3077 cleanup:
3078 PKIX_RETURN(CERT);
3079 }
3080
3081 /*
3082 * FUNCTION: PKIX_PL_Cert_GetNameConstraints
3083 * (see comments in pkix_pl_pki.h)
3084 */
3085 PKIX_Error *
3086 PKIX_PL_Cert_GetNameConstraints(
3087 PKIX_PL_Cert *cert,
3088 PKIX_PL_CertNameConstraints **pNameConstraints,
3089 void *plContext)
3090 {
3091 PKIX_PL_CertNameConstraints *nameConstraints = NULL;
3092
3093 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNameConstraints");
3094 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pNameConstraints);
3095
3096 /* if we don't have a cached copy from before, we create one */
3097 if (cert->nameConstraints == NULL && !cert->nameConstraintsAbsent) {
3098
3099 PKIX_OBJECT_LOCK(cert);
3100
3101 if (cert->nameConstraints == NULL &&
3102 !cert->nameConstraintsAbsent) {
3103
3104 PKIX_CHECK(pkix_pl_CertNameConstraints_Create
3105 (cert->nssCert, &nameConstraints, plContext),
3106 PKIX_CERTNAMECONSTRAINTSCREATEFAILED);
3107
3108 if (nameConstraints == NULL) {
3109 cert->nameConstraintsAbsent = PKIX_TRUE;
3110 }
3111
3112 cert->nameConstraints = nameConstraints;
3113 }
3114
3115 PKIX_OBJECT_UNLOCK(cert);
3116
3117 }
3118
3119 PKIX_INCREF(cert->nameConstraints);
3120
3121 *pNameConstraints = cert->nameConstraints;
3122
3123 cleanup:
3124 PKIX_OBJECT_UNLOCK(lockedObject);
3125 PKIX_RETURN(CERT);
3126 }
3127
3128 /*
3129 * FUNCTION: PKIX_PL_Cert_CheckNameConstraints
3130 * (see comments in pkix_pl_pki.h)
3131 */
3132 PKIX_Error *
3133 PKIX_PL_Cert_CheckNameConstraints(
3134 PKIX_PL_Cert *cert,
3135 PKIX_PL_CertNameConstraints *nameConstraints,
3136 PKIX_Boolean treatCommonNameAsDNSName,
3137 void *plContext)
3138 {
3139 PKIX_Boolean checkPass = PKIX_TRUE;
3140 CERTGeneralName *nssSubjectNames = NULL;
3141 PLArenaPool *arena = NULL;
3142
3143 PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckNameConstraints");
3144 PKIX_NULLCHECK_ONE(cert);
3145
3146 if (nameConstraints != NULL) {
3147
3148 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
3149 if (arena == NULL) {
3150 PKIX_ERROR(PKIX_OUTOFMEMORY);
3151 }
3152
3153 /* This NSS call returns Subject Alt Names. If
3154 * treatCommonNameAsDNSName is true, it also returns the
3155 * Subject Common Name
3156 */
3157 PKIX_CERT_DEBUG
3158 ("\t\tCalling CERT_GetConstrainedCertificateNames\n");
3159 nssSubjectNames = CERT_GetConstrainedCertificateNames
3160 (cert->nssCert, arena, treatCommonNameAsDNSName);
3161
3162 PKIX_CHECK(pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
3163 (nssSubjectNames,
3164 nameConstraints,
3165 &checkPass,
3166 plContext),
3167 PKIX_CERTNAMECONSTRAINTSCHECKNAMESPACENSSNAMESFAILED);
3168
3169 if (checkPass != PKIX_TRUE) {
3170 PKIX_ERROR(PKIX_CERTFAILEDNAMECONSTRAINTSCHECKING);
3171 }
3172 }
3173
3174 cleanup:
3175 if (arena){
3176 PORT_FreeArena(arena, PR_FALSE);
3177 }
3178
3179 PKIX_RETURN(CERT);
3180 }
3181
3182 /*
3183 * FUNCTION: PKIX_PL_Cert_MergeNameConstraints
3184 * (see comments in pkix_pl_pki.h)
3185 */
3186 PKIX_Error *
3187 PKIX_PL_Cert_MergeNameConstraints(
3188 PKIX_PL_CertNameConstraints *firstNC,
3189 PKIX_PL_CertNameConstraints *secondNC,
3190 PKIX_PL_CertNameConstraints **pResultNC,
3191 void *plContext)
3192 {
3193 PKIX_PL_CertNameConstraints *mergedNC = NULL;
3194
3195 PKIX_ENTER(CERT, "PKIX_PL_Cert_MergeNameConstraints");
3196 PKIX_NULLCHECK_TWO(firstNC, pResultNC);
3197
3198 if (secondNC == NULL) {
3199
3200 PKIX_INCREF(firstNC);
3201 *pResultNC = firstNC;
3202
3203 goto cleanup;
3204 }
3205
3206 PKIX_CHECK(pkix_pl_CertNameConstraints_Merge
3207 (firstNC, secondNC, &mergedNC, plContext),
3208 PKIX_CERTNAMECONSTRAINTSMERGEFAILED);
3209
3210 *pResultNC = mergedNC;
3211
3212 cleanup:
3213 PKIX_RETURN(CERT);
3214 }
3215
3216 /*
3217 * Find out the state of the NSS trust bits for the requested usage.
3218 * Returns SECFailure if the cert is explicitly distrusted.
3219 * Returns SECSuccess if the cert can be used to form a chain (normal case),
3220 * or it is explicitly trusted. The trusted bool is set to true if it is
3221 * explicitly trusted.
3222 */
3223 static SECStatus
3224 pkix_pl_Cert_GetTrusted(void *plContext,
3225 PKIX_PL_Cert *cert,
3226 PKIX_Boolean *trusted,
3227 PKIX_Boolean isCA)
3228 {
3229 SECStatus rv;
3230 CERTCertificate *nssCert = NULL;
3231 SECCertUsage certUsage = 0;
3232 SECCertificateUsage certificateUsage;
3233 SECTrustType trustType;
3234 unsigned int trustFlags;
3235 unsigned int requiredFlags;
3236 CERTCertTrust trust;
3237
3238 *trusted = PKIX_FALSE;
3239
3240 /* no key usage information */
3241 if (plContext == NULL) {
3242 return SECSuccess;
3243 }
3244
3245 certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
3246
3247 /* ensure we obtained a single usage bit only */
3248 PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
3249
3250 /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
3251 while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
3252
3253 nssCert = cert->nssCert;
3254
3255 if (!isCA) {
3256 PRBool prTrusted;
3257 unsigned int failedFlags;
3258 rv = cert_CheckLeafTrust(nssCert, certUsage,
3259 &failedFlags, &prTrusted);
3260 *trusted = (PKIX_Boolean) prTrusted;
3261 return rv;
3262 }
3263 rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
3264 &trustType);
3265 if (rv != SECSuccess) {
3266 return SECSuccess;
3267 }
3268
3269 rv = CERT_GetCertTrust(nssCert, &trust);
3270 if (rv != SECSuccess) {
3271 return SECSuccess;
3272 }
3273 trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType);
3274 /* normally trustTypeNone usages accept any of the given trust bits
3275 * being on as acceptable. If any are distrusted (and none are trusted),
3276 * then we will also distrust the cert */
3277 if ((trustFlags == 0) && (trustType == trustTypeNone)) {
3278 trustFlags = trust.sslFlags | trust.emailFlags |
3279 trust.objectSigningFlags;
3280 }
3281 if ((trustFlags & requiredFlags) == requiredFlags) {
3282 *trusted = PKIX_TRUE;
3283 return SECSuccess;
3284 }
3285 if ((trustFlags & CERTDB_TERMINAL_RECORD) &&
3286 ((trustFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
3287 return SECFailure;
3288 }
3289 return SECSuccess;
3290 }
3291
3292 /*
3293 * FUNCTION: PKIX_PL_Cert_IsCertTrusted
3294 * (see comments in pkix_pl_pki.h)
3295 */
3296 PKIX_Error *
3297 PKIX_PL_Cert_IsCertTrusted(
3298 PKIX_PL_Cert *cert,
3299 PKIX_PL_TrustAnchorMode trustAnchorMode,
3300 PKIX_Boolean *pTrusted,
3301 void *plContext)
3302 {
3303 PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
3304 PKIX_Boolean trusted = PKIX_FALSE;
3305 SECStatus rv = SECFailure;
3306
3307 PKIX_ENTER(CERT, "PKIX_PL_Cert_IsCertTrusted");
3308 PKIX_NULLCHECK_TWO(cert, pTrusted);
3309
3310 /* Call GetTrusted first to see if we are going to distrust the
3311 * certificate */
3312 rv = pkix_pl_Cert_GetTrusted(plContext, cert, &trusted, PKIX_TRUE);
3313 if (rv != SECSuccess) {
3314 /* Failure means the cert is explicitly distrusted,
3315 * let the next level know not to use it. */
3316 *pTrusted = PKIX_FALSE;
3317 PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
3318 }
3319
3320 if (trustAnchorMode == PKIX_PL_TrustAnchorMode_Exclusive ||
3321 (trustAnchorMode == PKIX_PL_TrustAnchorMode_Additive &&
3322 cert->isUserTrustAnchor)) {
3323 /* Use the trust anchor's |trusted| value */
3324 *pTrusted = cert->isUserTrustAnchor;
3325 goto cleanup;
3326 }
3327
3328 /* no key usage information or store is not trusted */
3329 if (plContext == NULL || cert->store == NULL) {
3330 *pTrusted = PKIX_FALSE;
3331 goto cleanup;
3332 }
3333
3334 PKIX_CHECK(PKIX_CertStore_GetTrustCallback
3335 (cert->store, &trustCallback, plContext),
3336 PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
3337
3338 PKIX_CHECK_ONLY_FATAL(trustCallback
3339 (cert->store, cert, &trusted, plContext),
3340 PKIX_CHECKTRUSTCALLBACKFAILED);
3341
3342 /* allow trust store to override if we can trust the trust
3343 * bits */
3344 if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
3345 *pTrusted = PKIX_FALSE;
3346 goto cleanup;
3347 }
3348
3349 *pTrusted = trusted;
3350
3351 cleanup:
3352 PKIX_RETURN(CERT);
3353 }
3354
3355 /*
3356 * FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted
3357 * (see comments in pkix_pl_pki.h)
3358 */
3359 PKIX_Error *
3360 PKIX_PL_Cert_IsLeafCertTrusted(
3361 PKIX_PL_Cert *cert,
3362 PKIX_Boolean *pTrusted,
3363 void *plContext)
3364 {
3365 SECStatus rv;
3366
3367 PKIX_ENTER(CERT, "PKIX_PL_Cert_IsLeafCertTrusted");
3368 PKIX_NULLCHECK_TWO(cert, pTrusted);
3369
3370 *pTrusted = PKIX_FALSE;
3371
3372 rv = pkix_pl_Cert_GetTrusted(plContext, cert, pTrusted, PKIX_FALSE);
3373 if (rv != SECSuccess) {
3374 /* Failure means the cert is explicitly distrusted,
3375 * let the next level know not to use it. */
3376 *pTrusted = PKIX_FALSE;
3377 PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
3378 }
3379
3380 cleanup:
3381 PKIX_RETURN(CERT);
3382 }
3383
3384 /* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
3385 PKIX_Error*
3386 PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert,
3387 void *plContext)
3388 {
3389 PKIX_ENTER(CERT, "PKIX_PL_Cert_SetAsTrustAnchor");
3390 PKIX_NULLCHECK_ONE(cert);
3391
3392 cert->isUserTrustAnchor = PKIX_TRUE;
3393
3394 PKIX_RETURN(CERT);
3395 }
3396
3397 /*
3398 * FUNCTION: PKIX_PL_Cert_GetCacheFlag (see comments in pkix_pl_pki.h)
3399 */
3400 PKIX_Error *
3401 PKIX_PL_Cert_GetCacheFlag(
3402 PKIX_PL_Cert *cert,
3403 PKIX_Boolean *pCacheFlag,
3404 void *plContext)
3405 {
3406 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCacheFlag");
3407 PKIX_NULLCHECK_TWO(cert, pCacheFlag);
3408
3409 *pCacheFlag = cert->cacheFlag;
3410
3411 PKIX_RETURN(CERT);
3412 }
3413
3414 /*
3415 * FUNCTION: PKIX_PL_Cert_SetCacheFlag (see comments in pkix_pl_pki.h)
3416 */
3417 PKIX_Error *
3418 PKIX_PL_Cert_SetCacheFlag(
3419 PKIX_PL_Cert *cert,
3420 PKIX_Boolean cacheFlag,
3421 void *plContext)
3422 {
3423 PKIX_ENTER(CERT, "PKIX_PL_Cert_SetCacheFlag");
3424 PKIX_NULLCHECK_ONE(cert);
3425
3426 cert->cacheFlag = cacheFlag;
3427
3428 PKIX_RETURN(CERT);
3429 }
3430
3431 /*
3432 * FUNCTION: PKIX_PL_Cert_GetTrustCertStore (see comments in pkix_pl_pki.h)
3433 */
3434 PKIX_Error *
3435 PKIX_PL_Cert_GetTrustCertStore(
3436 PKIX_PL_Cert *cert,
3437 PKIX_CertStore **pTrustCertStore,
3438 void *plContext)
3439 {
3440 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetTrustCertStore");
3441 PKIX_NULLCHECK_TWO(cert, pTrustCertStore);
3442
3443 PKIX_INCREF(cert->store);
3444 *pTrustCertStore = cert->store;
3445
3446 cleanup:
3447 PKIX_RETURN(CERT);
3448 }
3449
3450 /*
3451 * FUNCTION: PKIX_PL_Cert_SetTrustCertStore (see comments in pkix_pl_pki.h)
3452 */
3453 PKIX_Error *
3454 PKIX_PL_Cert_SetTrustCertStore(
3455 PKIX_PL_Cert *cert,
3456 PKIX_CertStore *trustCertStore,
3457 void *plContext)
3458 {
3459 PKIX_ENTER(CERT, "PKIX_PL_Cert_SetTrustCertStore");
3460 PKIX_NULLCHECK_TWO(cert, trustCertStore);
3461
3462 PKIX_INCREF(trustCertStore);
3463 cert->store = trustCertStore;
3464
3465 cleanup:
3466 PKIX_RETURN(CERT);
3467 }
3468
3469 /*
3470 * FUNCTION: PKIX_PL_Cert_GetAuthorityInfoAccess
3471 * (see comments in pkix_pl_pki.h)
3472 */
3473 PKIX_Error *
3474 PKIX_PL_Cert_GetAuthorityInfoAccess(
3475 PKIX_PL_Cert *cert,
3476 PKIX_List **pAiaList, /* of PKIX_PL_InfoAccess */
3477 void *plContext)
3478 {
3479 PKIX_List *aiaList = NULL; /* of PKIX_PL_InfoAccess */
3480 SECItem *encodedAIA = NULL;
3481 CERTAuthInfoAccess **aia = NULL;
3482 PLArenaPool *arena = NULL;
3483 SECStatus rv;
3484
3485 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityInfoAccess");
3486 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAiaList);
3487
3488 /* if we don't have a cached copy from before, we create one */
3489 if (cert->authorityInfoAccess == NULL) {
3490
3491 PKIX_OBJECT_LOCK(cert);
3492
3493 if (cert->authorityInfoAccess == NULL) {
3494
3495 PKIX_PL_NSSCALLRV(CERT, encodedAIA, SECITEM_AllocItem,
3496 (NULL, NULL, 0));
3497
3498 if (encodedAIA == NULL) {
3499 PKIX_ERROR(PKIX_OUTOFMEMORY);
3500 }
3501
3502 PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
3503 (cert->nssCert,
3504 SEC_OID_X509_AUTH_INFO_ACCESS,
3505 encodedAIA));
3506
3507 if (rv == SECFailure) {
3508 goto cleanup;
3509 }
3510
3511 PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
3512 (DER_DEFAULT_CHUNKSIZE));
3513
3514 if (arena == NULL) {
3515 PKIX_ERROR(PKIX_OUTOFMEMORY);
3516 }
3517
3518 PKIX_PL_NSSCALLRV
3519 (CERT, aia, CERT_DecodeAuthInfoAccessExtension,
3520 (arena, encodedAIA));
3521
3522 PKIX_CHECK(pkix_pl_InfoAccess_CreateList
3523 (aia, &aiaList, plContext),
3524 PKIX_INFOACCESSCREATELISTFAILED);
3525
3526 cert->authorityInfoAccess = aiaList;
3527 }
3528
3529 PKIX_OBJECT_UNLOCK(cert);
3530 }
3531
3532 PKIX_INCREF(cert->authorityInfoAccess);
3533
3534 *pAiaList = cert->authorityInfoAccess;
3535
3536 cleanup:
3537 PKIX_OBJECT_UNLOCK(lockedObject);
3538 if (arena != NULL) {
3539 PORT_FreeArena(arena, PR_FALSE);
3540 }
3541
3542 if (encodedAIA != NULL) {
3543 SECITEM_FreeItem(encodedAIA, PR_TRUE);
3544 }
3545
3546 PKIX_RETURN(CERT);
3547 }
3548
3549 /* XXX Following defines belongs to NSS */
3550 static const unsigned char siaOIDString[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
3551 0x07, 0x01, 0x0b};
3552 #define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
3553
3554 /*
3555 * FUNCTION: PKIX_PL_Cert_GetSubjectInfoAccess
3556 * (see comments in pkix_pl_pki.h)
3557 */
3558 PKIX_Error *
3559 PKIX_PL_Cert_GetSubjectInfoAccess(
3560 PKIX_PL_Cert *cert,
3561 PKIX_List **pSiaList, /* of PKIX_PL_InfoAccess */
3562 void *plContext)
3563 {
3564 PKIX_List *siaList; /* of PKIX_PL_InfoAccess */
3565 SECItem siaOID = OI(siaOIDString);
3566 SECItem *encodedSubjInfoAccess = NULL;
3567 CERTAuthInfoAccess **subjInfoAccess = NULL;
3568 PLArenaPool *arena = NULL;
3569 SECStatus rv;
3570
3571 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectInfoAccess");
3572 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSiaList);
3573
3574 /* XXX
3575 * Codes to deal with SubjectInfoAccess OID should be moved to
3576 * NSS soon. I implemented them here so we don't touch NSS
3577 * source tree, from JP's suggestion.
3578 */
3579
3580 /* if we don't have a cached copy from before, we create one */
3581 if (cert->subjectInfoAccess == NULL) {
3582
3583 PKIX_OBJECT_LOCK(cert);
3584
3585 if (cert->subjectInfoAccess == NULL) {
3586
3587 encodedSubjInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
3588 if (encodedSubjInfoAccess == NULL) {
3589 PKIX_ERROR(PKIX_OUTOFMEMORY);
3590 }
3591
3592 PKIX_CERT_DEBUG
3593 ("\t\tCalling CERT_FindCertExtensionByOID).\n");
3594 rv = CERT_FindCertExtensionByOID
3595 (cert->nssCert, &siaOID, encodedSubjInfoAccess);
3596
3597 if (rv == SECFailure) {
3598 goto cleanup;
3599 }
3600
3601 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
3602 if (arena == NULL) {
3603 PKIX_ERROR(PKIX_OUTOFMEMORY);
3604 }
3605
3606 /* XXX
3607 * Decode Subject Information Access -
3608 * since its type is the same as Authority Information
3609 * Access, reuse the call. NSS- change name to avoid
3610 * confusion.
3611 */
3612 PKIX_CERT_DEBUG
3613 ("\t\tCalling CERT_DecodeAuthInfoAccessExtension).\n");
3614 subjInfoAccess = CERT_DecodeAuthInfoAccessExtension
3615 (arena, encodedSubjInfoAccess);
3616
3617 PKIX_CHECK(pkix_pl_InfoAccess_CreateList
3618 (subjInfoAccess, &siaList, plContext),
3619 PKIX_INFOACCESSCREATELISTFAILED);
3620
3621 cert->subjectInfoAccess = siaList;
3622
3623 }
3624
3625 PKIX_OBJECT_UNLOCK(cert);
3626 }
3627
3628 PKIX_INCREF(cert->subjectInfoAccess);
3629 *pSiaList = cert->subjectInfoAccess;
3630
3631 cleanup:
3632 PKIX_OBJECT_UNLOCK(lockedObject);
3633 if (arena != NULL) {
3634 PORT_FreeArena(arena, PR_FALSE);
3635 }
3636
3637 if (encodedSubjInfoAccess != NULL) {
3638 SECITEM_FreeItem(encodedSubjInfoAccess, PR_TRUE);
3639 }
3640 PKIX_RETURN(CERT);
3641 }
3642
3643 /*
3644 * FUNCTION: PKIX_PL_Cert_GetCrlDp
3645 * (see comments in pkix_pl_pki.h)
3646 */
3647 PKIX_Error *
3648 PKIX_PL_Cert_GetCrlDp(
3649 PKIX_PL_Cert *cert,
3650 PKIX_List **pDpList,
3651 void *plContext)
3652 {
3653 PKIX_UInt32 dpIndex = 0;
3654 pkix_pl_CrlDp *dp = NULL;
3655 CERTCrlDistributionPoints *dpoints = NULL;
3656
3657 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCrlDp");
3658 PKIX_NULLCHECK_THREE(cert, cert->nssCert, pDpList);
3659
3660 /* if we don't have a cached copy from before, we create one */
3661 if (cert->crldpList == NULL) {
3662 PKIX_OBJECT_LOCK(cert);
3663 if (cert->crldpList != NULL) {
3664 goto cleanup;
3665 }
3666 PKIX_CHECK(PKIX_List_Create(&cert->crldpList, plContext),
3667 PKIX_LISTCREATEFAILED);
3668 dpoints = CERT_FindCRLDistributionPoints(cert->nssCert);
3669 if (!dpoints || !dpoints->distPoints) {
3670 goto cleanup;
3671 }
3672 for (;dpoints->distPoints[dpIndex];dpIndex++) {
3673 PKIX_CHECK(
3674 pkix_pl_CrlDp_Create(dpoints->distPoints[dpIndex],
3675 &cert->nssCert->issuer,
3676 &dp, plContext),
3677 PKIX_CRLDPCREATEFAILED);
3678 /* Create crldp list in reverse order in attempt to get
3679 * to the whole crl first. */
3680 PKIX_CHECK(
3681 PKIX_List_InsertItem(cert->crldpList, 0,
3682 (PKIX_PL_Object*)dp,
3683 plContext),
3684 PKIX_LISTAPPENDITEMFAILED);
3685 PKIX_DECREF(dp);
3686 }
3687 }
3688 cleanup:
3689 PKIX_INCREF(cert->crldpList);
3690 *pDpList = cert->crldpList;
3691
3692 PKIX_OBJECT_UNLOCK(lockedObject);
3693 PKIX_DECREF(dp);
3694
3695 PKIX_RETURN(CERT);
3696 }
3697
3698 /*
3699 * FUNCTION: PKIX_PL_Cert_GetCERTCertificate
3700 * (see comments in pkix_pl_pki.h)
3701 */
3702 PKIX_Error *
3703 PKIX_PL_Cert_GetCERTCertificate(
3704 PKIX_PL_Cert *cert,
3705 CERTCertificate **pnssCert,
3706 void *plContext)
3707 {
3708 PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNssCert");
3709 PKIX_NULLCHECK_TWO(cert, pnssCert);
3710
3711 *pnssCert = CERT_DupCertificate(cert->nssCert);
3712
3713 PKIX_RETURN(CERT);
3714 }
OLDNEW
« no previous file with comments | « nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h ('k') | nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698