diff --git a/src/internal.c b/src/internal.c index 79ec90351..7baad8c51 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1800,6 +1800,15 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifdef OPENSSL_EXTRA /* setup WOLFSSL_X509_STORE */ ctx->x509_store.cm = ctx->cm; + + /* WOLFSSL_X509_VERIFY_PARAM */ + if ((ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( + sizeof(WOLFSSL_X509_VERIFY_PARAM), + ctx->heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { + WOLFSSL_MSG("ctx->param memory error"); + return MEMORY_E; + } + XMEMSET(ctx->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); #endif #endif @@ -1948,6 +1957,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) XFREE((void *)ctx->alpn_cli_protos, NULL, DYNAMIC_TYPE_OPENSSL); ctx->alpn_cli_protos = NULL; } + if (ctx->param) { + XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL); + } #endif #ifdef WOLFSSL_STATIC_EPHEMERAL #ifndef NO_DH diff --git a/src/ssl.c b/src/ssl.c index c483d36b3..1b9d6835c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -26195,6 +26195,68 @@ int wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM *param, } +/* +* WOLFSSL_VPARAM_DEFAULT any values in "src" is copied +* if "src" value is new for "to". +* WOLFSSL_VPARAM_OVERWRITE all values of "form" are copied to "to" +* WOLFSSL_VPARAM_RESET_FLAGS the flag values are copied, not Ored +* WOLFSSL_VPARAM_LOCKED don't copy any values +* WOLFSSL_VPARAM_ONCE the current inherit_flags is zerroed +*/ +static int woflSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to, + const WOLFSSL_X509_VERIFY_PARAM *from) +{ + int ret = WOLFSSL_FAILURE; + int isOverWrite = 0; + int isDefault = 0; + unsigned int flags; + + /* sanity check */ + if (!to || !from) { + /* be compatible to openssl return value */ + return WOLFSSL_SUCCESS; + } + flags = to->inherit_flags | from->inherit_flags; + + if (flags & WOLFSSL_VPARAM_LOCKED) { + return WOLFSSL_SUCCESS; + } + + if (flags & WOLFSSL_VPARAM_ONCE) { + to->inherit_flags = 0; + } + + isOverWrite = (flags & WOLFSSL_VPARAM_OVERWRITE); + isDefault = (flags & WOLFSSL_VPARAM_DEFAULT); + + /* copy check_time if check time is not set */ + if ((to->flags & WOLFSSL_USE_CHECK_TIME) == 0 || isOverWrite) { + to->check_time = from->check_time; + to->flags &= ~WOLFSSL_USE_CHECK_TIME; + } + /* host name */ + if (isOverWrite || + (from->hostName[0] != 0 && (to->hostName[0] == 0 || isDefault))) { + if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_host(to, from->hostName, + XSTRLEN(from->hostName)))) + return ret; + to->hostFlags = from->hostFlags; + } + /* ip ascii */ + if (isOverWrite || + (from->ipasc[0] != 0 && (to->ipasc[0] == 0 || isDefault))) { + + if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(to, from->ipasc))) + return ret; + } + + if (flags & WOLFSSL_VPARAM_RESET_FLAGS) + to->flags = 0; + + to->flags |= from->flags; + + return ret; +} /****************************************************************************** * wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name * hostnames is cleared if name is NULL or empty. @@ -26236,12 +26298,32 @@ int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam, return WOLFSSL_SUCCESS; } /****************************************************************************** -* wolfSSL_get0_param - return a pointer to the SSL verification parameters +* wolfSSL_CTX_set1_param - set a pointer to the SSL verification parameters +* +* RETURNS: +* WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE +*/ +int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm) +{ + return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, vpm); +} + +/****************************************************************************** +* wolfSSL_CTX/_get0_param - return a pointer to the SSL verification parameters * * RETURNS: * returns pointer to the SSL verification parameters on success, * otherwise returns NULL */ +WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return ctx->param; +} + WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl) { if (ssl == NULL) { @@ -26250,6 +26332,32 @@ WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl) return ssl->param; } +/* Set VERIFY PARAM from "from" pointer to "to" pointer */ +int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM *to, + const WOLFSSL_X509_VERIFY_PARAM *from) +{ + int ret = WOLFSSL_FAILURE; + unsigned int _inherit_flags; + + if (!to) { + return ret; + } + /* keeps the inherit flags for save */ + _inherit_flags = to->inherit_flags; + + /* Ored DEFAULT inherit flag proerty to copy "from" contents to "to" + * contends + */ + to->inherit_flags |= WOLFSSL_VPARAM_DEFAULT; + + ret = woflSSL_X509_VERIFY_PARAM_inherit(to, from); + + /* restore inherit flag */ + to->inherit_flags = _inherit_flags; + + return ret; +} + /* Set the host flag in the X509_VERIFY_PARAM structure */ void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param, unsigned int flags) diff --git a/tests/api.c b/tests/api.c index 63e329fb0..759523728 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28045,6 +28045,50 @@ static void test_wolfSSL_X509_STORE_CTX_set_time(void) #endif /* OPENSSL_EXTRA */ } +static void test_wolfSSL_CTX_get0_set1_param(void) +{ +#if defined(OPENSSL_EXTRA) + int ret; + SSL_CTX* ctx; + WOLFSSL_X509_VERIFY_PARAM* pParam; + WOLFSSL_X509_VERIFY_PARAM* pvpm; + char testIPv4[] = "127.0.0.1"; + char testhostName[] = "foo.hoge.com"; + + printf(testingFmt, "wolfSSL_CTX_get0_set1_param()"); + + #ifndef NO_WOLFSSL_SERVER + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + #else + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method())); + #endif + + AssertNotNull(pParam = SSL_CTX_get0_param(ctx)); + + pvpm = (WOLFSSL_X509_VERIFY_PARAM *)XMALLOC( + sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL); + AssertNotNull(pvpm); + + wolfSSL_X509_VERIFY_PARAM_set1_host(pvpm, testhostName, + XSTRLEN(testhostName)); + wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(pvpm, testIPv4); + wolfSSL_X509_VERIFY_PARAM_set_hostflags(pvpm, 0x01); + + ret = SSL_CTX_set1_param(ctx, pvpm); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(pParam->hostName, testhostName, + XSTRLEN(testhostName))); + AssertIntEQ(0x01, pParam->hostFlags); + AssertIntEQ(0, XSTRNCMP(pParam->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); + + SSL_CTX_free(ctx); + + XFREE(pvpm, NULL, DYNAMIC_TYPE_OPENSSL); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA && !defined(NO_RSA)*/ +} + static void test_wolfSSL_get0_param(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) @@ -29903,50 +29947,128 @@ static void test_wolfSSL_X509_ALGOR_get0(void) static void test_wolfSSL_X509_VERIFY_PARAM(void) { #if defined(OPENSSL_EXTRA) - WOLFSSL_X509_VERIFY_PARAM *param; + WOLFSSL_X509_VERIFY_PARAM *paramTo; + WOLFSSL_X509_VERIFY_PARAM *paramFrom; int ret; char testIPv4[] = "127.0.0.1"; char testIPv6[] = "0001:0000:0000:0000:0000:0000:0000:0000/32"; - + char testhostName1[] = "foo.hoge.com"; + char testhostName2[] = "foobar.hoge.com"; + printf(testingFmt, "wolfSSL_X509()"); - param = wolfSSL_X509_VERIFY_PARAM_new(); - AssertNotNull(param); + paramTo = wolfSSL_X509_VERIFY_PARAM_new(); + AssertNotNull(paramTo); + XMEMSET(paramTo, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM )); - XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM )); + paramFrom = wolfSSL_X509_VERIFY_PARAM_new(); + AssertNotNull(paramFrom); + XMEMSET(paramFrom, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM )); + ret = wolfSSL_X509_VERIFY_PARAM_set1_host(paramFrom, testhostName1, + XSTRLEN(testhostName1)); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(paramFrom->hostName, testhostName1, + XSTRLEN(testhostName1))); + wolfSSL_X509_VERIFY_PARAM_set_hostflags(NULL, 0x00); - wolfSSL_X509_VERIFY_PARAM_set_hostflags(param, 0x01); - AssertIntEQ(0x01, param->hostFlags); + wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramFrom, 0x01); + AssertIntEQ(0x01, paramFrom->hostFlags); ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(NULL, testIPv4); AssertIntEQ(0, ret); - ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, testIPv4); + ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramFrom, testIPv4); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(param->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); + AssertIntEQ(0, XSTRNCMP(paramFrom->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); - ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, NULL); + ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramFrom, NULL); AssertIntEQ(1, ret); - ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, testIPv6); + ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramFrom, testIPv6); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(param->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); + AssertIntEQ(0, XSTRNCMP(paramFrom->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); - ret = wolfSSL_X509_VERIFY_PARAM_set_flags(param, WOLFSSL_CRL_CHECKALL); + /* null pointer */ + ret = wolfSSL_X509_VERIFY_PARAM_set1(NULL, paramFrom); + AssertIntEQ(WOLFSSL_FAILURE, ret); + /* in the case of "from" null, returns success */ + ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, NULL); + AssertIntEQ(WOLFSSL_SUCCESS, ret); + + ret = wolfSSL_X509_VERIFY_PARAM_set1(NULL, NULL); + AssertIntEQ(WOLFSSL_FAILURE, ret); + + /* inherit flags test : VPARAM_DEFAULT */ + ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, + XSTRLEN(testhostName1))); + AssertIntEQ(0x01, paramTo->hostFlags); + AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); + + /* inherit flags test : VPARAM OVERWRITE */ + wolfSSL_X509_VERIFY_PARAM_set1_host(paramTo, testhostName2, + XSTRLEN(testhostName2)); + wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4); + wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramTo, 0x00); + + paramTo->inherit_flags = WOLFSSL_VPARAM_OVERWRITE; + + ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, + XSTRLEN(testhostName1))); + AssertIntEQ(0x01, paramTo->hostFlags); + AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); + + /* inherit flags test : VPARAM_RESET_FLAGS */ + wolfSSL_X509_VERIFY_PARAM_set1_host(paramTo, testhostName2, + XSTRLEN(testhostName2)); + wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4); + wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramTo, 0x10); + + paramTo->inherit_flags = WOLFSSL_VPARAM_RESET_FLAGS; + + ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, + XSTRLEN(testhostName1))); + AssertIntEQ(0x01, paramTo->hostFlags); + AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); + + /* inherit flags test : VPARAM_LOCKED */ + wolfSSL_X509_VERIFY_PARAM_set1_host(paramTo, testhostName2, + XSTRLEN(testhostName2)); + wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4); + wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramTo, 0x00); + + paramTo->inherit_flags = WOLFSSL_VPARAM_LOCKED; + + ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName2, + XSTRLEN(testhostName2))); + AssertIntEQ(0x00, paramTo->hostFlags); + AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); + + /* inherit flags test : VPARAM_ONCE, not testable yet */ + + ret = wolfSSL_X509_VERIFY_PARAM_set_flags(paramTo, WOLFSSL_CRL_CHECKALL); AssertIntEQ(1, ret); - ret = wolfSSL_X509_VERIFY_PARAM_get_flags(param); + ret = wolfSSL_X509_VERIFY_PARAM_get_flags(paramTo); AssertIntEQ(WOLFSSL_CRL_CHECKALL, ret); - ret = wolfSSL_X509_VERIFY_PARAM_clear_flags(param, WOLFSSL_CRL_CHECKALL); + ret = wolfSSL_X509_VERIFY_PARAM_clear_flags(paramTo, WOLFSSL_CRL_CHECKALL); AssertIntEQ(1, ret); - ret = wolfSSL_X509_VERIFY_PARAM_get_flags(param); + ret = wolfSSL_X509_VERIFY_PARAM_get_flags(paramTo); AssertIntEQ(0, ret); - wolfSSL_X509_VERIFY_PARAM_free(param); + wolfSSL_X509_VERIFY_PARAM_free(paramTo); + wolfSSL_X509_VERIFY_PARAM_free(paramFrom); printf(resultFmt, passed); @@ -40637,6 +40759,7 @@ void ApiTest(void) test_wolfSSL_X509_STORE(); test_wolfSSL_X509_STORE_load_locations(); test_wolfSSL_BN(); + test_wolfSSL_CTX_get0_set1_param(); #ifndef NO_BIO test_wolfSSL_PEM_read_bio(); test_wolfSSL_BIO(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index aebfb3a69..8a124dd01 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2837,6 +2837,7 @@ struct WOLFSSL_CTX { byte sessionCtxSz; byte cbioFlag; /* WOLFSSL_CBIO_RECV/SEND: CBIORecv/Send is set */ CallbackInfoState* CBIS; /* used to get info about SSL state */ + WOLFSSL_X509_VERIFY_PARAM* param; /* verification parameters*/ #endif CallbackIORecv CBIORecv; CallbackIOSend CBIOSend; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 8b7604ea3..1fd838bce 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -558,6 +558,12 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define X509_V_FLAG_NO_CHECK_TIME WOLFSSL_NO_CHECK_TIME #define X509_CHECK_FLAG_NO_WILDCARDS WOLFSSL_NO_WILDCARDS +#define X509_VP_FLAG_DEFAULT WOLFSSL_VPARAM_DEFAULT +#define X509_VP_FLAG_OVERWRITE WOLFSSL_VPARAM_OVERWRITE +#define X509_VP_FLAG_RESET_FLAGS WOLFSSL_VPARAM_RESET_FLAGS +#define X509_VP_FLAG_LOCKED WOLFSSL_VPARAM_LOCKED +#define X509_VP_FLAG_ONCE WOLFSSL_VPARAM_ONCE + #define X509_STORE_CTX_get_current_cert wolfSSL_X509_STORE_CTX_get_current_cert #define X509_STORE_CTX_set_verify_cb wolfSSL_X509_STORE_CTX_set_verify_cb #define X509_STORE_CTX_new wolfSSL_X509_STORE_CTX_new @@ -605,6 +611,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_VERIFY_PARAM_set_hostflags wolfSSL_X509_VERIFY_PARAM_set_hostflags #define X509_VERIFY_PARAM_set1_host wolfSSL_X509_VERIFY_PARAM_set1_host #define X509_VERIFY_PARAM_set1_ip_asc wolfSSL_X509_VERIFY_PARAM_set1_ip_asc +#define X509_VERIFY_PARAM_set1 wolfSSL_X509_VERIFY_PARAM_set1 #define X509_STORE_load_locations wolfSSL_X509_STORE_load_locations #define X509_LOOKUP_add_dir wolfSSL_X509_LOOKUP_add_dir @@ -1312,6 +1319,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_set_srp_strength wolfSSL_CTX_set_srp_strength #define SSL_get_SSL_CTX wolfSSL_get_SSL_CTX #define SSL_get0_param wolfSSL_get0_param +#define SSL_CTX_get0_param wolfSSL_CTX_get0_param +#define SSL_CTX_set1_param wolfSSL_CTX_set1_param #define SSL_get_srp_username wolfSSL_get_srp_username #define ERR_NUM_ERRORS 16 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c3372b3f0..69103607e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -563,8 +563,16 @@ struct WOLFSSL_X509_STORE { #define WOLFSSL_USE_CHECK_TIME 0x2 #define WOLFSSL_NO_CHECK_TIME 0x200000 #define WOLFSSL_HOST_NAME_MAX 256 + +#define WOLFSSL_VPARAM_DEFAULT 0x1 +#define WOLFSSL_VPARAM_OVERWRITE 0x2 +#define WOLFSSL_VPARAM_RESET_FLAGS 0x4 +#define WOLFSSL_VPARAM_LOCKED 0x8 +#define WOLFSSL_VPARAM_ONCE 0x10 + struct WOLFSSL_X509_VERIFY_PARAM { time_t check_time; + unsigned int inherit_flags; unsigned long flags; char hostName[WOLFSSL_HOST_NAME_MAX]; unsigned int hostFlags; @@ -877,7 +885,9 @@ WOLFSSL_API int wolfSSL_CTX_up_ref(WOLFSSL_CTX*); #endif WOLFSSL_ABI WOLFSSL_API WOLFSSL* wolfSSL_new(WOLFSSL_CTX*); WOLFSSL_API WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl); +WOLFSSL_API WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx); WOLFSSL_API WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm); WOLFSSL_API int wolfSSL_is_server(WOLFSSL*); WOLFSSL_API WOLFSSL* wolfSSL_write_dup(WOLFSSL*); WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_fd (WOLFSSL*, int); @@ -1544,6 +1554,8 @@ WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* p unsigned int nameSz); WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc( WOLFSSL_X509_VERIFY_PARAM *param, const char *ipasc); +WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM* to, + const WOLFSSL_X509_VERIFY_PARAM* from); #endif WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL*); WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(