Index: pjproject/branches/1.x/pjlib/include/pj/ssl_sock.h
===================================================================
--- pjproject/branches/1.x/pjlib/include/pj/ssl_sock.h	(revision 3941)
+++ pjproject/branches/1.x/pjlib/include/pj/ssl_sock.h	(revision 3942)
@@ -333,11 +333,33 @@
 
 /**
+ * Check if the specified cipher is supported by SSL/TLS backend.
+ *
+ * @param cipher	The cipher.
+ *
+ * @return		PJ_TRUE when supported.
+ */
+PJ_DECL(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher);
+
+
+/**
  * Get cipher name string.
  *
  * @param cipher	The cipher.
  *
- * @return		The cipher name or NULL if cipher is not recognized.
+ * @return		The cipher name or NULL if cipher is not recognized/
+ *			supported.
  */
 PJ_DECL(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher);
+
+
+/**
+ * Get cipher ID from cipher name string.
+ *
+ * @param cipher_name	The cipher name string.
+ *
+ * @return		The cipher ID or PJ_TLS_UNKNOWN_CIPHER if the cipher
+ *			name string is not recognized/supported.
+ */
+PJ_DECL(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name);
 
 
Index: pjproject/branches/1.x/pjlib/src/pj/ssl_sock_common.c
===================================================================
--- pjproject/branches/1.x/pjlib/src/pj/ssl_sock_common.c	(revision 3941)
+++ pjproject/branches/1.x/pjlib/src/pj/ssl_sock_common.c	(revision 3942)
@@ -21,87 +21,4 @@
 #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"}
-};
-
 
 /*
@@ -128,21 +45,4 @@
     param->proto = PJ_SSL_SOCK_PROTO_DEFAULT;
 }
-
-
-/* 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;
-}
-
-
 
 
Index: pjproject/branches/1.x/pjlib/src/pj/ssl_sock_ossl.c
===================================================================
--- pjproject/branches/1.x/pjlib/src/pj/ssl_sock_ossl.c	(revision 3941)
+++ pjproject/branches/1.x/pjlib/src/pj/ssl_sock_ossl.c	(revision 3942)
@@ -40,4 +40,7 @@
 #define DELAYED_CLOSE_TIMEOUT	200
 
+/* Maximum ciphers */
+#define MAX_CIPHERS		100
+
 /* 
  * Include OpenSSL headers 
@@ -270,6 +273,9 @@
 
 /* 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 */
@@ -330,7 +336,7 @@
 	    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);
 	}
 
@@ -1706,13 +1712,52 @@
     }
 
-    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;
 }
 
Index: pjproject/branches/1.x/pjlib/src/pj/ssl_sock_symbian.cpp
===================================================================
--- pjproject/branches/1.x/pjlib/src/pj/ssl_sock_symbian.cpp	(revision 3941)
+++ pjproject/branches/1.x/pjlib/src/pj/ssl_sock_symbian.cpp	(revision 3942)
@@ -33,4 +33,102 @@
 #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);
 
@@ -116,5 +214,6 @@
     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);
@@ -147,4 +246,5 @@
     TInetAddr       	 rem_addr_;
     TPtrC8		 servername_;
+    TPtrC8		 ciphers_;
     TInetAddr       	 local_addr_;
     TSockXfrLength 	 sent_len_;
@@ -187,5 +287,6 @@
 			  const TInetAddr &local_addr, 
 			  const TInetAddr &rem_addr,
-			  const TDesC8 &servername)
+			  const TDesC8 &servername,
+			  const TDesC8 &ciphers)
 {
     pj_status_t status;
@@ -214,5 +315,9 @@
     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();
@@ -319,4 +424,6 @@
 		securesock_->SetOpt(KSoSSLDomainName, KSolInetSSL,
 				    servername_);
+	    if (ciphers_.Length() > 0)
+		securesock_->SetAvailableCipherSuites(ciphers_);
 
 	    // FlushSessionCache() seems to also fire signals to all 
@@ -442,7 +549,6 @@
     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;
 };
@@ -580,4 +686,12 @@
 
 
+/* 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.
@@ -586,7 +700,4 @@
 					          unsigned *cipher_num)
 {
-    /* Available ciphers */
-    static pj_ssl_cipher ciphers_[64];
-    static unsigned ciphers_num_ = 0;
     unsigned i;
 
@@ -606,7 +717,9 @@
             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);
+	    }
         }
         
@@ -615,4 +728,5 @@
     
     if (ciphers_num_ == 0) {
+	*cipher_num = 0;
 	return PJ_ENOTFOUND;
     }
@@ -620,8 +734,49 @@
     *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;
