From edc65dae7b3332ead145bb2d2b030c5df3e9a2e1 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Thu, 18 Dec 2014 04:40:35 +0000 Subject: Re #1806: Implement SSL/TLS setting to set protocol operation. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4968 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsip/sip_transport_tls.h | 49 ++++++++++++------- pjsip/include/pjsua2/siptypes.hpp | 16 +++++-- pjsip/src/pjsip/sip_transport_tls.c | 83 +++++++++++++++++---------------- pjsip/src/pjsua2/siptypes.cpp | 2 + 4 files changed, 90 insertions(+), 60 deletions(-) (limited to 'pjsip') diff --git a/pjsip/include/pjsip/sip_transport_tls.h b/pjsip/include/pjsip/sip_transport_tls.h index b6deafc7..5a36384d 100644 --- a/pjsip/include/pjsip/sip_transport_tls.h +++ b/pjsip/include/pjsip/sip_transport_tls.h @@ -51,18 +51,28 @@ PJ_BEGIN_DECL # define PJSIP_SSL_DEFAULT_METHOD PJSIP_TLSV1_METHOD #endif + /** SSL protocol method constants. */ typedef enum pjsip_ssl_method { - PJSIP_SSL_UNSPECIFIED_METHOD= 0, /**< Default protocol method. */ - PJSIP_TLSV1_METHOD = 31, /**< Use SSLv1 method. */ - PJSIP_SSLV2_METHOD = 20, /**< Use SSLv2 method. */ - PJSIP_SSLV3_METHOD = 30, /**< Use SSLv3 method. */ - PJSIP_SSLV23_METHOD = 23 /**< Use SSLv23 method. */ + PJSIP_SSL_UNSPECIFIED_METHOD = 0, /**< Default protocol method. */ + PJSIP_SSLV2_METHOD = 20, /**< Use SSLv2 method. */ + PJSIP_SSLV3_METHOD = 30, /**< Use SSLv3 method. */ + PJSIP_TLSV1_METHOD = 31, /**< Use TLSv1 method. */ + PJSIP_TLSV1_1_METHOD = 32, /**< Use TLSv1_1 method. */ + PJSIP_TLSV1_2_METHOD = 33, /**< Use TLSv1_2 method. */ + PJSIP_SSLV23_METHOD = 23, /**< Use SSLv23 method. */ } pjsip_ssl_method; - - +/** + * The default enabled SSL proto to be used. + * Default is all protocol above TLSv1 (TLSv1 & TLS v1.1 & TLS v1.2). + */ +#ifndef PJSIP_SSL_DEFAULT_PROTO +# define PJSIP_SSL_DEFAULT_PROTO (PJ_SSL_SOCK_PROTO_TLS1 | \ + PJ_SSL_SOCK_PROTO_TLS1_1 | \ + PJ_SSL_SOCK_PROTO_TLS1_2) +#endif /** * TLS transport settings. @@ -92,19 +102,23 @@ typedef struct pjsip_tls_setting pj_str_t password; /** - * TLS protocol method from #pjsip_ssl_method, which can be: - * - PJSIP_SSL_UNSPECIFIED_METHOD(0): default (which will use - * PJSIP_SSL_DEFAULT_METHOD) - * - PJSIP_TLSV1_METHOD(1): TLSv1 - * - PJSIP_SSLV2_METHOD(2): SSLv2 - * - PJSIP_SSLV3_METHOD(3): SSL3 - * - PJSIP_SSLV23_METHOD(23): SSL23 + * TLS protocol method from #pjsip_ssl_method. In the future, this field + * might be deprecated in favor of proto field. For now, this field + * is only applicable only when proto field is set to zero. * * Default is PJSIP_SSL_UNSPECIFIED_METHOD (0), which in turn will - * use PJSIP_SSL_DEFAULT_METHOD, which default value is - * PJSIP_TLSV1_METHOD. + * use PJSIP_SSL_DEFAULT_METHOD, which default value is PJSIP_TLSV1_METHOD. + */ + pjsip_ssl_method method; + + /** + * TLS protocol type from #pj_ssl_sock_proto. Use this field to enable + * specific protocol type. Use bitwise OR operation to combine the protocol + * type. + * + * Default is PJSIP_SSL_DEFAULT_PROTO. */ - int method; + pj_uint32_t proto; /** * Number of ciphers contained in the specified cipher preference. @@ -252,6 +266,7 @@ PJ_INLINE(void) pjsip_tls_setting_default(pjsip_tls_setting *tls_opt) tls_opt->qos_type = PJ_QOS_TYPE_BEST_EFFORT; tls_opt->qos_ignore_error = PJ_TRUE; tls_opt->sockopt_ignore_error = PJ_TRUE; + tls_opt->proto = PJSIP_SSL_DEFAULT_PROTO; } diff --git a/pjsip/include/pjsua2/siptypes.hpp b/pjsip/include/pjsua2/siptypes.hpp index 8e0428b9..c5b23dea 100644 --- a/pjsip/include/pjsua2/siptypes.hpp +++ b/pjsip/include/pjsua2/siptypes.hpp @@ -145,14 +145,24 @@ struct TlsConfig : public PersistentObject string password; /** - * TLS protocol method from pjsip_ssl_method. + * TLS protocol method from #pjsip_ssl_method. In the future, this field + * might be deprecated in favor of proto field. For now, this field + * is only applicable only when proto field is set to zero. * * Default is PJSIP_SSL_UNSPECIFIED_METHOD (0), which in turn will - * use PJSIP_SSL_DEFAULT_METHOD, which default value is - * PJSIP_TLSV1_METHOD. + * use PJSIP_SSL_DEFAULT_METHOD, which default value is PJSIP_TLSV1_METHOD. */ pjsip_ssl_method method; + /** + * TLS protocol type from #pj_ssl_sock_proto. Use this field to enable + * specific protocol type. Use bitwise OR operation to combine the protocol + * type. + * + * Default is PJSIP_SSL_DEFAULT_PROTO. + */ + unsigned proto; + /** * Ciphers and order preference. The Endpoint::utilSslGetAvailableCiphers() * can be used to check the available ciphers supported by backend. diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c index 0878c3a2..10c4f574 100644 --- a/pjsip/src/pjsip/sip_transport_tls.c +++ b/pjsip/src/pjsip/sip_transport_tls.c @@ -185,6 +185,43 @@ static void sockaddr_to_host_port( pj_pool_t *pool, } +static pj_uint32_t ssl_get_proto(pjsip_ssl_method ssl_method, pj_uint32_t proto) +{ + pj_uint32_t out_proto; + + if (proto) + return proto; + + if (ssl_method == PJSIP_SSL_UNSPECIFIED_METHOD) + ssl_method = PJSIP_SSL_DEFAULT_METHOD; + + switch(ssl_method) { + case PJSIP_SSLV2_METHOD: + out_proto = PJ_SSL_SOCK_PROTO_SSL2; + break; + case PJSIP_SSLV3_METHOD: + out_proto = PJ_SSL_SOCK_PROTO_SSL3; + break; + case PJSIP_TLSV1_METHOD: + out_proto = PJ_SSL_SOCK_PROTO_TLS1; + break; + case PJSIP_TLSV1_1_METHOD: + out_proto = PJ_SSL_SOCK_PROTO_TLS1_1; + break; + case PJSIP_TLSV1_2_METHOD: + out_proto = PJ_SSL_SOCK_PROTO_TLS1_2; + break; + case PJSIP_SSLV23_METHOD: + out_proto = PJ_SSL_SOCK_PROTO_SSL23; + break; + default: + out_proto = PJ_SSL_SOCK_PROTO_DEFAULT; + break; + } + return out_proto; +} + + static void tls_init_shutdown(struct tls_transport *tls, pj_status_t status) { pjsip_tp_state_callback state_cb; @@ -275,6 +312,7 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt, pj_pool_t *pool; pj_bool_t is_ipv6; int af, sip_ssl_method; + pj_uint32_t sip_ssl_proto; struct tls_listener *listener; pj_ssl_sock_param ssock_param; pj_sockaddr *listener_addr; @@ -368,26 +406,8 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt, has_listener = PJ_FALSE; sip_ssl_method = listener->tls_setting.method; - if (sip_ssl_method==PJSIP_SSL_UNSPECIFIED_METHOD) - sip_ssl_method = PJSIP_SSL_DEFAULT_METHOD; - - switch(sip_ssl_method) { - case PJSIP_TLSV1_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_TLS1; - break; - case PJSIP_SSLV2_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_SSL2; - break; - case PJSIP_SSLV3_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_SSL3; - break; - case PJSIP_SSLV23_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_SSL23; - break; - default: - ssock_param.proto = PJ_SSL_SOCK_PROTO_DEFAULT; - break; - } + sip_ssl_proto = listener->tls_setting.proto; + ssock_param.proto = ssl_get_proto(sip_ssl_method, sip_ssl_proto); /* Create group lock */ status = pj_grp_lock_create(pool, NULL, &listener->grp_lock); @@ -963,6 +983,7 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory, struct tls_listener *listener; struct tls_transport *tls; int sip_ssl_method; + pj_uint32_t sip_ssl_proto; pj_pool_t *pool; pj_grp_lock_t *glock; pj_ssl_sock_t *ssock; @@ -1027,26 +1048,8 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory, sizeof(listener->tls_setting.sockopt_params)); sip_ssl_method = listener->tls_setting.method; - if (sip_ssl_method==PJSIP_SSL_UNSPECIFIED_METHOD) - sip_ssl_method = PJSIP_SSL_DEFAULT_METHOD; - - switch(sip_ssl_method) { - case PJSIP_TLSV1_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_TLS1; - break; - case PJSIP_SSLV2_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_SSL2; - break; - case PJSIP_SSLV3_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_SSL3; - break; - case PJSIP_SSLV23_METHOD: - ssock_param.proto = PJ_SSL_SOCK_PROTO_SSL23; - break; - default: - ssock_param.proto = PJ_SSL_SOCK_PROTO_DEFAULT; - break; - } + sip_ssl_proto = listener->tls_setting.proto; + ssock_param.proto = ssl_get_proto(sip_ssl_method, sip_ssl_proto); /* Create group lock */ status = pj_grp_lock_create(pool, NULL, &glock); diff --git a/pjsip/src/pjsua2/siptypes.cpp b/pjsip/src/pjsua2/siptypes.cpp index 2b5ddc3e..a3391bbc 100644 --- a/pjsip/src/pjsua2/siptypes.cpp +++ b/pjsip/src/pjsua2/siptypes.cpp @@ -165,6 +165,7 @@ pjsip_tls_setting TlsConfig::toPj() const ts.password = str2Pj(this->password); ts.method = this->method; ts.ciphers_num = (unsigned)this->ciphers.size(); + ts.proto = this->proto; // The following will only work if sizeof(enum)==sizeof(int) pj_assert(sizeof(ts.ciphers[0]) == sizeof(int)); ts.ciphers = ts.ciphers_num? @@ -188,6 +189,7 @@ void TlsConfig::fromPj(const pjsip_tls_setting &prm) this->privKeyFile = pj2Str(prm.privkey_file); this->password = pj2Str(prm.password); this->method = (pjsip_ssl_method)prm.method; + this->proto = prm.proto; // The following will only work if sizeof(enum)==sizeof(int) pj_assert(sizeof(prm.ciphers[0]) == sizeof(int)); this->ciphers = IntVector(prm.ciphers, prm.ciphers+prm.ciphers_num); -- cgit v1.2.3