diff options
-rw-r--r-- | configs/samples/pjsip.conf.sample | 8 | ||||
-rw-r--r-- | configs/samples/sip.conf.sample | 7 | ||||
-rw-r--r-- | main/tcptls.c | 27 |
3 files changed, 40 insertions, 2 deletions
diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample index 5e3757175..276e214e9 100644 --- a/configs/samples/pjsip.conf.sample +++ b/configs/samples/pjsip.conf.sample @@ -765,7 +765,13 @@ ; (default: "") ;cert_file= ; Certificate file for endpoint TLS ONLY ; Will read .crt or .pem file but only uses cert, - ; a .key file must be specified via priv_key_file + ; a .key file must be specified via priv_key_file. + ; Since PJProject version 2.5: If the file name ends in _rsa, + ; for example "asterisk_rsa.pem", the files "asterisk_dsa.pem" + ; and/or "asterisk_ecc.pem" are loaded (certificate, inter- + ; mediates, private key), to support multiple algorithms for + ; server authentication (RSA, DSA, ECDSA). If the chains are + ; different, at least OpenSSL 1.0.2 is required. ; (default: "") ;cipher= ; Preferred cryptography cipher names TLS ONLY (default: "") ;domain= ; Domain the transport comes from (default: "") diff --git a/configs/samples/sip.conf.sample b/configs/samples/sip.conf.sample index e52fa6db2..71e3fb72b 100644 --- a/configs/samples/sip.conf.sample +++ b/configs/samples/sip.conf.sample @@ -561,7 +561,12 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ;------------------------ TLS settings ------------------------------------------------------------ ;tlscertfile=</path/to/certificate.pem> ; Certificate chain (*.pem format only) to use for TLS connections ; The certificates must be sorted starting with the subject's certificate - ; and followed by intermediate CA certificates if applicable. + ; and followed by intermediate CA certificates if applicable. If the + ; file name ends in _rsa, for example "asterisk_rsa.pem", the files + ; "asterisk_dsa.pem" and/or "asterisk_ecc.pem" are loaded + ; (certificate, intermediates, private key), to support multiple + ; algorithms for server authentication (RSA, DSA, ECDSA). If the chains + ; are different, at least OpenSSL 1.0.2 is required. ; Default is to look for "asterisk.pem" in current directory ;tlsprivatekey=</path/to/private.pem> ; Private key file (*.pem format only) for TLS connections. 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 ) { |