+}
+
 
 /*
@@ -653,12 +808,13 @@
     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);
@@ -1247,7 +1403,11 @@
 		       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;
Index: pjproject/branches/1.x/pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- pjproject/branches/1.x/pjsip-apps/src/pjsua/pjsua_app.c	(revision 3941)
+++ pjproject/branches/1.x/pjsip-apps/src/pjsua/pjsua_app.c	(revision 3942)
@@ -252,4 +252,6 @@
     puts  ("  --stun-srv=FORMAT   Set STUN server host or domain. This option may be");
     puts  ("                      specified more than once. FORMAT is hostdom[:PORT]");
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
     puts  ("");
     puts  ("TLS Options:");
@@ -263,4 +265,7 @@
     puts  ("  --tls-neg-timeout   Specify TLS negotiation timeout (default=no)");
     puts  ("  --tls-srv-name      Specify TLS server name for multihosting server");
+    puts  ("  --tls-cipher        Specify prefered TLS cipher (optional).");
+    puts  ("                      May be specified multiple times");
+#endif
 
     puts  ("");
@@ -530,5 +535,5 @@
 	   OPT_USE_TLS, OPT_TLS_CA_FILE, OPT_TLS_CERT_FILE, OPT_TLS_PRIV_FILE,
 	   OPT_TLS_PASSWORD, OPT_TLS_VERIFY_SERVER, OPT_TLS_VERIFY_CLIENT,
-	   OPT_TLS_NEG_TIMEOUT, OPT_TLS_SRV_NAME,
+	   OPT_TLS_NEG_TIMEOUT, OPT_TLS_SRV_NAME, OPT_TLS_CIPHER,
 	   OPT_CAPTURE_DEV, OPT_PLAYBACK_DEV,
 	   OPT_CAPTURE_LAT, OPT_PLAYBACK_LAT, OPT_NO_TONES, OPT_JB_MAX_SIZE,
@@ -629,4 +634,5 @@
 	{ "duration",	1, 0, OPT_DURATION},
 	{ "thread-cnt",	1, 0, OPT_THREAD_CNT},
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
 	{ "use-tls",	0, 0, OPT_USE_TLS}, 
 	{ "tls-ca-file",1, 0, OPT_TLS_CA_FILE},
@@ -638,4 +644,6 @@
 	{ "tls-neg-timeout", 1, 0, OPT_TLS_NEG_TIMEOUT},
 	{ "tls-srv-name", 1, 0, OPT_TLS_SRV_NAME},
+	{ "tls-cipher", 1, 0, OPT_TLS_CIPHER},
+#endif
 	{ "capture-dev",    1, 0, OPT_CAPTURE_DEV},
 	{ "playback-dev",   1, 0, OPT_PLAYBACK_DEV},
@@ -1304,26 +1312,15 @@
 	    break;
 
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
 	case OPT_USE_TLS:
 	    cfg->use_tls = PJ_TRUE;
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 	    
 	case OPT_TLS_CA_FILE:
 	    cfg->udp_cfg.tls_setting.ca_list_file = pj_str(pj_optarg);
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 	    
 	case OPT_TLS_CERT_FILE:
 	    cfg->udp_cfg.tls_setting.cert_file = pj_str(pj_optarg);
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 	    
@@ -1334,8 +1331,4 @@
 	case OPT_TLS_PASSWORD:
 	    cfg->udp_cfg.tls_setting.password = pj_str(pj_optarg);
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 
@@ -1356,4 +1349,37 @@
 	    cfg->udp_cfg.tls_setting.server_name = pj_str(pj_optarg);
 	    break;
+	case OPT_TLS_CIPHER:
+	    {
+		pj_ssl_cipher cipher;
+
+		if (pj_ansi_strnicmp(pj_optarg, "0x", 2) == 0) {
+		    pj_str_t cipher_st = pj_str(pj_optarg + 2);
+		    cipher = pj_strtoul2(&cipher_st, NULL, 16);
+		} else {
+		    cipher = atoi(pj_optarg);
+		}
+
+		if (pj_ssl_cipher_is_supported(cipher)) {
+		    static pj_ssl_cipher tls_ciphers[128];
+
+		    tls_ciphers[cfg->udp_cfg.tls_setting.ciphers_num++] = cipher;
+		    cfg->udp_cfg.tls_setting.ciphers = tls_ciphers;
+		} else {
+		    pj_ssl_cipher ciphers[128];
+		    unsigned j, ciphers_cnt;
+
+		    ciphers_cnt = PJ_ARRAY_SIZE(ciphers);
+		    pj_ssl_cipher_get_availables(ciphers, &ciphers_cnt);
+		    
+		    PJ_LOG(1,(THIS_FILE, "Cipher \"%s\" is not supported by "
+					 "TLS/SSL backend.", pj_optarg));
+		    printf("Available TLS/SSL ciphers (%d):\n", ciphers_cnt);
+		    for (j=0; j<ciphers_cnt; ++j)
+			printf("- 0x%06X: %s\n", ciphers[j], pj_ssl_cipher_name(ciphers[j]));
+		    return -1;
+		}
+	    }
+ 	    break;
+#endif /* PJSIP_HAS_TLS_TRANSPORT */
 
 	case OPT_CAPTURE_DEV:
