forked from wolfSSL/wolfssl
Merge pull request #6585 from cconlon/x509Ext
Fixes for WOLFSSL_X509 cert gen, WOLFSSL_ALT_NAMES to --enable-jni
This commit is contained in:
@ -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"
|
||||
|
@ -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. */
|
||||
|
52
src/x509.c
52
src/x509.c
@ -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:
|
||||
@ -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;
|
||||
|
33
tests/api.c
33
tests/api.c
@ -46255,6 +46255,7 @@ 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[] = {
|
||||
@ -46262,20 +46263,43 @@ static int test_wolfSSL_X509V3_EXT_nconf(void)
|
||||
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]));
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
@ -30471,56 +30597,14 @@ 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);
|
||||
ret = ParseKeyUsageStr(value, &cert->keyUsage, cert->heap);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -30528,52 +30612,14 @@ int wc_SetKeyUsage(Cert *cert, const char *value)
|
||||
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);
|
||||
ret = ParseExtKeyUsageStr(value, &cert->extKeyUsage, cert->heap);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2287,6 +2287,14 @@ WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type,
|
||||
WOLFSSL_LOCAL int AllocDer(DerBuffer** der, word32 length, int type, void* heap);
|
||||
WOLFSSL_LOCAL void FreeDer(DerBuffer** der);
|
||||
|
||||
#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) || \
|
||||
(defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA))
|
||||
WOLFSSL_LOCAL int ParseKeyUsageStr(const char* value, word16* keyUsage,
|
||||
void* heap);
|
||||
WOLFSSL_LOCAL int ParseExtKeyUsageStr(const char* value, byte* extKeyUsage,
|
||||
void* heap);
|
||||
#endif /* (CERT_GEN && CERT_EXT) || (OPENSSL_ALL || OPENSSL_EXTRA) */
|
||||
|
||||
#endif /* !NO_CERTS */
|
||||
|
||||
#ifdef HAVE_SMIME
|
||||
|
Reference in New Issue
Block a user