1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
40 * Certificate Object Functions
44 #include "pkix_pl_cert.h"
46 extern PKIX_PL_HashTable
*cachedCertSigTable
;
48 /* --Private-Cert-Functions------------------------------------- */
51 * FUNCTION: pkix_pl_Cert_IsExtensionCritical
54 * Checks the Cert specified by "cert" to determine whether the extension
55 * whose tag is the UInt32 value given by "tag" is marked as a critical
56 * extension, and stores the result in "pCritical".
58 * Tags are the index into the table "oids" of SECOidData defined in the
59 * file secoid.c. Constants, such as SEC_OID_X509_CERTIFICATE_POLICIES, are
60 * are defined in secoidt.h for most of the table entries.
62 * If the specified tag is invalid (not in the list of tags) or if the
63 * extension is not found in the certificate, PKIX_FALSE is stored.
67 * Address of Cert whose extensions are to be examined. Must be non-NULL.
69 * The UInt32 value of the tag for the extension whose criticality is
72 * Address where the Boolean value will be stored. Must be non-NULL.
74 * Platform-specific context pointer.
76 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
78 * Returns NULL if the function succeeds.
79 * Returns a Fatal Error if the function fails in an unrecoverable way.
82 pkix_pl_Cert_IsExtensionCritical(
85 PKIX_Boolean
*pCritical
,
88 PKIX_Boolean criticality
= PKIX_FALSE
;
89 CERTCertExtension
**extensions
= NULL
;
92 PKIX_ENTER(CERT
, "pkix_pl_Cert_IsExtensionCritical");
93 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pCritical
);
95 extensions
= cert
->nssCert
->extensions
;
96 PKIX_NULLCHECK_ONE(extensions
);
98 PKIX_CERT_DEBUG("\t\tCalling CERT_GetExtenCriticality).\n");
99 rv
= CERT_GetExtenCriticality(extensions
, tag
, &criticality
);
100 if (SECSuccess
== rv
) {
101 *pCritical
= criticality
;
103 *pCritical
= PKIX_FALSE
;
110 * FUNCTION: pkix_pl_Cert_DecodePolicyInfo
113 * Decodes the contents of the CertificatePolicy extension in the
114 * CERTCertificate pointed to by "nssCert", to create a List of
115 * CertPolicyInfos, which is stored at the address "pCertPolicyInfos".
116 * A CERTCertificate contains the DER representation of the Cert.
117 * If this certificate does not have a CertificatePolicy extension,
118 * NULL will be stored. If a List is returned, it will be immutable.
122 * Address of the Cert data whose extension is to be examined. Must be
125 * Address where the List of CertPolicyInfos will be stored. Must be
128 * Platform-specific context pointer.
130 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
132 * Returns NULL if the function succeeds.
133 * Returns a Cert Error if the function fails in a non-fatal way.
134 * Returns a Fatal Error if the function fails in an unrecoverable way.
137 pkix_pl_Cert_DecodePolicyInfo(
138 CERTCertificate
*nssCert
,
139 PKIX_List
**pCertPolicyInfos
,
144 SECItem encodedCertPolicyInfo
;
146 /* Allocated in the arena; freed in CERT_Destroy... */
147 CERTCertificatePolicies
*certPol
= NULL
;
148 CERTPolicyInfo
**policyInfos
= NULL
;
149 CERTPolicyInfo
*policyInfo
= NULL
;
150 CERTPolicyQualifier
**policyQualifiers
= NULL
;
151 CERTPolicyQualifier
*policyQualifier
= NULL
;
153 /* Holder for the return value */
154 PKIX_List
*infos
= NULL
;
156 char *oidAscii
= NULL
;
157 PKIX_PL_OID
*pkixOID
= NULL
;
158 PKIX_List
*qualifiers
= NULL
;
159 PKIX_PL_CertPolicyInfo
*certPolicyInfo
= NULL
;
160 PKIX_PL_CertPolicyQualifier
*certPolicyQualifier
= NULL
;
161 PKIX_PL_ByteArray
*qualifierArray
= NULL
;
163 PKIX_ENTER(CERT
, "pkix_pl_Cert_DecodePolicyInfo");
164 PKIX_NULLCHECK_TWO(nssCert
, pCertPolicyInfos
);
166 /* get PolicyInfo as a SECItem */
167 PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
168 rv
= CERT_FindCertExtension
170 SEC_OID_X509_CERTIFICATE_POLICIES
,
171 &encodedCertPolicyInfo
);
172 if (SECSuccess
!= rv
) {
173 *pCertPolicyInfos
= NULL
;
177 /* translate PolicyInfo to CERTCertificatePolicies */
178 PKIX_CERT_DEBUG("\t\tCERT_DecodeCertificatePoliciesExtension).\n");
179 certPol
= CERT_DecodeCertificatePoliciesExtension
180 (&encodedCertPolicyInfo
);
182 PKIX_CERT_DEBUG("\t\tCalling PORT_Free).\n");
183 PORT_Free(encodedCertPolicyInfo
.data
);
185 if (NULL
== certPol
) {
186 PKIX_ERROR(PKIX_CERTDECODECERTIFICATEPOLICIESEXTENSIONFAILED
);
190 * Check whether there are any policyInfos, so we can
191 * avoid creating an unnecessary List
193 policyInfos
= certPol
->policyInfos
;
195 *pCertPolicyInfos
= NULL
;
199 /* create a List of CertPolicyInfo Objects */
200 PKIX_CHECK(PKIX_List_Create(&infos
, plContext
),
201 PKIX_LISTCREATEFAILED
);
204 * Traverse the CERTCertificatePolicies structure,
205 * building each PKIX_PL_CertPolicyInfo object in turn
207 while (*policyInfos
!= NULL
) {
208 policyInfo
= *policyInfos
;
209 policyQualifiers
= policyInfo
->policyQualifiers
;
210 if (policyQualifiers
) {
211 /* create a PKIX_List of PKIX_PL_CertPolicyQualifiers */
212 PKIX_CHECK(PKIX_List_Create(&qualifiers
, plContext
),
213 PKIX_LISTCREATEFAILED
);
215 while (*policyQualifiers
!= NULL
) {
216 policyQualifier
= *policyQualifiers
;
218 /* create the qualifier's OID object */
220 PKIX_CHECK(pkix_pl_oidBytes2Ascii
221 (&(policyQualifier
->qualifierID
),
224 PKIX_OIDBYTES2ASCIIFAILED
);
226 PKIX_CHECK(PKIX_PL_OID_Create
227 (oidAscii
, &pkixOID
, plContext
),
228 PKIX_OIDCREATEFAILED
);
230 /* create qualifier's ByteArray object */
232 PKIX_CHECK(PKIX_PL_ByteArray_Create
233 (policyQualifier
->qualifierValue
.data
,
234 policyQualifier
->qualifierValue
.len
,
237 PKIX_BYTEARRAYCREATEFAILED
);
239 /* create a CertPolicyQualifier object */
241 PKIX_CHECK(pkix_pl_CertPolicyQualifier_Create
244 &certPolicyQualifier
,
246 PKIX_CERTPOLICYQUALIFIERCREATEFAILED
);
248 PKIX_CHECK(PKIX_List_AppendItem
250 (PKIX_PL_Object
*)certPolicyQualifier
,
252 PKIX_LISTAPPENDITEMFAILED
);
255 PKIX_DECREF(pkixOID
);
256 PKIX_DECREF(qualifierArray
);
257 PKIX_DECREF(certPolicyQualifier
);
262 PKIX_CHECK(PKIX_List_SetImmutable
263 (qualifiers
, plContext
),
264 PKIX_LISTSETIMMUTABLEFAILED
);
269 * Create an OID object pkixOID from policyInfo->policyID.
270 * (The CERTPolicyInfo structure has an oid field, but it
271 * is of type SECOidTag. This function wants a SECItem.)
274 PKIX_CHECK(pkix_pl_oidBytes2Ascii
275 (&(policyInfo
->policyID
), &oidAscii
, plContext
),
276 PKIX_OIDBYTES2ASCIIFAILED
);
278 PKIX_CHECK(PKIX_PL_OID_Create
279 (oidAscii
, &pkixOID
, plContext
),
280 PKIX_OIDCREATEFAILED
);
282 /* Create a CertPolicyInfo object */
283 PKIX_CHECK(pkix_pl_CertPolicyInfo_Create
284 (pkixOID
, qualifiers
, &certPolicyInfo
, plContext
),
285 PKIX_CERTPOLICYINFOCREATEFAILED
);
287 /* Append the new CertPolicyInfo object to the list */
288 PKIX_CHECK(PKIX_List_AppendItem
289 (infos
, (PKIX_PL_Object
*)certPolicyInfo
, plContext
),
290 PKIX_LISTAPPENDITEMFAILED
);
293 PKIX_DECREF(pkixOID
);
294 PKIX_DECREF(qualifiers
);
295 PKIX_DECREF(certPolicyInfo
);
301 * If there were no policies, we went straight to
302 * cleanup, so we don't have to NULLCHECK infos.
304 PKIX_CHECK(PKIX_List_SetImmutable(infos
, plContext
),
305 PKIX_LISTSETIMMUTABLEFAILED
);
307 *pCertPolicyInfos
= infos
;
313 ("\t\tCalling CERT_DestroyCertificatePoliciesExtension).\n");
314 CERT_DestroyCertificatePoliciesExtension(certPol
);
317 if (PKIX_ERROR_RECEIVED
){
322 PKIX_DECREF(pkixOID
);
323 PKIX_DECREF(qualifiers
);
324 PKIX_DECREF(certPolicyInfo
);
325 PKIX_DECREF(certPolicyQualifier
);
326 PKIX_DECREF(qualifierArray
);
331 * FUNCTION: pkix_pl_Cert_DecodePolicyMapping
334 * Decodes the contents of the PolicyMapping extension of the CERTCertificate
335 * pointed to by "nssCert", storing the resulting List of CertPolicyMaps at
336 * the address pointed to by "pCertPolicyMaps". If this certificate does not
337 * have a PolicyMapping extension, NULL will be stored. If a List is returned,
338 * it will be immutable.
342 * Address of the Cert data whose extension is to be examined. Must be
345 * Address where the List of CertPolicyMaps will be stored. Must be
348 * Platform-specific context pointer.
350 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
352 * Returns NULL if the function succeeds.
353 * Returns a Cert Error if the function fails in a non-fatal way.
354 * Returns a Fatal Error if the function fails in an unrecoverable way.
357 pkix_pl_Cert_DecodePolicyMapping(
358 CERTCertificate
*nssCert
,
359 PKIX_List
**pCertPolicyMaps
,
363 SECItem encodedCertPolicyMaps
;
365 /* Allocated in the arena; freed in CERT_Destroy... */
366 CERTCertificatePolicyMappings
*certPolMaps
= NULL
;
367 CERTPolicyMap
**policyMaps
= NULL
;
368 CERTPolicyMap
*policyMap
= NULL
;
370 /* Holder for the return value */
371 PKIX_List
*maps
= NULL
;
373 char *issuerPolicyOIDAscii
= NULL
;
374 char *subjectPolicyOIDAscii
= NULL
;
375 PKIX_PL_OID
*issuerDomainOID
= NULL
;
376 PKIX_PL_OID
*subjectDomainOID
= NULL
;
377 PKIX_PL_CertPolicyMap
*certPolicyMap
= NULL
;
379 PKIX_ENTER(CERT
, "pkix_pl_Cert_DecodePolicyMapping");
380 PKIX_NULLCHECK_TWO(nssCert
, pCertPolicyMaps
);
382 /* get PolicyMappings as a SECItem */
383 PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
384 rv
= CERT_FindCertExtension
385 (nssCert
, SEC_OID_X509_POLICY_MAPPINGS
, &encodedCertPolicyMaps
);
386 if (SECSuccess
!= rv
) {
387 *pCertPolicyMaps
= NULL
;
391 /* translate PolicyMaps to CERTCertificatePolicyMappings */
392 certPolMaps
= CERT_DecodePolicyMappingsExtension
393 (&encodedCertPolicyMaps
);
395 PKIX_CERT_DEBUG("\t\tCalling PORT_Free).\n");
396 PORT_Free(encodedCertPolicyMaps
.data
);
399 PKIX_ERROR(PKIX_CERTDECODEPOLICYMAPPINGSEXTENSIONFAILED
);
402 PKIX_NULLCHECK_ONE(certPolMaps
->policyMaps
);
404 policyMaps
= certPolMaps
->policyMaps
;
406 /* create a List of CertPolicyMap Objects */
407 PKIX_CHECK(PKIX_List_Create(&maps
, plContext
),
408 PKIX_LISTCREATEFAILED
);
411 * Traverse the CERTCertificatePolicyMappings structure,
412 * building each CertPolicyMap object in turn
415 policyMap
= *policyMaps
;
417 /* create the OID for the issuer Domain Policy */
419 PKIX_CHECK(pkix_pl_oidBytes2Ascii
420 (&(policyMap
->issuerDomainPolicy
),
421 &issuerPolicyOIDAscii
,
423 PKIX_OIDBYTES2ASCIIFAILED
);
425 PKIX_CHECK(PKIX_PL_OID_Create
426 (issuerPolicyOIDAscii
, &issuerDomainOID
, plContext
),
427 PKIX_OIDCREATEFAILED
);
429 /* create the OID for the subject Domain Policy */
431 PKIX_CHECK(pkix_pl_oidBytes2Ascii
432 (&(policyMap
->subjectDomainPolicy
),
433 &subjectPolicyOIDAscii
,
435 PKIX_OIDBYTES2ASCIIFAILED
);
437 PKIX_CHECK(PKIX_PL_OID_Create
438 (subjectPolicyOIDAscii
, &subjectDomainOID
, plContext
),
439 PKIX_OIDCREATEFAILED
);
441 /* create the CertPolicyMap */
443 PKIX_CHECK(pkix_pl_CertPolicyMap_Create
448 PKIX_CERTPOLICYMAPCREATEFAILED
);
450 PKIX_CHECK(PKIX_List_AppendItem
451 (maps
, (PKIX_PL_Object
*)certPolicyMap
, plContext
),
452 PKIX_LISTAPPENDITEMFAILED
);
454 PKIX_FREE(issuerPolicyOIDAscii
);
455 PKIX_FREE(subjectPolicyOIDAscii
);
456 PKIX_DECREF(issuerDomainOID
);
457 PKIX_DECREF(subjectDomainOID
);
458 PKIX_DECREF(certPolicyMap
);
461 } while (*policyMaps
!= NULL
);
463 PKIX_CHECK(PKIX_List_SetImmutable(maps
, plContext
),
464 PKIX_LISTSETIMMUTABLEFAILED
);
466 *pCertPolicyMaps
= maps
;
472 ("\t\tCalling CERT_DestroyPolicyMappingsExtension).\n");
473 CERT_DestroyPolicyMappingsExtension(certPolMaps
);
476 PKIX_FREE(issuerPolicyOIDAscii
);
477 PKIX_FREE(subjectPolicyOIDAscii
);
478 PKIX_DECREF(issuerDomainOID
);
479 PKIX_DECREF(subjectDomainOID
);
480 PKIX_DECREF(certPolicyMap
);
486 * FUNCTION: pkix_pl_Cert_DecodePolicyConstraints
489 * Decodes the contents of the PolicyConstraints extension in the
490 * CERTCertificate pointed to by "nssCert", to obtain SkipCerts values
491 * which are stored at the addresses "pExplicitPolicySkipCerts" and
492 * "pInhibitMappingSkipCerts", respectively. If this certificate does
493 * not have an PolicyConstraints extension, or if either of the optional
494 * components is not supplied, this function stores a value of -1 for any
499 * Address of the Cert data whose extension is to be examined. Must be
501 * "pExplicitPolicySkipCerts"
502 * Address where the SkipCert value for the requireExplicitPolicy
503 * component will be stored. Must be non-NULL.
504 * "pInhibitMappingSkipCerts"
505 * Address where the SkipCert value for the inhibitPolicyMapping
506 * component will be stored. Must be non-NULL.
508 * Platform-specific context pointer.
510 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
512 * Returns NULL if the function succeeds.
513 * Returns a Cert Error if the function fails in a non-fatal way.
514 * Returns a Fatal Error if the function fails in an unrecoverable way.
517 pkix_pl_Cert_DecodePolicyConstraints(
518 CERTCertificate
*nssCert
,
519 PKIX_Int32
*pExplicitPolicySkipCerts
,
520 PKIX_Int32
*pInhibitMappingSkipCerts
,
523 CERTCertificatePolicyConstraints policyConstraints
;
525 SECItem encodedCertPolicyConstraints
;
526 PKIX_Int32 explicitPolicySkipCerts
= -1;
527 PKIX_Int32 inhibitMappingSkipCerts
= -1;
529 PKIX_ENTER(CERT
, "pkix_pl_Cert_DecodePolicyConstraints");
531 (nssCert
, pExplicitPolicySkipCerts
, pInhibitMappingSkipCerts
);
533 /* get the two skipCert values as SECItems */
534 PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
535 rv
= CERT_FindCertExtension
537 SEC_OID_X509_POLICY_CONSTRAINTS
,
538 &encodedCertPolicyConstraints
);
540 if (rv
== SECSuccess
) {
542 policyConstraints
.explicitPolicySkipCerts
.data
=
543 (unsigned char *)&explicitPolicySkipCerts
;
544 policyConstraints
.inhibitMappingSkipCerts
.data
=
545 (unsigned char *)&inhibitMappingSkipCerts
;
547 /* translate DER to CERTCertificatePolicyConstraints */
548 rv
= CERT_DecodePolicyConstraintsExtension
549 (&policyConstraints
, &encodedCertPolicyConstraints
);
551 PKIX_CERT_DEBUG("\t\tCalling PORT_Free).\n");
552 PORT_Free(encodedCertPolicyConstraints
.data
);
554 if (rv
!= SECSuccess
) {
556 (PKIX_CERTDECODEPOLICYCONSTRAINTSEXTENSIONFAILED
);
560 *pExplicitPolicySkipCerts
= explicitPolicySkipCerts
;
561 *pInhibitMappingSkipCerts
= inhibitMappingSkipCerts
;
569 * FUNCTION: pkix_pl_Cert_DecodeInhibitAnyPolicy
572 * Decodes the contents of the InhibitAnyPolicy extension in the
573 * CERTCertificate pointed to by "nssCert", to obtain a SkipCerts value,
574 * which is stored at the address "pSkipCerts". If this certificate does
575 * not have an InhibitAnyPolicy extension, -1 will be stored.
579 * Address of the Cert data whose InhibitAnyPolicy extension is to be
580 * processed. Must be non-NULL.
582 * Address where the SkipCert value from the InhibitAnyPolicy extension
583 * will be stored. Must be non-NULL.
585 * Platform-specific context pointer.
587 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
589 * Returns NULL if the function succeeds.
590 * Returns a Cert Error if the function fails in a non-fatal way.
591 * Returns a Fatal Error if the function fails in an unrecoverable way.
594 pkix_pl_Cert_DecodeInhibitAnyPolicy(
595 CERTCertificate
*nssCert
,
596 PKIX_Int32
*pSkipCerts
,
599 CERTCertificateInhibitAny inhibitAny
;
601 SECItem encodedCertInhibitAny
;
602 PKIX_Int32 skipCerts
= -1;
604 PKIX_ENTER(CERT
, "pkix_pl_Cert_DecodeInhibitAnyPolicy");
605 PKIX_NULLCHECK_TWO(nssCert
, pSkipCerts
);
607 /* get InhibitAny as a SECItem */
608 PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
609 rv
= CERT_FindCertExtension
610 (nssCert
, SEC_OID_X509_INHIBIT_ANY_POLICY
, &encodedCertInhibitAny
);
612 if (rv
== SECSuccess
) {
613 inhibitAny
.inhibitAnySkipCerts
.data
=
614 (unsigned char *)&skipCerts
;
616 /* translate DER to CERTCertificateInhibitAny */
617 rv
= CERT_DecodeInhibitAnyExtension
618 (&inhibitAny
, &encodedCertInhibitAny
);
620 PKIX_CERT_DEBUG("\t\tCalling PORT_Free).\n");
621 PORT_Free(encodedCertInhibitAny
.data
);
623 if (rv
!= SECSuccess
) {
624 PKIX_ERROR(PKIX_CERTDECODEINHIBITANYEXTENSIONFAILED
);
628 *pSkipCerts
= skipCerts
;
636 * FUNCTION: pkix_pl_Cert_GetNssSubjectAltNames
639 * Retrieves the Subject Alternative Names of the certificate specified by
640 * "cert" and stores it at "pNssSubjAltNames". If the Subject Alternative
641 * Name extension is not present, NULL is returned at "pNssSubjAltNames".
642 * If the Subject Alternative Names has not been previously decoded, it is
643 * decoded here with lock on the "cert" unless the flag "hasLock" indicates
644 * the lock had been obtained at a higher call level.
648 * Address of the certificate whose Subject Alternative Names extensions
649 * is retrieved. Must be non-NULL.
651 * Boolean indicates caller has acquired a lock.
654 * Address where the returned Subject Alternative Names will be stored.
657 * Platform-specific context pointer.
659 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
661 * Returns NULL if the function succeeds.
662 * Returns a Cert Error if the function fails in a non-fatal way.
663 * Returns a Fatal Error if the function fails in an unrecoverable way.
666 pkix_pl_Cert_GetNssSubjectAltNames(
668 PKIX_Boolean hasLock
,
669 CERTGeneralName
**pNssSubjAltNames
,
672 CERTCertificate
*nssCert
= NULL
;
673 CERTGeneralName
*nssOriginalAltName
= NULL
;
674 PLArenaPool
*arena
= NULL
;
675 SECItem altNameExtension
= {siBuffer
, NULL
, 0};
676 SECStatus rv
= SECFailure
;
678 PKIX_ENTER(CERT
, "pkix_pl_Cert_GetNssSubjectAltNames");
679 PKIX_NULLCHECK_THREE(cert
, pNssSubjAltNames
, cert
->nssCert
);
681 nssCert
= cert
->nssCert
;
683 if ((cert
->nssSubjAltNames
== NULL
) && (!cert
->subjAltNamesAbsent
)){
686 PKIX_OBJECT_LOCK(cert
);
689 if ((cert
->nssSubjAltNames
== NULL
) &&
690 (!cert
->subjAltNamesAbsent
)){
692 PKIX_PL_NSSCALLRV(CERT
, rv
, CERT_FindCertExtension
,
694 SEC_OID_X509_SUBJECT_ALT_NAME
,
697 if (rv
!= SECSuccess
) {
698 *pNssSubjAltNames
= NULL
;
699 cert
->subjAltNamesAbsent
= PKIX_TRUE
;
703 if (cert
->arenaNameConstraints
== NULL
) {
704 PKIX_PL_NSSCALLRV(CERT
, arena
, PORT_NewArena
,
705 (DER_DEFAULT_CHUNKSIZE
));
708 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
710 cert
->arenaNameConstraints
= arena
;
716 (CERTGeneralName
*) CERT_DecodeAltNameExtension
,
717 (cert
->arenaNameConstraints
, &altNameExtension
));
719 PKIX_PL_NSSCALL(CERT
, PORT_Free
, (altNameExtension
.data
));
721 if (nssOriginalAltName
== NULL
) {
722 PKIX_ERROR(PKIX_CERTDECODEALTNAMEEXTENSIONFAILED
);
724 cert
->nssSubjAltNames
= nssOriginalAltName
;
729 PKIX_OBJECT_UNLOCK(cert
);
733 *pNssSubjAltNames
= cert
->nssSubjAltNames
;
736 if (objectIsLocked
== PKIX_TRUE
) {
737 PKIX_OBJECT_UNLOCK(lockedObject
);
744 * FUNCTION: pkix_pl_Cert_CheckExtendKeyUsage
747 * For each of the ON bit in "requiredExtendedKeyUsages" that represents its
748 * SECCertUsageEnum type, this function checks "cert"'s certType (extended
749 * key usage) and key usage with what is required for SECCertUsageEnum type.
753 * Address of the certificate whose Extended Key Usage extensions
754 * is retrieved. Must be non-NULL.
755 * "requiredExtendedKeyUsages"
756 * An unsigned integer, its bit location is ON based on the required key
757 * usage value representing in SECCertUsageEnum.
759 * Address where the return value, indicating key usage check passed, is
760 * stored. Must be non-NULL.
762 * Platform-specific context pointer.
764 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
766 * Returns NULL if the function succeeds.
767 * Returns a Cert Error if the function fails in a non-fatal way.
768 * Returns a Fatal Error if the function fails in an unrecoverable way.
771 pkix_pl_Cert_CheckExtendedKeyUsage(
773 PKIX_UInt32 requiredExtendedKeyUsages
,
777 PKIX_PL_CertBasicConstraints
*basicConstraints
= NULL
;
778 PKIX_UInt32 certType
= 0;
779 PKIX_UInt32 requiredKeyUsage
= 0;
780 PKIX_UInt32 requiredCertType
= 0;
781 PKIX_UInt32 requiredExtendedKeyUsage
= 0;
783 PKIX_Boolean isCA
= PKIX_FALSE
;
784 SECStatus rv
= SECFailure
;
786 PKIX_ENTER(CERT
, "pkix_pl_Cert_CheckExtendKeyUsage");
787 PKIX_NULLCHECK_THREE(cert
, pPass
, cert
->nssCert
);
791 PKIX_CERT_DEBUG("\t\tCalling cert_GetCertType).\n");
792 cert_GetCertType(cert
->nssCert
);
793 certType
= cert
->nssCert
->nsCertType
;
795 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
799 PKIX_CERTGETBASICCONSTRAINTFAILED
);
801 if (basicConstraints
!= NULL
) {
802 PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
803 (basicConstraints
, &isCA
, plContext
),
804 PKIX_BASICCONSTRAINTSGETCAFLAGFAILED
);
808 while (requiredExtendedKeyUsages
!= 0) {
810 /* Find the bit location of the right-most non-zero bit */
811 while (requiredExtendedKeyUsages
!= 0) {
812 if (((1 << i
) & requiredExtendedKeyUsages
) != 0) {
813 requiredExtendedKeyUsage
= 1 << i
;
818 requiredExtendedKeyUsages
^= requiredExtendedKeyUsage
;
820 requiredExtendedKeyUsage
= i
;
822 PKIX_PL_NSSCALLRV(CERT
, rv
, CERT_KeyUsageAndTypeForCertUsage
,
823 (requiredExtendedKeyUsage
,
828 if (!(certType
& requiredCertType
)) {
832 PKIX_PL_NSSCALLRV(CERT
, rv
, CERT_CheckKeyUsage
,
833 (cert
->nssCert
, requiredKeyUsage
));
834 if (rv
!= SECSuccess
) {
845 PKIX_DECREF(basicConstraints
);
851 * FUNCTION: pkix_pl_Cert_ToString_Helper
854 * Helper function that creates a string representation of the Cert pointed
855 * to by "cert" and stores it at "pString", where the value of
856 * "partialString" determines whether a full or partial representation of
857 * the Cert is stored.
861 * Address of Cert whose string representation is desired.
864 * Boolean indicating whether a partial Cert representation is desired.
866 * Address where object pointer will be stored. Must be non-NULL.
868 * Platform-specific context pointer.
870 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
872 * Returns NULL if the function succeeds.
873 * Returns a Cert Error if the function fails in a non-fatal way.
874 * Returns a Fatal Error if the function fails in an unrecoverable way.
877 pkix_pl_Cert_ToString_Helper(
879 PKIX_Boolean partialString
,
880 PKIX_PL_String
**pString
,
883 PKIX_PL_String
*certString
= NULL
;
884 char *asciiFormat
= NULL
;
885 PKIX_PL_String
*formatString
= NULL
;
886 PKIX_UInt32 certVersion
;
887 PKIX_PL_BigInt
*certSN
= NULL
;
888 PKIX_PL_String
*certSNString
= NULL
;
889 PKIX_PL_X500Name
*certIssuer
= NULL
;
890 PKIX_PL_String
*certIssuerString
= NULL
;
891 PKIX_PL_X500Name
*certSubject
= NULL
;
892 PKIX_PL_String
*certSubjectString
= NULL
;
893 PKIX_PL_String
*notBeforeString
= NULL
;
894 PKIX_PL_String
*notAfterString
= NULL
;
895 PKIX_List
*subjAltNames
= NULL
;
896 PKIX_PL_String
*subjAltNamesString
= NULL
;
897 PKIX_PL_ByteArray
*authKeyId
= NULL
;
898 PKIX_PL_String
*authKeyIdString
= NULL
;
899 PKIX_PL_ByteArray
*subjKeyId
= NULL
;
900 PKIX_PL_String
*subjKeyIdString
= NULL
;
901 PKIX_PL_PublicKey
*nssPubKey
= NULL
;
902 PKIX_PL_String
*nssPubKeyString
= NULL
;
903 PKIX_List
*critExtOIDs
= NULL
;
904 PKIX_PL_String
*critExtOIDsString
= NULL
;
905 PKIX_List
*extKeyUsages
= NULL
;
906 PKIX_PL_String
*extKeyUsagesString
= NULL
;
907 PKIX_PL_CertBasicConstraints
*basicConstraint
= NULL
;
908 PKIX_PL_String
*certBasicConstraintsString
= NULL
;
909 PKIX_List
*policyInfo
= NULL
;
910 PKIX_PL_String
*certPolicyInfoString
= NULL
;
911 PKIX_List
*certPolicyMappings
= NULL
;
912 PKIX_PL_String
*certPolicyMappingsString
= NULL
;
913 PKIX_Int32 certExplicitPolicy
= 0;
914 PKIX_Int32 certInhibitMapping
= 0;
915 PKIX_Int32 certInhibitAnyPolicy
= 0;
916 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
917 PKIX_PL_String
*nameConstraintsString
= NULL
;
918 PKIX_List
*authorityInfoAccess
= NULL
;
919 PKIX_PL_String
*authorityInfoAccessString
= NULL
;
920 PKIX_List
*subjectInfoAccess
= NULL
;
921 PKIX_PL_String
*subjectInfoAccessString
= NULL
;
923 PKIX_ENTER(CERT
, "pkix_pl_Cert_ToString_Helper");
924 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pString
);
927 * XXX Add to this format as certificate components are developed.
938 "\tSerialNumber: %s\n"
941 "\tValidity: [From: %s\n"
943 "\tSubjectAltNames: %s\n"
944 "\tAuthorityKeyId: %s\n"
945 "\tSubjectKeyId: %s\n"
946 "\tSubjPubKeyAlgId: %s\n"
947 "\tCritExtOIDs: %s\n"
948 "\tExtKeyUsages: %s\n"
949 "\tBasicConstraint: %s\n"
950 "\tCertPolicyInfo: %s\n"
951 "\tPolicyMappings: %s\n"
952 "\tExplicitPolicy: %d\n"
953 "\tInhibitMapping: %d\n"
954 "\tInhibitAnyPolicy:%d\n"
955 "\tNameConstraints: %s\n"
956 "\tAuthorityInfoAccess: %s\n"
957 "\tSubjectInfoAccess: %s\n"
964 PKIX_CHECK(PKIX_PL_String_Create
965 (PKIX_ESCASCII
, asciiFormat
, 0, &formatString
, plContext
),
966 PKIX_STRINGCREATEFAILED
);
969 PKIX_CHECK(PKIX_PL_Cert_GetIssuer
970 (cert
, &certIssuer
, plContext
),
971 PKIX_CERTGETISSUERFAILED
);
973 PKIX_CHECK(PKIX_PL_Object_ToString
974 ((PKIX_PL_Object
*)certIssuer
, &certIssuerString
, plContext
),
975 PKIX_X500NAMETOSTRINGFAILED
);
978 PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert
, &certSubject
, plContext
),
979 PKIX_CERTGETSUBJECTFAILED
);
981 PKIX_TOSTRING(certSubject
, &certSubjectString
, plContext
,
982 PKIX_X500NAMETOSTRINGFAILED
);
985 PKIX_CHECK(PKIX_PL_Sprintf
993 *pString
= certString
;
998 PKIX_CHECK(PKIX_PL_Cert_GetVersion(cert
, &certVersion
, plContext
),
999 PKIX_CERTGETVERSIONFAILED
);
1002 PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber(cert
, &certSN
, plContext
),
1003 PKIX_CERTGETSERIALNUMBERFAILED
);
1005 PKIX_CHECK(PKIX_PL_Object_ToString
1006 ((PKIX_PL_Object
*)certSN
, &certSNString
, plContext
),
1007 PKIX_BIGINTTOSTRINGFAILED
);
1009 /* Validity: NotBefore */
1010 PKIX_CHECK(pkix_pl_Date_ToString_Helper
1011 (&(cert
->nssCert
->validity
.notBefore
),
1014 PKIX_DATETOSTRINGHELPERFAILED
);
1016 /* Validity: NotAfter */
1017 PKIX_CHECK(pkix_pl_Date_ToString_Helper
1018 (&(cert
->nssCert
->validity
.notAfter
),
1021 PKIX_DATETOSTRINGHELPERFAILED
);
1023 /* SubjectAltNames */
1024 PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
1025 (cert
, &subjAltNames
, plContext
),
1026 PKIX_CERTGETSUBJECTALTNAMESFAILED
);
1028 PKIX_TOSTRING(subjAltNames
, &subjAltNamesString
, plContext
,
1029 PKIX_LISTTOSTRINGFAILED
);
1031 /* AuthorityKeyIdentifier */
1032 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
1033 (cert
, &authKeyId
, plContext
),
1034 PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED
);
1036 PKIX_TOSTRING(authKeyId
, &authKeyIdString
, plContext
,
1037 PKIX_BYTEARRAYTOSTRINGFAILED
);
1039 /* SubjectKeyIdentifier */
1040 PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
1041 (cert
, &subjKeyId
, plContext
),
1042 PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED
);
1044 PKIX_TOSTRING(subjKeyId
, &subjKeyIdString
, plContext
,
1045 PKIX_BYTEARRAYTOSTRINGFAILED
);
1047 /* SubjectPublicKey */
1048 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
1049 (cert
, &nssPubKey
, plContext
),
1050 PKIX_CERTGETSUBJECTPUBLICKEYFAILED
);
1052 PKIX_CHECK(PKIX_PL_Object_ToString
1053 ((PKIX_PL_Object
*)nssPubKey
, &nssPubKeyString
, plContext
),
1054 PKIX_PUBLICKEYTOSTRINGFAILED
);
1056 /* CriticalExtensionOIDs */
1057 PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
1058 (cert
, &critExtOIDs
, plContext
),
1059 PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED
);
1061 PKIX_TOSTRING(critExtOIDs
, &critExtOIDsString
, plContext
,
1062 PKIX_LISTTOSTRINGFAILED
);
1064 /* ExtendedKeyUsages */
1065 PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
1066 (cert
, &extKeyUsages
, plContext
),
1067 PKIX_CERTGETEXTENDEDKEYUSAGEFAILED
);
1069 PKIX_TOSTRING(extKeyUsages
, &extKeyUsagesString
, plContext
,
1070 PKIX_LISTTOSTRINGFAILED
);
1072 /* CertBasicConstraints */
1073 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
1074 (cert
, &basicConstraint
, plContext
),
1075 PKIX_CERTGETBASICCONSTRAINTSFAILED
);
1077 PKIX_TOSTRING(basicConstraint
, &certBasicConstraintsString
, plContext
,
1078 PKIX_CERTBASICCONSTRAINTSTOSTRINGFAILED
);
1080 /* CertPolicyInfo */
1081 PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
1082 (cert
, &policyInfo
, plContext
),
1083 PKIX_CERTGETPOLICYINFORMATIONFAILED
);
1085 PKIX_TOSTRING(policyInfo
, &certPolicyInfoString
, plContext
,
1086 PKIX_LISTTOSTRINGFAILED
);
1088 /* Advanced Policies */
1089 PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings
1090 (cert
, &certPolicyMappings
, plContext
),
1091 PKIX_CERTGETPOLICYMAPPINGSFAILED
);
1093 PKIX_TOSTRING(certPolicyMappings
, &certPolicyMappingsString
, plContext
,
1094 PKIX_LISTTOSTRINGFAILED
);
1096 PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
1097 (cert
, &certExplicitPolicy
, plContext
),
1098 PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED
);
1100 PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited
1101 (cert
, &certInhibitMapping
, plContext
),
1102 PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED
);
1104 PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy
1105 (cert
, &certInhibitAnyPolicy
, plContext
),
1106 PKIX_CERTGETINHIBITANYPOLICYFAILED
);
1108 /* Name Constraints */
1109 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
1110 (cert
, &nameConstraints
, plContext
),
1111 PKIX_CERTGETNAMECONSTRAINTSFAILED
);
1113 PKIX_TOSTRING(nameConstraints
, &nameConstraintsString
, plContext
,
1114 PKIX_LISTTOSTRINGFAILED
);
1116 /* Authority Information Access */
1117 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
1118 (cert
, &authorityInfoAccess
, plContext
),
1119 PKIX_CERTGETAUTHORITYINFOACCESSFAILED
);
1121 PKIX_TOSTRING(authorityInfoAccess
, &authorityInfoAccessString
, plContext
,
1122 PKIX_LISTTOSTRINGFAILED
);
1124 /* Subject Information Access */
1125 PKIX_CHECK(PKIX_PL_Cert_GetSubjectInfoAccess
1126 (cert
, &subjectInfoAccess
, plContext
),
1127 PKIX_CERTGETSUBJECTINFOACCESSFAILED
);
1129 PKIX_TOSTRING(subjectInfoAccess
, &subjectInfoAccessString
, plContext
,
1130 PKIX_LISTTOSTRINGFAILED
);
1132 PKIX_CHECK(PKIX_PL_Sprintf
1148 certBasicConstraintsString
,
1149 certPolicyInfoString
,
1150 certPolicyMappingsString
,
1151 certExplicitPolicy
, /* an Int32, not a String */
1152 certInhibitMapping
, /* an Int32, not a String */
1153 certInhibitAnyPolicy
, /* an Int32, not a String */
1154 nameConstraintsString
,
1155 authorityInfoAccessString
,
1156 subjectInfoAccessString
,
1157 cert
->cacheFlag
), /* a boolean */
1158 PKIX_SPRINTFFAILED
);
1160 *pString
= certString
;
1164 PKIX_DECREF(certSN
);
1165 PKIX_DECREF(certSNString
);
1166 PKIX_DECREF(certIssuer
);
1167 PKIX_DECREF(certIssuerString
);
1168 PKIX_DECREF(certSubject
);
1169 PKIX_DECREF(certSubjectString
);
1170 PKIX_DECREF(notBeforeString
);
1171 PKIX_DECREF(notAfterString
);
1172 PKIX_DECREF(subjAltNames
);
1173 PKIX_DECREF(subjAltNamesString
);
1174 PKIX_DECREF(authKeyId
);
1175 PKIX_DECREF(authKeyIdString
);
1176 PKIX_DECREF(subjKeyId
);
1177 PKIX_DECREF(subjKeyIdString
);
1178 PKIX_DECREF(nssPubKey
);
1179 PKIX_DECREF(nssPubKeyString
);
1180 PKIX_DECREF(critExtOIDs
);
1181 PKIX_DECREF(critExtOIDsString
);
1182 PKIX_DECREF(extKeyUsages
);
1183 PKIX_DECREF(extKeyUsagesString
);
1184 PKIX_DECREF(basicConstraint
);
1185 PKIX_DECREF(certBasicConstraintsString
);
1186 PKIX_DECREF(policyInfo
);
1187 PKIX_DECREF(certPolicyInfoString
);
1188 PKIX_DECREF(certPolicyMappings
);
1189 PKIX_DECREF(certPolicyMappingsString
);
1190 PKIX_DECREF(nameConstraints
);
1191 PKIX_DECREF(nameConstraintsString
);
1192 PKIX_DECREF(authorityInfoAccess
);
1193 PKIX_DECREF(authorityInfoAccessString
);
1194 PKIX_DECREF(subjectInfoAccess
);
1195 PKIX_DECREF(subjectInfoAccessString
);
1196 PKIX_DECREF(formatString
);
1202 * FUNCTION: pkix_pl_Cert_Destroy
1203 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
1206 pkix_pl_Cert_Destroy(
1207 PKIX_PL_Object
*object
,
1210 PKIX_PL_Cert
*cert
= NULL
;
1212 PKIX_ENTER(CERT
, "pkix_pl_Cert_Destroy");
1213 PKIX_NULLCHECK_ONE(object
);
1215 PKIX_CHECK(pkix_CheckType(object
, PKIX_CERT_TYPE
, plContext
),
1216 PKIX_OBJECTNOTCERT
);
1218 cert
= (PKIX_PL_Cert
*)object
;
1220 PKIX_DECREF(cert
->subject
);
1221 PKIX_DECREF(cert
->issuer
);
1222 PKIX_DECREF(cert
->subjAltNames
);
1223 PKIX_DECREF(cert
->publicKeyAlgId
);
1224 PKIX_DECREF(cert
->publicKey
);
1225 PKIX_DECREF(cert
->serialNumber
);
1226 PKIX_DECREF(cert
->critExtOids
);
1227 PKIX_DECREF(cert
->authKeyId
);
1228 PKIX_DECREF(cert
->subjKeyId
);
1229 PKIX_DECREF(cert
->extKeyUsages
);
1230 PKIX_DECREF(cert
->certBasicConstraints
);
1231 PKIX_DECREF(cert
->certPolicyInfos
);
1232 PKIX_DECREF(cert
->certPolicyMappings
);
1233 PKIX_DECREF(cert
->nameConstraints
);
1234 PKIX_DECREF(cert
->store
);
1235 PKIX_DECREF(cert
->authorityInfoAccess
);
1236 PKIX_DECREF(cert
->subjectInfoAccess
);
1238 if (cert
->arenaNameConstraints
){
1239 /* This arena was allocated for SubjectAltNames */
1240 PKIX_PL_NSSCALL(CERT
, PORT_FreeArena
,
1241 (cert
->arenaNameConstraints
, PR_FALSE
));
1243 cert
->arenaNameConstraints
= NULL
;
1244 cert
->nssSubjAltNames
= NULL
;
1247 PKIX_PL_NSSCALL(CERT
, CERT_DestroyCertificate
, (cert
->nssCert
));
1249 cert
->nssCert
= NULL
;
1257 * FUNCTION: pkix_pl_Cert_ToString
1258 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
1261 pkix_pl_Cert_ToString(
1262 PKIX_PL_Object
*object
,
1263 PKIX_PL_String
**pString
,
1266 PKIX_PL_String
*certString
= NULL
;
1267 PKIX_PL_Cert
*pkixCert
= NULL
;
1269 PKIX_ENTER(CERT
, "pkix_pl_Cert_toString");
1270 PKIX_NULLCHECK_TWO(object
, pString
);
1272 PKIX_CHECK(pkix_CheckType(object
, PKIX_CERT_TYPE
, plContext
),
1273 PKIX_OBJECTNOTCERT
);
1275 pkixCert
= (PKIX_PL_Cert
*)object
;
1277 PKIX_CHECK(pkix_pl_Cert_ToString_Helper
1278 (pkixCert
, PKIX_FALSE
, &certString
, plContext
),
1279 PKIX_CERTTOSTRINGHELPERFAILED
);
1281 *pString
= certString
;
1289 * FUNCTION: pkix_pl_Cert_Hashcode
1290 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
1293 pkix_pl_Cert_Hashcode(
1294 PKIX_PL_Object
*object
,
1295 PKIX_UInt32
*pHashcode
,
1298 PKIX_PL_Cert
*pkixCert
= NULL
;
1299 CERTCertificate
*nssCert
= NULL
;
1300 unsigned char *derBytes
= NULL
;
1301 PKIX_UInt32 derLength
;
1302 PKIX_UInt32 certHash
;
1304 PKIX_ENTER(CERT
, "pkix_pl_Cert_Hashcode");
1305 PKIX_NULLCHECK_TWO(object
, pHashcode
);
1307 PKIX_CHECK(pkix_CheckType(object
, PKIX_CERT_TYPE
, plContext
),
1308 PKIX_OBJECTNOTCERT
);
1310 pkixCert
= (PKIX_PL_Cert
*)object
;
1312 nssCert
= pkixCert
->nssCert
;
1313 derBytes
= (nssCert
->derCert
).data
;
1314 derLength
= (nssCert
->derCert
).len
;
1316 PKIX_CHECK(pkix_hash(derBytes
, derLength
, &certHash
, plContext
),
1319 *pHashcode
= certHash
;
1328 * FUNCTION: pkix_pl_Cert_Equals
1329 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
1332 pkix_pl_Cert_Equals(
1333 PKIX_PL_Object
*firstObject
,
1334 PKIX_PL_Object
*secondObject
,
1335 PKIX_Boolean
*pResult
,
1338 CERTCertificate
*firstCert
= NULL
;
1339 CERTCertificate
*secondCert
= NULL
;
1340 PKIX_UInt32 secondType
;
1341 PKIX_Boolean cmpResult
;
1343 PKIX_ENTER(CERT
, "pkix_pl_Cert_Equals");
1344 PKIX_NULLCHECK_THREE(firstObject
, secondObject
, pResult
);
1346 /* test that firstObject is a Cert */
1347 PKIX_CHECK(pkix_CheckType(firstObject
, PKIX_CERT_TYPE
, plContext
),
1348 PKIX_FIRSTOBJECTNOTCERT
);
1351 * Since we know firstObject is a Cert, if both references are
1352 * identical, they must be equal
1354 if (firstObject
== secondObject
){
1355 *pResult
= PKIX_TRUE
;
1360 * If secondObject isn't a Cert, we don't throw an error.
1361 * We simply return a Boolean result of FALSE
1363 *pResult
= PKIX_FALSE
;
1364 PKIX_CHECK(PKIX_PL_Object_GetType
1365 (secondObject
, &secondType
, plContext
),
1366 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
);
1367 if (secondType
!= PKIX_CERT_TYPE
) goto cleanup
;
1369 firstCert
= ((PKIX_PL_Cert
*)firstObject
)->nssCert
;
1370 secondCert
= ((PKIX_PL_Cert
*)secondObject
)->nssCert
;
1372 PKIX_NULLCHECK_TWO(firstCert
, secondCert
);
1374 /* CERT_CompareCerts does byte comparison on DER encodings of certs */
1375 PKIX_CERT_DEBUG("\t\tCalling CERT_CompareCerts).\n");
1376 cmpResult
= CERT_CompareCerts(firstCert
, secondCert
);
1378 *pResult
= cmpResult
;
1386 * FUNCTION: pkix_pl_Cert_RegisterSelf
1388 * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
1390 * Not Thread Safe - for performance and complexity reasons
1392 * Since this function is only called by PKIX_PL_Initialize, which should
1393 * only be called once, it is acceptable that this function is not
1397 pkix_pl_Cert_RegisterSelf(void *plContext
)
1400 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
1401 pkix_ClassTable_Entry entry
;
1403 PKIX_ENTER(CERT
, "pkix_pl_Cert_RegisterSelf");
1405 entry
.description
= "Cert";
1406 entry
.destructor
= pkix_pl_Cert_Destroy
;
1407 entry
.equalsFunction
= pkix_pl_Cert_Equals
;
1408 entry
.hashcodeFunction
= pkix_pl_Cert_Hashcode
;
1409 entry
.toStringFunction
= pkix_pl_Cert_ToString
;
1410 entry
.comparator
= NULL
;
1411 entry
.duplicateFunction
= pkix_duplicateImmutable
;
1413 systemClasses
[PKIX_CERT_TYPE
] = entry
;
1419 * FUNCTION: pkix_pl_Cert_CreateWithNSSCert
1422 * Creates a new certificate using the CERTCertificate pointed to by "nssCert"
1423 * and stores it at "pCert". Once created, a Cert is immutable.
1425 * This function is primarily used as a convenience function for the
1426 * performance tests that have easy access to a CERTCertificate.
1430 * Address of CERTCertificate representing the NSS certificate.
1433 * Address where object pointer will be stored. Must be non-NULL.
1435 * Platform-specific context pointer.
1437 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1439 * Returns NULL if the function succeeds.
1440 * Returns a Cert Error if the function fails in a non-fatal way.
1441 * Returns a Fatal Error if the function fails in an unrecoverable way.
1444 pkix_pl_Cert_CreateWithNSSCert(
1445 CERTCertificate
*nssCert
,
1446 PKIX_PL_Cert
**pCert
,
1449 PKIX_PL_Cert
*cert
= NULL
;
1451 PKIX_ENTER(CERT
, "PKIX_PL_Cert_CreateWithNSSCert");
1452 PKIX_NULLCHECK_TWO(pCert
, nssCert
);
1454 /* create a PKIX_PL_Cert object */
1455 PKIX_CHECK(PKIX_PL_Object_Alloc
1457 sizeof (PKIX_PL_Cert
),
1458 (PKIX_PL_Object
**)&cert
,
1460 PKIX_COULDNOTCREATEOBJECT
);
1462 /* populate the nssCert field */
1463 cert
->nssCert
= nssCert
;
1465 /* initialize remaining fields */
1467 * Fields ending with Absent are initialized to PKIX_FALSE so that the
1468 * first time we need the value we will look for it. If we find it is
1469 * actually absent, the flag will at that time be set to PKIX_TRUE to
1470 * prevent searching for it later.
1471 * Fields ending with Processed are those where a value is defined
1472 * for the Absent case, and a value of zero is possible. When the
1473 * flag is still true we have to look for the field, set the default
1474 * value if necessary, and set the Processed flag to PKIX_TRUE.
1476 cert
->subject
= NULL
;
1477 cert
->issuer
= NULL
;
1478 cert
->subjAltNames
= NULL
;
1479 cert
->subjAltNamesAbsent
= PKIX_FALSE
;
1480 cert
->publicKeyAlgId
= NULL
;
1481 cert
->publicKey
= NULL
;
1482 cert
->serialNumber
= NULL
;
1483 cert
->critExtOids
= NULL
;
1484 cert
->subjKeyId
= NULL
;
1485 cert
->subjKeyIdAbsent
= PKIX_FALSE
;
1486 cert
->authKeyId
= NULL
;
1487 cert
->authKeyIdAbsent
= PKIX_FALSE
;
1488 cert
->extKeyUsages
= NULL
;
1489 cert
->extKeyUsagesAbsent
= PKIX_FALSE
;
1490 cert
->certBasicConstraints
= NULL
;
1491 cert
->basicConstraintsAbsent
= PKIX_FALSE
;
1492 cert
->certPolicyInfos
= NULL
;
1493 cert
->policyInfoAbsent
= PKIX_FALSE
;
1494 cert
->policyMappingsAbsent
= PKIX_FALSE
;
1495 cert
->certPolicyMappings
= NULL
;
1496 cert
->policyConstraintsProcessed
= PKIX_FALSE
;
1497 cert
->policyConstraintsExplicitPolicySkipCerts
= 0;
1498 cert
->policyConstraintsInhibitMappingSkipCerts
= 0;
1499 cert
->inhibitAnyPolicyProcessed
= PKIX_FALSE
;
1500 cert
->inhibitAnySkipCerts
= 0;
1501 cert
->nameConstraints
= NULL
;
1502 cert
->nameConstraintsAbsent
= PKIX_FALSE
;
1503 cert
->arenaNameConstraints
= NULL
;
1504 cert
->nssSubjAltNames
= NULL
;
1505 cert
->cacheFlag
= PKIX_FALSE
;
1507 cert
->authorityInfoAccess
= NULL
;
1508 cert
->subjectInfoAccess
= NULL
;
1518 * FUNCTION: pkix_pl_Cert_CreateToList
1521 * Creates a new certificate using the DER-encoding pointed to by "derCertItem"
1522 * and appends it to the list pointed to by "certList". If Cert creation fails,
1523 * the function returns with certList unchanged, but any decoding Error is
1528 * Address of SECItem containing the DER representation of a certificate.
1531 * Address of List to which the Cert will be appended, if successfully
1532 * created. May be empty, but must be non-NULL.
1534 * Platform-specific context pointer.
1536 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1538 * Returns NULL if the function succeeds.
1539 * Returns a Cert Error if the function fails in a non-fatal way.
1540 * Returns a Fatal Error if the function fails in an unrecoverable way.
1543 pkix_pl_Cert_CreateToList(
1544 SECItem
*derCertItem
,
1545 PKIX_List
*certList
,
1548 CERTCertificate
*nssCert
= NULL
;
1549 PKIX_PL_Cert
*cert
= NULL
;
1551 PKIX_ENTER(CERT
, "pkix_pl_Cert_CreateToList");
1552 PKIX_NULLCHECK_TWO(derCertItem
, certList
);
1554 PKIX_PL_NSSCALLRV(CERT
, nssCert
, CERT_DecodeDERCertificate
,
1555 (derCertItem
, PR_TRUE
, NULL
));
1558 PKIX_CHECK_ONLY_FATAL(pkix_pl_Cert_CreateWithNSSCert
1559 (nssCert
, &cert
, plContext
),
1560 PKIX_CERTCREATEWITHNSSCERTFAILED
);
1562 /* skip bad certs and append good ones */
1563 if (!PKIX_ERROR_RECEIVED
) {
1564 PKIX_CHECK(PKIX_List_AppendItem
1565 (certList
, (PKIX_PL_Object
*) cert
, plContext
),
1566 PKIX_LISTAPPENDITEMFAILED
);
1579 /* --Public-Functions------------------------------------------------------- */
1582 * FUNCTION: PKIX_PL_Cert_Create (see comments in pkix_pl_pki.h)
1583 * XXX We may want to cache the cert after parsing it, so it can be reused
1584 * XXX Are the NSS/NSPR functions thread safe
1587 PKIX_PL_Cert_Create(
1588 PKIX_PL_ByteArray
*byteArray
,
1589 PKIX_PL_Cert
**pCert
,
1592 CERTCertificate
*nssCert
= NULL
;
1593 SECItem
*derCertItem
= NULL
;
1594 void *derBytes
= NULL
;
1595 PKIX_UInt32 derLength
;
1596 PKIX_Boolean copyDER
;
1597 PKIX_PL_Cert
*cert
= NULL
;
1599 PKIX_ENTER(CERT
, "PKIX_PL_Cert_Create");
1600 PKIX_NULLCHECK_TWO(pCert
, byteArray
);
1602 PKIX_CHECK(PKIX_PL_ByteArray_GetPointer
1603 (byteArray
, &derBytes
, plContext
),
1604 PKIX_BYTEARRAYGETPOINTERFAILED
);
1606 PKIX_CHECK(PKIX_PL_ByteArray_GetLength
1607 (byteArray
, &derLength
, plContext
),
1608 PKIX_BYTEARRAYGETLENGTHFAILED
);
1610 PKIX_CERT_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
1611 derCertItem
= SECITEM_AllocItem(NULL
, NULL
, derLength
);
1612 if (derCertItem
== NULL
){
1613 PKIX_ERROR(PKIX_UNABLETOALLOCATESECITEM
);
1616 PKIX_CERT_DEBUG("\t\tCalling PORT_Memcpy).\n");
1617 (void) PORT_Memcpy(derCertItem
->data
, derBytes
, derLength
);
1620 * setting copyDER to true forces NSS to make its own copy of the DER,
1621 * allowing us to free our copy without worrying about whether NSS
1624 copyDER
= PKIX_TRUE
;
1625 PKIX_CERT_DEBUG("\t\tCalling CERT_DecodeDERCertificate).\n");
1626 nssCert
= CERT_DecodeDERCertificate(derCertItem
, copyDER
, NULL
);
1628 PKIX_ERROR(PKIX_CERTDECODEDERCERTIFICATEFAILED
);
1631 PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
1632 (nssCert
, &cert
, plContext
),
1633 PKIX_CERTCREATEWITHNSSCERTFAILED
);
1639 PKIX_CERT_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
1640 SECITEM_FreeItem(derCertItem
, PKIX_TRUE
);
1643 if (nssCert
&& PKIX_ERROR_RECEIVED
){
1644 PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
1645 CERT_DestroyCertificate(nssCert
);
1649 PKIX_FREE(derBytes
);
1656 * FUNCTION: PKIX_PL_Cert_GetVersion (see comments in pkix_pl_pki.h)
1659 PKIX_PL_Cert_GetVersion(
1661 PKIX_UInt32
*pVersion
,
1664 CERTCertificate
*nssCert
= NULL
;
1665 PKIX_UInt32 myVersion
;
1667 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetVersion");
1668 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pVersion
);
1670 nssCert
= cert
->nssCert
;
1671 myVersion
= *(nssCert
->version
.data
);
1674 PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1V2ORV3
);
1677 *pVersion
= myVersion
;
1685 * FUNCTION: PKIX_PL_Cert_GetSerialNumber (see comments in pkix_pl_pki.h)
1688 PKIX_PL_Cert_GetSerialNumber(
1690 PKIX_PL_BigInt
**pSerialNumber
,
1693 CERTCertificate
*nssCert
= NULL
;
1694 SECItem serialNumItem
;
1695 PKIX_PL_BigInt
*serialNumber
= NULL
;
1699 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetSerialNumber");
1700 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pSerialNumber
);
1702 if (cert
->serialNumber
== NULL
){
1704 PKIX_OBJECT_LOCK(cert
);
1706 if (cert
->serialNumber
== NULL
){
1708 nssCert
= cert
->nssCert
;
1709 serialNumItem
= nssCert
->serialNumber
;
1711 length
= serialNumItem
.len
;
1712 bytes
= (char *)serialNumItem
.data
;
1714 PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
1715 (bytes
, length
, &serialNumber
, plContext
),
1716 PKIX_BIGINTCREATEWITHBYTESFAILED
);
1718 /* save a cached copy in case it is asked for again */
1719 cert
->serialNumber
= serialNumber
;
1722 PKIX_OBJECT_UNLOCK(cert
);
1725 PKIX_INCREF(cert
->serialNumber
);
1726 *pSerialNumber
= cert
->serialNumber
;
1729 if (objectIsLocked
== PKIX_TRUE
) {
1730 PKIX_OBJECT_UNLOCK(lockedObject
);
1738 * FUNCTION: PKIX_PL_Cert_GetSubject (see comments in pkix_pl_pki.h)
1741 PKIX_PL_Cert_GetSubject(
1743 PKIX_PL_X500Name
**pCertSubject
,
1746 PKIX_PL_X500Name
*pkixSubject
= NULL
;
1747 CERTCertificate
*nssCert
= NULL
;
1748 char *utf8Subject
= NULL
;
1750 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetSubject");
1751 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pCertSubject
);
1753 /* if we don't have a cached copy from before, we create one */
1754 if (cert
->subject
== NULL
){
1756 PKIX_OBJECT_LOCK(cert
);
1758 if (cert
->subject
== NULL
){
1760 nssCert
= cert
->nssCert
;
1761 utf8Subject
= nssCert
->subjectName
;
1763 /* if there is no subject name */
1764 if (utf8Subject
== NULL
) {
1770 PKIX_CHECK(pkix_pl_X500Name_CreateFromUtf8
1771 (utf8Subject
, &pkixSubject
, plContext
),
1772 PKIX_X500NAMECREATEFROMUTF8FAILED
);
1775 /* save a cached copy in case it is asked for again */
1776 cert
->subject
= pkixSubject
;
1779 PKIX_OBJECT_UNLOCK(cert
);
1782 PKIX_INCREF(cert
->subject
);
1783 *pCertSubject
= cert
->subject
;
1786 if (objectIsLocked
== PKIX_TRUE
) {
1787 PKIX_OBJECT_UNLOCK(lockedObject
);
1796 * FUNCTION: PKIX_PL_Cert_GetIssuer (see comments in pkix_pl_pki.h)
1799 PKIX_PL_Cert_GetIssuer(
1801 PKIX_PL_X500Name
**pCertIssuer
,
1804 PKIX_PL_X500Name
*pkixIssuer
= NULL
;
1805 CERTCertificate
*nssCert
= NULL
;
1806 char *utf8Issuer
= NULL
;
1808 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetIssuer");
1809 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pCertIssuer
);
1811 /* if we don't have a cached copy from before, we create one */
1812 if (cert
->issuer
== NULL
){
1814 PKIX_OBJECT_LOCK(cert
);
1816 if (cert
->issuer
== NULL
){
1818 nssCert
= cert
->nssCert
;
1819 utf8Issuer
= nssCert
->issuerName
;
1821 PKIX_CHECK(pkix_pl_X500Name_CreateFromUtf8
1822 (utf8Issuer
, &pkixIssuer
, plContext
),
1823 PKIX_X500NAMECREATEFROMUTF8FAILED
);
1825 /* save a cached copy in case it is asked for again */
1826 cert
->issuer
= pkixIssuer
;
1829 PKIX_OBJECT_UNLOCK(cert
);
1832 PKIX_INCREF(cert
->issuer
);
1833 *pCertIssuer
= cert
->issuer
;
1842 * FUNCTION: PKIX_PL_Cert_GetSubjectAltNames (see comments in pkix_pl_pki.h)
1845 PKIX_PL_Cert_GetSubjectAltNames(
1847 PKIX_List
**pSubjectAltNames
, /* list of PKIX_PL_GeneralName */
1850 PKIX_PL_GeneralName
*pkixAltName
= NULL
;
1851 PKIX_List
*altNamesList
= NULL
;
1853 CERTGeneralName
*nssOriginalAltName
= NULL
;
1854 CERTGeneralName
*nssTempAltName
= NULL
;
1856 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetSubjectAltNames");
1857 PKIX_NULLCHECK_TWO(cert
, pSubjectAltNames
);
1859 /* if we don't have a cached copy from before, we create one */
1860 if ((cert
->subjAltNames
== NULL
) && (!cert
->subjAltNamesAbsent
)){
1862 PKIX_OBJECT_LOCK(cert
);
1864 if ((cert
->subjAltNames
== NULL
) &&
1865 (!cert
->subjAltNamesAbsent
)){
1867 PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
1870 &nssOriginalAltName
,
1872 PKIX_CERTGETNSSSUBJECTALTNAMESFAILED
);
1874 if (nssOriginalAltName
== NULL
) {
1875 cert
->subjAltNamesAbsent
= PKIX_TRUE
;
1876 pSubjectAltNames
= NULL
;
1880 nssTempAltName
= nssOriginalAltName
;
1882 PKIX_CHECK(PKIX_List_Create(&altNamesList
, plContext
),
1883 PKIX_LISTCREATEFAILED
);
1886 PKIX_CHECK(pkix_pl_GeneralName_Create
1887 (nssTempAltName
, &pkixAltName
, plContext
),
1888 PKIX_GENERALNAMECREATEFAILED
);
1890 PKIX_CHECK(PKIX_List_AppendItem
1892 (PKIX_PL_Object
*)pkixAltName
,
1894 PKIX_LISTAPPENDITEMFAILED
);
1896 PKIX_DECREF(pkixAltName
);
1899 ("\t\tCalling CERT_GetNextGeneralName).\n");
1900 nssTempAltName
= CERT_GetNextGeneralName
1903 } while (nssTempAltName
!= nssOriginalAltName
);
1905 /* save a cached copy in case it is asked for again */
1906 cert
->subjAltNames
= altNamesList
;
1907 PKIX_CHECK(PKIX_List_SetImmutable
1908 (cert
->subjAltNames
, plContext
),
1909 PKIX_LISTSETIMMUTABLEFAILED
);
1913 PKIX_OBJECT_UNLOCK(cert
);
1916 PKIX_INCREF(cert
->subjAltNames
);
1918 *pSubjectAltNames
= cert
->subjAltNames
;
1922 PKIX_DECREF(pkixAltName
);
1924 if (PKIX_ERROR_RECEIVED
){
1925 PKIX_DECREF(altNamesList
);
1932 * FUNCTION: PKIX_PL_Cert_GetAllSubjectNames (see comments in pkix_pl_pki.h)
1935 PKIX_PL_Cert_GetAllSubjectNames(
1937 PKIX_List
**pAllSubjectNames
, /* list of PKIX_PL_GeneralName */
1940 CERTGeneralName
*nssOriginalSubjectName
= NULL
;
1941 CERTGeneralName
*nssTempSubjectName
= NULL
;
1942 PKIX_List
*allSubjectNames
= NULL
;
1943 PKIX_PL_GeneralName
*pkixSubjectName
= NULL
;
1944 PRArenaPool
*arena
= NULL
;
1946 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetAllSubjectNames");
1947 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pAllSubjectNames
);
1950 if (cert
->nssCert
->subjectName
== NULL
){
1951 /* if there is no subject DN, just get altnames */
1953 PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
1955 PKIX_FALSE
, /* hasLock */
1956 &nssOriginalSubjectName
,
1958 PKIX_CERTGETNSSSUBJECTALTNAMESFAILED
);
1960 } else { /* get subject DN and altnames */
1962 PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena\n");
1963 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
1964 if (arena
== NULL
) {
1965 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
1968 /* This NSS call returns both Subject and Subject Alt Names */
1969 PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
1970 nssOriginalSubjectName
=
1971 CERT_GetCertificateNames(cert
->nssCert
, arena
);
1974 if (nssOriginalSubjectName
== NULL
) {
1975 pAllSubjectNames
= NULL
;
1979 nssTempSubjectName
= nssOriginalSubjectName
;
1981 PKIX_CHECK(PKIX_List_Create(&allSubjectNames
, plContext
),
1982 PKIX_LISTCREATEFAILED
);
1985 PKIX_CHECK(pkix_pl_GeneralName_Create
1986 (nssTempSubjectName
, &pkixSubjectName
, plContext
),
1987 PKIX_GENERALNAMECREATEFAILED
);
1989 PKIX_CHECK(PKIX_List_AppendItem
1991 (PKIX_PL_Object
*)pkixSubjectName
,
1993 PKIX_LISTAPPENDITEMFAILED
);
1995 PKIX_DECREF(pkixSubjectName
);
1998 ("\t\tCalling CERT_GetNextGeneralName).\n");
1999 nssTempSubjectName
= CERT_GetNextGeneralName
2000 (nssTempSubjectName
);
2001 } while (nssTempSubjectName
!= nssOriginalSubjectName
);
2003 *pAllSubjectNames
= allSubjectNames
;
2007 if (PKIX_ERROR_RECEIVED
){
2008 PKIX_DECREF(allSubjectNames
);
2012 PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
2013 PORT_FreeArena(arena
, PR_FALSE
);
2016 PKIX_DECREF(pkixSubjectName
);
2022 * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKeyAlgId
2023 * (see comments in pkix_pl_pki.h)
2026 PKIX_PL_Cert_GetSubjectPublicKeyAlgId(
2028 PKIX_PL_OID
**pSubjKeyAlgId
,
2031 CERTCertificate
*nssCert
= NULL
;
2032 PKIX_PL_OID
*pubKeyAlgId
= NULL
;
2033 SECAlgorithmID algorithm
;
2035 char *asciiOID
= NULL
;
2037 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetSubjectPublicKeyAlgId");
2038 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pSubjKeyAlgId
);
2040 /* if we don't have a cached copy from before, we create one */
2041 if (cert
->publicKeyAlgId
== NULL
){
2043 PKIX_OBJECT_LOCK(cert
);
2045 if (cert
->publicKeyAlgId
== NULL
){
2047 nssCert
= cert
->nssCert
;
2048 algorithm
= nssCert
->subjectPublicKeyInfo
.algorithm
;
2049 algBytes
= algorithm
.algorithm
;
2051 PKIX_NULLCHECK_ONE(algBytes
.data
);
2052 if (algBytes
.len
== 0) {
2053 PKIX_ERROR_FATAL(PKIX_ALGORITHMBYTESLENGTH0
);
2056 PKIX_CHECK(pkix_pl_oidBytes2Ascii
2057 (&algBytes
, &asciiOID
, plContext
),
2058 PKIX_OIDBYTES2ASCIIFAILED
);
2060 PKIX_CHECK(PKIX_PL_OID_Create
2061 (asciiOID
, &pubKeyAlgId
, plContext
),
2062 PKIX_OIDCREATEFAILED
);
2064 /* save a cached copy in case it is asked for again */
2065 cert
->publicKeyAlgId
= pubKeyAlgId
;
2068 PKIX_OBJECT_UNLOCK(cert
);
2071 PKIX_INCREF(cert
->publicKeyAlgId
);
2072 *pSubjKeyAlgId
= cert
->publicKeyAlgId
;
2076 PKIX_FREE(asciiOID
);
2082 * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKey (see comments in pkix_pl_pki.h)
2085 PKIX_PL_Cert_GetSubjectPublicKey(
2087 PKIX_PL_PublicKey
**pPublicKey
,
2090 PKIX_PL_PublicKey
*pkixPubKey
= NULL
;
2093 CERTSubjectPublicKeyInfo
*from
= NULL
;
2094 CERTSubjectPublicKeyInfo
*to
= NULL
;
2095 SECItem
*fromItem
= NULL
;
2096 SECItem
*toItem
= NULL
;
2098 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetSubjectPublicKey");
2099 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pPublicKey
);
2101 /* if we don't have a cached copy from before, we create one */
2102 if (cert
->publicKey
== NULL
){
2104 PKIX_OBJECT_LOCK(cert
);
2106 if (cert
->publicKey
== NULL
){
2108 /* create a PKIX_PL_PublicKey object */
2109 PKIX_CHECK(PKIX_PL_Object_Alloc
2110 (PKIX_PUBLICKEY_TYPE
,
2111 sizeof (PKIX_PL_PublicKey
),
2112 (PKIX_PL_Object
**)&pkixPubKey
,
2114 PKIX_COULDNOTCREATEOBJECT
);
2116 /* initialize fields */
2117 pkixPubKey
->nssSPKI
= NULL
;
2119 /* populate the SPKI field */
2120 PKIX_CHECK(PKIX_PL_Malloc
2121 (sizeof (CERTSubjectPublicKeyInfo
),
2122 (void **)&pkixPubKey
->nssSPKI
,
2126 to
= pkixPubKey
->nssSPKI
;
2127 from
= &cert
->nssCert
->subjectPublicKeyInfo
;
2129 PKIX_NULLCHECK_TWO(to
, from
);
2132 ("\t\tCalling SECOID_CopyAlgorithmID).\n");
2133 rv
= SECOID_CopyAlgorithmID
2134 (NULL
, &to
->algorithm
, &from
->algorithm
);
2135 if (rv
!= SECSuccess
) {
2136 PKIX_ERROR(PKIX_SECOIDCOPYALGORITHMIDFAILED
);
2140 * NSS stores the length of subjectPublicKey in bits.
2141 * Therefore, we use that length converted to bytes
2142 * using ((length+7)>>3) before calling PORT_Memcpy
2143 * in order to avoid "read from uninitialized memory"
2147 toItem
= &to
->subjectPublicKey
;
2148 fromItem
= &from
->subjectPublicKey
;
2150 PKIX_NULLCHECK_TWO(toItem
, fromItem
);
2152 toItem
->type
= fromItem
->type
;
2154 PKIX_CERT_DEBUG("\t\tCalling PORT_ZAlloc).\n");
2156 (unsigned char*) PORT_ZAlloc(fromItem
->len
);
2158 PKIX_ERROR(PKIX_PORTZALLOCFAILED
);
2161 PKIX_CERT_DEBUG("\t\tCalling PORT_Memcpy).\n");
2162 (void) PORT_Memcpy(toItem
->data
,
2164 (fromItem
->len
+ 7)>>3);
2165 toItem
->len
= fromItem
->len
;
2167 /* save a cached copy in case it is asked for again */
2168 cert
->publicKey
= pkixPubKey
;
2171 PKIX_OBJECT_UNLOCK(cert
);
2174 PKIX_INCREF(cert
->publicKey
);
2175 *pPublicKey
= cert
->publicKey
;
2178 if (objectIsLocked
== PKIX_TRUE
) {
2179 PKIX_OBJECT_UNLOCK(lockedObject
);
2183 if (PKIX_ERROR_RECEIVED
){
2184 PKIX_DECREF(pkixPubKey
);
2191 * FUNCTION: PKIX_PL_Cert_GetCriticalExtensionOIDs
2192 * (see comments in pkix_pl_pki.h)
2195 PKIX_PL_Cert_GetCriticalExtensionOIDs(
2197 PKIX_List
**pList
, /* list of PKIX_PL_OID */
2200 PKIX_List
*oidsList
= NULL
;
2201 CERTCertExtension
**extensions
= NULL
;
2202 CERTCertificate
*nssCert
= NULL
;
2204 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetCriticalExtensionOIDs");
2205 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pList
);
2207 /* if we don't have a cached copy from before, we create one */
2208 if (cert
->critExtOids
== NULL
) {
2210 PKIX_OBJECT_LOCK(cert
);
2212 if (cert
->critExtOids
== NULL
) {
2214 nssCert
= cert
->nssCert
;
2217 * ASN.1 for Extension
2219 * Extension ::= SEQUENCE {
2220 * extnID OBJECT IDENTIFIER,
2221 * critical BOOLEAN DEFAULT FALSE,
2222 * extnValue OCTET STRING }
2226 extensions
= nssCert
->extensions
;
2228 PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
2229 (extensions
, &oidsList
, plContext
),
2230 PKIX_GETCRITICALEXTENSIONOIDSFAILED
);
2232 /* save a cached copy in case it is asked for again */
2233 cert
->critExtOids
= oidsList
;
2236 PKIX_OBJECT_UNLOCK(cert
);
2239 /* We should return a copy of the List since this list changes */
2240 PKIX_DUPLICATE(cert
->critExtOids
, pList
, plContext
,
2241 PKIX_OBJECTDUPLICATELISTFAILED
);
2244 if (objectIsLocked
== PKIX_TRUE
) {
2245 PKIX_OBJECT_UNLOCK(lockedObject
);
2253 * FUNCTION: PKIX_PL_Cert_GetAuthorityKeyIdentifier
2254 * (see comments in pkix_pl_pki.h)
2257 PKIX_PL_Cert_GetAuthorityKeyIdentifier(
2259 PKIX_PL_ByteArray
**pAuthKeyId
,
2262 PKIX_PL_ByteArray
*authKeyId
= NULL
;
2263 CERTCertificate
*nssCert
= NULL
;
2264 CERTAuthKeyID
*authKeyIdExtension
= NULL
;
2265 PRArenaPool
*arena
= NULL
;
2268 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetAuthorityKeyIdentifier");
2269 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pAuthKeyId
);
2271 /* if we don't have a cached copy from before, we create one */
2272 if ((cert
->authKeyId
== NULL
) && (!cert
->authKeyIdAbsent
)){
2274 PKIX_OBJECT_LOCK(cert
);
2276 if ((cert
->authKeyId
== NULL
) && (!cert
->authKeyIdAbsent
)){
2278 PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n");
2279 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
2280 if (arena
== NULL
) {
2281 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
2284 nssCert
= cert
->nssCert
;
2286 authKeyIdExtension
=
2287 CERT_FindAuthKeyIDExten(arena
, nssCert
);
2288 if (authKeyIdExtension
== NULL
){
2289 cert
->authKeyIdAbsent
= PKIX_TRUE
;
2294 retItem
= authKeyIdExtension
->keyID
;
2296 if (retItem
.len
== 0){
2297 cert
->authKeyIdAbsent
= PKIX_TRUE
;
2302 PKIX_CHECK(PKIX_PL_ByteArray_Create
2307 PKIX_BYTEARRAYCREATEFAILED
);
2309 /* save a cached copy in case it is asked for again */
2310 cert
->authKeyId
= authKeyId
;
2313 PKIX_OBJECT_UNLOCK(cert
);
2316 PKIX_INCREF(cert
->authKeyId
);
2317 *pAuthKeyId
= cert
->authKeyId
;
2320 if (objectIsLocked
== PKIX_TRUE
) {
2321 PKIX_OBJECT_UNLOCK(lockedObject
);
2326 PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
2327 PORT_FreeArena(arena
, PR_FALSE
);
2334 * FUNCTION: PKIX_PL_Cert_GetSubjectKeyIdentifier
2335 * (see comments in pkix_pl_pki.h)
2338 PKIX_PL_Cert_GetSubjectKeyIdentifier(
2340 PKIX_PL_ByteArray
**pSubjKeyId
,
2343 PKIX_PL_ByteArray
*subjKeyId
= NULL
;
2344 CERTCertificate
*nssCert
= NULL
;
2345 SECItem
*retItem
= NULL
;
2348 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetSubjectKeyIdentifier");
2349 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pSubjKeyId
);
2351 /* if we don't have a cached copy from before, we create one */
2352 if ((cert
->subjKeyId
== NULL
) && (!cert
->subjKeyIdAbsent
)){
2354 PKIX_OBJECT_LOCK(cert
);
2356 if ((cert
->subjKeyId
== NULL
) && (!cert
->subjKeyIdAbsent
)){
2358 PKIX_CERT_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
2359 retItem
= SECITEM_AllocItem(NULL
, NULL
, 0);
2360 if (retItem
== NULL
){
2361 PKIX_ERROR(PKIX_UNABLETOALLOCATESECITEM
);
2364 nssCert
= cert
->nssCert
;
2366 status
= CERT_FindSubjectKeyIDExtension
2368 if (status
!= SECSuccess
) {
2369 cert
->subjKeyIdAbsent
= PKIX_TRUE
;
2374 PKIX_CHECK(PKIX_PL_ByteArray_Create
2379 PKIX_BYTEARRAYCREATEFAILED
);
2381 /* save a cached copy in case it is asked for again */
2382 cert
->subjKeyId
= subjKeyId
;
2385 PKIX_OBJECT_UNLOCK(cert
);
2388 PKIX_INCREF(cert
->subjKeyId
);
2389 *pSubjKeyId
= cert
->subjKeyId
;
2392 if (objectIsLocked
== PKIX_TRUE
) {
2393 PKIX_OBJECT_UNLOCK(lockedObject
);
2398 PKIX_CERT_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
2399 SECITEM_FreeItem(retItem
, PKIX_TRUE
);
2406 * FUNCTION: PKIX_PL_Cert_GetExtendedKeyUsage (see comments in pkix_pl_pki.h)
2409 PKIX_PL_Cert_GetExtendedKeyUsage(
2411 PKIX_List
**pKeyUsage
, /* list of PKIX_PL_OID */
2414 CERTOidSequence
*extKeyUsage
= NULL
;
2415 CERTCertificate
*nssCert
= NULL
;
2416 PKIX_PL_OID
*pkixOID
= NULL
;
2417 PKIX_List
*oidsList
= NULL
;
2418 char *oidAscii
= NULL
;
2419 SECItem
**oids
= NULL
;
2420 SECItem
*oid
= NULL
;
2421 SECItem encodedExtKeyUsage
;
2424 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetExtendedKeyUsage");
2425 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pKeyUsage
);
2427 /* if we don't have a cached copy from before, we create one */
2428 if ((cert
->extKeyUsages
== NULL
) && (!cert
->extKeyUsagesAbsent
)){
2430 PKIX_OBJECT_LOCK(cert
);
2432 if ((cert
->extKeyUsages
== NULL
) &&
2433 (!cert
->extKeyUsagesAbsent
)){
2435 nssCert
= cert
->nssCert
;
2437 rv
= CERT_FindCertExtension
2438 (nssCert
, SEC_OID_X509_EXT_KEY_USAGE
,
2439 &encodedExtKeyUsage
);
2440 if (rv
!= SECSuccess
){
2441 cert
->extKeyUsagesAbsent
= PKIX_TRUE
;
2447 CERT_DecodeOidSequence(&encodedExtKeyUsage
);
2448 if (extKeyUsage
== NULL
){
2449 PKIX_ERROR(PKIX_CERTDECODEOIDSEQUENCEFAILED
);
2452 PKIX_CERT_DEBUG("\t\tCalling PORT_Free).\n");
2453 PORT_Free(encodedExtKeyUsage
.data
);
2455 oids
= extKeyUsage
->oids
;
2458 /* no extended key usage extensions found */
2459 cert
->extKeyUsagesAbsent
= PKIX_TRUE
;
2464 PKIX_CHECK(PKIX_List_Create(&oidsList
, plContext
),
2465 PKIX_LISTCREATEFAILED
);
2470 PKIX_CHECK(pkix_pl_oidBytes2Ascii
2471 (oid
, &oidAscii
, plContext
),
2472 PKIX_OIDBYTES2ASCIIFAILED
);
2474 PKIX_CHECK(PKIX_PL_OID_Create
2475 (oidAscii
, &pkixOID
, plContext
),
2476 PKIX_OIDCREATEFAILED
);
2478 PKIX_CHECK(PKIX_List_AppendItem
2480 (PKIX_PL_Object
*)pkixOID
,
2482 PKIX_LISTAPPENDITEMFAILED
);
2484 PKIX_FREE(oidAscii
);
2486 PKIX_DECREF(pkixOID
);
2489 /* save a cached copy in case it is asked for again */
2490 cert
->extKeyUsages
= oidsList
;
2493 PKIX_OBJECT_UNLOCK(cert
);
2496 if (cert
->extKeyUsages
){
2498 PKIX_INCREF(cert
->extKeyUsages
);
2500 PKIX_CHECK(PKIX_List_SetImmutable
2501 (cert
->extKeyUsages
, plContext
),
2502 PKIX_LISTSETIMMUTABLEFAILED
);
2505 *pKeyUsage
= cert
->extKeyUsages
;
2508 if (objectIsLocked
== PKIX_TRUE
) {
2509 PKIX_OBJECT_UNLOCK(lockedObject
);
2512 PKIX_FREE(oidAscii
);
2513 PKIX_DECREF(pkixOID
);
2515 CERT_DestroyOidSequence(extKeyUsage
);
2517 if (PKIX_ERROR_RECEIVED
){
2518 PKIX_DECREF(oidsList
);
2525 * FUNCTION: PKIX_PL_Cert_GetBasicConstraints
2526 * (see comments in pkix_pl_pki.h)
2529 PKIX_PL_Cert_GetBasicConstraints(
2531 PKIX_PL_CertBasicConstraints
**pBasicConstraints
,
2534 CERTCertificate
*nssCert
= NULL
;
2535 CERTBasicConstraints nssBasicConstraint
;
2537 PKIX_PL_CertBasicConstraints
*basic
;
2538 PKIX_Int32 pathLen
= 0;
2539 PKIX_Boolean isCA
= PKIX_FALSE
;
2541 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetBasicConstraints");
2542 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pBasicConstraints
);
2544 /* if we don't have a cached copy from before, we create one */
2545 if ((cert
->certBasicConstraints
== NULL
) &&
2546 (!cert
->basicConstraintsAbsent
)) {
2548 PKIX_OBJECT_LOCK(cert
);
2550 if ((cert
->certBasicConstraints
== NULL
) &&
2551 (!cert
->basicConstraintsAbsent
)) {
2553 nssCert
= cert
->nssCert
;
2556 "\t\tCalling Cert_FindBasicConstraintExten\n");
2557 rv
= CERT_FindBasicConstraintExten
2558 (nssCert
, &nssBasicConstraint
);
2559 if (rv
!= SECSuccess
) {
2560 cert
->basicConstraintsAbsent
= PKIX_TRUE
;
2561 *pBasicConstraints
= NULL
;
2566 PKIX_OBJECT_UNLOCK(cert
);
2568 isCA
= (nssBasicConstraint
.isCA
)?PKIX_TRUE
:PKIX_FALSE
;
2570 /* The pathLen has meaning only for CAs */
2572 if (CERT_UNLIMITED_PATH_CONSTRAINT
==
2573 nssBasicConstraint
.pathLenConstraint
) {
2574 pathLen
= PKIX_UNLIMITED_PATH_CONSTRAINT
;
2576 pathLen
= nssBasicConstraint
.pathLenConstraint
;
2580 PKIX_CHECK(pkix_pl_CertBasicConstraints_Create
2581 (isCA
, pathLen
, &basic
, plContext
),
2582 PKIX_CERTBASICCONSTRAINTSCREATEFAILED
);
2584 /* save a cached copy in case it is asked for again */
2585 cert
->certBasicConstraints
= basic
;
2588 PKIX_INCREF(cert
->certBasicConstraints
);
2589 *pBasicConstraints
= cert
->certBasicConstraints
;
2592 if (objectIsLocked
== PKIX_TRUE
) {
2593 PKIX_OBJECT_UNLOCK(lockedObject
);
2601 * FUNCTION: PKIX_PL_Cert_GetPolicyInformation
2602 * (see comments in pkix_pl_pki.h)
2605 PKIX_PL_Cert_GetPolicyInformation(
2607 PKIX_List
**pPolicyInfo
,
2610 PKIX_List
*policyList
= NULL
;
2612 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetPolicyInformation");
2613 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pPolicyInfo
);
2615 /* if we don't have a cached copy from before, we create one */
2616 if ((cert
->certPolicyInfos
== NULL
) &&
2617 (!cert
->policyInfoAbsent
)) {
2619 PKIX_OBJECT_LOCK(cert
);
2621 if ((cert
->certPolicyInfos
== NULL
) &&
2622 (!cert
->policyInfoAbsent
)) {
2624 PKIX_CHECK(pkix_pl_Cert_DecodePolicyInfo
2625 (cert
->nssCert
, &policyList
, plContext
),
2626 PKIX_CERTDECODEPOLICYINFOFAILED
);
2629 cert
->policyInfoAbsent
= PKIX_TRUE
;
2630 *pPolicyInfo
= NULL
;
2635 PKIX_OBJECT_UNLOCK(cert
);
2637 /* save a cached copy in case it is asked for again */
2638 cert
->certPolicyInfos
= policyList
;
2641 PKIX_INCREF(cert
->certPolicyInfos
);
2643 *pPolicyInfo
= cert
->certPolicyInfos
;
2646 if (objectIsLocked
== PKIX_TRUE
) {
2647 PKIX_OBJECT_UNLOCK(lockedObject
);
2654 * FUNCTION: PKIX_PL_Cert_GetPolicyMappings (see comments in pkix_pl_pki.h)
2657 PKIX_PL_Cert_GetPolicyMappings(
2659 PKIX_List
**pPolicyMappings
, /* list of PKIX_PL_CertPolicyMap */
2662 PKIX_List
*policyMappings
= NULL
; /* list of PKIX_PL_CertPolicyMap */
2664 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetPolicyMappings");
2665 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pPolicyMappings
);
2667 /* if we don't have a cached copy from before, we create one */
2668 if (!(cert
->certPolicyMappings
) && !(cert
->policyMappingsAbsent
)) {
2670 PKIX_OBJECT_LOCK(cert
);
2672 if (!(cert
->certPolicyMappings
) &&
2673 !(cert
->policyMappingsAbsent
)) {
2675 PKIX_CHECK(pkix_pl_Cert_DecodePolicyMapping
2676 (cert
->nssCert
, &policyMappings
, plContext
),
2677 PKIX_CERTDECODEPOLICYMAPPINGFAILED
);
2679 if (!policyMappings
) {
2680 cert
->policyMappingsAbsent
= PKIX_TRUE
;
2681 *pPolicyMappings
= NULL
;
2686 PKIX_OBJECT_UNLOCK(cert
);
2688 /* save a cached copy in case it is asked for again */
2689 cert
->certPolicyMappings
= policyMappings
;
2692 PKIX_INCREF(cert
->certPolicyMappings
);
2693 *pPolicyMappings
= cert
->certPolicyMappings
;
2696 if (objectIsLocked
== PKIX_TRUE
) {
2697 PKIX_OBJECT_UNLOCK(lockedObject
);
2704 * FUNCTION: PKIX_PL_Cert_GetRequireExplicitPolicy
2705 * (see comments in pkix_pl_pki.h)
2708 PKIX_PL_Cert_GetRequireExplicitPolicy(
2710 PKIX_Int32
*pSkipCerts
,
2713 PKIX_Int32 explicitPolicySkipCerts
= 0;
2714 PKIX_Int32 inhibitMappingSkipCerts
= 0;
2716 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetRequireExplicitPolicy");
2717 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pSkipCerts
);
2719 if (!(cert
->policyConstraintsProcessed
)) {
2720 PKIX_OBJECT_LOCK(cert
);
2722 if (!(cert
->policyConstraintsProcessed
)) {
2725 * If we can't process it now, we probably will be
2726 * unable to process it later. Set the default value.
2728 cert
->policyConstraintsProcessed
= PKIX_TRUE
;
2729 cert
->policyConstraintsExplicitPolicySkipCerts
= -1;
2730 cert
->policyConstraintsInhibitMappingSkipCerts
= -1;
2732 PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
2734 &explicitPolicySkipCerts
,
2735 &inhibitMappingSkipCerts
,
2737 PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED
);
2739 cert
->policyConstraintsExplicitPolicySkipCerts
=
2740 explicitPolicySkipCerts
;
2741 cert
->policyConstraintsInhibitMappingSkipCerts
=
2742 inhibitMappingSkipCerts
;
2745 PKIX_OBJECT_UNLOCK(cert
);
2748 *pSkipCerts
= cert
->policyConstraintsExplicitPolicySkipCerts
;
2752 if (objectIsLocked
== PKIX_TRUE
) {
2753 PKIX_OBJECT_UNLOCK(lockedObject
);
2760 * FUNCTION: PKIX_PL_Cert_GetPolicyMappingInhibited
2761 * (see comments in pkix_pl_pki.h)
2764 PKIX_PL_Cert_GetPolicyMappingInhibited(
2766 PKIX_Int32
*pSkipCerts
,
2769 PKIX_Int32 explicitPolicySkipCerts
= 0;
2770 PKIX_Int32 inhibitMappingSkipCerts
= 0;
2772 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetPolicyMappingInhibited");
2773 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pSkipCerts
);
2775 if (!(cert
->policyConstraintsProcessed
)) {
2776 PKIX_OBJECT_LOCK(cert
);
2778 if (!(cert
->policyConstraintsProcessed
)) {
2781 * If we can't process it now, we probably will be
2782 * unable to process it later. Set the default value.
2784 cert
->policyConstraintsProcessed
= PKIX_TRUE
;
2785 cert
->policyConstraintsExplicitPolicySkipCerts
= -1;
2786 cert
->policyConstraintsInhibitMappingSkipCerts
= -1;
2788 PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
2790 &explicitPolicySkipCerts
,
2791 &inhibitMappingSkipCerts
,
2793 PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED
);
2795 cert
->policyConstraintsExplicitPolicySkipCerts
=
2796 explicitPolicySkipCerts
;
2797 cert
->policyConstraintsInhibitMappingSkipCerts
=
2798 inhibitMappingSkipCerts
;
2801 PKIX_OBJECT_UNLOCK(cert
);
2804 *pSkipCerts
= cert
->policyConstraintsInhibitMappingSkipCerts
;
2808 if (objectIsLocked
== PKIX_TRUE
) {
2809 PKIX_OBJECT_UNLOCK(lockedObject
);
2816 * FUNCTION: PKIX_PL_Cert_GetInhibitAnyPolicy (see comments in pkix_pl_pki.h)
2819 PKIX_PL_Cert_GetInhibitAnyPolicy(
2821 PKIX_Int32
*pSkipCerts
,
2824 PKIX_Int32 skipCerts
= 0;
2826 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetInhibitAnyPolicy");
2827 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pSkipCerts
);
2829 if (!(cert
->inhibitAnyPolicyProcessed
)) {
2831 PKIX_OBJECT_LOCK(cert
);
2833 if (!(cert
->inhibitAnyPolicyProcessed
)) {
2836 * If we can't process it now, we probably will be
2837 * unable to process it later. Set the default value.
2839 cert
->inhibitAnyPolicyProcessed
= PKIX_TRUE
;
2840 cert
->inhibitAnySkipCerts
= -1;
2842 PKIX_CHECK(pkix_pl_Cert_DecodeInhibitAnyPolicy
2843 (cert
->nssCert
, &skipCerts
, plContext
),
2844 PKIX_CERTDECODEINHIBITANYPOLICYFAILED
);
2846 cert
->inhibitAnySkipCerts
= skipCerts
;
2849 PKIX_OBJECT_UNLOCK(cert
);
2854 if (objectIsLocked
== PKIX_TRUE
) {
2855 PKIX_OBJECT_UNLOCK(lockedObject
);
2858 *pSkipCerts
= cert
->inhibitAnySkipCerts
;
2864 * FUNCTION: PKIX_PL_Cert_AreCertPoliciesCritical
2865 * (see comments in pkix_pl_pki.h)
2868 PKIX_PL_Cert_AreCertPoliciesCritical(
2870 PKIX_Boolean
*pCritical
,
2873 PKIX_Boolean criticality
= PKIX_FALSE
;
2875 PKIX_ENTER(CERT
, "PKIX_PL_Cert_AreCertPoliciesCritical");
2876 PKIX_NULLCHECK_TWO(cert
, pCritical
);
2878 PKIX_CHECK(pkix_pl_Cert_IsExtensionCritical(
2880 SEC_OID_X509_CERTIFICATE_POLICIES
,
2883 PKIX_CERTISEXTENSIONCRITICALFAILED
);
2885 *pCritical
= criticality
;
2893 * FUNCTION: PKIX_PL_Cert_VerifySignature (see comments in pkix_pl_pki.h)
2896 PKIX_PL_Cert_VerifySignature(
2898 PKIX_PL_PublicKey
*pubKey
,
2901 CERTCertificate
*nssCert
= NULL
;
2902 SECKEYPublicKey
*nssPubKey
= NULL
;
2903 CERTSignedData
*tbsCert
= NULL
;
2904 PKIX_PL_Cert
*cachedCert
= NULL
;
2905 PKIX_Error
*verifySig
= NULL
;
2906 PKIX_Error
*cachedSig
= NULL
;
2908 PKIX_Boolean certEqual
= PKIX_FALSE
;
2909 PKIX_Boolean certInHash
= PKIX_FALSE
;
2911 PKIX_ENTER(CERT
, "PKIX_PL_Cert_VerifySignature");
2912 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pubKey
);
2914 verifySig
= PKIX_PL_HashTable_Lookup
2915 (cachedCertSigTable
,
2916 (PKIX_PL_Object
*) pubKey
,
2917 (PKIX_PL_Object
**) &cachedCert
,
2920 if (cachedCert
!= NULL
&& verifySig
== NULL
) {
2921 /* Cached Signature Table lookup succeed */
2922 PKIX_EQUALS(cert
, cachedCert
, &certEqual
, plContext
,
2923 PKIX_OBJECTEQUALSFAILED
);
2924 if (certEqual
== PKIX_TRUE
) {
2927 /* Different PubKey may hash to same value, skip add */
2928 certInHash
= PKIX_TRUE
;
2931 nssCert
= cert
->nssCert
;
2932 tbsCert
= &nssCert
->signatureWrap
;
2934 PKIX_CERT_DEBUG("\t\tCalling SECKEY_ExtractPublicKey).\n");
2935 nssPubKey
= SECKEY_ExtractPublicKey(pubKey
->nssSPKI
);
2937 PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED
);
2940 PKIX_CERT_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey).\n");
2941 status
= CERT_VerifySignedDataWithPublicKey(tbsCert
, nssPubKey
, NULL
);
2943 if (status
!= SECSuccess
) {
2944 PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHISPUBLICKEY
);
2947 if (certInHash
== PKIX_FALSE
) {
2948 cachedSig
= PKIX_PL_HashTable_Add
2949 (cachedCertSigTable
,
2950 (PKIX_PL_Object
*) pubKey
,
2951 (PKIX_PL_Object
*) cert
,
2954 if (cachedSig
!= NULL
) {
2955 PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
2962 PKIX_CERT_DEBUG("\t\tCalling SECKEY_DestroyPublicKey).\n");
2963 SECKEY_DestroyPublicKey(nssPubKey
);
2966 PKIX_DECREF(cachedCert
);
2967 PKIX_DECREF(verifySig
);
2968 PKIX_DECREF(cachedSig
);
2974 * FUNCTION: PKIX_PL_Cert_CheckValidity (see comments in pkix_pl_pki.h)
2977 PKIX_PL_Cert_CheckValidity(
2982 SECCertTimeValidity val
;
2985 PKIX_ENTER(CERT
, "PKIX_PL_Cert_CheckValidity");
2986 PKIX_NULLCHECK_ONE(cert
);
2988 /* if the caller supplies a date, we use it; else, use current time */
2990 PKIX_CHECK(pkix_pl_Date_GetPRTime
2991 (date
, &timeToCheck
, plContext
),
2992 PKIX_DATEGETPRTIMEFAILED
);
2994 PKIX_CERT_DEBUG("\t\tCalling PR_Now).\n");
2995 timeToCheck
= PR_Now();
2998 PKIX_CERT_DEBUG("\t\tCalling CERT_CheckCertValidTimes).\n");
2999 val
= CERT_CheckCertValidTimes(cert
->nssCert
, timeToCheck
, PKIX_FALSE
);
3000 if (val
!= secCertTimeValid
){
3001 PKIX_ERROR(PKIX_CERTCHECKCERTVALIDTIMESFAILED
);
3010 * FUNCTION: PKIX_PL_Cert_GetValidityNotAfter (see comments in pkix_pl_pki.h)
3013 PKIX_PL_Cert_GetValidityNotAfter(
3015 PKIX_PL_Date
**pDate
,
3019 SECStatus rv
= SECFailure
;
3021 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetValidityNotAfter");
3022 PKIX_NULLCHECK_TWO(cert
, pDate
);
3024 PKIX_DATE_DEBUG("\t\tCalling DER_DecodeTimeChoice).\n");
3025 rv
= DER_DecodeTimeChoice(&prtime
, &(cert
->nssCert
->validity
.notAfter
));
3026 if (rv
!= SECSuccess
){
3027 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED
);
3030 PKIX_CHECK(pkix_pl_Date_CreateFromPRTime
3031 (prtime
, pDate
, plContext
),
3032 PKIX_DATECREATEFROMPRTIMEFAILED
);
3040 * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h)
3043 PKIX_PL_Cert_VerifyKeyUsage(
3045 PKIX_UInt32 keyUsage
,
3048 CERTCertificate
*nssCert
= NULL
;
3049 PKIX_UInt32 nssKeyUsage
= 0;
3052 PKIX_ENTER(CERT
, "PKIX_PL_Cert_VerifyKeyUsage");
3053 PKIX_NULLCHECK_TWO(cert
, cert
->nssCert
);
3055 nssCert
= cert
->nssCert
;
3057 /* if cert doesn't have keyUsage extension, all keyUsages are valid */
3058 if (!nssCert
->keyUsagePresent
){
3062 if (keyUsage
& PKIX_DIGITAL_SIGNATURE
){
3063 nssKeyUsage
= nssKeyUsage
| KU_DIGITAL_SIGNATURE
;
3066 if (keyUsage
& PKIX_NON_REPUDIATION
){
3067 nssKeyUsage
= nssKeyUsage
| KU_NON_REPUDIATION
;
3070 if (keyUsage
& PKIX_KEY_ENCIPHERMENT
){
3071 nssKeyUsage
= nssKeyUsage
| KU_KEY_ENCIPHERMENT
;
3074 if (keyUsage
& PKIX_DATA_ENCIPHERMENT
){
3075 nssKeyUsage
= nssKeyUsage
| KU_DATA_ENCIPHERMENT
;
3078 if (keyUsage
& PKIX_KEY_AGREEMENT
){
3079 nssKeyUsage
= nssKeyUsage
| KU_KEY_AGREEMENT
;
3082 if (keyUsage
& PKIX_KEY_CERT_SIGN
){
3083 nssKeyUsage
= nssKeyUsage
| KU_KEY_CERT_SIGN
;
3086 if (keyUsage
& PKIX_CRL_SIGN
){
3087 nssKeyUsage
= nssKeyUsage
| KU_CRL_SIGN
;
3090 if (keyUsage
& PKIX_ENCIPHER_ONLY
){
3091 nssKeyUsage
= nssKeyUsage
| 0x01;
3094 if (keyUsage
& PKIX_DECIPHER_ONLY
){
3095 /* XXX we should support this once it is fixed in NSS */
3096 PKIX_ERROR(PKIX_DECIPHERONLYKEYUSAGENOTSUPPORTED
);
3099 status
= CERT_CheckKeyUsage(nssCert
, nssKeyUsage
);
3100 if (status
!= SECSuccess
) {
3101 PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED
);
3110 * FUNCTION: PKIX_PL_Cert_GetNameConstraints
3111 * (see comments in pkix_pl_pki.h)
3114 PKIX_PL_Cert_GetNameConstraints(
3116 PKIX_PL_CertNameConstraints
**pNameConstraints
,
3119 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
3121 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetNameConstraints");
3122 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pNameConstraints
);
3124 /* if we don't have a cached copy from before, we create one */
3125 if (cert
->nameConstraints
== NULL
&& !cert
->nameConstraintsAbsent
) {
3127 PKIX_OBJECT_LOCK(cert
);
3129 if (cert
->nameConstraints
== NULL
&&
3130 !cert
->nameConstraintsAbsent
) {
3132 PKIX_CHECK(pkix_pl_CertNameConstraints_Create
3133 (cert
->nssCert
, &nameConstraints
, plContext
),
3134 PKIX_CERTNAMECONSTRAINTSCREATEFAILED
);
3136 if (nameConstraints
== NULL
) {
3137 cert
->nameConstraintsAbsent
= PKIX_TRUE
;
3140 cert
->nameConstraints
= nameConstraints
;
3143 PKIX_OBJECT_UNLOCK(cert
);
3147 PKIX_INCREF(cert
->nameConstraints
);
3149 *pNameConstraints
= cert
->nameConstraints
;
3153 if (objectIsLocked
== PKIX_TRUE
) {
3154 PKIX_OBJECT_UNLOCK(lockedObject
);
3161 * FUNCTION: PKIX_PL_Cert_CheckNameConstraints
3162 * (see comments in pkix_pl_pki.h)
3165 PKIX_PL_Cert_CheckNameConstraints(
3167 PKIX_PL_CertNameConstraints
*nameConstraints
,
3170 PKIX_Boolean checkPass
= PKIX_TRUE
;
3171 CERTGeneralName
*nssSubjectNames
= NULL
;
3172 PRArenaPool
*arena
= NULL
;
3174 PKIX_ENTER(CERT
, "PKIX_PL_Cert_CheckNameConstraints");
3175 PKIX_NULLCHECK_ONE(cert
);
3177 if (nameConstraints
!= NULL
) {
3179 PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena\n");
3180 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
3181 if (arena
== NULL
) {
3182 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
3185 /* This NSS call returns both Subject and Subject Alt Names */
3186 PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
3187 nssSubjectNames
= CERT_GetCertificateNames
3188 (cert
->nssCert
, arena
);
3190 PKIX_CHECK(pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
3195 PKIX_CERTNAMECONSTRAINTSCHECKNAMESPACENSSNAMESFAILED
);
3197 if (checkPass
!= PKIX_TRUE
) {
3198 PKIX_ERROR(PKIX_CERTFAILEDNAMECONSTRAINTSCHECKING
);
3205 PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
3206 PORT_FreeArena(arena
, PR_FALSE
);
3213 * FUNCTION: PKIX_PL_Cert_MergeNameConstraints
3214 * (see comments in pkix_pl_pki.h)
3217 PKIX_PL_Cert_MergeNameConstraints(
3218 PKIX_PL_CertNameConstraints
*firstNC
,
3219 PKIX_PL_CertNameConstraints
*secondNC
,
3220 PKIX_PL_CertNameConstraints
**pResultNC
,
3223 PKIX_PL_CertNameConstraints
*mergedNC
= NULL
;
3225 PKIX_ENTER(CERT
, "PKIX_PL_Cert_MergeNameConstraints");
3226 PKIX_NULLCHECK_TWO(firstNC
, pResultNC
);
3228 if (secondNC
== NULL
) {
3230 PKIX_INCREF(firstNC
);
3231 *pResultNC
= firstNC
;
3236 PKIX_CHECK(pkix_pl_CertNameConstraints_Merge
3237 (firstNC
, secondNC
, &mergedNC
, plContext
),
3238 PKIX_CERTNAMECONSTRAINTSMERGEFAILED
);
3240 *pResultNC
= mergedNC
;
3248 * FUNCTION: PKIX_PL_Cert_IsCertTrusted
3249 * (see comments in pkix_pl_pki.h)
3252 PKIX_PL_Cert_IsCertTrusted(
3254 PKIX_Boolean
*pTrusted
,
3257 PKIX_CertStore_CheckTrustCallback trustCallback
= NULL
;
3258 SECCertUsage certUsage
= 0;
3259 PKIX_Boolean trusted
= PKIX_FALSE
;
3260 SECStatus rv
= SECFailure
;
3261 unsigned int requiredFlags
;
3262 unsigned int certFlags
;
3263 SECTrustType trustType
;
3264 CERTCertTrust trust
;
3265 CERTCertificate
*nssCert
= NULL
;
3266 SECCertificateUsage certificateUsage
;
3268 PKIX_ENTER(CERT
, "pkix_pl_Cert_IsCertTrusted");
3269 PKIX_NULLCHECK_TWO(cert
, pTrusted
);
3271 /* no key usage information and store is not trusted */
3272 if (plContext
== NULL
|| cert
->store
== NULL
) {
3273 *pTrusted
= PKIX_FALSE
;
3278 PKIX_CHECK(PKIX_CertStore_GetTrustCallback
3279 (cert
->store
, &trustCallback
, plContext
),
3280 PKIX_CERTSTOREGETTRUSTCALLBACKFAILED
);
3282 PKIX_CHECK_ONLY_FATAL(trustCallback
3283 (cert
->store
, cert
, &trusted
, plContext
),
3284 PKIX_CHECKTRUSTCALLBACKFAILED
);
3286 if (PKIX_ERROR_RECEIVED
|| (trusted
== PKIX_FALSE
)) {
3288 *pTrusted
= PKIX_FALSE
;
3294 certificateUsage
= ((PKIX_PL_NssContext
*)plContext
)->certificateUsage
;
3296 /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
3297 while (0 != (certificateUsage
= certificateUsage
>> 1)) { certUsage
++; }
3302 CERT_TrustFlagsForCACertUsage
,
3303 (certUsage
, &requiredFlags
, &trustType
));
3305 if (rv
!= SECSuccess
) {
3307 trustType
= trustSSL
;
3310 nssCert
= cert
->nssCert
;
3312 PKIX_PL_NSSCALLRV(CERT
, rv
, CERT_GetCertTrust
, (nssCert
, &trust
));
3314 if (rv
== SECSuccess
) {
3316 certFlags
= SEC_GET_TRUST_FLAGS((&trust
), trustType
);
3317 if ((certFlags
& CERTDB_VALID_CA
) &&
3318 ((certFlags
& requiredFlags
) == requiredFlags
)) {
3319 trusted
= PKIX_TRUE
;
3323 *pTrusted
= trusted
;
3331 * FUNCTION: PKIX_PL_Cert_GetCacheFlag (see comments in pkix_pl_pki.h)
3334 PKIX_PL_Cert_GetCacheFlag(
3336 PKIX_Boolean
*pCacheFlag
,
3339 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetCacheFlag");
3340 PKIX_NULLCHECK_TWO(cert
, pCacheFlag
);
3342 *pCacheFlag
= cert
->cacheFlag
;
3348 * FUNCTION: PKIX_PL_Cert_SetCacheFlag (see comments in pkix_pl_pki.h)
3351 PKIX_PL_Cert_SetCacheFlag(
3353 PKIX_Boolean cacheFlag
,
3356 PKIX_ENTER(CERT
, "PKIX_PL_Cert_SetCacheFlag");
3357 PKIX_NULLCHECK_ONE(cert
);
3359 cert
->cacheFlag
= cacheFlag
;
3365 * FUNCTION: PKIX_PL_Cert_GetTrustCertStore (see comments in pkix_pl_pki.h)
3368 PKIX_PL_Cert_GetTrustCertStore(
3370 PKIX_CertStore
**pTrustCertStore
,
3373 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetTrustCertStore");
3374 PKIX_NULLCHECK_TWO(cert
, pTrustCertStore
);
3376 PKIX_INCREF(cert
->store
);
3377 *pTrustCertStore
= cert
->store
;
3383 * FUNCTION: PKIX_PL_Cert_SetTrustCertStore (see comments in pkix_pl_pki.h)
3386 PKIX_PL_Cert_SetTrustCertStore(
3388 PKIX_CertStore
*trustCertStore
,
3391 PKIX_ENTER(CERT
, "PKIX_PL_Cert_SetTrustCertStore");
3392 PKIX_NULLCHECK_TWO(cert
, trustCertStore
);
3394 PKIX_INCREF(trustCertStore
);
3395 cert
->store
= trustCertStore
;
3401 * FUNCTION: PKIX_PL_Cert_GetAuthorityInfoAccess
3402 * (see comments in pkix_pl_pki.h)
3405 PKIX_PL_Cert_GetAuthorityInfoAccess(
3407 PKIX_List
**pAiaList
, /* of PKIX_PL_InfoAccess */
3410 PKIX_List
*aiaList
= NULL
; /* of PKIX_PL_InfoAccess */
3411 SECItem
*encodedAIA
= NULL
;
3412 CERTAuthInfoAccess
**aia
= NULL
;
3413 PRArenaPool
*arena
= NULL
;
3416 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetAuthorityInfoAccess");
3417 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pAiaList
);
3419 /* if we don't have a cached copy from before, we create one */
3420 if (cert
->authorityInfoAccess
== NULL
) {
3422 PKIX_OBJECT_LOCK(cert
);
3424 if (cert
->authorityInfoAccess
== NULL
) {
3426 PKIX_PL_NSSCALLRV(CERT
, encodedAIA
, SECITEM_AllocItem
,
3429 if (encodedAIA
== NULL
) {
3433 PKIX_PL_NSSCALLRV(CERT
, rv
, CERT_FindCertExtension
,
3435 SEC_OID_X509_AUTH_INFO_ACCESS
,
3438 if (rv
== SECFailure
) {
3442 PKIX_PL_NSSCALLRV(CERT
, arena
, PORT_NewArena
,
3443 (DER_DEFAULT_CHUNKSIZE
));
3445 if (arena
== NULL
) {
3450 (CERT
, aia
, CERT_DecodeAuthInfoAccessExtension
,
3451 (arena
, encodedAIA
));
3453 PKIX_CHECK(pkix_pl_InfoAccess_CreateList
3454 (aia
, &aiaList
, plContext
),
3455 PKIX_INFOACCESSCREATELISTFAILED
);
3457 cert
->authorityInfoAccess
= aiaList
;
3460 PKIX_OBJECT_UNLOCK(cert
);
3463 PKIX_INCREF(cert
->authorityInfoAccess
);
3465 *pAiaList
= cert
->authorityInfoAccess
;
3468 if (objectIsLocked
== PKIX_TRUE
) {
3469 PKIX_OBJECT_UNLOCK(lockedObject
);
3472 if (arena
!= NULL
) {
3473 PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
3474 PORT_FreeArena(arena
, PR_FALSE
);
3477 if (encodedAIA
!= NULL
) {
3478 PKIX_CERT_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
3479 SECITEM_FreeItem(encodedAIA
, PR_TRUE
);
3485 /* XXX Following defines belongs to NSS */
3486 static const unsigned char siaOIDString
[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
3488 #define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
3491 * FUNCTION: PKIX_PL_Cert_GetSubjectInfoAccess
3492 * (see comments in pkix_pl_pki.h)
3495 PKIX_PL_Cert_GetSubjectInfoAccess(
3497 PKIX_List
**pSiaList
, /* of PKIX_PL_InfoAccess */
3500 PKIX_List
*siaList
; /* of PKIX_PL_InfoAccess */
3501 SECItem siaOID
= OI(siaOIDString
);
3502 SECItem
*encodedSubjInfoAccess
= NULL
;
3503 CERTAuthInfoAccess
**subjInfoAccess
= NULL
;
3504 PRArenaPool
*arena
= NULL
;
3507 PKIX_ENTER(CERT
, "PKIX_PL_Cert_GetSubjectInfoAccess");
3508 PKIX_NULLCHECK_THREE(cert
, cert
->nssCert
, pSiaList
);
3511 * Codes to deal with SubjectInfoAccess OID should be moved to
3512 * NSS soon. I implemented them here so we don't touch NSS
3513 * source tree, from JP's suggestion.
3516 /* if we don't have a cached copy from before, we create one */
3517 if (cert
->subjectInfoAccess
== NULL
) {
3519 PKIX_OBJECT_LOCK(cert
);
3521 if (cert
->subjectInfoAccess
== NULL
) {
3523 PKIX_CERT_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
3524 encodedSubjInfoAccess
= SECITEM_AllocItem(NULL
, NULL
, 0);
3525 if (encodedSubjInfoAccess
== NULL
) {
3530 ("\t\tCalling CERT_FindCertExtensionByOID).\n");
3531 rv
= CERT_FindCertExtensionByOID
3532 (cert
->nssCert
, &siaOID
, encodedSubjInfoAccess
);
3534 if (rv
== SECFailure
) {
3538 PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n");
3539 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
3540 if (arena
== NULL
) {
3545 * Decode Subject Information Access -
3546 * since its type is the same as Authority Information
3547 * Access, reuse the call. NSS- change name to avoid
3551 ("\t\tCalling CERT_DecodeAuthInfoAccessExtension).\n");
3552 subjInfoAccess
= CERT_DecodeAuthInfoAccessExtension
3553 (arena
, encodedSubjInfoAccess
);
3555 PKIX_CHECK(pkix_pl_InfoAccess_CreateList
3556 (subjInfoAccess
, &siaList
, plContext
),
3557 PKIX_INFOACCESSCREATELISTFAILED
);
3559 cert
->subjectInfoAccess
= siaList
;
3563 PKIX_OBJECT_UNLOCK(cert
);
3566 PKIX_INCREF(cert
->subjectInfoAccess
);
3568 *pSiaList
= cert
->subjectInfoAccess
;
3571 if (objectIsLocked
== PKIX_TRUE
) {
3572 PKIX_OBJECT_UNLOCK(lockedObject
);
3575 if (arena
!= NULL
) {
3576 PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
3577 PORT_FreeArena(arena
, PR_FALSE
);
3580 if (encodedSubjInfoAccess
!= NULL
) {
3581 PKIX_CERT_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
3582 SECITEM_FreeItem(encodedSubjInfoAccess
, PR_TRUE
);