@@ -1774,4 +1800,5 @@
     }
 
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
     /* TLS */
     if (config->use_tls)
@@ -1821,4 +1848,12 @@
 	pj_strcat2(&cfg, line);
     }
+
+    for (i=0; i<config->udp_cfg.tls_setting.ciphers_num; ++i) {
+	pj_ansi_sprintf(line, "--tls-cipher 0x%06X # %s\n",
+			config->udp_cfg.tls_setting.ciphers[i],
+			pj_ssl_cipher_name(config->udp_cfg.tls_setting.ciphers[i]));
+	pj_strcat2(&cfg, line);
+    }
+#endif
 
     pj_strcat2(&cfg, "\n#\n# Media settings:\n#\n");
@@ -3006,4 +3041,9 @@
 	const char *verif_msgs[32];
 	unsigned verif_msg_cnt;
+
+	/* Dump server TLS cipher */
+	PJ_LOG(4,(THIS_FILE, "TLS cipher used: 0x%06X/%s",
+		  ssl_sock_info->cipher,
+		  pj_ssl_cipher_name(ssl_sock_info->cipher) ));
 
 	/* Dump server TLS certificate */
Index: pjproject/branches/1.x/pjsip/include/pjsip/sip_transport_tls.h
===================================================================
--- pjproject/branches/1.x/pjsip/include/pjsip/sip_transport_tls.h	(revision 3941)
+++ pjproject/branches/1.x/pjsip/include/pjsip/sip_transport_tls.h	(revision 3942)
@@ -27,4 +27,5 @@
 
 #include <pjsip/sip_transport.h>
+#include <pj/pool.h>
 #include <pj/ssl_sock.h>
 #include <pj/string.h>
@@ -107,8 +108,17 @@
 
     /**
-     * TLS cipher list string in OpenSSL format. If empty, then default
-     * cipher list of the backend will be used.
-     */
-    pj_str_t	ciphers;
+     * Number of ciphers contained in the specified cipher preference. 
+     * If this is set to zero, then default cipher list of the backend 
+     * will be used.
+     *
+     * Default: 0 (zero).
+     */
+    unsigned ciphers_num;
+
+    /**
+     * Ciphers and order preference. The #pj_ssl_cipher_get_availables()
+     * can be used to check the available ciphers supported by backend.
+     */
+    pj_ssl_cipher *ciphers;
 
     /**
@@ -247,5 +257,11 @@
     pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file);
     pj_strdup_with_null(pool, &dst->password, &src->password);
-    pj_strdup_with_null(pool, &dst->ciphers, &src->ciphers);
+    if (src->ciphers_num) {
+	unsigned i;
+	dst->ciphers = (pj_ssl_cipher*) pj_pool_calloc(pool, src->ciphers_num,
+						       sizeof(pj_ssl_cipher));
+	for (i=0; i<src->ciphers_num; ++i)
+	    dst->ciphers[i] = src->ciphers[i];
+    }
 }
 
Index: pjproject/branches/1.x/pjsip/src/pjsip/sip_transport_tls.c
===================================================================
--- pjproject/branches/1.x/pjsip/src/pjsip/sip_transport_tls.c	(revision 3941)
+++ pjproject/branches/1.x/pjsip/src/pjsip/sip_transport_tls.c	(revision 3942)
@@ -294,4 +294,6 @@
     if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)
 	ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;
+    ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
+    ssock_param.ciphers = listener->tls_setting.ciphers;
     ssock_param.qos_type = listener->tls_setting.qos_type;
     ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
@@ -863,5 +865,4 @@
     ssock_param.async_cnt = 1;
     ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt);
-    PJ_TODO(synchronize_tls_cipher_type_with_ssl_sock_cipher_type);
     ssock_param.server_name = remote_name;
     ssock_param.timeout = listener->tls_setting.timeout;
@@ -873,4 +874,6 @@
     if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)
 	ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;
+    ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
+    ssock_param.ciphers = listener->tls_setting.ciphers;
     ssock_param.qos_type = listener->tls_setting.qos_type;
     ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
