Add support for pyOpenSSL.

pyOpenSSL needs the OpenSSL function X509_EXTENSION_dup, so this commit adds
that to the compatibility layer. It also needs to be able to access the DER
encoding of the subject alt names in a cert, so that's added as well.
This commit is contained in:
Hayden Roche
2021-07-28 11:44:01 -07:00
parent f1377ed861
commit 35a33b2f00
8 changed files with 135 additions and 5 deletions

View File

@ -3828,6 +3828,10 @@ void FreeX509(WOLFSSL_X509* x509)
wolfSSL_EVP_PKEY_free(x509->key.pkey);
x509->key.pkey = NULL;
}
if (x509->subjAltNameSrc != NULL) {
XFREE(x509->subjAltNameSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
x509->subjAltNameSrc= NULL;
}
#endif /* OPENSSL_ALL */
#if defined(WOLFSSL_CERT_REQ) && defined(OPENSSL_ALL)
if (x509->challengePwAttr) {
@ -10620,6 +10624,19 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
}
#endif /* WOLFSSL_CERT_EXT */
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
#ifdef OPENSSL_ALL
if (dCert->extSubjAltNameSrc != NULL && dCert->extSubjAltNameSz != 0) {
x509->subjAltNameSrc = (byte*)XMALLOC(dCert->extSubjAltNameSz, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if (x509->subjAltNameSrc != NULL) {
XMEMCPY(x509->subjAltNameSrc,
dCert->extSubjAltNameSrc, dCert->extSubjAltNameSz);
x509->subjAltNameSz = dCert->extSubjAltNameSz;
}
else
ret = MEMORY_E;
}
#endif
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
x509->pkCurveOID = dCert->pkCurveOID;
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */

View File

@ -8525,6 +8525,45 @@ void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT);
}
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION* src)
{
WOLFSSL_X509_EXTENSION* ret = NULL;
int err = 0;
WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_dup");
if (src == NULL) {
err = 1;
}
if (err == 0) {
ret = wolfSSL_X509_EXTENSION_new();
if (ret == NULL) {
err = 1;
}
}
if (err == 0 && src->obj != NULL) {
ret->obj = wolfSSL_ASN1_OBJECT_dup(src->obj);
if (ret->obj == NULL) {
err = 1;
}
}
if (err == 0) {
ret->crit = src->crit;
if (wolfSSL_ASN1_STRING_copy(&ret->value, &src->value) !=
WOLFSSL_SUCCESS) {
err = 1;
}
}
if (err == 1 && ret != NULL) {
wolfSSL_X509_EXTENSION_free(ret);
ret = NULL;
}
return ret;
}
/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
{
@ -9048,10 +9087,23 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
if (!isSet)
break;
#ifdef OPENSSL_ALL
ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjAltNameSrc,
x509->subjAltNameSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
return NULL;
}
#endif
sk = (WOLFSSL_GENERAL_NAMES*)XMALLOC(
sizeof(WOLFSSL_GENERAL_NAMES), NULL,
DYNAMIC_TYPE_ASN1);
if (sk == NULL) {
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
return NULL;
}
XMEMSET(sk, 0, sizeof(WOLFSSL_GENERAL_NAMES));
@ -9065,6 +9117,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
gn = wolfSSL_GENERAL_NAME_new();
if (gn == NULL) {
WOLFSSL_MSG("Error creating GENERAL_NAME");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
wolfSSL_sk_free(sk);
return NULL;
}
@ -9074,6 +9128,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
gn->d.ia5->length) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set failed");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
wolfSSL_GENERAL_NAME_free(gn);
wolfSSL_sk_free(sk);
return NULL;
@ -9084,19 +9140,23 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
if (dns != NULL) {
if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error pushing onto stack");
wolfSSL_GENERAL_NAME_free(gn);
wolfSSL_sk_free(sk);
sk = NULL;
WOLFSSL_MSG("Error pushing onto stack");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
wolfSSL_GENERAL_NAME_free(gn);
wolfSSL_sk_free(sk);
return NULL;
}
}
}
if (wolfSSL_sk_GENERAL_NAME_push(sk,gn) !=
WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error pushing onto stack");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
wolfSSL_GENERAL_NAME_free(gn);
wolfSSL_sk_free(sk);
sk = NULL;
return NULL;
}
}
ext->ext_sk = sk;

