diff options
Diffstat (limited to 'pjlib/src/pj')
-rw-r--r-- | pjlib/src/pj/ssl_sock_common.c | 100 | ||||
-rw-r--r-- | pjlib/src/pj/ssl_sock_ossl.c | 57 | ||||
-rw-r--r-- | pjlib/src/pj/ssl_sock_symbian.cpp | 198 |
3 files changed, 230 insertions, 125 deletions
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, ¶m->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; |