diff options
Diffstat (limited to '')
-rw-r--r-- | security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c new file mode 100644 index 0000000000..4f29de2849 --- /dev/null +++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c @@ -0,0 +1,151 @@ +/* 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_crldp.c + * + * Crl DP Object Functions + * + */ + +#include "pkix_pl_crldp.h" + +static PKIX_Error * +pkix_pl_CrlDp_Destroy( + PKIX_PL_Object *object, + void *plContext) +{ + pkix_pl_CrlDp *crldp = NULL; + + PKIX_ENTER(CRLCHECKER, "pkix_CrlDp_Destroy"); + PKIX_NULLCHECK_ONE(object); + + /* Check that this object is a default CRL checker state */ + PKIX_CHECK( + pkix_CheckType(object, PKIX_CRLDP_TYPE, plContext), + PKIX_OBJECTNOTCRLCHECKER); + + crldp = (pkix_pl_CrlDp *)object; + if (crldp->distPointType == relativeDistinguishedName) { + CERT_DestroyName(crldp->name.issuerName); + crldp->name.issuerName = NULL; + } + crldp->nssdp = NULL; +cleanup: + PKIX_RETURN(CRLCHECKER); +} + +/* + * FUNCTION: pkix_pl_CrlDp_RegisterSelf + * + * DESCRIPTION: + * Registers PKIX_CRLDP_TYPE and its related functions + * with systemClasses[] + * + * THREAD SAFETY: + * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) + * + * 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_CrlDp_RegisterSelf(void *plContext) +{ + extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; + pkix_ClassTable_Entry* entry = &systemClasses[PKIX_CRLDP_TYPE]; + + PKIX_ENTER(CRLCHECKER, "pkix_CrlDp_RegisterSelf"); + + entry->description = "CrlDistPoint"; + entry->typeObjectSize = sizeof(pkix_pl_CrlDp); + entry->destructor = pkix_pl_CrlDp_Destroy; + entry->duplicateFunction = pkix_duplicateImmutable; + + PKIX_RETURN(CRLCHECKER); +} + + + +PKIX_Error * +pkix_pl_CrlDp_Create( + const CRLDistributionPoint *dp, + const CERTName *certIssuerName, + pkix_pl_CrlDp **pPkixDP, + void *plContext) +{ + PLArenaPool *rdnArena = NULL; + CERTName *issuerNameCopy = NULL; + pkix_pl_CrlDp *dpl = NULL; + + /* Need to save the following info to update crl cache: + * - reasons if partitioned(but can not return revocation check + * success if not all crl are downloaded) + * - issuer name if different from issuer of the cert + * - url to upload a crl if needed. + * */ + PKIX_ENTER(CRLDP, "pkix_pl_CrlDp_Create"); + PKIX_NULLCHECK_ONE(dp); + + PKIX_CHECK( + PKIX_PL_Object_Alloc(PKIX_CRLDP_TYPE, + sizeof (pkix_pl_CrlDp), + (PKIX_PL_Object **)&dpl, + plContext), + PKIX_COULDNOTCREATEOBJECT); + + dpl->nssdp = dp; + dpl->isPartitionedByReasonCode = PKIX_FALSE; + if (dp->reasons.data) { + dpl->isPartitionedByReasonCode = PKIX_TRUE; + } + if (dp->distPointType == generalName) { + dpl->distPointType = generalName; + dpl->name.fullName = dp->distPoint.fullName; + } else { + SECStatus rv; + const CERTName *issuerName = NULL; + const CERTRDN *relName = &dp->distPoint.relativeName; + + if (dp->crlIssuer) { + if (dp->crlIssuer->l.next) { + /* Violate RFC 5280: in this case crlIssuer + * should have only one name and should be + * a distinguish name. */ + PKIX_ERROR(PKIX_NOTCONFORMINGCRLDP); + } + issuerName = &dp->crlIssuer->name.directoryName; + } else { + issuerName = certIssuerName; + } + rdnArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!rdnArena) { + PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); + } + issuerNameCopy = (CERTName *)PORT_ArenaZNew(rdnArena, CERTName); + if (!issuerNameCopy) { + PKIX_ERROR(PKIX_ALLOCERROR); + } + rv = CERT_CopyName(rdnArena, issuerNameCopy, (CERTName*)issuerName); + if (rv == SECFailure) { + PKIX_ERROR(PKIX_ALLOCERROR); + } + rv = CERT_AddRDN(issuerNameCopy, (CERTRDN*)relName); + if (rv == SECFailure) { + PKIX_ERROR(PKIX_ALLOCERROR); + } + dpl->distPointType = relativeDistinguishedName; + dpl->name.issuerName = issuerNameCopy; + rdnArena = NULL; + } + *pPkixDP = dpl; + dpl = NULL; + +cleanup: + if (rdnArena) { + PORT_FreeArena(rdnArena, PR_FALSE); + } + PKIX_DECREF(dpl); + + PKIX_RETURN(CRLDP); +} |