Index: mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c |
=================================================================== |
--- mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c (revision 191424) |
+++ mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c (working copy) |
@@ -1,3710 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
-/* |
- * pkix_pl_cert.c |
- * |
- * Certificate Object Functions |
- * |
- */ |
- |
-#include "pkix_pl_cert.h" |
- |
-extern PKIX_PL_HashTable *cachedCertSigTable; |
- |
-/* --Private-Cert-Functions------------------------------------- */ |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_IsExtensionCritical |
- * DESCRIPTION: |
- * |
- * Checks the Cert specified by "cert" to determine whether the extension |
- * whose tag is the UInt32 value given by "tag" is marked as a critical |
- * extension, and stores the result in "pCritical". |
- * |
- * Tags are the index into the table "oids" of SECOidData defined in the |
- * file secoid.c. Constants, such as SEC_OID_X509_CERTIFICATE_POLICIES, are |
- * are defined in secoidt.h for most of the table entries. |
- * |
- * If the specified tag is invalid (not in the list of tags) or if the |
- * extension is not found in the certificate, PKIX_FALSE is stored. |
- * |
- * PARAMETERS |
- * "cert" |
- * Address of Cert whose extensions are to be examined. Must be non-NULL. |
- * "tag" |
- * The UInt32 value of the tag for the extension whose criticality is |
- * to be determined |
- * "pCritical" |
- * Address where the Boolean value will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_IsExtensionCritical( |
- PKIX_PL_Cert *cert, |
- PKIX_UInt32 tag, |
- PKIX_Boolean *pCritical, |
- void *plContext) |
-{ |
- PKIX_Boolean criticality = PKIX_FALSE; |
- CERTCertExtension **extensions = NULL; |
- SECStatus rv; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_IsExtensionCritical"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCritical); |
- |
- extensions = cert->nssCert->extensions; |
- PKIX_NULLCHECK_ONE(extensions); |
- |
- PKIX_CERT_DEBUG("\t\tCalling CERT_GetExtenCriticality).\n"); |
- rv = CERT_GetExtenCriticality(extensions, tag, &criticality); |
- if (SECSuccess == rv) { |
- *pCritical = criticality; |
- } else { |
- *pCritical = PKIX_FALSE; |
- } |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_DecodePolicyInfo |
- * DESCRIPTION: |
- * |
- * Decodes the contents of the CertificatePolicy extension in the |
- * CERTCertificate pointed to by "nssCert", to create a List of |
- * CertPolicyInfos, which is stored at the address "pCertPolicyInfos". |
- * A CERTCertificate contains the DER representation of the Cert. |
- * If this certificate does not have a CertificatePolicy extension, |
- * NULL will be stored. If a List is returned, it will be immutable. |
- * |
- * PARAMETERS |
- * "nssCert" |
- * Address of the Cert data whose extension is to be examined. Must be |
- * non-NULL. |
- * "pCertPolicyInfos" |
- * Address where the List of CertPolicyInfos will be stored. Must be |
- * non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_DecodePolicyInfo( |
- CERTCertificate *nssCert, |
- PKIX_List **pCertPolicyInfos, |
- void *plContext) |
-{ |
- |
- SECStatus rv; |
- SECItem encodedCertPolicyInfo; |
- |
- /* Allocated in the arena; freed in CERT_Destroy... */ |
- CERTCertificatePolicies *certPol = NULL; |
- CERTPolicyInfo **policyInfos = NULL; |
- |
- /* Holder for the return value */ |
- PKIX_List *infos = NULL; |
- |
- PKIX_PL_OID *pkixOID = NULL; |
- PKIX_List *qualifiers = NULL; |
- PKIX_PL_CertPolicyInfo *certPolicyInfo = NULL; |
- PKIX_PL_CertPolicyQualifier *certPolicyQualifier = NULL; |
- PKIX_PL_ByteArray *qualifierArray = NULL; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyInfo"); |
- PKIX_NULLCHECK_TWO(nssCert, pCertPolicyInfos); |
- |
- /* get PolicyInfo as a SECItem */ |
- PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n"); |
- rv = CERT_FindCertExtension |
- (nssCert, |
- SEC_OID_X509_CERTIFICATE_POLICIES, |
- &encodedCertPolicyInfo); |
- if (SECSuccess != rv) { |
- *pCertPolicyInfos = NULL; |
- goto cleanup; |
- } |
- |
- /* translate PolicyInfo to CERTCertificatePolicies */ |
- PKIX_CERT_DEBUG("\t\tCERT_DecodeCertificatePoliciesExtension).\n"); |
- certPol = CERT_DecodeCertificatePoliciesExtension |
- (&encodedCertPolicyInfo); |
- |
- PORT_Free(encodedCertPolicyInfo.data); |
- |
- if (NULL == certPol) { |
- PKIX_ERROR(PKIX_CERTDECODECERTIFICATEPOLICIESEXTENSIONFAILED); |
- } |
- |
- /* |
- * Check whether there are any policyInfos, so we can |
- * avoid creating an unnecessary List |
- */ |
- policyInfos = certPol->policyInfos; |
- if (!policyInfos) { |
- *pCertPolicyInfos = NULL; |
- goto cleanup; |
- } |
- |
- /* create a List of CertPolicyInfo Objects */ |
- PKIX_CHECK(PKIX_List_Create(&infos, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- /* |
- * Traverse the CERTCertificatePolicies structure, |
- * building each PKIX_PL_CertPolicyInfo object in turn |
- */ |
- while (*policyInfos != NULL) { |
- CERTPolicyInfo *policyInfo = *policyInfos; |
- CERTPolicyQualifier **policyQualifiers = |
- policyInfo->policyQualifiers; |
- if (policyQualifiers) { |
- /* create a PKIX_List of PKIX_PL_CertPolicyQualifiers */ |
- PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- while (*policyQualifiers != NULL) { |
- CERTPolicyQualifier *policyQualifier = |
- *policyQualifiers; |
- |
- /* create the qualifier's OID object */ |
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem |
- (&policyQualifier->qualifierID, |
- &pkixOID, plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- /* create qualifier's ByteArray object */ |
- |
- PKIX_CHECK(PKIX_PL_ByteArray_Create |
- (policyQualifier->qualifierValue.data, |
- policyQualifier->qualifierValue.len, |
- &qualifierArray, |
- plContext), |
- PKIX_BYTEARRAYCREATEFAILED); |
- |
- /* create a CertPolicyQualifier object */ |
- |
- PKIX_CHECK(pkix_pl_CertPolicyQualifier_Create |
- (pkixOID, |
- qualifierArray, |
- &certPolicyQualifier, |
- plContext), |
- PKIX_CERTPOLICYQUALIFIERCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (qualifiers, |
- (PKIX_PL_Object *)certPolicyQualifier, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(pkixOID); |
- PKIX_DECREF(qualifierArray); |
- PKIX_DECREF(certPolicyQualifier); |
- |
- policyQualifiers++; |
- } |
- |
- PKIX_CHECK(PKIX_List_SetImmutable |
- (qualifiers, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- } |
- |
- |
- /* |
- * Create an OID object pkixOID from policyInfo->policyID. |
- * (The CERTPolicyInfo structure has an oid field, but it |
- * is of type SECOidTag. This function wants a SECItem.) |
- */ |
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem |
- (&policyInfo->policyID, &pkixOID, plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- /* Create a CertPolicyInfo object */ |
- PKIX_CHECK(pkix_pl_CertPolicyInfo_Create |
- (pkixOID, qualifiers, &certPolicyInfo, plContext), |
- PKIX_CERTPOLICYINFOCREATEFAILED); |
- |
- /* Append the new CertPolicyInfo object to the list */ |
- PKIX_CHECK(PKIX_List_AppendItem |
- (infos, (PKIX_PL_Object *)certPolicyInfo, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(pkixOID); |
- PKIX_DECREF(qualifiers); |
- PKIX_DECREF(certPolicyInfo); |
- |
- policyInfos++; |
- } |
- |
- /* |
- * If there were no policies, we went straight to |
- * cleanup, so we don't have to NULLCHECK infos. |
- */ |
- PKIX_CHECK(PKIX_List_SetImmutable(infos, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- |
- *pCertPolicyInfos = infos; |
- infos = NULL; |
- |
-cleanup: |
- if (certPol) { |
- PKIX_CERT_DEBUG |
- ("\t\tCalling CERT_DestroyCertificatePoliciesExtension).\n"); |
- CERT_DestroyCertificatePoliciesExtension(certPol); |
- } |
- |
- PKIX_DECREF(infos); |
- PKIX_DECREF(pkixOID); |
- PKIX_DECREF(qualifiers); |
- PKIX_DECREF(certPolicyInfo); |
- PKIX_DECREF(certPolicyQualifier); |
- PKIX_DECREF(qualifierArray); |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_DecodePolicyMapping |
- * DESCRIPTION: |
- * |
- * Decodes the contents of the PolicyMapping extension of the CERTCertificate |
- * pointed to by "nssCert", storing the resulting List of CertPolicyMaps at |
- * the address pointed to by "pCertPolicyMaps". If this certificate does not |
- * have a PolicyMapping extension, NULL will be stored. If a List is returned, |
- * it will be immutable. |
- * |
- * PARAMETERS |
- * "nssCert" |
- * Address of the Cert data whose extension is to be examined. Must be |
- * non-NULL. |
- * "pCertPolicyMaps" |
- * Address where the List of CertPolicyMaps will be stored. Must be |
- * non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_DecodePolicyMapping( |
- CERTCertificate *nssCert, |
- PKIX_List **pCertPolicyMaps, |
- void *plContext) |
-{ |
- SECStatus rv; |
- SECItem encodedCertPolicyMaps; |
- |
- /* Allocated in the arena; freed in CERT_Destroy... */ |
- CERTCertificatePolicyMappings *certPolMaps = NULL; |
- CERTPolicyMap **policyMaps = NULL; |
- |
- /* Holder for the return value */ |
- PKIX_List *maps = NULL; |
- |
- PKIX_PL_OID *issuerDomainOID = NULL; |
- PKIX_PL_OID *subjectDomainOID = NULL; |
- PKIX_PL_CertPolicyMap *certPolicyMap = NULL; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyMapping"); |
- PKIX_NULLCHECK_TWO(nssCert, pCertPolicyMaps); |
- |
- /* get PolicyMappings as a SECItem */ |
- PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n"); |
- rv = CERT_FindCertExtension |
- (nssCert, SEC_OID_X509_POLICY_MAPPINGS, &encodedCertPolicyMaps); |
- if (SECSuccess != rv) { |
- *pCertPolicyMaps = NULL; |
- goto cleanup; |
- } |
- |
- /* translate PolicyMaps to CERTCertificatePolicyMappings */ |
- certPolMaps = CERT_DecodePolicyMappingsExtension |
- (&encodedCertPolicyMaps); |
- |
- PORT_Free(encodedCertPolicyMaps.data); |
- |
- if (!certPolMaps) { |
- PKIX_ERROR(PKIX_CERTDECODEPOLICYMAPPINGSEXTENSIONFAILED); |
- } |
- |
- PKIX_NULLCHECK_ONE(certPolMaps->policyMaps); |
- |
- policyMaps = certPolMaps->policyMaps; |
- |
- /* create a List of CertPolicyMap Objects */ |
- PKIX_CHECK(PKIX_List_Create(&maps, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- /* |
- * Traverse the CERTCertificatePolicyMappings structure, |
- * building each CertPolicyMap object in turn |
- */ |
- do { |
- CERTPolicyMap *policyMap = *policyMaps; |
- |
- /* create the OID for the issuer Domain Policy */ |
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem |
- (&policyMap->issuerDomainPolicy, |
- &issuerDomainOID, plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- /* create the OID for the subject Domain Policy */ |
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem |
- (&policyMap->subjectDomainPolicy, |
- &subjectDomainOID, plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- /* create the CertPolicyMap */ |
- |
- PKIX_CHECK(pkix_pl_CertPolicyMap_Create |
- (issuerDomainOID, |
- subjectDomainOID, |
- &certPolicyMap, |
- plContext), |
- PKIX_CERTPOLICYMAPCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (maps, (PKIX_PL_Object *)certPolicyMap, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(issuerDomainOID); |
- PKIX_DECREF(subjectDomainOID); |
- PKIX_DECREF(certPolicyMap); |
- |
- policyMaps++; |
- } while (*policyMaps != NULL); |
- |
- PKIX_CHECK(PKIX_List_SetImmutable(maps, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- |
- *pCertPolicyMaps = maps; |
- maps = NULL; |
- |
-cleanup: |
- if (certPolMaps) { |
- PKIX_CERT_DEBUG |
- ("\t\tCalling CERT_DestroyPolicyMappingsExtension).\n"); |
- CERT_DestroyPolicyMappingsExtension(certPolMaps); |
- } |
- |
- PKIX_DECREF(maps); |
- PKIX_DECREF(issuerDomainOID); |
- PKIX_DECREF(subjectDomainOID); |
- PKIX_DECREF(certPolicyMap); |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_DecodePolicyConstraints |
- * DESCRIPTION: |
- * |
- * Decodes the contents of the PolicyConstraints extension in the |
- * CERTCertificate pointed to by "nssCert", to obtain SkipCerts values |
- * which are stored at the addresses "pExplicitPolicySkipCerts" and |
- * "pInhibitMappingSkipCerts", respectively. If this certificate does |
- * not have an PolicyConstraints extension, or if either of the optional |
- * components is not supplied, this function stores a value of -1 for any |
- * missing component. |
- * |
- * PARAMETERS |
- * "nssCert" |
- * Address of the Cert data whose extension is to be examined. Must be |
- * non-NULL. |
- * "pExplicitPolicySkipCerts" |
- * Address where the SkipCert value for the requireExplicitPolicy |
- * component will be stored. Must be non-NULL. |
- * "pInhibitMappingSkipCerts" |
- * Address where the SkipCert value for the inhibitPolicyMapping |
- * component will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_DecodePolicyConstraints( |
- CERTCertificate *nssCert, |
- PKIX_Int32 *pExplicitPolicySkipCerts, |
- PKIX_Int32 *pInhibitMappingSkipCerts, |
- void *plContext) |
-{ |
- CERTCertificatePolicyConstraints policyConstraints; |
- SECStatus rv; |
- SECItem encodedCertPolicyConstraints; |
- PKIX_Int32 explicitPolicySkipCerts = -1; |
- PKIX_Int32 inhibitMappingSkipCerts = -1; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyConstraints"); |
- PKIX_NULLCHECK_THREE |
- (nssCert, pExplicitPolicySkipCerts, pInhibitMappingSkipCerts); |
- |
- /* get the two skipCert values as SECItems */ |
- PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n"); |
- rv = CERT_FindCertExtension |
- (nssCert, |
- SEC_OID_X509_POLICY_CONSTRAINTS, |
- &encodedCertPolicyConstraints); |
- |
- if (rv == SECSuccess) { |
- |
- policyConstraints.explicitPolicySkipCerts.data = |
- (unsigned char *)&explicitPolicySkipCerts; |
- policyConstraints.inhibitMappingSkipCerts.data = |
- (unsigned char *)&inhibitMappingSkipCerts; |
- |
- /* translate DER to CERTCertificatePolicyConstraints */ |
- rv = CERT_DecodePolicyConstraintsExtension |
- (&policyConstraints, &encodedCertPolicyConstraints); |
- |
- PORT_Free(encodedCertPolicyConstraints.data); |
- |
- if (rv != SECSuccess) { |
- PKIX_ERROR |
- (PKIX_CERTDECODEPOLICYCONSTRAINTSEXTENSIONFAILED); |
- } |
- } |
- |
- *pExplicitPolicySkipCerts = explicitPolicySkipCerts; |
- *pInhibitMappingSkipCerts = inhibitMappingSkipCerts; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_DecodeInhibitAnyPolicy |
- * DESCRIPTION: |
- * |
- * Decodes the contents of the InhibitAnyPolicy extension in the |
- * CERTCertificate pointed to by "nssCert", to obtain a SkipCerts value, |
- * which is stored at the address "pSkipCerts". If this certificate does |
- * not have an InhibitAnyPolicy extension, -1 will be stored. |
- * |
- * PARAMETERS |
- * "nssCert" |
- * Address of the Cert data whose InhibitAnyPolicy extension is to be |
- * processed. Must be non-NULL. |
- * "pSkipCerts" |
- * Address where the SkipCert value from the InhibitAnyPolicy extension |
- * will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_pl_Cert_DecodeInhibitAnyPolicy( |
- CERTCertificate *nssCert, |
- PKIX_Int32 *pSkipCerts, |
- void *plContext) |
-{ |
- CERTCertificateInhibitAny inhibitAny; |
- SECStatus rv; |
- SECItem encodedCertInhibitAny; |
- PKIX_Int32 skipCerts = -1; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodeInhibitAnyPolicy"); |
- PKIX_NULLCHECK_TWO(nssCert, pSkipCerts); |
- |
- /* get InhibitAny as a SECItem */ |
- PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n"); |
- rv = CERT_FindCertExtension |
- (nssCert, SEC_OID_X509_INHIBIT_ANY_POLICY, &encodedCertInhibitAny); |
- |
- if (rv == SECSuccess) { |
- inhibitAny.inhibitAnySkipCerts.data = |
- (unsigned char *)&skipCerts; |
- |
- /* translate DER to CERTCertificateInhibitAny */ |
- rv = CERT_DecodeInhibitAnyExtension |
- (&inhibitAny, &encodedCertInhibitAny); |
- |
- PORT_Free(encodedCertInhibitAny.data); |
- |
- if (rv != SECSuccess) { |
- PKIX_ERROR(PKIX_CERTDECODEINHIBITANYEXTENSIONFAILED); |
- } |
- } |
- |
- *pSkipCerts = skipCerts; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_GetNssSubjectAltNames |
- * DESCRIPTION: |
- * |
- * Retrieves the Subject Alternative Names of the certificate specified by |
- * "cert" and stores it at "pNssSubjAltNames". If the Subject Alternative |
- * Name extension is not present, NULL is returned at "pNssSubjAltNames". |
- * If the Subject Alternative Names has not been previously decoded, it is |
- * decoded here with lock on the "cert" unless the flag "hasLock" indicates |
- * the lock had been obtained at a higher call level. |
- * |
- * PARAMETERS |
- * "cert" |
- * Address of the certificate whose Subject Alternative Names extensions |
- * is retrieved. Must be non-NULL. |
- * "hasLock" |
- * Boolean indicates caller has acquired a lock. |
- * Must be non-NULL. |
- * "pNssSubjAltNames" |
- * Address where the returned Subject Alternative Names will be stored. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_GetNssSubjectAltNames( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean hasLock, |
- CERTGeneralName **pNssSubjAltNames, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- CERTGeneralName *nssOriginalAltName = NULL; |
- PLArenaPool *arena = NULL; |
- SECItem altNameExtension = {siBuffer, NULL, 0}; |
- SECStatus rv = SECFailure; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_GetNssSubjectAltNames"); |
- PKIX_NULLCHECK_THREE(cert, pNssSubjAltNames, cert->nssCert); |
- |
- nssCert = cert->nssCert; |
- |
- if ((cert->nssSubjAltNames == NULL) && (!cert->subjAltNamesAbsent)){ |
- |
- if (!hasLock) { |
- PKIX_OBJECT_LOCK(cert); |
- } |
- |
- if ((cert->nssSubjAltNames == NULL) && |
- (!cert->subjAltNamesAbsent)){ |
- |
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension, |
- (nssCert, |
- SEC_OID_X509_SUBJECT_ALT_NAME, |
- &altNameExtension)); |
- |
- if (rv != SECSuccess) { |
- *pNssSubjAltNames = NULL; |
- cert->subjAltNamesAbsent = PKIX_TRUE; |
- goto cleanup; |
- } |
- |
- if (cert->arenaNameConstraints == NULL) { |
- PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena, |
- (DER_DEFAULT_CHUNKSIZE)); |
- |
- if (arena == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- cert->arenaNameConstraints = arena; |
- } |
- |
- PKIX_PL_NSSCALLRV |
- (CERT, |
- nssOriginalAltName, |
- (CERTGeneralName *) CERT_DecodeAltNameExtension, |
- (cert->arenaNameConstraints, &altNameExtension)); |
- |
- PKIX_PL_NSSCALL(CERT, PORT_Free, (altNameExtension.data)); |
- |
- if (nssOriginalAltName == NULL) { |
- PKIX_ERROR(PKIX_CERTDECODEALTNAMEEXTENSIONFAILED); |
- } |
- cert->nssSubjAltNames = nssOriginalAltName; |
- |
- } |
- |
- if (!hasLock) { |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- } |
- |
- *pNssSubjAltNames = cert->nssSubjAltNames; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_CheckExtendKeyUsage |
- * DESCRIPTION: |
- * |
- * For each of the ON bit in "requiredExtendedKeyUsages" that represents its |
- * SECCertUsageEnum type, this function checks "cert"'s certType (extended |
- * key usage) and key usage with what is required for SECCertUsageEnum type. |
- * |
- * PARAMETERS |
- * "cert" |
- * Address of the certificate whose Extended Key Usage extensions |
- * is retrieved. Must be non-NULL. |
- * "requiredExtendedKeyUsages" |
- * An unsigned integer, its bit location is ON based on the required key |
- * usage value representing in SECCertUsageEnum. |
- * "pPass" |
- * Address where the return value, indicating key usage check passed, is |
- * stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_pl_Cert_CheckExtendedKeyUsage( |
- PKIX_PL_Cert *cert, |
- PKIX_UInt32 requiredExtendedKeyUsages, |
- PKIX_Boolean *pPass, |
- void *plContext) |
-{ |
- PKIX_PL_CertBasicConstraints *basicConstraints = NULL; |
- PKIX_UInt32 certType = 0; |
- PKIX_UInt32 requiredKeyUsage = 0; |
- PKIX_UInt32 requiredCertType = 0; |
- PKIX_UInt32 requiredExtendedKeyUsage = 0; |
- PKIX_UInt32 i; |
- PKIX_Boolean isCA = PKIX_FALSE; |
- SECStatus rv = SECFailure; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_CheckExtendKeyUsage"); |
- PKIX_NULLCHECK_THREE(cert, pPass, cert->nssCert); |
- |
- *pPass = PKIX_FALSE; |
- |
- PKIX_CERT_DEBUG("\t\tCalling cert_GetCertType).\n"); |
- cert_GetCertType(cert->nssCert); |
- certType = cert->nssCert->nsCertType; |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints |
- (cert, |
- &basicConstraints, |
- plContext), |
- PKIX_CERTGETBASICCONSTRAINTFAILED); |
- |
- if (basicConstraints != NULL) { |
- PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag |
- (basicConstraints, &isCA, plContext), |
- PKIX_BASICCONSTRAINTSGETCAFLAGFAILED); |
- } |
- |
- i = 0; |
- while (requiredExtendedKeyUsages != 0) { |
- |
- /* Find the bit location of the right-most non-zero bit */ |
- while (requiredExtendedKeyUsages != 0) { |
- if (((1 << i) & requiredExtendedKeyUsages) != 0) { |
- requiredExtendedKeyUsage = 1 << i; |
- break; |
- } |
- i++; |
- } |
- requiredExtendedKeyUsages ^= requiredExtendedKeyUsage; |
- |
- requiredExtendedKeyUsage = i; |
- |
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_KeyUsageAndTypeForCertUsage, |
- (requiredExtendedKeyUsage, |
- isCA, |
- &requiredKeyUsage, |
- &requiredCertType)); |
- |
- if (!(certType & requiredCertType)) { |
- goto cleanup; |
- } |
- |
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_CheckKeyUsage, |
- (cert->nssCert, requiredKeyUsage)); |
- if (rv != SECSuccess) { |
- goto cleanup; |
- } |
- i++; |
- |
- } |
- |
- *pPass = PKIX_TRUE; |
- |
-cleanup: |
- PKIX_DECREF(basicConstraints); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_ToString_Helper |
- * DESCRIPTION: |
- * |
- * Helper function that creates a string representation of the Cert pointed |
- * to by "cert" and stores it at "pString", where the value of |
- * "partialString" determines whether a full or partial representation of |
- * the Cert is stored. |
- * |
- * PARAMETERS |
- * "cert" |
- * Address of Cert whose string representation is desired. |
- * Must be non-NULL. |
- * "partialString" |
- * Boolean indicating whether a partial Cert representation is desired. |
- * "pString" |
- * Address where object pointer will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_pl_Cert_ToString_Helper( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean partialString, |
- PKIX_PL_String **pString, |
- void *plContext) |
-{ |
- PKIX_PL_String *certString = NULL; |
- char *asciiFormat = NULL; |
- PKIX_PL_String *formatString = NULL; |
- PKIX_UInt32 certVersion; |
- PKIX_PL_BigInt *certSN = NULL; |
- PKIX_PL_String *certSNString = NULL; |
- PKIX_PL_X500Name *certIssuer = NULL; |
- PKIX_PL_String *certIssuerString = NULL; |
- PKIX_PL_X500Name *certSubject = NULL; |
- PKIX_PL_String *certSubjectString = NULL; |
- PKIX_PL_String *notBeforeString = NULL; |
- PKIX_PL_String *notAfterString = NULL; |
- PKIX_List *subjAltNames = NULL; |
- PKIX_PL_String *subjAltNamesString = NULL; |
- PKIX_PL_ByteArray *authKeyId = NULL; |
- PKIX_PL_String *authKeyIdString = NULL; |
- PKIX_PL_ByteArray *subjKeyId = NULL; |
- PKIX_PL_String *subjKeyIdString = NULL; |
- PKIX_PL_PublicKey *nssPubKey = NULL; |
- PKIX_PL_String *nssPubKeyString = NULL; |
- PKIX_List *critExtOIDs = NULL; |
- PKIX_PL_String *critExtOIDsString = NULL; |
- PKIX_List *extKeyUsages = NULL; |
- PKIX_PL_String *extKeyUsagesString = NULL; |
- PKIX_PL_CertBasicConstraints *basicConstraint = NULL; |
- PKIX_PL_String *certBasicConstraintsString = NULL; |
- PKIX_List *policyInfo = NULL; |
- PKIX_PL_String *certPolicyInfoString = NULL; |
- PKIX_List *certPolicyMappings = NULL; |
- PKIX_PL_String *certPolicyMappingsString = NULL; |
- PKIX_Int32 certExplicitPolicy = 0; |
- PKIX_Int32 certInhibitMapping = 0; |
- PKIX_Int32 certInhibitAnyPolicy = 0; |
- PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
- PKIX_PL_String *nameConstraintsString = NULL; |
- PKIX_List *authorityInfoAccess = NULL; |
- PKIX_PL_String *authorityInfoAccessString = NULL; |
- PKIX_List *subjectInfoAccess = NULL; |
- PKIX_PL_String *subjectInfoAccessString = NULL; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_ToString_Helper"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pString); |
- |
- /* |
- * XXX Add to this format as certificate components are developed. |
- */ |
- |
- if (partialString){ |
- asciiFormat = |
- "\t[Issuer: %s\n" |
- "\t Subject: %s]"; |
- } else { |
- asciiFormat = |
- "[\n" |
- "\tVersion: v%d\n" |
- "\tSerialNumber: %s\n" |
- "\tIssuer: %s\n" |
- "\tSubject: %s\n" |
- "\tValidity: [From: %s\n" |
- "\t To: %s]\n" |
- "\tSubjectAltNames: %s\n" |
- "\tAuthorityKeyId: %s\n" |
- "\tSubjectKeyId: %s\n" |
- "\tSubjPubKeyAlgId: %s\n" |
- "\tCritExtOIDs: %s\n" |
- "\tExtKeyUsages: %s\n" |
- "\tBasicConstraint: %s\n" |
- "\tCertPolicyInfo: %s\n" |
- "\tPolicyMappings: %s\n" |
- "\tExplicitPolicy: %d\n" |
- "\tInhibitMapping: %d\n" |
- "\tInhibitAnyPolicy:%d\n" |
- "\tNameConstraints: %s\n" |
- "\tAuthorityInfoAccess: %s\n" |
- "\tSubjectInfoAccess: %s\n" |
- "\tCacheFlag: %d\n" |
- "]\n"; |
- } |
- |
- |
- |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext), |
- PKIX_STRINGCREATEFAILED); |
- |
- /* Issuer */ |
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer |
- (cert, &certIssuer, plContext), |
- PKIX_CERTGETISSUERFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Object_ToString |
- ((PKIX_PL_Object *)certIssuer, &certIssuerString, plContext), |
- PKIX_X500NAMETOSTRINGFAILED); |
- |
- /* Subject */ |
- PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &certSubject, plContext), |
- PKIX_CERTGETSUBJECTFAILED); |
- |
- PKIX_TOSTRING(certSubject, &certSubjectString, plContext, |
- PKIX_X500NAMETOSTRINGFAILED); |
- |
- if (partialString){ |
- PKIX_CHECK(PKIX_PL_Sprintf |
- (&certString, |
- plContext, |
- formatString, |
- certIssuerString, |
- certSubjectString), |
- PKIX_SPRINTFFAILED); |
- |
- *pString = certString; |
- goto cleanup; |
- } |
- |
- /* Version */ |
- PKIX_CHECK(PKIX_PL_Cert_GetVersion(cert, &certVersion, plContext), |
- PKIX_CERTGETVERSIONFAILED); |
- |
- /* SerialNumber */ |
- PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber(cert, &certSN, plContext), |
- PKIX_CERTGETSERIALNUMBERFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Object_ToString |
- ((PKIX_PL_Object *)certSN, &certSNString, plContext), |
- PKIX_BIGINTTOSTRINGFAILED); |
- |
- /* Validity: NotBefore */ |
- PKIX_CHECK(pkix_pl_Date_ToString_Helper |
- (&(cert->nssCert->validity.notBefore), |
- ¬BeforeString, |
- plContext), |
- PKIX_DATETOSTRINGHELPERFAILED); |
- |
- /* Validity: NotAfter */ |
- PKIX_CHECK(pkix_pl_Date_ToString_Helper |
- (&(cert->nssCert->validity.notAfter), |
- ¬AfterString, |
- plContext), |
- PKIX_DATETOSTRINGHELPERFAILED); |
- |
- /* SubjectAltNames */ |
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames |
- (cert, &subjAltNames, plContext), |
- PKIX_CERTGETSUBJECTALTNAMESFAILED); |
- |
- PKIX_TOSTRING(subjAltNames, &subjAltNamesString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- /* AuthorityKeyIdentifier */ |
- PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier |
- (cert, &authKeyId, plContext), |
- PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED); |
- |
- PKIX_TOSTRING(authKeyId, &authKeyIdString, plContext, |
- PKIX_BYTEARRAYTOSTRINGFAILED); |
- |
- /* SubjectKeyIdentifier */ |
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier |
- (cert, &subjKeyId, plContext), |
- PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED); |
- |
- PKIX_TOSTRING(subjKeyId, &subjKeyIdString, plContext, |
- PKIX_BYTEARRAYTOSTRINGFAILED); |
- |
- /* SubjectPublicKey */ |
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey |
- (cert, &nssPubKey, plContext), |
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Object_ToString |
- ((PKIX_PL_Object *)nssPubKey, &nssPubKeyString, plContext), |
- PKIX_PUBLICKEYTOSTRINGFAILED); |
- |
- /* CriticalExtensionOIDs */ |
- PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs |
- (cert, &critExtOIDs, plContext), |
- PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED); |
- |
- PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- /* ExtendedKeyUsages */ |
- PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage |
- (cert, &extKeyUsages, plContext), |
- PKIX_CERTGETEXTENDEDKEYUSAGEFAILED); |
- |
- PKIX_TOSTRING(extKeyUsages, &extKeyUsagesString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- /* CertBasicConstraints */ |
- PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints |
- (cert, &basicConstraint, plContext), |
- PKIX_CERTGETBASICCONSTRAINTSFAILED); |
- |
- PKIX_TOSTRING(basicConstraint, &certBasicConstraintsString, plContext, |
- PKIX_CERTBASICCONSTRAINTSTOSTRINGFAILED); |
- |
- /* CertPolicyInfo */ |
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation |
- (cert, &policyInfo, plContext), |
- PKIX_CERTGETPOLICYINFORMATIONFAILED); |
- |
- PKIX_TOSTRING(policyInfo, &certPolicyInfoString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- /* Advanced Policies */ |
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings |
- (cert, &certPolicyMappings, plContext), |
- PKIX_CERTGETPOLICYMAPPINGSFAILED); |
- |
- PKIX_TOSTRING(certPolicyMappings, &certPolicyMappingsString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy |
- (cert, &certExplicitPolicy, plContext), |
- PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited |
- (cert, &certInhibitMapping, plContext), |
- PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy |
- (cert, &certInhibitAnyPolicy, plContext), |
- PKIX_CERTGETINHIBITANYPOLICYFAILED); |
- |
- /* Name Constraints */ |
- PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints |
- (cert, &nameConstraints, plContext), |
- PKIX_CERTGETNAMECONSTRAINTSFAILED); |
- |
- PKIX_TOSTRING(nameConstraints, &nameConstraintsString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- /* Authority Information Access */ |
- PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess |
- (cert, &authorityInfoAccess, plContext), |
- PKIX_CERTGETAUTHORITYINFOACCESSFAILED); |
- |
- PKIX_TOSTRING(authorityInfoAccess, &authorityInfoAccessString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- /* Subject Information Access */ |
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectInfoAccess |
- (cert, &subjectInfoAccess, plContext), |
- PKIX_CERTGETSUBJECTINFOACCESSFAILED); |
- |
- PKIX_TOSTRING(subjectInfoAccess, &subjectInfoAccessString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Sprintf |
- (&certString, |
- plContext, |
- formatString, |
- certVersion + 1, |
- certSNString, |
- certIssuerString, |
- certSubjectString, |
- notBeforeString, |
- notAfterString, |
- subjAltNamesString, |
- authKeyIdString, |
- subjKeyIdString, |
- nssPubKeyString, |
- critExtOIDsString, |
- extKeyUsagesString, |
- certBasicConstraintsString, |
- certPolicyInfoString, |
- certPolicyMappingsString, |
- certExplicitPolicy, /* an Int32, not a String */ |
- certInhibitMapping, /* an Int32, not a String */ |
- certInhibitAnyPolicy, /* an Int32, not a String */ |
- nameConstraintsString, |
- authorityInfoAccessString, |
- subjectInfoAccessString, |
- cert->cacheFlag), /* a boolean */ |
- PKIX_SPRINTFFAILED); |
- |
- *pString = certString; |
- |
-cleanup: |
- PKIX_DECREF(certSN); |
- PKIX_DECREF(certSNString); |
- PKIX_DECREF(certIssuer); |
- PKIX_DECREF(certIssuerString); |
- PKIX_DECREF(certSubject); |
- PKIX_DECREF(certSubjectString); |
- PKIX_DECREF(notBeforeString); |
- PKIX_DECREF(notAfterString); |
- PKIX_DECREF(subjAltNames); |
- PKIX_DECREF(subjAltNamesString); |
- PKIX_DECREF(authKeyId); |
- PKIX_DECREF(authKeyIdString); |
- PKIX_DECREF(subjKeyId); |
- PKIX_DECREF(subjKeyIdString); |
- PKIX_DECREF(nssPubKey); |
- PKIX_DECREF(nssPubKeyString); |
- PKIX_DECREF(critExtOIDs); |
- PKIX_DECREF(critExtOIDsString); |
- PKIX_DECREF(extKeyUsages); |
- PKIX_DECREF(extKeyUsagesString); |
- PKIX_DECREF(basicConstraint); |
- PKIX_DECREF(certBasicConstraintsString); |
- PKIX_DECREF(policyInfo); |
- PKIX_DECREF(certPolicyInfoString); |
- PKIX_DECREF(certPolicyMappings); |
- PKIX_DECREF(certPolicyMappingsString); |
- PKIX_DECREF(nameConstraints); |
- PKIX_DECREF(nameConstraintsString); |
- PKIX_DECREF(authorityInfoAccess); |
- PKIX_DECREF(authorityInfoAccessString); |
- PKIX_DECREF(subjectInfoAccess); |
- PKIX_DECREF(subjectInfoAccessString); |
- PKIX_DECREF(formatString); |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_Destroy |
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_Destroy( |
- PKIX_PL_Object *object, |
- void *plContext) |
-{ |
- PKIX_PL_Cert *cert = NULL; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_Destroy"); |
- PKIX_NULLCHECK_ONE(object); |
- |
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext), |
- PKIX_OBJECTNOTCERT); |
- |
- cert = (PKIX_PL_Cert*)object; |
- |
- PKIX_DECREF(cert->subject); |
- PKIX_DECREF(cert->issuer); |
- PKIX_DECREF(cert->subjAltNames); |
- PKIX_DECREF(cert->publicKeyAlgId); |
- PKIX_DECREF(cert->publicKey); |
- PKIX_DECREF(cert->serialNumber); |
- PKIX_DECREF(cert->critExtOids); |
- PKIX_DECREF(cert->authKeyId); |
- PKIX_DECREF(cert->subjKeyId); |
- PKIX_DECREF(cert->extKeyUsages); |
- PKIX_DECREF(cert->certBasicConstraints); |
- PKIX_DECREF(cert->certPolicyInfos); |
- PKIX_DECREF(cert->certPolicyMappings); |
- PKIX_DECREF(cert->nameConstraints); |
- PKIX_DECREF(cert->store); |
- PKIX_DECREF(cert->authorityInfoAccess); |
- PKIX_DECREF(cert->subjectInfoAccess); |
- PKIX_DECREF(cert->crldpList); |
- |
- if (cert->arenaNameConstraints){ |
- /* This arena was allocated for SubjectAltNames */ |
- PKIX_PL_NSSCALL(CERT, PORT_FreeArena, |
- (cert->arenaNameConstraints, PR_FALSE)); |
- |
- cert->arenaNameConstraints = NULL; |
- cert->nssSubjAltNames = NULL; |
- } |
- |
- CERT_DestroyCertificate(cert->nssCert); |
- cert->nssCert = NULL; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_ToString |
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_ToString( |
- PKIX_PL_Object *object, |
- PKIX_PL_String **pString, |
- void *plContext) |
-{ |
- PKIX_PL_String *certString = NULL; |
- PKIX_PL_Cert *pkixCert = NULL; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_toString"); |
- PKIX_NULLCHECK_TWO(object, pString); |
- |
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext), |
- PKIX_OBJECTNOTCERT); |
- |
- pkixCert = (PKIX_PL_Cert *)object; |
- |
- PKIX_CHECK(pkix_pl_Cert_ToString_Helper |
- (pkixCert, PKIX_FALSE, &certString, plContext), |
- PKIX_CERTTOSTRINGHELPERFAILED); |
- |
- *pString = certString; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_Hashcode |
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_Hashcode( |
- PKIX_PL_Object *object, |
- PKIX_UInt32 *pHashcode, |
- void *plContext) |
-{ |
- PKIX_PL_Cert *pkixCert = NULL; |
- CERTCertificate *nssCert = NULL; |
- unsigned char *derBytes = NULL; |
- PKIX_UInt32 derLength; |
- PKIX_UInt32 certHash; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_Hashcode"); |
- PKIX_NULLCHECK_TWO(object, pHashcode); |
- |
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext), |
- PKIX_OBJECTNOTCERT); |
- |
- pkixCert = (PKIX_PL_Cert *)object; |
- |
- nssCert = pkixCert->nssCert; |
- derBytes = (nssCert->derCert).data; |
- derLength = (nssCert->derCert).len; |
- |
- PKIX_CHECK(pkix_hash(derBytes, derLength, &certHash, plContext), |
- PKIX_HASHFAILED); |
- |
- *pHashcode = certHash; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_Equals |
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_Cert_Equals( |
- PKIX_PL_Object *firstObject, |
- PKIX_PL_Object *secondObject, |
- PKIX_Boolean *pResult, |
- void *plContext) |
-{ |
- CERTCertificate *firstCert = NULL; |
- CERTCertificate *secondCert = NULL; |
- PKIX_UInt32 secondType; |
- PKIX_Boolean cmpResult; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_Equals"); |
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); |
- |
- /* test that firstObject is a Cert */ |
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CERT_TYPE, plContext), |
- PKIX_FIRSTOBJECTNOTCERT); |
- |
- /* |
- * Since we know firstObject is a Cert, if both references are |
- * identical, they must be equal |
- */ |
- if (firstObject == secondObject){ |
- *pResult = PKIX_TRUE; |
- goto cleanup; |
- } |
- |
- /* |
- * If secondObject isn't a Cert, we don't throw an error. |
- * We simply return a Boolean result of FALSE |
- */ |
- *pResult = PKIX_FALSE; |
- PKIX_CHECK(PKIX_PL_Object_GetType |
- (secondObject, &secondType, plContext), |
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); |
- if (secondType != PKIX_CERT_TYPE) goto cleanup; |
- |
- firstCert = ((PKIX_PL_Cert *)firstObject)->nssCert; |
- secondCert = ((PKIX_PL_Cert *)secondObject)->nssCert; |
- |
- PKIX_NULLCHECK_TWO(firstCert, secondCert); |
- |
- /* CERT_CompareCerts does byte comparison on DER encodings of certs */ |
- PKIX_CERT_DEBUG("\t\tCalling CERT_CompareCerts).\n"); |
- cmpResult = CERT_CompareCerts(firstCert, secondCert); |
- |
- *pResult = cmpResult; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_RegisterSelf |
- * DESCRIPTION: |
- * Registers PKIX_CERT_TYPE and its related functions with systemClasses[] |
- * THREAD SAFETY: |
- * Not Thread Safe - for performance and complexity reasons |
- * |
- * Since this function is only called by PKIX_PL_Initialize, which should |
- * only be called once, it is acceptable that this function is not |
- * thread-safe. |
- */ |
-PKIX_Error * |
-pkix_pl_Cert_RegisterSelf(void *plContext) |
-{ |
- |
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
- pkix_ClassTable_Entry entry; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_RegisterSelf"); |
- |
- entry.description = "Cert"; |
- entry.objCounter = 0; |
- entry.typeObjectSize = sizeof(PKIX_PL_Cert); |
- entry.destructor = pkix_pl_Cert_Destroy; |
- entry.equalsFunction = pkix_pl_Cert_Equals; |
- entry.hashcodeFunction = pkix_pl_Cert_Hashcode; |
- entry.toStringFunction = pkix_pl_Cert_ToString; |
- entry.comparator = NULL; |
- entry.duplicateFunction = pkix_duplicateImmutable; |
- |
- systemClasses[PKIX_CERT_TYPE] = entry; |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_CreateWithNSSCert |
- * DESCRIPTION: |
- * |
- * Creates a new certificate using the CERTCertificate pointed to by "nssCert" |
- * and stores it at "pCert". Once created, a Cert is immutable. |
- * |
- * This function is primarily used as a convenience function for the |
- * performance tests that have easy access to a CERTCertificate. |
- * |
- * PARAMETERS: |
- * "nssCert" |
- * Address of CERTCertificate representing the NSS certificate. |
- * Must be non-NULL. |
- * "pCert" |
- * Address where object pointer will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_pl_Cert_CreateWithNSSCert( |
- CERTCertificate *nssCert, |
- PKIX_PL_Cert **pCert, |
- void *plContext) |
-{ |
- PKIX_PL_Cert *cert = NULL; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_CreateWithNSSCert"); |
- PKIX_NULLCHECK_TWO(pCert, nssCert); |
- |
- /* create a PKIX_PL_Cert object */ |
- PKIX_CHECK(PKIX_PL_Object_Alloc |
- (PKIX_CERT_TYPE, |
- sizeof (PKIX_PL_Cert), |
- (PKIX_PL_Object **)&cert, |
- plContext), |
- PKIX_COULDNOTCREATEOBJECT); |
- |
- /* populate the nssCert field */ |
- cert->nssCert = nssCert; |
- |
- /* initialize remaining fields */ |
- /* |
- * Fields ending with Absent are initialized to PKIX_FALSE so that the |
- * first time we need the value we will look for it. If we find it is |
- * actually absent, the flag will at that time be set to PKIX_TRUE to |
- * prevent searching for it later. |
- * Fields ending with Processed are those where a value is defined |
- * for the Absent case, and a value of zero is possible. When the |
- * flag is still true we have to look for the field, set the default |
- * value if necessary, and set the Processed flag to PKIX_TRUE. |
- */ |
- cert->subject = NULL; |
- cert->issuer = NULL; |
- cert->subjAltNames = NULL; |
- cert->subjAltNamesAbsent = PKIX_FALSE; |
- cert->publicKeyAlgId = NULL; |
- cert->publicKey = NULL; |
- cert->serialNumber = NULL; |
- cert->critExtOids = NULL; |
- cert->subjKeyId = NULL; |
- cert->subjKeyIdAbsent = PKIX_FALSE; |
- cert->authKeyId = NULL; |
- cert->authKeyIdAbsent = PKIX_FALSE; |
- cert->extKeyUsages = NULL; |
- cert->extKeyUsagesAbsent = PKIX_FALSE; |
- cert->certBasicConstraints = NULL; |
- cert->basicConstraintsAbsent = PKIX_FALSE; |
- cert->certPolicyInfos = NULL; |
- cert->policyInfoAbsent = PKIX_FALSE; |
- cert->policyMappingsAbsent = PKIX_FALSE; |
- cert->certPolicyMappings = NULL; |
- cert->policyConstraintsProcessed = PKIX_FALSE; |
- cert->policyConstraintsExplicitPolicySkipCerts = 0; |
- cert->policyConstraintsInhibitMappingSkipCerts = 0; |
- cert->inhibitAnyPolicyProcessed = PKIX_FALSE; |
- cert->inhibitAnySkipCerts = 0; |
- cert->nameConstraints = NULL; |
- cert->nameConstraintsAbsent = PKIX_FALSE; |
- cert->arenaNameConstraints = NULL; |
- cert->nssSubjAltNames = NULL; |
- cert->cacheFlag = PKIX_FALSE; |
- cert->store = NULL; |
- cert->authorityInfoAccess = NULL; |
- cert->subjectInfoAccess = NULL; |
- cert->isUserTrustAnchor = PKIX_FALSE; |
- cert->crldpList = NULL; |
- |
- *pCert = cert; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_Cert_CreateToList |
- * DESCRIPTION: |
- * |
- * Creates a new certificate using the DER-encoding pointed to by "derCertItem" |
- * and appends it to the list pointed to by "certList". If Cert creation fails, |
- * the function returns with certList unchanged, but any decoding Error is |
- * discarded. |
- * |
- * PARAMETERS: |
- * "derCertItem" |
- * Address of SECItem containing the DER representation of a certificate. |
- * Must be non-NULL. |
- * "certList" |
- * Address of List to which the Cert will be appended, if successfully |
- * created. May be empty, but must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Cert Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_pl_Cert_CreateToList( |
- SECItem *derCertItem, |
- PKIX_List *certList, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- PKIX_PL_Cert *cert = NULL; |
- CERTCertDBHandle *handle; |
- |
- PKIX_ENTER(CERT, "pkix_pl_Cert_CreateToList"); |
- PKIX_NULLCHECK_TWO(derCertItem, certList); |
- |
- handle = CERT_GetDefaultCertDB(); |
- nssCert = CERT_NewTempCertificate(handle, derCertItem, |
- /* nickname */ NULL, |
- /* isPerm */ PR_FALSE, |
- /* copyDer */ PR_TRUE); |
- if (!nssCert) { |
- goto cleanup; |
- } |
- |
- PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert |
- (nssCert, &cert, plContext), |
- PKIX_CERTCREATEWITHNSSCERTFAILED); |
- |
- nssCert = NULL; |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (certList, (PKIX_PL_Object *) cert, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
-cleanup: |
- if (nssCert) { |
- CERT_DestroyCertificate(nssCert); |
- } |
- |
- PKIX_DECREF(cert); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* --Public-Functions------------------------------------------------------- */ |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_Create (see comments in pkix_pl_pki.h) |
- * XXX We may want to cache the cert after parsing it, so it can be reused |
- * XXX Are the NSS/NSPR functions thread safe |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_Create( |
- PKIX_PL_ByteArray *byteArray, |
- PKIX_PL_Cert **pCert, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- SECItem *derCertItem = NULL; |
- void *derBytes = NULL; |
- PKIX_UInt32 derLength; |
- PKIX_Boolean copyDER; |
- PKIX_PL_Cert *cert = NULL; |
- CERTCertDBHandle *handle; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_Create"); |
- PKIX_NULLCHECK_TWO(pCert, byteArray); |
- |
- PKIX_CHECK(PKIX_PL_ByteArray_GetPointer |
- (byteArray, &derBytes, plContext), |
- PKIX_BYTEARRAYGETPOINTERFAILED); |
- |
- PKIX_CHECK(PKIX_PL_ByteArray_GetLength |
- (byteArray, &derLength, plContext), |
- PKIX_BYTEARRAYGETLENGTHFAILED); |
- |
- derCertItem = SECITEM_AllocItem(NULL, NULL, derLength); |
- if (derCertItem == NULL){ |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- (void) PORT_Memcpy(derCertItem->data, derBytes, derLength); |
- |
- /* |
- * setting copyDER to true forces NSS to make its own copy of the DER, |
- * allowing us to free our copy without worrying about whether NSS |
- * is still using it |
- */ |
- copyDER = PKIX_TRUE; |
- handle = CERT_GetDefaultCertDB(); |
- nssCert = CERT_NewTempCertificate(handle, derCertItem, |
- /* nickname */ NULL, |
- /* isPerm */ PR_FALSE, |
- /* copyDer */ PR_TRUE); |
- if (!nssCert){ |
- PKIX_ERROR(PKIX_CERTDECODEDERCERTIFICATEFAILED); |
- } |
- |
- PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert |
- (nssCert, &cert, plContext), |
- PKIX_CERTCREATEWITHNSSCERTFAILED); |
- |
- *pCert = cert; |
- |
-cleanup: |
- if (derCertItem){ |
- SECITEM_FreeItem(derCertItem, PKIX_TRUE); |
- } |
- |
- if (nssCert && PKIX_ERROR_RECEIVED){ |
- PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n"); |
- CERT_DestroyCertificate(nssCert); |
- nssCert = NULL; |
- } |
- |
- PKIX_FREE(derBytes); |
- PKIX_RETURN(CERT); |
-} |
- |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_CreateFromCERTCertificate |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_CreateFromCERTCertificate( |
- const CERTCertificate *nssCert, |
- PKIX_PL_Cert **pCert, |
- void *plContext) |
-{ |
- void *buf = NULL; |
- PKIX_UInt32 len; |
- PKIX_PL_ByteArray *byteArray = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_CreateWithNssCert"); |
- PKIX_NULLCHECK_TWO(pCert, nssCert); |
- |
- buf = (void*)nssCert->derCert.data; |
- len = nssCert->derCert.len; |
- |
- PKIX_CHECK( |
- PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext), |
- PKIX_BYTEARRAYCREATEFAILED); |
- |
- PKIX_CHECK( |
- PKIX_PL_Cert_Create(byteArray, pCert, plContext), |
- PKIX_CERTCREATEWITHNSSCERTFAILED); |
- |
-#ifdef PKIX_UNDEF |
- /* will be tested and used as a patch for bug 391612 */ |
- nssCert = CERT_DupCertificate(nssInCert); |
- |
- PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert |
- (nssCert, &cert, plContext), |
- PKIX_CERTCREATEWITHNSSCERTFAILED); |
-#endif /* PKIX_UNDEF */ |
- |
-cleanup: |
- |
-#ifdef PKIX_UNDEF |
- if (nssCert && PKIX_ERROR_RECEIVED){ |
- PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n"); |
- CERT_DestroyCertificate(nssCert); |
- nssCert = NULL; |
- } |
-#endif /* PKIX_UNDEF */ |
- |
- PKIX_DECREF(byteArray); |
- PKIX_RETURN(CERT); |
-} |
- |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetVersion (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetVersion( |
- PKIX_PL_Cert *cert, |
- PKIX_UInt32 *pVersion, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- PKIX_UInt32 myVersion = 0; /* v1 */ |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetVersion"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pVersion); |
- |
- nssCert = cert->nssCert; |
- if (nssCert->version.len != 0) { |
- myVersion = *(nssCert->version.data); |
- } |
- |
- if (myVersion > 2){ |
- PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1V2ORV3); |
- } |
- |
- *pVersion = myVersion; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetSerialNumber (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetSerialNumber( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_BigInt **pSerialNumber, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- SECItem serialNumItem; |
- PKIX_PL_BigInt *serialNumber = NULL; |
- char *bytes = NULL; |
- PKIX_UInt32 length; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSerialNumber"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSerialNumber); |
- |
- if (cert->serialNumber == NULL){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->serialNumber == NULL){ |
- |
- nssCert = cert->nssCert; |
- serialNumItem = nssCert->serialNumber; |
- |
- length = serialNumItem.len; |
- bytes = (char *)serialNumItem.data; |
- |
- PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes |
- (bytes, length, &serialNumber, plContext), |
- PKIX_BIGINTCREATEWITHBYTESFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->serialNumber = serialNumber; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->serialNumber); |
- *pSerialNumber = cert->serialNumber; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetSubject (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetSubject( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_X500Name **pCertSubject, |
- void *plContext) |
-{ |
- PKIX_PL_X500Name *pkixSubject = NULL; |
- CERTName *subjName = NULL; |
- SECItem *derSubjName = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubject"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertSubject); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->subject == NULL){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->subject == NULL){ |
- |
- subjName = &cert->nssCert->subject; |
- derSubjName = &cert->nssCert->derSubject; |
- |
- /* if there is no subject name */ |
- if (derSubjName->data == NULL) { |
- |
- pkixSubject = NULL; |
- |
- } else { |
- PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName |
- (derSubjName, subjName, &pkixSubject, |
- plContext), |
- PKIX_X500NAMECREATEFROMCERTNAMEFAILED); |
- |
- } |
- /* save a cached copy in case it is asked for again */ |
- cert->subject = pkixSubject; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->subject); |
- *pCertSubject = cert->subject; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetIssuer (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetIssuer( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_X500Name **pCertIssuer, |
- void *plContext) |
-{ |
- PKIX_PL_X500Name *pkixIssuer = NULL; |
- SECItem *derIssuerName = NULL; |
- CERTName *issuerName = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetIssuer"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertIssuer); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->issuer == NULL){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->issuer == NULL){ |
- |
- issuerName = &cert->nssCert->issuer; |
- derIssuerName = &cert->nssCert->derIssuer; |
- |
- /* if there is no subject name */ |
- PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName |
- (derIssuerName, issuerName, |
- &pkixIssuer, plContext), |
- PKIX_X500NAMECREATEFROMCERTNAMEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->issuer = pkixIssuer; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->issuer); |
- *pCertIssuer = cert->issuer; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetSubjectAltNames (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetSubjectAltNames( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pSubjectAltNames, /* list of PKIX_PL_GeneralName */ |
- void *plContext) |
-{ |
- PKIX_PL_GeneralName *pkixAltName = NULL; |
- PKIX_List *altNamesList = NULL; |
- |
- CERTGeneralName *nssOriginalAltName = NULL; |
- CERTGeneralName *nssTempAltName = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectAltNames"); |
- PKIX_NULLCHECK_TWO(cert, pSubjectAltNames); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if ((cert->subjAltNames == NULL) && (!cert->subjAltNamesAbsent)){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if ((cert->subjAltNames == NULL) && |
- (!cert->subjAltNamesAbsent)){ |
- |
- PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames |
- (cert, |
- PKIX_TRUE, |
- &nssOriginalAltName, |
- plContext), |
- PKIX_CERTGETNSSSUBJECTALTNAMESFAILED); |
- |
- if (nssOriginalAltName == NULL) { |
- cert->subjAltNamesAbsent = PKIX_TRUE; |
- pSubjectAltNames = NULL; |
- goto cleanup; |
- } |
- |
- nssTempAltName = nssOriginalAltName; |
- |
- PKIX_CHECK(PKIX_List_Create(&altNamesList, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- do { |
- PKIX_CHECK(pkix_pl_GeneralName_Create |
- (nssTempAltName, &pkixAltName, plContext), |
- PKIX_GENERALNAMECREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (altNamesList, |
- (PKIX_PL_Object *)pkixAltName, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(pkixAltName); |
- |
- PKIX_CERT_DEBUG |
- ("\t\tCalling CERT_GetNextGeneralName).\n"); |
- nssTempAltName = CERT_GetNextGeneralName |
- (nssTempAltName); |
- |
- } while (nssTempAltName != nssOriginalAltName); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->subjAltNames = altNamesList; |
- PKIX_CHECK(PKIX_List_SetImmutable |
- (cert->subjAltNames, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->subjAltNames); |
- |
- *pSubjectAltNames = cert->subjAltNames; |
- |
-cleanup: |
- PKIX_DECREF(pkixAltName); |
- if (PKIX_ERROR_RECEIVED){ |
- PKIX_DECREF(altNamesList); |
- } |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetAllSubjectNames (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetAllSubjectNames( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pAllSubjectNames, /* list of PKIX_PL_GeneralName */ |
- void *plContext) |
-{ |
- CERTGeneralName *nssOriginalSubjectName = NULL; |
- CERTGeneralName *nssTempSubjectName = NULL; |
- PKIX_List *allSubjectNames = NULL; |
- PKIX_PL_GeneralName *pkixSubjectName = NULL; |
- PLArenaPool *arena = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAllSubjectNames"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAllSubjectNames); |
- |
- |
- if (cert->nssCert->subjectName == NULL){ |
- /* if there is no subject DN, just get altnames */ |
- |
- PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames |
- (cert, |
- PKIX_FALSE, /* hasLock */ |
- &nssOriginalSubjectName, |
- plContext), |
- PKIX_CERTGETNSSSUBJECTALTNAMESFAILED); |
- |
- } else { /* get subject DN and altnames */ |
- |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if (arena == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- /* This NSS call returns both Subject and Subject Alt Names */ |
- PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n"); |
- nssOriginalSubjectName = |
- CERT_GetCertificateNames(cert->nssCert, arena); |
- } |
- |
- if (nssOriginalSubjectName == NULL) { |
- pAllSubjectNames = NULL; |
- goto cleanup; |
- } |
- |
- nssTempSubjectName = nssOriginalSubjectName; |
- |
- PKIX_CHECK(PKIX_List_Create(&allSubjectNames, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- do { |
- PKIX_CHECK(pkix_pl_GeneralName_Create |
- (nssTempSubjectName, &pkixSubjectName, plContext), |
- PKIX_GENERALNAMECREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (allSubjectNames, |
- (PKIX_PL_Object *)pkixSubjectName, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(pkixSubjectName); |
- |
- PKIX_CERT_DEBUG |
- ("\t\tCalling CERT_GetNextGeneralName).\n"); |
- nssTempSubjectName = CERT_GetNextGeneralName |
- (nssTempSubjectName); |
- } while (nssTempSubjectName != nssOriginalSubjectName); |
- |
- *pAllSubjectNames = allSubjectNames; |
- |
-cleanup: |
- if (PKIX_ERROR_RECEIVED){ |
- PKIX_DECREF(allSubjectNames); |
- } |
- |
- if (arena){ |
- PORT_FreeArena(arena, PR_FALSE); |
- } |
- PKIX_DECREF(pkixSubjectName); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKeyAlgId |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetSubjectPublicKeyAlgId( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_OID **pSubjKeyAlgId, |
- void *plContext) |
-{ |
- PKIX_PL_OID *pubKeyAlgId = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKeyAlgId"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyAlgId); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->publicKeyAlgId == NULL){ |
- PKIX_OBJECT_LOCK(cert); |
- if (cert->publicKeyAlgId == NULL){ |
- CERTCertificate *nssCert = cert->nssCert; |
- SECAlgorithmID *algorithm; |
- SECItem *algBytes; |
- |
- algorithm = &nssCert->subjectPublicKeyInfo.algorithm; |
- algBytes = &algorithm->algorithm; |
- if (!algBytes->data || !algBytes->len) { |
- PKIX_ERROR_FATAL(PKIX_ALGORITHMBYTESLENGTH0); |
- } |
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem |
- (algBytes, &pubKeyAlgId, plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->publicKeyAlgId = pubKeyAlgId; |
- pubKeyAlgId = NULL; |
- } |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->publicKeyAlgId); |
- *pSubjKeyAlgId = cert->publicKeyAlgId; |
- |
-cleanup: |
- PKIX_DECREF(pubKeyAlgId); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKey (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetSubjectPublicKey( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_PublicKey **pPublicKey, |
- void *plContext) |
-{ |
- PKIX_PL_PublicKey *pkixPubKey = NULL; |
- SECStatus rv; |
- |
- CERTSubjectPublicKeyInfo *from = NULL; |
- CERTSubjectPublicKeyInfo *to = NULL; |
- SECItem *fromItem = NULL; |
- SECItem *toItem = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKey"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPublicKey); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->publicKey == NULL){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->publicKey == NULL){ |
- |
- /* create a PKIX_PL_PublicKey object */ |
- PKIX_CHECK(PKIX_PL_Object_Alloc |
- (PKIX_PUBLICKEY_TYPE, |
- sizeof (PKIX_PL_PublicKey), |
- (PKIX_PL_Object **)&pkixPubKey, |
- plContext), |
- PKIX_COULDNOTCREATEOBJECT); |
- |
- /* initialize fields */ |
- pkixPubKey->nssSPKI = NULL; |
- |
- /* populate the SPKI field */ |
- PKIX_CHECK(PKIX_PL_Malloc |
- (sizeof (CERTSubjectPublicKeyInfo), |
- (void **)&pkixPubKey->nssSPKI, |
- plContext), |
- PKIX_MALLOCFAILED); |
- |
- to = pkixPubKey->nssSPKI; |
- from = &cert->nssCert->subjectPublicKeyInfo; |
- |
- PKIX_NULLCHECK_TWO(to, from); |
- |
- PKIX_CERT_DEBUG |
- ("\t\tCalling SECOID_CopyAlgorithmID).\n"); |
- rv = SECOID_CopyAlgorithmID |
- (NULL, &to->algorithm, &from->algorithm); |
- if (rv != SECSuccess) { |
- PKIX_ERROR(PKIX_SECOIDCOPYALGORITHMIDFAILED); |
- } |
- |
- /* |
- * NSS stores the length of subjectPublicKey in bits. |
- * Therefore, we use that length converted to bytes |
- * using ((length+7)>>3) before calling PORT_Memcpy |
- * in order to avoid "read from uninitialized memory" |
- * errors. |
- */ |
- |
- toItem = &to->subjectPublicKey; |
- fromItem = &from->subjectPublicKey; |
- |
- PKIX_NULLCHECK_TWO(toItem, fromItem); |
- |
- toItem->type = fromItem->type; |
- |
- toItem->data = |
- (unsigned char*) PORT_ZAlloc(fromItem->len); |
- if (!toItem->data){ |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- (void) PORT_Memcpy(toItem->data, |
- fromItem->data, |
- (fromItem->len + 7)>>3); |
- toItem->len = fromItem->len; |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->publicKey = pkixPubKey; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->publicKey); |
- *pPublicKey = cert->publicKey; |
- |
-cleanup: |
- |
- if (PKIX_ERROR_RECEIVED && pkixPubKey){ |
- PKIX_DECREF(pkixPubKey); |
- cert->publicKey = NULL; |
- } |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetCriticalExtensionOIDs |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetCriticalExtensionOIDs( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pList, /* list of PKIX_PL_OID */ |
- void *plContext) |
-{ |
- PKIX_List *oidsList = NULL; |
- CERTCertExtension **extensions = NULL; |
- CERTCertificate *nssCert = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCriticalExtensionOIDs"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pList); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->critExtOids == NULL) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->critExtOids == NULL) { |
- |
- nssCert = cert->nssCert; |
- |
- /* |
- * ASN.1 for Extension |
- * |
- * Extension ::= SEQUENCE { |
- * extnID OBJECT IDENTIFIER, |
- * critical BOOLEAN DEFAULT FALSE, |
- * extnValue OCTET STRING } |
- * |
- */ |
- |
- extensions = nssCert->extensions; |
- |
- PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs |
- (extensions, &oidsList, plContext), |
- PKIX_GETCRITICALEXTENSIONOIDSFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->critExtOids = oidsList; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- /* We should return a copy of the List since this list changes */ |
- PKIX_DUPLICATE(cert->critExtOids, pList, plContext, |
- PKIX_OBJECTDUPLICATELISTFAILED); |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetAuthorityKeyIdentifier |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetAuthorityKeyIdentifier( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_ByteArray **pAuthKeyId, |
- void *plContext) |
-{ |
- PKIX_PL_ByteArray *authKeyId = NULL; |
- CERTCertificate *nssCert = NULL; |
- CERTAuthKeyID *authKeyIdExtension = NULL; |
- PLArenaPool *arena = NULL; |
- SECItem retItem; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityKeyIdentifier"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAuthKeyId); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){ |
- |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if (arena == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- nssCert = cert->nssCert; |
- |
- authKeyIdExtension = |
- CERT_FindAuthKeyIDExten(arena, nssCert); |
- if (authKeyIdExtension == NULL){ |
- cert->authKeyIdAbsent = PKIX_TRUE; |
- *pAuthKeyId = NULL; |
- goto cleanup; |
- } |
- |
- retItem = authKeyIdExtension->keyID; |
- |
- if (retItem.len == 0){ |
- cert->authKeyIdAbsent = PKIX_TRUE; |
- *pAuthKeyId = NULL; |
- goto cleanup; |
- } |
- |
- PKIX_CHECK(PKIX_PL_ByteArray_Create |
- (retItem.data, |
- retItem.len, |
- &authKeyId, |
- plContext), |
- PKIX_BYTEARRAYCREATEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->authKeyId = authKeyId; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->authKeyId); |
- *pAuthKeyId = cert->authKeyId; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- if (arena){ |
- PORT_FreeArena(arena, PR_FALSE); |
- } |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetSubjectKeyIdentifier |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetSubjectKeyIdentifier( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_ByteArray **pSubjKeyId, |
- void *plContext) |
-{ |
- PKIX_PL_ByteArray *subjKeyId = NULL; |
- CERTCertificate *nssCert = NULL; |
- SECItem *retItem = NULL; |
- SECStatus status; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectKeyIdentifier"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyId); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){ |
- |
- retItem = SECITEM_AllocItem(NULL, NULL, 0); |
- if (retItem == NULL){ |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- nssCert = cert->nssCert; |
- |
- status = CERT_FindSubjectKeyIDExtension |
- (nssCert, retItem); |
- if (status != SECSuccess) { |
- cert->subjKeyIdAbsent = PKIX_TRUE; |
- *pSubjKeyId = NULL; |
- goto cleanup; |
- } |
- |
- PKIX_CHECK(PKIX_PL_ByteArray_Create |
- (retItem->data, |
- retItem->len, |
- &subjKeyId, |
- plContext), |
- PKIX_BYTEARRAYCREATEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->subjKeyId = subjKeyId; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->subjKeyId); |
- *pSubjKeyId = cert->subjKeyId; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- if (retItem){ |
- SECITEM_FreeItem(retItem, PKIX_TRUE); |
- } |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetExtendedKeyUsage (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetExtendedKeyUsage( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pKeyUsage, /* list of PKIX_PL_OID */ |
- void *plContext) |
-{ |
- CERTOidSequence *extKeyUsage = NULL; |
- CERTCertificate *nssCert = NULL; |
- PKIX_PL_OID *pkixOID = NULL; |
- PKIX_List *oidsList = NULL; |
- SECItem **oids = NULL; |
- SECItem encodedExtKeyUsage; |
- SECStatus rv; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetExtendedKeyUsage"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pKeyUsage); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if ((cert->extKeyUsages == NULL) && (!cert->extKeyUsagesAbsent)){ |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if ((cert->extKeyUsages == NULL) && |
- (!cert->extKeyUsagesAbsent)){ |
- |
- nssCert = cert->nssCert; |
- |
- rv = CERT_FindCertExtension |
- (nssCert, SEC_OID_X509_EXT_KEY_USAGE, |
- &encodedExtKeyUsage); |
- if (rv != SECSuccess){ |
- cert->extKeyUsagesAbsent = PKIX_TRUE; |
- *pKeyUsage = NULL; |
- goto cleanup; |
- } |
- |
- extKeyUsage = |
- CERT_DecodeOidSequence(&encodedExtKeyUsage); |
- if (extKeyUsage == NULL){ |
- PKIX_ERROR(PKIX_CERTDECODEOIDSEQUENCEFAILED); |
- } |
- |
- PORT_Free(encodedExtKeyUsage.data); |
- |
- oids = extKeyUsage->oids; |
- |
- if (!oids){ |
- /* no extended key usage extensions found */ |
- cert->extKeyUsagesAbsent = PKIX_TRUE; |
- *pKeyUsage = NULL; |
- goto cleanup; |
- } |
- |
- PKIX_CHECK(PKIX_List_Create(&oidsList, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- while (*oids){ |
- SECItem *oid = *oids++; |
- |
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem |
- (oid, &pkixOID, plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (oidsList, |
- (PKIX_PL_Object *)pkixOID, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- PKIX_DECREF(pkixOID); |
- } |
- |
- PKIX_CHECK(PKIX_List_SetImmutable |
- (oidsList, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->extKeyUsages = oidsList; |
- oidsList = NULL; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->extKeyUsages); |
- *pKeyUsage = cert->extKeyUsages; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- |
- PKIX_DECREF(pkixOID); |
- PKIX_DECREF(oidsList); |
- CERT_DestroyOidSequence(extKeyUsage); |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetBasicConstraints |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetBasicConstraints( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_CertBasicConstraints **pBasicConstraints, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- CERTBasicConstraints nssBasicConstraint; |
- SECStatus rv; |
- PKIX_PL_CertBasicConstraints *basic; |
- PKIX_Int32 pathLen = 0; |
- PKIX_Boolean isCA = PKIX_FALSE; |
- enum { |
- realBC, synthBC, absentBC |
- } constraintSource = absentBC; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetBasicConstraints"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pBasicConstraints); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if ((cert->certBasicConstraints == NULL) && |
- (!cert->basicConstraintsAbsent)) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if ((cert->certBasicConstraints == NULL) && |
- (!cert->basicConstraintsAbsent)) { |
- |
- nssCert = cert->nssCert; |
- |
- PKIX_CERT_DEBUG( |
- "\t\tCalling Cert_FindBasicConstraintExten\n"); |
- rv = CERT_FindBasicConstraintExten |
- (nssCert, &nssBasicConstraint); |
- if (rv == SECSuccess) { |
- constraintSource = realBC; |
- } |
- |
- if (constraintSource == absentBC) { |
- /* can we deduce it's a CA and create a |
- synthetic constraint? |
- */ |
- CERTCertTrust trust; |
- rv = CERT_GetCertTrust(nssCert, &trust); |
- if (rv == SECSuccess) { |
- int anyWantedFlag = CERTDB_TRUSTED_CA | CERTDB_VALID_CA; |
- if ((trust.sslFlags & anyWantedFlag) |
- || (trust.emailFlags & anyWantedFlag) |
- || (trust.objectSigningFlags & anyWantedFlag)) { |
- |
- constraintSource = synthBC; |
- } |
- } |
- } |
- |
- if (constraintSource == absentBC) { |
- cert->basicConstraintsAbsent = PKIX_TRUE; |
- *pBasicConstraints = NULL; |
- goto cleanup; |
- } |
- } |
- |
- if (constraintSource == synthBC) { |
- isCA = PKIX_TRUE; |
- pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT; |
- } else { |
- isCA = (nssBasicConstraint.isCA)?PKIX_TRUE:PKIX_FALSE; |
- |
- /* The pathLen has meaning only for CAs */ |
- if (isCA) { |
- if (CERT_UNLIMITED_PATH_CONSTRAINT == |
- nssBasicConstraint.pathLenConstraint) { |
- pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT; |
- } else { |
- pathLen = nssBasicConstraint.pathLenConstraint; |
- } |
- } |
- } |
- |
- PKIX_CHECK(pkix_pl_CertBasicConstraints_Create |
- (isCA, pathLen, &basic, plContext), |
- PKIX_CERTBASICCONSTRAINTSCREATEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->certBasicConstraints = basic; |
- } |
- |
- PKIX_INCREF(cert->certBasicConstraints); |
- *pBasicConstraints = cert->certBasicConstraints; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetPolicyInformation |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetPolicyInformation( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pPolicyInfo, |
- void *plContext) |
-{ |
- PKIX_List *policyList = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyInformation"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyInfo); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if ((cert->certPolicyInfos == NULL) && |
- (!cert->policyInfoAbsent)) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if ((cert->certPolicyInfos == NULL) && |
- (!cert->policyInfoAbsent)) { |
- |
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyInfo |
- (cert->nssCert, &policyList, plContext), |
- PKIX_CERTDECODEPOLICYINFOFAILED); |
- |
- if (!policyList) { |
- cert->policyInfoAbsent = PKIX_TRUE; |
- *pPolicyInfo = NULL; |
- goto cleanup; |
- } |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->certPolicyInfos = policyList; |
- policyList = NULL; |
- } |
- |
- PKIX_INCREF(cert->certPolicyInfos); |
- *pPolicyInfo = cert->certPolicyInfos; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- |
- PKIX_DECREF(policyList); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetPolicyMappings (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetPolicyMappings( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pPolicyMappings, /* list of PKIX_PL_CertPolicyMap */ |
- void *plContext) |
-{ |
- PKIX_List *policyMappings = NULL; /* list of PKIX_PL_CertPolicyMap */ |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappings"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyMappings); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (!(cert->certPolicyMappings) && !(cert->policyMappingsAbsent)) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (!(cert->certPolicyMappings) && |
- !(cert->policyMappingsAbsent)) { |
- |
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyMapping |
- (cert->nssCert, &policyMappings, plContext), |
- PKIX_CERTDECODEPOLICYMAPPINGFAILED); |
- |
- if (!policyMappings) { |
- cert->policyMappingsAbsent = PKIX_TRUE; |
- *pPolicyMappings = NULL; |
- goto cleanup; |
- } |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- |
- /* save a cached copy in case it is asked for again */ |
- cert->certPolicyMappings = policyMappings; |
- policyMappings = NULL; |
- } |
- |
- PKIX_INCREF(cert->certPolicyMappings); |
- *pPolicyMappings = cert->certPolicyMappings; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- |
- PKIX_DECREF(policyMappings); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetRequireExplicitPolicy |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetRequireExplicitPolicy( |
- PKIX_PL_Cert *cert, |
- PKIX_Int32 *pSkipCerts, |
- void *plContext) |
-{ |
- PKIX_Int32 explicitPolicySkipCerts = 0; |
- PKIX_Int32 inhibitMappingSkipCerts = 0; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetRequireExplicitPolicy"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts); |
- |
- if (!(cert->policyConstraintsProcessed)) { |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (!(cert->policyConstraintsProcessed)) { |
- |
- /* |
- * If we can't process it now, we probably will be |
- * unable to process it later. Set the default value. |
- */ |
- cert->policyConstraintsProcessed = PKIX_TRUE; |
- cert->policyConstraintsExplicitPolicySkipCerts = -1; |
- cert->policyConstraintsInhibitMappingSkipCerts = -1; |
- |
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints |
- (cert->nssCert, |
- &explicitPolicySkipCerts, |
- &inhibitMappingSkipCerts, |
- plContext), |
- PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED); |
- |
- cert->policyConstraintsExplicitPolicySkipCerts = |
- explicitPolicySkipCerts; |
- cert->policyConstraintsInhibitMappingSkipCerts = |
- inhibitMappingSkipCerts; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- *pSkipCerts = cert->policyConstraintsExplicitPolicySkipCerts; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetPolicyMappingInhibited |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetPolicyMappingInhibited( |
- PKIX_PL_Cert *cert, |
- PKIX_Int32 *pSkipCerts, |
- void *plContext) |
-{ |
- PKIX_Int32 explicitPolicySkipCerts = 0; |
- PKIX_Int32 inhibitMappingSkipCerts = 0; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappingInhibited"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts); |
- |
- if (!(cert->policyConstraintsProcessed)) { |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (!(cert->policyConstraintsProcessed)) { |
- |
- /* |
- * If we can't process it now, we probably will be |
- * unable to process it later. Set the default value. |
- */ |
- cert->policyConstraintsProcessed = PKIX_TRUE; |
- cert->policyConstraintsExplicitPolicySkipCerts = -1; |
- cert->policyConstraintsInhibitMappingSkipCerts = -1; |
- |
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints |
- (cert->nssCert, |
- &explicitPolicySkipCerts, |
- &inhibitMappingSkipCerts, |
- plContext), |
- PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED); |
- |
- cert->policyConstraintsExplicitPolicySkipCerts = |
- explicitPolicySkipCerts; |
- cert->policyConstraintsInhibitMappingSkipCerts = |
- inhibitMappingSkipCerts; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- *pSkipCerts = cert->policyConstraintsInhibitMappingSkipCerts; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetInhibitAnyPolicy (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetInhibitAnyPolicy( |
- PKIX_PL_Cert *cert, |
- PKIX_Int32 *pSkipCerts, |
- void *plContext) |
-{ |
- PKIX_Int32 skipCerts = 0; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetInhibitAnyPolicy"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts); |
- |
- if (!(cert->inhibitAnyPolicyProcessed)) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (!(cert->inhibitAnyPolicyProcessed)) { |
- |
- /* |
- * If we can't process it now, we probably will be |
- * unable to process it later. Set the default value. |
- */ |
- cert->inhibitAnyPolicyProcessed = PKIX_TRUE; |
- cert->inhibitAnySkipCerts = -1; |
- |
- PKIX_CHECK(pkix_pl_Cert_DecodeInhibitAnyPolicy |
- (cert->nssCert, &skipCerts, plContext), |
- PKIX_CERTDECODEINHIBITANYPOLICYFAILED); |
- |
- cert->inhibitAnySkipCerts = skipCerts; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- *pSkipCerts = cert->inhibitAnySkipCerts; |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_AreCertPoliciesCritical |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_AreCertPoliciesCritical( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean *pCritical, |
- void *plContext) |
-{ |
- PKIX_Boolean criticality = PKIX_FALSE; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_AreCertPoliciesCritical"); |
- PKIX_NULLCHECK_TWO(cert, pCritical); |
- |
- PKIX_CHECK(pkix_pl_Cert_IsExtensionCritical( |
- cert, |
- SEC_OID_X509_CERTIFICATE_POLICIES, |
- &criticality, |
- plContext), |
- PKIX_CERTISEXTENSIONCRITICALFAILED); |
- |
- *pCritical = criticality; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_VerifySignature (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_VerifySignature( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_PublicKey *pubKey, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- SECKEYPublicKey *nssPubKey = NULL; |
- CERTSignedData *tbsCert = NULL; |
- PKIX_PL_Cert *cachedCert = NULL; |
- PKIX_Error *verifySig = NULL; |
- PKIX_Error *cachedSig = NULL; |
- SECStatus status; |
- PKIX_Boolean certEqual = PKIX_FALSE; |
- PKIX_Boolean certInHash = PKIX_FALSE; |
- void* wincx = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifySignature"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pubKey); |
- |
- verifySig = PKIX_PL_HashTable_Lookup |
- (cachedCertSigTable, |
- (PKIX_PL_Object *) pubKey, |
- (PKIX_PL_Object **) &cachedCert, |
- plContext); |
- |
- if (cachedCert != NULL && verifySig == NULL) { |
- /* Cached Signature Table lookup succeed */ |
- PKIX_EQUALS(cert, cachedCert, &certEqual, plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- if (certEqual == PKIX_TRUE) { |
- goto cleanup; |
- } |
- /* Different PubKey may hash to same value, skip add */ |
- certInHash = PKIX_TRUE; |
- } |
- |
- nssCert = cert->nssCert; |
- tbsCert = &nssCert->signatureWrap; |
- |
- PKIX_CERT_DEBUG("\t\tCalling SECKEY_ExtractPublicKey).\n"); |
- nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI); |
- if (!nssPubKey){ |
- PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED); |
- } |
- |
- PKIX_CERT_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey).\n"); |
- |
- PKIX_CHECK(pkix_pl_NssContext_GetWincx |
- ((PKIX_PL_NssContext *)plContext, &wincx), |
- PKIX_NSSCONTEXTGETWINCXFAILED); |
- |
- status = CERT_VerifySignedDataWithPublicKey(tbsCert, nssPubKey, wincx); |
- |
- if (status != SECSuccess) { |
- if (PORT_GetError() != SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) { |
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); |
- } |
- PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY); |
- } |
- |
- if (certInHash == PKIX_FALSE) { |
- cachedSig = PKIX_PL_HashTable_Add |
- (cachedCertSigTable, |
- (PKIX_PL_Object *) pubKey, |
- (PKIX_PL_Object *) cert, |
- plContext); |
- |
- if (cachedSig != NULL) { |
- PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n"); |
- } |
- } |
- |
-cleanup: |
- if (nssPubKey){ |
- PKIX_CERT_DEBUG("\t\tCalling SECKEY_DestroyPublicKey).\n"); |
- SECKEY_DestroyPublicKey(nssPubKey); |
- } |
- |
- PKIX_DECREF(cachedCert); |
- PKIX_DECREF(verifySig); |
- PKIX_DECREF(cachedSig); |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_CheckValidity (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_CheckValidity( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_Date *date, |
- void *plContext) |
-{ |
- SECCertTimeValidity val; |
- PRTime timeToCheck; |
- PKIX_Boolean allowOverride; |
- SECCertificateUsage requiredUsages; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckValidity"); |
- PKIX_NULLCHECK_ONE(cert); |
- |
- /* if the caller supplies a date, we use it; else, use current time */ |
- if (date != NULL){ |
- PKIX_CHECK(pkix_pl_Date_GetPRTime |
- (date, &timeToCheck, plContext), |
- PKIX_DATEGETPRTIMEFAILED); |
- } else { |
- timeToCheck = PR_Now(); |
- } |
- |
- requiredUsages = ((PKIX_PL_NssContext*)plContext)->certificateUsage; |
- allowOverride = |
- (PRBool)((requiredUsages & certificateUsageSSLServer) || |
- (requiredUsages & certificateUsageSSLServerWithStepUp)); |
- val = CERT_CheckCertValidTimes(cert->nssCert, timeToCheck, allowOverride); |
- if (val != secCertTimeValid){ |
- PKIX_ERROR(PKIX_CERTCHECKCERTVALIDTIMESFAILED); |
- } |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetValidityNotAfter (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetValidityNotAfter( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_Date **pDate, |
- void *plContext) |
-{ |
- PRTime prtime; |
- SECStatus rv = SECFailure; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetValidityNotAfter"); |
- PKIX_NULLCHECK_TWO(cert, pDate); |
- |
- PKIX_DATE_DEBUG("\t\tCalling DER_DecodeTimeChoice).\n"); |
- rv = DER_DecodeTimeChoice(&prtime, &(cert->nssCert->validity.notAfter)); |
- if (rv != SECSuccess){ |
- PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED); |
- } |
- |
- PKIX_CHECK(pkix_pl_Date_CreateFromPRTime |
- (prtime, pDate, plContext), |
- PKIX_DATECREATEFROMPRTIMEFAILED); |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_VerifyCertAndKeyType (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_VerifyCertAndKeyType( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean isChainCert, |
- void *plContext) |
-{ |
- PKIX_PL_CertBasicConstraints *basicConstraints = NULL; |
- SECCertificateUsage certificateUsage; |
- SECCertUsage certUsage = 0; |
- unsigned int requiredKeyUsage; |
- unsigned int requiredCertType; |
- unsigned int certType; |
- SECStatus rv = SECSuccess; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyCertType"); |
- PKIX_NULLCHECK_TWO(cert, plContext); |
- |
- certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage; |
- |
- /* ensure we obtained a single usage bit only */ |
- PORT_Assert(!(certificateUsage & (certificateUsage - 1))); |
- |
- /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */ |
- while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; } |
- |
- /* check key usage and netscape cert type */ |
- cert_GetCertType(cert->nssCert); |
- certType = cert->nssCert->nsCertType; |
- if (isChainCert || |
- (certUsage != certUsageVerifyCA && certUsage != certUsageAnyCA)) { |
- rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, isChainCert, |
- &requiredKeyUsage, |
- &requiredCertType); |
- if (rv == SECFailure) { |
- PKIX_ERROR(PKIX_UNSUPPORTEDCERTUSAGE); |
- } |
- } else { |
- /* use this key usage and cert type for certUsageAnyCA and |
- * certUsageVerifyCA. */ |
- requiredKeyUsage = KU_KEY_CERT_SIGN; |
- requiredCertType = NS_CERT_TYPE_CA; |
- } |
- if (CERT_CheckKeyUsage(cert->nssCert, requiredKeyUsage) != SECSuccess) { |
- PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED); |
- } |
- if (!(certType & requiredCertType)) { |
- PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED); |
- } |
-cleanup: |
- PKIX_DECREF(basicConstraints); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_VerifyKeyUsage( |
- PKIX_PL_Cert *cert, |
- PKIX_UInt32 keyUsage, |
- void *plContext) |
-{ |
- CERTCertificate *nssCert = NULL; |
- PKIX_UInt32 nssKeyUsage = 0; |
- SECStatus status; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyKeyUsage"); |
- PKIX_NULLCHECK_TWO(cert, cert->nssCert); |
- |
- nssCert = cert->nssCert; |
- |
- /* if cert doesn't have keyUsage extension, all keyUsages are valid */ |
- if (!nssCert->keyUsagePresent){ |
- goto cleanup; |
- } |
- |
- if (keyUsage & PKIX_DIGITAL_SIGNATURE){ |
- nssKeyUsage = nssKeyUsage | KU_DIGITAL_SIGNATURE; |
- } |
- |
- if (keyUsage & PKIX_NON_REPUDIATION){ |
- nssKeyUsage = nssKeyUsage | KU_NON_REPUDIATION; |
- } |
- |
- if (keyUsage & PKIX_KEY_ENCIPHERMENT){ |
- nssKeyUsage = nssKeyUsage | KU_KEY_ENCIPHERMENT; |
- } |
- |
- if (keyUsage & PKIX_DATA_ENCIPHERMENT){ |
- nssKeyUsage = nssKeyUsage | KU_DATA_ENCIPHERMENT; |
- } |
- |
- if (keyUsage & PKIX_KEY_AGREEMENT){ |
- nssKeyUsage = nssKeyUsage | KU_KEY_AGREEMENT; |
- } |
- |
- if (keyUsage & PKIX_KEY_CERT_SIGN){ |
- nssKeyUsage = nssKeyUsage | KU_KEY_CERT_SIGN; |
- } |
- |
- if (keyUsage & PKIX_CRL_SIGN){ |
- nssKeyUsage = nssKeyUsage | KU_CRL_SIGN; |
- } |
- |
- if (keyUsage & PKIX_ENCIPHER_ONLY){ |
- nssKeyUsage = nssKeyUsage | 0x01; |
- } |
- |
- if (keyUsage & PKIX_DECIPHER_ONLY){ |
- /* XXX we should support this once it is fixed in NSS */ |
- PKIX_ERROR(PKIX_DECIPHERONLYKEYUSAGENOTSUPPORTED); |
- } |
- |
- status = CERT_CheckKeyUsage(nssCert, nssKeyUsage); |
- if (status != SECSuccess) { |
- PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED); |
- } |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetNameConstraints |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetNameConstraints( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_CertNameConstraints **pNameConstraints, |
- void *plContext) |
-{ |
- PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNameConstraints"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pNameConstraints); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->nameConstraints == NULL && !cert->nameConstraintsAbsent) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->nameConstraints == NULL && |
- !cert->nameConstraintsAbsent) { |
- |
- PKIX_CHECK(pkix_pl_CertNameConstraints_Create |
- (cert->nssCert, &nameConstraints, plContext), |
- PKIX_CERTNAMECONSTRAINTSCREATEFAILED); |
- |
- if (nameConstraints == NULL) { |
- cert->nameConstraintsAbsent = PKIX_TRUE; |
- } |
- |
- cert->nameConstraints = nameConstraints; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- |
- } |
- |
- PKIX_INCREF(cert->nameConstraints); |
- |
- *pNameConstraints = cert->nameConstraints; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_CheckNameConstraints |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_CheckNameConstraints( |
- PKIX_PL_Cert *cert, |
- PKIX_PL_CertNameConstraints *nameConstraints, |
- void *plContext) |
-{ |
- PKIX_Boolean checkPass = PKIX_TRUE; |
- CERTGeneralName *nssSubjectNames = NULL; |
- PLArenaPool *arena = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckNameConstraints"); |
- PKIX_NULLCHECK_ONE(cert); |
- |
- if (nameConstraints != NULL) { |
- |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if (arena == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- /* This NSS call returns both Subject and Subject Alt Names */ |
- PKIX_CERT_DEBUG |
- ("\t\tCalling CERT_GetConstrainedCertificateNames\n"); |
- nssSubjectNames = CERT_GetConstrainedCertificateNames |
- (cert->nssCert, arena, PR_TRUE); |
- |
- PKIX_CHECK(pkix_pl_CertNameConstraints_CheckNameSpaceNssNames |
- (nssSubjectNames, |
- nameConstraints, |
- &checkPass, |
- plContext), |
- PKIX_CERTNAMECONSTRAINTSCHECKNAMESPACENSSNAMESFAILED); |
- |
- if (checkPass != PKIX_TRUE) { |
- PKIX_ERROR(PKIX_CERTFAILEDNAMECONSTRAINTSCHECKING); |
- } |
- } |
- |
-cleanup: |
- if (arena){ |
- PORT_FreeArena(arena, PR_FALSE); |
- } |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_MergeNameConstraints |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_MergeNameConstraints( |
- PKIX_PL_CertNameConstraints *firstNC, |
- PKIX_PL_CertNameConstraints *secondNC, |
- PKIX_PL_CertNameConstraints **pResultNC, |
- void *plContext) |
-{ |
- PKIX_PL_CertNameConstraints *mergedNC = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_MergeNameConstraints"); |
- PKIX_NULLCHECK_TWO(firstNC, pResultNC); |
- |
- if (secondNC == NULL) { |
- |
- PKIX_INCREF(firstNC); |
- *pResultNC = firstNC; |
- |
- goto cleanup; |
- } |
- |
- PKIX_CHECK(pkix_pl_CertNameConstraints_Merge |
- (firstNC, secondNC, &mergedNC, plContext), |
- PKIX_CERTNAMECONSTRAINTSMERGEFAILED); |
- |
- *pResultNC = mergedNC; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * Find out the state of the NSS trust bits for the requested usage. |
- * Returns SECFailure if the cert is explicitly distrusted. |
- * Returns SECSuccess if the cert can be used to form a chain (normal case), |
- * or it is explicitly trusted. The trusted bool is set to true if it is |
- * explicitly trusted. |
- */ |
-static SECStatus |
-pkix_pl_Cert_GetTrusted(void *plContext, |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean *trusted, |
- PKIX_Boolean isCA) |
-{ |
- SECStatus rv; |
- CERTCertificate *nssCert = NULL; |
- SECCertUsage certUsage = 0; |
- SECCertificateUsage certificateUsage; |
- SECTrustType trustType; |
- unsigned int trustFlags; |
- unsigned int requiredFlags; |
- CERTCertTrust trust; |
- |
- *trusted = PKIX_FALSE; |
- |
- /* no key usage information */ |
- if (plContext == NULL) { |
- return SECSuccess; |
- } |
- |
- certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage; |
- |
- /* ensure we obtained a single usage bit only */ |
- PORT_Assert(!(certificateUsage & (certificateUsage - 1))); |
- |
- /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */ |
- while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; } |
- |
- nssCert = cert->nssCert; |
- |
- if (!isCA) { |
- PRBool prTrusted; |
- unsigned int failedFlags; |
- rv = cert_CheckLeafTrust(nssCert, certUsage, |
- &failedFlags, &prTrusted); |
- *trusted = (PKIX_Boolean) prTrusted; |
- return rv; |
- } |
- rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, |
- &trustType); |
- if (rv != SECSuccess) { |
- return SECSuccess; |
- } |
- |
- rv = CERT_GetCertTrust(nssCert, &trust); |
- if (rv != SECSuccess) { |
- return SECSuccess; |
- } |
- trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType); |
- /* normally trustTypeNone usages accept any of the given trust bits |
- * being on as acceptable. If any are distrusted (and none are trusted), |
- * then we will also distrust the cert */ |
- if ((trustFlags == 0) && (trustType == trustTypeNone)) { |
- trustFlags = trust.sslFlags | trust.emailFlags | |
- trust.objectSigningFlags; |
- } |
- if ((trustFlags & requiredFlags) == requiredFlags) { |
- *trusted = PKIX_TRUE; |
- return SECSuccess; |
- } |
- if ((trustFlags & CERTDB_TERMINAL_RECORD) && |
- ((trustFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) { |
- return SECFailure; |
- } |
- return SECSuccess; |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_IsCertTrusted |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_IsCertTrusted( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean trustOnlyUserAnchors, |
- PKIX_Boolean *pTrusted, |
- void *plContext) |
-{ |
- PKIX_CertStore_CheckTrustCallback trustCallback = NULL; |
- PKIX_Boolean trusted = PKIX_FALSE; |
- SECStatus rv = SECFailure; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_IsCertTrusted"); |
- PKIX_NULLCHECK_TWO(cert, pTrusted); |
- |
- /* Call GetTrusted first to see if we are going to distrust the |
- * certificate */ |
- rv = pkix_pl_Cert_GetTrusted(plContext, cert, &trusted, PKIX_TRUE); |
- if (rv != SECSuccess) { |
- /* Failure means the cert is explicitly distrusted, |
- * let the next level know not to use it. */ |
- *pTrusted = PKIX_FALSE; |
- PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED); |
- } |
- |
- if (trustOnlyUserAnchors || cert->isUserTrustAnchor) { |
- /* discard our |trusted| value since we are using the anchors */ |
- *pTrusted = cert->isUserTrustAnchor; |
- goto cleanup; |
- } |
- |
- /* no key usage information or store is not trusted */ |
- if (plContext == NULL || cert->store == NULL) { |
- *pTrusted = PKIX_FALSE; |
- goto cleanup; |
- } |
- |
- PKIX_CHECK(PKIX_CertStore_GetTrustCallback |
- (cert->store, &trustCallback, plContext), |
- PKIX_CERTSTOREGETTRUSTCALLBACKFAILED); |
- |
- PKIX_CHECK_ONLY_FATAL(trustCallback |
- (cert->store, cert, &trusted, plContext), |
- PKIX_CHECKTRUSTCALLBACKFAILED); |
- |
- /* allow trust store to override if we can trust the trust |
- * bits */ |
- if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) { |
- *pTrusted = PKIX_FALSE; |
- goto cleanup; |
- } |
- |
- *pTrusted = trusted; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_IsLeafCertTrusted( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean *pTrusted, |
- void *plContext) |
-{ |
- SECStatus rv; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_IsLeafCertTrusted"); |
- PKIX_NULLCHECK_TWO(cert, pTrusted); |
- |
- *pTrusted = PKIX_FALSE; |
- |
- rv = pkix_pl_Cert_GetTrusted(plContext, cert, pTrusted, PKIX_FALSE); |
- if (rv != SECSuccess) { |
- /* Failure means the cert is explicitly distrusted, |
- * let the next level know not to use it. */ |
- *pTrusted = PKIX_FALSE; |
- PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED); |
- } |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */ |
-PKIX_Error* |
-PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert, |
- void *plContext) |
-{ |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_SetAsTrustAnchor"); |
- PKIX_NULLCHECK_ONE(cert); |
- |
- cert->isUserTrustAnchor = PKIX_TRUE; |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetCacheFlag (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetCacheFlag( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean *pCacheFlag, |
- void *plContext) |
-{ |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCacheFlag"); |
- PKIX_NULLCHECK_TWO(cert, pCacheFlag); |
- |
- *pCacheFlag = cert->cacheFlag; |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_SetCacheFlag (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_SetCacheFlag( |
- PKIX_PL_Cert *cert, |
- PKIX_Boolean cacheFlag, |
- void *plContext) |
-{ |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_SetCacheFlag"); |
- PKIX_NULLCHECK_ONE(cert); |
- |
- cert->cacheFlag = cacheFlag; |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetTrustCertStore (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetTrustCertStore( |
- PKIX_PL_Cert *cert, |
- PKIX_CertStore **pTrustCertStore, |
- void *plContext) |
-{ |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetTrustCertStore"); |
- PKIX_NULLCHECK_TWO(cert, pTrustCertStore); |
- |
- PKIX_INCREF(cert->store); |
- *pTrustCertStore = cert->store; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_SetTrustCertStore (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_SetTrustCertStore( |
- PKIX_PL_Cert *cert, |
- PKIX_CertStore *trustCertStore, |
- void *plContext) |
-{ |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_SetTrustCertStore"); |
- PKIX_NULLCHECK_TWO(cert, trustCertStore); |
- |
- PKIX_INCREF(trustCertStore); |
- cert->store = trustCertStore; |
- |
-cleanup: |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetAuthorityInfoAccess |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetAuthorityInfoAccess( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pAiaList, /* of PKIX_PL_InfoAccess */ |
- void *plContext) |
-{ |
- PKIX_List *aiaList = NULL; /* of PKIX_PL_InfoAccess */ |
- SECItem *encodedAIA = NULL; |
- CERTAuthInfoAccess **aia = NULL; |
- PLArenaPool *arena = NULL; |
- SECStatus rv; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityInfoAccess"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAiaList); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->authorityInfoAccess == NULL) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->authorityInfoAccess == NULL) { |
- |
- PKIX_PL_NSSCALLRV(CERT, encodedAIA, SECITEM_AllocItem, |
- (NULL, NULL, 0)); |
- |
- if (encodedAIA == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension, |
- (cert->nssCert, |
- SEC_OID_X509_AUTH_INFO_ACCESS, |
- encodedAIA)); |
- |
- if (rv == SECFailure) { |
- goto cleanup; |
- } |
- |
- PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena, |
- (DER_DEFAULT_CHUNKSIZE)); |
- |
- if (arena == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- PKIX_PL_NSSCALLRV |
- (CERT, aia, CERT_DecodeAuthInfoAccessExtension, |
- (arena, encodedAIA)); |
- |
- PKIX_CHECK(pkix_pl_InfoAccess_CreateList |
- (aia, &aiaList, plContext), |
- PKIX_INFOACCESSCREATELISTFAILED); |
- |
- cert->authorityInfoAccess = aiaList; |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->authorityInfoAccess); |
- |
- *pAiaList = cert->authorityInfoAccess; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- if (arena != NULL) { |
- PORT_FreeArena(arena, PR_FALSE); |
- } |
- |
- if (encodedAIA != NULL) { |
- SECITEM_FreeItem(encodedAIA, PR_TRUE); |
- } |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* XXX Following defines belongs to NSS */ |
-static const unsigned char siaOIDString[] = {0x2b, 0x06, 0x01, 0x05, 0x05, |
- 0x07, 0x01, 0x0b}; |
-#define OI(x) { siDEROID, (unsigned char *)x, sizeof x } |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetSubjectInfoAccess |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetSubjectInfoAccess( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pSiaList, /* of PKIX_PL_InfoAccess */ |
- void *plContext) |
-{ |
- PKIX_List *siaList; /* of PKIX_PL_InfoAccess */ |
- SECItem siaOID = OI(siaOIDString); |
- SECItem *encodedSubjInfoAccess = NULL; |
- CERTAuthInfoAccess **subjInfoAccess = NULL; |
- PLArenaPool *arena = NULL; |
- SECStatus rv; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectInfoAccess"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSiaList); |
- |
- /* XXX |
- * Codes to deal with SubjectInfoAccess OID should be moved to |
- * NSS soon. I implemented them here so we don't touch NSS |
- * source tree, from JP's suggestion. |
- */ |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->subjectInfoAccess == NULL) { |
- |
- PKIX_OBJECT_LOCK(cert); |
- |
- if (cert->subjectInfoAccess == NULL) { |
- |
- encodedSubjInfoAccess = SECITEM_AllocItem(NULL, NULL, 0); |
- if (encodedSubjInfoAccess == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- PKIX_CERT_DEBUG |
- ("\t\tCalling CERT_FindCertExtensionByOID).\n"); |
- rv = CERT_FindCertExtensionByOID |
- (cert->nssCert, &siaOID, encodedSubjInfoAccess); |
- |
- if (rv == SECFailure) { |
- goto cleanup; |
- } |
- |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if (arena == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- /* XXX |
- * Decode Subject Information Access - |
- * since its type is the same as Authority Information |
- * Access, reuse the call. NSS- change name to avoid |
- * confusion. |
- */ |
- PKIX_CERT_DEBUG |
- ("\t\tCalling CERT_DecodeAuthInfoAccessExtension).\n"); |
- subjInfoAccess = CERT_DecodeAuthInfoAccessExtension |
- (arena, encodedSubjInfoAccess); |
- |
- PKIX_CHECK(pkix_pl_InfoAccess_CreateList |
- (subjInfoAccess, &siaList, plContext), |
- PKIX_INFOACCESSCREATELISTFAILED); |
- |
- cert->subjectInfoAccess = siaList; |
- |
- } |
- |
- PKIX_OBJECT_UNLOCK(cert); |
- } |
- |
- PKIX_INCREF(cert->subjectInfoAccess); |
- *pSiaList = cert->subjectInfoAccess; |
- |
-cleanup: |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- if (arena != NULL) { |
- PORT_FreeArena(arena, PR_FALSE); |
- } |
- |
- if (encodedSubjInfoAccess != NULL) { |
- SECITEM_FreeItem(encodedSubjInfoAccess, PR_TRUE); |
- } |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetCrlDp |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetCrlDp( |
- PKIX_PL_Cert *cert, |
- PKIX_List **pDpList, |
- void *plContext) |
-{ |
- PKIX_UInt32 dpIndex = 0; |
- pkix_pl_CrlDp *dp = NULL; |
- CERTCrlDistributionPoints *dpoints = NULL; |
- |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCrlDp"); |
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pDpList); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (cert->crldpList == NULL) { |
- PKIX_OBJECT_LOCK(cert); |
- if (cert->crldpList != NULL) { |
- goto cleanup; |
- } |
- PKIX_CHECK(PKIX_List_Create(&cert->crldpList, plContext), |
- PKIX_LISTCREATEFAILED); |
- dpoints = CERT_FindCRLDistributionPoints(cert->nssCert); |
- if (!dpoints || !dpoints->distPoints) { |
- goto cleanup; |
- } |
- for (;dpoints->distPoints[dpIndex];dpIndex++) { |
- PKIX_CHECK( |
- pkix_pl_CrlDp_Create(dpoints->distPoints[dpIndex], |
- &cert->nssCert->issuer, |
- &dp, plContext), |
- PKIX_CRLDPCREATEFAILED); |
- /* Create crldp list in reverse order in attempt to get |
- * to the whole crl first. */ |
- PKIX_CHECK( |
- PKIX_List_InsertItem(cert->crldpList, 0, |
- (PKIX_PL_Object*)dp, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- PKIX_DECREF(dp); |
- } |
- } |
-cleanup: |
- PKIX_INCREF(cert->crldpList); |
- *pDpList = cert->crldpList; |
- |
- PKIX_OBJECT_UNLOCK(lockedObject); |
- PKIX_DECREF(dp); |
- |
- PKIX_RETURN(CERT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_Cert_GetCERTCertificate |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_Cert_GetCERTCertificate( |
- PKIX_PL_Cert *cert, |
- CERTCertificate **pnssCert, |
- void *plContext) |
-{ |
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNssCert"); |
- PKIX_NULLCHECK_TWO(cert, pnssCert); |
- |
- *pnssCert = CERT_DupCertificate(cert->nssCert); |
- |
- PKIX_RETURN(CERT); |
-} |