From a2381ba95475a218983aa69dc62f116a8f5fca58 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 22 Feb 2022 16:32:16 -0800 Subject: [PATCH] Adds CSR userId support in subject name. Minor build fixes for ASN template. --- src/ssl.c | 4 ++ tests/api.c | 12 +++-- wolfcrypt/src/asn.c | 87 +++++++++++++++++++++++++++++----- wolfcrypt/test/test.c | 2 + wolfssl/wolfcrypt/asn.h | 13 +++-- wolfssl/wolfcrypt/asn_public.h | 2 + 6 files changed, 99 insertions(+), 21 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index bf45f2f5d..d6fd24e51 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -33287,6 +33287,7 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { { NID_surname, NID_surname, oidCertNameType, "SN", "surname"}, { NID_serialNumber, NID_serialNumber, oidCertNameType, "serialNumber", "serialNumber"}, + { NID_userId, NID_userId, oidCertNameType, "UID", "userid"}, { NID_countryName, NID_countryName, oidCertNameType, "C", "countryName"}, { NID_localityName, NID_localityName, oidCertNameType, "L", "localityName"}, { NID_stateOrProvinceName, NID_stateOrProvinceName, oidCertNameType, "ST", @@ -44658,6 +44659,7 @@ static int ConvertNIDToWolfSSL(int nid) case NID_organizationalUnitName: return ASN_ORGUNIT_NAME; case NID_emailAddress: return ASN_EMAIL_NAME; case NID_serialNumber: return ASN_SERIAL_NUMBER; + case NID_userId: return ASN_USER_ID; case NID_businessCategory: return ASN_BUS_CAT; case NID_domainComponent: return ASN_DOMAIN_COMPONENT; case NID_postalCode: return ASN_POSTAL_CODE; @@ -53470,6 +53472,8 @@ int oid2nid(word32 oid, int grp) return NID_pkcs9_challengePassword; case SERIAL_NUMBER_OID: return NID_serialNumber; + case USER_ID_OID: + return NID_userId; } break; #endif diff --git a/tests/api.c b/tests/api.c index f8336579f..632be5f61 100644 --- a/tests/api.c +++ b/tests/api.c @@ -33957,7 +33957,7 @@ static void test_wolfSSL_Tls13_postauth(void) static void test_wolfSSL_X509_NID(void) { - #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ +#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_ASN) int sigType; int nameSz; @@ -34027,7 +34027,7 @@ static void test_wolfSSL_X509_NID(void) X509_free(cert); printf(resultFmt, passed); - #endif +#endif } static void test_wolfSSL_CTX_set_srp_username(void) @@ -41921,7 +41921,7 @@ static void test_wolfSSL_X509_check_ip_asc(void){ #endif } -static void test_wolfSSL_DC_cert(void) +static void test_wolfSSL_make_cert(void) { #if !defined(NO_RSA) && defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) int ret; @@ -41942,7 +41942,7 @@ static void test_wolfSSL_DC_cert(void) ASN1_STRING* entryValue; #endif - printf(testingFmt, "wolfSSL Certs with DC"); + printf(testingFmt, "wolfSSL Make Certs"); XMEMSET(&name, 0, sizeof(CertName)); @@ -41963,6 +41963,8 @@ static void test_wolfSSL_DC_cert(void) name.commonNameEnc = CTC_UTF8; XMEMCPY(name.serialDev, "wolfSSL12345", sizeof("wolfSSL12345")); name.serialDevEnc = CTC_PRINTABLE; + XMEMCPY(name.userId, "TestUserID", sizeof("TestUserID")); + name.userIdEnc = CTC_PRINTABLE; #ifdef WOLFSSL_MULTI_ATTRIB #if CTC_MAX_ATTRIB > 2 { @@ -52695,7 +52697,7 @@ void ApiTest(void) test_wolfSSL_i2c_ASN1_INTEGER(); test_wolfSSL_X509_check_ca(); test_wolfSSL_X509_check_ip_asc(); - test_wolfSSL_DC_cert(); + test_wolfSSL_make_cert(); test_wolfSSL_DES_ncbc(); test_wolfSSL_AES_cbc_encrypt(); test_wolfSSL_CRYPTO_cts128(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index b4e16fcd1..055a54109 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4061,12 +4061,9 @@ static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7}; #endif #if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_ASN_TEMPLATE) || defined(OPENSSL_EXTRA) || \ - defined(OPENSSL_EXTRA_X509_SMALL) + defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) /* 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 #if !defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \ defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) static const byte dcOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 25}; /* domain component */ @@ -4859,6 +4856,10 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) oid = attrSerialNumberOid; *oidSz = sizeof(attrSerialNumberOid); break; + case USER_ID_OID: + oid = uidOid; + *oidSz = sizeof(uidOid); + break; case EXTENSION_REQUEST_OID: oid = attrExtensionRequestOid; *oidSz = sizeof(attrExtensionRequestOid); @@ -10529,8 +10530,6 @@ static int GetHashId(const byte* id, int length, byte* hash) #ifdef WOLFSSL_ASN_TEMPLATE /* Id for email address. */ #define ASN_EMAIL 0x100 -/* Id for user id. */ -#define ASN_UID 0x101 /* Id for domain component. */ #define ASN_DC 0x102 /* Id for jurisdiction country. */ @@ -10774,6 +10773,19 @@ static const CertNameData certNameSubject[] = { #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE NID_postalCode +#endif + }, + /* User Id */ + { + "/userid=", 8, +#ifdef WOLFSSL_CERT_GEN + OFFSETOF(DecodedCert, subjectUID), + OFFSETOF(DecodedCert, subjectUIDLen), + OFFSETOF(DecodedCert, subjectUIDEnc), +#endif +#ifdef WOLFSSL_X509_NAME_AVAILABLE + NID_userId + #endif }, }; @@ -10970,7 +10982,7 @@ static int SetSubject(DecodedCert* cert, int id, byte* str, word32 strLen, cert->subjectCNEnc = tag; } #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - else if (id > ASN_COMMON_NAME && id <= ASN_BUS_CAT) { + else if (id > ASN_COMMON_NAME && id <= ASN_USER_ID) { /* Use table and offsets to put data into appropriate fields. */ SetCertNameSubject(cert, id, (char*)str); SetCertNameSubjectLen(cert, id, strLen); @@ -11053,7 +11065,7 @@ static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid, } else if (oidSz == sizeof(uidOid) && XMEMCMP(oid, uidOid, oidSz) == 0) { /* Set the user id, type string, length and NID. */ - id = ASN_UID; + id = ASN_USER_ID; typeStr = WOLFSSL_USER_ID; typeStrLen = sizeof(WOLFSSL_USER_ID) - 1; #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -11391,6 +11403,22 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType, nid = NID_serialNumber; #endif /* OPENSSL_EXTRA */ } + else if (id == ASN_USER_ID) { + copy = WOLFSSL_USER_ID; + copyLen = sizeof(WOLFSSL_USER_ID) - 1; + #ifdef WOLFSSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectUID = (char*)&input[srcIdx]; + cert->subjectUIDLen = strLen; + cert->subjectUIDEnc = b; + } + #endif /* WOLFSSL_CERT_GEN */ + #if (defined(OPENSSL_EXTRA) || \ + defined(OPENSSL_EXTRA_X509_SMALL)) \ + && !defined(WOLFCRYPT_ONLY) + nid = NID_userId; + #endif /* OPENSSL_EXTRA */ + } #ifdef WOLFSSL_CERT_EXT else if (id == ASN_STREET_ADDR) { copy = WOLFSSL_STREET_ADDR_NAME; @@ -11508,14 +11536,16 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType, byte email = FALSE; byte pilot = FALSE; - if (joint[0] == 0x2a && joint[1] == 0x86) { /* email id hdr */ + if (joint[0] == 0x2a && joint[1] == 0x86) { /* email id hdr 42.134.* */ id = ASN_EMAIL_NAME; email = TRUE; } - if (joint[0] == 0x9 && joint[1] == 0x92) { /* uid id hdr */ + if (joint[0] == 0x9 && joint[1] == 0x92) { /* uid id hdr 9.146.* */ /* last value of OID is the type of pilot attribute */ id = input[srcIdx + oidSz - 1]; + if (id == 0x01) + id = ASN_USER_ID; pilot = TRUE; } @@ -21681,6 +21711,8 @@ const char* GetOneCertName(CertName* name, int idx) return name->commonName; case ASN_SERIAL_NUMBER: return name->serialDev; + case ASN_USER_ID: + return name->userId; case ASN_POSTAL_CODE: return name->postalCode; case ASN_EMAIL_NAME: @@ -21722,6 +21754,8 @@ static char GetNameType(CertName* name, int idx) return name->commonNameEnc; case ASN_SERIAL_NUMBER: return name->serialDevEnc; + case ASN_USER_ID: + return name->userIdEnc; case ASN_POSTAL_CODE: return name->postalCodeEnc; case ASN_EMAIL_NAME: @@ -22097,7 +22131,7 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input) int cnt = 1 + EKU_OID_HI; int i; int ret = 0; - int sz = 0; + int sz; #ifdef WOLFSSL_EKU_OID cnt += CTC_MAX_EKU_NB; @@ -22152,7 +22186,7 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input) if (input & EXTKEYUSE_USER) { /* Iterate through OID values */ for (i = 0; i < CTC_MAX_EKU_NB; i++) { - int sz = cert->extKeyUsageOIDSz[i]; + sz = cert->extKeyUsageOIDSz[i]; if (sz > 0) { /* Set template item. */ XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID], @@ -22169,6 +22203,7 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input) } /* Calculate size of encoding. */ + sz = 0; ret = SizeASN_Items(extKuASN, dataASN, asnIdx, &sz); } /* When buffer to write to, ensure it's big enough. */ @@ -22558,6 +22593,10 @@ static int EncodeName(EncodedName* name, const char* nameStr, thisLen += (int)sizeof(dcOid); firstSz = (int)sizeof(dcOid); break; + case ASN_USER_ID: + thisLen += (int)sizeof(uidOid); + firstSz = (int)sizeof(uidOid); + break; #ifdef WOLFSSL_CUSTOM_OID case ASN_CUSTOM_NAME: thisLen += cname->custom.oidSz; @@ -22607,6 +22646,12 @@ static int EncodeName(EncodedName* name, const char* nameStr, /* str type */ name->encoded[idx++] = nameTag; break; + case ASN_USER_ID: + XMEMCPY(name->encoded + idx, uidOid, sizeof(uidOid)); + idx += (int)sizeof(uidOid); + /* str type */ + name->encoded[idx++] = nameTag; + break; #ifdef WOLFSSL_CUSTOM_OID case ASN_CUSTOM_NAME: XMEMCPY(name->encoded + idx, cname->custom.oid, @@ -22672,6 +22717,11 @@ static int EncodeName(EncodedName* name, const char* nameStr, oid = dcOid; oidSz = sizeof(dcOid); break; + case ASN_USER_ID: + /* Domain component OID different to standard types. */ + oid = uidOid; + oidSz = sizeof(uidOid); + break; #ifdef WOLFSSL_CUSTOM_OID case ASN_CUSTOM_NAME: nameSz = cname->custom.valSz; @@ -22850,6 +22900,12 @@ static int SetNameRdnItems(ASNSetData* dataASN, ASNItem* namesASN, sizeof(attrEmailOid), ASN_IA5_STRING, (const byte*)GetOneCertName(name, i), nameLen[i]); } + else if (type == ASN_USER_ID) { + /* Copy userID data into dynamic vars. */ + SetRdnItems(namesASN + idx, dataASN + idx, uidOid, + sizeof(uidOid), GetNameType(name, i), + (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, @@ -26235,6 +26291,13 @@ static void SetNameFromDcert(CertName* cn, DecodedCert* decoded) cn->serialDev[sz] = '\0'; cn->serialDevEnc = decoded->subjectSNDEnc; } + if (decoded->subjectUID) { + sz = (decoded->subjectUIDLen < CTC_NAME_SIZE) ? decoded->subjectUIDLen + : CTC_NAME_SIZE - 1; + XSTRNCPY(cn->userId, decoded->subjectUID, sz); + cn->userId[sz] = '\0'; + cn->userIdEnc = decoded->subjectUIDEnc; + } #ifdef WOLFSSL_CERT_EXT if (decoded->subjectBC) { sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d7f5d8917..78a6f71c8 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -11904,6 +11904,8 @@ static void initDefaultName(void) certDefaultName.joiCEnc = CTC_PRINTABLE; #endif XMEMCPY(certDefaultName.email, "info@wolfssl.com", sizeof("info@wolfssl.com")); + XMEMCPY(certDefaultName.userId, "TestUserID", sizeof("TestUserID")); + certDefaultName.userIdEnc = CTC_PRINTABLE; #if defined(WOLFSSL_MULTI_ATTRIB) && defined(WOLFSSL_TEST_CERT) /* test having additional OUs and setting DC */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 2bc94c074..18b85542c 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -668,12 +668,13 @@ enum DN_Tags { ASN_ORGUNIT_NAME = 0x0b, /* OU */ ASN_BUS_CAT = 0x0f, /* businessCategory */ ASN_POSTAL_CODE = 0x11, /* postalCode */ + ASN_USER_ID = 0x12, /* UserID */ + 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.* */ - ASN_USER_ID = 0x01, /* UID */ ASN_FAVOURITE_DRINK = 0x05, /* favouriteDrink */ ASN_DOMAIN_COMPONENT = 0x19 /* DC */ }; @@ -839,7 +840,7 @@ enum ECC_TYPES #define ASN_JOI_ST 0x2 #ifndef WC_ASN_NAME_MAX - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) #define WC_ASN_NAME_MAX 330 #else #define WC_ASN_NAME_MAX 256 @@ -973,9 +974,9 @@ enum Misc_ASN { #ifndef WC_MAX_NAME_ENTRIES /* entries added to x509 name struct */ #ifdef OPENSSL_EXTRA - #define WC_MAX_NAME_ENTRIES 15 + #define WC_MAX_NAME_ENTRIES 16 #else - #define WC_MAX_NAME_ENTRIES 13 + #define WC_MAX_NAME_ENTRIES 14 #endif #endif #define MAX_NAME_ENTRIES WC_MAX_NAME_ENTRIES @@ -1188,6 +1189,7 @@ enum CsrAttrType { CHALLENGE_PASSWORD_OID = 659, SERIAL_NUMBER_OID = 94, EXTENSION_REQUEST_OID = 666, + USER_ID_OID = 865, }; #endif @@ -1575,6 +1577,9 @@ struct DecodedCert { char* subjectSND; int subjectSNDLen; char subjectSNDEnc; + char* subjectUID; + int subjectUIDLen; + char subjectUIDEnc; #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) char* subjectStreet; int subjectStreetLen; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 205fc2e53..f333cf97d 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -345,6 +345,8 @@ typedef struct CertName { char commonNameEnc; char serialDev[CTC_NAME_SIZE]; char serialDevEnc; + char userId[CTC_NAME_SIZE]; + char userIdEnc; char postalCode[CTC_NAME_SIZE]; char postalCodeEnc; #ifdef WOLFSSL_CERT_EXT