Ignore:
Timestamp:
Jan 16, 2012 5:05:47 AM (13 years ago)
Author:
nanang
Message:

Close #1014:

  • Added configurable ciphers setting in SIP TLS transport and pjsua app.
  • Added API pj_ssl_cipher_is_supported().
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/1.x/pjlib/src/pj/ssl_sock_symbian.cpp

    r3553 r3942  
    3333#define THIS_FILE "ssl_sock_symbian.cpp" 
    3434 
     35 
     36/* Cipher name structure */ 
     37typedef struct cipher_name_t { 
     38    pj_ssl_cipher    cipher; 
     39    const char      *name; 
     40} cipher_name_t; 
     41 
     42/* Cipher name constants */ 
     43static cipher_name_t cipher_names[] = 
     44{ 
     45    {PJ_TLS_NULL_WITH_NULL_NULL,               "NULL"}, 
     46 
     47    /* TLS/SSLv3 */ 
     48    {PJ_TLS_RSA_WITH_NULL_MD5,                 "TLS_RSA_WITH_NULL_MD5"}, 
     49    {PJ_TLS_RSA_WITH_NULL_SHA,                 "TLS_RSA_WITH_NULL_SHA"}, 
     50    {PJ_TLS_RSA_WITH_NULL_SHA256,              "TLS_RSA_WITH_NULL_SHA256"}, 
     51    {PJ_TLS_RSA_WITH_RC4_128_MD5,              "TLS_RSA_WITH_RC4_128_MD5"}, 
     52    {PJ_TLS_RSA_WITH_RC4_128_SHA,              "TLS_RSA_WITH_RC4_128_SHA"}, 
     53    {PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA,         "TLS_RSA_WITH_3DES_EDE_CBC_SHA"}, 
     54    {PJ_TLS_RSA_WITH_AES_128_CBC_SHA,          "TLS_RSA_WITH_AES_128_CBC_SHA"}, 
     55    {PJ_TLS_RSA_WITH_AES_256_CBC_SHA,          "TLS_RSA_WITH_AES_256_CBC_SHA"}, 
     56    {PJ_TLS_RSA_WITH_AES_128_CBC_SHA256,       "TLS_RSA_WITH_AES_128_CBC_SHA256"}, 
     57    {PJ_TLS_RSA_WITH_AES_256_CBC_SHA256,       "TLS_RSA_WITH_AES_256_CBC_SHA256"}, 
     58    {PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,      "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"}, 
     59    {PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,      "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"}, 
     60    {PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,     "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"}, 
     61    {PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,     "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"}, 
     62    {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA,       "TLS_DH_DSS_WITH_AES_128_CBC_SHA"}, 
     63    {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA,       "TLS_DH_RSA_WITH_AES_128_CBC_SHA"}, 
     64    {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,      "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"}, 
     65    {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"}, 
     66    {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA,       "TLS_DH_DSS_WITH_AES_256_CBC_SHA"}, 
     67    {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA,       "TLS_DH_RSA_WITH_AES_256_CBC_SHA"}, 
     68    {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,      "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"}, 
     69    {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"}, 
     70    {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,    "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"}, 
     71    {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,    "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"}, 
     72    {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,   "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"}, 
     73    {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,   "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"}, 
     74    {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,    "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"}, 
     75    {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,    "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"}, 
     76    {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,   "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"}, 
     77    {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,   "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"}, 
     78    {PJ_TLS_DH_anon_WITH_RC4_128_MD5,          "TLS_DH_anon_WITH_RC4_128_MD5"}, 
     79    {PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,     "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"}, 
     80    {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA,      "TLS_DH_anon_WITH_AES_128_CBC_SHA"}, 
     81    {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA,      "TLS_DH_anon_WITH_AES_256_CBC_SHA"}, 
     82    {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256,   "TLS_DH_anon_WITH_AES_128_CBC_SHA256"}, 
     83    {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256,   "TLS_DH_anon_WITH_AES_256_CBC_SHA256"}, 
     84 
     85    /* TLS (deprecated) */ 
     86    {PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5,        "TLS_RSA_EXPORT_WITH_RC4_40_MD5"}, 
     87    {PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,    "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"}, 
     88    {PJ_TLS_RSA_WITH_IDEA_CBC_SHA,             "TLS_RSA_WITH_IDEA_CBC_SHA"}, 
     89    {PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,     "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"}, 
     90    {PJ_TLS_RSA_WITH_DES_CBC_SHA,              "TLS_RSA_WITH_DES_CBC_SHA"}, 
     91    {PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,  "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"}, 
     92    {PJ_TLS_DH_DSS_WITH_DES_CBC_SHA,           "TLS_DH_DSS_WITH_DES_CBC_SHA"}, 
     93    {PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,  "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"}, 
     94    {PJ_TLS_DH_RSA_WITH_DES_CBC_SHA,           "TLS_DH_RSA_WITH_DES_CBC_SHA"}, 
     95    {PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"}, 
     96    {PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA,          "TLS_DHE_DSS_WITH_DES_CBC_SHA"}, 
     97    {PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"}, 
     98    {PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA,          "TLS_DHE_RSA_WITH_DES_CBC_SHA"}, 
     99    {PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,    "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"}, 
     100    {PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"}, 
     101    {PJ_TLS_DH_anon_WITH_DES_CBC_SHA,          "TLS_DH_anon_WITH_DES_CBC_SHA"}, 
     102 
     103    /* SSLv3 */ 
     104    {PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA,        "SSL_FORTEZZA_KEA_WITH_NULL_SHA"}, 
     105    {PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA,"SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"}, 
     106    {PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA,     "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"}, 
     107 
     108    /* SSLv2 */ 
     109    {PJ_SSL_CK_RC4_128_WITH_MD5,               "SSL_CK_RC4_128_WITH_MD5"}, 
     110    {PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5,      "SSL_CK_RC4_128_EXPORT40_WITH_MD5"}, 
     111    {PJ_SSL_CK_RC2_128_CBC_WITH_MD5,           "SSL_CK_RC2_128_CBC_WITH_MD5"}, 
     112    {PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,  "SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5"}, 
     113    {PJ_SSL_CK_IDEA_128_CBC_WITH_MD5,          "SSL_CK_IDEA_128_CBC_WITH_MD5"}, 
     114    {PJ_SSL_CK_DES_64_CBC_WITH_MD5,            "SSL_CK_DES_64_CBC_WITH_MD5"}, 
     115    {PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5,      "SSL_CK_DES_192_EDE3_CBC_WITH_MD5"} 
     116}; 
     117 
     118 
     119/* Get cipher name string */ 
     120static const char* get_cipher_name(pj_ssl_cipher cipher) 
     121{ 
     122    unsigned i, n; 
     123 
     124    n = PJ_ARRAY_SIZE(cipher_names); 
     125    for (i = 0; i < n; ++i) { 
     126       if (cipher == cipher_names[i].cipher) 
     127           return cipher_names[i].name; 
     128    } 
     129 
     130    return "CIPHER_UNKNOWN"; 
     131} 
     132 
    35133typedef void (*CPjSSLSocket_cb)(int err, void *key); 
    36134 
     
    116214    int Connect(CPjSSLSocket_cb cb, void *key, const TInetAddr &local_addr,  
    117215                const TInetAddr &rem_addr,  
    118                 const TDesC8 &servername = TPtrC8(NULL,0)); 
     216                const TDesC8 &servername = TPtrC8(NULL,0), 
     217                const TDesC8 &ciphers = TPtrC8(NULL,0)); 
    119218    int Send(CPjSSLSocket_cb cb, void *key, const TDesC8 &aDesc, TUint flags); 
    120219    int SendSync(const TDesC8 &aDesc, TUint flags); 
     
    147246    TInetAddr            rem_addr_; 
    148247    TPtrC8               servername_; 
     248    TPtrC8               ciphers_; 
    149249    TInetAddr            local_addr_; 
    150250    TSockXfrLength       sent_len_; 
     
    187287                          const TInetAddr &local_addr,  
    188288                          const TInetAddr &rem_addr, 
    189                           const TDesC8 &servername) 
     289                          const TDesC8 &servername, 
     290                          const TDesC8 &ciphers) 
    190291{ 
    191292    pj_status_t status; 
     
    214315    key_ = key; 
    215316    rem_addr_ = rem_addr; 
     317     
     318    /* Note: the following members only keep the pointer, not the data */ 
    216319    servername_.Set(servername); 
     320    ciphers_.Set(ciphers); 
     321 
    217322    rSock.Connect(rem_addr_, iStatus); 
    218323    SetActive(); 
     
    319424                securesock_->SetOpt(KSoSSLDomainName, KSolInetSSL, 
    320425                                    servername_); 
     426            if (ciphers_.Length() > 0) 
     427                securesock_->SetAvailableCipherSuites(ciphers_); 
    321428 
    322429            // FlushSessionCache() seems to also fire signals to all  
     
    442549    pj_ssl_sock_proto    proto; 
    443550    pj_time_val          timeout; 
    444     unsigned             ciphers_num; 
    445     pj_ssl_cipher       *ciphers; 
    446551    pj_str_t             servername; 
     552    pj_str_t             ciphers; 
    447553    pj_ssl_cert_info     remote_cert_info; 
    448554}; 
     
    580686 
    581687 
     688/* Available ciphers */ 
     689static unsigned ciphers_num_ = 0; 
     690static struct ciphers_t 
     691{ 
     692    pj_ssl_cipher    id; 
     693    const char      *name; 
     694} ciphers_[64]; 
     695 
    582696/* 
    583697 * Get cipher list supported by SSL/TLS backend. 
     
    586700                                                  unsigned *cipher_num) 
    587701{ 
    588     /* Available ciphers */ 
    589     static pj_ssl_cipher ciphers_[64]; 
    590     static unsigned ciphers_num_ = 0; 
    591702    unsigned i; 
    592703 
     
    606717            if (ciphers_num_ > PJ_ARRAY_SIZE(ciphers_)) 
    607718                ciphers_num_ = PJ_ARRAY_SIZE(ciphers_); 
    608             for (i = 0; i < ciphers_num_; ++i) 
    609                 ciphers_[i] = (pj_ssl_cipher)(ciphers_buf[i*2]*10 +  
    610                                               ciphers_buf[i*2+1]); 
     719            for (i = 0; i < ciphers_num_; ++i) { 
     720                ciphers_[i].id = (pj_ssl_cipher)(ciphers_buf[i*2]*10 +  
     721                                                 ciphers_buf[i*2+1]); 
     722                ciphers_[i].name = get_cipher_name(ciphers_[i].id); 
     723            } 
    611724        } 
    612725         
     
    615728     
    616729    if (ciphers_num_ == 0) { 
     730        *cipher_num = 0; 
    617731        return PJ_ENOTFOUND; 
    618732    } 
     
    620734    *cipher_num = PJ_MIN(*cipher_num, ciphers_num_); 
    621735    for (i = 0; i < *cipher_num; ++i) 
    622         ciphers[i] = ciphers_[i]; 
     736        ciphers[i] = ciphers_[i].id; 
    623737     
    624738    return PJ_SUCCESS; 
    625739} 
     740 
     741 
     742/* Get cipher name string */ 
     743PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher) 
     744{ 
     745    unsigned i; 
     746 
     747    if (ciphers_num_ == 0) { 
     748        pj_ssl_cipher c[1]; 
     749        i = 0; 
     750        pj_ssl_cipher_get_availables(c, &i); 
     751    } 
     752         
     753    for (i = 0; i < ciphers_num_; ++i) { 
     754        if (cipher == ciphers_[i].id) 
     755            return ciphers_[i].name; 
     756    } 
     757 
     758    return NULL; 
     759} 
     760 
     761 
     762/* Check if the specified cipher is supported by SSL/TLS backend. */ 
     763PJ_DEF(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher) 
     764{ 
     765    unsigned i; 
     766 
     767    if (ciphers_num_ == 0) { 
     768        pj_ssl_cipher c[1]; 
     769        i = 0; 
     770        pj_ssl_cipher_get_availables(c, &i); 
     771    } 
     772         
     773    for (i = 0; i < ciphers_num_; ++i) { 
     774        if (cipher == ciphers_[i].id) 
     775            return PJ_TRUE; 
     776    } 
     777 
     778    return PJ_FALSE; 
     779} 
     780 
    626781 
    627782/* 
     
    653808    ssock->user_data = param->user_data; 
    654809    ssock->timeout = param->timeout; 
    655     ssock->ciphers_num = param->ciphers_num; 
    656810    if (param->ciphers_num > 0) { 
    657         unsigned i; 
    658         ssock->ciphers = (pj_ssl_cipher*) 
    659                          pj_pool_calloc(pool, param->ciphers_num,  
    660                                         sizeof(pj_ssl_cipher)); 
    661         for (i = 0; i < param->ciphers_num; ++i) 
    662             ssock->ciphers[i] = param->ciphers[i]; 
     811        /* Cipher list in Symbian is represented as array of two-octets. */ 
     812        ssock->ciphers.slen = param->ciphers_num*2; 
     813        ssock->ciphers.ptr  = (char*)pj_pool_alloc(pool, ssock->ciphers.slen); 
     814        pj_uint8_t *c = (pj_uint8_t*)ssock->ciphers.ptr; 
     815        for (unsigned i = 0; i < param->ciphers_num; ++i) { 
     816            *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF00) >> 8; 
     817            *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF); 
     818        } 
    663819    } 
    664820    pj_strdup_with_null(pool, &ssock->servername, &param->server_name); 
     
    12471403                       ssock->servername.slen); 
    12481404     
     1405    /* Convert cipher list to Symbian descriptor */ 
     1406    TPtrC8 ciphers_((TUint8*)ssock->ciphers.ptr,  
     1407                    ssock->ciphers.slen); 
     1408     
    12491409    /* Try to connect */ 
    12501410    status = sock->Connect(&connect_cb, ssock, localaddr_, remaddr_, 
    1251                            servername_); 
     1411                           servername_, ciphers_); 
    12521412    if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
    12531413        delete sock; 
Note: See TracChangeset for help on using the changeset viewer.