📄 x509packagecertificaterequest.c
字号:
memset (&pgpData, 0, sizeof (pgpData));
pgpData.passphrase = passphrase;
pgpData.context = context;
memset (&asnContext, 0, sizeof (PKICONTEXT));
asnContext.memMgr = &X509CMSMemoryMgr;
asnContext.memMgr->customValue = mem;
/* if encryption is requested, we do it BEFORE signing per the
CRS/CEP spec */
/* NOTE: the Netscape CA requires us to generate an EnvelopedData
object encapsulated inside of a ContentInfo, which is then
labeled as Data and put inside a SignedData object. This is
different from what you would normally do with PKCS-7. Apparently
Cisco shipped an early product that did it this way and to be
backwards compatible they never changed it to do it the correct
way. So we have to make sure not to label the EnvelopedData
as nested, and always use Data as the internal content type for
the outer SignedData object
-michael 11/24/99 */
if (encryptTo)
{
PGPByte *cert;
PGPSize certLength;
EncryptRecipient recipEntry;
List recipientCertificates;
/* since only Netscape requires encryption, we hard code the
the algorithm here */
const char *encryptAlgString = SM_OID_ALG_DES; /* DES-CBC */
memset (&recipientCertificates, 0, sizeof (List));
recipientCertificates.data = (void *) &recipEntry;
memset (&recipEntry, 0, sizeof (recipEntry));
recipEntry.data = (void *) encryptTo;
/* get the certificate associated with this key */
err = PGPExport (context,
PGPOExportKeyDBObj (context, encryptTo),
PGPOAllocatedOutputBuffer (context, (void **) &cert, 4096, &certLength),
PGPOExportFormat (pgpData.context, kPGPExportFormat_X509Cert),
PGPOLastOption (pgpData.context));
if (IsPGPError (err))
goto error_exit;
PKIUnpackCertificate (&asnContext, &recipEntry.certificate,
cert, certLength, &asnError);
PGPFreeData (cert);
if (asnError)
{
/* unable to unpack certificate */
err = kPGPError_X509CertificateParseError;
goto error_exit;
}
result = sm_EncryptMessage (certReqOut,
certReqOutSize,
certReqIn,
certReqInSize,
0, /* not nested, generate a envelopedData with ContentInfo */
SM_OID_CONTENT_DATA,
encryptAlgString,
&recipientCertificates,
pkcs7EncryptCallback,
(void *) &pgpData,
&asnContext);
PKIFreeCertificate (&asnContext, recipEntry.certificate);
if (result != PKCS7_OK)
{
err = kPGPError_PKCS7EncryptFailure;
goto error_exit;
}
inputData = *certReqOut;
inputDataSize = *certReqOutSize;
}
/* we always require a signature */
pgpAssert (signWith != 0);
if (signWith)
{
/* algs hard hardcoded for now */
const char *digestAlgString;
const char *signatureAlgString;
PGPInt32 keyAlgID;
char rsaSigParam[2] = { 0x05, 0x00 };
char *sigParam = NULL;
size_t sigParamSize = 0;
char md5param[2] = { 0x05, 0x00 };
char *digestParam = NULL;
size_t digestParamSize = 0;
PKIINTEGER *type;
PKIOCTET_STRING *nonce;
PGPByte *val;
PGPSize i, len;
pgpData.key = signWith;
/* determine pub key algorithm */
err = PGPGetKeyDBObjNumericProperty (signWith, kPGPKeyProperty_AlgorithmID, &keyAlgID);
if (IsPGPError (err))
goto error_exit;
switch (keyAlgID)
{
case kPGPPublicKeyAlgorithm_DSA:
digestAlgString = SM_OID_ALG_SHA;
signatureAlgString = SM_OID_ALG_DSA;
break;
case kPGPPublicKeyAlgorithm_RSA:
case kPGPPublicKeyAlgorithm_RSASignOnly:
case kPGPPublicKeyAlgorithm_RSAEncryptOnly:
digestAlgString = SM_OID_ALG_MD5;
signatureAlgString = SM_OID_ALG_RSA;
/* VeriSign requires the parameters for the digestAlg
and sigAlg to be explicitly encoded as ASN.1 NULL
rather than be omitted */
sigParam = rsaSigParam;
sigParamSize = sizeof rsaSigParam;
digestParam = md5param;
digestParamSize = sizeof md5param;
break;
default:
err = kPGPError_UnknownPublicKeyAlgorithm;
goto error_exit;
}
/* no certificate for this key, assume we need to generate
a temporary self-signed certificate for this message,
as prescribed by the VeriSign CRS specification */
/* if this is a PKCSReq message, use the information in the
PKCS-10 request as the basis for the DN for the self-signed
cert. otherwise generate a simple certificate. */
err = x509CreateSelfSignedCertificate (signWith,
&asnContext,
&pgpData,
isCertReq ? certReqIn : NULL,
isCertReq ? certReqInSize : 0,
format,
&sigCert);
if (IsPGPError (err))
goto error_exit;
pgpAssert (sigCert != 0);
if( sigCert )
{
includeCerts = PGPNewData (mem, sizeof (List),
kPGPMemoryMgrFlags_Clear);
if (!includeCerts)
{
err = kPGPError_OutOfMemory;
goto error_exit;
}
includeCerts->data = (void *) sigCert;
}
/* ----- begin building up the pkcs-7 message ----- */
attr = PKINewAttributes (&asnContext);
/* add the message-type attribute */
type = PKINewINTEGER (&asnContext);
if (isCertReq)
msgtype = 19;
else if (isGetCertInitial)
msgtype = 20;
else
msgtype = 22; /* GetCRL */
/* Entrust and Netscape use PrintableString, others use INTEGER */
if (isEntrust || isNetscape || isMicrosoft)
{
char str[3];
i=0;
if(msgtype>10)
str[i++]=msgtype/10+'0';
str[i++]=msgtype%10+'0';
str[i]=0;
PKIPutStrVal(&asnContext, type, str);
len=PKISizeofPrintableString(&asnContext, type, 1);
val=PGPNewData(mem,len,0);
if(!val) {
err=kPGPError_OutOfMemory;
goto error_exit;
}
PKIPackPrintableString(&asnContext, val, len, type, &asnError);
PKIFreePrintableString(&asnContext, type);
} else {
PKIPutIntVal (&asnContext, type, msgtype);
len = PKISizeofINTEGER (&asnContext, type, 1);
val = PGPNewData (mem, len, 0);
PKIPackINTEGER (&asnContext, val, len, type, &asnError);
PKIFreeINTEGER (&asnContext, type);
}
if (asnError)
err = kPGPError_ASNPackFailure;
if (IsPGPError (err)) {
PGPFreeData (val);
goto error_exit;
}
err = x509AddAuthAttribute (&asnContext,
PKIat_pki_message_type_OID,
PKIat_pki_message_type_OID_LEN,
val,
len,
attr);
PGPFreeData (val);
if (IsPGPError (err))
goto error_exit;
/* add the sendernonce attribute */
nonce = PKINewOCTET_STRING (&asnContext);
nonce->len = 16;
nonce->val = PGPNewData (mem, nonce->len, 0);
err = PGPContextGetRandomBytes (context,
nonce->val,
nonce->len);
if (IsPGPError (err))
{
PKIFreeOCTET_STRING (&asnContext, nonce);
goto error_exit;
}
len = PKISizeofOCTET_STRING (&asnContext, nonce, 1);
val = PGPNewData (mem, len, 0);
PKIPackOCTET_STRING (&asnContext, val, len, nonce, &asnError);
PKIFreeOCTET_STRING (&asnContext, nonce);
if (!asnError)
err = x509AddAuthAttribute (&asnContext,
PKIat_pki_sendernonce_OID,
PKIat_pki_sendernonce_OID_LEN,
val,
len,
attr);
else
err = kPGPError_ASNPackFailure;
PGPFreeData (val);
if (IsPGPError (err))
goto error_exit;
/* add the transactionid attribute */
if( transIDSize > 0 )
{
/* User caller-supplied transaction ID */
val = transIDIn;
len = transIDSize;
} else {
/* Calculate trans ID as hash of public key */
err = x509HashPublicKey (context, &asnContext,
&sigCert->tbsCertificate.subjectPublicKeyInfo,
&val,
&len);
if (IsPGPError (err))
goto error_exit;
}
type = PKINewINTEGER (&asnContext);
/* Entrust and Netscape use PrintableString, others use INTEGER */
if (isEntrust || isNetscape || isMicrosoft)
{
#if 1
type->len=len*2;
type->val=PGPNewData(mem, type->len + 1, 0);
for(i=0;(unsigned)i<len;i++)
sprintf((char *)(type->val + (2 * i)), "%2.2X", (unsigned int) val[i]);
#else
/* fake transaction id for testing purposes */
type->len = 2;
type->val = PGPNewData (mem, type->len, 0);
memcpy (type->val, "42", type->len);
#endif
if( transIDSize == 0 )
PGPFreeData (val);
len = PKISizeofPrintableString (&asnContext, type, 1);
val = PGPNewData (mem, len, 0);
PKIPackPrintableString (&asnContext, val, len, type, &asnError);
PKIFreePrintableString (&asnContext, type);
}
else
{
PKIPutUIntBytes (&asnContext, type, val, len);
if( transIDSize == 0 )
PGPFreeData (val);
len = PKISizeofINTEGER (&asnContext, type, 1);
val = PGPNewData (mem, len, 0);
PKIPackINTEGER (&asnContext, val, len, type, &asnError);
PKIFreeINTEGER (&asnContext, type);
}
if (asnError)
err = kPGPError_ASNPackFailure;
if (IsPGPError (err)) {
PGPFreeData (val);
goto error_exit;
}
err = x509AddAuthAttribute (&asnContext,
PKIat_pki_transactionid_OID,
PKIat_pki_transactionid_OID_LEN,
val,
len,
attr);
PGPFreeData (val);
if (IsPGPError (err))
goto error_exit;
result = sm_SignMessage (certReqOut,
certReqOutSize,
inputData,
inputDataSize,
0, /* not nested, outer content type */
SM_OID_CONTENT_DATA, /* always Data, even when encrypting (see comment above */
digestAlgString,
(uchar *) digestParam,
digestParamSize,
signatureAlgString,
(uchar *) sigParam,
sigParamSize,
sigCert,
attr, /* signed attributes */
includeCerts, /* certs to include in PKCS7 message */
pkcs7HashCallback,
(void *) &pgpData,
pkcs7SignCallback,
(void *) &pgpData,
&asnContext);
if (result != PKCS7_OK)
{
err = kPGPError_PKCS7SignFailure;
goto error_exit;
}
}
}
else if (format == kPGPOutputFormat_NetToolsCAV1_CertReqInPKCS7) /* jason: what if we ever want */
{ /* to create a real PKCS7 cert? */
/* no extra encoding required, just return what we were given */
*certReqOutSize = certReqInSize;
*certReqOut = PGPNewData (PGPPeekContextMemoryMgr (context),
*certReqOutSize,
0);
memcpy (*certReqOut, certReqIn, *certReqOutSize);
}
else
return kPGPError_InvalidOutputFormat;
err = kPGPError_NoErr;
error_exit:
if (attr)
PKIFreeAttributes (&asnContext, attr);
if (sigCert)
PKIFreeCertificate (&asnContext, sigCert);
if (includeCerts)
PGPFreeData (includeCerts);
if (inputData != certReqIn)
{
/* free intermediate data */
PKIFree (asnContext.memMgr, inputData);
}
if (IsPGPError (err))
{
/* clean up allocated data on failure */
if (*certReqOut)
{
if( *certReqOut != inputData )
PGPFreeData (*certReqOut);
*certReqOut = NULL;
*certReqOutSize = 0;
}
}
/* callback functions just make a copy of this since we could possible
use it more than once, so free the master copy */
PGPFreeOptionList (passphrase);
return (err); /* success */
}
/* vim:ts=4:sw=4:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -