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

📄 x509inputcertificate.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: x509InputCertificate.c,v 1.17 2002/08/06 20:11:06 dallen Exp $
____________________________________________________________________________*/
/*
 *  Author: michael_elkins@nai.com
 *	Last Edit: January 11, 2000
 */

#include "x509CMS.h"
#include "pgpX509Priv.h"
#include "pgpKeyPriv.h"
#include "pkcsreq_asn.h"
#include "pkcsreq_oid.h"

/* convert hex value into integer */
#define hexval(c) (((c)>='0'&&(c)<='9')?(c)-'0':10+(c)-'A')

static PGPKeyDBObjRef
x509FindPrivateKey (
	PGPContextRef	context,
	PGPKeyDBRef		db,
	PKICONTEXT		*asncontext,
	PKISignerInfos	*si)
{
	int				i, asnerr = 0;
	PGPByte			*hashval = 0;
	PGPSize			hashlen = 0;
	PGPKeyDBObjRef	key = kInvalidPGPKeyDBObjRef;

	/* we should only have one signer */
	pgpAssert (si->n <= 1);
	if (si->n==0 || !si->elt[0])
		return NULL;
	/* find the at-pki-transaction-id authenticated attribute */
	pgpAssert (si->elt[0]->authenticatedAttributes != 0);
	if (!si->elt[0]->authenticatedAttributes)
		return NULL;
	pgpAssert (si->elt[0]->authenticatedAttributes->n > 0);
	for (i = 0; i < si->elt[0]->authenticatedAttributes->n; i++)
	{
		if (memcmp (si->elt[0]->authenticatedAttributes->elt[i]->type.val,
				PKIat_pki_transactionid_OID,
				PKIat_pki_transactionid_OID_LEN) == 0)
		{
			/* depending on the CA, this will either be an INTEGER or
			   PrintableString */

			if (*si->elt[0]->authenticatedAttributes->elt[i]->values.elt[0]->val == PKIID_PrintableString)
			{
				PKIPrintableString *ps = 0;

				PKIUnpackPrintableString (asncontext,
					&ps,
					si->elt[0]->authenticatedAttributes->elt[i]->values.elt[0]->val,
					si->elt[0]->authenticatedAttributes->elt[i]->values.elt[0]->len,
					&asnerr);

				if (asnerr == 0)
				{
					PGPSize j;

					/* convert the hex string into binary */
					hashlen = ps->len / 2;
					hashval = PGPNewData (PGPPeekContextMemoryMgr (context),
						ps->len / 2, 0);
					for (j = 0; j < hashlen; j++)
					{
						hashval[j] = (hexval(ps->val[2 * j]) << 4) | hexval(ps->val[2 * j + 1]);
					}
					PKIFreePrintableString (asncontext, ps);
				}
			}
			else
			{
				PKIINTEGER *asn;

				PKIUnpackINTEGER (asncontext, &asn,
					si->elt[0]->authenticatedAttributes->elt[i]->values.elt[0]->val,
					si->elt[0]->authenticatedAttributes->elt[i]->values.elt[0]->len,
					&asnerr);

				if (asnerr == 0)
				{
					hashval = asn->val;
					hashlen = asn->len;
					PGPFreeData (asn);
				}
			}

			break;
		}
	}

	if (hashval)
	{
		PGPFilterRef	filter = 0;
		PGPKeySetRef	keyset = 0;
		PGPKeyIterRef	iter = 0;
		PGPError		err;

		err = PGPNewKeyDBObjDataFilter (context, kPGPKeyProperty_X509MD5Hash,
			hashval, hashlen, kPGPMatchCriterion_Equal, &filter);
		if (IsPGPError (err))
			goto error;
		err = PGPFilterKeyDB (db, filter, &keyset);
		if (IsPGPError (err))
			goto error;
		err = PGPNewKeyIterFromKeySet (keyset, &iter);
		if (IsPGPError (err))
			goto error;
		err = PGPKeyIterNextKeyDBObj (iter, kPGPKeyDBObjType_Key, &key);

error:

		if (iter)
			PGPFreeKeyIter (iter);
		if (filter)
			PGPFreeFilter (filter);
		if (keyset)
			PGPFreeKeySet (keyset);

		PGPFreeData (hashval);
	}

	if( key == kInvalidPGPKeyDBObjRef)
	{
		/* If no luck, just use first key.  Caller can give us just
		 * the key that is needed when we are retrieving a cert. */
		PGPKeyIterRef	iter;
		PGPNewKeyIterFromKeyDB (db, &iter);
		PGPKeyIterNextKeyDBObj (iter, kPGPKeyDBObjType_Key, &key);
		PGPFreeKeyIter (iter);
	}

	return key;
}

