diff --git a/CMakeLists.txt b/CMakeLists.txt index f8de21a0..c0e34a14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ set(CMAKE_MACOSX_RPATH TRUE) # micro version is changed with a set of small changes or bugfixes anywhere in the project. set(LIBNETCONF2_MAJOR_VERSION 4) set(LIBNETCONF2_MINOR_VERSION 4) -set(LIBNETCONF2_MICRO_VERSION 9) +set(LIBNETCONF2_MICRO_VERSION 10) set(LIBNETCONF2_VERSION ${LIBNETCONF2_MAJOR_VERSION}.${LIBNETCONF2_MINOR_VERSION}.${LIBNETCONF2_MICRO_VERSION}) # Version of the library @@ -67,7 +67,7 @@ set(LIBNETCONF2_VERSION ${LIBNETCONF2_MAJOR_VERSION}.${LIBNETCONF2_MINOR_VERSION # with backward compatible change and micro version is connected with any internal change of the library. set(LIBNETCONF2_MAJOR_SOVERSION 5) set(LIBNETCONF2_MINOR_SOVERSION 4) -set(LIBNETCONF2_MICRO_SOVERSION 8) +set(LIBNETCONF2_MICRO_SOVERSION 9) set(LIBNETCONF2_SOVERSION_FULL ${LIBNETCONF2_MAJOR_SOVERSION}.${LIBNETCONF2_MINOR_SOVERSION}.${LIBNETCONF2_MICRO_SOVERSION}) set(LIBNETCONF2_SOVERSION ${LIBNETCONF2_MAJOR_SOVERSION}) diff --git a/src/session.c b/src/session.c index ddb6dad9..de2b24f0 100644 --- a/src/session.c +++ b/src/session.c @@ -1919,6 +1919,53 @@ nc_session_curl_fetch(CURL *handle, const char *url) return 0; } +/** + * @brief Check if a URI has already been processed, add it to the seen list if not. + * + * @param[in] uri URI to check. + * @param[in,out] seen_uris Array of already seen URIs. + * @param[in,out] seen_count Number of seen URIs. + * @return 1 if already seen, 0 if added (not seen before), -1 on error. + */ +static int +nc_session_uri_seen(const char *uri, char ***seen_uris, int *seen_count) +{ + int i; + char **tmp; + + for (i = 0; i < *seen_count; i++) { + if (!strcmp((*seen_uris)[i], uri)) { + return 1; + } + } + + tmp = nc_realloc(*seen_uris, (*seen_count + 1) * sizeof **seen_uris); + NC_CHECK_ERRMEM_RET(!tmp, -1); + *seen_uris = tmp; + (*seen_uris)[*seen_count] = strdup(uri); + NC_CHECK_ERRMEM_RET(!(*seen_uris)[*seen_count], -1); + (*seen_count)++; + + return 0; +} + +/** + * @brief Free the seen URIs array. + * + * @param[in] seen_uris Array of seen URIs. + * @param[in] seen_count Number of seen URIs. + */ +static void +nc_session_seen_uris_free(char **seen_uris, int seen_count) +{ + int i; + + for (i = 0; i < seen_count; i++) { + free(seen_uris[i]); + } + free(seen_uris); +} + /** * @brief Initialize CURL handle for downloading CRL. * @@ -1939,6 +1986,18 @@ nc_session_curl_init(CURL **handle, struct nc_curl_data *data) return 1; } + /* limit connection phase to avoid long delays on unreachable CRL hosts */ + if (curl_easy_setopt(*handle, CURLOPT_CONNECTTIMEOUT_MS, NC_CURL_CONNECT_TIMEOUT_MS)) { + ERR(NULL, "Setting curl connection timeout failed."); + return 1; + } + + /* do not use signals for timeouts, required for thread safety */ + if (curl_easy_setopt(*handle, CURLOPT_NOSIGNAL, 1L)) { + ERR(NULL, "Setting CURLOPT_NOSIGNAL failed."); + return 1; + } + if (curl_easy_setopt(*handle, CURLOPT_WRITEFUNCTION, nc_session_curl_cb)) { ERR(NULL, "Setting curl callback failed."); return 1; @@ -1952,74 +2011,6 @@ nc_session_curl_init(CURL **handle, struct nc_curl_data *data) return 0; } -int -nc_session_tls_crl_from_cert_ext_fetch(void *leaf_cert, void *cert_store, void **crl_store) -{ - int ret = 0, uri_count = 0, i; - CURL *handle = NULL; - struct nc_curl_data downloaded = {0}; - char **uris = NULL; - void *crl_store_aux = NULL; - - *crl_store = NULL; - - crl_store_aux = nc_tls_crl_store_new_wrap(); - if (!crl_store_aux) { - goto cleanup; - } - - /* init curl */ - ret = nc_session_curl_init(&handle, &downloaded); - if (ret) { - goto cleanup; - } - - /* get all the uris we can, even though some may point to the same CRL */ - ret = nc_server_tls_get_crl_distpoint_uris_wrap(leaf_cert, cert_store, &uris, &uri_count); - if (ret) { - goto cleanup; - } - - if (!uri_count) { - /* no CRL distribution points, nothing to download */ - goto cleanup; - } - - for (i = 0; i < uri_count; i++) { - VRB(NULL, "Downloading CRL from \"%s\".", uris[i]); - ret = nc_session_curl_fetch(handle, uris[i]); - if (ret) { - /* failed to download the CRL from this entry, try the next entry */ - WRN(NULL, "Failed to fetch CRL from \"%s\".", uris[i]); - continue; - } - - /* convert the downloaded data to CRL and add it to the store */ - ret = nc_server_tls_add_crl_to_store_wrap(downloaded.data, downloaded.size, crl_store_aux); - - /* free the downloaded data */ - free(downloaded.data); - downloaded.data = NULL; - downloaded.size = 0; - - if (ret) { - goto cleanup; - } - } - - *crl_store = crl_store_aux; - crl_store_aux = NULL; - -cleanup: - for (i = 0; i < uri_count; i++) { - free(uris[i]); - } - free(uris); - curl_easy_cleanup(handle); - nc_tls_crl_store_destroy_wrap(crl_store_aux); - return ret; -} - /** * @brief Download CRLs for certificates in the peer's chain and merge them into crl_store. * @@ -2031,11 +2022,11 @@ nc_session_tls_crl_from_cert_ext_fetch(void *leaf_cert, void *cert_store, void * static int nc_session_tls_crl_fetch_for_peer_chain(void *peer_chain, void *cert_store, void *crl_store) { - int i, ret = 0, uri_count = 0, j; + int i, ret = 0, uri_count = 0, j, seen_count = 0, uri_seen; void *cert = NULL; CURL *handle = NULL; struct nc_curl_data downloaded = {0}; - char **uris = NULL; + char **uris = NULL, **seen_uris = NULL; /* init curl */ ret = nc_session_curl_init(&handle, &downloaded); @@ -2060,6 +2051,20 @@ nc_session_tls_crl_fetch_for_peer_chain(void *peer_chain, void *cert_store, void } for (j = 0; j < uri_count; j++) { + uri_seen = nc_session_uri_seen(uris[j], &seen_uris, &seen_count); + if (uri_seen == 1) { + /* already downloaded this URI, skip */ + continue; + } else if (uri_seen == -1) { + ret = 1; + for (j++; j < uri_count; j++) { + free(uris[j]); + } + free(uris); + uris = NULL; + goto cleanup; + } + VRB(NULL, "Downloading CRL from \"%s\".", uris[j]); ret = nc_session_curl_fetch(handle, uris[j]); if (ret) { @@ -2093,6 +2098,7 @@ nc_session_tls_crl_fetch_for_peer_chain(void *peer_chain, void *cert_store, void cleanup: curl_easy_cleanup(handle); free(downloaded.data); + nc_session_seen_uris_free(seen_uris, seen_count); if (uris) { for (i = 0; i < uri_count; i++) { free(uris[i]); @@ -2103,10 +2109,10 @@ nc_session_tls_crl_fetch_for_peer_chain(void *peer_chain, void *cert_store, void } int -nc_session_tls_crl_verify_post_handshake(void *tls_session, void *cert_store, void *crl_store) +nc_session_tls_crl_verify_post_handshake(void *tls_session, void *cert_store) { int ret = 0; - void *peer_chain = NULL; + void *peer_chain = NULL, *crl_store = NULL; peer_chain = nc_tls_get_peer_cert_chain_wrap(tls_session); if (!peer_chain) { @@ -2114,15 +2120,20 @@ nc_session_tls_crl_verify_post_handshake(void *tls_session, void *cert_store, vo return 0; } - if (!crl_store && !cert_store) { - /* no CRL store and no cert store, nothing to verify */ + if (!cert_store) { + /* no cert store, nothing to verify */ return 0; } + crl_store = nc_tls_crl_store_for_post_handshake_wrap(cert_store); + if (!crl_store) { + return 1; + } + /* download CRLs for peer certificates and add them to the CRL store */ ret = nc_session_tls_crl_fetch_for_peer_chain(peer_chain, cert_store, crl_store); if (ret) { - return ret; + goto cleanup; } /* verify the peer chain against the CRLs */ @@ -2131,6 +2142,8 @@ nc_session_tls_crl_verify_post_handshake(void *tls_session, void *cert_store, vo ERR(NULL, "Post-handshake CRL verification failed."); } +cleanup: + nc_tls_crl_store_post_handshake_free_wrap(crl_store); return ret; } diff --git a/src/session_client_tls.c b/src/session_client_tls.c index cdc3d9dd..9dd441b9 100644 --- a/src/session_client_tls.c +++ b/src/session_client_tls.c @@ -228,9 +228,9 @@ nc_client_tls_session_new(int sock, const char *host, struct nc_client_tls_opts { int ret = 0; struct timespec ts_timeout; - void *tls_session, *tls_cfg, *cli_cert, *cli_pkey, *cert_store, *crl_store; + void *tls_session, *tls_cfg, *cli_cert, *cli_pkey, *cert_store; - tls_session = tls_cfg = cli_cert = cli_pkey = cert_store = crl_store = NULL; + tls_session = tls_cfg = cli_cert = cli_pkey = cert_store = NULL; /* prepare TLS context from which a session will be created */ tls_cfg = nc_tls_config_new_wrap(NC_CLIENT); @@ -254,23 +254,18 @@ nc_client_tls_session_new(int sock, const char *host, struct nc_client_tls_opts goto fail; } - /* load CRLs from set certificates' extensions */ - if (nc_session_tls_crl_from_cert_ext_fetch(cli_cert, cert_store, &crl_store)) { - goto fail; - } - /* set client's verify mode flags */ if (nc_client_tls_set_verify_wrap(tls_cfg)) { goto fail; } /* init TLS context and store data which may be needed later in it */ - if (nc_tls_init_ctx_wrap(cli_cert, cli_pkey, cert_store, crl_store, NULL, tls_ctx)) { + if (nc_tls_init_ctx_wrap(cli_cert, cli_pkey, cert_store, NULL, tls_ctx)) { goto fail; } /* memory is managed by context now */ - cli_cert = cli_pkey = cert_store = crl_store = NULL; + cli_cert = cli_pkey = cert_store = NULL; /* setup config from ctx */ if (nc_tls_setup_config_from_ctx_wrap(tls_ctx, tls_cfg)) { @@ -308,8 +303,7 @@ nc_client_tls_session_new(int sock, const char *host, struct nc_client_tls_opts /* post-handshake CRL verification: download CRLs for peer certs and verify the full chain */ if (nc_session_tls_crl_verify_post_handshake(tls_session, - nc_tls_get_cert_store_wrap(tls_cfg, tls_ctx), - nc_tls_get_crl_store_wrap(tls_cfg, tls_ctx))) { + nc_tls_get_cert_store_wrap(tls_cfg, tls_ctx))) { ERR(NULL, "TLS connect failed (post-handshake CRL verification)."); goto fail; } @@ -326,7 +320,6 @@ nc_client_tls_session_new(int sock, const char *host, struct nc_client_tls_opts nc_tls_cert_destroy_wrap(cli_cert); nc_tls_privkey_destroy_wrap(cli_pkey); nc_tls_cert_store_destroy_wrap(cert_store); - nc_tls_crl_store_destroy_wrap(crl_store); nc_tls_config_destroy_wrap(tls_cfg); return NULL; } diff --git a/src/session_mbedtls.c b/src/session_mbedtls.c index f4c97a3a..81af476e 100644 --- a/src/session_mbedtls.c +++ b/src/session_mbedtls.c @@ -1200,6 +1200,12 @@ nc_tls_verify_cert_chain_crl_wrap(void *cert_chain, void *cert_store, void *crl_ return 0; } + /* skip verification if the CRL store is empty (no CRLs were downloaded) */ + if (((mbedtls_x509_crl *)crl_store)->raw.len == 0) { + DBG(NULL, "No CRLs in store, skipping CRL verification."); + return 0; + } + ret = mbedtls_x509_crt_verify((mbedtls_x509_crt *)peer_chain, (mbedtls_x509_crt *)trust_ca, (mbedtls_x509_crl *)ca_crl, NULL, &flags, NULL, NULL); @@ -1218,9 +1224,15 @@ nc_tls_get_cert_store_wrap(void *UNUSED(tls_cfg), struct nc_tls_ctx *tls_ctx) } void * -nc_tls_get_crl_store_wrap(void *UNUSED(tls_cfg), struct nc_tls_ctx *tls_ctx) +nc_tls_crl_store_for_post_handshake_wrap(void *UNUSED(cert_store)) +{ + return nc_tls_crl_store_new_wrap(); +} + +void +nc_tls_crl_store_post_handshake_free_wrap(void *crl_store) { - return tls_ctx->crl_store; + nc_tls_crl_store_destroy_wrap(crl_store); } void @@ -1230,7 +1242,6 @@ nc_tls_ctx_destroy_wrap(struct nc_tls_ctx *tls_ctx) nc_tls_cert_destroy_wrap(tls_ctx->cert); nc_tls_privkey_destroy_wrap(tls_ctx->pkey); nc_tls_cert_store_destroy_wrap(tls_ctx->cert_store); - nc_tls_crl_store_destroy_wrap(tls_ctx->crl_store); free(tls_ctx->sock); free(tls_ctx->cipher_suites); } @@ -1332,7 +1343,7 @@ nc_client_tls_set_hostname_wrap(void *tls_session, const char *hostname) int nc_tls_init_ctx_wrap(void *cert, void *pkey, void *cert_store, - void *crl_store, void *cipher_suites, struct nc_tls_ctx *tls_ctx) + void *cipher_suites, struct nc_tls_ctx *tls_ctx) { /* setup rng */ if (nc_tls_rng_new(&tls_ctx->ctr_drbg, &tls_ctx->entropy)) { @@ -1346,7 +1357,6 @@ nc_tls_init_ctx_wrap(void *cert, void *pkey, void *cert_store, tls_ctx->cert = cert; tls_ctx->pkey = pkey; tls_ctx->cert_store = cert_store; - tls_ctx->crl_store = crl_store; return 0; } @@ -1358,9 +1368,9 @@ nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, void *tls_cfg) /* set config's cert and key */ mbedtls_ssl_conf_own_cert(tls_cfg, tls_ctx->cert, tls_ctx->pkey); /* - * Do NOT pass crl_store to mbedtls_ssl_conf_ca_chain. CRL verification is done - * post-handshake so that CRLs for peer certificates (received during the handshake) - * can also be downloaded and checked. crl_store is kept in tls_ctx for later use. + * Do NOT pass a CRL store to mbedtls_ssl_conf_ca_chain. CRL verification + * is done post-handshake so that CRLs for peer certificates (received + * during the handshake) can also be downloaded and checked. */ mbedtls_ssl_conf_ca_chain(tls_cfg, tls_ctx->cert_store, NULL); diff --git a/src/session_openssl.c b/src/session_openssl.c index f269294d..b21ea994 100644 --- a/src/session_openssl.c +++ b/src/session_openssl.c @@ -856,10 +856,16 @@ nc_tls_get_cert_store_wrap(void *tls_cfg, struct nc_tls_ctx *UNUSED(tls_ctx)) } void * -nc_tls_get_crl_store_wrap(void *tls_cfg, struct nc_tls_ctx *UNUSED(tls_ctx)) +nc_tls_crl_store_for_post_handshake_wrap(void *cert_store) { /* OpenSSL stores CRLs in the same X509_STORE as CA certs */ - return SSL_CTX_get_cert_store(tls_cfg); + return cert_store; +} + +void +nc_tls_crl_store_post_handshake_free_wrap(void *UNUSED(crl_store)) +{ + /* no-op: the store is the cert_store owned by SSL_CTX */ } void @@ -950,46 +956,11 @@ nc_client_tls_set_hostname_wrap(void *tls_session, const char *hostname) int nc_tls_init_ctx_wrap(void *cert, void *pkey, void *cert_store, - void *crl_store, void *UNUSED(cipher_suites), struct nc_tls_ctx *tls_ctx) + void *UNUSED(cipher_suites), struct nc_tls_ctx *tls_ctx) { tls_ctx->cert = cert; tls_ctx->pkey = pkey; tls_ctx->cert_store = cert_store; - tls_ctx->crl_store = crl_store; - return 0; -} - -/** - * @brief Move CRLs from one store to another. - * - * @param[in] src Source store. - * @param[in] dst Destination store. - * @return 0 on success, 1 on error. - */ -static int -nc_tls_move_crls_to_store(const X509_STORE *src, X509_STORE *dst) -{ - int i, nobjs = 0; - - STACK_OF(X509_OBJECT) * objs; - X509_OBJECT *obj; - X509_CRL *crl; - - objs = X509_STORE_get0_objects(src); - nobjs = sk_X509_OBJECT_num(objs); - for (i = 0; i < nobjs; i++) { - obj = sk_X509_OBJECT_value(objs, i); - crl = X509_OBJECT_get0_X509_CRL(obj); - if (!crl) { - /* not a CRL */ - continue; - } - if (!X509_STORE_add_crl(dst, crl)) { - ERR(NULL, "Adding CRL to the store failed (%s).", ERR_reason_error_string(ERR_get_error())); - return 1; - } - } - return 0; } @@ -1006,27 +977,12 @@ nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, void *tls_cfg) return 1; } - if (tls_ctx->crl_store) { - /* move CRLs from crl_store to cert_store, because SSL_CTX can only have one store */ - if (nc_tls_move_crls_to_store(tls_ctx->crl_store, tls_ctx->cert_store)) { - return 1; - } - - /* - * Do NOT enable CRL checks here. CRL verification is done post-handshake - * so that CRLs for peer certificates (received during the handshake) can - * also be downloaded and checked. - */ - } - SSL_CTX_set_cert_store(tls_cfg, tls_ctx->cert_store); X509_free(tls_ctx->cert); tls_ctx->cert = NULL; EVP_PKEY_free(tls_ctx->pkey); tls_ctx->pkey = NULL; - X509_STORE_free(tls_ctx->crl_store); - tls_ctx->crl_store = NULL; return 0; } diff --git a/src/session_p.h b/src/session_p.h index 127391b7..d5482854 100644 --- a/src/session_p.h +++ b/src/session_p.h @@ -115,6 +115,13 @@ extern struct nc_server_opts server_opts; */ #define NC_CH_CONNECT_TIMEOUT 500 +/** + * @brief Timeout in msec for CURL connection phase when downloading CRLs. + * Limits the time spent on DNS resolution and TCP handshake per URI, + * preventing long delays on unreachable CRL distribution points. + */ +#define NC_CURL_CONNECT_TIMEOUT_MS 2000 + /** * @brief Timeout in msec for acquiring the hello_lock * (iterating through all YANG modules + building capability strings) @@ -1458,16 +1465,6 @@ int nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts void nc_client_tls_destroy_opts(void); void _nc_client_tls_destroy_opts(struct nc_client_tls_opts *opts); -/** - * @brief Fetch CRLs from the x509v3 CRLDistributionPoints extension. - * - * @param[in] leaf_cert Server/client certificate. - * @param[in] cert_store CA/EE certificates store. - * @param[out] crl_store Created CRL store. - * @return 0 on success, 1 on error. - */ -int nc_session_tls_crl_from_cert_ext_fetch(void *leaf_cert, void *cert_store, void **crl_store); - /** * @brief Perform post-handshake CRL verification for the peer's certificate chain. * @@ -1475,13 +1472,11 @@ int nc_session_tls_crl_from_cert_ext_fetch(void *leaf_cert, void *cert_store, vo * and verifies the entire peer chain against all collected CRLs. * * @param[in] tls_session Established TLS session. - * @param[in] cert_store Certificate store containing CAs and local CRLs - * (OpenSSL: used for verification, MbedTLS: for CRL DP URI extraction and verification). - * @param[in] crl_store CRL store with pre-downloaded CRLs - * (OpenSSL: unused as CRLs are in cert_store, MbedTLS: used for verification). + * @param[in] cert_store Certificate store containing CAs + * (OpenSSL: also used for CRL storage and verification, MbedTLS: for CRL DP URI extraction and verification). * @return 0 on success, non-zero on failure. */ -int nc_session_tls_crl_verify_post_handshake(void *tls_session, void *cert_store, void *crl_store); +int nc_session_tls_crl_verify_post_handshake(void *tls_session, void *cert_store); #endif /* NC_ENABLED_SSH_TLS */ diff --git a/src/session_server_tls.c b/src/session_server_tls.c index 3556a6f9..d3109f52 100644 --- a/src/session_server_tls.c +++ b/src/session_server_tls.c @@ -840,10 +840,10 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt struct timespec ts_timeout; struct nc_tls_verify_cb_data cb_data = {0}; struct nc_endpt *referenced_endpt; - void *tls_cfg, *srv_cert, *srv_pkey, *cert_store, *crl_store, *cipher_suites; + void *tls_cfg, *srv_cert, *srv_pkey, *cert_store, *cipher_suites; uint32_t cert_count = 0; - tls_cfg = srv_cert = srv_pkey = cert_store = crl_store = cipher_suites = NULL; + tls_cfg = srv_cert = srv_pkey = cert_store = cipher_suites = NULL; /* set verify cb data */ cb_data.session = session; @@ -898,11 +898,6 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt goto fail; } - if (nc_session_tls_crl_from_cert_ext_fetch(srv_cert, cert_store, &crl_store)) { - ERR(session, "Loading server CRL failed."); - goto fail; - } - /* set supported TLS versions */ if (nc_server_tls_set_tls_versions_wrap(tls_cfg, opts->min_version, opts->max_version)) { ERR(session, "Setting supported server TLS versions failed."); @@ -920,12 +915,12 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt nc_server_tls_set_verify_wrap(tls_cfg, &cb_data); /* init TLS context and store data which may be needed later in it */ - if (nc_tls_init_ctx_wrap(srv_cert, srv_pkey, cert_store, crl_store, cipher_suites, &session->ti.tls.ctx)) { + if (nc_tls_init_ctx_wrap(srv_cert, srv_pkey, cert_store, cipher_suites, &session->ti.tls.ctx)) { goto fail; } /* memory is managed by context now */ - srv_cert = srv_pkey = cert_store = crl_store = cipher_suites = NULL; + srv_cert = srv_pkey = cert_store = cipher_suites = NULL; /* setup config from ctx */ if (nc_tls_setup_config_from_ctx_wrap(&session->ti.tls.ctx, tls_cfg)) { @@ -968,8 +963,7 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt /* post-handshake CRL verification: download CRLs for peer certs and verify the full chain */ if (nc_session_tls_crl_verify_post_handshake(session->ti.tls.session, - nc_tls_get_cert_store_wrap(session->ti.tls.config, &session->ti.tls.ctx), - nc_tls_get_crl_store_wrap(session->ti.tls.config, &session->ti.tls.ctx))) { + nc_tls_get_cert_store_wrap(session->ti.tls.config, &session->ti.tls.ctx))) { ERR(session, "TLS accept failed (post-handshake CRL verification)."); goto fail; } @@ -985,7 +979,6 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt nc_tls_cert_destroy_wrap(srv_cert); nc_tls_privkey_destroy_wrap(srv_pkey); nc_tls_cert_store_destroy_wrap(cert_store); - nc_tls_crl_store_destroy_wrap(crl_store); free(cipher_suites); if (timeouted) { diff --git a/src/session_wrapper.h b/src/session_wrapper.h index d4cb4f4a..36713cd4 100644 --- a/src/session_wrapper.h +++ b/src/session_wrapper.h @@ -41,7 +41,6 @@ struct nc_tls_ctx { mbedtls_x509_crt *cert; /**< Certificate. */ mbedtls_pk_context *pkey; /**< Private key. */ mbedtls_x509_crt *cert_store; /**< CA certificates store. */ - mbedtls_x509_crl *crl_store; /**< CRL store. */ }; #else @@ -57,7 +56,6 @@ struct nc_tls_ctx { X509 *cert; /**< Certificate. */ EVP_PKEY *pkey; /**< Private key. */ X509_STORE *cert_store; /**< CA certificate store. */ - X509_STORE *crl_store; /**< CRL store. */ }; #endif @@ -454,13 +452,12 @@ int nc_client_tls_set_hostname_wrap(void *tls_session, const char *hostname); * @param[in] cert Certificate. * @param[in] pkey Private key. * @param[in] cert_store Certificate store. - * @param[in] crl_store CRL store. * @param[in] cipher_suites List of cipher suites. * @param[in,out] tls_ctx TLS context. * @return 0 on success, non-zero on fail. */ int nc_tls_init_ctx_wrap(void *cert, void *pkey, void *cert_store, - void *crl_store, void *cipher_suites, struct nc_tls_ctx *tls_ctx); + void *cipher_suites, struct nc_tls_ctx *tls_ctx); /** * @brief Setup a TLS configuration from a TLS context. @@ -811,16 +808,27 @@ int nc_tls_verify_cert_chain_crl_wrap(void *cert_chain, void *cert_store, void * void *nc_tls_get_cert_store_wrap(void *tls_cfg, struct nc_tls_ctx *tls_ctx); /** - * @brief Get the CRL store from a TLS context. + * @brief Get the CRL store for post-handshake CRL verification. * * For OpenSSL, returns the cert_store (X509_STORE), since CRLs are stored - * in the same X509_STORE as CA certs. - * For MbedTLS, returns the crl_store from the TLS context. + * in the same X509_STORE as CA certs. Must NOT be freed by the caller. * - * @param[in] tls_cfg TLS configuration (SSL_CTX for OpenSSL, unused for MbedTLS). - * @param[in] tls_ctx TLS context (unused for OpenSSL, used for MbedTLS). - * @return CRL store or NULL. + * For MbedTLS, creates and returns a new empty CRL store. Must be freed + * by calling nc_tls_crl_store_post_handshake_free_wrap after use. + * + * @param[in] cert_store Certificate store. + * @return CRL store or NULL on error. + */ +void *nc_tls_crl_store_for_post_handshake_wrap(void *cert_store); + +/** + * @brief Free the CRL store obtained from nc_tls_crl_store_for_post_handshake_wrap. + * + * For OpenSSL, no-op since the store is the cert_store owned by SSL_CTX. + * For MbedTLS, destroys the CRL store. + * + * @param[in] crl_store CRL store to free. */ -void *nc_tls_get_crl_store_wrap(void *tls_cfg, struct nc_tls_ctx *tls_ctx); +void nc_tls_crl_store_post_handshake_free_wrap(void *crl_store); #endif