Skip to content

Commit

Permalink
Merge pull request #6585 from cconlon/x509Ext
Browse files Browse the repository at this point in the history
Fixes for WOLFSSL_X509 cert gen, WOLFSSL_ALT_NAMES to --enable-jni
  • Loading branch information
JacobBarthelmeh committed Jul 12, 2023
2 parents 62c14e4 + a8ed78e commit b889b27
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 88 deletions.
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5850,6 +5850,9 @@ then
ENABLED_ALPN="yes"
AM_CFLAGS="$AM_CFLAGS -DHAVE_ALPN"
fi

# cert gen requires alt names
ENABLED_ALTNAMES="yes"
fi

if test "$ENABLED_LIGHTY" = "yes"
Expand Down
3 changes: 3 additions & 0 deletions src/ssl_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,9 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_dup(WOLFSSL_ASN1_OBJECT* obj)
dupl->grp = obj->grp;
dupl->nid = obj->nid;
dupl->objSz = obj->objSz;
#ifdef OPENSSL_EXTRA
dupl->ca = obj->ca;
#endif
/* Check for encoding. */
if (obj->obj) {
/* Allocate memory for ASN.1 OBJECT_ID DER encoding. */
Expand Down
52 changes: 47 additions & 5 deletions src/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -1360,11 +1360,45 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int lo
break;
}
case NID_key_usage:
if (ext && ext->value.data &&
ext->value.length == sizeof(word16)) {
x509->keyUsage = *(word16*)ext->value.data;
x509->keyUsageCrit = (byte)ext->crit;
x509->keyUsageSet = 1;
if (ext && ext->value.data) {
if (ext->value.length == sizeof(word16)) {
/* if ext->value is already word16, set directly */
x509->keyUsage = *(word16*)ext->value.data;
x509->keyUsageCrit = (byte)ext->crit;
x509->keyUsageSet = 1;
}
else if (ext->value.length > 0) {
/* ext->value is comma-delimited string, convert to word16 */
if (ParseKeyUsageStr(ext->value.data, &x509->keyUsage,
x509->heap) != 0) {
return WOLFSSL_FAILURE;
}
x509->keyUsageCrit = (byte)ext->crit;
x509->keyUsageSet = 1;
}
else {
return WOLFSSL_FAILURE;
}
}
break;
case NID_ext_key_usage:
if (ext && ext->value.data) {
if (ext->value.length == sizeof(byte)) {
/* if ext->value is already word16, set directly */
x509->extKeyUsage = *(byte*)ext->value.data;
x509->extKeyUsageCrit = (byte)ext->crit;
}
else if (ext->value.length > 0) {
/* ext->value is comma-delimited string, convert to word16 */
if (ParseExtKeyUsageStr(ext->value.data, &x509->extKeyUsage,
x509->heap) != 0) {
return WOLFSSL_FAILURE;
}
x509->extKeyUsageCrit = (byte)ext->crit;
}
else {
return WOLFSSL_FAILURE;
}
}
break;
case NID_basic_constraints:
Expand Down Expand Up @@ -2781,6 +2815,14 @@ static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value)
}
ext->value.type = KEY_USAGE_OID;
break;
case NID_ext_key_usage:
if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
!= WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
goto err_cleanup;
}
ext->value.type = EXT_KEY_USAGE_OID;
break;
default:
WOLFSSL_MSG("invalid or unsupported NID");
goto err_cleanup;
Expand Down
33 changes: 32 additions & 1 deletion tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -46255,27 +46255,51 @@ static int test_wolfSSL_X509V3_EXT_nconf(void)
"authorityKeyIdentifier",
"subjectAltName",
"keyUsage",
"extendedKeyUsage",
};
size_t ext_names_count = sizeof(ext_names)/sizeof(*ext_names);
int ext_nids[] = {
NID_subject_key_identifier,
NID_authority_key_identifier,
NID_subject_alt_name,
NID_key_usage,
NID_ext_key_usage,
};
size_t ext_nids_count = sizeof(ext_nids)/sizeof(*ext_nids);
const char *ext_values[] = {
"hash",
"hash",
"DNS:example.com, IP:127.0.0.1",
"digitalSignature,keyEncipherment,dataEncipherment",
"digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,"
"keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly",
"serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,"
"OCSPSigning",
};
size_t i;
X509_EXTENSION* ext = NULL;
X509* x509 = NULL;
unsigned int keyUsageFlags;
unsigned int extKeyUsageFlags;

ExpectNotNull(x509 = X509_new());

