Skip to content

Commit b889b27

Browse files
Merge pull request #6585 from cconlon/x509Ext
Fixes for WOLFSSL_X509 cert gen, WOLFSSL_ALT_NAMES to --enable-jni
2 parents 62c14e4 + a8ed78e commit b889b27

6 files changed

Lines changed: 221 additions & 88 deletions

File tree

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5850,6 +5850,9 @@ then
58505850
ENABLED_ALPN="yes"
58515851
AM_CFLAGS="$AM_CFLAGS -DHAVE_ALPN"
58525852
fi
5853+
5854+
# cert gen requires alt names
5855+
ENABLED_ALTNAMES="yes"
58535856
fi
58545857

58555858
if test "$ENABLED_LIGHTY" = "yes"

src/ssl_asn1.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,6 +1606,9 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_dup(WOLFSSL_ASN1_OBJECT* obj)
16061606
dupl->grp = obj->grp;
16071607
dupl->nid = obj->nid;
16081608
dupl->objSz = obj->objSz;
1609+
#ifdef OPENSSL_EXTRA
1610+
dupl->ca = obj->ca;
1611+
#endif
16091612
/* Check for encoding. */
16101613
if (obj->obj) {
16111614
/* Allocate memory for ASN.1 OBJECT_ID DER encoding. */

src/x509.c

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,11 +1360,45 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int lo
13601360
break;
13611361
}
13621362
case NID_key_usage:
1363-
if (ext && ext->value.data &&
1364-
ext->value.length == sizeof(word16)) {
1365-
x509->keyUsage = *(word16*)ext->value.data;
1366-
x509->keyUsageCrit = (byte)ext->crit;
1367-
x509->keyUsageSet = 1;
1363+
if (ext && ext->value.data) {
1364+
if (ext->value.length == sizeof(word16)) {
1365+
/* if ext->value is already word16, set directly */
1366+
x509->keyUsage = *(word16*)ext->value.data;
1367+
x509->keyUsageCrit = (byte)ext->crit;
1368+
x509->keyUsageSet = 1;
1369+
}
1370+
else if (ext->value.length > 0) {
1371+
/* ext->value is comma-delimited string, convert to word16 */
1372+
if (ParseKeyUsageStr(ext->value.data, &x509->keyUsage,
1373+
x509->heap) != 0) {
1374+
return WOLFSSL_FAILURE;
1375+
}
1376+
x509->keyUsageCrit = (byte)ext->crit;
1377+
x509->keyUsageSet = 1;
1378+
}
1379+
else {
1380+
return WOLFSSL_FAILURE;
1381+
}
1382+
}
1383+
break;
1384+
case NID_ext_key_usage:
1385+
if (ext && ext->value.data) {
1386+
if (ext->value.length == sizeof(byte)) {
1387+
/* if ext->value is already word16, set directly */
1388+
x509->extKeyUsage = *(byte*)ext->value.data;
1389+
x509->extKeyUsageCrit = (byte)ext->crit;
1390+
}
1391+
else if (ext->value.length > 0) {
1392+
/* ext->value is comma-delimited string, convert to word16 */
1393+
if (ParseExtKeyUsageStr(ext->value.data, &x509->extKeyUsage,
1394+
x509->heap) != 0) {
1395+
return WOLFSSL_FAILURE;
1396+
}
1397+
x509->extKeyUsageCrit = (byte)ext->crit;
1398+
}
1399+
else {
1400+
return WOLFSSL_FAILURE;
1401+
}
13681402
}
13691403
break;
13701404
case NID_basic_constraints:
@@ -2781,6 +2815,14 @@ static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value)
27812815
}
27822816
ext->value.type = KEY_USAGE_OID;
27832817
break;
2818+
case NID_ext_key_usage:
2819+
if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2820+
!= WOLFSSL_SUCCESS) {
2821+
WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2822+
goto err_cleanup;
2823+
}
2824+
ext->value.type = EXT_KEY_USAGE_OID;
2825+
break;
27842826
default:
27852827
WOLFSSL_MSG("invalid or unsupported NID");
27862828
goto err_cleanup;

