summaryrefslogtreecommitdiff
path: root/main/tcptls.c
diff options
context:
space:
mode:
authorAlexander Traud <pabstraud@compuserve.com>2015-05-10 16:55:24 +0200
committerAlexander Traud <pabstraud@compuserve.com>2015-05-15 10:01:04 +0200
commit8f3f414d8c8f80a2b0b23dd683a0adef25ddfa50 (patch)
tree57667632ef38c127025b43898b0b8a5acc0db1f0 /main/tcptls.c
parent32eb812b28ffc1745e08cb507d8c4409d3ed297a (diff)
tcptls: Enable multiple TLS certificate chains (RSA+ECC+DSA) for server socket.
When a client connects to a server via SSL/TLS, the server commonly utilizes an RSA key-pair. However, other such algorithms exist (i.e. DSA and ECDSA), and if the server socket is configured with a certificate for either one of those, it would lose its compatibility with RSA-only clients. Now, the server socket can be configured with up to one RSA, ECDSA and DSA key each. For example, if a client is not compatible with SHA-2 hashed certificates like Nokia mobile phones, the server socket still can use RSA/SHA-1 for legacy clients and ECDSA/SHA-2 for everyone else. ASTERISK-24815 #close Reported by: Alexander Traud patches: tls_rsa_ecc_dsa.patch uploaded by Alexander Traud (License 6520) Change-Id: Iada5e00d326db5ef86e0af7069b4dfa1b979da9a
Diffstat (limited to 'main/tcptls.c')
-rw-r--r--main/tcptls.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/main/tcptls.c b/main/tcptls.c
index 0b06d22ac..8af8501c9 100644
--- a/main/tcptls.c
+++ b/main/tcptls.c
@@ -752,6 +752,22 @@ void *ast_tcptls_server_root(void *data)
return NULL;
}
+static void __ssl_setup_certs(struct ast_tls_config *cfg, const size_t cert_file_len, const char *key_type_extension, const char *key_type)
+{
+ char *cert_file = ast_strdupa(cfg->certfile);
+
+ memcpy(cert_file + cert_file_len - 8, key_type_extension, 5);
+ if (access(cert_file, F_OK) == 0) {
+ if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cert_file) == 0) {
+ ast_log(LOG_WARNING, "TLS/SSL error loading public %s key (certificate) from <%s>.\n", key_type, cert_file);
+ } else if (SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, cert_file, SSL_FILETYPE_PEM) == 0) {
+ ast_log(LOG_WARNING, "TLS/SSL error loading private %s key from <%s>.\n", key_type, cert_file);
+ } else if (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0) {
+ ast_log(LOG_WARNING, "TLS/SSL error matching private %s key and certificate in <%s>.\n", key_type, cert_file);
+ }
+ }
+}
+
static int __ssl_setup(struct ast_tls_config *cfg, int client)
{
#ifndef DO_SSL
@@ -839,6 +855,17 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
return 0;
}
}
+ if (!client) {
+ size_t certfile_len = strlen(cfg->certfile);
+
+ /* expects a file name which contains _rsa. like asterisk_rsa.pem
+ * ignores any 3-character file-extension like .pem, .cer, .crt
+ */
+ if (certfile_len >= 8 && !strncmp(cfg->certfile + certfile_len - 8, "_rsa.", 5)) {
+ __ssl_setup_certs(cfg, certfile_len, "_ecc.", "ECC");
+ __ssl_setup_certs(cfg, certfile_len, "_dsa.", "DSA");
+ }
+ }
}
if (!ast_strlen_zero(cfg->cipher)) {
if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {