From 453aa16e8d6ba3fbe2422a83174bb6b6143b9c7a Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 23 Feb 2018 10:46:26 -0700 Subject: [PATCH 1/2] Add support for writing multiple OUs, DCs and for writing a unique EKU OID --- configure.ac | 3 +- wolfcrypt/src/asn.c | 354 ++++++++++++++++++++++++--------- wolfcrypt/test/test.c | 65 ++++++ wolfssl/wolfcrypt/asn.h | 2 + wolfssl/wolfcrypt/asn_public.h | 41 ++++ 5 files changed, 372 insertions(+), 93 deletions(-) diff --git a/configure.ac b/configure.ac index bf5d630ae..80bfa23cf 100644 --- a/configure.ac +++ b/configure.ac @@ -518,7 +518,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 diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 88083370d..4ae80e8e7 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -7808,6 +7808,8 @@ int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen) */ int wc_InitCert(Cert* cert) { + int i; + if (cert == NULL) { return BAD_FUNC_ARG; } @@ -7869,6 +7871,19 @@ int wc_InitCert(Cert* cert) cert->subject.commonNameEnc = CTC_UTF8; cert->subject.email[0] = '\0'; +#ifdef WOLFSSL_MULTI_ATTRIB + for (i = 0; i < CTC_MAX_ATTRIB; i++) { + cert->issuer.name[i].sz = 0; + cert->issuer.name[i].id = 0; + cert->issuer.name[i].type = CTC_UTF8; + cert->issuer.name[i].value[0] = '\0'; + + cert->subject.name[i].sz = 0; + cert->subject.name[i].id = 0; + cert->subject.name[i].type = CTC_UTF8; + cert->subject.name[i].value[0] = '\0'; + } +#endif /* WOLFSSL_MULTI_ATTRIB */ #ifdef WOLFSSL_CERT_REQ cert->challengePw[0] ='\0'; #endif @@ -7878,6 +7893,7 @@ int wc_InitCert(Cert* cert) cert->heap = NULL; #endif + (void)i; return 0; } @@ -8432,8 +8448,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 +8666,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 +8703,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 +8740,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 +8899,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 _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 +9037,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 +9056,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 = _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 = _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 +9100,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 +9358,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 +9891,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 +10624,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 >= CTX_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 */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 29f586fe8..3e23a8ea6 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -195,6 +195,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; @@ -423,6 +426,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) { @@ -7621,6 +7628,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 */ @@ -7631,6 +7686,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)) || \ @@ -9309,6 +9365,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; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 2d43c6a89..355bede32 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -398,6 +398,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 +877,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, diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 595c2f525..0101a65be 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -113,6 +113,31 @@ enum Ctc_Misc { #ifdef WOLFSSL_CERT_GEN +#ifdef WOLFSSL_EKU_OID + #ifndef CTC_MAX_EKU_NB + #define CTC_MAX_EKU_NB 1 + #endif + #ifndef CTX_MAX_EKU_OID_SZ + #define CTX_MAX_EKU_OID_SZ 30 + #endif +#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 +154,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 +189,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][CTX_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 +276,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 From f2cbab95b0c6819112c4182e63caa8ff69f14ab6 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 23 Feb 2018 17:22:48 -0700 Subject: [PATCH 2/2] change _EncodeName, add test with wc_MakeCertReq, add XMEMSET with Cert init --- wolfcrypt/src/asn.c | 60 +++++----------------------------- wolfcrypt/test/test.c | 9 +++++ wolfssl/wolfcrypt/asn.h | 3 +- wolfssl/wolfcrypt/asn_public.h | 9 +++-- 4 files changed, 25 insertions(+), 56 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 4ae80e8e7..96253e637 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -7814,83 +7814,39 @@ int wc_InitCert(Cert* cert) 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_MULTI_ATTRIB for (i = 0; i < CTC_MAX_ATTRIB; i++) { - cert->issuer.name[i].sz = 0; - cert->issuer.name[i].id = 0; - cert->issuer.name[i].type = CTC_UTF8; - cert->issuer.name[i].value[0] = '\0'; - - cert->subject.name[i].sz = 0; - cert->subject.name[i].id = 0; + cert->issuer.name[i].type = CTC_UTF8; cert->subject.name[i].type = CTC_UTF8; - cert->subject.name[i].value[0] = '\0'; } #endif /* WOLFSSL_MULTI_ATTRIB */ -#ifdef WOLFSSL_CERT_REQ - cert->challengePw[0] ='\0'; -#endif + #ifdef WOLFSSL_HEAP_TEST cert->heap = (void*)WOLFSSL_HEAP_TEST; -#else - cert->heap = NULL; #endif (void)i; @@ -8908,7 +8864,7 @@ static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length) * * returns length on success */ -static int _EncodeName(EncodedName* name, const char* nameStr, char nameType, +static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, byte type) { word32 idx = 0; @@ -9059,7 +9015,7 @@ int SetName(byte* output, word32 outputSz, CertName* name) int ret; const char* nameStr = GetOneName(name, i); - ret = _EncodeName(&names[i], nameStr, GetNameType(name, i), + ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i), GetNameId(i)); if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK @@ -9073,7 +9029,7 @@ int SetName(byte* output, word32 outputSz, CertName* name) for (i = 0; i < CTC_MAX_ATTRIB; i++) { if (name->name[i].sz > 0) { int ret; - ret = _EncodeName(&addNames[i], name->name[i].value, + ret = wc_EncodeName(&addNames[i], name->name[i].value, name->name[i].type, name->name[i].id); if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK @@ -10640,7 +10596,7 @@ int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx, byte oid[MAX_OID_SZ]; word32 oidSz = MAX_OID_SZ; - if (idx >= CTC_MAX_EKU_NB || sz >= CTX_MAX_EKU_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; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 3e23a8ea6..fc5368803 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9966,6 +9966,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); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 355bede32..54c2c5757 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -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, diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 0101a65be..fbc03fcc0 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -117,9 +117,12 @@ enum Ctc_Misc { #ifndef CTC_MAX_EKU_NB #define CTC_MAX_EKU_NB 1 #endif - #ifndef CTX_MAX_EKU_OID_SZ - #define CTX_MAX_EKU_OID_SZ 30 + #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 @@ -191,7 +194,7 @@ typedef struct Cert { byte extKeyUsage; /* Extended Key Usage */ #ifdef WOLFSSL_EKU_OID /* Extended Key Usage OIDs */ - byte extKeyUsageOID[CTC_MAX_EKU_NB][CTX_MAX_EKU_OID_SZ]; + 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];