From 3da810cb1b32583a6c1ded2f138062759586ae07 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 1 Oct 2021 14:08:58 +0200 Subject: [PATCH] Implement OpenSSL API's - `OBJ_DUP` - `i2d_PKCS7` - `BN_rshift1 - `BN_rshift` testing - Add `--enable-krb` --- configure.ac | 32 ++++++++-- src/ssl.c | 118 +++++++++++++++++++++++++++++++++---- tests/api.c | 44 +++++++++++++- wolfssl/internal.h | 4 +- wolfssl/openssl/bn.h | 1 + wolfssl/openssl/opensslv.h | 2 +- wolfssl/openssl/pkcs7.h | 2 + wolfssl/openssl/ssl.h | 9 +++ wolfssl/ssl.h | 15 ++++- 9 files changed, 205 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index f7ea2dbed..af899ce33 100644 --- a/configure.ac +++ b/configure.ac @@ -911,6 +911,7 @@ AC_ARG_ENABLE([mcast], # WOLFSSL_MYSQL_COMPATIBLE # web server (--enable-webserver) HAVE_WEBSERVER # net-snmp (--enable-net-snmp) +# krb (--enable-krb) WOLFSSL_KRB # Bind DNS compatibility Build @@ -1033,6 +1034,14 @@ AC_ARG_ENABLE([net-snmp], [ ENABLED_NETSNMP=no ] ) +# kerberos 5 Build +AC_ARG_ENABLE([krb], + [AS_HELP_STRING([--enable-krb],[Enable kerberos 5 support (default: disabled)])], + [ ENABLED_KRB=$enableval ], + [ ENABLED_KRB=no ] + ) + + #IP alternative name Support AC_ARG_ENABLE([ip-alt-name], [AS_HELP_STRING([--enable-ip-alt-name],[Enable IP subject alternative name (default: disabled)])], @@ -1104,7 +1113,8 @@ if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || \ test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || \ test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" || \ test "$ENABLED_NTP" = "yes" || test "$ENABLED_NETSNMP" = "yes" || \ - test "$ENABLED_OPENRESTY" = "yes" || test "$ENABLED_RSYSLOG" = "yes" + test "$ENABLED_OPENRESTY" = "yes" || test "$ENABLED_RSYSLOG" = "yes" || \ + test "$ENABLED_KRB" = "yes" then ENABLED_OPENSSLALL="yes" fi @@ -3249,7 +3259,7 @@ AC_ARG_ENABLE([des3], [ ENABLED_DES3=no ] ) -if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "x$ENABLED_WPAS" != "xno" || test "$ENABLED_NETSNMP" = "yes" || test "$ENABLED_LIBSSH2" = "yes" +if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "x$ENABLED_WPAS" != "xno" || test "$ENABLED_NETSNMP" = "yes" || test "$ENABLED_LIBSSH2" = "yes" || test "$ENABLED_KRB" = "yes" then ENABLED_DES3="yes" fi @@ -3267,7 +3277,7 @@ then fi # ARC4 -if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_WPAS" = "yes" +if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_KRB" = "yes" then # Requires RC4 make sure on (if not forcefully disabled with --disable-arc4) test "$enable_arc4" = "" && enable_arc4=yes @@ -3824,7 +3834,8 @@ AC_ARG_ENABLE([crl], ) if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" || \ - test "x$ENABLED_WPAS" != "xno" || test "x$ENABLED_LIGHTY" = "xyes" || test "x$ENABLED_NETSNMP" = "xyes" + test "x$ENABLED_WPAS" != "xno" || test "x$ENABLED_LIGHTY" = "xyes" || test "x$ENABLED_NETSNMP" = "xyes" || \ + test "x$ENABLED_KRB" = "xyes" then ENABLED_CRL=yes fi @@ -4719,6 +4730,17 @@ then fi fi +if test "$ENABLED_KRB" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KRB -DWOLFSSL_AES_DIRECT" + + # Requires PKCS7 + if test "x$ENABLED_PKCS7" = "xno" + then + ENABLED_PKCS7="yes" + fi +fi + if test "$ENABLED_SIGNAL" = "yes" then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SIGNAL -DWOLFSSL_AES_COUNTER -DWOLFSSL_AES_DIRECT" @@ -5164,7 +5186,7 @@ AC_ARG_ENABLE([md4], if test "$ENABLED_MD4" = "no" then #turn on MD4 if using stunnel - if test "x$ENABLED_STUNNEL" = "xyes" || test "x$ENABLED_WPAS" != "xno" + if test "x$ENABLED_STUNNEL" = "xyes" || test "x$ENABLED_WPAS" != "xno" || test "x$ENABLED_KRB" = "xyes" then ENABLED_MD4="yes" else diff --git a/src/ssl.c b/src/ssl.c index 3cbba9a10..70710be7e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -21094,6 +21094,66 @@ void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk) wolfSSL_sk_free(sk); } +#ifdef HAVE_CRL +WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void) +{ + WOLFSSL_STACK* s = wolfSSL_sk_new_node(NULL); + if (s != NULL) + s->type = STACK_TYPE_X509_CRL; + return s; +} + +void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk, + void (*f) (WOLFSSL_X509_CRL*)) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_pop_free"); + + while (sk != NULL) { + WOLFSSL_STACK* next = sk->next; + if (f) + f(sk->data.crl); + else + wolfSSL_X509_CRL_free(sk->data.crl); + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + sk = next; + } +} + +void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk) +{ + wolfSSL_sk_X509_CRL_pop_free(sk, NULL); +} + +/* return 1 on success 0 on fail */ +int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk, WOLFSSL_X509_CRL* crl) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_push"); + + if (sk == NULL || crl == NULL) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_sk_push(sk, crl); +} + +WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF(WOLFSSL_X509)* sk, + int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_value"); + if (sk) + return (WOLFSSL_X509_CRL*)wolfSSL_sk_value(sk, i); + return NULL; +} + +int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_num"); + if (sk) + return wolfSSL_sk_num(sk); + return 0; +} +#endif /* HAVE_CRL */ + #endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */ #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) @@ -30868,6 +30928,8 @@ void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) return (void*)sk->data.x509_obj; case STACK_TYPE_DIST_POINT: return (void*)sk->data.dp; + case STACK_TYPE_X509_CRL: + return (void*)sk->data.crl; default: return (void*)sk->data.generic; } @@ -61609,15 +61671,16 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) return (PKCS7*)pkcs7; } -int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) +int wolfSSL_i2d_PKCS7(PKCS7 *p7, unsigned char **out) { byte* output = NULL; + int localBuf = 0; int len; WC_RNG rng; int ret = WOLFSSL_FAILURE; WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio"); - if (!bio || !p7) { + if (!out || !p7) { WOLFSSL_MSG("Bad parameter"); return WOLFSSL_FAILURE; } @@ -61635,10 +61698,16 @@ int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) goto cleanup; } - output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (!output) { - WOLFSSL_MSG("malloc error"); - goto cleanup; + if (*out == NULL) { + output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!output) { + WOLFSSL_MSG("malloc error"); + goto cleanup; + } + localBuf = 1; + } + else { + output = *out; } if ((len = wc_PKCS7_EncodeSignedData(p7, output, len)) < 0) { @@ -61646,6 +61715,36 @@ int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) goto cleanup; } + ret = len; +cleanup: + if (p7->rng == &rng) { + wc_FreeRng(&rng); + p7->rng = NULL; + } + if (ret == WOLFSSL_FAILURE && localBuf && output) + XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (ret != WOLFSSL_FAILURE) + *out = output; + return ret; +} + +int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) +{ + byte* output = NULL; + int len; + int ret = WOLFSSL_FAILURE; + WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio"); + + if (!bio || !p7) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if ((len = wolfSSL_i2d_PKCS7(p7, &output)) == WOLFSSL_FAILURE) { + WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); + goto cleanup; + } + if (wolfSSL_BIO_write(bio, output, len) <= 0) { WOLFSSL_MSG("wolfSSL_BIO_write error"); goto cleanup; @@ -61653,13 +61752,8 @@ int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) ret = WOLFSSL_SUCCESS; cleanup: - if (p7->rng == &rng) { - wc_FreeRng(&rng); - p7->rng = NULL; - } - if (output) { + if (output) XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); - } return ret; } diff --git a/tests/api.c b/tests/api.c index f32dc09ba..df58e91ad 100644 --- a/tests/api.c +++ b/tests/api.c @@ -34257,7 +34257,7 @@ static void test_wolfSSL_BN(void) /* check result 3*2 */ AssertIntEQ(BN_get_word(d), 6); - /* c/b = */ + /* c/b => db + a */ AssertIntEQ(BN_div(d, NULL, c, b, NULL), WOLFSSL_FAILURE); AssertIntEQ(BN_div(d, a, c, b, NULL), WOLFSSL_SUCCESS); @@ -34286,6 +34286,14 @@ static void test_wolfSSL_BN(void) AssertIntEQ(BN_get_word(d), 8); #endif /* WOLFSSL_KEY_GEN */ + AssertIntEQ(BN_set_word(a, 1 << 6), SSL_SUCCESS); + AssertIntEQ(BN_rshift(b, a, 6), SSL_SUCCESS); + AssertIntEQ(BN_is_zero(b), 0); + AssertIntEQ(BN_rshift(b, a, 7), SSL_SUCCESS); + AssertIntEQ(BN_is_zero(b), 1); + AssertIntEQ(BN_rshift1(b, a), SSL_SUCCESS); + AssertIntEQ(BN_is_zero(b), 0); + /* set b back to 2 */ AssertIntEQ(BN_set_word(b, 2), SSL_SUCCESS); @@ -37539,6 +37547,7 @@ static void test_wolfSSL_OBJ(void) !defined(HAVE_FIPS) && !defined(NO_SHA) && defined(WOLFSSL_CERT_EXT) && \ defined(WOLFSSL_CERT_GEN) ASN1_OBJECT *obj = NULL; + ASN1_OBJECT *obj2 = NULL; char buf[50]; XFILE fp; @@ -37581,7 +37590,10 @@ static void test_wolfSSL_OBJ(void) AssertIntEQ(OBJ_txt2nid(buf), NID_sha256); #endif AssertIntGT(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 0), 0); + AssertNotNull(obj2 = OBJ_dup(obj)); + AssertIntEQ(OBJ_cmp(obj, obj2), 0); ASN1_OBJECT_free(obj); + ASN1_OBJECT_free(obj2); for (i = 0; f[i] != NULL; i++) { @@ -46181,6 +46193,31 @@ static void test_sk_X509(void) #endif } +static void test_sk_X509_CRL(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && defined(HAVE_CRL) + X509_CRL* crl; + XFILE fp; + STACK_OF(X509_CRL)* s; + + printf(testingFmt, "test_sk_X509_CRL"); + + fp = XFOPEN("./certs/crl/crl.pem", "rb"); + AssertTrue((fp != XBADFILE)); + AssertNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL, NULL, NULL)); + XFCLOSE(fp); + + AssertNotNull(s = sk_X509_CRL_new()); + AssertIntEQ(sk_X509_CRL_num(s), 0); + AssertIntEQ(sk_X509_CRL_push(s, crl), 1); + AssertIntEQ(sk_X509_CRL_num(s), 1); + AssertPtrEq(sk_X509_CRL_value(s, 0), crl); + sk_X509_CRL_free(s); + + printf(resultFmt, passed); +#endif +} + static void test_X509_get_signature_nid(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) @@ -46302,6 +46339,7 @@ static void test_wolfssl_PKCS7(void) BIO* bio; byte key[sizeof(client_key_der_2048)]; word32 keySz = (word32)sizeof(key); + byte* out = NULL; #endif AssertIntGT((len = CreatePKCS7SignedData(data, len, content, @@ -46337,6 +46375,8 @@ static void test_wolfssl_PKCS7(void) pkcs7->hashOID = SHAh; AssertNotNull(bio = BIO_new(BIO_s_mem())); AssertIntEQ(i2d_PKCS7_bio(bio, pkcs7), 1); + AssertIntEQ(i2d_PKCS7(pkcs7, &out), 644); + XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER); BIO_free(bio); #endif @@ -52171,6 +52211,8 @@ void ApiTest(void) test_ERR_load_crypto_strings(); /* OpenSSL sk_X509 API test */ test_sk_X509(); + /* OpenSSL sk_X509_CRL API test */ + test_sk_X509_CRL(); /* OpenSSL X509 API test */ test_X509_get_signature_nid(); /* OpenSSL X509 REQ API test */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 15929010c..d3b3017ad 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3787,7 +3787,8 @@ typedef enum { STACK_TYPE_BY_DIR_entry = 12, STACK_TYPE_BY_DIR_hash = 13, STACK_TYPE_X509_OBJ = 14, - STACK_TYPE_DIST_POINT = 15 + STACK_TYPE_DIST_POINT = 15, + STACK_TYPE_X509_CRL = 16, } WOLF_STACK_TYPE; struct WOLFSSL_STACK { @@ -3818,6 +3819,7 @@ struct WOLFSSL_STACK { WOLFSSL_BY_DIR_HASH* dir_hash; WOLFSSL_X509_OBJECT* x509_obj; WOLFSSL_DIST_POINT* dp; + WOLFSSL_X509_CRL* crl; } data; void* heap; /* memory heap hint */ WOLFSSL_STACK* next; diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index fc6fda20c..0efc263e5 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -215,6 +215,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_is_prime_ex wolfSSL_BN_is_prime_ex #define BN_print_fp wolfSSL_BN_print_fp #define BN_rshift wolfSSL_BN_rshift +#define BN_rshift1(r, a) wolfSSL_BN_rshift((r), (a), 1) #define BN_mod_word wolfSSL_BN_mod_word #define BN_CTX_get wolfSSL_BN_CTX_get diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index 38ef42ef9..0d6e5a9e9 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -32,7 +32,7 @@ /* valid version */ #elif defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIBEST) || \ defined(WOLFSSL_BIND) || defined(WOLFSSL_NGINX) || \ - defined(WOLFSSL_RSYSLOG) + defined(WOLFSSL_RSYSLOG) || defined(WOLFSSL_KRB) /* For Apache httpd, Use 1.1.0 compatibility */ #define OPENSSL_VERSION_NUMBER 0x10100000L #elif defined(WOLFSSL_QT) || defined(WOLFSSL_PYTHON) diff --git a/wolfssl/openssl/pkcs7.h b/wolfssl/openssl/pkcs7.h index 0eb8a1caf..ec02849a3 100644 --- a/wolfssl/openssl/pkcs7.h +++ b/wolfssl/openssl/pkcs7.h @@ -56,6 +56,7 @@ WOLFSSL_LOCAL PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len, byte* content, word32 contentSz); WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7); WOLFSSL_API int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7); +WOLFSSL_API int wolfSSL_i2d_PKCS7(PKCS7 *p7, unsigned char **out); WOLFSSL_API int wolfSSL_PKCS7_verify(PKCS7* p7, WOLFSSL_STACK* certs, WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags); WOLFSSL_API int wolfSSL_PKCS7_encode_certs(PKCS7* p7, WOLFSSL_STACK* certs, @@ -76,6 +77,7 @@ WOLFSSL_API PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in, WOLFSSL_BIO** bcont #define d2i_PKCS7 wolfSSL_d2i_PKCS7 #define d2i_PKCS7_bio wolfSSL_d2i_PKCS7_bio #define i2d_PKCS7_bio wolfSSL_i2d_PKCS7_bio +#define i2d_PKCS7 wolfSSL_i2d_PKCS7 #define PKCS7_verify wolfSSL_PKCS7_verify #define PKCS7_get0_signers wolfSSL_PKCS7_get0_signers #define PEM_write_bio_PKCS7 wolfSSL_PEM_write_bio_PKCS7 diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 5760200fb..5d37b3770 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -529,6 +529,13 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define sk_X509_free wolfSSL_sk_X509_free #define X509_chain_up_ref wolfSSL_X509_chain_up_ref +#define sk_X509_CRL_new wolfSSL_sk_X509_CRL_new +#define sk_X509_CRL_pop_free wolfSSL_sk_X509_CRL_pop_free +#define sk_X509_CRL_free wolfSSL_sk_X509_CRL_free +#define sk_X509_CRL_push wolfSSL_sk_X509_CRL_push +#define sk_X509_CRL_value wolfSSL_sk_X509_CRL_value +#define sk_X509_CRL_num wolfSSL_sk_X509_CRL_num + #define sk_X509_OBJECT_new wolfSSL_sk_X509_OBJECT_new #define sk_X509_OBJECT_free wolfSSL_sk_X509_OBJECT_free #define sk_X509_OBJECT_pop_free wolfSSL_sk_X509_OBJECT_pop_free @@ -1588,6 +1595,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define sk_SSL_COMP_free(...) #endif +#define OBJ_dup wolfSSL_ASN1_OBJECT_dup + #define SSL_set_psk_use_session_callback wolfSSL_set_psk_use_session_callback #define SSL_SESSION_is_resumable wolfSSL_SESSION_is_resumable typedef WOLFSSL_CONF_CTX SSL_CONF_CTX; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 6e53af58d..b7e264680 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1350,8 +1350,19 @@ typedef WOLF_STACK_OF(WOLFSSL_DIST_POINT) WOLFSSL_DIST_POINTS; WOLFSSL_API int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509); -WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk); -WOLFSSL_API void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk); +WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509)* sk); +WOLFSSL_API void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk); + +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void); +WOLFSSL_API void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk, + void (*f) (WOLFSSL_X509_CRL*)); +WOLFSSL_API void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk); +WOLFSSL_API int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk, + WOLFSSL_X509_CRL* crl); +WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value( + WOLF_STACK_OF(WOLFSSL_X509)* sk, int i); +WOLFSSL_API int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk); + WOLFSSL_API WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void); WOLFSSL_API void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* gn); WOLFSSL_API int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name,