From 5999427a728f5f87ccd3e7957a1e347a1ac6ace3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Sch=C3=A4rtl?= Date: Mon, 29 Jan 2024 11:34:34 +0100 Subject: [PATCH 1/2] Use new OpenSSL FIPS API --- example/client-brski/estclient-brski.c | 3 ++- example/client/estclient.c | 3 ++- example/proxy/estproxy.c | 3 ++- example/server/estserver.c | 3 ++- java/jni/client.c | 3 ++- src/est/est_client.c | 13 +++++++------ src/est/est_server.c | 3 ++- test/UT/US1864/us1864.c | 5 +++-- 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/example/client-brski/estclient-brski.c b/example/client-brski/estclient-brski.c index 9e63af5..b7bb606 100644 --- a/example/client-brski/estclient-brski.c +++ b/example/client-brski/estclient-brski.c @@ -17,6 +17,7 @@ #include #include #include +#include #ifndef WIN32 #include #endif @@ -388,7 +389,7 @@ int main (int argc, char **argv) break; case 'f': /* Turn FIPS on if requested and exit if failure */ - set_fips_return = FIPS_mode_set(1); + set_fips_return = EVP_default_properties_enable_fips(NULL, 1); if (!set_fips_return) { printf("\nERROR setting FIPS MODE ON ...\n"); ERR_load_crypto_strings(); diff --git a/example/client/estclient.c b/example/client/estclient.c index a8a2d6f..44d5082 100644 --- a/example/client/estclient.c +++ b/example/client/estclient.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #ifndef WIN32 @@ -1280,7 +1281,7 @@ int main (int argc, char **argv) break; case 'f': /* Turn FIPS on if requested and exit if failure */ - set_fips_return = FIPS_mode_set(1); + set_fips_return = EVP_default_properties_enable_fips(NULL, 1); if (!set_fips_return) { printf("\nERROR setting FIPS MODE ON ...\n"); ERR_load_crypto_strings(); diff --git a/example/proxy/estproxy.c b/example/proxy/estproxy.c index 114bd65..03015e5 100644 --- a/example/proxy/estproxy.c +++ b/example/proxy/estproxy.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #ifndef WIN32 @@ -593,7 +594,7 @@ int main (int argc, char **argv) /* * Turn FIPS on if user requested it and exit if failure */ - set_fips_return = FIPS_mode_set(1); + set_fips_return = EVP_default_properties_enable_fips(NULL, 1); if (set_fips_return != 1) { set_fips_error = ERR_get_error(); printf("\nERROR WHILE SETTING FIPS MODE ON exiting ....\n"); diff --git a/example/server/estserver.c b/example/server/estserver.c index 3539dc4..635f420 100644 --- a/example/server/estserver.c +++ b/example/server/estserver.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -2285,7 +2286,7 @@ int main (int argc, char **argv) /* turn FIPS on if user requested it * and exit if failure. */ - set_fips_return = FIPS_mode_set(1); + set_fips_return = EVP_default_properties_enable_fips(NULL, 1); if (set_fips_return != 1) { set_fips_error = ERR_get_error(); printf("\nERROR WHILE SETTING FIPS MODE ON exiting ....\n"); diff --git a/java/jni/client.c b/java/jni/client.c index c5bc28e..d213776 100644 --- a/java/jni/client.c +++ b/java/jni/client.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "safe_mem_lib.h" #define EST_CLASS_ENROLL_EXCEPTION "com/cisco/c3m/est/EnrollException" @@ -179,7 +180,7 @@ static int jni_est_client_X509_REQ_sign (X509_REQ *x, EVP_PKEY *pkey, const EVP_ */ JNIEXPORT jint JNICALL Java_com_cisco_c3m_est_ESTClient_enable_1fips( JNIEnv *env, jclass obj) { - if (!FIPS_mode() && !FIPS_mode_set(1)) { + if (!EVP_default_properties_is_fips_enabled(NULL) && !EVP_default_properties_enable_fips(NULL, 1)) { ERR_print_errors_fp(stderr); return -1; } else { diff --git a/src/est/est_client.c b/src/est/est_client.c index 8dff9d9..282eab8 100644 --- a/src/est/est_client.c +++ b/src/est/est_client.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "est.h" #include "est_locl.h" #include "est_ossl_util.h" @@ -3182,7 +3183,7 @@ EST_ERROR est_client_enroll_internal (EST_CTX *ctx, char *cn, int *pkcs7_len, in * HTTPS digest mode requires the use of MD5. Make sure we're not * in FIPS mode and can use MD5 */ - if (ctx->auth_mode == AUTH_DIGEST && (FIPS_mode())){ + if (ctx->auth_mode == AUTH_DIGEST && (EVP_default_properties_is_fips_enabled(NULL))){ EST_LOG_ERR("HTTP digest auth not allowed while in FIPS mode"); rv = EST_ERR_BAD_MODE; goto err; @@ -3593,7 +3594,7 @@ EST_ERROR est_client_reenroll (EST_CTX *ctx, X509 *cert, int *pkcs7_len, EVP_PKE * HTTPS digest mode requires the use of MD5. Make sure we're not * in FIPS mode and can use MD5 */ - if (ctx->auth_mode == AUTH_DIGEST && (FIPS_mode())){ + if (ctx->auth_mode == AUTH_DIGEST && (EVP_default_properties_is_fips_enabled(NULL))){ EST_LOG_ERR("HTTP digest auth not allowed while in FIPS mode"); rv = EST_ERR_BAD_MODE; goto err; @@ -3679,7 +3680,7 @@ static EST_ERROR est_client_enroll_csr_internal (EST_CTX *ctx, X509_REQ *csr, in * HTTPS digest mode requires the use of MD5. Make sure we're not * in FIPS mode and can use MD5 */ - if (ctx->auth_mode == AUTH_DIGEST && (FIPS_mode())){ + if (ctx->auth_mode == AUTH_DIGEST && (EVP_default_properties_is_fips_enabled(NULL))){ EST_LOG_ERR("HTTP digest auth not allowed while in FIPS mode"); rv = EST_ERR_BAD_MODE; goto err; @@ -5871,7 +5872,7 @@ static EST_ERROR est_client_brski_send_get_voucher (EST_CTX *ctx, int *cacert_le * HTTPS digest mode requires the use of MD5. Make sure we're not * in FIPS mode and can use MD5 */ - if (ctx->auth_mode == AUTH_DIGEST && (FIPS_mode())){ + if (ctx->auth_mode == AUTH_DIGEST && (EVP_default_properties_is_fips_enabled(NULL))){ EST_LOG_ERR("HTTP digest auth not allowed while in FIPS mode"); rv = EST_ERR_BAD_MODE; goto err; @@ -6365,7 +6366,7 @@ EST_ERROR est_client_brski_send_voucher_status (EST_CTX *ctx, EST_BRSKI_STATUS_V * HTTPS digest mode requires the use of MD5. Make sure we're not * in FIPS mode and can use MD5 */ - if (ctx->auth_mode == AUTH_DIGEST && (FIPS_mode())){ + if (ctx->auth_mode == AUTH_DIGEST && (EVP_default_properties_is_fips_enabled(NULL))){ EST_LOG_ERR("HTTP digest auth not allowed while in FIPS mode"); rv = EST_ERR_BAD_MODE; goto err; @@ -6534,7 +6535,7 @@ EST_ERROR est_client_brski_send_enroll_status (EST_CTX *ctx, EST_BRSKI_STATUS_VA * HTTPS digest mode requires the use of MD5. Make sure we're not * in FIPS mode and can use MD5 */ - if (ctx->auth_mode == AUTH_DIGEST && (FIPS_mode())){ + if (ctx->auth_mode == AUTH_DIGEST && (EVP_default_properties_is_fips_enabled(NULL))){ EST_LOG_ERR("HTTP digest auth not allowed while in FIPS mode"); rv = EST_ERR_BAD_MODE; goto err; diff --git a/src/est/est_server.c b/src/est/est_server.c index d047b48..751a0f1 100644 --- a/src/est/est_server.c +++ b/src/est/est_server.c @@ -30,6 +30,7 @@ #include #include #include +#include static ASN1_OBJECT *o_cmcRA = NULL; @@ -3355,7 +3356,7 @@ EST_ERROR est_server_set_auth_mode (EST_CTX *ctx, EST_HTTP_AUTH_MODE amode) /* * Since HTTP digest auth uses MD5, make sure we're not in FIPS mode. */ - if (FIPS_mode()) { + if (EVP_default_properties_is_fips_enabled(NULL)) { EST_LOG_ERR("HTTP digest auth not allowed while in FIPS mode"); return (EST_ERR_BAD_MODE); } diff --git a/test/UT/US1864/us1864.c b/test/UT/US1864/us1864.c index 3e41cd7..8d89ab2 100644 --- a/test/UT/US1864/us1864.c +++ b/test/UT/US1864/us1864.c @@ -17,6 +17,7 @@ #include "test_utils.h" #include "st_server.h" #include +#include #ifdef HAVE_CUNIT #include "CUnit/Basic.h" @@ -218,12 +219,12 @@ static void us1864_test1 (void) /* * Make sure we don't allow DIGEST mode when in FIPS mode */ - if (!FIPS_mode_set(1)) { + if (!EVP_default_properties_enable_fips(NULL, 1)) { printf("FIPS mode not supported, skipping test to prevent digest auth when in FIPS mode"); } else { est_rv = est_server_set_auth_mode(ctx, AUTH_DIGEST); CU_ASSERT(est_rv == EST_ERR_BAD_MODE); - FIPS_mode_set(0); + EVP_default_properties_enable_fips(NULL, 0) } X509_free(x); From ca0a0505c69807c906d864b26db53e307158ece5 Mon Sep 17 00:00:00 2001 From: Steffen Klemer Date: Sat, 12 Sep 2026 12:14:43 +0200 Subject: [PATCH 2/2] Add possibility for the https-server part to serve a certificate chain. --- example/server/README | 15 +++++++ example/server/estserver.c | 26 +++++++++++- src/est/est.c | 4 ++ src/est/est.h | 3 +- src/est/est_locl.h | 3 +- src/est/est_server.c | 85 ++++++++++++++++++++++++++++++++++++++ src/est/est_server_http.c | 18 +++----- test/UT/US1190/us1190.c | 66 ++++++++++++++++++++++++++--- test/util/st_server.c | 24 +++++++++++ test/util/st_server.h | 4 +- 10 files changed, 225 insertions(+), 23 deletions(-) diff --git a/example/server/README b/example/server/README index 3715628..e83e439 100644 --- a/example/server/README +++ b/example/server/README @@ -32,6 +32,21 @@ To run the example: 4. Use an EST client to exercise the server. +TLS server certificate chain +---------------------------- +The -c option supplies the TLS server certificate and -k supplies its private +key. To send intermediate CA certificates during the HTTPS handshake, use +-C or --tls-chain . The chain file must be PEM encoded and +contain the issuer of the server certificate first, followed by any higher +intermediate CAs. Do not include the server certificate or, normally, the +self-signed root CA in this file. + +For example: + + ./estserver -c server.crt -k server.key -C intermediates.pem \ + -r estrealm -v + + Certificate Revocation ---------------------- diff --git a/example/server/estserver.c b/example/server/estserver.c index 635f420..d6cdf8a 100644 --- a/example/server/estserver.c +++ b/example/server/estserver.c @@ -121,6 +121,7 @@ static int perf_timers_on = 0; char certfile[EST_MAX_FILE_LEN]; char keyfile[EST_MAX_FILE_LEN]; +char tls_chain_file[EST_MAX_FILE_LEN + 1]; char cert_auth_ah_pwd[MAX_PWD_LEN + 1]; char local_nid[MAX_PWD_LEN + 1]; char mfg_name[MFG_NAME_MAX_LEN + 1]; @@ -228,6 +229,7 @@ static void show_usage_and_exit (void) " -v Verbose operation\n" " -c PEM file to use for server cert\n" " -k PEM file to use for server key\n" + " -C PEM file of intermediate certs to send in the TLS chain\n" " -r HTTP realm to present to clients. Max is 32 characters.\n" " -l Enable CRL checks\n" " -t Enable check for binding client PoP to the TLS UID\n" @@ -246,6 +248,7 @@ static void show_usage_and_exit (void) " -? Print this help message and exit\n" " --keypass_stdin Specify en-/decryption of private key, password read from STDIN\n" " --keypass_arg Specify en-/decryption of private key, password read from argument\n" + " --tls-chain PEM file of intermediate certs to send in the TLS chain\n" " --srp Enable TLS-SRP authentication of client using the specified SRP parameters file\n" " --enforce-csr Enable CSR attributes enforcement. The client must provide all the attributes in the CSR.\n" " --token Use HTTP Bearer Token auth.\n" @@ -2082,6 +2085,7 @@ int main (int argc, char **argv) #endif static struct option long_options[] = { {"srp", 1, NULL, 0}, + {"tls-chain", 1, NULL, 'C'}, {"enforce-csr", 0, NULL, 0}, {"token", 1, 0, 0}, #if ENABLE_BRSKI @@ -2123,7 +2127,7 @@ int main (int argc, char **argv) memset(masa_root_ca_file, 0, EST_MAX_FILE_LEN+1); memset(masa_priv_key_file, 0, EST_MAX_FILE_LEN+1); #endif - while ((c = getopt_long(argc, argv, "?fhbwnovr:c:k:m:p:d:lt6", long_options, + while ((c = getopt_long(argc, argv, "?fhbwnovr:c:k:C:m:p:d:lt6", long_options, &option_index)) != -1) { switch (c) { case 0: @@ -2274,6 +2278,9 @@ int main (int argc, char **argv) case 'k': strncpy(keyfile, optarg, EST_MAX_FILE_LEN); break; + case 'C': + strncpy(tls_chain_file, optarg, EST_MAX_FILE_LEN); + break; case 'r': if (strnlen(optarg, MAX_REALM_LEN+1) > MAX_REALM_LEN) { printf("\nRealm value is too large. Max is 32 characters\n"); @@ -2393,6 +2400,22 @@ int main (int argc, char **argv) printf("\nUnable to initialize EST context. Aborting!!!\n"); exit(1); } + if (tls_chain_file[0]) { + unsigned char *tls_chain = NULL; + int tls_chain_len = read_binary_file(tls_chain_file, &tls_chain); + + if (tls_chain_len <= 0) { + printf("\nTLS identity chain file could not be read: %s\n", + tls_chain_file); + exit(1); + } + rv = est_server_set_tls_identity_chain(ectx, tls_chain, tls_chain_len); + free(tls_chain); + if (rv != EST_ERR_NONE) { + printf("\nUnable to configure TLS identity chain (rv=%d)\n", rv); + exit(1); + } + } est_set_ex_data(ectx, &test_app_data); if (enforce_csr) { @@ -2761,4 +2784,3 @@ int main (int argc, char **argv) X509_free(x); return 0; } - diff --git a/src/est/est.c b/src/est/est.c index 8a65f87..9f9636d 100644 --- a/src/est/est.c +++ b/src/est/est.c @@ -775,6 +775,10 @@ EST_ERROR est_destroy (EST_CTX *ctx) free(ctx->ca_chain_raw); } + if (ctx->server_cert_chain) { + sk_X509_pop_free(ctx->server_cert_chain, X509_free); + } + if (ctx->uri_path_segment) { free(ctx->uri_path_segment); } diff --git a/src/est/est.h b/src/est/est.h index ffbe85f..4c72fe7 100644 --- a/src/est/est.h +++ b/src/est/est.h @@ -598,6 +598,8 @@ LIBEST_API EST_CTX * est_proxy_init(unsigned char *ca_chain, int ca_chain_len, char *uid, char *pwd); LIBEST_API EST_ERROR est_destroy(EST_CTX *ctx); LIBEST_API EST_ERROR est_server_set_auth_mode(EST_CTX *ctx, EST_HTTP_AUTH_MODE amode); +LIBEST_API EST_ERROR est_server_set_tls_identity_chain( + EST_CTX *ctx, const unsigned char *chain, int chain_len); LIBEST_API EST_ERROR est_server_enable_enhanced_cert_auth( EST_CTX *ctx, int local_pki_subj_field_nid, const char *ah_pwd, EST_ECA_CSR_CHECK_FLAG csr_check_enabled); @@ -867,4 +869,3 @@ LIBEST_API EST_ERROR est_disable_performance_timers(EST_CTX *ctx); #endif #endif - diff --git a/src/est/est_locl.h b/src/est/est_locl.h index b16f62d..b71669c 100644 --- a/src/est/est_locl.h +++ b/src/est/est_locl.h @@ -58,7 +58,7 @@ typedef struct est_timer { * Version identifiers. These should be updated appropriately * for each release. */ -#define EST_API_LEVEL 4 //Update this whenever there's a change to the public API +#define EST_API_LEVEL 5 //Update this whenever there's a change to the public API #define EST_VER_STRING PACKAGE_STRING #define EST_URI_PATH_PREFIX_MAX_LEN (16) @@ -529,6 +529,7 @@ struct est_ctx { EST_MG_CONTEXT *mg_ctx; int server_read_timeout; X509 *server_cert; + STACK_OF(X509) *server_cert_chain; EVP_PKEY *server_priv_key; int server_enable_pop; /* enable proof-of-possession check */ int client_force_pop; /* force proof-of-possession gen at the client */ diff --git a/src/est/est_server.c b/src/est/est_server.c index 751a0f1..819877c 100644 --- a/src/est/est_server.c +++ b/src/est/est_server.c @@ -31,6 +31,8 @@ #include #include #include +#include + static ASN1_OBJECT *o_cmcRA = NULL; @@ -3373,6 +3375,89 @@ EST_ERROR est_server_set_auth_mode (EST_CTX *ctx, EST_HTTP_AUTH_MODE amode) } } +/*! @brief est_server_set_tls_identity_chain() configures the intermediate + certificates sent with the server identity certificate during TLS setup. + + @param ctx Pointer to the EST context + @param chain PEM encoded intermediate certificates, issuer first + @param chain_len Length of the chain buffer + + The server identity certificate supplied to est_server_init() is not + included in this buffer. This function must be invoked before starting + the EST server. + + @return EST_ERROR. + */ +EST_ERROR est_server_set_tls_identity_chain (EST_CTX *ctx, + const unsigned char *chain, + int chain_len) +{ + BIO *in = NULL; + STACK_OF(X509_INFO) *cert_info = NULL; + STACK_OF(X509) *cert_chain = NULL; + X509_INFO *info; + + if (!ctx) { + EST_LOG_ERR("Null context"); + return (EST_ERR_NO_CTX); + } + if (ctx->est_mode != EST_SERVER && ctx->est_mode != EST_PROXY) { + EST_LOG_ERR("TLS identity chain is only valid in server or proxy mode"); + return (EST_ERR_BAD_MODE); + } + if (ctx->mg_ctx) { + EST_LOG_ERR("TLS identity chain must be configured before server start"); + return (EST_ERR_BAD_MODE); + } + if (!chain || chain_len <= 0) { + EST_LOG_ERR("Invalid TLS identity chain"); + return (EST_ERR_INVALID_PARAMETERS); + } + + in = BIO_new_mem_buf((void *)chain, chain_len); + cert_chain = sk_X509_new_null(); + if (!in || !cert_chain) { + BIO_free(in); + sk_X509_free(cert_chain); + return (EST_ERR_MALLOC); + } + + cert_info = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if (!cert_info) { + sk_X509_free(cert_chain); + EST_LOG_ERR("Unable to read PEM encoded TLS identity chain"); + return (EST_ERR_NO_CERTS_FOUND); + } + + while (sk_X509_INFO_num(cert_info)) { + info = sk_X509_INFO_shift(cert_info); + if (info->x509) { + if (!sk_X509_push(cert_chain, info->x509)) { + X509_INFO_free(info); + sk_X509_INFO_pop_free(cert_info, X509_INFO_free); + sk_X509_pop_free(cert_chain, X509_free); + return (EST_ERR_MALLOC); + } + info->x509 = NULL; + } + X509_INFO_free(info); + } + sk_X509_INFO_free(cert_info); + + if (!sk_X509_num(cert_chain)) { + sk_X509_free(cert_chain); + EST_LOG_ERR("No certificates found in TLS identity chain"); + return (EST_ERR_NO_CERTS_FOUND); + } + + if (ctx->server_cert_chain) { + sk_X509_pop_free(ctx->server_cert_chain, X509_free); + } + ctx->server_cert_chain = cert_chain; + return (EST_ERR_NONE); +} + /*! @brief est_set_ca_enroll_cb() is used by an application to install a handler for signing incoming PKCS10 requests. diff --git a/src/est/est_server_http.c b/src/est/est_server_http.c index 2bd08d5..2935e52 100644 --- a/src/est/est_server_http.c +++ b/src/est/est_server_http.c @@ -1471,24 +1471,16 @@ static int set_ssl_option (struct mg_context *ctx) EST_LOG_ERR("Unable to set server certificate"); return 0; } + if (ectx->server_cert_chain && + !SSL_CTX_set1_chain(ssl_ctx, ectx->server_cert_chain)) { + EST_LOG_ERR("Unable to set server certificate chain"); + return 0; + } if (SSL_CTX_use_PrivateKey(ssl_ctx, ectx->server_priv_key) == 0) { EST_LOG_ERR("Unable to set server private key"); return 0; } - /* - * There should be no need to include the cert chain for the - * server's certificate in the TLS Certificate message from - * the server. The reason is the EST draft specifies that - * all the subordinate CA certs should be included in the - * cacerts message flow. Hence, the client will already have - * the full cert chain. Therefore, the TLS handshake will only - * contain the server's cert, not the full chain. - * - SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, - ctx->est_ctx->http_cert_file); - */ - return 1; } diff --git a/test/UT/US1190/us1190.c b/test/UT/US1190/us1190.c index 64b56b7..673711c 100644 --- a/test/UT/US1190/us1190.c +++ b/test/UT/US1190/us1190.c @@ -14,6 +14,7 @@ #include #include "test_utils.h" #include +#include #include "st_server.h" #ifdef HAVE_CUNIT @@ -25,14 +26,16 @@ #define US1190_CACERTS "CA/estCA/cacert.crt" #define US1190_CACERT "CA/estCA/cacert.crt" #define US1190_TRUSTED_CERT "CA/trustedcerts.crt" -#define US1190_SERVER_CERT "CA/estCA/private/estservercertandkey.pem" -#define US1190_SERVER_KEY "CA/estCA/private/estservercertandkey.pem" +#define US1190_SERVER_CERT "CA/mfgCAs/TestMfgCA0/esttestmfg0.crt" +#define US1190_SERVER_KEY "CA/mfgCAs/TestMfgCA0/private/certandkey1-esttestmfg0.pem" +#define US1190_SERVER_CHAIN "CA/mfgCAs/TestMfgCA0/cacert1-0.crt" #else #define US1190_CACERTS "CA\\estCA\\cacert.crt" #define US1190_CACERT "CA\\estCA\\cacert.crt" #define US1190_TRUSTED_CERT "CA\\trustedcerts.crt" -#define US1190_SERVER_CERT "CA\\estCA\\private\\estservercertandkey.pem" -#define US1190_SERVER_KEY "CA\\estCA\\private\\estservercertandkey.pem" +#define US1190_SERVER_CERT "CA\\mfgCAs\\TestMfgCA0\\esttestmfg0.crt" +#define US1190_SERVER_KEY "CA\\mfgCAs\\TestMfgCA0\\private\\certandkey1-esttestmfg0.pem" +#define US1190_SERVER_CHAIN "CA\\mfgCAs\\TestMfgCA0\\cacert1-0.crt" #endif #define US1190_TCP_SERVER_PORT "15895" @@ -49,6 +52,9 @@ int us1190_start_server () * Start an EST server acting as the CA * this server does not support TLS 1.0 */ +#ifndef WIN32 + st_set_tls_identity_chain_file(US1190_SERVER_CHAIN); +#endif rv = st_start(atoi(US1190_TCP_SERVER_PORT), US1190_SERVER_CERT, US1190_SERVER_KEY, @@ -249,6 +255,51 @@ static void us1190_test5 (void) } +#ifndef WIN32 +static void us1190_test6 (void) +{ + BIO *conn = NULL; + BIO *certin = NULL; + SSL *ssl = NULL; + SSL_CTX *ssl_ctx = NULL; + STACK_OF(X509) *peer_chain; + X509 *expected_intermediate = NULL; + int rv; + +#ifdef HAVE_OLD_OPENSSL + ssl_ctx = SSL_CTX_new(SSLv23_client_method()); +#else + ssl_ctx = SSL_CTX_new(TLS_client_method()); +#endif + CU_ASSERT_FATAL(ssl_ctx != NULL); + + conn = open_tcp_socket_ipv4("127.0.0.1", US1190_TCP_SERVER_PORT); + CU_ASSERT_FATAL(conn != NULL); + ssl = SSL_new(ssl_ctx); + CU_ASSERT_FATAL(ssl != NULL); + SSL_set_bio(ssl, conn, conn); + + rv = SSL_connect(ssl); + CU_ASSERT_FATAL(rv > 0); + peer_chain = SSL_get_peer_cert_chain(ssl); + CU_ASSERT_FATAL(peer_chain != NULL); + CU_ASSERT_EQUAL(sk_X509_num(peer_chain), 2); + + certin = BIO_new_file(US1190_SERVER_CHAIN, "r"); + CU_ASSERT_FATAL(certin != NULL); + expected_intermediate = PEM_read_bio_X509(certin, NULL, NULL, NULL); + CU_ASSERT_FATAL(expected_intermediate != NULL); + CU_ASSERT_EQUAL(X509_cmp(sk_X509_value(peer_chain, 1), + expected_intermediate), 0); + + X509_free(expected_intermediate); + BIO_free(certin); + SSL_shutdown(ssl); + SSL_free(ssl); + SSL_CTX_free(ssl_ctx); +} +#endif + /* The main() function for setting up and running the tests. * Returns a CUE_SUCCESS on successful running, another * CUnit error code on failure. @@ -278,8 +329,13 @@ int us1190_add_suite (void) CU_cleanup_registry(); return CU_get_error(); } +#ifndef WIN32 + if (NULL == CU_add_test(pSuite, "server sends TLS chain", us1190_test6)) { + CU_cleanup_registry(); + return CU_get_error(); + } +#endif return CUE_SUCCESS; #endif } - diff --git a/test/util/st_server.c b/test/util/st_server.c index 2269745..53016ae 100644 --- a/test/util/st_server.c +++ b/test/util/st_server.c @@ -50,6 +50,7 @@ SRP_VBASE *srp_db = NULL; unsigned char *trustcerts = NULL; int trustcerts_len = 0; static char conf_file[MAX_FILENAME_LEN]; +static char *tls_identity_chain_file; static char *csr_attr_value = NULL; int write_csr = 0; static char csr_filename[MAX_FILENAME_LEN]; @@ -57,6 +58,11 @@ static char csr_filename[MAX_FILENAME_LEN]; X509 *x; EVP_PKEY *priv_key; +void st_set_tls_identity_chain_file (char *chainfile) +{ + tls_identity_chain_file = chainfile; +} + static char valid_token_value[MAX_AUTH_TOKEN_LEN+1]; extern void dumpbin(char *buf, size_t len); @@ -1499,10 +1505,12 @@ static int st_start_internal ( EST_ERROR rv; pthread_t thread; int rc; + char *tls_chain_file = tls_identity_chain_file; #ifdef HAVE_LIBCOAP int coap_port; #endif + tls_identity_chain_file = NULL; manual_enroll = simulate_manual_enroll; /* @@ -1611,6 +1619,22 @@ static int st_start_internal ( return (-1); } + if (tls_chain_file) { + unsigned char *tls_chain = NULL; + int tls_chain_len = read_binary_file(tls_chain_file, &tls_chain); + + if (tls_chain_len <= 0) { + printf("\nTLS identity chain file could not be read\n"); + return (-1); + } + rv = est_server_set_tls_identity_chain(ectx, tls_chain, tls_chain_len); + free(tls_chain); + if (rv != EST_ERR_NONE) { + printf("\nUnable to configure TLS identity chain\n"); + return (-1); + } + } + /* * Install event callbacks */ diff --git a/test/util/st_server.h b/test/util/st_server.h index b7adbbf..cbe3b78 100644 --- a/test/util/st_server.h +++ b/test/util/st_server.h @@ -11,6 +11,9 @@ #ifndef ST_SERVER_H #define ST_SERVER_H void st_stop(void); +#ifndef WIN32 +void st_set_tls_identity_chain_file(char *chainfile); +#endif int st_start(int tcp_port, char *certfile, char *keyfile, @@ -215,4 +218,3 @@ EST_ERROR st_server_enable_performance_timers(); EST_ERROR st_server_disable_performance_timers(); #endif -