summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorRiza Sulistyo <riza@teluu.com>2014-12-18 04:40:35 +0000
committerRiza Sulistyo <riza@teluu.com>2014-12-18 04:40:35 +0000
commitedc65dae7b3332ead145bb2d2b030c5df3e9a2e1 (patch)
tree01dc1d7cb5b4b53d00a22d0f84d1e7306fc8cf5d /pjlib
parent91ce3c4bf51a884f7534551669e38d6b44a2da55 (diff)
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
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/ssl_sock.h59
-rw-r--r--pjlib/src/pj/ssl_sock_ossl.c51
-rw-r--r--pjlib/src/pj/ssl_sock_symbian.cpp9
3 files changed, 93 insertions, 26 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;
}