tests/api.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46255,27 +46255,51 @@ static int test_wolfSSL_X509V3_EXT_nconf(void)
4625546255
"authorityKeyIdentifier",
4625646256
"subjectAltName",
4625746257
"keyUsage",
46258+
"extendedKeyUsage",
4625846259
};
4625946260
size_t ext_names_count = sizeof(ext_names)/sizeof(*ext_names);
4626046261
int ext_nids[] = {
4626146262
NID_subject_key_identifier,
4626246263
NID_authority_key_identifier,
4626346264
NID_subject_alt_name,
4626446265
NID_key_usage,
46266+
NID_ext_key_usage,
4626546267
};
4626646268
size_t ext_nids_count = sizeof(ext_nids)/sizeof(*ext_nids);
4626746269
const char *ext_values[] = {
4626846270
"hash",
4626946271
"hash",
4627046272
"DNS:example.com, IP:127.0.0.1",
46271-
"digitalSignature,keyEncipherment,dataEncipherment",
46273+
"digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,"
46274+
"keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly",
46275+
"serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,"
46276+
"OCSPSigning",
4627246277
};
4627346278
size_t i;
4627446279
X509_EXTENSION* ext = NULL;
4627546280
X509* x509 = NULL;
46281+
unsigned int keyUsageFlags;
46282+
unsigned int extKeyUsageFlags;
4627646283

4627746284
ExpectNotNull(x509 = X509_new());
4627846285

46286+
/* keyUsage / extKeyUsage should match string above */
46287+
keyUsageFlags = KU_DIGITAL_SIGNATURE
46288+
| KU_NON_REPUDIATION
46289+
| KU_KEY_ENCIPHERMENT
46290+
| KU_DATA_ENCIPHERMENT
46291+
| KU_KEY_AGREEMENT
46292+
| KU_KEY_CERT_SIGN
46293+
| KU_CRL_SIGN
46294+
| KU_ENCIPHER_ONLY
46295+
| KU_DECIPHER_ONLY;
46296+
extKeyUsageFlags = XKU_SSL_CLIENT
46297+
| XKU_SSL_SERVER
46298+
| XKU_CODE_SIGN
46299+
| XKU_SMIME
46300+
| XKU_TIMESTAMP
46301+
| XKU_OCSP_SIGN;
46302+
4627946303
for (i = 0; i < ext_names_count; i++) {
4628046304
ExpectNotNull(ext = X509V3_EXT_nconf(NULL, NULL, ext_names[i],
4628146305
ext_values[i]));
@@ -46295,6 +46319,13 @@ static int test_wolfSSL_X509V3_EXT_nconf(void)
4629546319
ExpectNotNull(ext = X509V3_EXT_nconf(NULL, NULL, ext_names[i],
4629646320
ext_values[i]));
4629746321
ExpectIntEQ(X509_add_ext(x509, ext, -1), WOLFSSL_SUCCESS);
46322+
46323+
if (ext_nids[i] == NID_key_usage) {
46324+
ExpectIntEQ(X509_get_key_usage(x509), keyUsageFlags);
46325+
}
46326+
else if (ext_nids[i] == NID_ext_key_usage) {
46327+
ExpectIntEQ(X509_get_extended_key_usage(x509), extKeyUsageFlags);
46328+
}
4629846329
X509_EXTENSION_free(ext);
4629946330
ext = NULL;
4630046331
}

wolfcrypt/src/asn.c

Lines changed: 128 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -26647,6 +26647,132 @@ int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr,
2664726647
}
2664826648
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
2664926649

