📄 x509createcertificaterequest.c
字号:
/* Copyright (C) 1998-9 Network Associates, Inc.
Author: Michael_Elkins@NAI.com
Last Edit: May 13, 1999 */
#include "x509CMS.h"
#include "reginfo.h"
#include "pgpX509Priv.h"
#include "cert_oid.h"
/* pkcs-9 14 */
static PGPByte PKIid_ce_rsaExtensions_OID[] = {
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e
};
#define PKIid_ce_rsaExtensions_OID_LEN 9
/* returns the number of bytes required for the encoded version of the
DN string */
static PGPSize
x509EncodedStringLength (const char *s, PGPSize slen)
{
PGPSize bytes = 0;
for (; slen > 0; s++, slen--, bytes++)
{
if (*s == '=' || *s == '\\' || *s == ',' || *s == '+')
bytes++;
}
return (bytes);
}
/* encode a DN string for input to CMS. assumes that the caller has allocated
enough space to encode the string using the x509EncodedStringLength()
function */
static PGPError
x509EncodeString (const char *src, PGPSize srclen, char *dest)
{
for (; srclen > 0; src++, dest++, srclen--)
{
if (*src == '=' || *src == '\\' || *src == ',' || *src == '+')
*dest++ = '\\';
*dest = *src;
}
*dest = 0;
return kPGPError_NoErr;
}
enum {
kPGPPersonalAttr_CommonName,
kPGPPersonalAttr_SerialNumber,
kPGPPersonalAttr_Description
};
static PGPError
x509AppendDNAttribute(
PGPMemoryMgrRef mem,
const char *sep,
const char *type,
const char *val,
PGPSize valsize,
char **dn,
PGPSize *dnsize)
{
*dnsize += strlen(type) + 2 + x509EncodedStringLength(val,valsize);
PGPReallocData(mem, (void **)dn, *dnsize, kPGPMemoryMgrFlags_Clear);
strcat(*dn, type);
strcat(*dn, "=");
x509EncodeString(val,valsize,*dn+strlen(*dn));
strcat(*dn, sep);
return kPGPError_NoErr;
}
static PGPError
x509CreateDistinguishedName (
PGPMemoryMgrRef mem,
PGPExportFormat caType,
PGPAttributeValue *formatData,
PGPUInt32 formatDataCount,
char **dnString)
{
const char *dnType = NULL;
PGPSize bytesNeeded = 1; /* 1 for nul char */
PGPSize i, j;
char *p;
/* used when processing Entrust DN's */
const char *personaltype[3] = { "CN", "SerialNumber", "description" };
char *personal[3] = { NULL, NULL, NULL };
size_t personalsizes[3] = { 0, 0, 0 };
for(i = 0; i < formatDataCount; i++)
{
switch(formatData[i].attribute)
{
case kPGPAVAttribute_CommonName:
if(caType==kPGPExportFormat_EntrustV1_CertReq) /* jason */
{
personal[kPGPPersonalAttr_CommonName]=formatData[i].value.pointervalue;
personalsizes[kPGPPersonalAttr_CommonName]=formatData[i].size;
dnType=NULL;
}
else
dnType = "CN";
break;
case kPGPAVAttribute_Email:
dnType = "emailAddress";
/* do a check to make sure we don't also have "embed_email=no"
for the reginfo field */
for (j = 0; j < formatDataCount; j++)
{
if (formatData[j].attribute == kPGPAVAttribute_EmbedEmail)
{
if (!formatData[j].value.booleanvalue)
dnType = NULL; /* don't include it */
break;
}
}
break;
case kPGPAVAttribute_OrganizationName:
dnType = "O";
break;
case kPGPAVAttribute_OrganizationalUnitName:
dnType = "OU";
break;
case kPGPAVAttribute_SurName:
dnType = "SN";
break;
case kPGPAVAttribute_SerialNumber:
if(caType==kPGPExportFormat_EntrustV1_CertReq) /* jason */
{
personal[kPGPPersonalAttr_SerialNumber]=formatData[i].value.pointervalue;
personalsizes[kPGPPersonalAttr_SerialNumber]=formatData[i].size;
dnType=NULL;
}
else
dnType = "SerialNumber";
break;
case kPGPAVAttribute_Country:
dnType = "C";
break;
case kPGPAVAttribute_Locality:
dnType = "L";
break;
case kPGPAVAttribute_State:
dnType = "ST";
break;
case kPGPAVAttribute_StreetAddress:
dnType = "STREET";
break;
case kPGPAVAttribute_Title:
dnType = "title";
break;
case kPGPAVAttribute_Description:
if(caType==kPGPExportFormat_EntrustV1_CertReq) /* jason */
{
personal[kPGPPersonalAttr_Description]=formatData[i].value.pointervalue;
personalsizes[kPGPPersonalAttr_Description]=formatData[i].size;
dnType=NULL;
}
else
dnType = "description";
break;
case kPGPAVAttribute_PostalCode:
dnType = "postalCode";
break;
case kPGPAVAttribute_POBOX:
dnType = "POBOX";
break;
case kPGPAVAttribute_PhysicalDeliveryOfficeName:
dnType = "physicalDeliveryOfficeName";
break;
case kPGPAVAttribute_TelephoneNumber:
dnType = "TN";
break;
case kPGPAVAttribute_X121Address:
dnType = "x121Adress";
break;
case kPGPAVAttribute_ISDN:
dnType = "ISDN";
break;
case kPGPAVAttribute_DestinationIndicator:
dnType = "destinationIndicator";
break;
case kPGPAVAttribute_Name:
dnType = "name";
break;
case kPGPAVAttribute_GivenName:
dnType = "givenName";
break;
case kPGPAVAttribute_Initials:
dnType = "initials";
break;
/* case kPGPAVAttribute_GenerationQualifier:
dnType = "generationQualifier";
break; */
case kPGPAVAttribute_HouseIdentifier:
dnType = "houseIdentifier";
break;
case kPGPAVAttribute_DirectoryManagementDomain:
dnType = "dmdName";
break;
case kPGPAVAttribute_DomainComponent:
dnType = "DC";
break;
case kPGPAVAttribute_UnstructuredName:
dnType = "unstructuredName";
break;
case kPGPAVAttribute_UnstructuredAddress:
dnType = "unstructuredAddress";
break;
/* VeriSign CRS RegInfo entries, skip these for now so we don't
generate a bogus error */
case kPGPAVAttribute_Challenge:
case kPGPAVAttribute_CertType:
case kPGPAVAttribute_EmployeeID:
case kPGPAVAttribute_MailStop:
case kPGPAVAttribute_AdditionalField4:
case kPGPAVAttribute_AdditionalField5:
case kPGPAVAttribute_AdditionalField6:
case kPGPAVAttribute_Authenticate:
case kPGPAVAttribute_EmbedEmail:
/* ExtensionReq attributes, skip these */
case kPGPAVAttribute_RFC822Name:
case kPGPAVAttribute_DNSName:
case kPGPAVAttribute_AnotherName:
case kPGPAVAttribute_IPAddress:
case kPGPAVAttribute_CertificateExtension:
dnType = NULL;
break;
default:
return (kPGPError_X509AttributeNotSupported);
}
if(dnType && formatData[i].size > 0)
x509AppendDNAttribute(mem,",",dnType,formatData[i].value.pointervalue,formatData[i].size,dnString,&bytesNeeded);
}
if(caType==kPGPExportFormat_EntrustV1_CertReq) /* jason */
{
for(i=0;i<=kPGPPersonalAttr_Description;i++)
if(personal[i] && personalsizes[i] > 0)
x509AppendDNAttribute(mem,"+",personaltype[i],personal[i],
personalsizes[i],dnString,&bytesNeeded);
}
p = *dnString + strlen(*dnString) - 1;
*p = 0;
return(kPGPError_NoErr);
}
static PGPError
x509FormatDSAKey (
PGPMemoryMgrRef mgr,
PKICONTEXT *asnContext,
PGPKeyRef key,
PGPByte **y,
PGPSize *ySize,
PGPByte **pqg,
PGPSize *pqgSize)
{
PKIINTEGER *py;
PKIDss_Parms *ppqg;
int asnError = 0;
PGPByte *keydata, *kd;
PGPSize keydatasize;
int pbits, pbytes;
int qbits, qbytes;
int gbits, gbytes;
int ybits, ybytes;
PGPByte *pdata, *qdata, *gdata, *ydata;
PGPError err;
/* Read algorithm-specific key data into keydata buffer */
err = PGPGetKeyPropertyBuffer( key, kPGPKeyPropKeyData, 0, NULL,
&keydatasize );
if (err != kPGPError_BufferTooSmall && IsPGPError (err))
return err;
keydata = PGPNewData( mgr, keydatasize, 0);
err = PGPGetKeyPropertyBuffer( key, kPGPKeyPropKeyData, keydatasize,
keydata,
&keydatasize );
if (IsPGPError (err))
{
PGPFreeData (keydata);
return err;
}
/* Parse keydata buffer */
kd = keydata;
pbits = (kd[0] << 8) | kd[1];
pbytes = (pbits + 7) / 8;
pdata = kd + 2;
kd += 2 + pbytes;
qbits = (kd[0] << 8) | kd[1];
qbytes = (qbits + 7) / 8;
qdata = kd + 2;
kd += 2 + qbytes;
gbits = (kd[0] << 8) | kd[1];
gbytes = (gbits + 7) / 8;
gdata = kd + 2;
kd += 2 + gbytes;
ybits = (kd[0] << 8) | kd[1];
ybytes = (ybits + 7) / 8;
ydata = kd + 2;
kd += 2 + ybytes;
/* This leaves pbytes, qbytes, gbytes, ybytes holding the length
of the data buffers, with
pdata, qdata, gdata, ydata pointing at the raw numeric data
(with no leading zeros) */
/* clear outputs */
*y = NULL;
*ySize = 0;
*pqg = NULL;
*pqgSize = 0;
if ((ppqg = PKINewDss_Parms (asnContext)) == NULL)
{
PGPFreeData (keydata);
return (kPGPError_OutOfMemory);
}
PKIPutUIntBytes (asnContext, &ppqg->p, pdata, pbytes);
PKIPutUIntBytes (asnContext, &ppqg->q, qdata, qbytes);
PKIPutUIntBytes (asnContext, &ppqg->g, gdata, gbytes);
*pqgSize = PKISizeofDss_Parms (asnContext, ppqg, 1);
*pqg = PGPNewData (mgr, *pqgSize, 0);
PKIPackDss_Parms (asnContext, *pqg, *pqgSize, ppqg, &asnError);
PKIFreeDss_Parms (asnContext, ppqg);
if (asnError)
{
PGPFreeData (keydata);
return kPGPError_LazyProgrammer;
}
py = PKINewINTEGER (asnContext);
PKIPutUIntBytes (asnContext, py, ydata, ybytes);
*ySize = PKISizeofINTEGER (asnContext, py, 1);
*y = PGPNewData (mgr, *ySize, 0);
PKIPackINTEGER (asnContext, *y, *ySize, py, &asnError);
PKIFreeINTEGER (asnContext, py);
if (asnError)
{
PGPFreeData (keydata);
return kPGPError_LazyProgrammer;
}
PGPFreeData (keydata);
return (kPGPError_NoErr);
}
static PGPError
x509FormatRSAKey (
PGPMemoryMgrRef mgr,
PKICONTEXT *asnContext,
PGPKeyRef key,
PGPByte **keyData,
PGPSize *keyDataSize,
PGPByte **paramData,
PGPSize *paramDataSize)
{
PGPByte *keydata, *kd;
PGPSize keydatasize;
PGPByte *e, *n;
int ebytes, nbytes;
int ebits, nbits;
PKIRSAKey *rsaKey;
int asnError = 0;
PGPError err;
*keyData = NULL;
*keyDataSize = 0;
*paramData = NULL;
*paramDataSize = 0;
err = PGPGetKeyPropertyBuffer( key, kPGPKeyPropKeyData, 0, NULL,
&keydatasize );
if (err != kPGPError_BufferTooSmall && IsPGPError (err))
return err;
keydata = PGPNewData( mgr, keydatasize, 0);
err = PGPGetKeyPropertyBuffer( key, kPGPKeyPropKeyData, keydatasize,
keydata,
&keydatasize );
if (IsPGPError (err))
{
PGPFreeData (keydata);
return err;
}
kd = keydata;
nbits = (kd[0] << 8) | kd[1];
nbytes = (nbits + 7) / 8;
n = kd + 2;
kd += 2 + nbytes;
ebits = (kd[0] << 8) | kd[1];
ebytes = (ebits + 7) / 8;
e = kd + 2;
/* clear outputs */
*keyData = NULL;
*keyDataSize = 0;
/* pack n and e in an ASN.1 structure */
rsaKey = PKINewRSAKey (asnContext);
if (!rsaKey)
{
PGPFreeData (keydata);
return kPGPError_OutOfMemory;
}
PKIPutUIntBytes (asnContext, &rsaKey->modulus, n, nbytes);
PKIPutUIntBytes (asnContext, &rsaKey->exponent, e, ebytes);
PGPFreeData (keydata);
*keyDataSize = PKISizeofRSAKey (asnContext, rsaKey, 1);
*keyData = PGPNewData (mgr, *keyDataSize, 0);
if (!*keyData)
{
PKIFreeRSAKey (asnContext, rsaKey);
return kPGPError_OutOfMemory;
}
PKIPackRSAKey (asnContext, *keyData, *keyDataSize, rsaKey, &asnError);
PKIFreeRSAKey (asnContext, rsaKey);
if (asnError)
return kPGPError_LazyProgrammer;
/* encoded as ASN.1 NULL value */
*paramDataSize = 2;
*paramData = PGPNewData (mgr, 2, 0);
(*paramData)[0] = 0x05;
(*paramData)[1] = 0x00;
return kPGPError_NoErr;
}
static PGPError
x509CompileRegInfo (
PKICONTEXT *context,
PGPAttributeValue *formatData,
PGPSize formatDataCount,
vri_ava_t **av)
{
int avCount = 0;
size_t i;
*av = PKIAlloc (context->memMgr, sizeof (vri_ava_t) * (formatDataCount + 1));
for (i = 0; i < formatDataCount; i++)
{
switch (formatData[i].attribute)
{
case kPGPAVAttribute_Challenge:
(*av)[avCount].type = "challenge";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_CertType:
(*av)[avCount].type = "cert_type";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_CommonName:
(*av)[avCount].type = "common_name";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_EmployeeID:
(*av)[avCount].type = "employeeID";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_MailStop:
(*av)[avCount].type = "mailStop";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_AdditionalField4:
(*av)[avCount].type = "additional_field4";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_AdditionalField5:
(*av)[avCount].type = "additional_field5";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_AdditionalField6:
(*av)[avCount].type = "additional_field6";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_Authenticate:
(*av)[avCount].type = "authenticate";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_EmbedEmail:
(*av)[avCount].type = "embed_email";
(*av)[avCount].value = formatData[i].value.booleanvalue ?
"yes" : "no";
(*av)[avCount].size = strlen((*av)[avCount].value);
++avCount;
break;
/* stock X.500 attributes we also use here */
case kPGPAVAttribute_OrganizationName:
(*av)[avCount].type = "corp_company";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_OrganizationalUnitName:
(*av)[avCount].type = "org_unit";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_Title:
(*av)[avCount].type = "jobTitle";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
case kPGPAVAttribute_Email:
(*av)[avCount].type = "mail_email";
(*av)[avCount].size = formatData[i].size;
(*av)[avCount++].value = formatData[i].value.pointervalue;
break;
default:
break; /* do nothing */
}
}
/* add termination record */
(*av)[avCount].type = NULL;
(*av)[avCount].size = 0;
(*av)[avCount++].value = NULL;
/* resize to actual size used */
PKIRealloc (context->memMgr, (void **) av, sizeof (vri_ava_t) * avCount);
return kPGPError_NoErr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -