Changeset 5597 for pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c
- Timestamp:
- Jun 3, 2017 9:22:34 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c
r5588 r5597 22 22 #include <pjmedia/endpoint.h> 23 23 #include <pjlib-util/base64.h> 24 #include <pj/array.h> 24 25 #include <pj/assert.h> 25 26 #include <pj/ctype.h> … … 80 81 char *name; 81 82 cipher_type_id_t cipher_type; 82 unsigned cipher_key_len; 83 unsigned cipher_key_len; /* key + salt length */ 84 unsigned cipher_salt_len; /* salt only length */ 83 85 auth_type_id_t auth_type; 84 86 unsigned auth_key_len; … … 101 103 /* plain RTP/RTCP (no cipher & no auth) */ 102 104 {"NULL", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none}, 103 #if defined(PJMEDIA_SRTP_HAS_AES_GCM_256) && \ 104 (PJMEDIA_SRTP_HAS_AES_GCM_256 != 0) 105 106 #if defined(PJMEDIA_SRTP_HAS_AES_GCM_256)&&(PJMEDIA_SRTP_HAS_AES_GCM_256!=0) 107 105 108 /* cipher AES_GCM, NULL auth, auth tag len = 16 octets */ 106 {"AEAD_AES_256_GCM", AES_256_GCM, AES_256_GCM_KEYSIZE_WSALT,109 {"AEAD_AES_256_GCM", AES_256_GCM, 44, 12, 107 110 NULL_AUTH, 0, 16, 16, sec_serv_conf_and_auth, &aes_gcm_256_openssl}, 111 108 112 /* cipher AES_GCM, NULL auth, auth tag len = 8 octets */ 109 {"AEAD_AES_256_GCM_8", AES_256_GCM, AES_256_GCM_KEYSIZE_WSALT,113 {"AEAD_AES_256_GCM_8", AES_256_GCM, 44, 12, 110 114 NULL_AUTH, 0, 8, 8, sec_serv_conf_and_auth, &aes_gcm_256_openssl}, 111 115 #endif 112 #if defined(PJMEDIA_SRTP_HAS_AES_CM_256) && \113 (PJMEDIA_SRTP_HAS_AES_CM_256 != 0) 116 #if defined(PJMEDIA_SRTP_HAS_AES_CM_256)&&(PJMEDIA_SRTP_HAS_AES_CM_256!=0) 117 114 118 /* cipher AES_CM_256, auth HMAC_SHA1, auth tag len = 10 octets */ 115 {"AES_256_CM_HMAC_SHA1_80", AES_ICM, 46, HMAC_SHA1, 20, 10, 10,119 {"AES_256_CM_HMAC_SHA1_80", AES_ICM, 46, 14, HMAC_SHA1, 20, 10, 10, 116 120 sec_serv_conf_and_auth, NULL, 117 121 &crypto_policy_set_aes_cm_256_hmac_sha1_80}, 122 118 123 /* cipher AES_CM_256, auth HMAC_SHA1, auth tag len = 10 octets */ 119 {"AES_256_CM_HMAC_SHA1_32", AES_ICM, 46, HMAC_SHA1, 20, 4, 10,124 {"AES_256_CM_HMAC_SHA1_32", AES_ICM, 46, 14, HMAC_SHA1, 20, 4, 10, 120 125 sec_serv_conf_and_auth, NULL, 121 126 &crypto_policy_set_aes_cm_256_hmac_sha1_32}, 122 127 #endif 123 #if defined(PJMEDIA_SRTP_HAS_AES_CM_192) && \124 (PJMEDIA_SRTP_HAS_AES_CM_192 != 0) 128 #if defined(PJMEDIA_SRTP_HAS_AES_CM_192)&&(PJMEDIA_SRTP_HAS_AES_CM_192!=0) 129 125 130 /* cipher AES_CM_192, auth HMAC_SHA1, auth tag len = 10 octets */ 126 {"AES_192_CM_HMAC_SHA1_80", AES_ICM, 38, HMAC_SHA1, 20, 10, 10,131 {"AES_192_CM_HMAC_SHA1_80", AES_ICM, 38, 14, HMAC_SHA1, 20, 10, 10, 127 132 sec_serv_conf_and_auth, &aes_icm_192}, 133 128 134 /* cipher AES_CM_192, auth HMAC_SHA1, auth tag len = 4 octets */ 129 {"AES_192_CM_HMAC_SHA1_32", AES_ICM, 38, HMAC_SHA1, 20, 4, 10,135 {"AES_192_CM_HMAC_SHA1_32", AES_ICM, 38, 14, HMAC_SHA1, 20, 4, 10, 130 136 sec_serv_conf_and_auth, &aes_icm_192}, 131 137 #endif 132 #if defined(PJMEDIA_SRTP_HAS_AES_GCM_128) && \133 (PJMEDIA_SRTP_HAS_AES_GCM_128 != 0) 138 #if defined(PJMEDIA_SRTP_HAS_AES_GCM_128)&&(PJMEDIA_SRTP_HAS_AES_GCM_128!=0) 139 134 140 /* cipher AES_GCM, NULL auth, auth tag len = 16 octets */ 135 {"AEAD_AES_128_GCM", AES_128_GCM, AES_128_GCM_KEYSIZE_WSALT,141 {"AEAD_AES_128_GCM", AES_128_GCM, 28, 12, 136 142 NULL_AUTH, 0, 16, 16, sec_serv_conf_and_auth, &aes_gcm_128_openssl}, 137 143 138 144 /* cipher AES_GCM, NULL auth, auth tag len = 8 octets */ 139 {"AEAD_AES_128_GCM_8", AES_128_GCM, AES_128_GCM_KEYSIZE_WSALT,145 {"AEAD_AES_128_GCM_8", AES_128_GCM, 28, 12, 140 146 NULL_AUTH, 0, 8, 8, sec_serv_conf_and_auth, &aes_gcm_128_openssl}, 141 147 #endif 142 #if defined(PJMEDIA_SRTP_HAS_AES_CM_128) && \143 (PJMEDIA_SRTP_HAS_AES_CM_128 != 0) 148 #if defined(PJMEDIA_SRTP_HAS_AES_CM_128)&&(PJMEDIA_SRTP_HAS_AES_CM_128!=0) 149 144 150 /* cipher AES_CM_128, auth HMAC_SHA1, auth tag len = 10 octets */ 145 {"AES_CM_128_HMAC_SHA1_80", AES_ICM, 30, HMAC_SHA1, 20, 10, 10,151 {"AES_CM_128_HMAC_SHA1_80", AES_ICM, 30, 14, HMAC_SHA1, 20, 10, 10, 146 152 sec_serv_conf_and_auth}, 153 147 154 /* cipher AES_CM_128, auth HMAC_SHA1, auth tag len = 4 octets */ 148 {"AES_CM_128_HMAC_SHA1_32", AES_ICM, 30, HMAC_SHA1, 20, 4, 10,155 {"AES_CM_128_HMAC_SHA1_32", AES_ICM, 30, 14, HMAC_SHA1, 20, 4, 10, 149 156 sec_serv_conf_and_auth}, 150 157 #endif 158 151 159 /* 152 160 * F8_128_HMAC_SHA1_8 not supported by libsrtp? 153 * {"F8_128_HMAC_SHA1_8", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none} 161 * {"F8_128_HMAC_SHA1_8", NULL_CIPHER, 0, 0, NULL_AUTH, 0, 0, 0, 162 * sec_serv_none} 154 163 */ 155 164 }; 156 165 166 167 /* SRTP transport */ 157 168 typedef struct transport_srtp 158 169 { … … 193 204 /* Transport information */ 194 205 pjmedia_transport *member_tp; /**< Underlying transport. */ 206 pj_bool_t member_tp_attached; 195 207 196 208 /* SRTP usage policy of peer. This field is updated when media is starting. … … 205 217 */ 206 218 unsigned probation_cnt; 219 220 /* SRTP keying methods. The keying is implemented using media transport 221 * abstraction, so it will also be invoked when the SRTP media transport 222 * operation is invoked. 223 * 224 * As there can be multiple keying methods enabled (currently only SDES & 225 * DTLS-SRTP), each keying method will be given the chance to respond to 226 * remote SDP. If any keying operation returns non-success, it will be 227 * removed from the session. And once SRTP key is obtained via a keying 228 * method, any other keying methods will be stopped and destroyed. 229 */ 230 unsigned keying_cnt; 231 pjmedia_transport *keying[2]; 232 233 /* If not zero, keying nego is ongoing (async-ly, e.g: by DTLS-SRTP). 234 * This field may be updated by keying method. 235 */ 236 unsigned keying_pending_cnt; 237 207 238 } transport_srtp; 208 239 … … 224 255 static pj_status_t transport_get_info (pjmedia_transport *tp, 225 256 pjmedia_transport_info *info); 226 static pj_status_t transport_attach (pjmedia_transport *tp,227 void *user_data,228 const pj_sockaddr_t *rem_addr,229 const pj_sockaddr_t *rem_rtcp,230 unsigned addr_len,231 void (*rtp_cb)(void*,232 void*,233 pj_ssize_t),234 void (*rtcp_cb)(void*,235 void*,236 pj_ssize_t));257 //static pj_status_t transport_attach (pjmedia_transport *tp, 258 // void *user_data, 259 // const pj_sockaddr_t *rem_addr, 260 // const pj_sockaddr_t *rem_rtcp, 261 // unsigned addr_len, 262 // void (*rtp_cb)(void*, 263 // void*, 264 // pj_ssize_t), 265 // void (*rtcp_cb)(void*, 266 // void*, 267 // pj_ssize_t)); 237 268 static void transport_detach (pjmedia_transport *tp, 238 269 void *strm); … … 268 299 unsigned pct_lost); 269 300 static pj_status_t transport_destroy (pjmedia_transport *tp); 301 static pj_status_t transport_attach2 (pjmedia_transport *tp, 302 pjmedia_transport_attach_param *param); 270 303 271 304 … … 274 307 { 275 308 &transport_get_info, 276 &transport_attach,309 NULL, //&transport_attach, 277 310 &transport_detach, 278 311 &transport_send_rtp, … … 284 317 &transport_media_stop, 285 318 &transport_simulate_lost, 286 &transport_destroy 319 &transport_destroy, 320 &transport_attach2 287 321 }; 322 323 /* Get crypto index from crypto name */ 324 static int get_crypto_idx(const pj_str_t* crypto_name); 325 326 /* Is crypto empty (i.e: no name or key)? */ 327 static pj_bool_t srtp_crypto_empty(const pjmedia_srtp_crypto* c); 328 329 /* Compare crypto, return zero if same */ 330 static int srtp_crypto_cmp(const pjmedia_srtp_crypto* c1, 331 const pjmedia_srtp_crypto* c2); 332 333 /* Start SRTP */ 334 static pj_status_t start_srtp(transport_srtp *srtp); 335 336 /* SRTP keying method: Session Description */ 337 #if defined(PJMEDIA_SRTP_HAS_SDES) && (PJMEDIA_SRTP_HAS_SDES != 0) 338 # include "transport_srtp_sdes.c" 339 #endif 340 341 /* SRTP keying method: DTLS */ 342 #if defined(PJMEDIA_SRTP_HAS_DTLS) && (PJMEDIA_SRTP_HAS_DTLS != 0) 343 # include "transport_srtp_dtls.c" 344 #endif 345 288 346 289 347 /* This function may also be used by other module, e.g: pjmedia/errno.c, … … 346 404 PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt) 347 405 { 406 pj_status_t status = PJ_SUCCESS; 407 408 if (libsrtp_initialized) 409 return PJ_SUCCESS; 410 348 411 #if PJMEDIA_LIBSRTP_AUTO_INIT_DEINIT 349 if (libsrtp_initialized == PJ_FALSE) { 412 /* Init libsrtp */ 413 { 350 414 err_status_t err; 351 415 … … 356 420 return PJMEDIA_ERRNO_FROM_LIBSRTP(err); 357 421 } 358 359 if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS) 360 { 361 /* There will be memory leak when it fails to schedule libsrtp 362 * deinitialization, however the memory leak could be harmless, 363 * since in modern OS's memory used by an application is released 364 * when the application terminates. 365 */ 366 PJ_LOG(4, (THIS_FILE, "Failed to register libsrtp deinit.")); 367 } 368 369 libsrtp_initialized = PJ_TRUE; 370 } 371 #else 372 PJ_UNUSED_ARG(endpt); 373 #endif 374 375 return PJ_SUCCESS; 422 } 423 #endif 424 425 #if defined(PJMEDIA_SRTP_HAS_DTLS) && (PJMEDIA_SRTP_HAS_DTLS != 0) 426 dtls_init(); 427 #endif 428 429 if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS) 430 { 431 /* There will be memory leak when it fails to schedule libsrtp 432 * deinitialization, however the memory leak could be harmless, 433 * since in modern OS's memory used by an application is released 434 * when the application terminates. 435 */ 436 PJ_LOG(4, (THIS_FILE, "Failed to register libsrtp deinit.")); 437 } 438 439 libsrtp_initialized = PJ_TRUE; 440 441 return status; 376 442 } 377 443 … … 392 458 # define PJMEDIA_SRTP_HAS_SHUTDOWN 1 393 459 #endif 460 461 #if PJMEDIA_LIBSRTP_AUTO_INIT_DEINIT 394 462 395 463 # if defined(PJMEDIA_SRTP_HAS_DEINIT) && PJMEDIA_SRTP_HAS_DEINIT!=0 … … 404 472 get_libsrtp_errstr(err))); 405 473 } 474 #endif // PJMEDIA_LIBSRTP_AUTO_INIT_DEINIT 475 476 #if defined(PJMEDIA_SRTP_HAS_DTLS) && (PJMEDIA_SRTP_HAS_DTLS != 0) 477 dtls_deinit(); 478 #endif 406 479 407 480 libsrtp_initialized = PJ_FALSE; … … 464 537 for (i=0; i<opt->crypto_count; ++i) 465 538 opt->crypto[i].name = pj_str(crypto_suites[i+1].name); 539 540 /* Keying method */ 541 opt->keying_count = PJMEDIA_SRTP_KEYINGS_COUNT; 542 opt->keying[0] = PJMEDIA_SRTP_KEYING_SDES; 543 opt->keying[1] = PJMEDIA_SRTP_KEYING_DTLS_SRTP; 544 545 /* Just for reminder to add any new keying to the array above */ 546 pj_assert(PJMEDIA_SRTP_KEYINGS_COUNT == 2); 466 547 } 467 548 … … 551 632 srtp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP; 552 633 srtp->base.op = &transport_srtp_op; 634 srtp->base.user_data = srtp->setting.user_data; 553 635 554 636 /* Set underlying transport */ … … 557 639 /* Initialize peer's SRTP usage mode. */ 558 640 srtp->peer_use = srtp->setting.use; 641 642 /* Initialize SRTP keying method. */ 643 for (i = 0; i < srtp->setting.keying_count; ++i) { 644 switch(srtp->setting.keying[i]) { 645 646 case PJMEDIA_SRTP_KEYING_SDES: 647 #if defined(PJMEDIA_SRTP_HAS_SDES) && (PJMEDIA_SRTP_HAS_SDES != 0) 648 sdes_create(srtp, &srtp->keying[srtp->keying_cnt++]); 649 #endif 650 break; 651 652 case PJMEDIA_SRTP_KEYING_DTLS_SRTP: 653 #if defined(PJMEDIA_SRTP_HAS_DTLS) && (PJMEDIA_SRTP_HAS_DTLS != 0) 654 dtls_create(srtp, &srtp->keying[srtp->keying_cnt++]); 655 #endif 656 break; 657 658 default: 659 break; 660 } 661 } 559 662 560 663 /* Done */ … … 780 883 } 781 884 885 886 static pj_status_t start_srtp(transport_srtp *srtp) 887 { 888 /* Make sure we have the SRTP policies */ 889 if (srtp_crypto_empty(&srtp->tx_policy_neg) || 890 srtp_crypto_empty(&srtp->rx_policy_neg)) 891 { 892 srtp->bypass_srtp = PJ_TRUE; 893 srtp->peer_use = PJMEDIA_SRTP_DISABLED; 894 if (srtp->session_inited) { 895 pjmedia_transport_srtp_stop(&srtp->base); 896 } 897 898 return PJ_SUCCESS; 899 } 900 901 /* Reset probation counts */ 902 srtp->probation_cnt = PROBATION_CNT_INIT; 903 904 /* Got policy_local & policy_remote, let's initalize the SRTP */ 905 906 /* Ticket #1075: media_start() is called whenever media description 907 * gets updated, e.g: call hold, however we should restart SRTP only 908 * when the SRTP policy settings are updated. 909 */ 910 if (srtp_crypto_cmp(&srtp->tx_policy_neg, &srtp->tx_policy) || 911 srtp_crypto_cmp(&srtp->rx_policy_neg, &srtp->rx_policy)) 912 { 913 pj_status_t status; 914 status = pjmedia_transport_srtp_start(&srtp->base, 915 &srtp->tx_policy_neg, 916 &srtp->rx_policy_neg); 917 if (status != PJ_SUCCESS) 918 return status; 919 } 920 921 srtp->bypass_srtp = PJ_FALSE; 922 923 return PJ_SUCCESS; 924 } 925 926 782 927 PJ_DEF(pjmedia_transport *) pjmedia_transport_srtp_get_member( 783 928 pjmedia_transport *tp) … … 797 942 pjmedia_srtp_info srtp_info; 798 943 int spc_info_idx; 944 unsigned i; 799 945 800 946 PJ_ASSERT_RETURN(tp && info, PJ_EINVAL); … … 816 962 sizeof(srtp_info)); 817 963 964 /* Invoke get_info() of all keying methods */ 965 for (i=0; i < srtp->keying_cnt; i++) 966 pjmedia_transport_get_info(srtp->keying[i], info); 967 818 968 return pjmedia_transport_get_info(srtp->member_tp, info); 819 969 } 820 970 821 static pj_status_t transport_attach(pjmedia_transport *tp, 822 void *user_data, 823 const pj_sockaddr_t *rem_addr, 824 const pj_sockaddr_t *rem_rtcp, 825 unsigned addr_len, 826 void (*rtp_cb) (void*, void*, 827 pj_ssize_t), 828 void (*rtcp_cb)(void*, void*, 829 pj_ssize_t)) 971 static pj_status_t transport_attach2(pjmedia_transport *tp, 972 pjmedia_transport_attach_param *param) 830 973 { 831 974 transport_srtp *srtp = (transport_srtp*) tp; 975 pjmedia_transport_attach_param member_param; 832 976 pj_status_t status; 833 977 834 PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);978 PJ_ASSERT_RETURN(tp && param, PJ_EINVAL); 835 979 836 980 /* Save the callbacks */ 837 981 pj_lock_acquire(srtp->mutex); 838 srtp->rtp_cb = rtp_cb;839 srtp->rtcp_cb = rtcp_cb;840 srtp->user_data = user_data;982 srtp->rtp_cb = param->rtp_cb; 983 srtp->rtcp_cb = param->rtcp_cb; 984 srtp->user_data = param->user_data; 841 985 pj_lock_release(srtp->mutex); 842 986 843 /* Attach itself to transport */ 844 status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr, 845 rem_rtcp, addr_len, &srtp_rtp_cb, 846 &srtp_rtcp_cb); 987 /* Attach self to member transport */ 988 member_param = *param; 989 member_param.user_data = srtp; 990 member_param.rtp_cb = &srtp_rtp_cb; 991 member_param.rtcp_cb = &srtp_rtcp_cb; 992 status = pjmedia_transport_attach2(srtp->member_tp, &member_param); 847 993 if (status != PJ_SUCCESS) { 848 994 pj_lock_acquire(srtp->mutex); … … 854 1000 } 855 1001 1002 srtp->member_tp_attached = PJ_TRUE; 856 1003 return PJ_SUCCESS; 857 1004 } … … 874 1021 srtp->user_data = NULL; 875 1022 pj_lock_release(srtp->mutex); 1023 srtp->member_tp_attached = PJ_FALSE; 876 1024 } 877 1025 … … 973 1121 transport_srtp *srtp = (transport_srtp *) tp; 974 1122 pj_status_t status; 1123 unsigned i; 975 1124 976 1125 PJ_ASSERT_RETURN(tp, PJ_EINVAL); 977 1126 1127 /* Close keying */ 1128 for (i=0; i < srtp->keying_cnt; i++) 1129 pjmedia_transport_close(srtp->keying[i]); 1130 1131 /* Close member if configured */ 978 1132 if (srtp->setting.close_member_tp && srtp->member_tp) { 979 1133 pjmedia_transport_close(srtp->member_tp); … … 1010 1164 if (size < 0) { 1011 1165 return; 1166 } 1167 1168 /* Give the packet to keying first by invoking its send_rtp() op. 1169 * Yes, the usage of send_rtp() is rather hacky, but it is convenient 1170 * as the signature suits the purpose and it is ready to use 1171 * (no futher registration/setting needed), and it may never be used 1172 * by any keying method in the future. 1173 */ 1174 { 1175 unsigned i; 1176 pj_status_t status; 1177 for (i=0; i < srtp->keying_cnt; i++) { 1178 if (!srtp->keying[i]->op->send_rtp) 1179 continue; 1180 status = pjmedia_transport_send_rtp(srtp->keying[i], pkt, size); 1181 if (status != PJ_EIGNORED) { 1182 /* Packet is already consumed by the keying method */ 1183 return; 1184 } 1185 } 1012 1186 } 1013 1187 … … 1111 1285 } 1112 1286 1113 /* Generate crypto attribute, including crypto key.1114 * If crypto-suite chosen is crypto NULL, just return PJ_SUCCESS,1115 * and set buffer_len = 0.1116 */1117 static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,1118 char *buffer, int *buffer_len,1119 pjmedia_srtp_crypto *crypto,1120 int tag)1121 {1122 pj_status_t status;1123 int cs_idx = get_crypto_idx(&crypto->name);1124 char b64_key[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)+1];1125 int b64_key_len = sizeof(b64_key);1126 int print_len;1127 1128 if (cs_idx == -1)1129 return PJMEDIA_SRTP_ENOTSUPCRYPTO;1130 1131 /* Crypto-suite NULL. */1132 if (cs_idx == 0) {1133 *buffer_len = 0;1134 return PJ_SUCCESS;1135 }1136 1137 /* Generate key if not specified. */1138 if (crypto->key.slen == 0) {1139 pj_bool_t key_ok;1140 char key[MAX_KEY_LEN];1141 err_status_t err;1142 unsigned i;1143 1144 PJ_ASSERT_RETURN(MAX_KEY_LEN >= crypto_suites[cs_idx].cipher_key_len,1145 PJ_ETOOSMALL);1146 1147 do {1148 key_ok = PJ_TRUE;1149 1150 1151 #if defined(PJ_HAS_SSL_SOCK) && (PJ_HAS_SSL_SOCK != 0)1152 1153 /* Include OpenSSL libraries for MSVC */1154 # ifdef _MSC_VER1155 # if OPENSSL_VERSION_NUMBER >= 0x10100000L1156 # pragma comment(lib, "libcrypto")1157 # else1158 # pragma comment(lib, "libeay32")1159 # pragma comment(lib, "ssleay32")1160 # endif1161 # endif1162 1163 err = RAND_bytes((unsigned char*)key,1164 crypto_suites[cs_idx].cipher_key_len);1165 if (err != 1) {1166 PJ_LOG(5,(THIS_FILE, "Failed generating random key"));1167 return PJMEDIA_ERRNO_FROM_LIBSRTP(1);1168 }1169 #else1170 err = crypto_get_random((unsigned char*)key,1171 crypto_suites[cs_idx].cipher_key_len);1172 if (err != err_status_ok) {1173 PJ_LOG(5,(THIS_FILE, "Failed generating random key: %s",1174 get_libsrtp_errstr(err)));1175 return PJMEDIA_ERRNO_FROM_LIBSRTP(err);1176 }1177 #endif1178 for (i=0; i<crypto_suites[cs_idx].cipher_key_len && key_ok; ++i)1179 if (key[i] == 0) key_ok = PJ_FALSE;1180 1181 } while (!key_ok);1182 crypto->key.ptr = (char*)1183 pj_pool_zalloc(pool,1184 crypto_suites[cs_idx].cipher_key_len);1185 pj_memcpy(crypto->key.ptr, key, crypto_suites[cs_idx].cipher_key_len);1186 crypto->key.slen = crypto_suites[cs_idx].cipher_key_len;1187 }1188 1189 if (crypto->key.slen != (pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)1190 return PJMEDIA_SRTP_EINKEYLEN;1191 1192 /* Key transmitted via SDP should be base64 encoded. */1193 status = pj_base64_encode((pj_uint8_t*)crypto->key.ptr, crypto->key.slen,1194 b64_key, &b64_key_len);1195 if (status != PJ_SUCCESS) {1196 PJ_LOG(5,(THIS_FILE, "Failed encoding plain key to base64"));1197 return status;1198 }1199 1200 b64_key[b64_key_len] = '\0';1201 1202 PJ_ASSERT_RETURN(*buffer_len >= (crypto->name.slen + \1203 b64_key_len + 16), PJ_ETOOSMALL);1204 1205 /* Print the crypto attribute value. */1206 print_len = pj_ansi_snprintf(buffer, *buffer_len, "%d %s inline:%s",1207 tag,1208 crypto_suites[cs_idx].name,1209 b64_key);1210 if (print_len < 1 || print_len >= *buffer_len)1211 return PJ_ETOOSMALL;1212 1213 *buffer_len = print_len;1214 1215 return PJ_SUCCESS;1216 }1217 1218 /* Parse crypto attribute line */1219 static pj_status_t parse_attr_crypto(pj_pool_t *pool,1220 const pjmedia_sdp_attr *attr,1221 pjmedia_srtp_crypto *crypto,1222 int *tag)1223 {1224 pj_str_t token, delim;1225 pj_status_t status;1226 int itmp, found_idx;1227 1228 pj_bzero(crypto, sizeof(*crypto));1229 1230 /* Tag */1231 delim = pj_str(" ");1232 found_idx = pj_strtok(&attr->value, &delim, &token, 0);1233 if (found_idx == attr->value.slen) {1234 PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag"));1235 return PJMEDIA_SDP_EINATTR;1236 }1237 1238 /* Tag must not use leading zeroes. */1239 if (token.slen > 1 && *token.ptr == '0')1240 return PJMEDIA_SDP_EINATTR;1241 1242 /* Tag must be decimal, i.e: contains only digit '0'-'9'. */1243 for (itmp = 0; itmp < token.slen; ++itmp)1244 if (!pj_isdigit(token.ptr[itmp]))1245 return PJMEDIA_SDP_EINATTR;1246 1247 /* Get tag value. */1248 *tag = pj_strtoul(&token);1249 1250 /* Crypto-suite */1251 found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen);1252 if (found_idx == attr->value.slen) {1253 PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite"));1254 return PJMEDIA_SDP_EINATTR;1255 }1256 pj_strdup(pool, &crypto->name, &token);1257 1258 /* Key method */1259 delim = pj_str(": ");1260 found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen);1261 if (found_idx == attr->value.slen) {1262 PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method"));1263 return PJMEDIA_SDP_EINATTR;1264 }1265 if (pj_stricmp2(&token, "inline")) {1266 PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%.*s' "1267 "not supported!", token.slen, token.ptr));1268 return PJMEDIA_SDP_EINATTR;1269 }1270 1271 /* Key */1272 delim = pj_str("| ");1273 found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen);1274 if (found_idx == attr->value.slen) {1275 PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key"));1276 return PJMEDIA_SDP_EINATTR;1277 }1278 1279 if (PJ_BASE64_TO_BASE256_LEN(token.slen) > MAX_KEY_LEN) {1280 PJ_LOG(4,(THIS_FILE, "Key too long"));1281 return PJMEDIA_SRTP_EINKEYLEN;1282 }1283 1284 /* Decode key */1285 crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);1286 itmp = MAX_KEY_LEN;1287 status = pj_base64_decode(&token, (pj_uint8_t*)crypto->key.ptr,1288 &itmp);1289 if (status != PJ_SUCCESS) {1290 PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64"));1291 return status;1292 }1293 crypto->key.slen = itmp;1294 1295 return PJ_SUCCESS;1296 }1297 1287 1298 1288 static pj_status_t transport_media_create(pjmedia_transport *tp, … … 1304 1294 struct transport_srtp *srtp = (struct transport_srtp*) tp; 1305 1295 unsigned member_tp_option; 1296 pj_status_t last_err_st = PJ_EBUG; 1297 pj_status_t status; 1298 unsigned i; 1306 1299 1307 1300 PJ_ASSERT_RETURN(tp, PJ_EINVAL); … … 1310 1303 pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg)); 1311 1304 1312 srtp->media_option = options; 1313 member_tp_option = options | PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 1314 1315 srtp->offerer_side = sdp_remote == NULL; 1316 1317 /* Validations */ 1318 if (srtp->offerer_side) { 1319 1320 if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) 1321 goto BYPASS_SRTP; 1322 1323 } else { 1324 1325 pjmedia_sdp_media *m_rem; 1326 1327 m_rem = sdp_remote->media[media_index]; 1328 1329 /* Nothing to do on inactive media stream */ 1330 if (pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)) 1331 goto BYPASS_SRTP; 1332 1333 /* Validate remote media transport based on SRTP usage option. 1334 */ 1335 switch (srtp->setting.use) { 1336 case PJMEDIA_SRTP_DISABLED: 1337 if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 1338 return PJMEDIA_SRTP_ESDPINTRANSPORT; 1339 goto BYPASS_SRTP; 1340 case PJMEDIA_SRTP_OPTIONAL: 1341 break; 1342 case PJMEDIA_SRTP_MANDATORY: 1343 if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0) 1344 return PJMEDIA_SRTP_ESDPINTRANSPORT; 1345 break; 1305 srtp->media_option = member_tp_option = options; 1306 srtp->offerer_side = (sdp_remote == NULL); 1307 1308 if (srtp->offerer_side && srtp->setting.use == PJMEDIA_SRTP_DISABLED) 1309 srtp->bypass_srtp = PJ_TRUE; 1310 else 1311 member_tp_option |= PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 1312 1313 status = pjmedia_transport_media_create(srtp->member_tp, sdp_pool, 1314 member_tp_option, sdp_remote, 1315 media_index); 1316 if (status != PJ_SUCCESS || srtp->bypass_srtp) 1317 return status; 1318 1319 /* Invoke media_create() of all keying methods */ 1320 for (i=0; i < srtp->keying_cnt; ) { 1321 pj_status_t st; 1322 st = pjmedia_transport_media_create(srtp->keying[i], sdp_pool, 1323 options, sdp_remote, 1324 media_index); 1325 if (st != PJ_SUCCESS) { 1326 /* This keying method returns error, remove it */ 1327 pj_array_erase(srtp->keying, sizeof(srtp->keying[0]), 1328 srtp->keying_cnt, i); 1329 srtp->keying_cnt--; 1330 last_err_st = st; 1331 continue; 1332 } else if (srtp->offerer_side) { 1333 /* Currently we can send one keying only in outgoing offer */ 1334 srtp->keying[0] = srtp->keying[i]; 1335 srtp->keying_cnt = 1; 1336 break; 1346 1337 } 1347 1338 1348 } 1349 goto PROPAGATE_MEDIA_CREATE; 1350 1351 BYPASS_SRTP: 1352 srtp->bypass_srtp = PJ_TRUE; 1353 member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 1354 1355 PROPAGATE_MEDIA_CREATE: 1356 return pjmedia_transport_media_create(srtp->member_tp, sdp_pool, 1357 member_tp_option, sdp_remote, 1358 media_index); 1339 ++i; 1340 } 1341 1342 /* All keying method failed to process remote SDP? */ 1343 if (srtp->keying_cnt == 0) 1344 return last_err_st; 1345 1346 return PJ_SUCCESS; 1359 1347 } 1360 1348 … … 1366 1354 { 1367 1355 struct transport_srtp *srtp = (struct transport_srtp*) tp; 1368 pjmedia_sdp_media *m_rem, *m_loc; 1369 enum { MAXLEN = 512 }; 1370 char buffer[MAXLEN]; 1371 int buffer_len; 1356 pj_status_t last_err_st = PJ_EBUG; 1372 1357 pj_status_t status; 1373 pjmedia_sdp_attr *attr; 1374 pj_str_t attr_value; 1375 unsigned i, j; 1358 unsigned i; 1376 1359 1377 1360 PJ_ASSERT_RETURN(tp && sdp_pool && sdp_local, PJ_EINVAL); … … 1380 1363 pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg)); 1381 1364 1382 srtp->offerer_side = sdp_remote == NULL; 1383 1384 m_rem = sdp_remote ? sdp_remote->media[media_index] : NULL; 1385 m_loc = sdp_local->media[media_index]; 1386 1387 /* Bypass if media transport is not RTP/AVP or RTP/SAVP */ 1388 if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) != 0 && 1389 pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0) 1390 goto BYPASS_SRTP; 1391 1392 /* If the media is inactive, do nothing. */ 1393 /* No, we still need to process SRTP offer/answer even if the media is 1394 * marked as inactive, because the transport is still alive in this 1395 * case (e.g. for keep-alive). See: 1396 * http://trac.pjsip.org/repos/ticket/1079 1397 */ 1398 /* 1399 if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) || 1400 (m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL))) 1401 goto BYPASS_SRTP; 1402 */ 1403 1404 /* Check remote media transport & set local media transport 1405 * based on SRTP usage option. 1406 */ 1407 if (srtp->offerer_side) { 1408 1409 /* Generate transport */ 1410 switch (srtp->setting.use) { 1411 case PJMEDIA_SRTP_DISABLED: 1412 goto BYPASS_SRTP; 1413 case PJMEDIA_SRTP_OPTIONAL: 1414 m_loc->desc.transport = 1415 (srtp->peer_use == PJMEDIA_SRTP_MANDATORY)? 1416 ID_RTP_SAVP : ID_RTP_AVP; 1417 break; 1418 case PJMEDIA_SRTP_MANDATORY: 1419 m_loc->desc.transport = ID_RTP_SAVP; 1420 break; 1365 srtp->offerer_side = (sdp_remote == NULL); 1366 1367 status = pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool, 1368 sdp_local, sdp_remote, media_index); 1369 if (status != PJ_SUCCESS || srtp->bypass_srtp) 1370 return status; 1371 1372 /* Invoke encode_sdp() of all keying methods */ 1373 for (i=0; i < srtp->keying_cnt; ) { 1374 pj_status_t st; 1375 st = pjmedia_transport_encode_sdp(srtp->keying[i], sdp_pool, 1376 sdp_local, sdp_remote, 1377 media_index); 1378 if (st != PJ_SUCCESS) { 1379 /* This keying method returns error, remove it */ 1380 pj_array_erase(srtp->keying, sizeof(srtp->keying[0]), 1381 srtp->keying_cnt, i); 1382 srtp->keying_cnt--; 1383 last_err_st = st; 1384 continue; 1421 1385 } 1422 1386 1423 /* Generate crypto attribute if not yet */ 1424 if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) { 1425 int tag = 1; 1426 1427 /* Offer only current active crypto if any, otherwise offer all 1428 * crypto-suites in the setting. 1429 */ 1430 for (i=0; i<srtp->setting.crypto_count; ++i) { 1431 if (srtp->tx_policy.name.slen && 1432 pj_stricmp(&srtp->tx_policy.name, 1433 &srtp->setting.crypto[i].name) != 0) 1434 { 1435 continue; 1436 } 1437 1438 buffer_len = MAXLEN; 1439 status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len, 1440 &srtp->setting.crypto[i], 1441 tag); 1442 if (status != PJ_SUCCESS) 1443 return status; 1444 1445 /* If buffer_len==0, just skip the crypto attribute. */ 1446 if (buffer_len) { 1447 pj_strset(&attr_value, buffer, buffer_len); 1448 attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr, 1449 &attr_value); 1450 m_loc->attr[m_loc->attr_count++] = attr; 1451 ++tag; 1452 } 1387 if (!srtp_crypto_empty(&srtp->tx_policy_neg) && 1388 !srtp_crypto_empty(&srtp->rx_policy_neg)) 1389 { 1390 /* SRTP nego is done, let's destroy any other keying. */ 1391 unsigned j; 1392 for (j = 0; j < srtp->keying_cnt; ++j) { 1393 if (j != i) 1394 pjmedia_transport_close(srtp->keying[j]); 1453 1395 } 1396 srtp->keying_cnt = 1; 1397 srtp->keying[0] = srtp->keying[i]; 1398 srtp->keying_pending_cnt = 0; 1399 break; 1454 1400 } 1455 1401 1456 } else { 1457 /* Answerer side */ 1458 1459 pj_assert(sdp_remote && m_rem); 1460 1461 /* Generate transport */ 1462 switch (srtp->setting.use) { 1463 case PJMEDIA_SRTP_DISABLED: 1464 if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 1465 return PJMEDIA_SRTP_ESDPINTRANSPORT; 1466 goto BYPASS_SRTP; 1467 case PJMEDIA_SRTP_OPTIONAL: 1468 m_loc->desc.transport = m_rem->desc.transport; 1469 break; 1470 case PJMEDIA_SRTP_MANDATORY: 1471 if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0) 1472 return PJMEDIA_SRTP_ESDPINTRANSPORT; 1473 m_loc->desc.transport = ID_RTP_SAVP; 1474 break; 1475 } 1476 1477 /* Generate crypto attribute if not yet */ 1478 if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) { 1479 1480 pjmedia_srtp_crypto tmp_rx_crypto; 1481 pj_bool_t has_crypto_attr = PJ_FALSE; 1482 int matched_idx = -1; 1483 int chosen_tag = 0; 1484 int tags[64]; /* assume no more than 64 crypto attrs in a media */ 1485 unsigned cr_attr_count = 0; 1486 1487 /* Find supported crypto-suite, get the tag, and assign policy_local */ 1488 for (i=0; i<m_rem->attr_count; ++i) { 1489 if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 1490 continue; 1491 1492 has_crypto_attr = PJ_TRUE; 1493 1494 status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 1495 &tmp_rx_crypto, &tags[cr_attr_count]); 1496 if (status != PJ_SUCCESS) 1497 return status; 1498 1499 /* Check duplicated tag */ 1500 for (j=0; j<cr_attr_count; ++j) { 1501 if (tags[j] == tags[cr_attr_count]) { 1502 DEACTIVATE_MEDIA(sdp_pool, m_loc); 1503 return PJMEDIA_SRTP_ESDPDUPCRYPTOTAG; 1504 } 1505 } 1506 1507 if (matched_idx == -1) { 1508 /* lets see if the crypto-suite offered is supported */ 1509 for (j=0; j<srtp->setting.crypto_count; ++j) 1510 if (pj_stricmp(&tmp_rx_crypto.name, 1511 &srtp->setting.crypto[j].name) == 0) 1512 { 1513 int cs_idx = get_crypto_idx(&tmp_rx_crypto.name); 1514 1515 if (cs_idx == -1) 1516 return PJMEDIA_SRTP_ENOTSUPCRYPTO; 1517 1518 /* Force to use test key */ 1519 /* bad keys for snom: */ 1520 //char *hex_test_key = "58b29c5c8f42308120ce857e439f2d" 1521 // "7810a8b10ad0b1446be5470faea496"; 1522 //char *hex_test_key = "20a26aac7ba062d356ff52b61e3993" 1523 // "ccb78078f12c64db94b9c294927fd0"; 1524 //pj_str_t *test_key = &srtp->setting.crypto[j].key; 1525 //char *raw_test_key = pj_pool_zalloc(srtp->pool, 64); 1526 //hex_string_to_octet_string( 1527 // raw_test_key, 1528 // hex_test_key, 1529 // strlen(hex_test_key)); 1530 //pj_strset(test_key, raw_test_key, 1531 // crypto_suites[cs_idx].cipher_key_len); 1532 /* EO Force to use test key */ 1533 1534 if (tmp_rx_crypto.key.slen != 1535 (int)crypto_suites[cs_idx].cipher_key_len) 1536 return PJMEDIA_SRTP_EINKEYLEN; 1537 1538 srtp->rx_policy_neg = tmp_rx_crypto; 1539 chosen_tag = tags[cr_attr_count]; 1540 matched_idx = j; 1541 break; 1542 } 1543 } 1544 cr_attr_count++; 1545 } 1546 1547 /* Check crypto negotiation result */ 1548 switch (srtp->setting.use) { 1549 case PJMEDIA_SRTP_DISABLED: 1550 pj_assert(!"Should never reach here"); 1551 break; 1552 1553 case PJMEDIA_SRTP_OPTIONAL: 1554 /* bypass SRTP when no crypto-attr and remote uses RTP/AVP */ 1555 if (!has_crypto_attr && 1556 pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 1557 goto BYPASS_SRTP; 1558 /* bypass SRTP when nothing match and remote uses RTP/AVP */ 1559 else if (matched_idx == -1 && 1560 pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 1561 goto BYPASS_SRTP; 1562 break; 1563 1564 case PJMEDIA_SRTP_MANDATORY: 1565 /* Do nothing, intentional */ 1566 break; 1567 } 1568 1569 /* No crypto attr */ 1570 if (!has_crypto_attr) { 1571 DEACTIVATE_MEDIA(sdp_pool, m_loc); 1572 return PJMEDIA_SRTP_ESDPREQCRYPTO; 1573 } 1574 1575 /* No crypto match */ 1576 if (matched_idx == -1) { 1577 DEACTIVATE_MEDIA(sdp_pool, m_loc); 1578 return PJMEDIA_SRTP_ENOTSUPCRYPTO; 1579 } 1580 1581 /* we have to generate crypto answer, 1582 * with srtp->tx_policy_neg matched the offer 1583 * and rem_tag contains matched offer tag. 1584 */ 1585 buffer_len = MAXLEN; 1586 status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len, 1587 &srtp->setting.crypto[matched_idx], 1588 chosen_tag); 1589 if (status != PJ_SUCCESS) 1590 return status; 1591 1592 srtp->tx_policy_neg = srtp->setting.crypto[matched_idx]; 1593 1594 /* If buffer_len==0, just skip the crypto attribute. */ 1595 if (buffer_len) { 1596 pj_strset(&attr_value, buffer, buffer_len); 1597 attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr, 1598 &attr_value); 1599 m_loc->attr[m_loc->attr_count++] = attr; 1600 } 1601 1602 /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 1603 } 1604 1605 } 1606 goto PROPAGATE_MEDIA_CREATE; 1607 1608 BYPASS_SRTP: 1609 /* Do not update this flag here as actually the media session hasn't been 1610 * updated. 1611 */ 1612 //srtp->bypass_srtp = PJ_TRUE; 1613 1614 PROPAGATE_MEDIA_CREATE: 1615 return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool, 1616 sdp_local, sdp_remote, media_index); 1617 } 1618 1619 1620 static pj_status_t fill_local_crypto(pj_pool_t *pool, 1621 const pjmedia_sdp_media *m_loc, 1622 pjmedia_srtp_crypto loc_crypto[], 1623 int *count) 1624 { 1625 int i; 1626 int crypto_count = 0; 1627 pj_status_t status = PJ_SUCCESS; 1628 1629 for (i = 0; i < *count; ++i) { 1630 pj_bzero(&loc_crypto[i], sizeof(loc_crypto[i])); 1631 } 1632 1633 for (i = 0; i < (int)m_loc->attr_count; ++i) { 1634 pjmedia_srtp_crypto tmp_crypto; 1635 int loc_tag; 1636 1637 if (pj_stricmp(&m_loc->attr[i]->name, &ID_CRYPTO) != 0) 1638 continue; 1639 1640 status = parse_attr_crypto(pool, m_loc->attr[i], 1641 &tmp_crypto, &loc_tag); 1642 if (status != PJ_SUCCESS) 1643 return status; 1644 1645 if (loc_tag > *count) 1646 return PJMEDIA_SRTP_ESDPINCRYPTOTAG; 1647 1648 loc_crypto[loc_tag-1] = tmp_crypto; 1649 ++crypto_count; 1650 } 1651 *count = crypto_count; 1652 return status; 1402 i++; 1403 } 1404 1405 /* All keying method failed to process remote SDP? */ 1406 if (srtp->keying_cnt == 0) 1407 return last_err_st; 1408 1409 return PJ_SUCCESS; 1653 1410 } 1654 1411 … … 1661 1418 { 1662 1419 struct transport_srtp *srtp = (struct transport_srtp*) tp; 1663 pj media_sdp_media *m_rem, *m_loc;1420 pj_status_t last_err_st = PJ_EBUG; 1664 1421 pj_status_t status; 1665 1422 unsigned i; 1666 pjmedia_srtp_crypto loc_crypto[PJMEDIA_SRTP_MAX_CRYPTOS];1667 int loc_cryto_cnt = PJMEDIA_SRTP_MAX_CRYPTOS;1668 1423 1669 1424 PJ_ASSERT_RETURN(tp && pool && sdp_local && sdp_remote, PJ_EINVAL); 1670 1425 1671 m_rem = sdp_remote->media[media_index]; 1672 m_loc = sdp_local->media[media_index]; 1673 1674 if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 1675 srtp->peer_use = PJMEDIA_SRTP_MANDATORY; 1676 else 1677 srtp->peer_use = PJMEDIA_SRTP_OPTIONAL; 1678 1679 /* For answerer side, this function will just have to start SRTP */ 1680 1681 /* Check remote media transport & set local media transport 1682 * based on SRTP usage option. 1426 status = pjmedia_transport_media_start(srtp->member_tp, pool, 1427 sdp_local, sdp_remote, 1428 media_index); 1429 if (status != PJ_SUCCESS || srtp->bypass_srtp) 1430 return status; 1431 1432 /* Invoke media_start() of all keying methods */ 1433 for (i=0; i < srtp->keying_cnt; ) { 1434 status = pjmedia_transport_media_start(srtp->keying[i], pool, 1435 sdp_local, sdp_remote, 1436 media_index); 1437 if (status != PJ_SUCCESS) { 1438 /* This keying method returns error, remove it */ 1439 pj_array_erase(srtp->keying, sizeof(srtp->keying[0]), 1440 srtp->keying_cnt, i); 1441 srtp->keying_cnt--; 1442 last_err_st = status; 1443 continue; 1444 } 1445 1446 if (!srtp_crypto_empty(&srtp->tx_policy_neg) && 1447 !srtp_crypto_empty(&srtp->rx_policy_neg)) 1448 { 1449 /* SRTP nego is done, let's destroy any other keying. */ 1450 unsigned j; 1451 for (j = 0; j < srtp->keying_cnt; ++j) { 1452 if (j != i) 1453 pjmedia_transport_close(srtp->keying[j]); 1454 } 1455 srtp->keying_cnt = 1; 1456 srtp->keying[0] = srtp->keying[i]; 1457 srtp->keying_pending_cnt = 0; 1458 break; 1459 } 1460 1461 i++; 1462 } 1463 1464 /* All keying method failed to process remote SDP? */ 1465 if (srtp->keying_cnt == 0) 1466 return last_err_st; 1467 1468 /* If SRTP key is being negotiated, just return now. 1469 * The keying method should start the SRTP once keying nego is done. 1683 1470 */ 1684 if (srtp->offerer_side) { 1685 if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 1686 if (pjmedia_sdp_media_find_attr(m_rem, &ID_CRYPTO, NULL)) { 1687 DEACTIVATE_MEDIA(pool, m_loc); 1688 return PJMEDIA_SRTP_ESDPINCRYPTO; 1689 } 1690 goto BYPASS_SRTP; 1691 } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 1692 // Regardless the answer's transport type (RTP/AVP or RTP/SAVP), 1693 // the answer must be processed through in optional mode. 1694 // Please note that at this point transport type is ensured to be 1695 // RTP/AVP or RTP/SAVP, see transport_media_create() 1696 //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) { 1697 //DEACTIVATE_MEDIA(pool, m_loc); 1698 //return PJMEDIA_SDP_EINPROTO; 1699 //} 1700 fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt); 1701 } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 1702 if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) { 1703 DEACTIVATE_MEDIA(pool, m_loc); 1704 return PJMEDIA_SDP_EINPROTO; 1705 } 1706 fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt); 1707 } 1708 } 1709 1710 if (srtp->offerer_side) { 1711 /* find supported crypto-suite, get the tag, and assign policy_local */ 1712 pjmedia_srtp_crypto tmp_tx_crypto; 1713 pj_bool_t has_crypto_attr = PJ_FALSE; 1714 int rem_tag; 1715 int j; 1716 1717 for (i=0; i<m_rem->attr_count; ++i) { 1718 if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 1719 continue; 1720 1721 /* more than one crypto attribute in media answer */ 1722 if (has_crypto_attr) { 1723 DEACTIVATE_MEDIA(pool, m_loc); 1724 return PJMEDIA_SRTP_ESDPAMBIGUEANS; 1725 } 1726 1727 has_crypto_attr = PJ_TRUE; 1728 1729 status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 1730 &tmp_tx_crypto, &rem_tag); 1731 if (status != PJ_SUCCESS) 1732 return status; 1733 1734 1735 /* Tag range check, our tags in the offer must be in the SRTP 1736 * setting range, so does the remote answer's. The remote answer's 1737 * tag must not exceed the tag range of the local offer. 1738 */ 1739 if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count || 1740 rem_tag > loc_cryto_cnt) 1741 1742 { 1743 DEACTIVATE_MEDIA(pool, m_loc); 1744 return PJMEDIA_SRTP_ESDPINCRYPTOTAG; 1745 } 1746 1747 /* match the crypto name */ 1748 if (pj_stricmp(&tmp_tx_crypto.name, 1749 &loc_crypto[rem_tag-1].name) != 0) 1750 { 1751 DEACTIVATE_MEDIA(pool, m_loc); 1752 return PJMEDIA_SRTP_ECRYPTONOTMATCH; 1753 } 1754 1755 /* Find the crypto from the setting. */ 1756 for (j = 0; j < (int)srtp->setting.crypto_count; ++j) { 1757 if (pj_stricmp(&tmp_tx_crypto.name, 1758 &srtp->setting.crypto[j].name) == 0) 1759 1760 { 1761 srtp->tx_policy_neg = srtp->setting.crypto[j]; 1762 break; 1763 } 1764 } 1765 1766 srtp->rx_policy_neg = tmp_tx_crypto; 1767 } 1768 1769 if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 1770 /* should never reach here */ 1771 goto BYPASS_SRTP; 1772 } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 1773 if (!has_crypto_attr) 1774 goto BYPASS_SRTP; 1775 } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 1776 if (!has_crypto_attr) { 1777 DEACTIVATE_MEDIA(pool, m_loc); 1778 return PJMEDIA_SRTP_ESDPREQCRYPTO; 1779 } 1780 } 1781 1782 /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 1783 } 1784 1785 /* Make sure we have the SRTP policies */ 1786 if (srtp_crypto_empty(&srtp->tx_policy_neg) || 1787 srtp_crypto_empty(&srtp->rx_policy_neg)) 1788 { 1789 goto BYPASS_SRTP; 1790 } 1791 1792 /* Reset probation counts */ 1793 srtp->probation_cnt = PROBATION_CNT_INIT; 1794 1795 /* Got policy_local & policy_remote, let's initalize the SRTP */ 1796 1797 /* Ticket #1075: media_start() is called whenever media description 1798 * gets updated, e.g: call hold, however we should restart SRTP only 1799 * when the SRTP policy settings are updated. 1800 */ 1801 if (srtp_crypto_cmp(&srtp->tx_policy_neg, &srtp->tx_policy) || 1802 srtp_crypto_cmp(&srtp->rx_policy_neg, &srtp->rx_policy)) 1803 { 1804 status = pjmedia_transport_srtp_start(tp, 1805 &srtp->tx_policy_neg, 1806 &srtp->rx_policy_neg); 1807 if (status != PJ_SUCCESS) 1808 return status; 1809 } 1810 1811 srtp->bypass_srtp = PJ_FALSE; 1812 1813 goto PROPAGATE_MEDIA_START; 1814 1815 BYPASS_SRTP: 1816 srtp->bypass_srtp = PJ_TRUE; 1817 srtp->peer_use = PJMEDIA_SRTP_DISABLED; 1818 if (srtp->session_inited) { 1819 pjmedia_transport_srtp_stop(tp); 1820 } 1821 1822 PROPAGATE_MEDIA_START: 1823 return pjmedia_transport_media_start(srtp->member_tp, pool, 1824 sdp_local, sdp_remote, 1825 media_index); 1826 } 1471 if (srtp->keying_pending_cnt) 1472 return PJ_SUCCESS; 1473 1474 /* Start SRTP */ 1475 status = start_srtp(srtp); 1476 1477 return status; 1478 } 1479 1827 1480 1828 1481 static pj_status_t transport_media_stop(pjmedia_transport *tp) … … 1830 1483 struct transport_srtp *srtp = (struct transport_srtp*) tp; 1831 1484 pj_status_t status; 1485 unsigned i; 1832 1486 1833 1487 PJ_ASSERT_RETURN(tp, PJ_EINVAL); 1834 1488 1489 /* Invoke media_stop() of all keying methods */ 1490 for (i=0; i < srtp->keying_cnt; ++i) { 1491 pjmedia_transport_media_stop(srtp->keying[i]); 1492 } 1493 1494 /* Invoke media_stop() of member tp */ 1835 1495 status = pjmedia_transport_media_stop(srtp->member_tp); 1836 1496 if (status != PJ_SUCCESS) … … 1838 1498 "SRTP failed stop underlying media transport.")); 1839 1499 1500 /* Finally, stop SRTP */ 1840 1501 return pjmedia_transport_srtp_stop(tp); 1841 1502 } 1503 1842 1504 1843 1505 /* Utility */
Note: See TracChangeset
for help on using the changeset viewer.