26650+
#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) || \
26651+
(defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA))
26652+
26653+
/* Convert key usage string (comma delimited, null terminated) to word16
26654+
* Returns 0 on success, negative on error */
26655+
int ParseKeyUsageStr(const char* value, word16* keyUsage, void* heap)
26656+
{
26657+
int ret = 0;
26658+
char *token, *str, *ptr;
26659+
word32 len = 0;
26660+
word16 usage = 0;
26661+
26662+
if (value == NULL || keyUsage == NULL) {
26663+
return BAD_FUNC_ARG;
26664+
}
26665+
26666+
/* duplicate string (including terminator) */
26667+
len = (word32)XSTRLEN(value);
26668+
str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
26669+
if (str == NULL) {
26670+
return MEMORY_E;
26671+
}
26672+
XMEMCPY(str, value, len + 1);
26673+
26674+
/* parse value, and set corresponding Key Usage value */
26675+
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
26676+
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26677+
return KEYUSAGE_E;
26678+
}
26679+
while (token != NULL) {
26680+
if (!XSTRCASECMP(token, "digitalSignature"))
26681+
usage |= KEYUSE_DIGITAL_SIG;
26682+
else if (!XSTRCASECMP(token, "nonRepudiation") ||
26683+
!XSTRCASECMP(token, "contentCommitment"))
26684+
usage |= KEYUSE_CONTENT_COMMIT;
26685+
else if (!XSTRCASECMP(token, "keyEncipherment"))
26686+
usage |= KEYUSE_KEY_ENCIPHER;
26687+
else if (!XSTRCASECMP(token, "dataEncipherment"))
26688+
usage |= KEYUSE_DATA_ENCIPHER;
26689+
else if (!XSTRCASECMP(token, "keyAgreement"))
26690+
usage |= KEYUSE_KEY_AGREE;
26691+
else if (!XSTRCASECMP(token, "keyCertSign"))
26692+
usage |= KEYUSE_KEY_CERT_SIGN;
26693+
else if (!XSTRCASECMP(token, "cRLSign"))
26694+
usage |= KEYUSE_CRL_SIGN;
26695+
else if (!XSTRCASECMP(token, "encipherOnly"))
26696+
usage |= KEYUSE_ENCIPHER_ONLY;
26697+
else if (!XSTRCASECMP(token, "decipherOnly"))
26698+
usage |= KEYUSE_DECIPHER_ONLY;
26699+
else {
26700+
ret = KEYUSAGE_E;
26701+
break;
26702+
}
26703+
26704+
token = XSTRTOK(NULL, ",", &ptr);
26705+
}
26706+
26707+
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26708+
26709+
if (ret == 0) {
26710+
*keyUsage = usage;
26711+
}
26712+
26713+
return ret;
26714+
}
26715+
26716+
/* Convert extended key usage string (comma delimited, null terminated) to byte
26717+
* Returns 0 on success, negative on error */
26718+
int ParseExtKeyUsageStr(const char* value, byte* extKeyUsage, void* heap)
26719+
{
26720+
int ret = 0;
26721+
char *token, *str, *ptr;
26722+
word32 len = 0;
26723+
byte usage = 0;
26724+
26725+
if (value == NULL || extKeyUsage == NULL) {
26726+
return BAD_FUNC_ARG;
26727+
}
26728+
26729+
/* duplicate string (including terminator) */
26730+
len = (word32)XSTRLEN(value);
26731+
str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
26732+
if (str == NULL) {
26733+
return MEMORY_E;
26734+
}
26735+
XMEMCPY(str, value, len + 1);
26736+
26737+
/* parse value, and set corresponding Key Usage value */
26738+
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
26739+
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26740+
return EXTKEYUSAGE_E;
26741+
}
26742+
while (token != NULL) {
26743+
if (!XSTRCASECMP(token, "any"))
26744+
usage |= EXTKEYUSE_ANY;
26745+
else if (!XSTRCASECMP(token, "serverAuth"))
26746+
usage |= EXTKEYUSE_SERVER_AUTH;
26747+
else if (!XSTRCASECMP(token, "clientAuth"))
26748+
usage |= EXTKEYUSE_CLIENT_AUTH;
26749+
else if (!XSTRCASECMP(token, "codeSigning"))
26750+
usage |= EXTKEYUSE_CODESIGN;
26751+
else if (!XSTRCASECMP(token, "emailProtection"))
26752+
usage |= EXTKEYUSE_EMAILPROT;
26753+
else if (!XSTRCASECMP(token, "timeStamping"))
26754+
usage |= EXTKEYUSE_TIMESTAMP;
26755+
else if (!XSTRCASECMP(token, "OCSPSigning"))
26756+
usage |= EXTKEYUSE_OCSP_SIGN;
26757+
else {
26758+
ret = EXTKEYUSAGE_E;
26759+
break;
26760+
}
26761+
26762+
token = XSTRTOK(NULL, ",", &ptr);
26763+
}
26764+
26765+
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26766+
26767+
if (ret == 0) {
26768+
*extKeyUsage = usage;
26769+
}
26770+
26771+
return ret;
26772+
}
26773+
26774+
#endif /* (CERT_GEN && CERT_EXT) || (OPENSSL_ALL || OPENSSL_EXTRA) */
26775+
2665026776
#ifdef WOLFSSL_CERT_GEN
2665126777
/* Encodes one attribute of the name (issuer/subject)
2665226778
* call we_EncodeName_ex with 0x16, IA5String for email type
@@ -30471,109 +30597,29 @@ int wc_SetAuthKeyId(Cert *cert, const char* file)
3047130597
int wc_SetKeyUsage(Cert *cert, const char *value)
3047230598
{
3047330599
int ret = 0;
30474-
char *token, *str, *ptr;
30475-
word32 len;
3047630600

3047730601
if (cert == NULL || value == NULL)
3047830602
return BAD_FUNC_ARG;
3047930603

3048030604
cert->keyUsage = 0;
3048130605

30482-
/* duplicate string (including terminator) */
30483-
len = (word32)XSTRLEN(value);
30484-
str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30485-
if (str == NULL)
30486-
return MEMORY_E;
30487-
XMEMCPY(str, value, len+1);
30488-
30489-
/* parse value, and set corresponding Key Usage value */
30490-
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
30491-
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30492-
return KEYUSAGE_E;
30493-
}
30494-
while (token != NULL)
30495-
{
30496-
if (!XSTRCASECMP(token, "digitalSignature"))
30497-
cert->keyUsage |= KEYUSE_DIGITAL_SIG;
30498-
else if (!XSTRCASECMP(token, "nonRepudiation") ||
30499-
!XSTRCASECMP(token, "contentCommitment"))
30500-
cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
30501-
else if (!XSTRCASECMP(token, "keyEncipherment"))
30502-
cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
30503-
else if (!XSTRCASECMP(token, "dataEncipherment"))
30504-
cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
30505-
else if (!XSTRCASECMP(token, "keyAgreement"))
30506-
cert->keyUsage |= KEYUSE_KEY_AGREE;
30507-
else if (!XSTRCASECMP(token, "keyCertSign"))
30508-
cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
30509-
else if (!XSTRCASECMP(token, "cRLSign"))
30510-
cert->keyUsage |= KEYUSE_CRL_SIGN;
30511-
else if (!XSTRCASECMP(token, "encipherOnly"))
30512-
cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
30513-
else if (!XSTRCASECMP(token, "decipherOnly"))
30514-
cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
30515-
else {
30516-
ret = KEYUSAGE_E;
30517-
break;
30518-
}
30519-
30520-
token = XSTRTOK(NULL, ",", &ptr);
30521-
}
30606+
ret = ParseKeyUsageStr(value, &cert->keyUsage, cert->heap);
3052230607

