From 2af5925e6fc57a48c9e6590261b9a19090b68b8e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 20 Sep 2016 14:20:52 +0200 Subject: [PATCH] Added API to set RootCA by buffer instead of file --- coreapi/bellesip_sal/sal_impl.c | 23 ++++++++++++---- coreapi/bellesip_sal/sal_impl.h | 1 + coreapi/linphonecore.c | 16 ++++++++--- coreapi/linphonecore.h | 1 + include/sal/sal.h | 1 + tester/register_tester.c | 49 +++++++++++++++++++++++++++++++++ tester/tester.c | 1 + 7 files changed, 83 insertions(+), 9 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 1ab19716d..5294336d1 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -596,6 +596,7 @@ void sal_uninit(Sal* sal){ bctbx_list_free_with_data(sal->supported_tags,ms_free); if (sal->uuid) ms_free(sal->uuid); if (sal->root_ca) ms_free(sal->root_ca); + if (sal->root_ca_data) ms_free(sal->root_ca_data); ms_free(sal); }; @@ -761,21 +762,33 @@ static void set_tls_properties(Sal *ctx){ else if (!ctx->tls_verify_cn) verify_exceptions = BELLE_TLS_VERIFY_CN_MISMATCH; belle_tls_crypto_config_set_verify_exceptions(crypto_config, verify_exceptions); if (ctx->root_ca != NULL) belle_tls_crypto_config_set_root_ca(crypto_config, ctx->root_ca); + if (ctx->root_ca_data != NULL) belle_tls_crypto_config_set_root_ca_data(crypto_config, ctx->root_ca_data); if (ctx->ssl_config != NULL) belle_tls_crypto_config_set_ssl_config(crypto_config, ctx->ssl_config); belle_sip_tls_listening_point_set_crypto_config(tlp, crypto_config); belle_sip_object_unref(crypto_config); } } -void sal_set_root_ca(Sal* ctx, const char* rootCa){ - if (ctx->root_ca){ +void sal_set_root_ca(Sal* ctx, const char* rootCa) { + if (ctx->root_ca) { ms_free(ctx->root_ca); - ctx->root_ca=NULL; + ctx->root_ca = NULL; } if (rootCa) - ctx->root_ca=ms_strdup(rootCa); + ctx->root_ca = ms_strdup(rootCa); set_tls_properties(ctx); - return ; + return; +} + +void sal_set_root_ca_data(Sal* ctx, const char* data) { + if (ctx->root_ca_data) { + ms_free(ctx->root_ca_data); + ctx->root_ca_data = NULL; + } + if (data) + ctx->root_ca_data = ms_strdup(data); + set_tls_properties(ctx); + return; } void sal_verify_server_certificates(Sal *ctx, bool_t verify){ diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index e43baa9ac..e0fc4fc77 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -37,6 +37,7 @@ struct Sal{ int session_expires; unsigned int keep_alive; char *root_ca; + char *root_ca_data; char *uuid; int refresher_retry_after; /*retry after value for refresher*/ MSList *supported_tags;/*list of char * */ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0609ac9c9..0a3581475 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4931,12 +4931,20 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){ * * @ingroup initializing **/ -void linphone_core_set_root_ca(LinphoneCore *lc,const char *path){ +void linphone_core_set_root_ca(LinphoneCore *lc, const char *path) { sal_set_root_ca(lc->sal, path); - if (lc->http_crypto_config){ - belle_tls_crypto_config_set_root_ca(lc->http_crypto_config,path); + if (lc->http_crypto_config) { + belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, path); + } + lp_config_set_string(lc->config,"sip", "root_ca", path); +} + +void linphone_core_set_root_ca_data(LinphoneCore *lc, const char *data) { + sal_set_root_ca(lc->sal, NULL); + sal_set_root_ca_data(lc->sal, data); + if (lc->http_crypto_config) { + belle_tls_crypto_config_set_root_ca_data(lc->http_crypto_config, data); } - lp_config_set_string(lc->config,"sip","root_ca",path); } /** diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 1dee47b24..6594a6be7 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -3385,6 +3385,7 @@ LINPHONE_PUBLIC const char *linphone_core_get_ring(const LinphoneCore *lc); LINPHONE_PUBLIC void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno); LINPHONE_PUBLIC void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno); LINPHONE_PUBLIC void linphone_core_set_root_ca(LinphoneCore *lc, const char *path); +LINPHONE_PUBLIC void linphone_core_set_root_ca_data(LinphoneCore *lc, const char *data); /** * @internal * Set the pointer to an externally provided ssl configuration for the crypto library diff --git a/include/sal/sal.h b/include/sal/sal.h index 72ee8c0d6..e22d42259 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -645,6 +645,7 @@ void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec); void sal_use_rport(Sal *ctx, bool_t use_rports); void sal_enable_auto_contacts(Sal *ctx, bool_t enabled); void sal_set_root_ca(Sal* ctx, const char* rootCa); +void sal_set_root_ca_data(Sal* ctx, const char* data); const char *sal_get_root_ca(Sal* ctx); void sal_verify_server_certificates(Sal *ctx, bool_t verify); void sal_verify_server_cn(Sal *ctx, bool_t verify); diff --git a/tester/register_tester.c b/tester/register_tester.c index 03fdb1197..eea6aefa8 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -827,6 +827,54 @@ static void tls_certificate_failure(void){ } } +char *read_file(const char *path) { + long numbytes = 0; + size_t readbytes; + char *buffer = NULL; + FILE *infile = fopen(path, "rb"); + + BC_ASSERT_PTR_NOT_NULL(infile); + if (infile) { + fseek(infile, 0L, SEEK_END); + numbytes = ftell(infile); + fseek(infile, 0L, SEEK_SET); + buffer = (char*)ms_malloc((numbytes + 1) * sizeof(char)); + readbytes = fread(buffer, sizeof(char), numbytes, infile); + fclose(infile); + buffer[readbytes] = '\0'; + } + return buffer; +} + +static void tls_certificate_data(void) { + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* lcm; + LinphoneCore *lc; + char *rootcapath = bc_tester_res("certificates/cn/agent.pem"); /*bad root ca*/ + char *data = read_file(rootcapath); + + lcm = linphone_core_manager_new2("pauline_rc",FALSE); + lc = lcm->lc; + linphone_core_set_root_ca_data(lcm->lc, data); + linphone_core_set_network_reachable(lc, TRUE); + BC_ASSERT_TRUE(wait_for(lcm->lc, lcm->lc, &lcm->stat.number_of_LinphoneRegistrationFailed, 1)); + linphone_core_set_root_ca_data(lcm->lc, NULL); /*no root ca*/ + linphone_core_refresh_registers(lcm->lc); + BC_ASSERT_TRUE(wait_for(lc, lc, &lcm->stat.number_of_LinphoneRegistrationFailed, 2)); + ms_free(rootcapath); + ms_free(data); + rootcapath = bc_tester_res("certificates/cn/cafile.pem"); /*good root ca*/ + data = read_file(rootcapath); + linphone_core_set_root_ca_data(lcm->lc, data); + linphone_core_refresh_registers(lcm->lc); + BC_ASSERT_TRUE(wait_for(lc, lc, &lcm->stat.number_of_LinphoneRegistrationOk, 1)); + BC_ASSERT_EQUAL(lcm->stat.number_of_LinphoneRegistrationFailed, 2, int, "%d"); + linphone_core_manager_destroy(lcm); + ms_free(rootcapath); + ms_free(data); + } +} + /*the purpose of this test is to check that will not block the proxy config during SSL handshake for entire life in case of mistaken configuration*/ static void tls_with_non_tls_server(void){ if (transport_supported(LinphoneTransportTls)) { @@ -909,6 +957,7 @@ test_t register_tests[] = { TEST_NO_TAG("TLS register with alt. name certificate", tls_alt_name_register), TEST_NO_TAG("TLS register with wildcard certificate", tls_wildcard_register), TEST_NO_TAG("TLS certificate not verified",tls_certificate_failure), + TEST_NO_TAG("TLS certificate given by string instead of file",tls_certificate_data), TEST_NO_TAG("TLS with non tls server",tls_with_non_tls_server), TEST_NO_TAG("Simple authenticated register", simple_authenticated_register), TEST_NO_TAG("Ha1 authenticated register", ha1_authenticated_register), diff --git a/tester/tester.c b/tester/tester.c index fe3b76066..1339cc91a 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -17,6 +17,7 @@ */ #include +#include #include "linphonecore.h" #include "private.h" #include "liblinphone_tester.h"