From 7524ededd326e564d615c8ba3e860d6621af6fde Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 23 Nov 2021 09:51:13 -0800 Subject: [PATCH 1/4] Support for Custom OID in subject and CSR request extension: * Adds new build option `WOLFSSL_CUSTOM_OID` for supplying a custom OID in a CSR * Fixes in ASN template CSR generation. * Fix to allow calling `wc_Ed25519PublicKeyToDer` and `wc_Ed448PublicKeyToDer` with NULL output buffer to get length only. * Refactor of the certificate subject name encoding. * Refactor of the OID's to consolidate. * Improvements to the Domain Component API unit test. ZD 12943 --- tests/api.c | 57 ++- wolfcrypt/src/asn.c | 728 +++++++++++++++++---------------- wolfcrypt/test/test.c | 83 ++-- wolfssl/wolfcrypt/asn.h | 11 +- wolfssl/wolfcrypt/asn_public.h | 16 + 5 files changed, 473 insertions(+), 422 deletions(-) diff --git a/tests/api.c b/tests/api.c index c27e7f7f1..9f4cacc31 100644 --- a/tests/api.c +++ b/tests/api.c @@ -344,8 +344,7 @@ #if (defined(SESSION_CERTS) && defined(TEST_PEER_CERT_CHAIN)) || \ defined(HAVE_SESSION_TICKET) || (defined(OPENSSL_EXTRA) && \ - defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && \ - !defined(WOLFSSL_ASN_TEMPLATE)) + defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) /* for testing SSL_get_peer_cert_chain, or SESSION_TICKET_HINT_DEFAULT, * or for setting authKeyIdSrc in WOLFSSL_X509 */ #include "wolfssl/internal.h" @@ -41545,24 +41544,25 @@ static void test_wolfSSL_X509_check_ip_asc(void){ static void test_wolfSSL_DC_cert(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \ - defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_KEY_GEN) && \ - defined(WOLFSSL_CERT_EXT) - Cert cert; - RsaKey key; - WC_RNG rng; - byte der[FOURK_BUF]; - int certSz; - int ret, idx; - const byte mySerial[8] = {1,2,3,4,5,6,7,8}; - const unsigned char* pt; - - X509* x509; - X509_NAME* x509name; - X509_NAME_ENTRY* entry; - ASN1_STRING* entryValue; - +#if !defined(NO_RSA) && defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) + int ret; + Cert cert; CertName name; + RsaKey key; + WC_RNG rng; + byte der[FOURK_BUF]; + word32 idx; + const byte mySerial[8] = {1,2,3,4,5,6,7,8}; + +#ifdef OPENSSL_EXTRA + const unsigned char* pt; + int certSz; + X509* x509; + X509_NAME* x509name; + X509_NAME_ENTRY* entry; + ASN1_STRING* entryValue; +#endif + printf(testingFmt, "wolfSSL Certs with DC"); XMEMSET(&name, 0, sizeof(CertName)); @@ -41609,8 +41609,19 @@ static void test_wolfSSL_DC_cert(void) #else AssertIntEQ(wc_InitRng(&rng), 0); #endif - AssertIntEQ(wc_MakeRsaKey(&key, 2048, 3, &rng), 0); + /* load test RSA key */ + idx = 0; +#if defined(USE_CERT_BUFFERS_1024) + AssertIntEQ(wc_RsaPrivateKeyDecode(server_key_der_1024, &idx, &key, + sizeof_server_key_der_1024), 0); +#elif defined(USE_CERT_BUFFERS_2048) + AssertIntEQ(wc_RsaPrivateKeyDecode(server_key_der_2048, &idx, &key, + sizeof_server_key_der_2048), 0); +#else + /* error case, no RSA key loaded, happens later */ + (void)idx; +#endif XMEMSET(&cert, 0 , sizeof(Cert)); AssertIntEQ(wc_InitCert(&cert), 0); @@ -41641,9 +41652,10 @@ static void test_wolfSSL_DC_cert(void) } } while (ret == WC_PENDING_E); AssertIntGT(ret, 0); - certSz = ret; +#ifdef OPENSSL_EXTRA /* der holds a certificate with DC's now check X509 parsing of it */ + certSz = ret; pt = der; AssertNotNull(x509 = d2i_X509(NULL, &pt, certSz)); AssertNotNull(x509name = X509_get_subject_name(x509)); @@ -41681,8 +41693,9 @@ static void test_wolfSSL_DC_cert(void) AssertNull(entry = X509_NAME_get_entry(x509name, 11)); AssertNull(entry = X509_NAME_get_entry(x509name, 20)); - (void)idx; X509_free(x509); +#endif /* OPENSSL_EXTRA */ + wc_FreeRsaKey(&key); wc_FreeRng(&rng); printf(resultFmt, passed); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 0edab12a2..7f6ba3a9b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -75,7 +75,9 @@ ASN Options: type issues for testing * CRLDP_VALIDATE_DATA: For ASN template only, validates the reason data * WOLFSSL_AKID_NAME: Enable support for full AuthorityKeyIdentifier extension. - * Only supports copying full AKID from an existing certificate. + Only supports copying full AKID from an existing certificate. + * WOLFSSL_CUSTOM_OID: Enable custom OID support for subject and request + extensions */ #ifndef NO_ASN @@ -3980,10 +3982,11 @@ static const byte extExtKeyUsageOcspSignOid[] = {43, 6, 1, 5, 5, 7, 3, 9}; #ifdef WOLFSSL_CERT_REQ /* csrAttrType */ -static const byte attrUnstructuredNameOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 2}; -static const byte attrPkcs9ContentTypeOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 3}; +static const byte attrEmailOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 1}; +static const byte attrUnstructuredNameOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 2}; +static const byte attrPkcs9ContentTypeOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 3}; static const byte attrChallengePasswordOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 7}; -static const byte attrExtensionRequestOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 14}; +static const byte attrExtensionRequestOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 14}; static const byte attrSerialNumberOid[] = {85, 4, 5}; #endif @@ -4018,6 +4021,14 @@ static const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24}; static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7}; #endif +#ifdef WOLFSSL_CERT_REQ +/* Pilot attribute types (0.9.2342.19200300.100.1.*) */ +#ifdef WOLFSSL_ASN_TEMPLATE +static const byte uidOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 1}; /* user id */ +#endif +static const byte dcOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 25}; /* domain component */ +#endif + /* Looks up the ID/type of an OID. * @@ -10519,20 +10530,6 @@ static const CertNameData certNameSubject[] = { static const int certNameSubjectSz = (int) (sizeof(certNameSubject) / sizeof(CertNameData)); -/* Full email OID. */ -static const byte emailOid[] = { - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 -}; -/* Full user id OID. */ -static const byte uidOid[] = { - 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01 -}; -/* Full domain component OID. */ -static const byte dcOid[] = { - 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 -}; - - /* ASN.1 template for an RDN. * X.509: RFC 5280, 4.1.2.4 - RelativeDistinguishedName */ @@ -10723,7 +10720,7 @@ static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid, #endif } } - else if (oidSz == sizeof(emailOid) && XMEMCMP(oid, emailOid, oidSz) == 0) { + else if (oidSz == sizeof(attrEmailOid) && XMEMCMP(oid, attrEmailOid, oidSz) == 0) { /* Set the email id, type string, length and NID. */ id = ASN_EMAIL; typeStr = WOLFSSL_EMAIL_ADDR; @@ -20245,6 +20242,9 @@ typedef struct DerCert { #endif #ifdef WOLFSSL_CERT_REQ byte attrib[MAX_ATTRIB_SZ]; /* Cert req attributes encoded */ + #ifdef WOLFSSL_CUSTOM_OID + byte extCustom[MAX_ATTRIB_SZ]; /* Encoded user oid and value */ + #endif #endif #ifdef WOLFSSL_ALT_NAMES byte altNames[CTC_MAX_ALT_SIZE]; /* Alternative Names encoded */ @@ -20277,6 +20277,9 @@ typedef struct DerCert { int total; /* total encoded lengths */ #ifdef WOLFSSL_CERT_REQ int attribSz; + #ifdef WOLFSSL_CUSTOM_OID + int extCustomSz; + #endif #endif } DerCert; @@ -20818,7 +20821,7 @@ int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen, byte pubKey[ED25519_PUB_KEY_SIZE]; word32 pubKeyLen = (word32)sizeof(pubKey); - if (key == NULL || output == NULL) { + if (key == NULL) { return BAD_FUNC_ARG; } @@ -20851,7 +20854,7 @@ int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen, byte pubKey[ED448_PUB_KEY_SIZE]; word32 pubKeyLen = (word32)sizeof(pubKey); - if (key == NULL || output == NULL) { + if (key == NULL) { return BAD_FUNC_ARG; } @@ -20970,48 +20973,79 @@ static int CopyValidity(byte* output, Cert* cert) #endif /* !WOLFSSL_ASN_TEMPLATE */ #endif + +/* Simple name OID size. */ +#define NAME_OID_SZ 3 + +/* Domain name OIDs. */ +static const byte nameOid[][NAME_OID_SZ] = { + { 0x55, 0x04, ASN_COUNTRY_NAME }, + { 0x55, 0x04, ASN_STATE_NAME }, + { 0x55, 0x04, ASN_STREET_ADDR }, + { 0x55, 0x04, ASN_LOCALITY_NAME }, + { 0x55, 0x04, ASN_SUR_NAME }, + { 0x55, 0x04, ASN_ORG_NAME }, + { 0x00, 0x00, ASN_DOMAIN_COMPONENT}, /* not actual OID - see dcOid */ + /* list all DC values before OUs */ + { 0x55, 0x04, ASN_ORGUNIT_NAME }, + { 0x55, 0x04, ASN_COMMON_NAME }, + { 0x55, 0x04, ASN_SERIAL_NUMBER }, +#ifdef WOLFSSL_CERT_EXT + { 0x55, 0x04, ASN_BUS_CAT }, +#endif + { 0x55, 0x04, ASN_POSTAL_CODE }, + { 0x00, 0x00, ASN_EMAIL_NAME}, /* not actual OID - see attrEmailOid */ + { 0x00, 0x00, ASN_USER_ID}, /* not actual OID - see uidOid */ +#ifdef WOLFSSL_CUSTOM_OID + { 0x00, 0x00, ASN_CUSTOM_NAME} /* OID comes from CertOidField */ +#endif +}; +#define NAME_ENTRIES (int)(sizeof(nameOid)/NAME_OID_SZ) + + +/* Get ASN Name from index */ +byte GetCertNameId(int idx) +{ + if (idx < NAME_ENTRIES) + return nameOid[idx][2]; + return 0; +} + /* Get Which Name from index */ const char* GetOneCertName(CertName* name, int idx) { - switch (idx) { - case 0: + byte type = GetCertNameId(idx); + switch (type) { + case ASN_COUNTRY_NAME: return name->country; - - case 1: + case ASN_STATE_NAME: return name->state; - - case 2: + case ASN_STREET_ADDR: return name->street; - - case 3: + case ASN_LOCALITY_NAME: return name->locality; - - case 4: + case ASN_SUR_NAME: return name->sur; - - case 5: + case ASN_ORG_NAME: return name->org; - - case 6: + case ASN_ORGUNIT_NAME: return name->unit; - - case 7: + case ASN_COMMON_NAME: return name->commonName; - - case 8: + case ASN_SERIAL_NUMBER: return name->serialDev; - - case 9: + case ASN_POSTAL_CODE: return name->postalCode; - - case 10: -#ifdef WOLFSSL_CERT_EXT - return name->busCat; - - case 11: -#endif + case ASN_EMAIL_NAME: return name->email; - +#ifdef WOLFSSL_CERT_EXT + case ASN_BUS_CAT: + return name->busCat; +#endif +#ifdef WOLFSSL_CUSTOM_OID + case ASN_CUSTOM_NAME: + return (const char*)name->custom.val; +#endif default: return NULL; } @@ -21021,100 +21055,43 @@ const char* GetOneCertName(CertName* name, int idx) /* Get Which Name Encoding from index */ static char GetNameType(CertName* name, int idx) { - switch (idx) { - case 0: + byte type = GetCertNameId(idx); + switch (type) { + case ASN_COUNTRY_NAME: return name->countryEnc; - - case 1: + case ASN_STATE_NAME: return name->stateEnc; - - case 2: - return name->postalCodeEnc; - - case 3: + case ASN_STREET_ADDR: + return name->streetEnc; + case ASN_LOCALITY_NAME: return name->localityEnc; - - case 4: + case ASN_SUR_NAME: return name->surEnc; - - case 5: + case ASN_ORG_NAME: return name->orgEnc; - - case 6: + case ASN_ORGUNIT_NAME: return name->unitEnc; - - case 7: + case ASN_COMMON_NAME: return name->commonNameEnc; - - case 8: + case ASN_SERIAL_NUMBER: return name->serialDevEnc; - - case 9: + case ASN_POSTAL_CODE: return name->postalCodeEnc; - - case 10: + case ASN_EMAIL_NAME: + return 0; /* special */ #ifdef WOLFSSL_CERT_EXT + case ASN_BUS_CAT: return name->busCatEnc; - - case 11: #endif - /* FALL THROUGH */ - /* The last index, email name, does not have encoding type. - The empty case here is to keep track of it for future reference. */ +#ifdef WOLFSSL_CUSTOM_OID + case ASN_CUSTOM_NAME: + return name->custom.enc; +#endif default: return 0; } } - -/* Get ASN Name from index */ -byte GetCertNameId(int idx) -{ - switch (idx) { - case 0: - return ASN_COUNTRY_NAME; - - case 1: - return ASN_STATE_NAME; - - case 2: - return ASN_STREET_ADDR; - - case 3: - return ASN_LOCALITY_NAME; - - case 4: - return ASN_SUR_NAME; - - case 5: - return ASN_ORG_NAME; - - case 6: - return ASN_ORGUNIT_NAME; - - case 7: - return ASN_COMMON_NAME; - - case 8: - return ASN_SERIAL_NUMBER; - - case 9: - return ASN_POSTAL_CODE; - - case 10: -#ifdef WOLFSSL_CERT_EXT - return ASN_BUS_CAT; - - case 11: -#endif - return ASN_EMAIL_NAME; - - default: - return 0; - } -} - - #ifndef WOLFSSL_ASN_TEMPLATE /* Extensions ::= SEQUENCE OF Extension @@ -21874,8 +21851,8 @@ int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names) * emailTag tag of email i.e CTC_UTF8 * returns length on success */ -static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, - byte nameTag, byte type, byte emailTag) +static int EncodeName(EncodedName* name, const char* nameStr, + byte nameTag, byte type, byte emailTag, CertName* cname) { #if !defined(WOLFSSL_ASN_TEMPLATE) word32 idx = 0; @@ -21893,14 +21870,27 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, name->used = 0; return 0; } + thisLen = strLen = (int)XSTRLEN(nameStr); +#ifdef WOLFSSL_CUSTOM_OID + if (type == ASN_CUSTOM_NAME) { + if (cname == NULL || cname->custom.oidSz == 0) { + name->used = 0; + return 0; + } + thisLen = strLen = cname->custom.valSz; + } +#else + (void)cname; +#endif + 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) { + if (type == ASN_COUNTRY_NAME && strLen != CTC_COUNTRY_SIZE) { WOLFSSL_MSG("Country code size error"); return ASN_COUNTRY_SIZE_E; } @@ -21909,19 +21899,22 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, thisLen += secondSz; switch (type) { case ASN_EMAIL_NAME: /* email */ - thisLen += EMAIL_JOINT_LEN; - firstSz = EMAIL_JOINT_LEN; + thisLen += (int)sizeof(attrEmailOid); + firstSz = (int)sizeof(attrEmailOid); break; - case ASN_DOMAIN_COMPONENT: - thisLen += PILOT_JOINT_LEN; - firstSz = PILOT_JOINT_LEN; + thisLen += (int)sizeof(dcOid); + firstSz = (int)sizeof(dcOid); break; - + #ifdef WOLFSSL_CUSTOM_OID + case ASN_CUSTOM_NAME: + thisLen += cname->custom.oidSz; + firstSz = cname->custom.oidSz; + break; + #endif default: - thisLen++; /* str type */ - thisLen += JOINT_LEN; - firstSz = JOINT_LEN + 1; + thisLen += DN_OID_SZ; + firstSz = DN_OID_SZ; } thisLen++; /* id type */ firstSz = SetObjectId(firstSz, firstLen); @@ -21949,32 +21942,28 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, idx += firstSz; switch (type) { case ASN_EMAIL_NAME: - { - const byte EMAIL_OID[] = { - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 - }; /* email joint id */ - XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); - idx += (int)sizeof(EMAIL_OID); + XMEMCPY(name->encoded + idx, attrEmailOid, sizeof(attrEmailOid)); + idx += (int)sizeof(attrEmailOid); name->encoded[idx++] = emailTag; 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); + XMEMCPY(name->encoded + idx, dcOid, sizeof(dcOid)-1); + idx += (int)sizeof(dcOid)-1; /* id type */ name->encoded[idx++] = type; /* str type */ name->encoded[idx++] = nameTag; break; - } - + #ifdef WOLFSSL_CUSTOM_OID + case ASN_CUSTOM_NAME: + XMEMCPY(name->encoded + idx, cname->custom.oid, + cname->custom.oidSz); + idx += cname->custom.oidSz; + /* str type */ + name->encoded[idx++] = nameTag; + break; + #endif default: name->encoded[idx++] = 0x55; name->encoded[idx++] = 0x04; @@ -22003,6 +21992,7 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, int sz; const byte* oid; int oidSz; + word32 nameSz; /* Validate input parameters. */ if ((name == NULL) || (nameStr == NULL)) { @@ -22010,6 +22000,8 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, } if (ret == 0) { + nameSz = (word32)XSTRLEN(nameStr); + /* Clear data to use when encoding. */ XMEMSET(dataASN, 0, rdnASN_Length * sizeof(ASNSetData)); /* Copy the RDN encoding template. ASN.1 tag for the name string is set @@ -22020,8 +22012,8 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, switch (type) { case ASN_EMAIL_NAME: /* email OID different to standard types. */ - oid = emailOid; - oidSz = sizeof(emailOid); + oid = attrEmailOid; + oidSz = sizeof(attrEmailOid); /* Use email specific type/tag. */ nameTag = emailTag; break; @@ -22030,6 +22022,13 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, oid = dcOid; oidSz = sizeof(dcOid); break; + #ifdef WOLFSSL_CUSTOM_OID + case ASN_CUSTOM_NAME: + nameSz = cname->custom.valSz; + oid = cname->custom.oid; + oidSz = cname->custom.oidSz; + break; + #endif default: /* Construct OID using type. */ dnOid[2] = type; @@ -22041,8 +22040,7 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, /* Set OID corresponding to the name type. */ SetASN_Buffer(&dataASN[2], oid, oidSz); /* Set name string. */ - SetASN_Buffer(&dataASN[3], (const byte *)nameStr, - (word32)XSTRLEN(nameStr)); + SetASN_Buffer(&dataASN[3], (const byte *)nameStr, nameSz); /* Set the ASN.1 tag for the name string. */ namesASN[3].tag = nameTag; @@ -22064,13 +22062,14 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, /* Return size of encoding. */ ret = sz; } + (void)cname; return ret; #endif /* WOLFSSL_ASN_TEMPLATE */ } /* canonical encoding one attribute of the name (issuer/subject) - * call wc_EncodeName_ex with CTC_UTF8 for email type + * call EncodeName with CTC_UTF8 for email type * * name structure to hold result of encoding * nameStr value to be encoded @@ -22082,8 +22081,8 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr, char nameType, byte type) { - return wc_EncodeName_ex(name, nameStr, (byte)nameType, type, - ASN_UTF8STRING); + return EncodeName(name, nameStr, (byte)nameType, type, + ASN_UTF8STRING, NULL); } /* Encodes one attribute of the name (issuer/subject) @@ -22098,32 +22097,11 @@ int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr, int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, byte type) { - return wc_EncodeName_ex(name, nameStr, (byte)nameType, type, - ASN_IA5_STRING); + return EncodeName(name, nameStr, (byte)nameType, type, + ASN_IA5_STRING, NULL); } #ifdef WOLFSSL_ASN_TEMPLATE -/* Simple name OID size. */ -#define NAME_OID_SZ 3 - -/* Domain name OIDs. */ -static const byte nameOid[NAME_ENTRIES - 1][NAME_OID_SZ] = { - { 0x55, 0x04, ASN_COUNTRY_NAME }, - { 0x55, 0x04, ASN_STATE_NAME }, - { 0x55, 0x04, ASN_STREET_ADDR }, - { 0x55, 0x04, ASN_LOCALITY_NAME }, - { 0x55, 0x04, ASN_SUR_NAME }, - { 0x55, 0x04, ASN_ORG_NAME }, - { 0x55, 0x04, ASN_ORGUNIT_NAME }, - { 0x55, 0x04, ASN_COMMON_NAME }, - { 0x55, 0x04, ASN_SERIAL_NUMBER }, -#ifdef WOLFSSL_CERT_EXT - { 0x55, 0x04, ASN_BUS_CAT }, -#endif - { 0x55, 0x04, ASN_POSTAL_CODE }, - /* Email OID is much longer. */ -}; - static void SetRdnItems(ASNItem* namesASN, ASNSetData* dataASN, const byte* oid, int oidSz, byte tag, const byte* data, int sz) { @@ -22165,7 +22143,8 @@ static const ASNItem nameASN[] = { int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap) { #ifndef WOLFSSL_ASN_TEMPLATE - int totalBytes = 0, i, idx; + int ret; + int totalBytes = 0, i, idx; #ifdef WOLFSSL_SMALL_STACK EncodedName* names = NULL; #else @@ -22190,11 +22169,10 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap) #endif for (i = 0; i < NAME_ENTRIES; i++) { - int ret; const char* nameStr = GetOneCertName(name, i); - ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i), - GetCertNameId(i)); + ret = EncodeName(&names[i], nameStr, GetNameType(name, i), + GetCertNameId(i), ASN_IA5_STRING, name); if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -22207,9 +22185,9 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap) #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); + ret = EncodeName(&addNames[i], name->name[i].value, + (byte)name->name[i].type, name->name[i].id, + ASN_IA5_STRING, NULL); if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -22239,35 +22217,13 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap) for (i = 0; i < NAME_ENTRIES; i++) { #ifdef WOLFSSL_MULTI_ATTRIB type = GetCertNameId(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 - WOLFSSL_MSG("Not enough space left for DC value"); - 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 + WOLFSSL_MSG("Not enough space left for DC value"); return BUFFER_E; } @@ -22315,7 +22271,8 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap) idx = nameASN_Length; for (i = 0; i < NAME_ENTRIES; i++) { /* Keep name length to identify component is to be encoded. */ - nameLen[i] = (int)XSTRLEN(GetOneCertName(name, i)); + const char* nameStr = GetOneCertName(name, i); + nameLen[i] = nameStr ? (int)XSTRLEN(nameStr) : 0; if (nameLen[i] > 0) { idx += rdnASN_Length; } @@ -22351,32 +22308,35 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap) idx = nameASN_Length; for (i = 0; i < NAME_ENTRIES; i++) { - int email = (i == (NAME_ENTRIES - 1)); - - #ifdef WOLFSSL_MULTI_ATTRIB int type = GetCertNameId(i); - if (type == ASN_ORGUNIT_NAME) { - j = -1; - /* Put DomainComponents before OrgUnitName. */ - while (FindMultiAttrib(name, ASN_DOMAIN_COMPONENT, &j)) { - /* Copy data into dynamic vars. */ - SetRdnItems(namesASN + idx, dataASN + idx, dcOid, - sizeof(dcOid), name->name[j].type, - (byte*)name->name[j].value, name->name[j].sz); - idx += rdnASN_Length; - } + #ifdef WOLFSSL_MULTI_ATTRIB + j = -1; + /* Put DomainComponents before OrgUnitName. */ + while (FindMultiAttrib(name, type, &j)) { + /* Copy data into dynamic vars. */ + SetRdnItems(namesASN + idx, dataASN + idx, dcOid, + sizeof(dcOid), name->name[j].type, + (byte*)name->name[j].value, name->name[j].sz); + idx += rdnASN_Length; } #endif if (nameLen[i] > 0) { /* Write out first instance of attribute type. */ - if (email) { + if (type == ASN_EMAIL_NAME) { /* Copy email data into dynamic vars. */ - SetRdnItems(namesASN + idx, dataASN + idx, emailOid, - sizeof(emailOid), ASN_IA5_STRING, + SetRdnItems(namesASN + idx, dataASN + idx, attrEmailOid, + sizeof(attrEmailOid), ASN_IA5_STRING, (const byte*)GetOneCertName(name, i), nameLen[i]); } + else if (type == ASN_CUSTOM_NAME) { + #ifdef WOLFSSL_CUSTOM_OID + SetRdnItems(namesASN + idx, dataASN + idx, name->custom.oid, + name->custom.oidSz, name->custom.enc, + name->custom.val, name->custom.valSz); + #endif + } else { /* Copy name data into dynamic vars. */ SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i], @@ -22487,57 +22447,59 @@ static int EncodePublicKey(int keyType, byte* output, int outLen, * All extensions supported for encoding are described. */ static const ASNItem certExtsASN[] = { + /* Basic Constraints Extension - 4.2.1.9 */ /* 0 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, - /* Basic Constraints Extension - 4.2.1.9 */ -/* 1 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 2 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 3 */ { 2, ASN_OCTET_STRING, 0, 1, 0 }, -/* 4 */ { 3, ASN_SEQUENCE, 1, 1, 0 }, - /* cA */ -/* 5 */ { 4, ASN_BOOLEAN, 0, 0, 0 }, - /* pathLenConstraint */ -/* 6 */ { 4, ASN_INTEGER, 0, 0, 1 }, - /* Subject Alternative Name - 4.2.1.6 */ -/* 7 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 8 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, - /* */ -/* 9 */ { 2, ASN_OCTET_STRING, 0, 0, 0 }, +/* 1 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 2 */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, +/* 3 */ { 2, ASN_SEQUENCE, 1, 1, 0 }, + /* cA */ +/* 4 */ { 3, ASN_BOOLEAN, 0, 0, 0 }, + /* pathLenConstraint */ +/* 5 */ { 3, ASN_INTEGER, 0, 0, 1 }, + /* Subject Alternative Name - 4.2.1.6 */ +/* 6 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 7 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 8 */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, #ifdef WOLFSSL_CERT_EXT - /* Subject Key Identifier - 4.2.1.2 */ -/* 10 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 11 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 12 */ { 2, ASN_OCTET_STRING, 0, 1, 0 }, -/* 13 */ { 3, ASN_OCTET_STRING, 0, 0, 0 }, - /* Authority Key Identifier - 4.2.1.1 */ -/* 14 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 15 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 16 */ { 2, ASN_OCTET_STRING, 0, 1, 0 }, -/* 17 */ { 3, ASN_SEQUENCE, 1, 1, 0 }, -/* 18 */ { 4, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 }, - /* Key Usage - 4.2.1.3 */ -/* 19 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 20 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 21 */ { 2, ASN_BOOLEAN, 0, 0, 0 }, -/* 22 */ { 2, ASN_OCTET_STRING, 0, 1, 0 }, -/* 23 */ { 3, ASN_BIT_STRING, 0, 0, 0 }, - /* Extended Key Usage - 4,2,1,12 */ -/* 24 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 25 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 26 */ { 2, ASN_OCTET_STRING, 0, 0, 0 }, - /* Certificate Policies - 4.2.1.4 */ -/* 27 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 28 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 29 */ { 2, ASN_OCTET_STRING, 0, 1, 0 }, -/* 30 */ { 3, ASN_SEQUENCE, 0, 0, 0 }, - /* Netscape Certificate Type */ -/* 31 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 32 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 33 */ { 2, ASN_OCTET_STRING, 0, 1, 0 }, -/* 34 */ { 3, ASN_BIT_STRING, 0, 0, 0 }, -/* 35 */ { 1, ASN_SEQUENCE, 1, 1, 0 }, -/* 36 */ { 2, ASN_OBJECT_ID, 0, 0, 0 }, -/* 37 */ { 2, ASN_OCTET_STRING, 0, 0, 0 }, - + /* Subject Key Identifier - 4.2.1.2 */ +/* 9 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 10 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 11 */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, +/* 12 */ { 2, ASN_OCTET_STRING, 0, 0, 0 }, + /* Authority Key Identifier - 4.2.1.1 */ +/* 13 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 14 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 15 */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, +/* 16 */ { 2, ASN_SEQUENCE, 1, 1, 0 }, +/* 17 */ { 3, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 }, + /* Key Usage - 4.2.1.3 */ +/* 18 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 19 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 20 */ { 1, ASN_BOOLEAN, 0, 0, 0 }, +/* 21 */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, +/* 22 */ { 2, ASN_BIT_STRING, 0, 0, 0 }, + /* Extended Key Usage - 4,2,1,12 */ +/* 23 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 24 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 25 */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, + /* Certificate Policies - 4.2.1.4 */ +/* 26 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 27 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 28 */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, +/* 29 */ { 2, ASN_SEQUENCE, 0, 0, 0 }, + /* Netscape Certificate Type */ +/* 30 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 31 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 32 */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, +/* 33 */ { 2, ASN_BIT_STRING, 0, 0, 0 }, +/* 34 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 35 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 36 */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, +#endif /* WOLFSSL_CERT_EXT */ +#ifdef WOLFSSL_CUSTOM_OID +/* 37 */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* 38 */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* 39 */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, #endif }; @@ -22561,7 +22523,7 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, static const byte ekuOID[] = { 0x55, 0x1d, 0x25 }; static const byte cpOID[] = { 0x55, 0x1d, 0x20 }; static const byte nsCertOID[] = { 0x60, 0x86, 0x48, 0x01, - 0x86, 0xF8, 0x42, 0x01, 0x01 }; + 0x86, 0xF8, 0x42, 0x01, 0x01 }; static const byte crlInfoOID[] = { 0x55, 0x1D, 0x1F }; #endif @@ -22572,63 +22534,66 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, if (ret == 0) { if (cert->isCA) { /* Set Basic Constraints to be a Certificate Authority. */ - SetASN_Boolean(&dataASN[5], 1); - SetASN_Buffer(&dataASN[2], bcOID, sizeof(bcOID)); + SetASN_Boolean(&dataASN[4], 1); + SetASN_Buffer(&dataASN[1], bcOID, sizeof(bcOID)); /* TODO: consider adding path length field in Cert. */ - dataASN[6].noOut = 1; + dataASN[5].noOut = 1; } else { /* Don't write out Basic Constraints extension items. */ - SetASNItem_NoOut(dataASN, 1, 6); + SetASNItem_NoOut(dataASN, 0, 5); } #ifdef WOLFSSL_ALT_NAMES if (!forRequest && cert->altNamesSz > 0) { /* Set Subject Alternative Name OID and data. */ - SetASN_Buffer(&dataASN[8], sanOID, sizeof(sanOID)); - SetASN_Buffer(&dataASN[9], cert->altNames, cert->altNamesSz); + SetASN_Buffer(&dataASN[7], sanOID, sizeof(sanOID)); + SetASN_Buffer(&dataASN[8], cert->altNames, cert->altNamesSz); } else #endif { /* Don't write out Subject Alternative Name extension items. */ - SetASNItem_NoOut(dataASN, 7, 9); + SetASNItem_NoOut(dataASN, 6, 8); } #ifdef WOLFSSL_CERT_EXT if (cert->skidSz > 0) { /* Set Subject Key Identifier OID and data. */ - SetASN_Buffer(&dataASN[11], skidOID, sizeof(skidOID)); - SetASN_Buffer(&dataASN[13], cert->skid, cert->skidSz); + SetASN_Buffer(&dataASN[10], skidOID, sizeof(skidOID)); + SetASN_Buffer(&dataASN[12], cert->skid, cert->skidSz); } else { /* Don't write out Subject Key Identifier extension items. */ - SetASNItem_NoOut(dataASN, 10, 13); + SetASNItem_NoOut(dataASN, 9, 12); } if (cert->akidSz > 0) { /* Set Authority Key Identifier OID and data. */ - SetASN_Buffer(&dataASN[15], akidOID, sizeof(akidOID)); + SetASN_Buffer(&dataASN[14], akidOID, sizeof(akidOID)); + #ifdef WOLFSSL_AKID_NAME if (cert->rawAkid) { - SetASN_Buffer(&dataASN[16], cert->akid, cert->akidSz); + SetASN_Buffer(&dataASN[15], cert->akid, cert->akidSz); /* cert->akid contains the internal ext structure */ - SetASNItem_NoOutBelow(dataASN, certExtsASN, 16, + SetASNItem_NoOutBelow(dataASN, certExtsASN, 15, certExtsASN_Length); } - else { - SetASN_Buffer(&dataASN[18], cert->akid, cert->akidSz); + else + #endif + { + SetASN_Buffer(&dataASN[17], cert->akid, cert->akidSz); } } else { /* Don't write out Authority Key Identifier extension items. */ - SetASNItem_NoOut(dataASN, 14, 18); + SetASNItem_NoOut(dataASN, 13, 17); } if (cert->keyUsage != 0) { /* Set Key Usage OID, critical and value. */ - SetASN_Buffer(&dataASN[20], kuOID, sizeof(kuOID)); - SetASN_Boolean(&dataASN[21], 1); - SetASN_Int16Bit(&dataASN[23], cert->keyUsage); + SetASN_Buffer(&dataASN[19], kuOID, sizeof(kuOID)); + SetASN_Boolean(&dataASN[20], 1); + SetASN_Int16Bit(&dataASN[22], cert->keyUsage); } else { /* Don't write out Key Usage extension items. */ - SetASNItem_NoOut(dataASN, 19, 23); + SetASNItem_NoOut(dataASN, 18, 22); } if (cert->extKeyUsage != 0) { /* Calculate size of Extended Key Usage data. */ @@ -22637,12 +22602,12 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, ret = KEYUSAGE_E; } /* Set Extended Key Usage OID and data. */ - SetASN_Buffer(&dataASN[25], ekuOID, sizeof(ekuOID)); - SetASN_Buffer(&dataASN[26], NULL, sz); + SetASN_Buffer(&dataASN[24], ekuOID, sizeof(ekuOID)); + SetASN_Buffer(&dataASN[25], NULL, sz); } else { /* Don't write out Extended Key Usage extension items. */ - SetASNItem_NoOut(dataASN, 24, 26); + SetASNItem_NoOut(dataASN, 23, 25); } if ((!forRequest) && (cert->certPoliciesNb > 0)) { @@ -22651,9 +22616,9 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, cert->certPoliciesNb, cert->heap); if (sz > 0) { /* Set Certificate Policies OID. */ - SetASN_Buffer(&dataASN[28], cpOID, sizeof(cpOID)); + SetASN_Buffer(&dataASN[27], cpOID, sizeof(cpOID)); /* Make space for data. */ - SetASN_Buffer(&dataASN[30], NULL, sz); + SetASN_Buffer(&dataASN[29], NULL, sz); } else { ret = CERTPOLICIES_E; @@ -22661,29 +22626,42 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, } else { /* Don't write out Certificate Policies extension items. */ - SetASNItem_NoOut(dataASN, 27, 30); + SetASNItem_NoOut(dataASN, 26, 29); } #ifndef IGNORE_NETSCAPE_CERT_TYPE /* Netscape Certificate Type */ if (cert->nsCertType != 0) { /* Set Netscape Certificate Type OID and data. */ - SetASN_Buffer(&dataASN[32], nsCertOID, sizeof(nsCertOID)); - SetASN_Buffer(&dataASN[34], &cert->nsCertType, 1); + SetASN_Buffer(&dataASN[31], nsCertOID, sizeof(nsCertOID)); + SetASN_Buffer(&dataASN[33], &cert->nsCertType, 1); } else #endif { /* Don't write out Netscape Certificate Type. */ - SetASNItem_NoOut(dataASN, 31, 34); + SetASNItem_NoOut(dataASN, 30, 33); } if (cert->crlInfoSz > 0) { /* Set CRL Distribution Points OID and data. */ - SetASN_Buffer(&dataASN[36], crlInfoOID, sizeof(crlInfoOID)); - SetASN_Buffer(&dataASN[37], cert->crlInfo, cert->crlInfoSz); + SetASN_Buffer(&dataASN[35], crlInfoOID, sizeof(crlInfoOID)); + SetASN_Buffer(&dataASN[36], cert->crlInfo, cert->crlInfoSz); } else { /* Don't write out CRL Distribution Points. */ - SetASNItem_NoOut(dataASN, 35, 37); + SetASNItem_NoOut(dataASN, 34, 36); + } + #endif /* WOLFSSL_CERT_EXT */ + + #ifdef WOLFSSL_CUSTOM_OID + /* encode a custom oid and value */ + if (cert->extCustom.oidSz > 0) { + /* Set CRL Distribution Points OID and data. */ + SetASN_Buffer(&dataASN[38], cert->extCustom.oid, cert->extCustom.oidSz); + SetASN_Buffer(&dataASN[39], cert->extCustom.val, cert->extCustom.valSz); + } + else { + /* Don't write out custom OID. */ + SetASNItem_NoOut(dataASN, 37, 39); } #endif } @@ -23703,11 +23681,13 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, else if (ed448Key) { cert->keyType = ED448_KEY; } - else if ((falconKey != NULL) && (falconKey->level == 1)) { - cert->keyType = FALCON_LEVEL1_KEY; - } - else if ((falconKey != NULL) && (falconKey->level == 5)) { - cert->keyType = FALCON_LEVEL5_KEY; + else if (falconKey != NULL) { + #ifdef HAVE_LIBOQS + if (falconKey->level == 1) + cert->keyType = FALCON_LEVEL1_KEY; + else if (falconKey->level == 5) + cert->keyType = FALCON_LEVEL5_KEY; + #endif } else { ret = BAD_FUNC_ARG; @@ -23952,10 +23932,6 @@ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, int extSz) { - const byte erOid[] = - { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x0e }; - int sz = 0; /* overall size */ int cpSz = 0; /* Challenge Password section size */ int cpSeqSz = 0; @@ -23975,6 +23951,8 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, sz++; if (pw && pw[0]) { + int cpOidSz = SetObjectId(sizeof(attrChallengePasswordOid), NULL); + cpOidSz += sizeof(attrChallengePasswordOid); pwSz = (int)XSTRLEN(pw); if (pwPrintableString) { cpStrSz = SetPrintableString(pwSz, cpStr); @@ -23983,16 +23961,18 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, } cpSetSz = SetSet(cpStrSz + pwSz, cpSet); /* +2 for tag and length parts of the TLV triplet */ - cpSeqSz = SetSequence(2 + sizeof(attrChallengePasswordOid) + cpSetSz + + cpSeqSz = SetSequence(cpOidSz + cpSetSz + cpStrSz + pwSz, cpSeq); - cpSz = cpSeqSz + 2 + sizeof(attrChallengePasswordOid) + cpSetSz + + cpSz = cpSeqSz + cpOidSz + cpSetSz + cpStrSz + pwSz; } if (extSz) { + int erOidSz = SetObjectId(sizeof(attrExtensionRequestOid), NULL); + erOidSz += sizeof(attrExtensionRequestOid); erSetSz = SetSet(extSz, erSet); - erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq); - erSz = extSz + erSetSz + erSeqSz + sizeof(erOid); + erSeqSz = SetSequence(erSetSz + erOidSz + extSz, erSeq); + erSz = extSz + erSetSz + erSeqSz + erOidSz; } /* Put the pieces together. */ @@ -24016,8 +23996,10 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, if (erSz) { XMEMCPY(&output[sz], erSeq, erSeqSz); sz += erSeqSz; - XMEMCPY(&output[sz], erOid, sizeof(erOid)); - sz += sizeof(erOid); + sz += SetObjectId(sizeof(attrExtensionRequestOid), output + sz); + XMEMCPY(&output[sz], attrExtensionRequestOid, + sizeof(attrExtensionRequestOid)); + sz += sizeof(attrExtensionRequestOid); XMEMCPY(&output[sz], erSet, erSetSz); sz += erSetSz; /* The actual extension data will be tacked onto the output later. */ @@ -24026,6 +24008,45 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, return sz; } +#ifdef WOLFSSL_CUSTOM_OID +/* encode a custom oid and value */ +static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz, + CertOidField* custom) +{ + int idx = 0, cust_lenSz, cust_oidSz; + + if (cert == NULL || output == NULL || custom == NULL) { + return BAD_FUNC_ARG; + } + if (custom->oid == NULL || custom->oidSz <= 0) { + return 0; /* none set */ + } + + /* Octet String header */ + cust_lenSz = SetOctetString(custom->valSz, NULL); + cust_oidSz = SetObjectId(custom->oidSz, NULL); + + /* check for output buffer room */ + if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) > outSz) + return BUFFER_E; + + /* put sequence with total */ + idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz, output); + + /* put oid header */ + idx += SetObjectId(custom->oidSz, output+idx); + XMEMCPY(output+idx, custom->oid, custom->oidSz); + idx += custom->oidSz; + + /* put value */ + idx += SetOctetString(custom->valSz, output+idx); + XMEMCPY(output+idx, custom->val, custom->valSz); + idx += custom->valSz; + + return idx; +} +#endif /* WOLFSSL_CUSTOM_OID */ + /* encode info from cert into DER encoded format */ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, @@ -24183,7 +24204,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, der->skidSz = 0; /* Key Usage */ - if (cert->keyUsage != 0){ + if (cert->keyUsage != 0) { der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage), cert->keyUsage); if (der->keyUsageSz <= 0) @@ -24195,7 +24216,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, der->keyUsageSz = 0; /* Extended Key Usage */ - if (cert->extKeyUsage != 0){ + if (cert->extKeyUsage != 0) { der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage, sizeof(der->extKeyUsage), cert->extKeyUsage); if (der->extKeyUsageSz <= 0) @@ -24208,6 +24229,16 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, #endif /* WOLFSSL_CERT_EXT */ +#ifdef WOLFSSL_CUSTOM_OID + /* encode a custom oid and value */ + /* zero returns, means none set */ + der->extCustomSz = SetCustomObjectId(cert, der->extCustom, + sizeof(der->extCustom), &cert->extCustom); + if (der->extCustomSz < 0) + return der->extCustomSz; + der->extensionsSz += der->extCustomSz; +#endif + /* put extensions */ if (der->extensionsSz > 0) { int ret; @@ -24274,6 +24305,15 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, return EXTENSIONS_E; } + #ifdef WOLFSSL_CUSTOM_OID + if (der->extCustomSz) { + ret = SetExtensions(der->extensions, sizeof(der->extensions), + &der->extensionsSz, + der->extCustom, der->extCustomSz); + if (ret <= 0) + return EXTENSIONS_E; + } + #endif #endif /* WOLFSSL_CERT_EXT */ } @@ -24418,12 +24458,6 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) word32 sbjRawSz; #endif - /* Challenge Password OID. */ - static const byte cpOid[] = - { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x07 }; - /* Extension Requested OID. */ - static const byte erOid[] = - { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e }; CALLOC_ASNSETDATA(dataASN, certReqBodyASN_Length, ret, cert->heap); @@ -24444,11 +24478,13 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, else if (ed448Key != NULL) { cert->keyType = ED448_KEY; } - else if ((falconKey != NULL) && (falconKey->level == 1)) { - cert->keyType = FALCON_LEVEL1_KEY; - } - else if ((falconKey != NULL) && (falconKey->level == 5)) { - cert->keyType = FALCON_LEVEL5_KEY; + else if (falconKey != NULL) { + #ifdef HAVE_LIBOQS + if (falconKey->level == 1) + cert->keyType = FALCON_LEVEL1_KEY; + else if (falconKey->level == 5) + cert->keyType = FALCON_LEVEL5_KEY; + #endif } else { ret = BAD_FUNC_ARG; @@ -24496,7 +24532,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, if (cert->challengePw[0] != '\0') { /* Add challenge password attribute. */ /* Set challenge password OID. */ - SetASN_Buffer(&dataASN[6], cpOid, sizeof(cpOid)); + SetASN_Buffer(&dataASN[6], attrChallengePasswordOid, + sizeof(attrChallengePasswordOid)); /* Enable the ASN template item with the appropriate tag. */ if (cert->challengePwPrintableString) { /* PRINTABLE_STRING - set buffer */ @@ -24519,7 +24556,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, } if (extSz > 0) { /* Set extension attribute OID. */ - SetASN_Buffer(&dataASN[11], erOid, sizeof(erOid)); + SetASN_Buffer(&dataASN[11], attrExtensionRequestOid, + sizeof(attrExtensionRequestOid)); /* Leave space for data. */ SetASN_Buffer(&dataASN[13], NULL, extSz); } @@ -24547,7 +24585,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, { /* Encode subject name into space in buffer. */ ret = SetNameEx((byte*)dataASN[2].data.buffer.data, - dataASN[3].data.buffer.length, &cert->subject, cert->heap); + dataASN[2].data.buffer.length, &cert->subject, cert->heap); } } if (ret >= 0) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 13dbdd4ce..0d5956d0a 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -355,7 +355,7 @@ _Pragma("GCC diagnostic ignored \"-Wunused-function\"") #define NO_INTM_HASH_TEST #endif -#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_MULTI_ATTRIB) +#ifdef WOLFSSL_CERT_GEN static void initDefaultName(void); #endif @@ -753,8 +753,8 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif /* USE_FAST_MATH */ #endif /* !NO_BIG_INT */ -#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_MULTI_ATTRIB) -initDefaultName(); +#ifdef WOLFSSL_CERT_GEN + initDefaultName(); #endif #ifdef WOLFSSL_ASYNC_CRYPT @@ -12252,14 +12252,19 @@ WOLFSSL_TEST_SUBROUTINE int memory_test(void) #if defined(WOLFSSL_CERT_GEN) && (!defined(NO_RSA) || defined(HAVE_ECC)) || \ (defined(WOLFSSL_TEST_CERT) && (defined(HAVE_ED25519) || defined(HAVE_ED448))) -#ifdef WOLFSSL_MULTI_ATTRIB static CertName certDefaultName; static void initDefaultName(void) { +#if defined(WOLFSSL_MULTI_ATTRIB) && defined(WOLFSSL_TEST_CERT) + NameAttrib* n; +#endif + XMEMCPY(certDefaultName.country, "US", sizeof("US")); certDefaultName.countryEnc = CTC_PRINTABLE; XMEMCPY(certDefaultName.state, "Oregon", sizeof("Oregon")); certDefaultName.stateEnc = CTC_UTF8; + XMEMCPY(certDefaultName.street, "Main St", sizeof("Main St")); + certDefaultName.streetEnc = CTC_UTF8; XMEMCPY(certDefaultName.locality, "Portland", sizeof("Portland")); certDefaultName.localityEnc = CTC_UTF8; XMEMCPY(certDefaultName.sur, "Test", sizeof("Test")); @@ -12272,59 +12277,45 @@ static void initDefaultName(void) certDefaultName.commonNameEnc = CTC_UTF8; XMEMCPY(certDefaultName.serialDev, "wolfSSL12345", sizeof("wolfSSL12345")); certDefaultName.serialDevEnc = CTC_PRINTABLE; + XMEMCPY(certDefaultName.postalCode, "12-456", sizeof("12-456")); + certDefaultName.postalCodeEnc = CTC_PRINTABLE; #ifdef WOLFSSL_CERT_EXT XMEMCPY(certDefaultName.busCat, "Private Organization", sizeof("Private Organization")); certDefaultName.busCatEnc = CTC_UTF8; + XMEMCPY(certDefaultName.joiSt, "US", sizeof("US")); + certDefaultName.joiStEnc = CTC_PRINTABLE; + XMEMCPY(certDefaultName.joiC, "Oregon", sizeof("Oregon")); + certDefaultName.joiCEnc = CTC_PRINTABLE; #endif 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 defined(WOLFSSL_MULTI_ATTRIB) && defined(WOLFSSL_TEST_CERT) + /* 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")); + 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 */ - "Oregon", CTC_UTF8, /* state */ - "Main St", CTC_UTF8, /* street */ - "Portland", CTC_UTF8, /* locality */ - "Test", CTC_UTF8, /* sur */ - "wolfSSL", CTC_UTF8, /* org */ - "Development", CTC_UTF8, /* unit */ - "www.wolfssl.com", CTC_UTF8, /* commonName */ - "wolfSSL12345", CTC_PRINTABLE, /* serial number of device */ - "12-456", CTC_PRINTABLE, /* Postal Code */ -#ifdef WOLFSSL_CERT_EXT - "Private Organization", CTC_UTF8, /* businessCategory */ - "US", CTC_PRINTABLE, /* jurisdiction country */ - "Oregon", CTC_PRINTABLE, /* jurisdiction state */ +#endif /* WOLFSSL_MULTI_ATTRIB && WOLFSSL_TEST_CERT */ + +#ifdef WOLFSSL_CUSTOM_OID + /* TODO: Add test case for custom OID's */ #endif - "info@wolfssl.com", /* email */ -}; -#endif /* WOLFSSL_MULTI_ATTRIB */ +} #ifdef WOLFSSL_CERT_EXT #if ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index f34ee8d82..ddfb7b654 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -622,7 +622,8 @@ enum DN_Tags { ASN_ORGUNIT_NAME = 0x0b, /* OU */ ASN_BUS_CAT = 0x0f, /* businessCategory */ ASN_POSTAL_CODE = 0x11, /* postalCode */ - ASN_EMAIL_NAME = 0x98, /* not oid number there is 97 in 2.5.4.0-97 */ + ASN_EMAIL_NAME = 0x98, /* not actual OID (see attrEmailOid) */ + ASN_CUSTOM_NAME = 0x99, /* not actual OID (see CertOidField) */ /* pilot attribute types * OID values of 0.9.2342.19200300.100.1.* */ @@ -1939,14 +1940,6 @@ WOLFSSL_LOCAL int wc_MIME_free_hdrs(MimeHdr* head); #ifdef WOLFSSL_CERT_GEN enum cert_enums { -#ifdef WOLFSSL_CERT_EXT - NAME_ENTRIES = 12, -#else - NAME_ENTRIES = 11, -#endif - JOINT_LEN = 2, - EMAIL_JOINT_LEN = 9, - PILOT_JOINT_LEN = 10, RSA_KEY = 10, ECC_KEY = 12, ED25519_KEY = 13, diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index bc7f85ca4..d70589201 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -310,6 +310,15 @@ typedef struct NameAttrib { } NameAttrib; #endif /* WOLFSSL_MULTI_ATTRIB */ +#ifdef WOLFSSL_CUSTOM_OID +typedef struct CertOidField { + byte* oid; + byte* val; + int oidSz; + int valSz; + char enc; +} CertOidField; +#endif typedef struct CertName { char country[CTC_NAME_SIZE]; @@ -344,6 +353,9 @@ typedef struct CertName { #ifdef WOLFSSL_MULTI_ATTRIB NameAttrib name[CTC_MAX_ATTRIB]; #endif +#ifdef WOLFSSL_CUSTOM_OID + CertOidField custom; +#endif } CertName; @@ -409,6 +421,10 @@ typedef struct Cert { char challengePw[CTC_NAME_SIZE]; int challengePwPrintableString; /* encode as PrintableString */ #endif +#ifdef WOLFSSL_CUSTOM_OID + CertOidField extCustom; /* user oid and value to go in req extensions */ +#endif + void* decodedCert; /* internal DecodedCert allocated from heap */ byte* der; /* Pointer to buffer of current DecodedCert cache */ void* heap; /* heap hint */ From be870e742d7ffc15ea4a59243ec435432d951815 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 23 Nov 2021 15:12:48 -0800 Subject: [PATCH 2/4] Edge case build fixes (cert gen only). --- wolfcrypt/src/asn.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 7f6ba3a9b..6d3b81b0e 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3980,15 +3980,17 @@ static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4}; static const byte extExtKeyUsageTimestampOid[] = {43, 6, 1, 5, 5, 7, 3, 8}; static const byte extExtKeyUsageOcspSignOid[] = {43, 6, 1, 5, 5, 7, 3, 9}; -#ifdef WOLFSSL_CERT_REQ +#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) /* csrAttrType */ static const byte attrEmailOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 1}; +#ifdef WOLFSSL_CERT_REQ static const byte attrUnstructuredNameOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 2}; static const byte attrPkcs9ContentTypeOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 3}; static const byte attrChallengePasswordOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 7}; static const byte attrExtensionRequestOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 14}; static const byte attrSerialNumberOid[] = {85, 4, 5}; #endif +#endif /* kdfType */ static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12}; @@ -4021,7 +4023,7 @@ static const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24}; static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7}; #endif -#ifdef WOLFSSL_CERT_REQ +#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) /* Pilot attribute types (0.9.2342.19200300.100.1.*) */ #ifdef WOLFSSL_ASN_TEMPLATE static const byte uidOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 1}; /* user id */ From 579056a2f39e8060c21130bcdd59ca3dcdbd1ace Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 6 Dec 2021 14:19:32 -0800 Subject: [PATCH 3/4] Subject raw should be populated with `WOLFSSL_CERT_EXT`. --- wolfcrypt/src/asn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6d3b81b0e..bc8d5eae7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -10876,7 +10876,7 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType, cert->issuerRawLen = length; } #endif -#ifndef IGNORE_NAME_CONSTRAINTS +#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT) if (nameType == SUBJECT) { cert->subjectRaw = &input[srcIdx]; cert->subjectRawLen = length; @@ -11417,7 +11417,7 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType, cert->issuerRawLen = len; } #endif - #ifndef IGNORE_NAME_CONSTRAINTS + #if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT) /* Store pointer and length to raw subject. */ if (nameType == SUBJECT) { cert->subjectRaw = &input[srcIdx]; From e1b73636475b2296d6c5ac5185c81dbd393f702f Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 6 Dec 2021 16:12:07 -0800 Subject: [PATCH 4/4] Fixes from peer review. --- wolfcrypt/src/asn.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index bc8d5eae7..8c67ae9d1 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3982,12 +3982,13 @@ static const byte extExtKeyUsageOcspSignOid[] = {43, 6, 1, 5, 5, 7, 3, 9}; #if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) /* csrAttrType */ -static const byte attrEmailOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 1}; +#define CSR_ATTR_TYPE_OID_BASE(num) {42, 134, 72, 134, 247, 13, 1, 9, num} +static const byte attrEmailOid[] = CSR_ATTR_TYPE_OID_BASE(1); #ifdef WOLFSSL_CERT_REQ -static const byte attrUnstructuredNameOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 2}; -static const byte attrPkcs9ContentTypeOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 3}; -static const byte attrChallengePasswordOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 7}; -static const byte attrExtensionRequestOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 14}; +static const byte attrUnstructuredNameOid[] = CSR_ATTR_TYPE_OID_BASE(2); +static const byte attrPkcs9ContentTypeOid[] = CSR_ATTR_TYPE_OID_BASE(3); +static const byte attrChallengePasswordOid[] = CSR_ATTR_TYPE_OID_BASE(7); +static const byte attrExtensionRequestOid[] = CSR_ATTR_TYPE_OID_BASE(14); static const byte attrSerialNumberOid[] = {85, 4, 5}; #endif #endif @@ -24029,11 +24030,14 @@ static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz, cust_oidSz = SetObjectId(custom->oidSz, NULL); /* check for output buffer room */ - if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) > outSz) + if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) > + outSz) { return BUFFER_E; + } /* put sequence with total */ - idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz, output); + idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz, + output); /* put oid header */ idx += SetObjectId(custom->oidSz, output+idx); @@ -24056,6 +24060,8 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey) { + int ret; + (void)eccKey; (void)ed25519Key; (void)ed448Key; @@ -24234,17 +24240,16 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, #ifdef WOLFSSL_CUSTOM_OID /* encode a custom oid and value */ /* zero returns, means none set */ - der->extCustomSz = SetCustomObjectId(cert, der->extCustom, + ret = SetCustomObjectId(cert, der->extCustom, sizeof(der->extCustom), &cert->extCustom); - if (der->extCustomSz < 0) - return der->extCustomSz; + if (ret < 0) + return ret; + der->extCustomSz = ret; der->extensionsSz += der->extCustomSz; #endif /* put extensions */ if (der->extensionsSz > 0) { - int ret; - /* put the start of sequence (ID, Size) */ der->extensionsSz = SetSequence(der->extensionsSz, der->extensions); if (der->extensionsSz <= 0)