blob: 4f29de2849bd897f6310fe7f40e7573bbf3b1cae [file] [log] [blame]
/* 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);
}