add more subject name support and expande REQ attributes creation support

pull/5277/head
Jacob Barthelmeh 2022-06-22 17:28:04 -06:00 committed by JacobBarthelmeh
parent 5dcb1ba21f
commit f6c4e295b1
5 changed files with 324 additions and 64 deletions

View File

@ -25650,6 +25650,7 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
oidCsrAttrType, "contentType", "contentType" },
{ NID_pkcs9_unstructuredName, UNSTRUCTURED_NAME_OID,
oidCsrAttrType, "unstructuredName", "unstructuredName" },
{ NID_name, NAME_OID, oidCsrAttrType, "name", "name" },
{ NID_surname, SURNAME_OID,
oidCsrAttrType, "surname", "surname" },
{ NID_givenName, GIVEN_NAME_OID,

View File

@ -8610,6 +8610,10 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
}
if (ret == WOLFSSL_SUCCESS) {
#if defined(OPENSSL_ALL)
int idx;
#endif
cert->version = req->version;
cert->isCA = req->isCa;
cert->basicConstSet = req->basicConstSet;
@ -8626,6 +8630,34 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
cert->challengePwPrintableString = req->challengePw[0] != 0;
#if defined(OPENSSL_ALL)
idx = wolfSSL_X509_REQ_get_attr_by_NID(req,
NID_pkcs9_unstructuredName, -1);
if (idx != WOLFSSL_FATAL_ERROR) {
WOLFSSL_X509_ATTRIBUTE *attr;
attr = wolfSSL_X509_REQ_get_attr(req, idx);
if (attr != NULL) {
const unsigned char *attrData;
int attrDataSz;
attrData = wolfSSL_ASN1_STRING_get0_data(
attr->value->value.asn1_string);
attrDataSz = wolfSSL_ASN1_STRING_length(
attr->value->value.asn1_string);
/* +1 to make sure is terminated string */
if (attrDataSz + 1 > CTC_NAME_SIZE) {
WOLFSSL_MSG("attribute size was too large to copy");
ret = REQ_ATTRIBUTE_E;
}
else {
XMEMCPY(cert->unstructuredName, attrData, attrDataSz);
cert->unstructuredName[attrDataSz] = '\0';
}
}
}
#endif /* OPENSSL_ALL */
#ifdef WOLFSSL_ALT_NAMES
cert->altNamesSz = FlattenAltNames(cert->altNames,
sizeof(cert->altNames), req->altNames);
@ -9371,6 +9403,10 @@ static int ConvertNIDToWolfSSL(int nid)
{
switch (nid) {
case NID_commonName : return ASN_COMMON_NAME;
case NID_name : return ASN_NAME;
case NID_givenName: return ASN_GIVEN_NAME;
case NID_dnQualifier : return ASN_DNQUALIFIER;
case NID_initials: return ASN_INITIALS;
case NID_surname : return ASN_SUR_NAME;
case NID_countryName: return ASN_COUNTRY_NAME;
case NID_localityName: return ASN_LOCALITY_NAME;
@ -11464,6 +11500,26 @@ static int get_dn_attr_by_nid(int n, const char** buf)
str = "emailAddress";
len = 12;
break;
case NID_surname:
str = "SN";
len = 2;
break;
case NID_givenName:
str = "GN";
len = 2;
break;
case NID_dnQualifier:
str = "dnQualifier";
len = 11;
break;
case NID_name:
str = "name";
len = 4;
break;
case NID_initials:
str = "initials";
len = 8;
break;
default:
WOLFSSL_MSG("Attribute type not found");
str = NULL;

View File

@ -9956,6 +9956,10 @@ void InitDecodedCert(DecodedCert* cert,
cert->heap = heap;
cert->maxPathLen = WOLFSSL_MAX_PATH_LEN;
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
cert->subjectNEnc = CTC_UTF8;
cert->subjectIEnc = CTC_UTF8;
cert->subjectDNQEnc = CTC_UTF8;
cert->subjectGNEnc = CTC_UTF8;
cert->subjectSNEnc = CTC_UTF8;
cert->subjectCEnc = CTC_PRINTABLE;
cert->subjectLEnc = CTC_UTF8;
@ -10864,6 +10868,54 @@ static const CertNameData certNameSubject[] = {
#endif
#ifdef WOLFSSL_X509_NAME_AVAILABLE
NID_commonName
#endif
},
/* Given Name */
{
"/GN=", 4,
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
OFFSETOF(DecodedCert, subjectGN),
OFFSETOF(DecodedCert, subjectGNLen),
OFFSETOF(DecodedCert, subjectGNEnc),
#endif
#ifdef WOLFSSL_X509_NAME_AVAILABLE
NID_givenName
#endif
},
/* initials */
{
"/initials=", 10,
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
OFFSETOF(DecodedCert, subjectI),
OFFSETOF(DecodedCert, subjectILen),
OFFSETOF(DecodedCert, subjectIEnc),
#endif
#ifdef WOLFSSL_X509_NAME_AVAILABLE
NID_initials
#endif
},
/* DN Qualifier Name */
{
"/dnQualifier=", 13,
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
OFFSETOF(DecodedCert, subjectDNQ),
OFFSETOF(DecodedCert, subjectDNQLen),
OFFSETOF(DecodedCert, subjectDNQEnc),
#endif
#ifdef WOLFSSL_X509_NAME_AVAILABLE
NID_dnQualifier
#endif
},
/* Name */
{
"/N=", 3,
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
OFFSETOF(DecodedCert, subjectN),
OFFSETOF(DecodedCert, subjectNLen),
OFFSETOF(DecodedCert, subjectNEnc),
#endif
#ifdef WOLFSSL_X509_NAME_AVAILABLE
NID_name
#endif
},
/* Surname */
@ -11581,6 +11633,70 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
nid = NID_commonName;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_NAME) {
copy = WOLFSSL_NAME;
copyLen = sizeof(WOLFSSL_NAME) - 1;
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
if (nameType == SUBJECT) {
cert->subjectN = (char*)&input[srcIdx];
cert->subjectNLen = strLen;
cert->subjectNEnc = b;
}
#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
#if (defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)) \
&& !defined(WOLFCRYPT_ONLY)
nid = NID_name;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_INITIALS) {
copy = WOLFSSL_INITIALS;
copyLen = sizeof(WOLFSSL_INITIALS) - 1;
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
if (nameType == SUBJECT) {
cert->subjectI = (char*)&input[srcIdx];
cert->subjectILen = strLen;
cert->subjectIEnc = b;
}
#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
#if (defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)) \
&& !defined(WOLFCRYPT_ONLY)
nid = NID_initials;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_GIVEN_NAME) {
copy = WOLFSSL_GIVEN_NAME;
copyLen = sizeof(WOLFSSL_GIVEN_NAME) - 1;
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
if (nameType == SUBJECT) {
cert->subjectGN = (char*)&input[srcIdx];
cert->subjectGNLen = strLen;
cert->subjectGNEnc = b;
}
#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
#if (defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)) \
&& !defined(WOLFCRYPT_ONLY)
nid = NID_givenName;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_DNQUALIFIER) {
copy = WOLFSSL_DNQUALIFIER;
copyLen = sizeof(WOLFSSL_DNQUALIFIER) - 1;
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
if (nameType == SUBJECT) {
cert->subjectDNQ = (char*)&input[srcIdx];
cert->subjectDNQLen = strLen;
cert->subjectDNQEnc = b;
}
#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
#if (defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)) \
&& !defined(WOLFCRYPT_ONLY)
nid = NID_dnQualifier;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_SUR_NAME) {
copy = WOLFSSL_SUR_NAME;
copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
@ -22683,6 +22799,10 @@ static const byte nameOid[][NAME_OID_SZ] = {
{ 0x55, 0x04, ASN_STATE_NAME },
{ 0x55, 0x04, ASN_STREET_ADDR },
{ 0x55, 0x04, ASN_LOCALITY_NAME },
{ 0x55, 0x04, ASN_NAME },
{ 0x55, 0x04, ASN_GIVEN_NAME },
{ 0x55, 0x04, ASN_INITIALS },
{ 0x55, 0x04, ASN_DNQUALIFIER },
{ 0x55, 0x04, ASN_SUR_NAME },
{ 0x55, 0x04, ASN_ORG_NAME },
{ 0x00, 0x00, ASN_DOMAIN_COMPONENT}, /* not actual OID - see dcOid */
@ -22724,6 +22844,14 @@ const char* GetOneCertName(CertName* name, int idx)
return name->street;
case ASN_LOCALITY_NAME:
return name->locality;
case ASN_NAME:
return name->name;
case ASN_GIVEN_NAME:
return name->givenName;
case ASN_INITIALS:
return name->initials;
case ASN_DNQUALIFIER:
return name->dnQualifier;
case ASN_SUR_NAME:
return name->sur;
case ASN_ORG_NAME:
@ -22767,6 +22895,14 @@ static char GetNameType(CertName* name, int idx)
return name->streetEnc;
case ASN_LOCALITY_NAME:
return name->localityEnc;
case ASN_NAME:
return name->nameEnc;
case ASN_GIVEN_NAME:
return name->givenNameEnc;
case ASN_INITIALS:
return name->initialsEnc;
case ASN_DNQUALIFIER:
return name->dnQualifierEnc;
case ASN_SUR_NAME:
return name->surEnc;
case ASN_ORG_NAME:
@ -25950,79 +26086,109 @@ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
#ifdef WOLFSSL_CERT_REQ
#ifndef WOLFSSL_ASN_TEMPLATE
static int SetReqAttrib(byte* output, char* pw, int pwPrintableString,
int extSz)
/* return size of data set on success
* if getting size only then attr and oid should be NULL
*/
static int SetReqAttribSingle(byte* output, int* idx, char* attr, int attrSz,
const byte* oid, int oidSz, byte printable, int extSz)
{
int totalSz = 0;
int seqSz = 0;
int setSz = 0;
int strSz = 0;
byte seq[MAX_SEQ_SZ];
byte set[MAX_SET_SZ];
byte str[MAX_PRSTR_SZ];
totalSz = SetObjectId(oidSz, NULL);
totalSz += oidSz;
if (extSz > 0) {
totalSz += setSz = SetSet(extSz, set);
totalSz += seqSz = SetSequence(totalSz + extSz, seq);
totalSz += extSz;
}
else {
if (printable) {
totalSz += strSz = SetPrintableString(attrSz, str);
}
else {
totalSz += strSz = SetUTF8String(attrSz, str);
}
totalSz += setSz = SetSet(strSz + attrSz, set);
totalSz += seqSz = SetSequence(totalSz + attrSz, seq);
totalSz += attrSz;
}
if (oid) {
XMEMCPY(&output[*idx], seq, seqSz);
*idx += seqSz;
*idx += SetObjectId(oidSz, output + *idx);
XMEMCPY(&output[*idx], oid, oidSz);
*idx += oidSz;
XMEMCPY(&output[*idx], set, setSz);
*idx += setSz;
if (strSz > 0) {
XMEMCPY(&output[*idx], str, strSz);
*idx += strSz;
XMEMCPY(&output[*idx], attr, attrSz);
*idx += attrSz;
}
}
return totalSz;
}
static int SetReqAttrib(byte* output, Cert* cert, int extSz)
{
int sz = 0; /* overall size */
int cpSz = 0; /* Challenge Password section size */
int cpSeqSz = 0;
int cpSetSz = 0;
int cpStrSz = 0;
int pwSz = 0;
int erSz = 0; /* Extension Request section size */
int erSeqSz = 0;
int erSetSz = 0;
byte cpSeq[MAX_SEQ_SZ];
byte cpSet[MAX_SET_SZ];
byte cpStr[MAX_PRSTR_SZ];
byte erSeq[MAX_SEQ_SZ];
byte erSet[MAX_SET_SZ];
int setSz = 0;
output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
sz++;
if (pw && pw[0]) {
int cpOidSz = SetObjectId(sizeof(attrChallengePasswordOid), NULL);
cpOidSz += sizeof(attrChallengePasswordOid);
pwSz = (int)XSTRLEN(pw);
if (pwPrintableString) {
cpStrSz = SetPrintableString(pwSz, cpStr);
} else {
cpStrSz = SetUTF8String(pwSz, cpStr);
}
cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
/* +2 for tag and length parts of the TLV triplet */
cpSeqSz = SetSequence(cpOidSz + cpSetSz +
cpStrSz + pwSz, cpSeq);
cpSz = cpSeqSz + cpOidSz + cpSetSz +
cpStrSz + pwSz;
if (cert->challengePw[0]) {
setSz += SetReqAttribSingle(output, &sz, NULL,
(int)XSTRLEN(cert->challengePw), NULL,
sizeof(attrChallengePasswordOid),
cert->challengePwPrintableString, 0);
}
if (cert->unstructuredName[0]) {
setSz += SetReqAttribSingle(output, &sz, NULL,
(int)XSTRLEN(cert->unstructuredName), NULL,
sizeof(attrUnstructuredNameOid), 1, 0);
}
if (extSz) {
int erOidSz = SetObjectId(sizeof(attrExtensionRequestOid), NULL);
erOidSz += sizeof(attrExtensionRequestOid);
erSetSz = SetSet(extSz, erSet);
erSeqSz = SetSequence(erSetSz + erOidSz + extSz, erSeq);
erSz = extSz + erSetSz + erSeqSz + erOidSz;
setSz += SetReqAttribSingle(output, &sz, NULL, 0, NULL,
sizeof(attrExtensionRequestOid), 1, extSz);
}
/* Put the pieces together. */
sz += SetLength(cpSz + erSz, &output[sz]);
if (cpSz) {
XMEMCPY(&output[sz], cpSeq, cpSeqSz);
sz += cpSeqSz;
sz += SetObjectId(sizeof(attrChallengePasswordOid), output + sz);
XMEMCPY(&output[sz], attrChallengePasswordOid,
sizeof(attrChallengePasswordOid));
sz += sizeof(attrChallengePasswordOid);
XMEMCPY(&output[sz], cpSet, cpSetSz);
sz += cpSetSz;
XMEMCPY(&output[sz], cpStr, cpStrSz);
sz += cpStrSz;
XMEMCPY(&output[sz], pw, pwSz);
sz += pwSz;
sz += SetLength(setSz, &output[sz]);
if (sz + setSz - extSz > MAX_ATTRIB_SZ) {
WOLFSSL_MSG("Attribute Buffer is not big enough!");
return REQ_ATTRIBUTE_E;
}
if (erSz) {
XMEMCPY(&output[sz], erSeq, erSeqSz);
sz += erSeqSz;
sz += SetObjectId(sizeof(attrExtensionRequestOid), output + sz);
XMEMCPY(&output[sz], attrExtensionRequestOid,
sizeof(attrExtensionRequestOid));
sz += sizeof(attrExtensionRequestOid);
XMEMCPY(&output[sz], erSet, erSetSz);
sz += erSetSz;
if (cert->challengePw[0]) {
SetReqAttribSingle(output, &sz, cert->challengePw,
(int)XSTRLEN(cert->challengePw), &attrChallengePasswordOid[0],
sizeof(attrChallengePasswordOid),
cert->challengePwPrintableString, 0);
}
if (cert->unstructuredName[0]) {
SetReqAttribSingle(output, &sz, cert->unstructuredName,
(int)XSTRLEN(cert->unstructuredName),
&attrUnstructuredNameOid[0],
sizeof(attrUnstructuredNameOid), 1, 0);
}
if (extSz) {
SetReqAttribSingle(output, &sz, NULL, 0, &attrExtensionRequestOid[0],
sizeof(attrExtensionRequestOid), 1, extSz);
/* The actual extension data will be tacked onto the output later. */
}
@ -26350,9 +26516,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
#endif /* WOLFSSL_CERT_EXT */
}
der->attribSz = SetReqAttrib(der->attrib, cert->challengePw,
cert->challengePwPrintableString,
der->extensionsSz);
der->attribSz = SetReqAttrib(der->attrib, cert, der->extensionsSz);
if (der->attribSz <= 0)
return REQ_ATTRIBUTE_E;
@ -27478,6 +27642,13 @@ static void SetNameFromDcert(CertName* cn, DecodedCert* decoded)
cn->unit[sz] = '\0';
cn->unitEnc = decoded->subjectOUEnc;
}
if (decoded->subjectN) {
sz = (decoded->subjectNLen < CTC_NAME_SIZE) ? decoded->subjectNLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->name, decoded->subjectN, sz);
cn->name[sz] = '\0';
cn->nameEnc = decoded->subjectNEnc;
}
if (decoded->subjectSN) {
sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
: CTC_NAME_SIZE - 1;

View File

@ -674,6 +674,10 @@ enum DN_Tags {
ASN_BUS_CAT = 0x0f, /* businessCategory */
ASN_POSTAL_CODE = 0x11, /* postalCode */
ASN_USER_ID = 0x12, /* UserID */
ASN_NAME = 0x2a, /* name */
ASN_GIVEN_NAME = 0x29, /* GN */
ASN_INITIALS = 0x2b, /* initials */
ASN_DNQUALIFIER = 0x2e, /* dnQualifier */
ASN_EMAIL_NAME = 0x98, /* not actual OID (see attrEmailOid) */
ASN_CUSTOM_NAME = 0x99, /* not actual OID (see CertOidField) */
@ -703,6 +707,10 @@ extern const WOLFSSL_ObjectInfo wolfssl_object_info[];
#define WOLFSSL_COMMON_NAME "/CN="
#define WOLFSSL_LN_COMMON_NAME "/commonName="
#define WOLFSSL_SUR_NAME "/SN="
#define WOLFSSL_NAME "/N="
#define WOLFSSL_INITIALS "/initials="
#define WOLFSSL_GIVEN_NAME "/GN="
#define WOLFSSL_DNQUALIFIER "/dnQualifier="
#define WOLFSSL_SERIAL_NUMBER "/serialNumber="
#define WOLFSSL_COUNTRY_NAME "/C="
#define WOLFSSL_LN_COUNTRY_NAME "/countryName="
@ -791,6 +799,7 @@ enum
NID_dnQualifier = 174,
NID_commonName = 14, /* CN Changed to not conflict
* with PBE_SHA1_DES3 */
NID_name = 173, /* N */
NID_surname = 0x04, /* SN */
NID_serialNumber = 0x05, /* serialNumber */
NID_countryName = 0x06, /* C */
@ -918,8 +927,9 @@ enum Misc_ASN {
#ifdef WOLFSSL_CERT_GEN
#ifdef WOLFSSL_CERT_REQ
/* Max encoded cert req attributes length */
MAX_ATTRIB_SZ = MAX_SEQ_SZ * 3 + (11 + MAX_SEQ_SZ) * 2 +
MAX_PRSTR_SZ + CTC_NAME_SIZE, /* 11 is the OID size */
MAX_ATTRIB_SZ = MAX_SEQ_SZ * 4 + (11 + MAX_SEQ_SZ) * 3 +
MAX_PRSTR_SZ * 2 + CTC_NAME_SIZE * 2,
/* 11 is the OID size */
#endif
#if defined(WOLFSSL_ALT_NAMES) || defined(WOLFSSL_CERT_EXT)
MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + CTC_MAX_ALT_SIZE,
@ -1237,6 +1247,7 @@ enum CsrAttrType {
DNQUALIFIER_OID = 135,
INITIALS_OID = 132,
SURNAME_OID = 93,
NAME_OID = 130,
GIVEN_NAME_OID = 131,
};
#endif
@ -1647,6 +1658,18 @@ struct DecodedCert {
char* subjectSN;
int subjectSNLen;
char subjectSNEnc;
char* subjectN;
int subjectNLen;
char subjectNEnc;
char* subjectI;
int subjectILen;
char subjectIEnc;
char* subjectGN;
int subjectGNLen;
char subjectGNEnc;
char* subjectDNQ;
int subjectDNQLen;
char subjectDNQEnc;
char* subjectC;
int subjectCLen;
char subjectCEnc;

View File

@ -337,6 +337,14 @@ typedef struct CertName {
char localityEnc;
char sur[CTC_NAME_SIZE];
char surEnc;
char givenName[CTC_NAME_SIZE];
char givenNameEnc;
char initials[CTC_NAME_SIZE];
char initialsEnc;
char dnQualifier[CTC_NAME_SIZE];
char dnQualifierEnc;
char name[CTC_NAME_SIZE];
char nameEnc;
char org[CTC_NAME_SIZE];
char orgEnc;
char unit[CTC_NAME_SIZE];
@ -433,6 +441,7 @@ typedef struct Cert {
#endif
#ifdef WOLFSSL_CERT_REQ
char challengePw[CTC_NAME_SIZE];
char unstructuredName[CTC_NAME_SIZE];
int challengePwPrintableString; /* encode as PrintableString */
#endif
#ifdef WOLFSSL_CUSTOM_OID