Changeset 4728 for pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c
- Timestamp:
- Feb 4, 2014 10:13:56 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c
r4723 r4728 1 1 /* $Id$ */ 2 /* 2 /* 3 3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) 4 4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> … … 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 … … 46 46 #define MAX_KEY_LEN 128 47 47 48 /* Initial value of probation counter. When probation counter > 0, 48 /* Initial value of probation counter. When probation counter > 0, 49 49 * it means SRTP is in probation state, and it may restart when 50 50 * srtp_unprotect() returns err_status_replay_* … … 77 77 78 78 /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 10 octets */ 79 {"AES_CM_128_HMAC_SHA1_80", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10, 79 {"AES_CM_128_HMAC_SHA1_80", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10, 80 80 sec_serv_conf_and_auth}, 81 81 … … 84 84 sec_serv_conf_and_auth}, 85 85 86 /* 86 /* 87 87 * F8_128_HMAC_SHA1_8 not supported by libsrtp? 88 88 * {"F8_128_HMAC_SHA1_8", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none} … … 125 125 void *pkt, 126 126 pj_ssize_t size); 127 127 128 128 /* Transport information */ 129 129 pjmedia_transport *member_tp; /**< Underlying transport. */ … … 131 131 /* SRTP usage policy of peer. This field is updated when media is starting. 132 132 * This is useful when SRTP is in optional mode and peer is using mandatory 133 * mode, so when local is about to reinvite/update, it should offer 133 * mode, so when local is about to reinvite/update, it should offer 134 134 * RTP/SAVP instead of offering RTP/AVP. 135 135 */ 136 136 pjmedia_srtp_use peer_use; 137 137 138 /* When probation counter > 0, it means SRTP is in probation state, 138 /* When probation counter > 0, it means SRTP is in probation state, 139 139 * and it may restart when srtp_unprotect() returns err_status_replay_* 140 140 */ … … 206 206 207 207 208 static pjmedia_transport_op transport_srtp_op = 208 static pjmedia_transport_op transport_srtp_op = 209 209 { 210 210 &transport_get_info, … … 239 239 "couldn't deallocate properly", /* err_status_dealloc_fail = 4 */ 240 240 "couldn't initialize", /* err_status_init_fail = 5 */ 241 "can't process as much data as requested", 241 "can't process as much data as requested", 242 242 /* err_status_terminus = 6 */ 243 243 "authentication failure", /* err_status_auth_fail = 7 */ 244 244 "cipher failure", /* err_status_cipher_fail = 8 */ 245 245 "replay check failed (bad index)", /* err_status_replay_fail = 9 */ 246 "replay check failed (index too old)", 246 "replay check failed (index too old)", 247 247 /* err_status_replay_old = 10 */ 248 248 "algorithm failed test routine", /* err_status_algo_fail = 11 */ 249 249 "unsupported operation", /* err_status_no_such_op = 12 */ 250 250 "no appropriate context found", /* err_status_no_ctx = 13 */ 251 "unable to perform desired validation", 251 "unable to perform desired validation", 252 252 /* err_status_cant_check = 14 */ 253 253 "can't use key any more", /* err_status_key_expired = 15 */ … … 286 286 287 287 err = srtp_init(); 288 if (err != err_status_ok) { 289 PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s", 288 if (err != err_status_ok) { 289 PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s", 290 290 get_libsrtp_errstr(err))); 291 291 return PJMEDIA_ERRNO_FROM_LIBSRTP(err); … … 294 294 if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS) 295 295 { 296 /* There will be memory leak when it fails to schedule libsrtp 296 /* There will be memory leak when it fails to schedule libsrtp 297 297 * deinitialization, however the memory leak could be harmless, 298 * since in modern OS's memory used by an application is released 298 * since in modern OS's memory used by an application is released 299 299 * when the application terminates. 300 300 */ … … 307 307 PJ_UNUSED_ARG(endpt); 308 308 #endif 309 309 310 310 return PJ_SUCCESS; 311 311 } … … 338 338 #endif 339 339 if (err != err_status_ok) { 340 PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s", 340 PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s", 341 341 get_libsrtp_errstr(err))); 342 342 } … … 350 350 int i; 351 351 int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]); 352 352 353 353 /* treat unspecified crypto_name as crypto 'NULL' */ 354 354 if (crypto_name->slen == 0) … … 421 421 422 422 /* Check crypto availability */ 423 if (opt && opt->crypto_count == 0 && 423 if (opt && opt->crypto_count == 0 && 424 424 opt->use == PJMEDIA_SRTP_MANDATORY) 425 425 return PJMEDIA_SRTP_ESDPREQCRYPTO; … … 435 435 436 436 /* check key length */ 437 if (opt->crypto[i].key.slen && 438 opt->crypto[i].key.slen < 437 if (opt->crypto[i].key.slen && 438 opt->crypto[i].key.slen < 439 439 (pj_ssize_t)crypto_suites[cs_idx].cipher_key_len) 440 440 return PJMEDIA_SRTP_EINKEYLEN; … … 506 506 */ 507 507 PJ_DEF(pj_status_t) pjmedia_transport_srtp_start( 508 pjmedia_transport *tp, 508 pjmedia_transport *tp, 509 509 const pjmedia_srtp_crypto *tx, 510 510 const pjmedia_srtp_crypto *rx) … … 518 518 int cr_rx_idx = 0; 519 519 int au_rx_idx = 0; 520 int crypto_suites_cnt;521 520 pj_status_t status = PJ_SUCCESS; 522 521 … … 528 527 pjmedia_transport_srtp_stop(tp); 529 528 } 530 531 crypto_suites_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);532 529 533 530 /* Get encryption and authentication method */ … … 545 542 546 543 /* Check whether the crypto-suite requested is supported */ 547 if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 || 544 if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 || 548 545 au_rx_idx == -1) 549 546 { … … 648 645 else 649 646 b64[b64_len] = '\0'; 650 647 651 648 PJ_LOG(5, (srtp->pool->obj_name, "TX: %s key=%s", 652 649 srtp->tx_policy.name.ptr, b64)); … … 700 697 err = srtp_dealloc(p_srtp->srtp_rx_ctx); 701 698 if (err != err_status_ok) { 702 PJ_LOG(4, (p_srtp->pool->obj_name, 699 PJ_LOG(4, (p_srtp->pool->obj_name, 703 700 "Failed to dealloc RX SRTP context: %s", 704 701 get_libsrtp_errstr(err))); … … 706 703 err = srtp_dealloc(p_srtp->srtp_tx_ctx); 707 704 if (err != err_status_ok) { 708 PJ_LOG(4, (p_srtp->pool->obj_name, 705 PJ_LOG(4, (p_srtp->pool->obj_name, 709 706 "Failed to dealloc TX SRTP context: %s", 710 707 get_libsrtp_errstr(err))); … … 753 750 info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_SRTP; 754 751 info->spc_info[spc_info_idx].cbsize = sizeof(srtp_info); 755 pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info, 752 pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info, 756 753 sizeof(srtp_info)); 757 754 … … 782 779 783 780 /* Attach itself to transport */ 784 status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr, 781 status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr, 785 782 rem_rtcp, addr_len, &srtp_rtp_cb, 786 783 &srtp_rtcp_cb); … … 842 839 843 840 if (err == err_status_ok) { 844 status = pjmedia_transport_send_rtp(srtp->member_tp, 841 status = pjmedia_transport_send_rtp(srtp->member_tp, 845 842 srtp->rtp_tx_buffer, len); 846 843 } else { 847 844 status = PJMEDIA_ERRNO_FROM_LIBSRTP(err); 848 845 } 849 846 850 847 return status; 851 848 } … … 870 867 871 868 if (srtp->bypass_srtp) { 872 return pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len, 869 return pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len, 873 870 pkt, size); 874 871 } … … 903 900 { 904 901 transport_srtp *srtp = (transport_srtp *) tp; 905 902 906 903 PJ_ASSERT_RETURN(tp, PJ_EINVAL); 907 904 … … 965 962 } 966 963 err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); 967 if (srtp->probation_cnt > 0 && 968 (err == err_status_replay_old || err == err_status_replay_fail)) 964 if (srtp->probation_cnt > 0 && 965 (err == err_status_replay_old || err == err_status_replay_fail)) 969 966 { 970 967 /* Handle such condition that stream is updated (RTP seq is reinited 971 * & SRTP is restarted), but some old packets are still coming 968 * & SRTP is restarted), but some old packets are still coming 972 969 * so SRTP is learning wrong RTP seq. While the newly inited RTP seq 973 * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect() 970 * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect() 974 971 * will return err_status_replay_*. Restarting SRTP can resolve this. 975 972 */ … … 982 979 &tx, &rx); 983 980 if (status != PJ_SUCCESS) { 984 PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s", 981 PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s", 985 982 get_libsrtp_errstr(err))); 986 983 } else if (!srtp->bypass_srtp) { … … 990 987 991 988 if (err != err_status_ok) { 992 PJ_LOG(5,(srtp->pool->obj_name, 993 "Failed to unprotect SRTP, pkt size=%d, err=%s", 989 PJ_LOG(5,(srtp->pool->obj_name, 990 "Failed to unprotect SRTP, pkt size=%d, err=%s", 994 991 size, get_libsrtp_errstr(err))); 995 992 } else { … … 1036 1033 err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); 1037 1034 if (err != err_status_ok) { 1038 PJ_LOG(5,(srtp->pool->obj_name, 1035 PJ_LOG(5,(srtp->pool->obj_name, 1039 1036 "Failed to unprotect SRTCP, pkt size=%d, err=%s", 1040 1037 size, get_libsrtp_errstr(err))); … … 1056 1053 */ 1057 1054 static pj_status_t generate_crypto_attr_value(pj_pool_t *pool, 1058 char *buffer, int *buffer_len, 1055 char *buffer, int *buffer_len, 1059 1056 pjmedia_srtp_crypto *crypto, 1060 1057 int tag) … … 1088 1085 key_ok = PJ_TRUE; 1089 1086 1090 err = crypto_get_random((unsigned char*)key, 1087 err = crypto_get_random((unsigned char*)key, 1091 1088 crypto_suites[cs_idx].cipher_key_len); 1092 1089 if (err != err_status_ok) { … … 1100 1097 } while (!key_ok); 1101 1098 crypto->key.ptr = (char*) 1102 pj_pool_zalloc(pool, 1099 pj_pool_zalloc(pool, 1103 1100 crypto_suites[cs_idx].cipher_key_len); 1104 1101 pj_memcpy(crypto->key.ptr, key, crypto_suites[cs_idx].cipher_key_len); … … 1118 1115 1119 1116 b64_key[b64_key_len] = '\0'; 1120 1117 1121 1118 PJ_ASSERT_RETURN(*buffer_len >= (crypto->name.slen + \ 1122 1119 b64_key_len + 16), PJ_ETOOSMALL); … … 1124 1121 /* Print the crypto attribute value. */ 1125 1122 print_len = pj_ansi_snprintf(buffer, *buffer_len, "%d %s inline:%s", 1126 tag, 1123 tag, 1127 1124 crypto_suites[cs_idx].name, 1128 1125 b64_key); … … 1206 1203 crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN); 1207 1204 itmp = MAX_KEY_LEN; 1208 status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr, 1205 status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr, 1209 1206 &itmp); 1210 1207 if (status != PJ_SUCCESS) { … … 1227 1224 1228 1225 PJ_ASSERT_RETURN(tp, PJ_EINVAL); 1229 1226 1230 1227 pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg)); 1231 1228 pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg)); … … 1275 1272 1276 1273 PROPAGATE_MEDIA_CREATE: 1277 return pjmedia_transport_media_create(srtp->member_tp, sdp_pool, 1274 return pjmedia_transport_media_create(srtp->member_tp, sdp_pool, 1278 1275 member_tp_option, sdp_remote, 1279 1276 media_index); … … 1297 1294 1298 1295 PJ_ASSERT_RETURN(tp && sdp_pool && sdp_local, PJ_EINVAL); 1299 1296 1300 1297 pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg)); 1301 1298 pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg)); … … 1307 1304 1308 1305 /* Bypass if media transport is not RTP/AVP or RTP/SAVP */ 1309 if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) != 0 && 1306 if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) != 0 && 1310 1307 pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0) 1311 1308 goto BYPASS_SRTP; … … 1318 1315 */ 1319 1316 /* 1320 if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) || 1317 if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) || 1321 1318 (m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL))) 1322 1319 goto BYPASS_SRTP; 1323 1320 */ 1324 1321 1325 /* Check remote media transport & set local media transport 1322 /* Check remote media transport & set local media transport 1326 1323 * based on SRTP usage option. 1327 1324 */ … … 1333 1330 goto BYPASS_SRTP; 1334 1331 case PJMEDIA_SRTP_OPTIONAL: 1335 m_loc->desc.transport = 1332 m_loc->desc.transport = 1336 1333 (srtp->peer_use == PJMEDIA_SRTP_MANDATORY)? 1337 1334 ID_RTP_SAVP : ID_RTP_AVP; … … 1356 1353 if (buffer_len) { 1357 1354 pj_strset(&attr_value, buffer, buffer_len); 1358 attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr, 1355 attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr, 1359 1356 &attr_value); 1360 1357 m_loc->attr[m_loc->attr_count++] = attr; … … 1401 1398 has_crypto_attr = PJ_TRUE; 1402 1399 1403 status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 1400 status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 1404 1401 &tmp_rx_crypto, &tags[cr_attr_count]); 1405 1402 if (status != PJ_SUCCESS) 1406 1403 return status; 1407 1404 1408 1405 /* Check duplicated tag */ 1409 1406 for (j=0; j<cr_attr_count; ++j) { … … 1417 1414 /* lets see if the crypto-suite offered is supported */ 1418 1415 for (j=0; j<srtp->setting.crypto_count; ++j) 1419 if (pj_stricmp(&tmp_rx_crypto.name, 1416 if (pj_stricmp(&tmp_rx_crypto.name, 1420 1417 &srtp->setting.crypto[j].name) == 0) 1421 1418 { … … 1434 1431 // hex_test_key, 1435 1432 // strlen(hex_test_key)); 1436 //pj_strset(test_key, raw_test_key, 1433 //pj_strset(test_key, raw_test_key, 1437 1434 // crypto_suites[cs_idx].cipher_key_len); 1438 1435 /* EO Force to use test key */ 1439 1436 1440 if (tmp_rx_crypto.key.slen != 1437 if (tmp_rx_crypto.key.slen != 1441 1438 (int)crypto_suites[cs_idx].cipher_key_len) 1442 1439 return PJMEDIA_SRTP_EINKEYLEN; … … 1459 1456 case PJMEDIA_SRTP_OPTIONAL: 1460 1457 /* bypass SRTP when no crypto-attr and remote uses RTP/AVP */ 1461 if (!has_crypto_attr && 1458 if (!has_crypto_attr && 1462 1459 pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 1463 1460 goto BYPASS_SRTP; 1464 1461 /* bypass SRTP when nothing match and remote uses RTP/AVP */ 1465 else if (matched_idx == -1 && 1462 else if (matched_idx == -1 && 1466 1463 pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 1467 1464 goto BYPASS_SRTP; … … 1485 1482 } 1486 1483 1487 /* we have to generate crypto answer, 1484 /* we have to generate crypto answer, 1488 1485 * with srtp->tx_policy_neg matched the offer 1489 1486 * and rem_tag contains matched offer tag. … … 1497 1494 1498 1495 srtp->tx_policy_neg = srtp->setting.crypto[matched_idx]; 1499 1496 1500 1497 /* If buffer_len==0, just skip the crypto attribute. */ 1501 1498 if (buffer_len) { 1502 1499 pj_strset(&attr_value, buffer, buffer_len); 1503 attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr, 1500 attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr, 1504 1501 &attr_value); 1505 1502 m_loc->attr[m_loc->attr_count++] = attr; … … 1508 1505 /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 1509 1506 } 1510 1507 1511 1508 } 1512 1509 goto PROPAGATE_MEDIA_CREATE; … … 1519 1516 1520 1517 PROPAGATE_MEDIA_CREATE: 1521 return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool, 1518 return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool, 1522 1519 sdp_local, sdp_remote, media_index); 1523 1520 } … … 1548 1545 /* For answerer side, this function will just have to start SRTP */ 1549 1546 1550 /* Check remote media transport & set local media transport 1547 /* Check remote media transport & set local media transport 1551 1548 * based on SRTP usage option. 1552 1549 */ … … 1561 1558 // Regardless the answer's transport type (RTP/AVP or RTP/SAVP), 1562 1559 // the answer must be processed through in optional mode. 1563 // Please note that at this point transport type is ensured to be 1560 // Please note that at this point transport type is ensured to be 1564 1561 // RTP/AVP or RTP/SAVP, see transport_media_create() 1565 1562 //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) { … … 1574 1571 } 1575 1572 } 1576 1573 1577 1574 if (srtp->offerer_side) { 1578 1575 /* find supported crypto-suite, get the tag, and assign policy_local */ … … 1593 1590 has_crypto_attr = PJ_TRUE; 1594 1591 1595 status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 1592 status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 1596 1593 &tmp_tx_crypto, &rem_tag); 1597 1594 if (status != PJ_SUCCESS) … … 1606 1603 1607 1604 /* match the crypto name */ 1608 if (pj_stricmp(&tmp_tx_crypto.name, 1605 if (pj_stricmp(&tmp_tx_crypto.name, 1609 1606 &srtp->setting.crypto[rem_tag-1].name) != 0) 1610 1607 { … … 1634 1631 1635 1632 /* Make sure we have the SRTP policies */ 1636 if (srtp_crypto_empty(&srtp->tx_policy_neg) || 1633 if (srtp_crypto_empty(&srtp->tx_policy_neg) || 1637 1634 srtp_crypto_empty(&srtp->rx_policy_neg)) 1638 1635 { … … 1671 1668 1672 1669 PROPAGATE_MEDIA_START: 1673 return pjmedia_transport_media_start(srtp->member_tp, pool, 1670 return pjmedia_transport_media_start(srtp->member_tp, pool, 1674 1671 sdp_local, sdp_remote, 1675 1672 media_index); … … 1685 1682 status = pjmedia_transport_media_stop(srtp->member_tp); 1686 1683 if (status != PJ_SUCCESS) 1687 PJ_LOG(4, (srtp->pool->obj_name, 1684 PJ_LOG(4, (srtp->pool->obj_name, 1688 1685 "SRTP failed stop underlying media transport.")); 1689 1686 … … 1720 1717 else 1721 1718 err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, pkt, pkt_len); 1722 1719 1723 1720 if (err != err_status_ok) { 1724 PJ_LOG(5,(srtp->pool->obj_name, 1725 "Failed to unprotect SRTP, pkt size=%d, err=%s", 1721 PJ_LOG(5,(srtp->pool->obj_name, 1722 "Failed to unprotect SRTP, pkt size=%d, err=%s", 1726 1723 *pkt_len, get_libsrtp_errstr(err))); 1727 1724 }
Note: See TracChangeset
for help on using the changeset viewer.