static void
x509VerifyPKCS7Signatures (
	PGPContextRef	context,
	PGPKeyDBRef		keydb,			/* [IN] where to find keys */
	PKICONTEXT		*asnContext,	/* [IN] */
	PKISignedData	*sigData,		/* [IN] */
	PGPBoolean		*sigPresent,	/* [OUT] */
	PGPBoolean		*sigChecked,	/* [OUT] */
	PGPBoolean		*sigVerified,	/* [OUT] */
	PGPKeyDBObjRef	*signKey		/* [OUT] */
)
{
    X509CMSCallbackData	pgpData;
    int			p7err;
    int			asnError = 0;
    PGPError		err;
    PGPFilterRef	filter = NULL;
    PGPKeySetRef	targetKeySet = NULL;
    PGPKeyIterRef	keyIter = NULL;
    PGPKeyDBObjRef	keyRef = NULL;
    PGPByte		*isnData = NULL;
    PGPSize		isnDataLen;
    PKICertificate	*cert = NULL;
    PGPMemoryMgrRef	mem = PGPPeekContextMemoryMgr (context);

	if (!sigData || sigData->signerInfos.n < 1 || !sigData->signerInfos.elt[0])
		return; /* nothing to check */

	*sigPresent = 1;

	if (!keydb)
		return; /* Can't check without keys to check with */

	/* find certificate for this user */
	/* use the Issuer And Serial Number as a filter */
	isnDataLen = PKISizeofIssuerAndSerialNumber (asnContext,
		&sigData->signerInfos.elt[0]->issuerAndSerialNumber,
		1);
	isnData = PGPNewData (mem, isnDataLen, 0);
	PKIPackIssuerAndSerialNumber (asnContext,
		isnData,
		isnDataLen,
		&sigData->signerInfos.elt[0]->issuerAndSerialNumber,
		&asnError);
	if (asnError)
		goto error_exit;

	err = PGPNewKeyDBObjDataFilter( context, kPGPSigProperty_X509IASN, 
				isnData, isnDataLen, kPGPMatchCriterion_Equal, &filter );
	if (IsPGPError (err))
		goto error_exit;
	err = PGPFilterKeySet (pgpKeyDBPeekRootSet(keydb), filter, &targetKeySet);
	if (IsPGPError (err))
		goto error_exit;
	err = PGPNewKeyIterFromKeySet (targetKeySet, &keyIter);
	if (IsPGPError (err))
		goto error_exit;
	err = PGPKeyIterNextKeyDBObj (keyIter, kPGPKeyDBObjType_Key, &keyRef);
	if (IsPGPError (err))
		goto error_exit;

	*signKey = keyRef;

	err = x509ExtractCertificate (context,
		keyRef,
		asnContext,
		&cert);
	if (IsPGPError (err))
		goto error_exit;

	*sigChecked = 1;

	/* set up callback data */
	memset (&pgpData, 0, sizeof (pgpData));
	pgpData.context = context;
	pgpData.key = keyRef;

	/* verify signature */
	p7err = sm_VerifyMessage (NULL,	/* dont return the inner data */
		0,
		sigData,
		cert,
		pkcs7HashCallback,
		(void *) &pgpData,
		pkcs7VerifyCallback,
		(void *) &pgpData,
		asnContext);
	if (p7err == PKCS7_OK)
		*sigVerified = 1;

error_exit:

	if (keyIter)
		PGPFreeKeyIter (keyIter);
	if (targetKeySet)
		PGPFreeKeySet (targetKeySet);
	if (filter)
		PGPFreeFilter (filter);
	if (cert)
		PKIFreeCertificate (asnContext, cert);
	if (isnData)
		PGPFreeData (isnData);
}

