forked from wolfSSL/wolfssl
Merge pull request #1395 from JacobBarthelmeh/Certs
Add support for writing multiple OUs, DCs and for writing a unique EKU OID
This commit is contained in:
@ -519,7 +519,8 @@ fi
|
|||||||
if test "$ENABLED_OPENSSLEXTRA" = "x509small"
|
if test "$ENABLED_OPENSSLEXTRA" = "x509small"
|
||||||
then
|
then
|
||||||
AC_MSG_NOTICE([Enabling only a subset of X509 opensslextra])
|
AC_MSG_NOTICE([Enabling only a subset of X509 opensslextra])
|
||||||
AM_CFLAGS="-DOPENSSL_EXTRA_X509_SMALL"
|
AM_CFLAGS="-DOPENSSL_EXTRA_X509_SMALL $AM_CFLAGS"
|
||||||
|
AM_CFLAGS="-DWOLFSSL_EKU_OID -DWOLFSSL_MULTI_ATTRIB $AM_CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# High Strength Build
|
# High Strength Build
|
||||||
|
@ -7808,76 +7808,48 @@ int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
|
|||||||
*/
|
*/
|
||||||
int wc_InitCert(Cert* cert)
|
int wc_InitCert(Cert* cert)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (cert == NULL) {
|
if (cert == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMEMSET(cert, 0, sizeof(Cert));
|
||||||
|
|
||||||
cert->version = 2; /* version 3 is hex 2 */
|
cert->version = 2; /* version 3 is hex 2 */
|
||||||
cert->sigType = CTC_SHAwRSA;
|
cert->sigType = CTC_SHAwRSA;
|
||||||
cert->daysValid = 500;
|
cert->daysValid = 500;
|
||||||
cert->selfSigned = 1;
|
cert->selfSigned = 1;
|
||||||
cert->isCA = 0;
|
|
||||||
cert->bodySz = 0;
|
|
||||||
#ifdef WOLFSSL_ALT_NAMES
|
|
||||||
cert->altNamesSz = 0;
|
|
||||||
cert->beforeDateSz = 0;
|
|
||||||
cert->afterDateSz = 0;
|
|
||||||
#endif
|
|
||||||
#ifdef WOLFSSL_CERT_EXT
|
|
||||||
cert->skidSz = 0;
|
|
||||||
cert->akidSz = 0;
|
|
||||||
cert->keyUsage = 0;
|
|
||||||
cert->extKeyUsage = 0;
|
|
||||||
cert->certPoliciesNb = 0;
|
|
||||||
XMEMSET(cert->akid, 0, CTC_MAX_AKID_SIZE);
|
|
||||||
XMEMSET(cert->skid, 0, CTC_MAX_SKID_SIZE);
|
|
||||||
XMEMSET(cert->certPolicies, 0, CTC_MAX_CERTPOL_NB*CTC_MAX_CERTPOL_SZ);
|
|
||||||
#endif
|
|
||||||
cert->keyType = RSA_KEY;
|
cert->keyType = RSA_KEY;
|
||||||
XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
|
|
||||||
cert->serialSz = 0;
|
|
||||||
|
|
||||||
cert->issuer.country[0] = '\0';
|
|
||||||
cert->issuer.countryEnc = CTC_PRINTABLE;
|
cert->issuer.countryEnc = CTC_PRINTABLE;
|
||||||
cert->issuer.state[0] = '\0';
|
|
||||||
cert->issuer.stateEnc = CTC_UTF8;
|
cert->issuer.stateEnc = CTC_UTF8;
|
||||||
cert->issuer.locality[0] = '\0';
|
|
||||||
cert->issuer.localityEnc = CTC_UTF8;
|
cert->issuer.localityEnc = CTC_UTF8;
|
||||||
cert->issuer.sur[0] = '\0';
|
|
||||||
cert->issuer.surEnc = CTC_UTF8;
|
cert->issuer.surEnc = CTC_UTF8;
|
||||||
cert->issuer.org[0] = '\0';
|
|
||||||
cert->issuer.orgEnc = CTC_UTF8;
|
cert->issuer.orgEnc = CTC_UTF8;
|
||||||
cert->issuer.unit[0] = '\0';
|
|
||||||
cert->issuer.unitEnc = CTC_UTF8;
|
cert->issuer.unitEnc = CTC_UTF8;
|
||||||
cert->issuer.commonName[0] = '\0';
|
|
||||||
cert->issuer.commonNameEnc = CTC_UTF8;
|
cert->issuer.commonNameEnc = CTC_UTF8;
|
||||||
cert->issuer.email[0] = '\0';
|
|
||||||
|
|
||||||
cert->subject.country[0] = '\0';
|
|
||||||
cert->subject.countryEnc = CTC_PRINTABLE;
|
cert->subject.countryEnc = CTC_PRINTABLE;
|
||||||
cert->subject.state[0] = '\0';
|
|
||||||
cert->subject.stateEnc = CTC_UTF8;
|
cert->subject.stateEnc = CTC_UTF8;
|
||||||
cert->subject.locality[0] = '\0';
|
|
||||||
cert->subject.localityEnc = CTC_UTF8;
|
cert->subject.localityEnc = CTC_UTF8;
|
||||||
cert->subject.sur[0] = '\0';
|
|
||||||
cert->subject.surEnc = CTC_UTF8;
|
cert->subject.surEnc = CTC_UTF8;
|
||||||
cert->subject.org[0] = '\0';
|
|
||||||
cert->subject.orgEnc = CTC_UTF8;
|
cert->subject.orgEnc = CTC_UTF8;
|
||||||
cert->subject.unit[0] = '\0';
|
|
||||||
cert->subject.unitEnc = CTC_UTF8;
|
cert->subject.unitEnc = CTC_UTF8;
|
||||||
cert->subject.commonName[0] = '\0';
|
|
||||||
cert->subject.commonNameEnc = CTC_UTF8;
|
cert->subject.commonNameEnc = CTC_UTF8;
|
||||||
cert->subject.email[0] = '\0';
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_CERT_REQ
|
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||||
cert->challengePw[0] ='\0';
|
for (i = 0; i < CTC_MAX_ATTRIB; i++) {
|
||||||
#endif
|
cert->issuer.name[i].type = CTC_UTF8;
|
||||||
|
cert->subject.name[i].type = CTC_UTF8;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||||
|
|
||||||
#ifdef WOLFSSL_HEAP_TEST
|
#ifdef WOLFSSL_HEAP_TEST
|
||||||
cert->heap = (void*)WOLFSSL_HEAP_TEST;
|
cert->heap = (void*)WOLFSSL_HEAP_TEST;
|
||||||
#else
|
|
||||||
cert->heap = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
(void)i;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8432,8 +8404,7 @@ static byte GetNameId(int idx)
|
|||||||
return ASN_COMMON_NAME;
|
return ASN_COMMON_NAME;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
/* email uses different id type */
|
return ASN_EMAIL_NAME;
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@ -8651,7 +8622,7 @@ static int SetOjectIdValue(byte* output, word32 outSz, int* idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
|
/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
|
||||||
static int SetExtKeyUsage(byte* output, word32 outSz, byte input)
|
static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
|
||||||
{
|
{
|
||||||
int idx = 0, oidListSz = 0, totalSz, ret = 0;
|
int idx = 0, oidListSz = 0, totalSz, ret = 0;
|
||||||
static const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
|
static const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
|
||||||
@ -8688,6 +8659,19 @@ static int SetExtKeyUsage(byte* output, word32 outSz, byte input)
|
|||||||
if (input & EXTKEYUSE_OCSP_SIGN)
|
if (input & EXTKEYUSE_OCSP_SIGN)
|
||||||
ret |= SetOjectIdValue(output, outSz, &idx,
|
ret |= SetOjectIdValue(output, outSz, &idx,
|
||||||
extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
|
extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
|
||||||
|
#ifdef WOLFSSL_EKU_OID
|
||||||
|
/* iterate through OID values */
|
||||||
|
if (input & EXTKEYUSE_USER) {
|
||||||
|
int i, sz;
|
||||||
|
for (i = 0; i < CTC_MAX_EKU_NB; i++) {
|
||||||
|
sz = cert->extKeyUsageOIDSz[i];
|
||||||
|
if (sz > 0) {
|
||||||
|
ret |= SetOjectIdValue(output, outSz, &idx,
|
||||||
|
cert->extKeyUsageOID[i], sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_EKU_OID */
|
||||||
}
|
}
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
@ -8712,6 +8696,7 @@ static int SetExtKeyUsage(byte* output, word32 outSz, byte input)
|
|||||||
/* 5. Oid List (already set in-place above) */
|
/* 5. Oid List (already set in-place above) */
|
||||||
idx += oidListSz;
|
idx += oidListSz;
|
||||||
|
|
||||||
|
(void)cert;
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8870,6 +8855,134 @@ static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length)
|
|||||||
}
|
}
|
||||||
#endif /* WOLFSL_ALT_NAMES */
|
#endif /* WOLFSL_ALT_NAMES */
|
||||||
|
|
||||||
|
/* Encodes one attribute of the name (issuer/subject)
|
||||||
|
*
|
||||||
|
* name structure to hold result of encoding
|
||||||
|
* nameStr value to be encoded
|
||||||
|
* nameType type of encoding i.e CTC_UTF8
|
||||||
|
* type id of attribute i.e ASN_COMMON_NAME
|
||||||
|
*
|
||||||
|
* returns length on success
|
||||||
|
*/
|
||||||
|
static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
|
||||||
|
byte type)
|
||||||
|
{
|
||||||
|
word32 idx = 0;
|
||||||
|
|
||||||
|
if (nameStr) {
|
||||||
|
/* bottom up */
|
||||||
|
byte firstLen[1 + MAX_LENGTH_SZ];
|
||||||
|
byte secondLen[MAX_LENGTH_SZ];
|
||||||
|
byte sequence[MAX_SEQ_SZ];
|
||||||
|
byte set[MAX_SET_SZ];
|
||||||
|
|
||||||
|
int strLen = (int)XSTRLEN(nameStr);
|
||||||
|
int thisLen = strLen;
|
||||||
|
int firstSz, secondSz, seqSz, setSz;
|
||||||
|
|
||||||
|
if (strLen == 0) { /* no user data for this item */
|
||||||
|
name->used = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restrict country code size */
|
||||||
|
if (ASN_COUNTRY_NAME == type && strLen != CTC_COUNTRY_SIZE) {
|
||||||
|
return ASN_COUNTRY_SIZE_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
secondSz = SetLength(strLen, secondLen);
|
||||||
|
thisLen += secondSz;
|
||||||
|
switch (type) {
|
||||||
|
case ASN_EMAIL_NAME: /* email */
|
||||||
|
thisLen += EMAIL_JOINT_LEN;
|
||||||
|
firstSz = EMAIL_JOINT_LEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASN_DOMAIN_COMPONENT:
|
||||||
|
thisLen += PILOT_JOINT_LEN;
|
||||||
|
firstSz = PILOT_JOINT_LEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
thisLen++; /* str type */
|
||||||
|
thisLen += JOINT_LEN;
|
||||||
|
firstSz = JOINT_LEN + 1;
|
||||||
|
}
|
||||||
|
thisLen++; /* id type */
|
||||||
|
firstSz = SetObjectId(firstSz, firstLen);
|
||||||
|
thisLen += firstSz;
|
||||||
|
|
||||||
|
seqSz = SetSequence(thisLen, sequence);
|
||||||
|
thisLen += seqSz;
|
||||||
|
setSz = SetSet(thisLen, set);
|
||||||
|
thisLen += setSz;
|
||||||
|
|
||||||
|
if (thisLen > (int)sizeof(name->encoded)) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store it */
|
||||||
|
idx = 0;
|
||||||
|
/* set */
|
||||||
|
XMEMCPY(name->encoded, set, setSz);
|
||||||
|
idx += setSz;
|
||||||
|
/* seq */
|
||||||
|
XMEMCPY(name->encoded + idx, sequence, seqSz);
|
||||||
|
idx += seqSz;
|
||||||
|
/* asn object id */
|
||||||
|
XMEMCPY(name->encoded + idx, firstLen, firstSz);
|
||||||
|
idx += firstSz;
|
||||||
|
switch (type) {
|
||||||
|
case ASN_EMAIL_NAME:
|
||||||
|
{
|
||||||
|
const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||||
|
0x01, 0x09, 0x01, 0x16 };
|
||||||
|
/* email joint id */
|
||||||
|
XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
|
||||||
|
idx += (int)sizeof(EMAIL_OID);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASN_DOMAIN_COMPONENT:
|
||||||
|
{
|
||||||
|
const byte PILOT_OID[] = { 0x09, 0x92, 0x26, 0x89,
|
||||||
|
0x93, 0xF2, 0x2C, 0x64, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
XMEMCPY(name->encoded + idx, PILOT_OID,
|
||||||
|
sizeof(PILOT_OID));
|
||||||
|
idx += (int)sizeof(PILOT_OID);
|
||||||
|
/* id type */
|
||||||
|
name->encoded[idx++] = type;
|
||||||
|
/* str type */
|
||||||
|
name->encoded[idx++] = nameType;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
name->encoded[idx++] = 0x55;
|
||||||
|
name->encoded[idx++] = 0x04;
|
||||||
|
/* id type */
|
||||||
|
name->encoded[idx++] = type;
|
||||||
|
/* str type */
|
||||||
|
name->encoded[idx++] = nameType;
|
||||||
|
}
|
||||||
|
/* second length */
|
||||||
|
XMEMCPY(name->encoded + idx, secondLen, secondSz);
|
||||||
|
idx += secondSz;
|
||||||
|
/* str value */
|
||||||
|
XMEMCPY(name->encoded + idx, nameStr, strLen);
|
||||||
|
idx += strLen;
|
||||||
|
|
||||||
|
name->type = type;
|
||||||
|
name->totalLen = idx;
|
||||||
|
name->used = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
name->used = 0;
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
/* encode CertName into output, return total bytes written */
|
/* encode CertName into output, return total bytes written */
|
||||||
int SetName(byte* output, word32 outputSz, CertName* name)
|
int SetName(byte* output, word32 outputSz, CertName* name)
|
||||||
@ -8880,6 +8993,10 @@ int SetName(byte* output, word32 outputSz, CertName* name)
|
|||||||
#else
|
#else
|
||||||
EncodedName names[NAME_ENTRIES];
|
EncodedName names[NAME_ENTRIES];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||||
|
EncodedName addNames[CTC_MAX_ATTRIB];
|
||||||
|
int j, type;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (output == NULL || name == NULL)
|
if (output == NULL || name == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
@ -8895,101 +9012,38 @@ int SetName(byte* output, word32 outputSz, CertName* name)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < NAME_ENTRIES; i++) {
|
for (i = 0; i < NAME_ENTRIES; i++) {
|
||||||
|
int ret;
|
||||||
const char* nameStr = GetOneName(name, i);
|
const char* nameStr = GetOneName(name, i);
|
||||||
if (nameStr) {
|
|
||||||
/* bottom up */
|
|
||||||
byte firstLen[1 + MAX_LENGTH_SZ];
|
|
||||||
byte secondLen[MAX_LENGTH_SZ];
|
|
||||||
byte sequence[MAX_SEQ_SZ];
|
|
||||||
byte set[MAX_SET_SZ];
|
|
||||||
|
|
||||||
int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
|
ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),
|
||||||
int strLen = (int)XSTRLEN(nameStr);
|
GetNameId(i));
|
||||||
int thisLen = strLen;
|
if (ret < 0) {
|
||||||
int firstSz, secondSz, seqSz, setSz;
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
|
||||||
if (strLen == 0) { /* no user data for this item */
|
|
||||||
names[i].used = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restrict country code size */
|
|
||||||
if (i == 0 && strLen != CTC_COUNTRY_SIZE) {
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#endif
|
#endif
|
||||||
return ASN_COUNTRY_SIZE_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
totalBytes += ret;
|
||||||
secondSz = SetLength(strLen, secondLen);
|
}
|
||||||
thisLen += secondSz;
|
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||||
if (email) {
|
for (i = 0; i < CTC_MAX_ATTRIB; i++) {
|
||||||
thisLen += EMAIL_JOINT_LEN;
|
if (name->name[i].sz > 0) {
|
||||||
thisLen ++; /* id type */
|
int ret;
|
||||||
firstSz = SetObjectId(EMAIL_JOINT_LEN, firstLen);
|
ret = wc_EncodeName(&addNames[i], name->name[i].value,
|
||||||
}
|
name->name[i].type, name->name[i].id);
|
||||||
else {
|
if (ret < 0) {
|
||||||
thisLen++; /* str type */
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
thisLen++; /* id type */
|
|
||||||
thisLen += JOINT_LEN;
|
|
||||||
firstSz = SetObjectId(JOINT_LEN + 1, firstLen);
|
|
||||||
}
|
|
||||||
thisLen += firstSz;
|
|
||||||
|
|
||||||
seqSz = SetSequence(thisLen, sequence);
|
|
||||||
thisLen += seqSz;
|
|
||||||
setSz = SetSet(thisLen, set);
|
|
||||||
thisLen += setSz;
|
|
||||||
|
|
||||||
if (thisLen > (int)sizeof(names[i].encoded)) {
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#endif
|
#endif
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
totalBytes += ret;
|
||||||
/* store it */
|
}
|
||||||
idx = 0;
|
else {
|
||||||
/* set */
|
addNames[i].used = 0;
|
||||||
XMEMCPY(names[i].encoded, set, setSz);
|
|
||||||
idx += setSz;
|
|
||||||
/* seq */
|
|
||||||
XMEMCPY(names[i].encoded + idx, sequence, seqSz);
|
|
||||||
idx += seqSz;
|
|
||||||
/* asn object id */
|
|
||||||
XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
|
|
||||||
idx += firstSz;
|
|
||||||
if (email) {
|
|
||||||
const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
|
||||||
0x01, 0x09, 0x01, 0x16 };
|
|
||||||
/* email joint id */
|
|
||||||
XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
|
|
||||||
idx += (int)sizeof(EMAIL_OID);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* joint id */
|
|
||||||
byte bType = GetNameId(i);
|
|
||||||
names[i].encoded[idx++] = 0x55;
|
|
||||||
names[i].encoded[idx++] = 0x04;
|
|
||||||
/* id type */
|
|
||||||
names[i].encoded[idx++] = bType;
|
|
||||||
/* str type */
|
|
||||||
names[i].encoded[idx++] = GetNameType(name, i);
|
|
||||||
}
|
|
||||||
/* second length */
|
|
||||||
XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
|
|
||||||
idx += secondSz;
|
|
||||||
/* str value */
|
|
||||||
XMEMCPY(names[i].encoded + idx, nameStr, strLen);
|
|
||||||
idx += strLen;
|
|
||||||
|
|
||||||
totalBytes += idx;
|
|
||||||
names[i].totalLen = idx;
|
|
||||||
names[i].used = 1;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
names[i].used = 0;
|
|
||||||
}
|
}
|
||||||
|
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||||
|
|
||||||
/* header */
|
/* header */
|
||||||
idx = SetSequence(totalBytes, output);
|
idx = SetSequence(totalBytes, output);
|
||||||
@ -9002,6 +9056,46 @@ int SetName(byte* output, word32 outputSz, CertName* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NAME_ENTRIES; i++) {
|
for (i = 0; i < NAME_ENTRIES; i++) {
|
||||||
|
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||||
|
type = GetNameId(i);
|
||||||
|
|
||||||
|
/* list all DC values before OUs */
|
||||||
|
if (type == ASN_ORGUNIT_NAME) {
|
||||||
|
type = ASN_DOMAIN_COMPONENT;
|
||||||
|
for (j = 0; j < CTC_MAX_ATTRIB; j++) {
|
||||||
|
if (name->name[j].sz > 0 && type == name->name[j].id) {
|
||||||
|
if (outputSz < (word32)(idx+addNames[j].totalLen)) {
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(output + idx, addNames[j].encoded,
|
||||||
|
addNames[j].totalLen);
|
||||||
|
idx += addNames[j].totalLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type = ASN_ORGUNIT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write all similar types to the buffer */
|
||||||
|
for (j = 0; j < CTC_MAX_ATTRIB; j++) {
|
||||||
|
if (name->name[j].sz > 0 && type == name->name[j].id) {
|
||||||
|
if (outputSz < (word32)(idx+addNames[j].totalLen)) {
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(output + idx, addNames[j].encoded,
|
||||||
|
addNames[j].totalLen);
|
||||||
|
idx += addNames[j].totalLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||||
|
|
||||||
if (names[i].used) {
|
if (names[i].used) {
|
||||||
if (outputSz < (word32)(idx+names[i].totalLen)) {
|
if (outputSz < (word32)(idx+names[i].totalLen)) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
@ -9220,7 +9314,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
|
|||||||
|
|
||||||
/* Extended Key Usage */
|
/* Extended Key Usage */
|
||||||
if (cert->extKeyUsage != 0){
|
if (cert->extKeyUsage != 0){
|
||||||
der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
|
der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
|
||||||
sizeof(der->extKeyUsage), cert->extKeyUsage);
|
sizeof(der->extKeyUsage), cert->extKeyUsage);
|
||||||
if (der->extKeyUsageSz <= 0)
|
if (der->extKeyUsageSz <= 0)
|
||||||
return EXTKEYUSAGE_E;
|
return EXTKEYUSAGE_E;
|
||||||
@ -9753,7 +9847,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
|
|||||||
|
|
||||||
/* Extended Key Usage */
|
/* Extended Key Usage */
|
||||||
if (cert->extKeyUsage != 0){
|
if (cert->extKeyUsage != 0){
|
||||||
der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
|
der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
|
||||||
sizeof(der->extKeyUsage), cert->extKeyUsage);
|
sizeof(der->extKeyUsage), cert->extKeyUsage);
|
||||||
if (der->extKeyUsageSz <= 0)
|
if (der->extKeyUsageSz <= 0)
|
||||||
return EXTKEYUSAGE_E;
|
return EXTKEYUSAGE_E;
|
||||||
@ -10486,6 +10580,38 @@ int wc_SetExtKeyUsage(Cert *cert, const char *value)
|
|||||||
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_EKU_OID
|
||||||
|
/*
|
||||||
|
* cert structure to set EKU oid in
|
||||||
|
* oid the oid in byte representation
|
||||||
|
* sz size of oid buffer
|
||||||
|
* idx index of array to place oid
|
||||||
|
*
|
||||||
|
* returns 0 on success
|
||||||
|
*/
|
||||||
|
int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
|
||||||
|
void* heap)
|
||||||
|
{
|
||||||
|
byte oid[MAX_OID_SZ];
|
||||||
|
word32 oidSz = MAX_OID_SZ;
|
||||||
|
|
||||||
|
if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
|
||||||
|
WOLFSSL_MSG("Either idx or sz was too large");
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
|
||||||
|
cert->extKeyUsageOIDSz[idx] = oidSz;
|
||||||
|
cert->extKeyUsage |= EXTKEYUSE_USER;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_EKU_OID */
|
||||||
#endif /* WOLFSSL_CERT_EXT */
|
#endif /* WOLFSSL_CERT_EXT */
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,6 +198,9 @@
|
|||||||
|
|
||||||
#include "wolfcrypt/test/test.h"
|
#include "wolfcrypt/test/test.h"
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_MULTI_ATTRIB)
|
||||||
|
static void initDefaultName(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* for async devices */
|
/* for async devices */
|
||||||
static int devId = INVALID_DEVID;
|
static int devId = INVALID_DEVID;
|
||||||
@ -427,6 +430,10 @@ int wolfcrypt_test(void* args)
|
|||||||
#endif /* USE_FAST_MATH */
|
#endif /* USE_FAST_MATH */
|
||||||
#endif /* !NO_BIG_INT */
|
#endif /* !NO_BIG_INT */
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_MULTI_ATTRIB)
|
||||||
|
initDefaultName();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||||
ret = wolfAsync_DevOpen(&devId);
|
ret = wolfAsync_DevOpen(&devId);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -7638,6 +7645,54 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_CERT_GEN
|
#ifdef WOLFSSL_CERT_GEN
|
||||||
|
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||||
|
static CertName certDefaultName;
|
||||||
|
static void initDefaultName(void)
|
||||||
|
{
|
||||||
|
XMEMCPY(certDefaultName.country, "US", sizeof("US"));
|
||||||
|
certDefaultName.countryEnc = CTC_PRINTABLE;
|
||||||
|
XMEMCPY(certDefaultName.state, "Orgeon", sizeof("Orgeon"));
|
||||||
|
certDefaultName.stateEnc = CTC_UTF8;
|
||||||
|
XMEMCPY(certDefaultName.locality, "Portland", sizeof("Portland"));
|
||||||
|
certDefaultName.localityEnc = CTC_UTF8;
|
||||||
|
XMEMCPY(certDefaultName.sur, "Test", sizeof("Test"));
|
||||||
|
certDefaultName.surEnc = CTC_UTF8;
|
||||||
|
XMEMCPY(certDefaultName.org, "wolfSSL", sizeof("wolfSSL"));
|
||||||
|
certDefaultName.orgEnc = CTC_UTF8;
|
||||||
|
XMEMCPY(certDefaultName.unit, "Development", sizeof("Development"));
|
||||||
|
certDefaultName.unitEnc = CTC_UTF8;
|
||||||
|
XMEMCPY(certDefaultName.commonName, "www.wolfssl.com", sizeof("www.wolfssl.com"));
|
||||||
|
certDefaultName.commonNameEnc = CTC_UTF8;
|
||||||
|
XMEMCPY(certDefaultName.email, "info@wolfssl.com", sizeof("info@wolfssl.com"));
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_CERT
|
||||||
|
{
|
||||||
|
NameAttrib* n;
|
||||||
|
/* test having additional OUs and setting DC */
|
||||||
|
n = &certDefaultName.name[0];
|
||||||
|
n->id = ASN_ORGUNIT_NAME;
|
||||||
|
n->type = CTC_UTF8;
|
||||||
|
n->sz = sizeof("Development-2");
|
||||||
|
XMEMCPY(n->value, "Development-2", sizeof("Development-2"));
|
||||||
|
|
||||||
|
#if CTC_MAX_ATTRIB > 3
|
||||||
|
n = &certDefaultName.name[1];
|
||||||
|
n->id = ASN_DOMAIN_COMPONENT;
|
||||||
|
n->type = CTC_UTF8;
|
||||||
|
n->sz = sizeof("com");
|
||||||
|
XMEMCPY(n->value, "com", sizeof("com"));
|
||||||
|
|
||||||
|
n = &certDefaultName.name[2];
|
||||||
|
n->id = ASN_DOMAIN_COMPONENT;
|
||||||
|
n->type = CTC_UTF8;
|
||||||
|
n->sz = sizeof("wolfssl");
|
||||||
|
XMEMCPY(n->value, "wolfssl", sizeof("wolfssl"));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TEST_CERT */
|
||||||
|
}
|
||||||
|
#else
|
||||||
static const CertName certDefaultName = {
|
static const CertName certDefaultName = {
|
||||||
"US", CTC_PRINTABLE, /* country */
|
"US", CTC_PRINTABLE, /* country */
|
||||||
"Orgeon", CTC_UTF8, /* state */
|
"Orgeon", CTC_UTF8, /* state */
|
||||||
@ -7648,6 +7703,7 @@ static const CertName certDefaultName = {
|
|||||||
"www.wolfssl.com", CTC_UTF8, /* commonName */
|
"www.wolfssl.com", CTC_UTF8, /* commonName */
|
||||||
"info@wolfssl.com" /* email */
|
"info@wolfssl.com" /* email */
|
||||||
};
|
};
|
||||||
|
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||||
|
|
||||||
#ifdef WOLFSSL_CERT_EXT
|
#ifdef WOLFSSL_CERT_EXT
|
||||||
#if (defined(HAVE_ED25519) && defined(WOLFSSL_TEST_CERT)) || \
|
#if (defined(HAVE_ED25519) && defined(WOLFSSL_TEST_CERT)) || \
|
||||||
@ -9521,6 +9577,15 @@ int rsa_test(void)
|
|||||||
if (wc_SetKeyUsage(&myCert,"cRLSign,keyCertSign") != 0) {
|
if (wc_SetKeyUsage(&myCert,"cRLSign,keyCertSign") != 0) {
|
||||||
ERROR_OUT(-5575, exit_rsa);
|
ERROR_OUT(-5575, exit_rsa);
|
||||||
}
|
}
|
||||||
|
#ifdef WOLFSSL_EKU_OID
|
||||||
|
{
|
||||||
|
const char unique[] = "2.16.840.1.111111.100.1.10.1";
|
||||||
|
if (wc_SetExtKeyUsageOID(&myCert, unique, sizeof(unique), 0,
|
||||||
|
HEAP_HINT) != 0) {
|
||||||
|
ERROR_OUT(-5651, exit_rsa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_EKU_OID */
|
||||||
#endif /* WOLFSSL_CERT_EXT */
|
#endif /* WOLFSSL_CERT_EXT */
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -10113,6 +10178,15 @@ int rsa_test(void)
|
|||||||
"emailProtection,timeStamping,OCSPSigning") != 0) {
|
"emailProtection,timeStamping,OCSPSigning") != 0) {
|
||||||
ERROR_OUT(-5645, exit_rsa);
|
ERROR_OUT(-5645, exit_rsa);
|
||||||
}
|
}
|
||||||
|
#ifdef WOLFSSL_EKU_OID
|
||||||
|
{
|
||||||
|
const char unique[] = "2.16.840.1.111111.100.1.10.1";
|
||||||
|
if (wc_SetExtKeyUsageOID(&req, unique, sizeof(unique), 0,
|
||||||
|
HEAP_HINT) != 0) {
|
||||||
|
ERROR_OUT(-5652, exit_rsa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_EKU_OID */
|
||||||
#endif /* WOLFSSL_CERT_EXT */
|
#endif /* WOLFSSL_CERT_EXT */
|
||||||
|
|
||||||
derSz = wc_MakeCertReq(&req, der, FOURK_BUF, &key, NULL);
|
derSz = wc_MakeCertReq(&req, der, FOURK_BUF, &key, NULL);
|
||||||
|
@ -194,7 +194,8 @@ enum Misc_ASN {
|
|||||||
#ifdef WOLFSSL_CERT_EXT
|
#ifdef WOLFSSL_CERT_EXT
|
||||||
MAX_KID_SZ = 45, /* Max encoded KID length (SHA-256 case) */
|
MAX_KID_SZ = 45, /* Max encoded KID length (SHA-256 case) */
|
||||||
MAX_KEYUSAGE_SZ = 18, /* Max encoded Key Usage length */
|
MAX_KEYUSAGE_SZ = 18, /* Max encoded Key Usage length */
|
||||||
MAX_EXTKEYUSAGE_SZ = 12 + (6 * (8 + 2)), /* Max encoded ExtKeyUsage
|
MAX_EXTKEYUSAGE_SZ = 12 + (6 * (8 + 2)) +
|
||||||
|
CTC_MAX_EKU_OID_SZ, /* Max encoded ExtKeyUsage
|
||||||
(SEQ/LEN + OBJID + OCTSTR/LEN + SEQ + (6 * (SEQ + OID))) */
|
(SEQ/LEN + OBJID + OCTSTR/LEN + SEQ + (6 * (SEQ + OID))) */
|
||||||
MAX_CERTPOL_NB = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */
|
MAX_CERTPOL_NB = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */
|
||||||
MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ,
|
MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ,
|
||||||
@ -398,6 +399,7 @@ enum KeyIdType {
|
|||||||
#define KEYUSE_DECIPHER_ONLY 0x8000
|
#define KEYUSE_DECIPHER_ONLY 0x8000
|
||||||
|
|
||||||
/* Extended Key Usage bits (internal mapping only) */
|
/* Extended Key Usage bits (internal mapping only) */
|
||||||
|
#define EXTKEYUSE_USER 0x80
|
||||||
#define EXTKEYUSE_OCSP_SIGN 0x40
|
#define EXTKEYUSE_OCSP_SIGN 0x40
|
||||||
#define EXTKEYUSE_TIMESTAMP 0x20
|
#define EXTKEYUSE_TIMESTAMP 0x20
|
||||||
#define EXTKEYUSE_EMAILPROT 0x10
|
#define EXTKEYUSE_EMAILPROT 0x10
|
||||||
@ -876,6 +878,7 @@ enum cert_enums {
|
|||||||
NAME_ENTRIES = 8,
|
NAME_ENTRIES = 8,
|
||||||
JOINT_LEN = 2,
|
JOINT_LEN = 2,
|
||||||
EMAIL_JOINT_LEN = 9,
|
EMAIL_JOINT_LEN = 9,
|
||||||
|
PILOT_JOINT_LEN = 10,
|
||||||
RSA_KEY = 10,
|
RSA_KEY = 10,
|
||||||
NTRU_KEY = 11,
|
NTRU_KEY = 11,
|
||||||
ECC_KEY = 12,
|
ECC_KEY = 12,
|
||||||
|
@ -113,6 +113,34 @@ enum Ctc_Misc {
|
|||||||
|
|
||||||
#ifdef WOLFSSL_CERT_GEN
|
#ifdef WOLFSSL_CERT_GEN
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_EKU_OID
|
||||||
|
#ifndef CTC_MAX_EKU_NB
|
||||||
|
#define CTC_MAX_EKU_NB 1
|
||||||
|
#endif
|
||||||
|
#ifndef CTC_MAX_EKU_OID_SZ
|
||||||
|
#define CTC_MAX_EKU_OID_SZ 30
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#undef CTC_MAX_EKU_OID_SZ
|
||||||
|
#define CTC_MAX_EKU_OID_SZ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||||
|
#ifndef CTC_MAX_ATTRIB
|
||||||
|
#define CTC_MAX_ATTRIB 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ASN Encoded Name field */
|
||||||
|
typedef struct NameAttrib {
|
||||||
|
int sz; /* actual string value length */
|
||||||
|
int id; /* id of name */
|
||||||
|
int type; /* enc of name */
|
||||||
|
char value[CTC_NAME_SIZE]; /* name */
|
||||||
|
} NameAttrib;
|
||||||
|
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||||
|
|
||||||
|
|
||||||
typedef struct CertName {
|
typedef struct CertName {
|
||||||
char country[CTC_NAME_SIZE];
|
char country[CTC_NAME_SIZE];
|
||||||
char countryEnc;
|
char countryEnc;
|
||||||
@ -129,6 +157,9 @@ typedef struct CertName {
|
|||||||
char commonName[CTC_NAME_SIZE];
|
char commonName[CTC_NAME_SIZE];
|
||||||
char commonNameEnc;
|
char commonNameEnc;
|
||||||
char email[CTC_NAME_SIZE]; /* !!!! email has to be last !!!! */
|
char email[CTC_NAME_SIZE]; /* !!!! email has to be last !!!! */
|
||||||
|
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||||
|
NameAttrib name[CTC_MAX_ATTRIB];
|
||||||
|
#endif
|
||||||
} CertName;
|
} CertName;
|
||||||
|
|
||||||
|
|
||||||
@ -161,6 +192,11 @@ typedef struct Cert {
|
|||||||
int akidSz; /* AKID size in bytes */
|
int akidSz; /* AKID size in bytes */
|
||||||
word16 keyUsage; /* Key Usage */
|
word16 keyUsage; /* Key Usage */
|
||||||
byte extKeyUsage; /* Extended Key Usage */
|
byte extKeyUsage; /* Extended Key Usage */
|
||||||
|
#ifdef WOLFSSL_EKU_OID
|
||||||
|
/* Extended Key Usage OIDs */
|
||||||
|
byte extKeyUsageOID[CTC_MAX_EKU_NB][CTC_MAX_EKU_OID_SZ];
|
||||||
|
byte extKeyUsageOIDSz[CTC_MAX_EKU_NB];
|
||||||
|
#endif
|
||||||
char certPolicies[CTC_MAX_CERTPOL_NB][CTC_MAX_CERTPOL_SZ];
|
char certPolicies[CTC_MAX_CERTPOL_NB][CTC_MAX_CERTPOL_SZ];
|
||||||
word16 certPoliciesNb; /* Number of Cert Policy */
|
word16 certPoliciesNb; /* Number of Cert Policy */
|
||||||
#endif
|
#endif
|
||||||
@ -243,6 +279,14 @@ WOLFSSL_API int wc_SetKeyUsage(Cert *cert, const char *value);
|
|||||||
*/
|
*/
|
||||||
WOLFSSL_API int wc_SetExtKeyUsage(Cert *cert, const char *value);
|
WOLFSSL_API int wc_SetExtKeyUsage(Cert *cert, const char *value);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_EKU_OID
|
||||||
|
/* Set ExtendedKeyUsage with unique OID
|
||||||
|
* oid is expected to be in byte representation
|
||||||
|
*/
|
||||||
|
WOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz,
|
||||||
|
byte idx, void* heap);
|
||||||
|
#endif /* WOLFSSL_EKU_OID */
|
||||||
#endif /* WOLFSSL_CERT_EXT */
|
#endif /* WOLFSSL_CERT_EXT */
|
||||||
|
|
||||||
#ifdef HAVE_NTRU
|
#ifdef HAVE_NTRU
|
||||||
|
Reference in New Issue
Block a user