/* keyUsage / extKeyUsage should match string above */
keyUsageFlags = KU_DIGITAL_SIGNATURE
| KU_NON_REPUDIATION
| KU_KEY_ENCIPHERMENT
| KU_DATA_ENCIPHERMENT
| KU_KEY_AGREEMENT
| KU_KEY_CERT_SIGN
| KU_CRL_SIGN
| KU_ENCIPHER_ONLY
| KU_DECIPHER_ONLY;
extKeyUsageFlags = XKU_SSL_CLIENT
| XKU_SSL_SERVER
| XKU_CODE_SIGN
| XKU_SMIME
| XKU_TIMESTAMP
| XKU_OCSP_SIGN;

for (i = 0; i < ext_names_count; i++) {
ExpectNotNull(ext = X509V3_EXT_nconf(NULL, NULL, ext_names[i],
ext_values[i]));
Expand All @@ -46295,6 +46319,13 @@ static int test_wolfSSL_X509V3_EXT_nconf(void)
ExpectNotNull(ext = X509V3_EXT_nconf(NULL, NULL, ext_names[i],
ext_values[i]));
ExpectIntEQ(X509_add_ext(x509, ext, -1), WOLFSSL_SUCCESS);

if (ext_nids[i] == NID_key_usage) {
ExpectIntEQ(X509_get_key_usage(x509), keyUsageFlags);
}
else if (ext_nids[i] == NID_ext_key_usage) {
ExpectIntEQ(X509_get_extended_key_usage(x509), extKeyUsageFlags);
}
X509_EXTENSION_free(ext);
ext = NULL;
}
Expand Down
210 changes: 128 additions & 82 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -26647,6 +26647,132 @@ int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr,
}
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */

#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) || \
(defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA))

/* Convert key usage string (comma delimited, null terminated) to word16
* Returns 0 on success, negative on error */
int ParseKeyUsageStr(const char* value, word16* keyUsage, void* heap)
{
int ret = 0;
char *token, *str, *ptr;
word32 len = 0;
word16 usage = 0;

if (value == NULL || keyUsage == NULL) {
return BAD_FUNC_ARG;
}

/* duplicate string (including terminator) */
len = (word32)XSTRLEN(value);
str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (str == NULL) {
return MEMORY_E;
}
XMEMCPY(str, value, len + 1);

/* parse value, and set corresponding Key Usage value */
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
return KEYUSAGE_E;
}
while (token != NULL) {
if (!XSTRCASECMP(token, "digitalSignature"))
usage |= KEYUSE_DIGITAL_SIG;
else if (!XSTRCASECMP(token, "nonRepudiation") ||
!XSTRCASECMP(token, "contentCommitment"))
usage |= KEYUSE_CONTENT_COMMIT;
else if (!XSTRCASECMP(token, "keyEncipherment"))
usage |= KEYUSE_KEY_ENCIPHER;
else if (!XSTRCASECMP(token, "dataEncipherment"))
usage |= KEYUSE_DATA_ENCIPHER;
else if (!XSTRCASECMP(token, "keyAgreement"))
usage |= KEYUSE_KEY_AGREE;
else if (!XSTRCASECMP(token, "keyCertSign"))
usage |= KEYUSE_KEY_CERT_SIGN;
else if (!XSTRCASECMP(token, "cRLSign"))
usage |= KEYUSE_CRL_SIGN;
else if (!XSTRCASECMP(token, "encipherOnly"))
usage |= KEYUSE_ENCIPHER_ONLY;
else if (!XSTRCASECMP(token, "decipherOnly"))
usage |= KEYUSE_DECIPHER_ONLY;
else {
ret = KEYUSAGE_E;
break;
}

token = XSTRTOK(NULL, ",", &ptr);
}

XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);

if (ret == 0) {
*keyUsage = usage;
}

return ret;
}

/* Convert extended key usage string (comma delimited, null terminated) to byte
* Returns 0 on success, negative on error */
int ParseExtKeyUsageStr(const char* value, byte* extKeyUsage, void* heap)
{
int ret = 0;
char *token, *str, *ptr;
word32 len = 0;
byte usage = 0;

if (value == NULL || extKeyUsage == NULL) {
return BAD_FUNC_ARG;
}

/* duplicate string (including terminator) */
len = (word32)XSTRLEN(value);
str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (str == NULL) {
return MEMORY_E;
}
XMEMCPY(str, value, len + 1);

/* parse value, and set corresponding Key Usage value */
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
return EXTKEYUSAGE_E;
}
while (token != NULL) {
if (!XSTRCASECMP(token, "any"))
usage |= EXTKEYUSE_ANY;
else if (!XSTRCASECMP(token, "serverAuth"))
usage |= EXTKEYUSE_SERVER_AUTH;
else if (!XSTRCASECMP(token, "clientAuth"))
usage |= EXTKEYUSE_CLIENT_AUTH;
else if (!XSTRCASECMP(token, "codeSigning"))
usage |= EXTKEYUSE_CODESIGN;
else if (!XSTRCASECMP(token, "emailProtection"))
usage |= EXTKEYUSE_EMAILPROT;
else if (!XSTRCASECMP(token, "timeStamping"))
usage |= EXTKEYUSE_TIMESTAMP;
else if (!XSTRCASECMP(token, "OCSPSigning"))
usage |= EXTKEYUSE_OCSP_SIGN;
else {
ret = EXTKEYUSAGE_E;
break;
}

token = XSTRTOK(NULL, ",", &ptr);
}

XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);

if (ret == 0) {
*extKeyUsage = usage;
}

return ret;
}

#endif /* (CERT_GEN && CERT_EXT) || (OPENSSL_ALL || OPENSSL_EXTRA) */

#ifdef WOLFSSL_CERT_GEN
/* Encodes one attribute of the name (issuer/subject)
* call we_EncodeName_ex with 0x16, IA5String for email type
Expand Down Expand Up @@ -30471,109 +30597,29 @@ int wc_SetAuthKeyId(Cert *cert, const char* file)
int wc_SetKeyUsage(Cert *cert, const char *value)
{
int ret = 0;
char *token, *str, *ptr;
word32 len;

if (cert == NULL || value == NULL)
return BAD_FUNC_ARG;

cert->keyUsage = 0;

/* duplicate string (including terminator) */
len = (word32)XSTRLEN(value);
str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (str == NULL)
return MEMORY_E;
XMEMCPY(str, value, len+1);

/* parse value, and set corresponding Key Usage value */
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
return KEYUSAGE_E;
}
while (token != NULL)
{
if (!XSTRCASECMP(token, "digitalSignature"))
cert->keyUsage |= KEYUSE_DIGITAL_SIG;
else if (!XSTRCASECMP(token, "nonRepudiation") ||
!XSTRCASECMP(token, "contentCommitment"))
cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
else if (!XSTRCASECMP(token, "keyEncipherment"))
cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
else if (!XSTRCASECMP(token, "dataEncipherment"))
cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
else if (!XSTRCASECMP(token, "keyAgreement"))
cert->keyUsage |= KEYUSE_KEY_AGREE;
else if (!XSTRCASECMP(token, "keyCertSign"))
cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
else if (!XSTRCASECMP(token, "cRLSign"))
cert->keyUsage |= KEYUSE_CRL_SIGN;
else if (!XSTRCASECMP(token, "encipherOnly"))
cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
else if (!XSTRCASECMP(token, "decipherOnly"))
cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
else {
ret = KEYUSAGE_E;
break;
}

token = XSTRTOK(NULL, ",", &ptr);
}
ret = ParseKeyUsageStr(value, &cert->keyUsage, cert->heap);

XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}

/* Set ExtendedKeyUsage from human readable string */
int wc_SetExtKeyUsage(Cert *cert, const char *value)
{
int ret = 0;
char *token, *str, *ptr;
word32 len;

if (cert == NULL || value == NULL)
return BAD_FUNC_ARG;

cert->extKeyUsage = 0;

/* duplicate string (including terminator) */
len = (word32)XSTRLEN(value);
str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (str == NULL)
return MEMORY_E;
XMEMCPY(str, value, len+1);

/* parse value, and set corresponding Key Usage value */
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
return EXTKEYUSAGE_E;
}

while (token != NULL)
{
if (!XSTRCASECMP(token, "any"))
cert->extKeyUsage |= EXTKEYUSE_ANY;
else if (!XSTRCASECMP(token, "serverAuth"))
cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;
else if (!XSTRCASECMP(token, "clientAuth"))
cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
else if (!XSTRCASECMP(token, "codeSigning"))
cert->extKeyUsage |= EXTKEYUSE_CODESIGN;
else if (!XSTRCASECMP(token, "emailProtection"))
cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;
else if (!XSTRCASECMP(token, "timeStamping"))
cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;
else if (!XSTRCASECMP(token, "OCSPSigning"))
cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;
else {
ret = EXTKEYUSAGE_E;
break;
}

token = XSTRTOK(NULL, ",", &ptr);
}
ret = ParseExtKeyUsageStr(value, &cert->extKeyUsage, cert->heap);

XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}

Expand Down
Loading

0 comments on commit b889b27

Please sign in to comment.