30523-
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
3052430608
return ret;
3052530609
}
3052630610

3052730611
/* Set ExtendedKeyUsage from human readable string */
3052830612
int wc_SetExtKeyUsage(Cert *cert, const char *value)
3052930613
{
3053030614
int ret = 0;
30531-
char *token, *str, *ptr;
30532-
word32 len;
3053330615

3053430616
if (cert == NULL || value == NULL)
3053530617
return BAD_FUNC_ARG;
3053630618

3053730619
cert->extKeyUsage = 0;
3053830620

30539-
/* duplicate string (including terminator) */
30540-
len = (word32)XSTRLEN(value);
30541-
str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30542-
if (str == NULL)
30543-
return MEMORY_E;
30544-
XMEMCPY(str, value, len+1);
30545-
30546-
/* parse value, and set corresponding Key Usage value */
30547-
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
30548-
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30549-
return EXTKEYUSAGE_E;
30550-
}
30551-
30552-
while (token != NULL)
30553-
{
30554-
if (!XSTRCASECMP(token, "any"))
30555-
cert->extKeyUsage |= EXTKEYUSE_ANY;
30556-
else if (!XSTRCASECMP(token, "serverAuth"))
30557-
cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;
30558-
else if (!XSTRCASECMP(token, "clientAuth"))
30559-
cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
30560-
else if (!XSTRCASECMP(token, "codeSigning"))
30561-
cert->extKeyUsage |= EXTKEYUSE_CODESIGN;
30562-
else if (!XSTRCASECMP(token, "emailProtection"))
30563-
cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;
30564-
else if (!XSTRCASECMP(token, "timeStamping"))
30565-
cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;
30566-
else if (!XSTRCASECMP(token, "OCSPSigning"))
30567-
cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;
30568-
else {
30569-
ret = EXTKEYUSAGE_E;
30570-
break;
30571-
}
30572-
30573-
token = XSTRTOK(NULL, ",", &ptr);
30574-
}
30621+
ret = ParseExtKeyUsageStr(value, &cert->extKeyUsage, cert->heap);
3057530622

30576-
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
3057730623
return ret;
3057830624
}
3057930625

0 commit comments

Comments
 (0)