summaryrefslogtreecommitdiff
path: root/pjlib/src
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2012-03-30 07:10:13 +0000
committerBenny Prijono <bennylp@teluu.com>2012-03-30 07:10:13 +0000
commit6b4964727bffb379aca9601e1cf69051ccbf600c (patch)
tree1d9739ea8b3b5e0421f1d99b39e798b1514fb644 /pjlib/src
parent85ac546acb235df62169c4ad317da74a62e56a88 (diff)
Re #1474: Merged all changes from 1.12 - HEAD (from the 1.x branch)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3999 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src')
-rw-r--r--pjlib/src/pj/os_core_symbian.cpp20
-rw-r--r--pjlib/src/pj/os_core_unix.c20
-rw-r--r--pjlib/src/pj/os_core_win32.c20
-rw-r--r--pjlib/src/pj/ssl_sock_common.c100
-rw-r--r--pjlib/src/pj/ssl_sock_ossl.c57
-rw-r--r--pjlib/src/pj/ssl_sock_symbian.cpp198
6 files changed, 288 insertions, 127 deletions
diff --git a/pjlib/src/pj/os_core_symbian.cpp b/pjlib/src/pj/os_core_symbian.cpp
index 5446df5d..d6a1df22 100644
--- a/pjlib/src/pj/os_core_symbian.cpp
+++ b/pjlib/src/pj/os_core_symbian.cpp
@@ -75,6 +75,9 @@ struct pj_sem_t
int max;
};
+/* Flag and reference counter for PJLIB instance */
+static int initialized;
+
/* Flags to indicate which TLS variables have been used */
static int tls_vars[PJ_MAX_TLS];
@@ -83,8 +86,6 @@ static unsigned atexit_count;
static void (*atexit_func[32])(void);
-
-
/////////////////////////////////////////////////////////////////////////////
//
// CPjTimeoutTimer implementation
@@ -335,6 +336,12 @@ PJ_DEF(pj_status_t) pj_init(void)
char stack_ptr;
pj_status_t status;
+ /* Check if PJLIB have been initialized */
+ if (initialized) {
+ ++initialized;
+ return PJ_SUCCESS;
+ }
+
pj_ansi_strcpy(main_thread.obj_name, "pjthread");
// Init main thread
@@ -368,6 +375,10 @@ PJ_DEF(pj_status_t) pj_init(void)
stack_ptr = '\0';
#endif
+ /* Flag PJLIB as initialized */
+ ++initialized;
+ pj_assert(initialized == 1);
+
PJ_LOG(5,(THIS_FILE, "PJLIB initialized."));
return PJ_SUCCESS;
@@ -390,6 +401,11 @@ PJ_DEF(pj_status_t) pj_atexit(pj_exit_callback func)
PJ_DEF(void) pj_shutdown(void)
{
+ /* Only perform shutdown operation when 'initialized' reaches zero */
+ pj_assert(initialized > 0);
+ if (--initialized != 0)
+ return;
+
/* Call atexit() functions */
while (atexit_count > 0) {
(*atexit_func[atexit_count-1])();
diff --git a/pjlib/src/pj/os_core_unix.c b/pjlib/src/pj/os_core_unix.c
index 1c8cb14e..810e4b0d 100644
--- a/pjlib/src/pj/os_core_unix.c
+++ b/pjlib/src/pj/os_core_unix.c
@@ -102,6 +102,11 @@ struct pj_event_t
#endif /* PJ_HAS_EVENT_OBJ */
+/*
+ * Flag and reference counter for PJLIB instance.
+ */
+static int initialized;
+
#if PJ_HAS_THREADS
static pj_thread_t main_thread;
static long thread_tls_id;
@@ -127,6 +132,12 @@ PJ_DEF(pj_status_t) pj_init(void)
pj_str_t guid;
pj_status_t rc;
+ /* Check if PJLIB have been initialized */
+ if (initialized) {
+ ++initialized;
+ return PJ_SUCCESS;
+ }
+
#if PJ_HAS_THREADS
/* Init this thread's TLS. */
if ((rc=pj_thread_init()) != 0) {
@@ -167,6 +178,10 @@ PJ_DEF(pj_status_t) pj_init(void)
}
#endif
+ /* Flag PJLIB as initialized */
+ ++initialized;
+ pj_assert(initialized == 1);
+
PJ_LOG(4,(THIS_FILE, "pjlib %s for POSIX initialized",
PJ_VERSION));
@@ -192,6 +207,11 @@ PJ_DEF(void) pj_shutdown()
{
int i;
+ /* Only perform shutdown operation when 'initialized' reaches zero */
+ pj_assert(initialized > 0);
+ if (--initialized != 0)
+ return;
+
/* Call atexit() functions */
for (i=atexit_count-1; i>=0; --i) {
(*atexit_func[i])();
diff --git a/pjlib/src/pj/os_core_win32.c b/pjlib/src/pj/os_core_win32.c
index 30992a4f..5168d7db 100644
--- a/pjlib/src/pj/os_core_win32.c
+++ b/pjlib/src/pj/os_core_win32.c
@@ -117,6 +117,11 @@ struct pj_atomic_t
};
/*
+ * Flag and reference counter for PJLIB instance.
+ */
+static int initialized;
+
+/*
* Static global variables.
*/
static pj_thread_desc main_thread;
@@ -142,6 +147,12 @@ PJ_DEF(pj_status_t) pj_init(void)
pj_str_t guid;
pj_status_t rc;
+ /* Check if PJLIB have been initialized */
+ if (initialized) {
+ ++initialized;
+ return PJ_SUCCESS;
+ }
+
/* Init Winsock.. */
if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
return PJ_RETURN_OS_ERROR(WSAGetLastError());
@@ -187,6 +198,10 @@ PJ_DEF(pj_status_t) pj_init(void)
}
#endif
+ /* Flag PJLIB as initialized */
+ ++initialized;
+ pj_assert(initialized == 1);
+
PJ_LOG(4,(THIS_FILE, "pjlib %s for win32 initialized",
PJ_VERSION));
@@ -213,6 +228,11 @@ PJ_DEF(void) pj_shutdown()
{
int i;
+ /* Only perform shutdown operation when 'initialized' reaches zero */
+ pj_assert(initialized > 0);
+ if (--initialized != 0)
+ return;
+
/* Display stack usage */
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
{
diff --git a/pjlib/src/pj/ssl_sock_common.c b/pjlib/src/pj/ssl_sock_common.c
index c70a7af1..67a8d63c 100644
--- a/pjlib/src/pj/ssl_sock_common.c
+++ b/pjlib/src/pj/ssl_sock_common.c
@@ -21,89 +21,6 @@
#include <pj/errno.h>
#include <pj/string.h>
-/* Cipher name structure */
-typedef struct cipher_name_t {
- pj_ssl_cipher cipher;
- const char *name;
-} cipher_name_t;
-
-/* Cipher name constants */
-static cipher_name_t cipher_names[] =
-{
- {PJ_TLS_NULL_WITH_NULL_NULL, "NULL"},
-
- /* TLS/SSLv3 */
- {PJ_TLS_RSA_WITH_NULL_MD5, "TLS_RSA_WITH_NULL_MD5"},
- {PJ_TLS_RSA_WITH_NULL_SHA, "TLS_RSA_WITH_NULL_SHA"},
- {PJ_TLS_RSA_WITH_NULL_SHA256, "TLS_RSA_WITH_NULL_SHA256"},
- {PJ_TLS_RSA_WITH_RC4_128_MD5, "TLS_RSA_WITH_RC4_128_MD5"},
- {PJ_TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA"},
- {PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
- {PJ_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
- {PJ_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"},
- {PJ_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"},
- {PJ_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"},
- {PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"},
- {PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"},
- {PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"},
- {PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"},
- {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"},
- {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"},
- {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"},
- {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
- {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"},
- {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"},
- {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"},
- {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
- {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"},
- {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"},
- {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"},
- {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
- {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"},
- {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"},
- {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"},
- {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
- {PJ_TLS_DH_anon_WITH_RC4_128_MD5, "TLS_DH_anon_WITH_RC4_128_MD5"},
- {PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"},
- {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA, "TLS_DH_anon_WITH_AES_128_CBC_SHA"},
- {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA, "TLS_DH_anon_WITH_AES_256_CBC_SHA"},
- {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"},
- {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"},
-
- /* TLS (deprecated) */
- {PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5, "TLS_RSA_EXPORT_WITH_RC4_40_MD5"},
- {PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"},
- {PJ_TLS_RSA_WITH_IDEA_CBC_SHA, "TLS_RSA_WITH_IDEA_CBC_SHA"},
- {PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"},
- {PJ_TLS_RSA_WITH_DES_CBC_SHA, "TLS_RSA_WITH_DES_CBC_SHA"},
- {PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"},
- {PJ_TLS_DH_DSS_WITH_DES_CBC_SHA, "TLS_DH_DSS_WITH_DES_CBC_SHA"},
- {PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"},
- {PJ_TLS_DH_RSA_WITH_DES_CBC_SHA, "TLS_DH_RSA_WITH_DES_CBC_SHA"},
- {PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"},
- {PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA, "TLS_DHE_DSS_WITH_DES_CBC_SHA"},
- {PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"},
- {PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS_DHE_RSA_WITH_DES_CBC_SHA"},
- {PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"},
- {PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"},
- {PJ_TLS_DH_anon_WITH_DES_CBC_SHA, "TLS_DH_anon_WITH_DES_CBC_SHA"},
-
- /* SSLv3 */
- {PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA, "SSL_FORTEZZA_KEA_WITH_NULL_SHA"},
- {PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA,"SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"},
- {PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"},
-
- /* SSLv2 */
- {PJ_SSL_CK_RC4_128_WITH_MD5, "SSL_CK_RC4_128_WITH_MD5"},
- {PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5, "SSL_CK_RC4_128_EXPORT40_WITH_MD5"},
- {PJ_SSL_CK_RC2_128_CBC_WITH_MD5, "SSL_CK_RC2_128_CBC_WITH_MD5"},
- {PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5"},
- {PJ_SSL_CK_IDEA_128_CBC_WITH_MD5, "SSL_CK_IDEA_128_CBC_WITH_MD5"},
- {PJ_SSL_CK_DES_64_CBC_WITH_MD5, "SSL_CK_DES_64_CBC_WITH_MD5"},
- {PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5, "SSL_CK_DES_192_EDE3_CBC_WITH_MD5"}
-};
-
-
/*
* Initialize the SSL socket configuration with the default values.
*/
@@ -129,23 +46,6 @@ PJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param)
}
-/* Get cipher name string */
-PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)
-{
- unsigned i, n;
-
- n = PJ_ARRAY_SIZE(cipher_names);
- for (i = 0; i < n; ++i) {
- if (cipher == cipher_names[i].cipher)
- return cipher_names[i].name;
- }
-
- return NULL;
-}
-
-
-
-
PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(
pj_uint32_t verify_status,
const char *error_strings[],
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
index 6ce44ad1..559b5134 100644
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -39,6 +39,9 @@
/* Workaround for ticket #985 */
#define DELAYED_CLOSE_TIMEOUT 200
+/* Maximum ciphers */
+#define MAX_CIPHERS 100
+
/*
* Include OpenSSL headers
*/
@@ -269,8 +272,11 @@ static pj_str_t ssl_strerror(pj_status_t status,
static int openssl_init_count;
/* OpenSSL available ciphers */
-static pj_ssl_cipher openssl_ciphers[100];
static unsigned openssl_cipher_num;
+static struct openssl_ciphers_t {
+ pj_ssl_cipher id;
+ const char *name;
+} openssl_ciphers[MAX_CIPHERS];
/* OpenSSL application data index */
static int sslsock_idx;
@@ -329,9 +335,9 @@ static pj_status_t init_openssl(void)
for (i = 0; i < n; ++i) {
SSL_CIPHER *c;
c = sk_SSL_CIPHER_value(sk_cipher,i);
- openssl_ciphers[i] = (pj_ssl_cipher)
- (pj_uint32_t)c->id & 0x00FFFFFF;
- //printf("%3u: %08x=%s\n", i+1, c->id, SSL_CIPHER_get_name(c));
+ openssl_ciphers[i].id = (pj_ssl_cipher)
+ (pj_uint32_t)c->id & 0x00FFFFFF;
+ openssl_ciphers[i].name = SSL_CIPHER_get_name(c);
}
SSL_free(ssl);
@@ -1705,18 +1711,57 @@ PJ_DEF(pj_status_t) pj_ssl_cipher_get_availables(pj_ssl_cipher ciphers[],
shutdown_openssl();
}
- if (openssl_cipher_num == 0)
+ if (openssl_cipher_num == 0) {
+ *cipher_num = 0;
return PJ_ENOTFOUND;
+ }
*cipher_num = PJ_MIN(*cipher_num, openssl_cipher_num);
for (i = 0; i < *cipher_num; ++i)
- ciphers[i] = openssl_ciphers[i];
+ ciphers[i] = openssl_ciphers[i].id;
return PJ_SUCCESS;
}
+/* Get cipher name string */
+PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)
+{
+ unsigned i;
+
+ if (openssl_cipher_num == 0) {
+ init_openssl();
+ shutdown_openssl();
+ }
+
+ for (i = 0; i < openssl_cipher_num; ++i) {
+ if (cipher == openssl_ciphers[i].id)
+ return openssl_ciphers[i].name;
+ }
+
+ return NULL;
+}
+
+/* Check if the specified cipher is supported by SSL/TLS backend. */
+PJ_DEF(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher)
+{
+ unsigned i;
+
+ if (openssl_cipher_num == 0) {
+ init_openssl();
+ shutdown_openssl();
+ }
+
+ for (i = 0; i < openssl_cipher_num; ++i) {
+ if (cipher == openssl_ciphers[i].id)
+ return PJ_TRUE;
+ }
+
+ return PJ_FALSE;
+}
+
+
/*
* Create SSL socket instance.
*/
diff --git a/pjlib/src/pj/ssl_sock_symbian.cpp b/pjlib/src/pj/ssl_sock_symbian.cpp
index 95c10077..47288fae 100644
--- a/pjlib/src/pj/ssl_sock_symbian.cpp
+++ b/pjlib/src/pj/ssl_sock_symbian.cpp
@@ -32,6 +32,104 @@
#define THIS_FILE "ssl_sock_symbian.cpp"
+
+/* Cipher name structure */
+typedef struct cipher_name_t {
+ pj_ssl_cipher cipher;
+ const char *name;
+} cipher_name_t;
+
+/* Cipher name constants */
+static cipher_name_t cipher_names[] =
+{
+ {PJ_TLS_NULL_WITH_NULL_NULL, "NULL"},
+
+ /* TLS/SSLv3 */
+ {PJ_TLS_RSA_WITH_NULL_MD5, "TLS_RSA_WITH_NULL_MD5"},
+ {PJ_TLS_RSA_WITH_NULL_SHA, "TLS_RSA_WITH_NULL_SHA"},
+ {PJ_TLS_RSA_WITH_NULL_SHA256, "TLS_RSA_WITH_NULL_SHA256"},
+ {PJ_TLS_RSA_WITH_RC4_128_MD5, "TLS_RSA_WITH_RC4_128_MD5"},
+ {PJ_TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA"},
+ {PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
+ {PJ_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
+ {PJ_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"},
+ {PJ_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"},
+ {PJ_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"},
+ {PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"},
+ {PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"},
+ {PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"},
+ {PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"},
+ {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"},
+ {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"},
+ {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"},
+ {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
+ {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"},
+ {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"},
+ {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"},
+ {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
+ {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"},
+ {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"},
+ {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"},
+ {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
+ {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"},
+ {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"},
+ {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"},
+ {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
+ {PJ_TLS_DH_anon_WITH_RC4_128_MD5, "TLS_DH_anon_WITH_RC4_128_MD5"},
+ {PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"},
+ {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA, "TLS_DH_anon_WITH_AES_128_CBC_SHA"},
+ {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA, "TLS_DH_anon_WITH_AES_256_CBC_SHA"},
+ {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"},
+ {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"},
+
+ /* TLS (deprecated) */
+ {PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5, "TLS_RSA_EXPORT_WITH_RC4_40_MD5"},
+ {PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"},
+ {PJ_TLS_RSA_WITH_IDEA_CBC_SHA, "TLS_RSA_WITH_IDEA_CBC_SHA"},
+ {PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"},
+ {PJ_TLS_RSA_WITH_DES_CBC_SHA, "TLS_RSA_WITH_DES_CBC_SHA"},
+ {PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"},
+ {PJ_TLS_DH_DSS_WITH_DES_CBC_SHA, "TLS_DH_DSS_WITH_DES_CBC_SHA"},
+ {PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"},
+ {PJ_TLS_DH_RSA_WITH_DES_CBC_SHA, "TLS_DH_RSA_WITH_DES_CBC_SHA"},
+ {PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"},
+ {PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA, "TLS_DHE_DSS_WITH_DES_CBC_SHA"},
+ {PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"},
+ {PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS_DHE_RSA_WITH_DES_CBC_SHA"},
+ {PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"},
+ {PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"},
+ {PJ_TLS_DH_anon_WITH_DES_CBC_SHA, "TLS_DH_anon_WITH_DES_CBC_SHA"},
+
+ /* SSLv3 */
+ {PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA, "SSL_FORTEZZA_KEA_WITH_NULL_SHA"},
+ {PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA,"SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"},
+ {PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"},
+
+ /* SSLv2 */
+ {PJ_SSL_CK_RC4_128_WITH_MD5, "SSL_CK_RC4_128_WITH_MD5"},
+ {PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5, "SSL_CK_RC4_128_EXPORT40_WITH_MD5"},
+ {PJ_SSL_CK_RC2_128_CBC_WITH_MD5, "SSL_CK_RC2_128_CBC_WITH_MD5"},
+ {PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5"},
+ {PJ_SSL_CK_IDEA_128_CBC_WITH_MD5, "SSL_CK_IDEA_128_CBC_WITH_MD5"},
+ {PJ_SSL_CK_DES_64_CBC_WITH_MD5, "SSL_CK_DES_64_CBC_WITH_MD5"},
+ {PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5, "SSL_CK_DES_192_EDE3_CBC_WITH_MD5"}
+};
+
+
+/* Get cipher name string */
+static const char* get_cipher_name(pj_ssl_cipher cipher)
+{
+ unsigned i, n;
+
+ n = PJ_ARRAY_SIZE(cipher_names);
+ for (i = 0; i < n; ++i) {
+ if (cipher == cipher_names[i].cipher)
+ return cipher_names[i].name;
+ }
+
+ return "CIPHER_UNKNOWN";
+}
+
typedef void (*CPjSSLSocket_cb)(int err, void *key);
class CPjSSLSocketReader : public CActive
@@ -115,7 +213,8 @@ public:
int Connect(CPjSSLSocket_cb cb, void *key, const TInetAddr &local_addr,
const TInetAddr &rem_addr,
- const TDesC8 &servername = TPtrC8(NULL,0));
+ const TDesC8 &servername = TPtrC8(NULL,0),
+ const TDesC8 &ciphers = TPtrC8(NULL,0));
int Send(CPjSSLSocket_cb cb, void *key, const TDesC8 &aDesc, TUint flags);
int SendSync(const TDesC8 &aDesc, TUint flags);
@@ -146,6 +245,7 @@ private:
TBuf<32> ssl_proto_;
TInetAddr rem_addr_;
TPtrC8 servername_;
+ TPtrC8 ciphers_;
TInetAddr local_addr_;
TSockXfrLength sent_len_;
@@ -186,7 +286,8 @@ private:
int CPjSSLSocket::Connect(CPjSSLSocket_cb cb, void *key,
const TInetAddr &local_addr,
const TInetAddr &rem_addr,
- const TDesC8 &servername)
+ const TDesC8 &servername,
+ const TDesC8 &ciphers)
{
pj_status_t status;
@@ -213,7 +314,11 @@ int CPjSSLSocket::Connect(CPjSSLSocket_cb cb, void *key,
cb_ = cb;
key_ = key;
rem_addr_ = rem_addr;
+
+ /* Note: the following members only keep the pointer, not the data */
servername_.Set(servername);
+ ciphers_.Set(ciphers);
+
rSock.Connect(rem_addr_, iStatus);
SetActive();
state_ = SSL_STATE_CONNECTING;
@@ -318,6 +423,8 @@ void CPjSSLSocket::RunL()
if (servername_.Length() > 0)
securesock_->SetOpt(KSoSSLDomainName, KSolInetSSL,
servername_);
+ if (ciphers_.Length() > 0)
+ securesock_->SetAvailableCipherSuites(ciphers_);
// FlushSessionCache() seems to also fire signals to all
// completed AOs (something like CActiveScheduler::RunIfReady())
@@ -441,9 +548,8 @@ struct pj_ssl_sock_t
pj_ssl_sock_proto proto;
pj_time_val timeout;
- unsigned ciphers_num;
- pj_ssl_cipher *ciphers;
pj_str_t servername;
+ pj_str_t ciphers;
pj_ssl_cert_info remote_cert_info;
};
@@ -579,15 +685,20 @@ static void update_certs_info(pj_ssl_sock_t *ssock)
}
+/* Available ciphers */
+static unsigned ciphers_num_ = 0;
+static struct ciphers_t
+{
+ pj_ssl_cipher id;
+ const char *name;
+} ciphers_[64];
+
/*
* Get cipher list supported by SSL/TLS backend.
*/
PJ_DEF(pj_status_t) pj_ssl_cipher_get_availables (pj_ssl_cipher ciphers[],
unsigned *cipher_num)
{
- /* Available ciphers */
- static pj_ssl_cipher ciphers_[64];
- static unsigned ciphers_num_ = 0;
unsigned i;
PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL);
@@ -605,25 +716,69 @@ PJ_DEF(pj_status_t) pj_ssl_cipher_get_availables (pj_ssl_cipher ciphers[],
ciphers_num_ = ciphers_buf.Length() / 2;
if (ciphers_num_ > PJ_ARRAY_SIZE(ciphers_))
ciphers_num_ = PJ_ARRAY_SIZE(ciphers_);
- for (i = 0; i < ciphers_num_; ++i)
- ciphers_[i] = (pj_ssl_cipher)(ciphers_buf[i*2]*10 +
- ciphers_buf[i*2+1]);
+ for (i = 0; i < ciphers_num_; ++i) {
+ ciphers_[i].id = (pj_ssl_cipher)(ciphers_buf[i*2]*10 +
+ ciphers_buf[i*2+1]);
+ ciphers_[i].name = get_cipher_name(ciphers_[i].id);
+ }
}
delete secure_sock;
}
if (ciphers_num_ == 0) {
+ *cipher_num = 0;
return PJ_ENOTFOUND;
}
*cipher_num = PJ_MIN(*cipher_num, ciphers_num_);
for (i = 0; i < *cipher_num; ++i)
- ciphers[i] = ciphers_[i];
+ ciphers[i] = ciphers_[i].id;
return PJ_SUCCESS;
}
+
+/* Get cipher name string */
+PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)
+{
+ unsigned i;
+
+ if (ciphers_num_ == 0) {
+ pj_ssl_cipher c[1];
+ i = 0;
+ pj_ssl_cipher_get_availables(c, &i);
+ }
+
+ for (i = 0; i < ciphers_num_; ++i) {
+ if (cipher == ciphers_[i].id)
+ return ciphers_[i].name;
+ }
+
+ return NULL;
+}
+
+
+/* Check if the specified cipher is supported by SSL/TLS backend. */
+PJ_DEF(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher)
+{
+ unsigned i;
+
+ if (ciphers_num_ == 0) {
+ pj_ssl_cipher c[1];
+ i = 0;
+ pj_ssl_cipher_get_availables(c, &i);
+ }
+
+ for (i = 0; i < ciphers_num_; ++i) {
+ if (cipher == ciphers_[i].id)
+ return PJ_TRUE;
+ }
+
+ return PJ_FALSE;
+}
+
+
/*
* Create SSL socket instance.
*/
@@ -652,14 +807,15 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
ssock->cb = param->cb;
ssock->user_data = param->user_data;
ssock->timeout = param->timeout;
- ssock->ciphers_num = param->ciphers_num;
if (param->ciphers_num > 0) {
- unsigned i;
- ssock->ciphers = (pj_ssl_cipher*)
- pj_pool_calloc(pool, param->ciphers_num,
- sizeof(pj_ssl_cipher));
- for (i = 0; i < param->ciphers_num; ++i)
- ssock->ciphers[i] = param->ciphers[i];
+ /* Cipher list in Symbian is represented as array of two-octets. */
+ ssock->ciphers.slen = param->ciphers_num*2;
+ ssock->ciphers.ptr = (char*)pj_pool_alloc(pool, ssock->ciphers.slen);
+ pj_uint8_t *c = (pj_uint8_t*)ssock->ciphers.ptr;
+ for (unsigned i = 0; i < param->ciphers_num; ++i) {
+ *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF00) >> 8;
+ *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF);
+ }
}
pj_strdup_with_null(pool, &ssock->servername, &param->server_name);
@@ -1246,9 +1402,13 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_connect (pj_ssl_sock_t *ssock,
TPtrC8 servername_((TUint8*)ssock->servername.ptr,
ssock->servername.slen);
+ /* Convert cipher list to Symbian descriptor */
+ TPtrC8 ciphers_((TUint8*)ssock->ciphers.ptr,
+ ssock->ciphers.slen);
+
/* Try to connect */
status = sock->Connect(&connect_cb, ssock, localaddr_, remaddr_,
- servername_);
+ servername_, ciphers_);
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
delete sock;
return status;