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:
commit
73dbc8f6e7
@ -519,7 +519,8 @@ fi
|
||||
if test "$ENABLED_OPENSSLEXTRA" = "x509small"
|
||||
then
|
||||
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
|
||||
|
||||
# High Strength Build
|
||||
|
@ -7808,76 +7808,48 @@ int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
|
||||
*/
|
||||
int wc_InitCert(Cert* cert)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cert == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMSET(cert, 0, sizeof(Cert));
|
||||
|
||||
cert->version = 2; /* version 3 is hex 2 */
|
||||
cert->sigType = CTC_SHAwRSA;
|
||||
cert->daysValid = 500;
|
||||
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;
|
||||
XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
|
||||
cert->serialSz = 0;
|
||||
|
||||
cert->issuer.country[0] = '\0';
|
||||
cert->issuer.countryEnc = CTC_PRINTABLE;
|
||||
cert->issuer.state[0] = '\0';
|
||||
cert->issuer.stateEnc = CTC_UTF8;
|
||||
cert->issuer.locality[0] = '\0';
|
||||
cert->issuer.localityEnc = CTC_UTF8;
|
||||
cert->issuer.sur[0] = '\0';
|
||||
cert->issuer.surEnc = CTC_UTF8;
|
||||
cert->issuer.org[0] = '\0';
|
||||
cert->issuer.orgEnc = CTC_UTF8;
|
||||
cert->issuer.unit[0] = '\0';
|
||||
cert->issuer.unitEnc = CTC_UTF8;
|
||||
cert->issuer.commonName[0] = '\0';
|
||||
cert->issuer.commonNameEnc = CTC_UTF8;
|
||||
cert->issuer.email[0] = '\0';
|
||||
|
||||
cert->subject.country[0] = '\0';
|
||||
cert->subject.countryEnc = CTC_PRINTABLE;
|
||||
cert->subject.state[0] = '\0';
|
||||
cert->subject.stateEnc = CTC_UTF8;
|
||||
cert->subject.locality[0] = '\0';
|
||||
cert->subject.localityEnc = CTC_UTF8;
|
||||
cert->subject.sur[0] = '\0';
|
||||
cert->subject.surEnc = CTC_UTF8;
|
||||
cert->subject.org[0] = '\0';
|
||||
cert->subject.orgEnc = CTC_UTF8;
|
||||
cert->subject.unit[0] = '\0';
|
||||
cert->subject.unitEnc = CTC_UTF8;
|
||||
cert->subject.commonName[0] = '\0';
|
||||
cert->subject.commonNameEnc = CTC_UTF8;
|
||||
cert->subject.email[0] = '\0';
|
||||
|
||||
#ifdef WOLFSSL_CERT_REQ
|
||||
cert->challengePw[0] ='\0';
|
||||
#endif
|
||||
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||
for (i = 0; i < CTC_MAX_ATTRIB; i++) {
|
||||
cert->issuer.name[i].type = CTC_UTF8;
|
||||
cert->subject.name[i].type = CTC_UTF8;
|
||||
}
|
||||
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||
|
||||
#ifdef WOLFSSL_HEAP_TEST
|
||||
cert->heap = (void*)WOLFSSL_HEAP_TEST;
|
||||
#else
|
||||
cert->heap = NULL;
|
||||
#endif
|
||||
|
||||
(void)i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -8432,8 +8404,7 @@ static byte GetNameId(int idx)
|
||||
return ASN_COMMON_NAME;
|
||||
|
||||
case 7:
|
||||
/* email uses different id type */
|
||||
return 0;
|
||||
return ASN_EMAIL_NAME;
|
||||
|
||||
default:
|
||||
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 */
|
||||
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;
|
||||
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)
|
||||
ret |= SetOjectIdValue(output, outSz, &idx,
|
||||
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)
|
||||
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) */
|
||||
idx += oidListSz;
|
||||
|
||||
(void)cert;
|
||||
return idx;
|
||||
}
|
||||
|
||||
@ -8870,6 +8855,134 @@ static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length)
|
||||
}
|
||||
#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 */
|
||||
int SetName(byte* output, word32 outputSz, CertName* name)
|
||||
@ -8880,6 +8993,10 @@ int SetName(byte* output, word32 outputSz, CertName* name)
|
||||
#else
|
||||
EncodedName names[NAME_ENTRIES];
|
||||
#endif
|
||||
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||
EncodedName addNames[CTC_MAX_ATTRIB];
|
||||
int j, type;
|
||||
#endif
|
||||
|
||||
if (output == NULL || name == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
@ -8895,101 +9012,38 @@ int SetName(byte* output, word32 outputSz, CertName* name)
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NAME_ENTRIES; i++) {
|
||||
int ret;
|
||||
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;
|
||||
int strLen = (int)XSTRLEN(nameStr);
|
||||
int thisLen = strLen;
|
||||
int firstSz, secondSz, seqSz, setSz;
|
||||
|
||||
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
|
||||
ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),
|
||||
GetNameId(i));
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_COUNTRY_SIZE_E;
|
||||
}
|
||||
|
||||
secondSz = SetLength(strLen, secondLen);
|
||||
thisLen += secondSz;
|
||||
if (email) {
|
||||
thisLen += EMAIL_JOINT_LEN;
|
||||
thisLen ++; /* id type */
|
||||
firstSz = SetObjectId(EMAIL_JOINT_LEN, firstLen);
|
||||
}
|
||||
else {
|
||||
thisLen++; /* str type */
|
||||
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
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
totalBytes += ret;
|
||||
}
|
||||
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||
for (i = 0; i < CTC_MAX_ATTRIB; i++) {
|
||||
if (name->name[i].sz > 0) {
|
||||
int ret;
|
||||
ret = wc_EncodeName(&addNames[i], name->name[i].value,
|
||||
name->name[i].type, name->name[i].id);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* store it */
|
||||
idx = 0;
|
||||
/* set */
|
||||
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;
|
||||
totalBytes += ret;
|
||||
}
|
||||
else {
|
||||
addNames[i].used = 0;
|
||||
}
|
||||
else
|
||||
names[i].used = 0;
|
||||
}
|
||||
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||
|
||||
/* header */
|
||||
idx = SetSequence(totalBytes, output);
|
||||
@ -9002,6 +9056,46 @@ int SetName(byte* output, word32 outputSz, CertName* name)
|
||||
}
|
||||
|
||||
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 (outputSz < (word32)(idx+names[i].totalLen)) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@ -9220,7 +9314,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
|
||||
|
||||
/* Extended Key Usage */
|
||||
if (cert->extKeyUsage != 0){
|
||||
der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
|
||||
der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
|
||||
sizeof(der->extKeyUsage), cert->extKeyUsage);
|
||||
if (der->extKeyUsageSz <= 0)
|
||||
return EXTKEYUSAGE_E;
|
||||
@ -9753,7 +9847,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
|
||||
|
||||
/* Extended Key Usage */
|
||||
if (cert->extKeyUsage != 0){
|
||||
der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
|
||||
der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
|
||||
sizeof(der->extKeyUsage), cert->extKeyUsage);
|
||||
if (der->extKeyUsageSz <= 0)
|
||||
return EXTKEYUSAGE_E;
|
||||
@ -10486,6 +10580,38 @@ int wc_SetExtKeyUsage(Cert *cert, const char *value)
|
||||
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
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 */
|
||||
|
||||
|
||||
|
@ -198,6 +198,9 @@
|
||||
|
||||
#include "wolfcrypt/test/test.h"
|
||||
|
||||
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_MULTI_ATTRIB)
|
||||
static void initDefaultName(void);
|
||||
#endif
|
||||
|
||||
/* for async devices */
|
||||
static int devId = INVALID_DEVID;
|
||||
@ -427,6 +430,10 @@ int wolfcrypt_test(void* args)
|
||||
#endif /* USE_FAST_MATH */
|
||||
#endif /* !NO_BIG_INT */
|
||||
|
||||
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_MULTI_ATTRIB)
|
||||
initDefaultName();
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ret = wolfAsync_DevOpen(&devId);
|
||||
if (ret < 0) {
|
||||
@ -7638,6 +7645,54 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
|
||||
|
||||
|
||||
#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 = {
|
||||
"US", CTC_PRINTABLE, /* country */
|
||||
"Orgeon", CTC_UTF8, /* state */
|
||||
@ -7648,6 +7703,7 @@ static const CertName certDefaultName = {
|
||||
"www.wolfssl.com", CTC_UTF8, /* commonName */
|
||||
"info@wolfssl.com" /* email */
|
||||
};
|
||||
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
#if (defined(HAVE_ED25519) && defined(WOLFSSL_TEST_CERT)) || \
|
||||
@ -9521,6 +9577,15 @@ int rsa_test(void)
|
||||
if (wc_SetKeyUsage(&myCert,"cRLSign,keyCertSign") != 0) {
|
||||
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 */
|
||||
|
||||
ret = 0;
|
||||
@ -10113,6 +10178,15 @@ int rsa_test(void)
|
||||
"emailProtection,timeStamping,OCSPSigning") != 0) {
|
||||
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 */
|
||||
|
||||
derSz = wc_MakeCertReq(&req, der, FOURK_BUF, &key, NULL);
|
||||
|
@ -194,7 +194,8 @@ enum Misc_ASN {
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
MAX_KID_SZ = 45, /* Max encoded KID length (SHA-256 case) */
|
||||
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))) */
|
||||
MAX_CERTPOL_NB = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */
|
||||
MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ,
|
||||
@ -398,6 +399,7 @@ enum KeyIdType {
|
||||
#define KEYUSE_DECIPHER_ONLY 0x8000
|
||||
|
||||
/* Extended Key Usage bits (internal mapping only) */
|
||||
#define EXTKEYUSE_USER 0x80
|
||||
#define EXTKEYUSE_OCSP_SIGN 0x40
|
||||
#define EXTKEYUSE_TIMESTAMP 0x20
|
||||
#define EXTKEYUSE_EMAILPROT 0x10
|
||||
@ -876,6 +878,7 @@ enum cert_enums {
|
||||
NAME_ENTRIES = 8,
|
||||
JOINT_LEN = 2,
|
||||
EMAIL_JOINT_LEN = 9,
|
||||
PILOT_JOINT_LEN = 10,
|
||||
RSA_KEY = 10,
|
||||
NTRU_KEY = 11,
|
||||
ECC_KEY = 12,
|
||||
|
@ -113,6 +113,34 @@ enum Ctc_Misc {
|
||||
|
||||
#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 {
|
||||
char country[CTC_NAME_SIZE];
|
||||
char countryEnc;
|
||||
@ -129,6 +157,9 @@ typedef struct CertName {
|
||||
char commonName[CTC_NAME_SIZE];
|
||||
char commonNameEnc;
|
||||
char email[CTC_NAME_SIZE]; /* !!!! email has to be last !!!! */
|
||||
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||
NameAttrib name[CTC_MAX_ATTRIB];
|
||||
#endif
|
||||
} CertName;
|
||||
|
||||
|
||||
@ -161,6 +192,11 @@ typedef struct Cert {
|
||||
int akidSz; /* AKID size in bytes */
|
||||
word16 keyUsage; /* 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];
|
||||
word16 certPoliciesNb; /* Number of Cert Policy */
|
||||
#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);
|
||||
|
||||
|
||||
#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 */
|
||||
|
||||
#ifdef HAVE_NTRU
|
||||
|
Loading…
x
Reference in New Issue
Block a user