📄 crl.c
字号:
/****************************************************************************
*
* Copyright (c) 1998, Network Associates, Inc. and its affiliated Companies
*
****************************************************************************/
#include <time.h>
#include "tc.h"
#include "cms.h"
void tc_free_crl(TC_CertificateList *crl, TC_CONTEXT *ctx)
{
PKIFreeCertificateList(ctx->certasnctx, crl);
return;
}
/****
*
* tc_create_crl
*
* return
* 0 okay
* TC_E_INVARGS
* TC_E_NOMEMORY
* TC_E_INVDATE
*
*****/
int tc_create_crl (TC_CertificateList **crl,
const unsigned char *alg, /* alg to sign crl */
size_t algLen, /* len of `alg' */
const unsigned char *algParm,
size_t algParmLen,
TC_Name *issuer, /* crl issuer */
time_t nextUpdate, /* next crl update expected */
TC_ExtensionList *crlExts, /* CRL ext's */
TC_CONTEXT *ctx)
{
int status = 0;
PKICertificateList *localCRL = NULL;
TC_Name *localIssuer = NULL;
do {
if (crl == NULL || issuer == NULL || nextUpdate < 0) {
status = TC_E_INVARGS;
break;
}
localCRL = PKINewCertificateList(ctx->certasnctx);
if (localCRL == NULL) {
status = TC_E_NOMEMORY;
break;
}
/* set the version, if there are extensions then its v2, otherwise
leave NULL */
if (crlExts != NULL) {
localCRL->tbsCertList.version = PKINewINTEGER(ctx->certasnctx);
if (localCRL->tbsCertList.version == NULL) {
status = TC_E_NOMEMORY;
break;
}
PKIPutIntVal(ctx->certasnctx, localCRL->tbsCertList.version,
TC_X509_VERSION_2);
}
if ((status = tc_set_alg(&localCRL->tbsCertList.signature,
alg, algLen, algParm, algParmLen, ctx)) != 0)
break;
if ((status = tc_set_alg(&localCRL->signatureAlgorithm,
alg, algLen, algParm, algParmLen, ctx)) != 0)
break;
/* issuer, create a local copy first */
if ((status = CopyName(&localIssuer, issuer, ctx)) != 0)
break;
localCRL->tbsCertList.issuer.CHOICE_field_type =
localIssuer->CHOICE_field_type;
localCRL->tbsCertList.issuer.data = localIssuer->data;
/* now free just the upper level structure, free'ing the Cert will
free the rest */
TC_Free(ctx->memMgr, localIssuer);
/* this update */
localCRL->tbsCertList.thisUpdate.CHOICE_field_type =
PKIID_UTCTime;
if ((status = tc_encode_utctime (
(PKIUTCTime **)&localCRL->tbsCertList.thisUpdate.data,
time(NULL), ctx) ) != 0)
break;
/* next update */
if (nextUpdate != 0) { /* its optional */
/* the value for nextUpdate must be later than current time */
if (nextUpdate <= time(NULL)) {
status = TC_E_INVDATE;
break;
}
localCRL->tbsCertList.nextUpdate =
PKINewTime(ctx->certasnctx);
localCRL->tbsCertList.nextUpdate->CHOICE_field_type =
PKIID_UTCTime;
if ((status = tc_encode_utctime (
(PKIUTCTime **)&localCRL->tbsCertList.nextUpdate->data,
nextUpdate, ctx)) != 0)
break;
}
/* extensions */
if (crlExts != NULL) {
if ((status = CopyExtList(&localCRL->tbsCertList.crlExtensions,
crlExts, ctx)) != 0)
break;
}
else
localCRL->tbsCertList.crlExtensions = NULL;
} while (0);
if (status == 0)
*crl = localCRL;
else
*crl = NULL;
return status;
} /* tc_create_crl */
int tc_add_to_crl(
TC_CertificateList *crl, /* crl to update */
unsigned char *serialNumber, /* serial num of revoked cert */
size_t serialLength,
time_t revocationDate,
TC_ExtensionList *entryExts, /* CRL entry exts */
TC_CONTEXT *ctx)
{
PKIRevokedCertificate *revokedCert;
int crlCount;
int status;
if (crl == NULL)
return TC_E_INVARGS;
if (!crl->tbsCertList.revokedCertificates) {
crl->tbsCertList.revokedCertificates =
PKINewRevokedCertificates(ctx->certasnctx);
if (crl->tbsCertList.revokedCertificates == NULL)
return TC_E_NOMEMORY;
}
revokedCert = PKINewRevokedCertificate(ctx->certasnctx);
if (revokedCert == NULL) {
/* don't really need to free crl->tbsCertList.revokedCertificates
here since the user could try again, or there may be other
entries already on the list and we don't want the user to
have to start from scratch */
return TC_E_NOMEMORY;
}
crlCount = crl->tbsCertList.revokedCertificates->n;
crl->tbsCertList.revokedCertificates->elt[crlCount] = revokedCert;
crl->tbsCertList.revokedCertificates->n++;
/* userCertificate field */
PKIPutOctVal(ctx->certasnctx, &revokedCert->userCertificate,
serialNumber, serialLength);
/* revocationDate field */
revokedCert->revocationDate.CHOICE_field_type = PKIID_UTCTime;
status = tc_encode_utctime(
(PKIUTCTime **)&revokedCert->revocationDate.data,
revocationDate, ctx);
if (status != 0)
return status;
/* crlEntryExtensions field */
if (entryExts != NULL) {
/* first make sure the version is v2, following PKIX, if its
there assume its v2 */
if (crl->tbsCertList.version == NULL) {
crl->tbsCertList.version = PKINewINTEGER(ctx->certasnctx);
if (crl->tbsCertList.version == NULL) {
return TC_E_NOMEMORY;
}
PKIPutIntVal(ctx->certasnctx, crl->tbsCertList.version,
TC_X509_VERSION_2);
}
if ((status = CopyExtList(&revokedCert->crlEntryExtensions,
entryExts, ctx)) != 0)
return status;
}
return status;
}
/*****
*
* return
* TC_E_INVARGS
* TC_E_NOMEMORY
* TC_E_PARSE
*
*****/
static int tc_pack_tbscertlist(unsigned char **ptr,
size_t *ptrlen,
TC_CertificateList *crl,
TC_CONTEXT *ctx)
{
int error = 0;
if (!ptr || !ptrlen || !crl)
return TC_E_INVARGS;
*ptrlen = PKISizeofTBSCertList(ctx->certasnctx, &crl->tbsCertList, 1);
*ptr = TC_Alloc(ctx->memMgr, *ptrlen);
if (*ptr == NULL)
return TC_E_NOMEMORY;
(void)PKIPackTBSCertList(ctx->certasnctx,
*ptr, *ptrlen, &crl->tbsCertList, &error);
return compiler2tc_error(error);
}
int tc_pack_crl(
unsigned char **ptr,
size_t *ptrlen,
TC_CertificateList *crl,
TC_CONTEXT *ctx)
{
int error = 0;
if (!ptr || !ptrlen || !crl)
return TC_E_INVARGS;
*ptrlen = PKISizeofCertificateList (ctx->certasnctx, crl, 1);
*ptr = TC_Alloc(ctx->memMgr, *ptrlen);
if (*ptr == NULL)
return TC_E_NOMEMORY;
(void)PKIPackCertificateList (ctx->certasnctx,
*ptr, *ptrlen, crl, &error);
return compiler2tc_error(error);
}
int tc_unpack_crl(TC_CertificateList **crl, unsigned char *data,
size_t dataLen,
TC_CONTEXT *ctx)
{
int error = 0;
(void)PKIUnpackCertificateList(ctx->certasnctx,
crl, data, dataLen, &error);
if (error != 0)
return compiler2tc_error(error);
return 0;
}
/*****
*
* verify the signature over a CRL
*
* return
* 0 - okay, signature valid
* TC_E_INVARGS
* TC_E_NOTFOUND couldn't find the issuer's cert in the context
* TC_E_INVSIG
*
*****/
static int tc_verify_crl (
TC_CertificateList *crl,
TC_CONTEXT *ctx)
{
unsigned char *asnptr= NULL;
size_t asnlen;
int error = 0;
TC_CERT *issuer;
unsigned char *params;
size_t paramLen;
PKIRevokedCertificate *revdCertEntry;
PKIRevokedCertificates *revdCerts;
int i;
if (!crl || !ctx || !ctx->verify)
return TC_E_INVARGS;
do {
/* need to find the crl issuer's certificate for verification */
error = tc_find_cert (&issuer, &crl->tbsCertList.issuer, ctx);
if (error != 0)
break;
error = tc_pack_tbscertlist(&asnptr, &asnlen, crl, ctx);
if (error != 0)
break;
/* TODO: make sure the CRL's 2 sig alg OIDs agree and that the encryption
algorithm agree's with the issuer's key alg. */
/* TODO: deal with finding the parameters, for now assuming they are
in the issuer's subjectPublicKeyInfo */
if (issuer->tbsCertificate->subjectPublicKeyInfo.algorithm.parameters != NULL) {
params = issuer->tbsCertificate->subjectPublicKeyInfo.algorithm.parameters->val;
paramLen = issuer->tbsCertificate->subjectPublicKeyInfo.algorithm.parameters->len;
}
else {
params = NULL;
paramLen = 0;
}
error = ctx->verify(
asnptr, asnlen,
crl->signatureAlgorithm.algorithm.val,
crl->signatureAlgorithm.algorithm.len,
params, paramLen,
crl->signature.val,
crl->signature.len,
issuer->tbsCertificate->subjectPublicKeyInfo.subjectPublicKey.val,
issuer->tbsCertificate->subjectPublicKeyInfo.subjectPublicKey.len,
issuer,
ctx->verfuncdata,
ctx);
if (error != 0) {
error = TC_E_INVSIG;
break;
}
/* check for unhandled CRL extensions */
if ((error = tc_process_extensions(crl->tbsCertList.crlExtensions,
crl, ctx)) != 0)
break;
revdCerts = crl->tbsCertList.revokedCertificates;
if (revdCerts == NULL)
break; /* no revd certs in this crl */
/* check for unhandled crlEntry extensions */
for (i = 0; i < revdCerts->n; i++) {
revdCertEntry = revdCerts->elt[i];
error = tc_process_extensions(revdCertEntry->crlEntryExtensions,
crl, ctx);
if (error != 0)
break;
}
/* note, break in 'for' above will end up here, if new code is added
here, need to add (error != 0) check... */
} while (0);
if (asnptr != NULL)
TC_Free(ctx->memMgr, asnptr);
return error;
}
/*****
*
* return
* 0 - okay
* TC_E_INVARGS
* TC_E_PARSE
*
*****/
int tc_import_crl (unsigned char *crlData,
size_t crlDataLen,
TC_CONTEXT *ctx,
int flags)
{
int status = 0;
TC_CertificateList *crl;
if (ctx == NULL || crlData == NULL || crlDataLen == 0)
return TC_E_INVARGS;
if ((status = tc_unpack_crl(&crl, crlData, crlDataLen, ctx)) != 0) {
return status;
}
/* note: do not free crl on success since it's pointer is copied into the
context... */
status = tc_add_crl(crl, ctx, flags);
if (status != 0)
tc_free_crl(crl, ctx);
return (status);
}
/*****
*
* return
* TC_E_INVARGS
* TC_E_NOMEMORY
* TC_E_PARSE
* TC_E_SIGNFAIL
*
*****/
int tc_sign_crl (TC_CertificateList *crl,
TC_CONTEXT *ctx)
{
int r = 0;
unsigned char *ptr;
size_t ptrlen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -