Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for WOLFSSL_X509 cert gen, WOLFSSL_ALT_NAMES to --enable-jni #6585

Merged
merged 2 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5839,6 +5839,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 @@ -46250,27 +46250,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 @@ -46290,6 +46314,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 @@ -26660,6 +26660,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 @@ -30484,109 +30610,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