static void
x509ExtractCertificatesFromSignedData (
	PKICONTEXT					*asnContext,
	PKISignedData				*sigData,
	PKIExtendedCertificatesAndCertificates	*certSet)
{
	int i;

	if (sigData->certificates)
	{
		for (i = 0; i < sigData->certificates->n; i++)
		{
			PKIAddOfElement(asnContext,sigData->certificates->elt[i],certSet);
			sigData->certificates->elt[i] = NULL;
		}
		/* don't free this data when free'ing sigData */
		if (sigData->certificates->n)
			PGPFreeData( sigData->certificates->elt );
		PGPFreeData (sigData->certificates);
		sigData->certificates = NULL;
	}
}

static void
x509ExtractCRLsFromSignedData (
	PKICONTEXT						*asnContext,
	PKISignedData					*sig,
	PKICertificateRevocationLists	*crls)
{
	int i;

	if (sig->crls)
	{
		for (i = 0; i < sig->crls->n; i++)
		{
			PKIAddOfElement (asnContext, sig->crls->elt[i], crls);
			sig->crls->elt[i] = NULL;
		}
		if (sig->crls->n)
			PGPFreeData (sig->crls->elt);
		PGPFreeData (sig->crls);
		sig->crls = NULL;
	}
}

static PGPError
x509ParseAsCertificate(
	PKICONTEXT *asnContext,
	/*const*/ PGPByte *input,
	PGPSize inputSize,
	PKIExtendedCertificatesAndCertificates *certSet)
{
	/* first check to see if this is a vanilla X.509 certificate */
	int asnError = 0;
	PKICertificate *cert;
	PKIExtendedCertificateOrCertificate *extended;

	PKIUnpackCertificate (asnContext, &cert, input, inputSize, &asnError);
	if(asnError)
		return kPGPError_LazyProgrammer;
	extended = PKINewExtendedCertificateOrCertificate (asnContext);
	extended->CHOICE_field_type = PKIID_Certificate;
	extended->data = (void *) cert; /* NOTE: don't free `cert' */
	PKIAddOfElement (asnContext, extended, certSet);
	return kPGPError_NoErr;
}

static PGPError
x509ParseAsCRL(
	PKICONTEXT *asnContext,
	/*const*/ PGPByte *input,
	PGPSize inputSize,
	PKICertificateRevocationLists *crls)
{
	/* check for x.509 crl */
	int asnError=0;
	PKICertificateList *crl;

	PKIUnpackCertificateList(asnContext,&crl,input,inputSize,&asnError);
	if(asnError)
		return kPGPError_LazyProgrammer;
	PKIAddOfElement (asnContext, crl, crls); /* don't free crl */
	return kPGPError_NoErr;
}

PGPError
X509InputCertificate (
	PGPContextRef	context,
	PGPByte		*input,		/* input buffer */
	PGPSize		inputSize,
	PGPKeyDBRef	keydb,		/* where to find keys */
	PGPInputFormat	format,		/* Import format (CA) */
	PGPOptionListRef    passphrase,/* Passphrase for decrypting */
	PGPKeyDBObjRef	*decryptKey,	/* Output decryption key */
	PGPKeyDBObjRef	*signKey,	/* Output signing key */
	PGPBoolean	*sigPresent,	/* output flag for signed message */
	PGPBoolean	*sigChecked,	/* output that we have sig key */
	PGPBoolean	*sigVerified,	/* output flag for sig ok */
	PGPAttributeValue	**extraData,
	PGPUInt32	*extraDataCount,
	PGPByte		**certOut,
	PGPSize		*certOutSize,
	PGPByte		**crlOut,
	PGPSize		*crlOutSize
)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -