diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2015-05-07 04:48:19 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2015-05-07 04:48:19 +0000 |
commit | 3866e1c3e2173b477cfaceb1f13f8a9458dcfaa3 (patch) | |
tree | e403650ce7bf204d347826be7a3951228fed0162 /pjlib | |
parent | d2e299bfe6ca3dd77727c3928b6898767d8e51d2 (diff) |
Close #1849: Enabled multiple TLS certificate chains (RSA+ECC+DSA) for server socket.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5087 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r-- | pjlib/include/pj/ssl_sock.h | 10 | ||||
-rw-r--r-- | pjlib/src/pj/ssl_sock_ossl.c | 44 |
2 files changed, 52 insertions, 2 deletions
diff --git a/pjlib/include/pj/ssl_sock.h b/pjlib/include/pj/ssl_sock.h index 172943da..c24e7bd9 100644 --- a/pjlib/include/pj/ssl_sock.h +++ b/pjlib/include/pj/ssl_sock.h @@ -185,7 +185,10 @@ typedef struct pj_ssl_cert_info { /** - * Create credential from files. + * Create credential from files. TLS server application can provide multiple + * certificates (RSA, ECC, and DSA) by supplying certificate name with "_rsa" + * suffix, e.g: "pjsip_rsa.pem", the library will automatically check for + * other certificates with "_ecc" and "_dsa" suffix. * * @param CA_file The file of trusted CA list. * @param cert_file The file of certificate. @@ -203,7 +206,10 @@ PJ_DECL(pj_status_t) pj_ssl_cert_load_from_files(pj_pool_t *pool, pj_ssl_cert_t **p_cert); /** - * Create credential from files. + * Create credential from files. TLS server application can provide multiple + * certificates (RSA, ECC, and DSA) by supplying certificate name with "_rsa" + * suffix, e.g: "pjsip_rsa.pem", the library will automatically check for + * other certificates with "_ecc" and "_dsa" suffix. * * This is the same as pj_ssl_cert_load_from_files() but also * accepts an additional param CA_path to load CA certificates from diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c index e2726f66..bffb5f1e 100644 --- a/pjlib/src/pj/ssl_sock_ossl.c +++ b/pjlib/src/pj/ssl_sock_ossl.c @@ -21,6 +21,7 @@ #include <pj/compat/socket.h> #include <pj/assert.h> #include <pj/errno.h> +#include <pj/file_access.h> #include <pj/list.h> #include <pj/lock.h> #include <pj/log.h> @@ -671,6 +672,49 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) } if (ssock->is_server) { + char *p = NULL; + + /* If certificate file name contains "_rsa.", let's check if there are + * ecc and dsa certificates too. + */ + if (cert && cert->cert_file.slen) { + const pj_str_t RSA = {"_rsa.", 5}; + p = pj_strstr(&cert->cert_file, &RSA); + if (p) p++; /* Skip underscore */ + } + if (p) { + /* Certificate type string length must be exactly 3 */ + enum { CERT_TYPE_LEN = 3 }; + const char* cert_types[] = { "ecc", "dsa" }; + char *cf = cert->cert_file.ptr; + int i; + + /* Check and load ECC & DSA certificates & private keys */ + for (i = 0; i < PJ_ARRAY_SIZE(cert_types); ++i) { + int err; + + pj_memcpy(p, cert_types[i], CERT_TYPE_LEN); + if (!pj_file_exists(cf)) + continue; + + err = SSL_CTX_use_certificate_chain_file(ctx, cf); + if (err == 1) + err = SSL_CTX_use_PrivateKey_file(ctx, cf, + SSL_FILETYPE_PEM); + if (err == 1) { + PJ_LOG(4,(ssock->pool->obj_name, + "Additional certificate '%s' loaded.", cf)); + } else { + pj_perror(1, ssock->pool->obj_name, GET_SSL_STATUS(ssock), + "Error loading certificate file '%s'", cf); + ERR_clear_error(); + } + } + + /* Put back original name */ + pj_memcpy(p, "rsa", CERT_TYPE_LEN); + } + #ifndef SSL_CTRL_SET_ECDH_AUTO #define SSL_CTRL_SET_ECDH_AUTO 94 #endif |