diff options
-rw-r--r-- | pjlib/include/pj/ssl_sock.h | 59 | ||||
-rw-r--r-- | pjlib/src/pj/ssl_sock_ossl.c | 51 | ||||
-rw-r--r-- | pjlib/src/pj/ssl_sock_symbian.cpp | 9 | ||||
-rw-r--r-- | pjsip-apps/src/swig/symbols.i | 4 | ||||
-rw-r--r-- | pjsip-apps/src/swig/symbols.lst | 2 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_transport_tls.h | 49 | ||||
-rw-r--r-- | pjsip/include/pjsua2/siptypes.hpp | 16 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_tls.c | 83 | ||||
-rw-r--r-- | pjsip/src/pjsua2/siptypes.cpp | 2 |
9 files changed, 187 insertions, 88 deletions
diff --git a/pjlib/include/pj/ssl_sock.h b/pjlib/include/pj/ssl_sock.h index 92e86aab..b2a530b3 100644 --- a/pjlib/include/pj/ssl_sock.h +++ b/pjlib/include/pj/ssl_sock.h @@ -487,16 +487,51 @@ typedef struct pj_ssl_sock_cb /** * Enumeration of secure socket protocol types. + * This can be combined using bitwise OR operation. */ typedef enum pj_ssl_sock_proto { - PJ_SSL_SOCK_PROTO_DEFAULT, /**< Default protocol of backend. */ - PJ_SSL_SOCK_PROTO_TLS1, /**< TLSv1.0 protocol. */ - PJ_SSL_SOCK_PROTO_SSL3, /**< SSLv3.0 protocol. */ - PJ_SSL_SOCK_PROTO_SSL23, /**< SSLv3.0 but can roll back to - SSLv2.0. */ - PJ_SSL_SOCK_PROTO_SSL2, /**< SSLv2.0 protocol. */ - PJ_SSL_SOCK_PROTO_DTLS1 /**< DTLSv1.0 protocol. */ + /** + * Default protocol of backend. + */ + PJ_SSL_SOCK_PROTO_DEFAULT = 0, + + /** + * SSLv2.0 protocol. + */ + PJ_SSL_SOCK_PROTO_SSL2 = (1 << 0), + + /** + * SSLv3.0 protocol. + */ + PJ_SSL_SOCK_PROTO_SSL3 = (1 << 1), + + /** + * TLSv1.0 protocol. + */ + PJ_SSL_SOCK_PROTO_TLS1 = (1 << 2), + + /** + * TLSv1.1 protocol. + */ + PJ_SSL_SOCK_PROTO_TLS1_1 = (1 << 3), + + /** + * TLSv1.2 protocol. + */ + PJ_SSL_SOCK_PROTO_TLS1_2 = (1 << 4), + + /** + * Certain backend implementation e.g:OpenSSL, has feature to enable all + * protocol. + */ + PJ_SSL_SOCK_PROTO_SSL23 = (1 << 16) - 1, + + /** + * DTLSv1.0 protocol. + */ + PJ_SSL_SOCK_PROTO_DTLS1 = (1 << 16), + } pj_ssl_sock_proto; @@ -512,9 +547,10 @@ typedef struct pj_ssl_sock_info pj_bool_t established; /** - * Describes secure socket protocol being used. + * Describes secure socket protocol being used, see #pj_ssl_sock_proto. + * Use bitwise OR operation to combine the protocol type. */ - pj_ssl_sock_proto proto; + pj_uint32_t proto; /** * Describes cipher suite being used, this will only be set when connection @@ -614,11 +650,12 @@ typedef struct pj_ssl_sock_param void *user_data; /** - * Specify security protocol to use, see #pj_ssl_sock_proto. + * Specify security protocol to use, see #pj_ssl_sock_proto. Use bitwise OR + * operation to combine the protocol type. * * Default is PJ_SSL_SOCK_PROTO_DEFAULT. */ - pj_ssl_sock_proto proto; + pj_uint32_t proto; /** * Number of concurrent asynchronous operations that is to be supported diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c index 84ff5d92..e4013e2e 100644 --- a/pjlib/src/pj/ssl_sock_ossl.c +++ b/pjlib/src/pj/ssl_sock_ossl.c @@ -502,8 +502,9 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) #if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L EC_KEY *ecdh; #endif - SSL_METHOD *ssl_method; + SSL_METHOD *ssl_method = NULL; SSL_CTX *ctx; + pj_uint32_t ssl_opt = 0; pj_ssl_cert_t *cert; int mode, rc; pj_status_t status; @@ -515,6 +516,9 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) /* Make sure OpenSSL library has been initialized */ init_openssl(); + if (ssock->param.proto == PJ_SSL_SOCK_PROTO_DEFAULT) + ssock->param.proto = PJ_SSL_SOCK_PROTO_SSL23; + /* Determine SSL method to use */ switch (ssock->param.proto) { case PJ_SSL_SOCK_PROTO_TLS1: @@ -528,15 +532,42 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) case PJ_SSL_SOCK_PROTO_SSL3: ssl_method = (SSL_METHOD*)SSLv3_method(); break; - case PJ_SSL_SOCK_PROTO_DEFAULT: - case PJ_SSL_SOCK_PROTO_SSL23: + } + + if (!ssl_method) { ssl_method = (SSL_METHOD*)SSLv23_method(); - break; - //case PJ_SSL_SOCK_PROTO_DTLS1: - //ssl_method = (SSL_METHOD*)DTLSv1_method(); - //break; - default: - return PJ_EINVAL; + +#ifdef SSL_OP_NO_SSLv2 + /** Check if SSLv2 is enabled */ + ssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_SSL2)==0)? + SSL_OP_NO_SSLv2:0; +#endif + +#ifdef SSL_OP_NO_SSLv3 + /** Check if SSLv3 is enabled */ + ssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_SSL3)==0)? + SSL_OP_NO_SSLv3:0; +#endif + +#ifdef SSL_OP_NO_TLSv1 + /** Check if TLSv1 is enabled */ + ssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_TLS1)==0)? + SSL_OP_NO_TLSv1:0; +#endif + +#ifdef SSL_OP_NO_TLSv1_1 + /** Check if TLSv1_1 is enabled */ + ssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_TLS1_1)==0)? + SSL_OP_NO_TLSv1_1:0; +#endif + +#ifdef SSL_OP_NO_TLSv1_2 + /** Check if TLSv1_2 is enabled */ + ssl_opt |= ((ssock->param.proto & PJ_SSL_SOCK_PROTO_TLS1_2)==0)? + SSL_OP_NO_TLSv1_2:0; + +#endif + } /* Create SSL context */ @@ -544,6 +575,8 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) if (ctx == NULL) { return GET_SSL_STATUS(ssock); } + if (ssl_opt) + SSL_CTX_set_options(ctx, ssl_opt); /* Apply credentials */ if (cert) { diff --git a/pjlib/src/pj/ssl_sock_symbian.cpp b/pjlib/src/pj/ssl_sock_symbian.cpp index 013318b2..509b1072 100644 --- a/pjlib/src/pj/ssl_sock_symbian.cpp +++ b/pjlib/src/pj/ssl_sock_symbian.cpp @@ -1383,14 +1383,11 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_connect (pj_ssl_sock_t *ssock, ssock->proto = PJ_SSL_SOCK_PROTO_TLS1; /* CSecureSocket only support TLS1.0 and SSL3.0 */ - switch(ssock->proto) { - case PJ_SSL_SOCK_PROTO_TLS1: + if (ssock->proto & PJ_SSL_SOCK_PROTO_TLS1==PJ_SSL_SOCK_PROTO_TLS1) { proto.Set((const TUint8*)"TLS1.0", 6); - break; - case PJ_SSL_SOCK_PROTO_SSL3: + } else if (ssock->proto & PJ_SSL_SOCK_PROTO_SSL3==PJ_SSL_SOCK_PROTO_SSL3) { proto.Set((const TUint8*)"SSL3.0", 6); - break; - default: + } else { return PJ_ENOTSUP; } diff --git a/pjsip-apps/src/swig/symbols.i b/pjsip-apps/src/swig/symbols.i index 1e37d729..ead4c85a 100644 --- a/pjsip-apps/src/swig/symbols.i +++ b/pjsip-apps/src/swig/symbols.i @@ -32,6 +32,8 @@ typedef struct pj_qos_params typedef enum pj_ssl_cipher {PJ_TLS_UNKNOWN_CIPHER = -1, PJ_TLS_NULL_WITH_NULL_NULL = 0x00000000, PJ_TLS_RSA_WITH_NULL_MD5 = 0x00000001, PJ_TLS_RSA_WITH_NULL_SHA = 0x00000002, PJ_TLS_RSA_WITH_NULL_SHA256 = 0x0000003B, PJ_TLS_RSA_WITH_RC4_128_MD5 = 0x00000004, PJ_TLS_RSA_WITH_RC4_128_SHA = 0x00000005, PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x0000000A, PJ_TLS_RSA_WITH_AES_128_CBC_SHA = 0x0000002F, PJ_TLS_RSA_WITH_AES_256_CBC_SHA = 0x00000035, PJ_TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003C, PJ_TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x0000003D, PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x0000000D, PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000010, PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x00000013, PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000016, PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x00000030, PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x00000031, PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x00000032, PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x00000033, PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x00000036, PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x00000037, PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x00000038, PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x00000039, PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x0000003E, PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003F, PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x00000040, PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x00000067, PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x00000068, PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x00000069, PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x0000006A, PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x0000006B, PJ_TLS_DH_anon_WITH_RC4_128_MD5 = 0x00000018, PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x0000001B, PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x00000034, PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x0000003A, PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x0000006C, PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x0000006D, PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x00000003, PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x00000006, PJ_TLS_RSA_WITH_IDEA_CBC_SHA = 0x00000007, PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000008, PJ_TLS_RSA_WITH_DES_CBC_SHA = 0x00000009, PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0000000B, PJ_TLS_DH_DSS_WITH_DES_CBC_SHA = 0x0000000C, PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0000000E, PJ_TLS_DH_RSA_WITH_DES_CBC_SHA = 0x0000000F, PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x00000011, PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x00000012, PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000014, PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x00000015, PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x00000017, PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x00000019, PJ_TLS_DH_anon_WITH_DES_CBC_SHA = 0x0000001A, PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA = 0x0000001C, PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA = 0x0000001D, PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA = 0x0000001E, PJ_SSL_CK_RC4_128_WITH_MD5 = 0x00010080, PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5 = 0x00020080, PJ_SSL_CK_RC2_128_CBC_WITH_MD5 = 0x00030080, PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 = 0x00040080, PJ_SSL_CK_IDEA_128_CBC_WITH_MD5 = 0x00050080, PJ_SSL_CK_DES_64_CBC_WITH_MD5 = 0x00060040, PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5 = 0x000700C0} pj_ssl_cipher; +typedef enum pj_ssl_sock_proto {PJ_SSL_SOCK_PROTO_DEFAULT = 0, PJ_SSL_SOCK_PROTO_SSL2 = 1 << 0, PJ_SSL_SOCK_PROTO_SSL3 = 1 << 1, PJ_SSL_SOCK_PROTO_TLS1 = 1 << 2, PJ_SSL_SOCK_PROTO_TLS1_1 = 1 << 3, PJ_SSL_SOCK_PROTO_TLS1_2 = 1 << 4, PJ_SSL_SOCK_PROTO_SSL23 = (1 << 16) - 1, PJ_SSL_SOCK_PROTO_DTLS1 = 1 << 16} pj_ssl_sock_proto; + typedef enum pj_stun_nat_type {PJ_STUN_NAT_TYPE_UNKNOWN, PJ_STUN_NAT_TYPE_ERR_UNKNOWN, PJ_STUN_NAT_TYPE_OPEN, PJ_STUN_NAT_TYPE_BLOCKED, PJ_STUN_NAT_TYPE_SYMMETRIC_UDP, PJ_STUN_NAT_TYPE_FULL_CONE, PJ_STUN_NAT_TYPE_SYMMETRIC, PJ_STUN_NAT_TYPE_RESTRICTED, PJ_STUN_NAT_TYPE_PORT_RESTRICTED} pj_stun_nat_type; typedef enum pj_turn_tp_type {PJ_TURN_TP_UDP = 17, PJ_TURN_TP_TCP = 6, PJ_TURN_TP_TLS = 255} pj_turn_tp_type; @@ -107,7 +109,7 @@ enum pjsip_transport_flags_e {PJSIP_TRANSPORT_RELIABLE = 1, PJSIP_TRANSPORT_SECU typedef enum pjsip_transport_state {PJSIP_TP_STATE_CONNECTED, PJSIP_TP_STATE_DISCONNECTED, PJSIP_TP_STATE_SHUTDOWN, PJSIP_TP_STATE_DESTROY} pjsip_transport_state; -typedef enum pjsip_ssl_method {PJSIP_SSL_UNSPECIFIED_METHOD = 0, PJSIP_TLSV1_METHOD = 31, PJSIP_SSLV2_METHOD = 20, PJSIP_SSLV3_METHOD = 30, PJSIP_SSLV23_METHOD = 23} pjsip_ssl_method; +typedef enum pjsip_ssl_method {PJSIP_SSL_UNSPECIFIED_METHOD = 0, PJSIP_SSLV2_METHOD = 20, PJSIP_SSLV3_METHOD = 30, PJSIP_TLSV1_METHOD = 31, PJSIP_TLSV1_1_METHOD = 32, PJSIP_TLSV1_2_METHOD = 33, PJSIP_SSLV23_METHOD = 23} pjsip_ssl_method; typedef enum pjsip_tsx_state_e {PJSIP_TSX_STATE_NULL, PJSIP_TSX_STATE_CALLING, PJSIP_TSX_STATE_TRYING, PJSIP_TSX_STATE_PROCEEDING, PJSIP_TSX_STATE_COMPLETED, PJSIP_TSX_STATE_CONFIRMED, PJSIP_TSX_STATE_TERMINATED, PJSIP_TSX_STATE_DESTROYED, PJSIP_TSX_STATE_MAX} pjsip_tsx_state_e; diff --git a/pjsip-apps/src/swig/symbols.lst b/pjsip-apps/src/swig/symbols.lst index b5e7b6e2..3e1dbdcd 100644 --- a/pjsip-apps/src/swig/symbols.lst +++ b/pjsip-apps/src/swig/symbols.lst @@ -2,7 +2,7 @@ pj/types.h pj_status_t pj_constants_ pj_uint8_t pj_int32_t pj_uint32_t pj_uint pj/file_io.h pj_file_access pj/log.h pj_log_decoration pj/sock_qos.h pj_qos_type pj_qos_flag pj_qos_wmm_prio pj_qos_params -pj/ssl_sock.h pj_ssl_cipher +pj/ssl_sock.h pj_ssl_cipher pj_ssl_sock_proto pjnath/nat_detect.h pj_stun_nat_type pjnath/turn_session.h pj_turn_tp_type 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 <b>proto</b> field. For now, this field + * is only applicable only when <b>proto</b> 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,15 +145,25 @@ 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 <b>proto</b> field. For now, this field + * is only applicable only when <b>proto</b> 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. * If the array is empty, then default cipher list of the 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); |