View File

@ -40440,7 +40440,41 @@ static void test_wolfSSL_X509_get_ext_by_NID(void)
AssertIntEQ(rc, -1);
wolfSSL_X509_free(x509);
#endif
}
static void test_wolfSSL_X509_get_ext_subj_alt_name(void)
{
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
int rc;
XFILE f;
WOLFSSL_X509* x509;
WOLFSSL_X509_EXTENSION* ext;
WOLFSSL_ASN1_STRING* sanString;
byte* sanDer;
const byte expectedDer[] = {
0x30, 0x13, 0x82, 0x0b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
0x63, 0x6f, 0x6d, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01};
printf(testingFmt, "test_wolfSSL_X509_get_ext_subj_alt_name");
f = XFOPEN("./certs/server-cert.pem", "rb");
AssertTrue(f != XBADFILE);
AssertNotNull(x509 = PEM_read_X509(f, NULL, NULL, NULL));
fclose(f);
rc = X509_get_ext_by_NID(x509, NID_subject_alt_name, -1);
AssertIntNE(rc, -1);
AssertNotNull(ext = X509_get_ext(x509, rc));
AssertNotNull(sanString = X509_EXTENSION_get_data(ext));
AssertIntEQ(ASN1_STRING_length(sanString), sizeof(expectedDer));
AssertNotNull(sanDer = ASN1_STRING_data(sanString));
AssertIntEQ(XMEMCMP(sanDer, expectedDer, sizeof(expectedDer)), 0);
X509_free(x509);
printf(resultFmt, passed);
#endif
}
@ -47006,6 +47040,7 @@ void ApiTest(void)
test_wolfSSL_X509V3_EXT();
test_wolfSSL_X509_get_ext();
test_wolfSSL_X509_get_ext_by_NID();
test_wolfSSL_X509_get_ext_subj_alt_name();
test_wolfSSL_X509_get_ext_count();
test_wolfSSL_X509_EXTENSION_new();
test_wolfSSL_X509_EXTENSION_get_object();

View File

@ -8360,6 +8360,11 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
return ASN_PARSE_E;
}
#ifdef OPENSSL_ALL
cert->extSubjAltNameSrc = input;
cert->extSubjAltNameSz = sz;
#endif
cert->weOwnAltNames = 1;
while (length > 0) {

View File

@ -3891,6 +3891,9 @@ struct WOLFSSL_X509 {
byte* authKeyId;
byte* subjKeyId;
byte* extKeyUsageSrc;
#ifdef OPENSSL_ALL
byte* subjAltNameSrc;
#endif
const byte* CRLInfo;
byte* authInfo;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
@ -3905,6 +3908,9 @@ struct WOLFSSL_X509 {
word32 subjKeyIdSz;
word32 extKeyUsageSz;
word32 extKeyUsageCount;
#ifdef OPENSSL_ALL
word32 subjAltNameSz;
#endif
byte CRLdistSet:1;
byte CRLdistCrit:1;

View File

@ -495,6 +495,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object
#define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data
#define X509_EXTENSION_dup wolfSSL_X509_EXTENSION_dup
#define sk_X509_new wolfSSL_sk_X509_new
#define sk_X509_new_null wolfSSL_sk_X509_new

View File

@ -3777,6 +3777,8 @@ WOLFSSL_API int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x, int loc);
WOLFSSL_API int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex);
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void);
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(
WOLFSSL_X509_EXTENSION*);
WOLFSSL_API int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,
WOLFSSL_X509_EXTENSION* ext);
WOLFSSL_API void wolfSSL_sk_X509_EXTENSION_free(WOLFSSL_STACK* sk);

View File

@ -856,6 +856,10 @@ struct DecodedCert {
const byte* extSubjKeyIdSrc;
word32 extSubjKeyIdSz;
#endif
#ifdef OPENSSL_ALL
const byte* extSubjAltNameSrc;
word32 extSubjAltNameSz;
#endif
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
word32 pkCurveOID; /* Public Key's curve OID */