Ignore:
Timestamp:
Mar 15, 2018 3:00:59 AM (6 years ago)
Author:
nanang
Message:

Close #2100:

  • Added new APIs:
    • PJMEDIA: pjmedia_srtp_enum_crypto(), pjmedia_srtp_enum_keying()
    • PJSUA: pjsua_config.srtp_opt, pjsua_acc_config.srtp_opt, pjsua_srtp_opt_default()
    • PJSUA2: AccountMediaConfig::srtpOpt, Endpoint::srtpCryptoEnum()
  • Deprecated PJSUA callback on_create_media_transport_srtp() (not removed yet, just warnings).
  • Slightly refactored SRTP code:
    • Fixed potential issue with on_create_media_transport_srtp(), some PJSUA internal values in pjmedia_srtp_setting may be overridden by app.
    • Fixed few issues in SRTP and keying mechanism, e.g: premature local SDP modification (it should be done after verification).
    • Potential minor backward compatibility issue: default value of pjmedia_srtp_setting.crypto_count is now zero, previously it was initialized with all crypto via pjmedia_srtp_setting_default(), actually zero and all cryptos in this setting semantically are the same.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/transport_srtp_sdes.c

    r5749 r5755  
    278278    PJ_UNUSED_ARG(sdp_pool); 
    279279 
     280    /* Verify remote media transport, it has to be RTP/AVP or RTP/SAVP */ 
     281    if (!srtp->offerer_side) { 
     282        pjmedia_sdp_media *m = sdp_remote->media[media_index]; 
     283        if (pj_stricmp(&m->desc.transport, &ID_RTP_AVP)  != 0 && 
     284            pj_stricmp(&m->desc.transport, &ID_RTP_SAVP) != 0) 
     285        { 
     286            return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     287        } 
     288    } 
     289 
    280290    /* Validations */ 
    281291    if (srtp->offerer_side) { 
     
    284294        pjmedia_sdp_media *m_rem = sdp_remote->media[media_index]; 
    285295 
    286         /* Nothing to do on inactive media stream */ 
    287         if (pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)) 
    288             srtp->bypass_srtp = PJ_TRUE; 
    289  
    290296        /* Validate remote media transport based on SRTP usage option. */ 
    291297        switch (srtp->setting.use) { 
     
    293299                if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 
    294300                    return PJMEDIA_SRTP_ESDPINTRANSPORT; 
    295                 srtp->bypass_srtp = PJ_TRUE; 
    296301                break; 
    297302            case PJMEDIA_SRTP_OPTIONAL: 
     
    326331    m_loc = sdp_local->media[media_index]; 
    327332 
    328     /* Bypass SDES if media transport is not RTP/AVP or RTP/SAVP */ 
    329     if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP)  != 0 && 
    330         pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0) 
     333    /* Verify media transport, it has to be RTP/AVP or RTP/SAVP */ 
    331334    { 
    332         return PJ_SUCCESS; 
     335        pjmedia_sdp_media *m = sdp_remote? m_rem : m_loc; 
     336        if (pj_stricmp(&m->desc.transport, &ID_RTP_AVP)  != 0 && 
     337            pj_stricmp(&m->desc.transport, &ID_RTP_SAVP) != 0) 
     338        { 
     339            return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     340        } 
    333341    } 
    334342 
     
    353361        switch (srtp->setting.use) { 
    354362            case PJMEDIA_SRTP_DISABLED: 
    355                 pj_assert(!"Shouldn't reach here"); 
     363                /* Should never reach here */ 
    356364                return PJ_SUCCESS; 
    357365            case PJMEDIA_SRTP_OPTIONAL: 
     
    407415        switch (srtp->setting.use) { 
    408416            case PJMEDIA_SRTP_DISABLED: 
     417                /* Should never reach here */ 
    409418                if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 
    410419                    return PJMEDIA_SRTP_ESDPINTRANSPORT; 
    411420                return PJ_SUCCESS; 
    412421            case PJMEDIA_SRTP_OPTIONAL: 
    413                 m_loc->desc.transport = m_rem->desc.transport; 
    414422                break; 
    415423            case PJMEDIA_SRTP_MANDATORY: 
    416424                if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0) 
    417425                    return PJMEDIA_SRTP_ESDPINTRANSPORT; 
    418                 m_loc->desc.transport = ID_RTP_SAVP; 
    419426                break; 
    420427        } 
     
    480487            switch (srtp->setting.use) { 
    481488                case PJMEDIA_SRTP_DISABLED: 
    482                     pj_assert(!"Should never reach here"); 
     489                    /* Should never reach here */ 
    483490                    break; 
    484491 
     
    536543            /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 
    537544        } 
     545 
     546        /* Update transport description in local media SDP */ 
     547        m_loc->desc.transport = m_rem->desc.transport; 
    538548    } 
    539549 
     
    590600    pjmedia_srtp_crypto loc_crypto[PJMEDIA_SRTP_MAX_CRYPTOS]; 
    591601    int loc_cryto_cnt = PJMEDIA_SRTP_MAX_CRYPTOS; 
     602    pjmedia_srtp_crypto tmp_tx_crypto; 
     603    pj_bool_t has_crypto_attr = PJ_FALSE; 
     604    int rem_tag; 
     605    int j; 
     606 
    592607 
    593608    m_rem = sdp_remote->media[media_index]; 
    594609    m_loc = sdp_local->media[media_index]; 
     610 
     611    /* Verify media transport, it has to be RTP/AVP or RTP/SAVP */ 
     612    if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP)  != 0 && 
     613        pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0) 
     614    { 
     615        return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     616    } 
    595617 
    596618    if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 
     
    599621        srtp->peer_use = PJMEDIA_SRTP_OPTIONAL; 
    600622 
    601     /* For answerer side, this function will just have to start SRTP */ 
     623    /* For answerer side, this function will just have to start SRTP as 
     624     * SRTP crypto policies have been populated in media_encode_sdp(). 
     625     */ 
     626    if (!srtp->offerer_side) 
     627        return PJ_SUCCESS; 
    602628 
    603629    /* Check remote media transport & set local media transport 
    604630     * based on SRTP usage option. 
    605631     */ 
    606     if (srtp->offerer_side) { 
    607         if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
    608             if (pjmedia_sdp_media_find_attr(m_rem, &ID_CRYPTO, NULL)) { 
    609                 DEACTIVATE_MEDIA(pool, m_loc); 
    610                 return PJMEDIA_SRTP_ESDPINCRYPTO; 
    611             } 
     632    if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
     633        if (pjmedia_sdp_media_find_attr(m_rem, &ID_CRYPTO, NULL)) { 
     634            DEACTIVATE_MEDIA(pool, m_loc); 
     635            return PJMEDIA_SRTP_ESDPINCRYPTO; 
     636        } 
     637        return PJ_SUCCESS; 
     638    } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
     639        // Regardless the answer's transport type (RTP/AVP or RTP/SAVP), 
     640        // the answer must be processed through in optional mode. 
     641        // Please note that at this point transport type is ensured to be 
     642        // RTP/AVP or RTP/SAVP, see sdes_media_create() 
     643        //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) { 
     644            //DEACTIVATE_MEDIA(pool, m_loc); 
     645            //return PJMEDIA_SDP_EINPROTO; 
     646        //} 
     647        fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt); 
     648    } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
     649        if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) { 
     650            DEACTIVATE_MEDIA(pool, m_loc); 
     651            return PJMEDIA_SDP_EINPROTO; 
     652        } 
     653        fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt); 
     654    } 
     655 
     656    /* find supported crypto-suite, get the tag, and assign policy_local */ 
     657    for (i=0; i<m_rem->attr_count; ++i) { 
     658        if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 
     659            continue; 
     660 
     661        /* more than one crypto attribute in media answer */ 
     662        if (has_crypto_attr) { 
     663            DEACTIVATE_MEDIA(pool, m_loc); 
     664            return PJMEDIA_SRTP_ESDPAMBIGUEANS; 
     665        } 
     666 
     667        has_crypto_attr = PJ_TRUE; 
     668 
     669        status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 
     670                                   &tmp_tx_crypto, &rem_tag); 
     671        if (status != PJ_SUCCESS) 
     672            return status; 
     673 
     674 
     675        /* Tag range check, our tags in the offer must be in the SRTP  
     676         * setting range, so does the remote answer's. The remote answer's  
     677         * tag must not exceed the tag range of the local offer. 
     678         */ 
     679        if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count || 
     680            rem_tag > loc_cryto_cnt)  
     681        { 
     682            DEACTIVATE_MEDIA(pool, m_loc); 
     683            return PJMEDIA_SRTP_ESDPINCRYPTOTAG; 
     684        } 
     685 
     686        /* match the crypto name */ 
     687        if (pj_stricmp(&tmp_tx_crypto.name, &loc_crypto[rem_tag-1].name)) 
     688        { 
     689            DEACTIVATE_MEDIA(pool, m_loc); 
     690            return PJMEDIA_SRTP_ECRYPTONOTMATCH; 
     691        } 
     692 
     693        /* Find the crypto from the setting. */ 
     694        for (j = 0; j < (int)srtp->setting.crypto_count; ++j) { 
     695            if (pj_stricmp(&tmp_tx_crypto.name,  
     696                           &srtp->setting.crypto[j].name) == 0)  
     697            { 
     698                srtp->tx_policy_neg = srtp->setting.crypto[j]; 
     699                break; 
     700            }            
     701        } 
     702 
     703        srtp->rx_policy_neg = tmp_tx_crypto; 
     704    } 
     705 
     706    if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
     707        /* should never reach here */ 
     708        return PJ_SUCCESS; 
     709    } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
     710        if (!has_crypto_attr) 
    612711            return PJ_SUCCESS; 
    613         } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
    614             // Regardless the answer's transport type (RTP/AVP or RTP/SAVP), 
    615             // the answer must be processed through in optional mode. 
    616             // Please note that at this point transport type is ensured to be 
    617             // RTP/AVP or RTP/SAVP, see sdes_media_create() 
    618             //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) { 
    619                 //DEACTIVATE_MEDIA(pool, m_loc); 
    620                 //return PJMEDIA_SDP_EINPROTO; 
    621             //} 
    622             fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt); 
    623         } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
    624             if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) { 
    625                 DEACTIVATE_MEDIA(pool, m_loc); 
    626                 return PJMEDIA_SDP_EINPROTO; 
    627             } 
    628             fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt); 
    629         } 
    630     } 
    631  
    632     if (srtp->offerer_side) { 
    633         /* find supported crypto-suite, get the tag, and assign policy_local */ 
    634         pjmedia_srtp_crypto tmp_tx_crypto; 
    635         pj_bool_t has_crypto_attr = PJ_FALSE; 
    636         int rem_tag; 
    637         int j; 
    638  
    639         for (i=0; i<m_rem->attr_count; ++i) { 
    640             if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 
    641                 continue; 
    642  
    643             /* more than one crypto attribute in media answer */ 
    644             if (has_crypto_attr) { 
    645                 DEACTIVATE_MEDIA(pool, m_loc); 
    646                 return PJMEDIA_SRTP_ESDPAMBIGUEANS; 
    647             } 
    648  
    649             has_crypto_attr = PJ_TRUE; 
    650  
    651             status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 
    652                                        &tmp_tx_crypto, &rem_tag); 
    653             if (status != PJ_SUCCESS) 
    654                 return status; 
    655  
    656  
    657             /* Tag range check, our tags in the offer must be in the SRTP  
    658              * setting range, so does the remote answer's. The remote answer's  
    659              * tag must not exceed the tag range of the local offer. 
    660              */ 
    661             if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count || 
    662                 rem_tag > loc_cryto_cnt)  
    663             { 
    664                 DEACTIVATE_MEDIA(pool, m_loc); 
    665                 return PJMEDIA_SRTP_ESDPINCRYPTOTAG; 
    666             } 
    667  
    668             /* match the crypto name */ 
    669             if (pj_stricmp(&tmp_tx_crypto.name, &loc_crypto[rem_tag-1].name)) 
    670             { 
    671                 DEACTIVATE_MEDIA(pool, m_loc); 
    672                 return PJMEDIA_SRTP_ECRYPTONOTMATCH; 
    673             } 
    674  
    675             /* Find the crypto from the setting. */ 
    676             for (j = 0; j < (int)srtp->setting.crypto_count; ++j) { 
    677                 if (pj_stricmp(&tmp_tx_crypto.name,  
    678                                &srtp->setting.crypto[j].name) == 0)  
    679                 { 
    680                     srtp->tx_policy_neg = srtp->setting.crypto[j]; 
    681                     break; 
    682                 }                
    683             } 
    684  
    685             srtp->rx_policy_neg = tmp_tx_crypto; 
    686         } 
    687  
    688         if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
    689             /* should never reach here */ 
    690             return PJ_SUCCESS; 
    691         } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
    692             if (!has_crypto_attr) 
    693                 return PJ_SUCCESS; 
    694         } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
    695             if (!has_crypto_attr) { 
    696                 DEACTIVATE_MEDIA(pool, m_loc); 
    697                 return PJMEDIA_SRTP_ESDPREQCRYPTO; 
    698             } 
    699         } 
    700  
    701         /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 
    702     } 
     712    } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
     713        if (!has_crypto_attr) { 
     714            DEACTIVATE_MEDIA(pool, m_loc); 
     715            return PJMEDIA_SRTP_ESDPREQCRYPTO; 
     716        } 
     717    } 
     718 
     719    /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 
    703720 
    704721    return PJ_SUCCESS; 
Note: See TracChangeset for help on using the changeset viewer.