Changeset 1722


Ignore:
Timestamp:
Jan 21, 2008 6:08:47 PM (12 years ago)
Author:
nanang
Message:

Ticket #452:

  • Bug fixed in mandatory mode, change local media sdp transport from RTP/AVP to RTP/SAVP
  • Bug fixed for setting libsrtp flags (no encrypt, no auth)
  • Changed log level & messages
  • Put some more comments
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/users/nanang/pjmedia/src/pjmedia/transport_srtp.c

    r1721 r1722  
    4242static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 }; 
    4343static const pj_str_t ID_INACTIVE = { "inactive", 8 }; 
     44static const pj_str_t ID_CRYPTO   = { "crypto", 6 }; 
    4445 
    4546typedef struct crypto_suite 
     
    243244    int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]); 
    244245     
     246    /* treat unspecified crypto_name as crypto 'NULL' */ 
    245247    if (crypto_name->slen == 0) 
    246248        return 0; 
     
    301303            /* check key length */ 
    302304            if (opt->crypto[i].key.slen &&  
    303                 opt->crypto[i].key.slen < crypto_suites[cs_idx].cipher_key_len) 
     305                opt->crypto[i].key.slen <  
     306                (pj_ssize_t)crypto_suites[cs_idx].cipher_key_len) 
    304307                return PJMEDIA_SRTP_EINKEYLEN; 
    305308        } 
     
    384387    crypto_suites_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]); 
    385388 
    386     /* Check whether the crypto-suite requested is supported */ 
     389    /* Get encryption and authentication method */ 
    387390    cr_tx_idx = au_tx_idx = get_crypto_idx(&tx->name); 
    388391    if (tx->flags && PJMEDIA_SRTP_NO_ENCRYPTION) 
     
    391394        au_tx_idx = 0; 
    392395 
    393     /* Check whether the crypto-suite requested is supported */ 
    394396    cr_rx_idx = au_rx_idx = get_crypto_idx(&rx->name); 
    395397    if (rx->flags && PJMEDIA_SRTP_NO_ENCRYPTION) 
     
    398400        au_rx_idx = 0; 
    399401 
    400     if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 || au_rx_idx == -1) 
     402    /* Check whether the crypto-suite requested is supported */ 
     403    if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 ||  
     404        au_rx_idx == -1) 
    401405        return PJMEDIA_SRTP_ENOTSUPCRYPTO; 
    402406 
     407    /* If all options points to 'NULL' method, just bypass SRTP */ 
    403408    if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) { 
    404409        srtp->bypass_srtp = PJ_TRUE; 
     
    406411    } 
    407412 
     413    /* Check key length */ 
     414    if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len || 
     415        rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len) 
     416        return PJMEDIA_SRTP_EINKEYLEN; 
     417 
    408418    /* Init transmit direction */ 
    409419    pj_bzero(&tx_, sizeof(srtp_policy_t)); 
    410420    pj_memmove(srtp->tx_key, tx->key.ptr, tx->key.slen); 
     421    if (cr_tx_idx && au_tx_idx) 
     422        tx_.rtp.sec_serv    = sec_serv_conf_and_auth; 
     423    else if (cr_tx_idx) 
     424        tx_.rtp.sec_serv    = sec_serv_conf; 
     425    else if (au_tx_idx) 
     426        tx_.rtp.sec_serv    = sec_serv_auth; 
     427    else 
     428        tx_.rtp.sec_serv    = sec_serv_none; 
    411429    tx_.key                 = (uint8_t*)srtp->tx_key; 
    412430    tx_.ssrc.type           = ssrc_any_outbound; 
    413431    tx_.ssrc.value          = 0; 
    414     tx_.rtp.sec_serv        = crypto_suites[cr_tx_idx].service; 
    415432    tx_.rtp.cipher_type     = crypto_suites[cr_tx_idx].cipher_type; 
    416433    tx_.rtp.cipher_key_len  = crypto_suites[cr_tx_idx].cipher_key_len; 
     
    434451    pj_bzero(&rx_, sizeof(srtp_policy_t)); 
    435452    pj_memmove(srtp->rx_key, rx->key.ptr, rx->key.slen); 
     453    if (cr_rx_idx && au_rx_idx) 
     454        rx_.rtp.sec_serv    = sec_serv_conf_and_auth; 
     455    else if (cr_rx_idx) 
     456        rx_.rtp.sec_serv    = sec_serv_conf; 
     457    else if (au_rx_idx) 
     458        rx_.rtp.sec_serv    = sec_serv_auth; 
     459    else 
     460        rx_.rtp.sec_serv    = sec_serv_none; 
    436461    rx_.key                 = (uint8_t*)srtp->rx_key; 
    437462    rx_.ssrc.type           = ssrc_any_inbound; 
     
    774799    } 
    775800 
    776     if (crypto->key.slen != (int)crypto_suites[cs_idx].cipher_key_len) 
     801    if (crypto->key.slen != (pj_ssize_t)crypto_suites[cs_idx].cipher_key_len) 
    777802        return PJMEDIA_SRTP_EINKEYLEN; 
    778803 
     
    817842    token = strtok(input.ptr, " "); 
    818843    if (!token) { 
    819         PJ_LOG(5,(THIS_FILE, "Expecting tag")); 
     844        PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag")); 
    820845        return PJMEDIA_SDP_EINATTR; 
    821846    } 
     
    827852    token = strtok(NULL, " "); 
    828853    if (!token) { 
    829         PJ_LOG(5,(THIS_FILE, "Expecting crypto suite")); 
     854        PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite")); 
    830855        return PJMEDIA_SDP_EINATTR; 
    831856    } 
     
    835860    token = strtok(NULL, ":"); 
    836861    if (!token) { 
    837         PJ_LOG(5,(THIS_FILE, "Expecting key method")); 
     862        PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method")); 
    838863        return PJMEDIA_SDP_EINATTR; 
    839864    } 
    840865    if (pj_ansi_stricmp(token, "inline")) { 
    841         PJ_LOG(5,(THIS_FILE, "Key method %s not supported!", token)); 
     866        PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%s' not supported!", 
     867                  token)); 
    842868        return PJMEDIA_SDP_EINATTR; 
    843869    } 
     
    846872    token = strtok(NULL, "| "); 
    847873    if (!token) { 
    848         PJ_LOG(5,(THIS_FILE, "Expecting key")); 
     874        PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key")); 
    849875        return PJMEDIA_SDP_EINATTR; 
    850876    } 
     
    857883                              &itmp); 
    858884    if (status != PJ_SUCCESS) { 
    859         PJ_LOG(5,(THIS_FILE, "Failed decoding key from base64")); 
     885        PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64")); 
    860886        return status; 
    861887    } 
     
    927953                return PJMEDIA_SRTP_ESDPINTRANSPORT; 
    928954            } 
     955            m_loc->desc.transport = ID_RTP_SAVP; 
    929956        } 
    930957    } 
     
    944971            if (buffer_len) { 
    945972                pj_strset(&attr_value, buffer, buffer_len); 
    946                 attr = pjmedia_sdp_attr_create(pool, "crypto", &attr_value); 
     973                attr = pjmedia_sdp_attr_create(pool, ID_CRYPTO.ptr,  
     974                                               &attr_value); 
    947975                m_loc->attr[m_loc->attr_count++] = attr; 
    948976            } 
     
    954982        pj_bool_t has_match = PJ_FALSE; 
    955983        int chosen_tag = 0; 
    956         int tags[8]; 
    957         int cr_count = 0; 
     984        int tags[64]; /* assume no more than 64 crypto attrs in a media */ 
     985        int cr_attr_count = 0; 
    958986        int k; 
    959987 
    960988        for (i=0; i<m_rem->attr_count; ++i) { 
    961             if (pj_stricmp2(&m_rem->attr[i]->name, "crypto") != 0) 
     989            if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 
    962990                continue; 
    963991 
    964992            /* SRTP is disabled but there is crypto attr in remote media */ 
     993            /* Put the checking here to save a bit memory for parsing */ 
    965994            if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
    966995                DEACTIVATE_MEDIA(pool, m_loc); 
     
    9711000 
    9721001            status = parse_attr_crypto(pool, m_rem->attr[i],  
    973                                        &tmp_rx_crypto, &tags[cr_count]); 
     1002                                       &tmp_rx_crypto, &tags[cr_attr_count]); 
    9741003            if (status != PJ_SUCCESS) 
    9751004                return status; 
    9761005          
    9771006            /* Check duplicated tag */ 
    978             for (k=0; k<cr_count; ++k) { 
    979                 if (tags[k] == tags[cr_count]) { 
     1007            for (k=0; k<cr_attr_count; ++k) { 
     1008                if (tags[k] == tags[cr_attr_count]) { 
    9801009                    DEACTIVATE_MEDIA(pool, m_loc); 
    9811010                    return PJMEDIA_SRTP_ESDPDUPCRYPTOTAG; 
     
    9971026                        srtp->tx_policy = srtp->setting.crypto[j]; 
    9981027                        srtp->rx_policy = tmp_rx_crypto; 
    999                         chosen_tag = tags[cr_count]; 
     1028                        chosen_tag = tags[cr_attr_count]; 
    10001029                        has_match = PJ_TRUE; 
    10011030                        break; 
    10021031                    } 
    10031032            } 
    1004             cr_count++; 
     1033            cr_attr_count++; 
    10051034        } 
    10061035 
     
    10181047                goto BYPASS_SRTP; 
    10191048        } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
    1020             if (!has_crypto_attr) { 
    1021                 DEACTIVATE_MEDIA(pool, m_loc); 
    1022                 return PJMEDIA_SRTP_ESDPREQCRYPTO; 
    1023             } 
    1024         } 
    1025  
    1026         /* No crypto match? */ 
     1049            /* do nothing, this is intended */ 
     1050        } 
     1051 
     1052        /* No crypto attr */ 
     1053        if (!has_crypto_attr) { 
     1054            DEACTIVATE_MEDIA(pool, m_loc); 
     1055            return PJMEDIA_SRTP_ESDPREQCRYPTO; 
     1056        } 
     1057 
     1058        /* No crypto match */ 
    10271059        if (!has_match) { 
    10281060            DEACTIVATE_MEDIA(pool, m_loc); 
     
    10441076        if (buffer_len) { 
    10451077            pj_strset(&attr_value, buffer, buffer_len); 
    1046             attr = pjmedia_sdp_attr_create(pool, "crypto", &attr_value); 
     1078            attr = pjmedia_sdp_attr_create(pool, ID_CRYPTO.ptr, &attr_value); 
    10471079            m_loc->attr[m_loc->attr_count++] = attr; 
    10481080        } 
     
    10911123    if (srtp->offerer_side) { 
    10921124        if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
    1093             if (pjmedia_sdp_media_find_attr2(m_rem, "crypto", NULL)) { 
     1125            if (pjmedia_sdp_media_find_attr(m_rem, &ID_CRYPTO, NULL)) { 
    10941126                DEACTIVATE_MEDIA(pool, m_loc); 
    10951127                return PJMEDIA_SRTP_ESDPINCRYPTO; 
     
    11161148 
    11171149        for (i=0; i<m_rem->attr_count; ++i) { 
    1118             if (pj_stricmp2(&m_rem->attr[i]->name, "crypto") != 0) 
     1150            if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 
    11191151                continue; 
    11201152 
Note: See TracChangeset for help on using the changeset viewer.