📄 x509createcertificaterequest.c
字号:
static PGPError
x509CRSToPGPError (int err)
{
switch (err)
{
case VRI_E_MISSING_MANDATORY:
return kPGPError_CRSMissingRequiredAttribute;
case VRI_E_INVALID_CHAR:
return kPGPError_CRSInvalidCharacter;
case VRI_E_AVA_TYPE:
return kPGPError_CRSInvalidAttributeType;
case VRI_E_CERT_TYPE:
return kPGPError_CRSInvalidCertType;
case VRI_E_LENGTH:
return kPGPError_CRSInvalidAttributeValueLength;
case VRI_E_AUTHENTICATE:
return kPGPError_CRSInvalidAuthenticateValue;
default:
return kPGPError_LazyProgrammer;
}
}
#if 1
const PGPByte x509TestNameOid[] = { 0x2a, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };
#define x509TestNameOidLen 8
#endif
static PGPError
x509AddGeneralName (
PKICONTEXT *pki, /* [IN] */
PGPByte tag, /* [IN] */
const PGPByte *data, /* [IN] */
PGPSize datasize, /* [IN] */
PKIGeneralNames *gn) /* [OUT] */
{
PKIAnotherName *on = NULL;
gn->elt[gn->n] = PKINewGeneralName (pki);
gn->elt[gn->n]->CHOICE_field_type = 0xA0 | tag;
if (tag == 0)
{
on = PKINewAnotherName (pki);
PKIPutOctVal (pki, &on->type_id, x509TestNameOid, x509TestNameOidLen);
PKIPutOctVal (pki, &on->value, data, datasize);
gn->elt[gn->n]->data = (void *) on;
}
else
{
PKIOCTET_STRING *os=PKINewOCTET_STRING(pki);
PKIPutOctVal(pki,os,data,datasize);
gn->elt[gn->n]->data = (void *) os;
}
gn->n++;
return kPGPError_NoErr;
}
static PGPError
x509AddExtensionReq (
PGPAttributeValue *format,/* [IN] */
PGPSize formatcount, /* [IN] */
TC_CONTEXT *ctx, /* [IN] */
TC_Attributes *attr) /* [OUT] */
{
int asnerr = 0;
PGPSize n;
PGPError err;
PGPByte *der = NULL;
PGPSize dersize;
PKIExtensions *ext=NULL;
PKICONTEXT *pki = ctx->certasnctx;
PKIGeneralNames *gn = PKINewGeneralNames (pki);
ext = PKINewExtensions (pki);
/* see if RFC822Name, DNSName, IPAddress or AnotherName are specified */
for (n = 0; n < formatcount; n++)
{
/* skip empty fields since they are not valid in ASN.1 */
if (format[n].size > 0)
{
if (format[n].attribute == kPGPAVAttribute_RFC822Name)
x509AddGeneralName (pki, 1, format[n].value.pointervalue,
format[n].size, gn);
else if (format[n].attribute == kPGPAVAttribute_DNSName)
x509AddGeneralName (pki, 2, format[n].value.pointervalue,
format[n].size, gn);
#if 0 /* TODO: not finished */
else if (format[n].attribute == kPGPAVAttribute_AnotherName)
x509AddGeneralName (pki, 0, format[n].value.pointervalue,
format[n].size, gn);
#endif
else if (format[n].attribute == kPGPAVAttribute_IPAddress)
x509AddGeneralName (pki, 7, format[n].value.pointervalue,
format[n].size, gn);
else if (format[n].attribute == kPGPAVAttribute_CertificateExtension)
{
PKIExtension *t;
PKIUnpackExtension (pki, &t, format[n].value.pointervalue,
format[n].size, &asnerr);
if (asnerr)
{
err = kPGPError_InvalidCertificateExtension;
goto ERROR;
}
ext->elt[ext->n] = t;
ext->n++;
}
}
}
if (gn->n)
{
dersize = PKISizeofGeneralNames (pki, gn, TRUE);
der = PKIAlloc (pki->memMgr, dersize);
if (!der)
{
err = kPGPError_OutOfMemory;
goto ERROR;
}
PKIPackGeneralNames (pki, der, dersize, gn, &asnerr);
if (asnerr)
{
err = kPGPError_ASNPackFailure;
goto ERROR;
}
ext->elt[ext->n] = PKINewExtension (pki);
PKIPutOctVal (pki, &ext->elt[ext->n]->extnID,
PKIid_ce_subjectAltName_OID, PKIid_ce_subjectAltName_OID_LEN);
ext->elt[ext->n]->extnValue.val = der;
ext->elt[ext->n]->extnValue.len = dersize;
ext->n++;
}
if (ext->n)
{
dersize = PKISizeofExtensions (pki, ext, TRUE);
der = PKIAlloc (pki->memMgr, dersize);
if (!der)
{
err = kPGPError_OutOfMemory;
goto ERROR;
}
PKIPackExtensions (pki, der, dersize, ext, &asnerr);
if (asnerr)
{
err = kPGPError_ASNPackFailure;
goto ERROR;
}
asnerr = tc_add_attribute (attr,
PKIid_ce_rsaExtensions_OID,
PKIid_ce_rsaExtensions_OID_LEN,
der,
dersize,
ctx);
if (asnerr)
{
err = kPGPError_LazyProgrammer;
goto ERROR;
}
}
err = kPGPError_NoErr;
ERROR:
if (gn)
PKIFreeGeneralNames (ctx->certasnctx,gn);
if (ext)
PKIFreeExtensions (pki,ext);
if (der)
PGPFreeData (der);
return err;
}
PGPError x509CreateSubjectPublicKeyInfo (
PGPKeyRef keyref,
PKICONTEXT *asnContext,
X509SubjectPublicKeyInfo *info)
{
PGPError err;
PGPInt32 keyAlgID;
PGPMemoryMgrRef mem = PGPGetContextMemoryMgr (PGPGetKeyContext (keyref));
const PGPByte rsaparm[2] = { 0x05, 0x00 };
memset (info, 0, sizeof (X509SubjectPublicKeyInfo));
/* determine which type of key we have */
err = PGPGetKeyNumber (keyref, kPGPKeyPropAlgID, &keyAlgID);
if (IsPGPError (err))
return err;
/* format the key and any parameters for PKCS-10 */
if (keyAlgID == kPGPPublicKeyAlgorithm_DSA)
{
err = x509FormatDSAKey (mem,
asnContext,
keyref,
&info->keyData,
&info->keyDataSize,
&info->keyParm,
&info->keyParmSize);
info->keyAlg = TC_ALG_DSA;
info->keyAlgSize = TC_ALG_DSA_LEN;
info->sigAlg = TC_ALG_DSA_SHA1;
info->sigAlgSize = TC_ALG_DSA_SHA1_LEN;
}
else if (keyAlgID == kPGPPublicKeyAlgorithm_RSA ||
keyAlgID == kPGPPublicKeyAlgorithm_RSAEncryptOnly ||
keyAlgID == kPGPPublicKeyAlgorithm_RSASignOnly)
{
err = x509FormatRSAKey (mem,
asnContext,
keyref,
&info->keyData,
&info->keyDataSize,
&info->keyParm,
&info->keyParmSize);
info->keyAlg = TC_ALG_RSA;
info->keyAlgSize = TC_ALG_RSA_LEN;
info->sigAlg = TC_ALG_RSA_MD5;
info->sigAlgSize = TC_ALG_RSA_MD5_LEN;
info->sigParmSize = sizeof rsaparm;
info->sigParm = PGPNewData (mem, info->sigParmSize, 0);
memcpy (info->sigParm, rsaparm, info->sigParmSize);
}
else
{
/* we don't support whatever type of key this is */
err = kPGPError_UnknownPublicKeyAlgorithm;
}
return err;
}
void
x509FreeSubjectPublicKeyInfo (X509SubjectPublicKeyInfo *info)
{
if (info->keyData)
PGPFreeData (info->keyData);
if (info->keyParm)
PGPFreeData (info->keyParm);
if (info->sigParm)
PGPFreeData (info->sigParm);
}
/* Create the payload */
PGPError
X509CreateCertificateRequest (
PGPContextRef context,
PGPKeyRef keyref, /* Key to export */
PGPExportFormat format, /* Export format (CA) */
PGPAttributeValue *formatData, /* Formatting data */
PGPUInt32 formatDataCount,
PGPOptionListRef passphrase, /* Passphrase if signing */
PGPByte **certReq, /* Output buffer */
PGPSize *certReqSize /* Output buffer size */
)
{
TC_CONTEXT *tcContext;
PKICONTEXT asnContext;
TC_CertificationRequest *certRequest = NULL;
TC_Name *subjectName = NULL;
PGPMemoryMgrRef mem = PGPGetContextMemoryMgr (context);
X509CMSCallbackData callbackData;
char *dnString = NULL;
int tcError;
PGPError err;
X509SubjectPublicKeyInfo spki;
TC_Attributes *attr = NULL;
char *reginfo = NULL;
/* clear outputs */
*certReq = NULL;
*certReqSize = 0;
/* initialize callback data */
memset (&callbackData, 0, sizeof (callbackData));
callbackData.passphrase = passphrase;
callbackData.context = context;
callbackData.key = keyref;
/* initialize ASN.1 compiler */
memset (&asnContext, 0, sizeof (asnContext));
asnContext.memMgr = &X509CMSMemoryMgr;
asnContext.memMgr->customValue = (void *) mem;
memset (&spki, 0, sizeof spki);
/* initialize CMS */
tcError = tc_init_context (&tcContext,
asnContext.memMgr,
x509CMSSignCallback,
&callbackData,
NULL,
NULL);
if (tcError)
return kPGPError_CMSInitialization;
/* convert AVA array into printable string suitable for input to CMS */
err = x509CreateDistinguishedName (mem,
format,
formatData,
formatDataCount,
&dnString);
if (IsPGPError (err))
goto error;
tcError = tc_create_dname (&subjectName, tcContext);
if (tcError)
{
err = kPGPError_LazyProgrammer;
goto error;
}
tcError = tc_make_dname_fromstring (subjectName, dnString, tcContext);
PGPFreeData (dnString);
if (tcError)
{
err = kPGPError_InvalidDistinguishedName;
goto error;
}
err = x509CreateSubjectPublicKeyInfo (keyref, &asnContext, &spki);
if (IsPGPError (err))
goto error;
/* some CAs will barf on pkcs-10 with no attributes, so add a signing-time
to ensure we have at least one present */
tcError = tc_create_attrlist (&attr, tcContext);
tcError = tc_set_signing_time (attr, tcContext);
/* determine if we need to add the ExtensionReq attribute */
err = x509AddExtensionReq (formatData, formatDataCount, tcContext, attr);
if (IsPGPError (err))
goto error;
tcError = tc_create_request (&certRequest,
0, /* pkcs-10 1.5 requires version number 0 */
spki.sigAlg,
spki.sigAlgSize,
spki.sigParm,
spki.sigParmSize,
subjectName,
spki.keyAlg,
spki.keyAlgSize,
spki.keyData, /* public key material */
spki.keyDataSize,
spki.keyParm, /* key parameters.*/
spki.keyParmSize,
attr, /* attributes */
tcContext);
if (tcError)
{
/* TODO: should this return a finer grain of error code? */
err = kPGPError_CertRequestCreationFailure;
goto error;
}
tcError = tc_pack_request (certReq, certReqSize, certRequest, tcContext);
if (tcError)
{
err = kPGPError_CertRequestCreationFailure;
goto error;
}
/* since we could have more than one crypto operation, the callbacks
make a copy of this, so free the master copy now */
PGPFreeOptionList (passphrase);
/* create CRS wrapper */
if (format == kPGPExportFormat_VerisignV1_CertReq) /* jason */
{
vri_ava_t *av;
int certType = -1;
size_t i;
/* determine what type of certificate we are requesting */
for (i = 0; i < formatDataCount; i++)
if (formatData[i].attribute == kPGPAVAttribute_CertType)
{
if (!strncmp ((char *) formatData[i].value.pointervalue, "end-user",
formatData[i].size))
certType = VRI_CERT_PERSONAL;
else if (!strncmp ((char *) formatData[i].value.pointervalue, "ipsec",
formatData[i].size))
certType = VRI_CERT_IPSEC;
else if (!strncmp ((char *) formatData[i].value.pointervalue, "server",
formatData[i].size))
certType = VRI_CERT_SECURE_SERVER;
break;
}
if (certType == -1)
{
/* missing or bad cert_type */
err = kPGPError_CRSInvalidCertType;
goto error;
}
x509CompileRegInfo (&asnContext, formatData, formatDataCount, &av);
tcError = vri_GenerateRegInfo (&asnContext,
VRI_ENTITY_EE,
certType,
av,
®info);
PGPFreeData (av);
if (tcError)
{
err = x509CRSToPGPError (tcError);
goto error;
}
}
if (format == kPGPExportFormat_VerisignV1_CertReq ||
format == kPGPExportFormat_EntrustV1_CertReq) /* jason */
{
PGPByte *p10 = *certReq;
PGPSize p10len = *certReqSize;
tcError = vri_GeneratePKCSReq (&asnContext,
p10,
p10len,
reginfo,
certReq,
certReqSize);
if (reginfo)
PGPFreeData (reginfo);
PGPFreeData (p10);
if (tcError)
{
err = kPGPError_LazyProgrammer;
goto error;
}
}
err = kPGPError_NoErr;
error:
x509FreeSubjectPublicKeyInfo (&spki);
if (certRequest)
tc_free_request (certRequest, tcContext);
if (subjectName)
tc_free_dname (subjectName, tcContext);
if (attr)
tc_free_attrlist (attr, tcContext);
if (tcContext)
tc_free_context (tcContext);
if (IsPGPError (err))
{
if (*certReq)
{
PGPFreeData(*certReq);
*certReq=NULL;
}
*certReqSize = 0;
}
return err;
}
/* Create a distinguished name buffer */
PGPError
X509CreateDistinguishedName (
PGPContextRef context,
char const *str, /* LDAP format string */
PGPByte **dname, /* Output buffer */
PGPSize *dnamesize /* Output buffer size */
)
{
TC_CONTEXT *tcContext = NULL;
PKICONTEXT asnContext;
PKIName *name = NULL;
PGPMemoryMgrRef mem = PGPGetContextMemoryMgr (context);
PGPError err = kPGPError_NoErr;
*dname = NULL;
/* initialize ASN.1 compiler */
memset (&asnContext, 0, sizeof (asnContext));
asnContext.memMgr = &X509CMSMemoryMgr;
asnContext.memMgr->customValue = (void *) mem;
/* initialize CMS */
err = tc_init_context (&tcContext,
asnContext.memMgr,
NULL,
NULL,
NULL,
NULL);
if (err)
return kPGPError_CMSInitialization;
err = tc_create_dname (&name, tcContext);
if (err)
{
err = kPGPError_LazyProgrammer;
goto error;
}
err = tc_make_dname_fromstring (name, str, tcContext);
if (err)
{
err = kPGPError_InvalidDistinguishedName;
goto error;
}
*dnamesize = PKISizeofName (&asnContext, name, 1);
*dname = PKIAlloc (asnContext.memMgr, *dnamesize);
if( *dname == NULL )
{
err = kPGPError_OutOfMemory;
goto error;
}
PKIPackName (&asnContext, *dname, *dnamesize, name, &err);
PKIFreeName (&asnContext, name);
name = NULL;
if (err)
{
err = kPGPError_InvalidDistinguishedName;
goto error;
}
error:
if (name)
PKIFreeName (&asnContext, name);
if (tcContext)
tc_free_context (tcContext);
if (IsPGPError (err))
{
if (*dname)
{
PGPFreeData(*dname);
*dname=NULL;
}
*dnamesize = 0;
}
return err;
}
/* vim:ts=4:sw=4:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -