⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crl.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
 *
 * 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 + -