Ticket #1014: 1014-key_uses_cipher_code.diff

File 1014-key_uses_cipher_code.diff, 22.9 KB (added by nanang, 14 years ago)

implementation with cipher code as key, also has cipher names table

  • pjsip/include/pjsip/sip_transport_tls.h

     
    2626 */ 
    2727 
    2828#include <pjsip/sip_transport.h> 
     29#include <pj/pool.h> 
    2930#include <pj/ssl_sock.h> 
    3031#include <pj/string.h> 
    3132#include <pj/sock_qos.h> 
     
    106107    int         method; 
    107108 
    108109    /** 
    109      * TLS cipher list string in OpenSSL format. If empty, then default 
    110      * cipher list of the backend will be used. 
     110     * Number of ciphers contained in the specified cipher preference.  
     111     * If this is set to zero, then default cipher list of the backend  
     112     * will be used. 
     113     * 
     114     * Default: 0 (zero). 
    111115     */ 
    112     pj_str_t    ciphers; 
     116    unsigned ciphers_num; 
    113117 
    114118    /** 
    115      * Optionally specify the server name instance to be contacted when 
    116      * making outgoing TLS connection. This setting is useful when the 
    117      * server is hosting multiple domains for the same TLS listening 
    118      * socket. 
    119      * 
    120      * Default: empty. 
     119     * Ciphers and order preference. The #pj_ssl_cipher_get_availables() 
     120     * can be used to check the available ciphers supported by backend. 
    121121     */ 
    122     pj_str_t    server_name; 
     122    pj_ssl_cipher *ciphers; 
    123123 
    124124    /** 
    125125     * Specifies TLS transport behavior on the server TLS certificate  
     
    246246    pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file); 
    247247    pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file); 
    248248    pj_strdup_with_null(pool, &dst->password, &src->password); 
    249     pj_strdup_with_null(pool, &dst->ciphers, &src->ciphers); 
     249    if (src->ciphers_num) { 
     250        unsigned i; 
     251        dst->ciphers = (pj_ssl_cipher*) pj_pool_calloc(pool, src->ciphers_num, 
     252                                                       sizeof(pj_ssl_cipher)); 
     253        for (i=0; i<src->ciphers_num; ++i) 
     254            dst->ciphers[i] = src->ciphers[i]; 
     255    } 
    250256} 
    251257 
    252258 
  • pjsip/src/pjsip/sip_transport_tls.c

     
    293293        ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN; 
    294294    if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN) 
    295295        ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN; 
     296    ssock_param.ciphers_num = listener->tls_setting.ciphers_num; 
     297    ssock_param.ciphers = listener->tls_setting.ciphers; 
    296298    ssock_param.qos_type = listener->tls_setting.qos_type; 
    297299    ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error; 
    298300    pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params, 
     
    862864    ssock_param.cb.on_data_sent = &on_data_sent; 
    863865    ssock_param.async_cnt = 1; 
    864866    ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt); 
    865     PJ_TODO(synchronize_tls_cipher_type_with_ssl_sock_cipher_type); 
    866867    ssock_param.server_name = remote_name; 
    867868    ssock_param.timeout = listener->tls_setting.timeout; 
    868869    ssock_param.user_data = NULL; /* pending, must be set later */ 
     
    872873        ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN; 
    873874    if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN) 
    874875        ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN; 
     876    ssock_param.ciphers_num = listener->tls_setting.ciphers_num; 
     877    ssock_param.ciphers = listener->tls_setting.ciphers; 
    875878    ssock_param.qos_type = listener->tls_setting.qos_type; 
    876879    ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error; 
    877880    pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params, 
  • pjsip-apps/src/pjsua/pjsua_app.c

     
    234234    puts  ("                      May be specified multiple times"); 
    235235    puts  ("  --stun-srv=FORMAT   Set STUN server host or domain. This option may be"); 
    236236    puts  ("                      specified more than once. FORMAT is hostdom[:PORT]"); 
     237 
     238#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0) 
    237239    puts  (""); 
    238240    puts  ("TLS Options:"); 
    239241    puts  ("  --use-tls           Enable TLS transport (default=no)"); 
     
    244246    puts  ("  --tls-verify-server Verify server's certificate (default=no)"); 
    245247    puts  ("  --tls-verify-client Verify client's certificate (default=no)"); 
    246248    puts  ("  --tls-neg-timeout   Specify TLS negotiation timeout (default=no)"); 
    247     puts  ("  --tls-srv-name      Specify TLS server name for multi-hosting server (optional)"); 
     249    puts  ("  --tls-cipher        Specify prefered TLS cipher (optional)."); 
     250    puts  ("                      May be specified multiple times"); 
     251#endif 
    248252 
    249253    puts  (""); 
    250254    puts  ("Media Options:"); 
     
    509513           OPT_NEXT_ACCOUNT, OPT_NEXT_CRED, OPT_MAX_CALLS,  
    510514           OPT_DURATION, OPT_NO_TCP, OPT_NO_UDP, OPT_THREAD_CNT, 
    511515           OPT_NOREFERSUB, OPT_ACCEPT_REDIRECT, 
     516#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0) 
    512517           OPT_USE_TLS, OPT_TLS_CA_FILE, OPT_TLS_CERT_FILE, OPT_TLS_PRIV_FILE, 
    513518           OPT_TLS_PASSWORD, OPT_TLS_VERIFY_SERVER, OPT_TLS_VERIFY_CLIENT, 
    514            OPT_TLS_NEG_TIMEOUT, OPT_TLS_SRV_NAME, 
     519           OPT_TLS_NEG_TIMEOUT, OPT_TLS_CIPHER, 
     520#endif 
    515521           OPT_CAPTURE_DEV, OPT_PLAYBACK_DEV, 
    516522           OPT_CAPTURE_LAT, OPT_PLAYBACK_LAT, OPT_NO_TONES, OPT_JB_MAX_SIZE, 
    517523           OPT_STDOUT_REFRESH, OPT_STDOUT_REFRESH_TEXT, OPT_IPV6, OPT_QOS, 
     
    610616        { "max-calls",  1, 0, OPT_MAX_CALLS}, 
    611617        { "duration",   1, 0, OPT_DURATION}, 
    612618        { "thread-cnt", 1, 0, OPT_THREAD_CNT}, 
     619#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0) 
    613620        { "use-tls",    0, 0, OPT_USE_TLS},  
    614621        { "tls-ca-file",1, 0, OPT_TLS_CA_FILE}, 
    615622        { "tls-cert-file",1,0, OPT_TLS_CERT_FILE},  
     
    618625        { "tls-verify-server", 0, 0, OPT_TLS_VERIFY_SERVER}, 
    619626        { "tls-verify-client", 0, 0, OPT_TLS_VERIFY_CLIENT}, 
    620627        { "tls-neg-timeout", 1, 0, OPT_TLS_NEG_TIMEOUT}, 
    621         { "tls-srv-name", 1, 0, OPT_TLS_SRV_NAME}, 
     628        { "tls-cipher", 1, 0, OPT_TLS_CIPHER}, 
     629#endif 
    622630        { "capture-dev",    1, 0, OPT_CAPTURE_DEV}, 
    623631        { "playback-dev",   1, 0, OPT_PLAYBACK_DEV}, 
    624632        { "capture-lat",    1, 0, OPT_CAPTURE_LAT}, 
     
    12741282            } 
    12751283            break; 
    12761284 
     1285#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0) 
    12771286        case OPT_USE_TLS: 
    12781287            cfg->use_tls = PJ_TRUE; 
    1279 #if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
    1280             PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
    1281             return -1; 
    1282 #endif 
    12831288            break; 
    12841289             
    12851290        case OPT_TLS_CA_FILE: 
    12861291            cfg->udp_cfg.tls_setting.ca_list_file = pj_str(pj_optarg); 
    1287 #if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
    1288             PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
    1289             return -1; 
    1290 #endif 
    12911292            break; 
    12921293             
    12931294        case OPT_TLS_CERT_FILE: 
    12941295            cfg->udp_cfg.tls_setting.cert_file = pj_str(pj_optarg); 
    1295 #if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
    1296             PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
    1297             return -1; 
    1298 #endif 
    12991296            break; 
    13001297             
    13011298        case OPT_TLS_PRIV_FILE: 
     
    13041301 
    13051302        case OPT_TLS_PASSWORD: 
    13061303            cfg->udp_cfg.tls_setting.password = pj_str(pj_optarg); 
    1307 #if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
    1308             PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
    1309             return -1; 
    1310 #endif 
    13111304            break; 
    13121305 
    13131306        case OPT_TLS_VERIFY_SERVER: 
     
    13231316            cfg->udp_cfg.tls_setting.timeout.sec = atoi(pj_optarg); 
    13241317            break; 
    13251318 
    1326         case OPT_TLS_SRV_NAME: 
    1327             cfg->udp_cfg.tls_setting.server_name = pj_str(pj_optarg); 
     1319        case OPT_TLS_CIPHER: 
     1320            { 
     1321                pj_ssl_cipher cipher; 
     1322 
     1323                cipher = pj_ssl_cipher_id(pj_optarg); 
     1324                if (cipher != PJ_TLS_CIPHER_UNKNOWN) { 
     1325                    static pj_ssl_cipher tls_ciphers[128]; 
     1326                    static unsigned tls_ciphers_num = 0; 
     1327 
     1328                    tls_ciphers[tls_ciphers_num++] = cipher; 
     1329                    cfg->udp_cfg.tls_setting.ciphers_num = tls_ciphers_num; 
     1330                    cfg->udp_cfg.tls_setting.ciphers = tls_ciphers; 
     1331                } else { 
     1332                    /* The cipher is not supported */ 
     1333                    pj_ssl_cipher ciphers[128]; 
     1334                    unsigned j, ciphers_cnt; 
     1335 
     1336                    ciphers_cnt = PJ_ARRAY_SIZE(ciphers); 
     1337                    pj_ssl_cipher_get_availables(ciphers, &ciphers_cnt); 
     1338                    PJ_LOG(1,(THIS_FILE, "Cipher \"%s\" is not supported by " 
     1339                                         "TLS/SSL backend.", pj_optarg)); 
     1340                    puts("Supported TLS/SSL ciphers:"); 
     1341                    for (j=0; j<ciphers_cnt; ++j) 
     1342                        printf("- %s\n", pj_ssl_cipher_name(ciphers[j])); 
     1343                    return -1; 
     1344                } 
     1345            } 
    13281346            break; 
     1347#endif 
    13291348 
    13301349        case OPT_CAPTURE_DEV: 
    13311350            cfg->capture_dev = atoi(pj_optarg); 
     
    17421761        pj_strcat2(&cfg, line); 
    17431762    } 
    17441763 
     1764#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0) 
    17451765    /* TLS */ 
    17461766    if (config->use_tls) 
    17471767        pj_strcat2(&cfg, "--use-tls\n"); 
     
    17711791        pj_strcat2(&cfg, line); 
    17721792    } 
    17731793 
    1774     if (config->udp_cfg.tls_setting.server_name.slen) { 
    1775         pj_ansi_sprintf(line, "--tls-srv-name %.*s\n", 
    1776                         (int)config->udp_cfg.tls_setting.server_name.slen,  
    1777                         config->udp_cfg.tls_setting.server_name.ptr); 
    1778         pj_strcat2(&cfg, line); 
    1779     } 
    1780  
    17811794    if (config->udp_cfg.tls_setting.verify_server) 
    17821795        pj_strcat2(&cfg, "--tls-verify-server\n"); 
    17831796 
     
    17901803        pj_strcat2(&cfg, line); 
    17911804    } 
    17921805 
     1806    for (i=0; i<config->udp_cfg.tls_setting.ciphers_num; ++i) { 
     1807        pj_ansi_sprintf(line, "--tls-cipher %s\n", 
     1808                        pj_ssl_cipher_name(config->udp_cfg.tls_setting.ciphers[i])); 
     1809        pj_strcat2(&cfg, line); 
     1810    } 
     1811#endif 
     1812 
    17931813    pj_strcat2(&cfg, "\n#\n# Media settings:\n#\n"); 
    17941814 
    17951815    /* SRTP */ 
     
    29072927        const char *verif_msgs[32]; 
    29082928        unsigned verif_msg_cnt; 
    29092929 
    2910         /* Dump server TLS certificate */ 
    2911         pj_ssl_cert_info_dump(ssl_sock_info->remote_cert_info, "  ", 
    2912                               buf, sizeof(buf)); 
    2913         PJ_LOG(4,(THIS_FILE, "TLS cert info of %s:\n%s", host_port, buf)); 
     2930        /* Dump server TLS cipher */ 
     2931        PJ_LOG(4,(THIS_FILE, "TLS cipher used: %s", 
     2932                  pj_ssl_cipher_name(ssl_sock_info->cipher))); 
    29142933 
    2915         /* Dump server TLS certificate verification result */ 
    2916         verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs); 
    2917         pj_ssl_cert_get_verify_status_strings(ssl_sock_info->verify_status, 
    2918                                               verif_msgs, &verif_msg_cnt); 
    2919         PJ_LOG(3,(THIS_FILE, "TLS cert verification result of %s : %s", 
    2920                              host_port, 
    2921                              (verif_msg_cnt == 1? verif_msgs[0]:""))); 
    2922         if (verif_msg_cnt > 1) { 
    2923             unsigned i; 
    2924             for (i = 0; i < verif_msg_cnt; ++i) 
    2925                 PJ_LOG(3,(THIS_FILE, "- %s", verif_msgs[i])); 
    2926         } 
     2934        /* Dump server TLS certificate and the verification result, if any */ 
     2935        if (ssl_sock_info->remote_cert_info && 
     2936            ssl_sock_info->remote_cert_info->subject.info.slen) 
     2937        { 
     2938            /* Dump server TLS certificate */ 
     2939            pj_ssl_cert_info_dump(ssl_sock_info->remote_cert_info, "  ", 
     2940                                  buf, sizeof(buf)); 
     2941            PJ_LOG(4,(THIS_FILE, "TLS cert info of %s:\n%s", host_port, buf)); 
    29272942 
    2928         if (ssl_sock_info->verify_status && 
    2929             !app_config.udp_cfg.tls_setting.verify_server)  
    2930         { 
    2931             PJ_LOG(3,(THIS_FILE, "PJSUA is configured to ignore TLS cert " 
    2932                                  "verification errors")); 
     2943            /* Dump server TLS certificate verification result */ 
     2944            verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs); 
     2945            pj_ssl_cert_get_verify_status_strings(ssl_sock_info->verify_status, 
     2946                                                  verif_msgs, &verif_msg_cnt); 
     2947            PJ_LOG(3,(THIS_FILE, "TLS cert verification result of %s : %s", 
     2948                                 host_port, 
     2949                                 (verif_msg_cnt == 1? verif_msgs[0]:""))); 
     2950            if (verif_msg_cnt > 1) { 
     2951                unsigned i; 
     2952                for (i = 0; i < verif_msg_cnt; ++i) 
     2953                    PJ_LOG(3,(THIS_FILE, "- %s", verif_msgs[i])); 
     2954            } 
     2955 
     2956            if (ssl_sock_info->verify_status && 
     2957                !app_config.udp_cfg.tls_setting.verify_server)  
     2958            { 
     2959                PJ_LOG(3,(THIS_FILE, "PJSUA is configured to ignore TLS cert " 
     2960                                     "verification errors")); 
     2961            } 
    29332962        } 
    29342963    } 
    29352964 
  • pjlib/include/pj/ssl_sock.h

     
    246246    /* NULL */ 
    247247    PJ_TLS_NULL_WITH_NULL_NULL                  = 0x00000000, 
    248248 
     249    /* UNKNOWN */ 
     250    PJ_TLS_CIPHER_UNKNOWN                       = 0xFFFFFFFF, 
     251 
    249252    /* TLS/SSLv3 */ 
    250253    PJ_TLS_RSA_WITH_NULL_MD5                    = 0x00000001, 
    251254    PJ_TLS_RSA_WITH_NULL_SHA                    = 0x00000002, 
     
    336339 * 
    337340 * @param cipher        The cipher. 
    338341 * 
    339  * @return              The cipher name or NULL if cipher is not recognized. 
     342 * @return              The cipher name or NULL if cipher is not recognized/ 
     343 *                      supported. 
    340344 */ 
    341345PJ_DECL(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher); 
    342346 
    343347 
    344348/** 
     349 * Get cipher ID from cipher name string. 
     350 * 
     351 * @param cipher_name   The cipher name string. 
     352 * 
     353 * @return              The cipher ID or PJ_TLS_UNKNOWN_CIPHER if the cipher 
     354 *                      name string is not recognized/supported. 
     355 */ 
     356PJ_DECL(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name); 
     357 
     358 
     359/** 
     360 * Internal function to resolve the generic/standard cipher name. 
     361 * 
     362 * @param cipher        The cipher. 
     363 * 
     364 * @return              The cipher name or NULL if cipher is not recognized. 
     365 */ 
     366const char* pj_ssl_cipher_generic_name(pj_ssl_cipher cipher); 
     367 
     368 
     369/** 
     370 * Internal function to resolve generic/standard cipher ID. 
     371 * 
     372 * @param cipher_name   The cipher name string. 
     373 * 
     374 * @return              The cipher ID or PJ_TLS_UNKNOWN_CIPHER if the cipher 
     375 *                      name string is not recognized. 
     376 */ 
     377pj_ssl_cipher pj_ssl_cipher_generic_id(const char *cipher_name); 
     378 
     379 
     380/** 
    345381 * This structure contains the callbacks to be called by the secure socket. 
    346382 */ 
    347383typedef struct pj_ssl_sock_cb 
  • pjlib/src/pj/ssl_sock_ossl.c

     
    270270static int openssl_reg_strerr; 
    271271 
    272272/* OpenSSL available ciphers */ 
    273 static pj_ssl_cipher openssl_ciphers[100]; 
    274273static unsigned openssl_cipher_num; 
     274static struct openssl_ciphers_t { 
     275    pj_ssl_cipher    id; 
     276    const char      *name; 
     277} openssl_ciphers[100]; 
    275278 
    276279/* OpenSSL application data index */ 
    277280static int sslsock_idx; 
     
    330333 
    331334        for (i = 0; i < n; ++i) { 
    332335            SSL_CIPHER *c; 
     336            const char *name; 
    333337            c = sk_SSL_CIPHER_value(sk_cipher,i); 
    334             openssl_ciphers[i] = (pj_ssl_cipher) 
    335                                  (pj_uint32_t)c->id & 0x00FFFFFF; 
    336             //printf("%3u: %08x=%s\n", i+1, c->id, SSL_CIPHER_get_name(c)); 
     338            openssl_ciphers[i].id = (pj_ssl_cipher) 
     339                                    (pj_uint32_t)c->id & 0x00FFFFFF; 
     340            name = pj_ssl_cipher_generic_name(openssl_ciphers[i].id); 
     341            if (name == NULL) 
     342                name = SSL_CIPHER_get_name(c); 
     343            openssl_ciphers[i].name = name; 
    337344        } 
    338345 
    339346        SSL_free(ssl); 
     
    17051712        shutdown_openssl(); 
    17061713    } 
    17071714 
    1708     if (openssl_cipher_num == 0) 
     1715    if (openssl_cipher_num == 0) { 
     1716        *cipher_num = 0; 
    17091717        return PJ_ENOTFOUND; 
     1718    } 
    17101719 
    17111720    *cipher_num = PJ_MIN(*cipher_num, openssl_cipher_num); 
    17121721 
    17131722    for (i = 0; i < *cipher_num; ++i) 
    1714         ciphers[i] = openssl_ciphers[i]; 
     1723        ciphers[i] = openssl_ciphers[i].id; 
    17151724 
    17161725    return PJ_SUCCESS; 
    17171726} 
    17181727 
    17191728 
     1729/* Get cipher name string */ 
     1730PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher) 
     1731{ 
     1732    unsigned i; 
     1733 
     1734    if (openssl_cipher_num == 0) { 
     1735        init_openssl(); 
     1736        shutdown_openssl(); 
     1737    } 
     1738 
     1739    for (i = 0; i < openssl_cipher_num; ++i) { 
     1740        if (cipher == openssl_ciphers[i].id) 
     1741            return openssl_ciphers[i].name; 
     1742    } 
     1743 
     1744    return NULL; 
     1745} 
     1746 
     1747 
     1748/* Get cipher from cipher name string. */ 
     1749PJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name) 
     1750{ 
     1751    unsigned i; 
     1752 
     1753    if (openssl_cipher_num == 0) { 
     1754        init_openssl(); 
     1755        shutdown_openssl(); 
     1756    } 
     1757 
     1758    for (i = 0; i < openssl_cipher_num; ++i) { 
     1759        if (pj_ansi_stricmp(cipher_name, openssl_ciphers[i].name)==0) 
     1760            return openssl_ciphers[i].id; 
     1761    } 
     1762 
     1763    return PJ_TLS_CIPHER_UNKNOWN; 
     1764} 
     1765 
     1766 
    17201767/* 
    17211768 * Create SSL socket instance.  
    17221769 */ 
  • pjlib/src/pj/ssl_sock_symbian.cpp

     
    115115 
    116116    int Connect(CPjSSLSocket_cb cb, void *key, const TInetAddr &local_addr,  
    117117                const TInetAddr &rem_addr,  
    118                 const TDesC8 &servername = TPtrC8(NULL,0)); 
     118                const TDesC8 &servername = TPtrC8(NULL,0), 
     119                const TDesC8 &ciphers = TPtrC8(NULL,0)); 
    119120    int Send(CPjSSLSocket_cb cb, void *key, const TDesC8 &aDesc, TUint flags); 
    120121    int SendSync(const TDesC8 &aDesc, TUint flags); 
    121122 
     
    146147    TBuf<32>             ssl_proto_; 
    147148    TInetAddr            rem_addr_; 
    148149    TPtrC8               servername_; 
     150    TPtrC8               ciphers_; 
    149151    TInetAddr            local_addr_; 
    150152    TSockXfrLength       sent_len_; 
    151153 
     
    186188int CPjSSLSocket::Connect(CPjSSLSocket_cb cb, void *key,  
    187189                          const TInetAddr &local_addr,  
    188190                          const TInetAddr &rem_addr, 
    189                           const TDesC8 &servername) 
     191                          const TDesC8 &servername, 
     192                          const TDesC8 &ciphers) 
    190193{ 
    191194    pj_status_t status; 
    192195     
     
    213216    cb_ = cb; 
    214217    key_ = key; 
    215218    rem_addr_ = rem_addr; 
     219     
     220    /* Note: the following members only keep the pointer, not the data */ 
    216221    servername_.Set(servername); 
     222    ciphers_.Set(ciphers); 
     223 
    217224    rSock.Connect(rem_addr_, iStatus); 
    218225    SetActive(); 
    219226    state_ = SSL_STATE_CONNECTING; 
     
    318325            if (servername_.Length() > 0) 
    319326                securesock_->SetOpt(KSoSSLDomainName, KSolInetSSL, 
    320327                                    servername_); 
     328            if (ciphers_.Length() > 0) 
     329                securesock_->SetAvailableCipherSuites(ciphers_); 
    321330 
    322331            // FlushSessionCache() seems to also fire signals to all  
    323332            // completed AOs (something like CActiveScheduler::RunIfReady()) 
     
    441450 
    442451    pj_ssl_sock_proto    proto; 
    443452    pj_time_val          timeout; 
    444     unsigned             ciphers_num; 
    445     pj_ssl_cipher       *ciphers; 
    446453    pj_str_t             servername; 
     454    pj_str_t             ciphers; 
    447455    pj_ssl_cert_info     remote_cert_info; 
    448456}; 
    449457 
     
    579587} 
    580588 
    581589 
     590/* Available ciphers */ 
     591static unsigned ciphers_num_ = 0; 
     592static struct ciphers_t 
     593{ 
     594    pj_ssl_cipher    id; 
     595    const char      *name; 
     596} ciphers_[64]; 
     597 
    582598/* 
    583599 * Get cipher list supported by SSL/TLS backend. 
    584600 */ 
    585601PJ_DEF(pj_status_t) pj_ssl_cipher_get_availables (pj_ssl_cipher ciphers[], 
    586602                                                  unsigned *cipher_num) 
    587603{ 
    588     /* Available ciphers */ 
    589     static pj_ssl_cipher ciphers_[64]; 
    590     static unsigned ciphers_num_ = 0; 
    591604    unsigned i; 
    592605 
    593606    PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL); 
     
    605618            ciphers_num_ = ciphers_buf.Length() / 2; 
    606619            if (ciphers_num_ > PJ_ARRAY_SIZE(ciphers_)) 
    607620                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]); 
     621            for (i = 0; i < ciphers_num_; ++i) { 
     622                ciphers_[i].id = (pj_ssl_cipher)(ciphers_buf[i*2]*10 +  
     623                                                 ciphers_buf[i*2+1]); 
     624                ciphers_[i].name = pj_ssl_cipher_generic_name(ciphers_[i].id); 
     625            } 
    611626        } 
    612627         
    613628        delete secure_sock; 
    614629    } 
    615630     
    616631    if (ciphers_num_ == 0) { 
     632        *cipher_num = 0; 
    617633        return PJ_ENOTFOUND; 
    618634    } 
    619635     
    620636    *cipher_num = PJ_MIN(*cipher_num, ciphers_num_); 
    621637    for (i = 0; i < *cipher_num; ++i) 
    622         ciphers[i] = ciphers_[i]; 
     638        ciphers[i] = ciphers_[i].id; 
    623639     
    624640    return PJ_SUCCESS; 
    625641} 
    626642 
     643 
     644/* Get cipher name string */ 
     645PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher) 
     646{ 
     647    unsigned i; 
     648 
     649    if (ciphers_num_ == 0) { 
     650        pj_ssl_cipher c[1]; 
     651        i = 0; 
     652        pj_ssl_cipher_get_availables(c, &i); 
     653    } 
     654         
     655    for (i = 0; i < ciphers_num_; ++i) { 
     656        if (cipher == ciphers_[i].id) 
     657            return ciphers_[i].name; 
     658    } 
     659 
     660    return NULL; 
     661} 
     662 
     663 
     664/* Get cipher ID from cipher name string. */ 
     665PJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name) 
     666{ 
     667    unsigned i; 
     668 
     669    if (ciphers_num_ == 0) { 
     670        pj_ssl_cipher c[1]; 
     671        i = 0; 
     672        pj_ssl_cipher_get_availables(c, &i); 
     673    } 
     674 
     675    for (i = 0; i < ciphers_num_; ++i) { 
     676        if (pj_ansi_stricmp(cipher_name, ciphers_[i].name)==0) 
     677            return ciphers_[i].id; 
     678    } 
     679 
     680    return PJ_TLS_CIPHER_UNKNOWN; 
     681} 
     682 
     683 
    627684/* 
    628685 * Create SSL socket instance.  
    629686 */ 
     
    652709    ssock->cb = param->cb; 
    653710    ssock->user_data = param->user_data; 
    654711    ssock->timeout = param->timeout; 
    655     ssock->ciphers_num = param->ciphers_num; 
    656712    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]; 
     713        /* Cipher list in Symbian is represented as array of two-octets. */ 
     714        ssock->ciphers.slen = param->ciphers_num*2; 
     715        ssock->ciphers.ptr  = (char*)pj_pool_alloc(pool, ssock->ciphers.slen); 
     716        pj_uint8_t *c = (pj_uint8_t*)ssock->ciphers.ptr; 
     717        for (unsigned i = 0; i < param->ciphers_num; ++i) { 
     718            *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF00) >> 8; 
     719            *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF); 
     720        } 
    663721    } 
    664722    pj_strdup_with_null(pool, &ssock->servername, &param->server_name); 
    665723 
     
    782840        /* Cipher suite */ 
    783841        TBuf8<4> cipher; 
    784842        if (ssock->sock->GetCipher(cipher) == KErrNone) { 
    785             info->cipher = (pj_ssl_cipher)cipher[1];  
     843            info->cipher = (pj_ssl_cipher)(cipher[0]*10+cipher[1]);  
    786844        } 
    787845 
    788846        /* Remote address */ 
     
    12521310    TPtrC8 servername_((TUint8*)ssock->servername.ptr,  
    12531311                       ssock->servername.slen); 
    12541312     
     1313    /* Convert cipher list to Symbian descriptor */ 
     1314    TPtrC8 ciphers_((TUint8*)ssock->ciphers.ptr,  
     1315                    ssock->ciphers.slen); 
     1316     
    12551317    /* Try to connect */ 
    12561318    status = sock->Connect(&connect_cb, ssock, localaddr_, remaddr_, 
    1257                            servername_); 
     1319                           servername_, ciphers_); 
    12581320    if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
    12591321        delete sock; 
    12601322        return status; 
  • pjlib/src/pj/ssl_sock_common.c

     
    129129} 
    130130 
    131131 
    132 /* Get cipher name string */ 
    133 PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher) 
     132/* Get generic/standard cipher name string */ 
     133const char* pj_ssl_cipher_generic_name(pj_ssl_cipher cipher) 
    134134{ 
    135135    unsigned i, n; 
    136136 
     
    144144} 
    145145 
    146146 
     147/* Get generic/standard cipher ID from cipher name string. */ 
     148pj_ssl_cipher pj_ssl_cipher_generic_id(const char *cipher_name) 
     149{ 
     150    unsigned i, n; 
    147151 
     152    n = PJ_ARRAY_SIZE(cipher_names); 
     153    for (i = 0; i < n; ++i) { 
     154        if (pj_ansi_stricmp(cipher_name, cipher_names[i].name)==0) 
     155            return cipher_names[i].cipher; 
     156    } 
    148157 
     158    return PJ_TLS_CIPHER_UNKNOWN; 
     159} 
     160 
     161 
    149162PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings( 
    150163                                                pj_uint32_t verify_status,  
    151164                                                const char *error_strings[], 
  • pjsip-apps/src/symbian_ua/ua.cpp

     
    5858#define ENABLE_SIP_TCP  0 // experimental 
    5959#define ENABLE_SIP_TLS  0 // experimental 
    6060 
    61 #define TLS_SRV_NAME    "pjsip.org"     // TLS servername (required for 
    62                                         // TLS transport) 
    63  
    6461// 
    6562// Configure nameserver if DNS SRV is to be used with both SIP 
    6663// or STUN (for STUN see other settings below)