📄 x509inputcertificate.c
字号:
{
/* The calling function expects to be returned SET OF Certificate, but
the PKCS-7 definition ExtendedCertificatesAndCertificates produces the
same encoding when no ExtendedCertificate's are present, so just use
that defintion to reduce code size */
PKIExtendedCertificatesAndCertificates *certSet = NULL;
PKICONTEXT asnContext;
PKIContentInfo *contentInfo = NULL;
PKISignedData *sigData = NULL;
PKIEnvelopedData *envData = NULL;
PKICertificateRevocationLists *crls = NULL;
PGPError err;
PGPMemoryMgrRef mem = PGPPeekContextMemoryMgr (context);
PGPByte *contentData = NULL;
PGPSize contentDataLen;
int messageType;
int asnError = 0;
(void) passphrase; /* Unused argument */
(void) format; /* Unused argument */
/* clear outputs */
*sigPresent = 0;
*sigChecked = 0;
*sigVerified = 0;
*extraData = NULL;
*extraDataCount = 0;
*decryptKey = NULL;
*signKey = NULL;
*crlOut = NULL;
*crlOutSize = 0;
memset (&asnContext, 0, sizeof (PKICONTEXT));
asnContext.memMgr = &X509CMSMemoryMgr;
asnContext.memMgr->customValue = (void *) mem;
certSet = PKINewExtendedCertificatesAndCertificates (&asnContext);
crls = PKINewCertificateRevocationLists(&asnContext);
/* first check to see if input is a plain x.509 certificate. if not, check
to see if input is a plain CRL. failing that, attempt to decode as
a PKCS-7 message */
if (x509ParseAsCertificate(&asnContext,input,inputSize,certSet)!=kPGPError_NoErr &&
x509ParseAsCRL(&asnContext,input,inputSize,crls)!=kPGPError_NoErr)
{
/* either this is not a certificate/crl or it has a bad encoding, so
try to decode it as a PKCS-7 message */
contentInfo = sm_DecodeMessage (input, inputSize, &asnContext);
if (!contentInfo)
{
/* failed to decode message */
err = kPGPError_InvalidPKCS7Encoding;
goto error_exit;
}
messageType = sm_MessageType (contentInfo, &asnContext);
if (!contentInfo->content)
{
PKIFreeContentInfo (&asnContext, contentInfo);
err = kPGPError_InvalidPKCS7Encoding;
goto error_exit;
}
/* save the internal content */
contentData = contentInfo->content->val;
contentDataLen = contentInfo->content->len;
contentInfo->content->val = NULL;
contentInfo->content->len = 0;
PGPFreeData (contentInfo->content);
contentInfo->content = NULL;
PKIFreeContentInfo (&asnContext, contentInfo);
/* remove the security enhancements */
while (messageType == PKCS7_CONTENT_SIGNED_DATA ||
messageType == PKCS7_CONTENT_ENVELOPED_DATA)
{
if (messageType == PKCS7_CONTENT_SIGNED_DATA)
{
sigData = sm_DecodeSignedData (contentData,
contentDataLen,
&asnContext);
if (!sigData)
{
err = kPGPError_InvalidPKCS7Encoding; /* parse error */
goto error_exit;
}
/* find our key based on the transaction-id in the
authenticated attributes */
if (!*decryptKey)
{
*decryptKey = x509FindPrivateKey (context, keydb,
&asnContext, &sigData->signerInfos);
}
/* check for signature. since the returned certificate is
itself signed, we don't exit upon failure during this
step */
x509VerifyPKCS7Signatures (
context,
keydb,
&asnContext,
sigData,
sigPresent,
sigChecked,
sigVerified,
signKey);
/* if there are certificates present, return them */
x509ExtractCertificatesFromSignedData (&asnContext, sigData,
certSet);
/* if there are CRLs present, return them */
x509ExtractCRLsFromSignedData (&asnContext, sigData, crls);
PGPFreeData (contentData); /* free existing data */
/* get the content data */
sm_VerifyMessage (&contentData,
&contentDataLen,
sigData,
NULL,
NULL,
NULL,
NULL,
NULL,
&asnContext);
/* peek at the internal content type */
messageType = sm_ContentType (&sigData->contentInfo.contentType, &asnContext);
PKIFreeSignedData (&asnContext, sigData);
sigData = NULL;
}
else
{
/* EnvelopedData */
X509CMSCallbackData pgpData;
pgpAssert (messageType == PKCS7_CONTENT_ENVELOPED_DATA);
envData = sm_DecodeEnvelopedData (contentData, contentDataLen,
&asnContext);
if (!envData)
{
err = kPGPError_InvalidPKCS7Encoding;
goto error_exit;
}
PGPFreeData (contentData);
contentData = 0;
memset (&pgpData, 0, sizeof (pgpData));
pgpData.passphrase = passphrase;
pgpData.context = context;
pgpData.key = *decryptKey; /* my private key */
if (sm_DecryptMessage (&contentData,
&contentDataLen,
envData,
NULL, /* use first recipient */
pkcs7DecryptCallback,
(void *) &pgpData,
&asnContext) != PKCS7_OK)
{
err = kPGPError_PKCS7DecryptFailure;
goto error_exit;
}
/* peek at the internal content type */
messageType = sm_ContentType (&envData->encryptedContentInfo.contentType,
&asnContext);
PKIFreeEnvelopedData (&asnContext, envData);
envData = NULL;
}
/* Netscape CMS 4.1 also encrypts the message, so do a quick
check to see if this look like an encrypted message. we do
this by looking to see if this looks like the beginning of
an ASN.1 SEQUENCE OF */
if (messageType == PKCS7_CONTENT_DATA &&
contentDataLen && *contentData == 0x30)
{
/* probably ASN.1 */
contentInfo = sm_DecodeMessage (contentData, contentDataLen,
&asnContext);
if (contentInfo)
{
/* yes, it really is */
/* set the correct message type */
messageType = sm_MessageType (contentInfo, &asnContext);
/* replace the current content with the interior content */
PGPFreeData (contentData);
if (contentInfo->content)
{
contentData = contentInfo->content->val;
contentDataLen = contentInfo->content->len;
/* so PKIFreeContentInfo doesn't free the memory */
PGPFreeData (contentInfo->content);
contentInfo->content = NULL;
}
else
{
contentData = NULL;
contentDataLen = 0;
}
PKIFreeContentInfo (&asnContext, contentInfo);
}
}
}
if (messageType != PKCS7_CONTENT_DATA)
{
/* unknown PKCS7 content type */
err = kPGPError_InvalidPKCS7Encoding;
goto error_exit;
}
/* if we have something from Verisign, the certificates are located
in the body of the signed message */
if (contentData)
{
PKICertRep *certRep;
/* Try to parse with VeriSign structure (extra reginfo) */
asnError = 0;
PKIUnpackCertRep (&asnContext,
&certRep,
contentData,
contentDataLen,
&asnError);
if (certRep) {
/* Verisign parse succeeded, extract contentInfo portion */
contentInfo = certRep->certs;
certRep->certs = NULL;
PKIFreeCertRep (&asnContext, certRep);
} else {
/* Try to parse as a plain CMS message */
asnError = 0;
contentInfo = sm_DecodeMessage (contentData, contentDataLen,
&asnContext);
}
if (contentInfo)
{
messageType = sm_MessageType (contentInfo, &asnContext);
if (messageType == PKCS7_CONTENT_SIGNED_DATA &&
contentInfo->content)
{
PKIUnpackSignedData (&asnContext, &sigData,
contentInfo->content->val,
contentInfo->content->len,
&asnError);
if (!asnError)
{
x509ExtractCertificatesFromSignedData (&asnContext,
sigData,
certSet);
x509ExtractCRLsFromSignedData (&asnContext, sigData,
crls);
PKIFreeSignedData (&asnContext, sigData);
sigData = NULL;
}
}
PKIFreeContentInfo (&asnContext, contentInfo);
}
}
}
asnError = 0; /* reset error code */
if (certSet->n)
{
*certOutSize = PKISizeofExtendedCertificatesAndCertificates (
&asnContext,
certSet,
1);
*certOut = PGPNewData (mem, *certOutSize, 0);
asnError = 0;
PKIPackExtendedCertificatesAndCertificates (&asnContext,
*certOut,
*certOutSize,
certSet,
&asnError);
if (asnError)
{
PGPFreeData (*certOut);
*certOut = NULL;
*certOutSize = 0;
err = kPGPError_ASNPackFailure;
goto error_exit;
}
}
if (crls->n)
{
/* if we found CRLs, pack them up now */
*crlOutSize = PKISizeofCertificateRevocationLists (&asnContext, crls, 1);
*crlOut = PGPNewData (mem, *crlOutSize, 0);
PKIPackCertificateRevocationLists (&asnContext, *crlOut, *crlOutSize, crls, &asnError);
if (asnError)
{
PGPFreeData (*crlOut);
*crlOut = NULL;
*crlOutSize = 0;
PGPFreeData (*certOut);
*certOut = NULL;
*certOutSize = 0;
err = kPGPError_ASNPackFailure;
goto error_exit;
}
}
err = kPGPError_NoErr;
error_exit:
/* certSet and crls should always have been allocated */
PKIFreeExtendedCertificatesAndCertificates (&asnContext, certSet);
PKIFreeCertificateRevocationLists(&asnContext, crls);
if (envData)
PKIFreeEnvelopedData (&asnContext, envData);
if (sigData)
PKIFreeSignedData (&asnContext, sigData);
if (contentData)
PGPFreeData (contentData);
if (passphrase)
PGPFreeOptionList (passphrase);
return err;
}
/* vim:ts=4:sw=4:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -