Changeset 5621
- Timestamp:
- Jul 5, 2017 5:37:24 AM (7 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/transport_srtp.h
r5597 r5621 269 269 270 270 /** 271 * This structure specifies DTLS-SRTP negotiation parameters. 272 */ 273 typedef struct pjmedia_srtp_dtls_nego_param 274 { 275 /** 276 * Fingerprint of remote certificate, should be formatted as 277 * "SHA-256/1 XX:XX:XX...". If this is not set, fingerprint verification 278 * will not be performed. 279 */ 280 pj_str_t rem_fingerprint; 281 282 /** 283 * Remote address and port. 284 */ 285 pj_sockaddr rem_addr; 286 287 /** 288 * Remote RTCP address and port. 289 */ 290 pj_sockaddr rem_rtcp; 291 292 /** 293 * Set to PJ_TRUE if our role is active. Active role will initiates 294 * the DTLS negotiation. Passive role will wait for incoming DTLS 295 * negotiation packet. 296 */ 297 pj_bool_t is_role_active; 298 299 } pjmedia_srtp_dtls_nego_param; 300 301 302 303 /** 271 304 * Initialize SRTP library. This function should be called before 272 305 * any SRTP functions, however calling #pjmedia_transport_srtp_create() … … 308 341 const pjmedia_srtp_setting *opt, 309 342 pjmedia_transport **p_tp); 343 344 /** 345 * Get fingerprint of local DTLS-SRTP certificate. 346 * 347 * @param srtp The SRTP transport. 348 * @param hash Fingerprint hash algorithm, currently valid values are 349 * "SHA-256" and "SHA-1". 350 * @param buf Buffer for fingerprint output. The output will be 351 * formatted as "SHA-256/1 XX:XX:XX..." and null terminated. 352 * @param len On input, the size of the buffer. 353 * On output, the length of the fingerprint. 354 * 355 * @return PJ_SUCCESS on success. 356 */ 357 PJ_DECL(pj_status_t) pjmedia_transport_srtp_dtls_get_fingerprint( 358 pjmedia_transport *srtp, 359 const char *hash, 360 char *buf, pj_size_t *len); 361 362 363 /** 364 * Manually start DTLS-SRTP negotiation with the given parameters. Application 365 * only needs to call this function when the SRTP transport is used without 366 * SDP offer/answer. When SDP offer/answer framework is used, the DTLS-SRTP 367 * negotiation will be handled by pjmedia_transport_media_create(), 368 * pjmedia_transport_media_start(), pjmedia_transport_media_encode_sdp(), and 369 * pjmedia_transport_media_stop(). 370 * 371 * When the negotiation completes, application will be notified via SRTP 372 * callback on_srtp_nego_complete(), if set. If the negotiation is successful, 373 * SRTP will be automatically started. 374 * 375 * Note that if the SRTP member transport is an ICE transport, application 376 * should only call this function after ICE negotiation is completed 377 * successfully. 378 * 379 * @param srtp The SRTP transport. 380 * @param param DTLS-SRTP nego parameter. 381 * 382 * @return PJ_SUCCESS on success. 383 */ 384 PJ_DECL(pj_status_t) pjmedia_transport_srtp_dtls_start_nego( 385 pjmedia_transport *srtp, 386 const pjmedia_srtp_dtls_nego_param *param); 310 387 311 388 -
pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c
r5614 r5621 403 403 #if defined(PJMEDIA_SRTP_HAS_DTLS) && (PJMEDIA_SRTP_HAS_DTLS != 0) 404 404 # include "transport_srtp_dtls.c" 405 #else 406 PJ_DEF(pj_status_t) pjmedia_transport_srtp_dtls_start_nego( 407 pjmedia_transport *srtp, 408 const pjmedia_srtp_dtls_nego_param *param) 409 { 410 PJ_UNUSED_ARG(srtp); 411 PJ_UNUSED_ARG(param); 412 return PJ_ENOTSUP; 413 } 414 PJ_DEF(pj_status_t) pjmedia_transport_srtp_dtls_get_fingerprint( 415 pjmedia_transport *srtp, 416 const char *hash, 417 char *buf, pj_size_t *len) 418 { 419 PJ_UNUSED_ARG(srtp); 420 PJ_UNUSED_ARG(hash); 421 PJ_UNUSED_ARG(buf); 422 PJ_UNUSED_ARG(len); 423 return PJ_ENOTSUP; 424 } 405 425 #endif 406 426 -
pjproject/trunk/pjmedia/src/pjmedia/transport_srtp_dtls.c
r5614 r5621 188 188 189 189 *p_keying = &ds->base; 190 PJ_LOG(5,( THIS_FILE, "SRTP keying DTLS-SRTP created"));190 PJ_LOG(5,(srtp->pool->obj_name, "SRTP keying DTLS-SRTP created")); 191 191 return PJ_SUCCESS; 192 192 } … … 549 549 is_sha256 = PJ_FALSE; 550 550 else { 551 PJ_LOG(4,(ds->base.name, " Remote hash algo inSDP for "552 " DTLS-SRTPis not supported"));551 PJ_LOG(4,(ds->base.name, "Hash algo specified in remote SDP for " 552 "its DTLS certificate fingerprint is not supported")); 553 553 return PJ_ENOTSUP; 554 554 } … … 641 641 ds->srtp->keying_pending_cnt--; 642 642 643 /* Copy negotiated policy to SRTP */ 643 644 ds->srtp->tx_policy_neg = ds->tx_crypto; 644 645 ds->srtp->rx_policy_neg = ds->rx_crypto; 646 645 647 status = start_srtp(ds->srtp); 646 648 if (status != PJ_SUCCESS) … … 716 718 /* Finally, DTLS nego started! */ 717 719 ds->nego_started = PJ_TRUE; 718 PJ_LOG( 2,(ds->base.name, "DTLS-SRTP negotiation initiated as %s",720 PJ_LOG(4,(ds->base.name, "DTLS-SRTP negotiation initiated as %s", 719 721 (ds->setup==DTLS_SETUP_ACTIVE? "client":"server"))); 720 722 … … 1248 1250 ds->srtp->rx_policy_neg = ds->rx_crypto; 1249 1251 1250 /* Verify remote fingerprint if not yet*/1252 /* Verify remote fingerprint (if available) */ 1251 1253 if (ds->rem_fingerprint.slen && ds->rem_fprint_status == PJ_EPENDING) 1254 { 1252 1255 ds->rem_fprint_status = ssl_match_fingerprint(ds); 1253 if (ds->rem_fprint_status != PJ_SUCCESS) { 1254 pj_perror(4, ds->base.name, ds->rem_fprint_status, 1255 "Fingerprint specified in remote SDP doesn't match " 1256 "to actual remote certificate fingerprint!"); 1257 return ds->rem_fprint_status; 1256 if (ds->rem_fprint_status != PJ_SUCCESS) { 1257 pj_perror(4, ds->base.name, ds->rem_fprint_status, 1258 "Fingerprint specified in remote SDP doesn't match " 1259 "to actual remote certificate fingerprint!"); 1260 return ds->rem_fprint_status; 1261 } 1258 1262 } 1259 1263 … … 1345 1349 return PJ_SUCCESS; 1346 1350 } 1351 1352 1353 /* Get fingerprint of local DTLS-SRTP certificate. */ 1354 PJ_DEF(pj_status_t) pjmedia_transport_srtp_dtls_get_fingerprint( 1355 pjmedia_transport *tp, 1356 const char *hash, 1357 char *buf, pj_size_t *len) 1358 { 1359 PJ_ASSERT_RETURN(dtls_cert, PJ_EINVALIDOP); 1360 PJ_ASSERT_RETURN(tp && hash && buf && len, PJ_EINVAL); 1361 PJ_ASSERT_RETURN(pj_ansi_strcmp(hash, "SHA-256")==0 || 1362 pj_ansi_strcmp(hash, "SHA-1")==0, PJ_EINVAL); 1363 PJ_UNUSED_ARG(tp); 1364 1365 return ssl_get_fingerprint(dtls_cert, 1366 pj_ansi_strcmp(hash, "SHA-256")==0, 1367 buf, len); 1368 } 1369 1370 1371 /* Manually start DTLS-SRTP negotiation (without SDP offer/answer) */ 1372 PJ_DEF(pj_status_t) pjmedia_transport_srtp_dtls_start_nego( 1373 pjmedia_transport *tp, 1374 const pjmedia_srtp_dtls_nego_param *param) 1375 { 1376 transport_srtp *srtp = (transport_srtp*)tp; 1377 dtls_srtp *ds = NULL; 1378 unsigned j; 1379 pjmedia_transport_attach_param ap; 1380 pj_status_t status; 1381 1382 PJ_ASSERT_RETURN(tp && param, PJ_EINVAL); 1383 PJ_ASSERT_RETURN(pj_sockaddr_has_addr(¶m->rem_addr), PJ_EINVAL); 1384 1385 /* Find DTLS keying and destroy any other keying. */ 1386 for (j = 0; j < srtp->keying_cnt; ++j) { 1387 if (srtp->keying[j]->op == &dtls_op) 1388 ds = (dtls_srtp*)srtp->keying[j]; 1389 else 1390 pjmedia_transport_close(srtp->keying[j]); 1391 } 1392 1393 /* DTLS-SRTP is not enabled */ 1394 if (!ds) 1395 return PJ_ENOTSUP; 1396 1397 /* Set SRTP keying to DTLS-SRTP only */ 1398 srtp->keying_cnt = 1; 1399 srtp->keying[0] = &ds->base; 1400 srtp->keying_pending_cnt = 1; 1401 1402 /* Apply param to DTLS-SRTP internal states */ 1403 pj_strdup(ds->pool, &ds->rem_fingerprint, ¶m->rem_fingerprint); 1404 ds->rem_fprint_status = PJ_EPENDING; 1405 ds->rem_addr = param->rem_addr; 1406 ds->rem_rtcp = param->rem_rtcp; 1407 ds->setup = param->is_role_active? DTLS_SETUP_ACTIVE:DTLS_SETUP_PASSIVE; 1408 1409 /* Pending start SRTP */ 1410 ds->pending_start = PJ_TRUE; 1411 srtp->keying_pending_cnt++; 1412 1413 /* Create SSL */ 1414 status = ssl_create(ds); 1415 if (status != PJ_SUCCESS) 1416 goto on_return; 1417 1418 /* Attach member transport, so we can send/receive DTLS init packets */ 1419 pj_bzero(&ap, sizeof(ap)); 1420 pj_sockaddr_cp(&ap.rem_addr, &ds->rem_addr); 1421 pj_sockaddr_cp(&ap.rem_rtcp, &ds->rem_rtcp); 1422 ap.addr_len = pj_sockaddr_get_len(&ap.rem_addr); 1423 status = pjmedia_transport_attach2(&ds->srtp->base, &ap); 1424 if (status != PJ_SUCCESS) 1425 goto on_return; 1426 1427 /* Start DTLS handshake */ 1428 pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg)); 1429 pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg)); 1430 status = ssl_handshake(ds); 1431 if (status != PJ_SUCCESS) 1432 goto on_return; 1433 1434 on_return: 1435 if (status != PJ_SUCCESS) { 1436 ssl_destroy(ds); 1437 } 1438 return status; 1439 } -
pjproject/trunk/pjmedia/src/pjmedia/transport_srtp_sdes.c
r5617 r5621 77 77 78 78 sdes = PJ_POOL_ZALLOC_T(srtp->pool, pjmedia_transport); 79 pj_ansi_strncpy(sdes->name, "SDES", PJ_MAX_OBJ_NAME); 79 pj_ansi_strncpy(sdes->name, srtp->pool->obj_name, PJ_MAX_OBJ_NAME); 80 pj_memcpy(sdes->name, "sdes", 4); 80 81 sdes->type = PJMEDIA_TRANSPORT_TYPE_SRTP; 81 82 sdes->op = &sdes_op; … … 83 84 84 85 *p_keying = sdes; 85 PJ_LOG(5,( THIS_FILE, "SRTP keying SDES created"));86 PJ_LOG(5,(srtp->pool->obj_name, "SRTP keying SDES created")); 86 87 return PJ_SUCCESS; 87 88 } -
pjproject/trunk/pjsip-apps/src/samples/streamutil.c
r5618 r5621 88 88 " AES_CM_128_HMAC_SHA1_32 \n" 89 89 " Use this option along with the TX & RX keys, \n" 90 " formated of 60 hex digits (e.g: E148DA..) 90 " formated of 60 hex digits (e.g: E148DA..) \n" 91 91 " --srtp-tx-key SRTP key for transmiting \n" 92 92 " --srtp-rx-key SRTP key for receiving \n" 93 " --srtp-dtls-client Use DTLS for SRTP keying, as DTLS client \n" 94 " --srtp-dtls-server Use DTLS for SRTP keying, as DTLS server \n" 93 95 #endif 94 96 … … 147 149 const pj_str_t *srtp_tx_key, 148 150 const pj_str_t *srtp_rx_key, 151 pj_bool_t is_dtls_client, 152 pj_bool_t is_dtls_server, 149 153 #endif 150 154 pjmedia_stream **p_stream ) … … 287 291 /* Check if SRTP enabled */ 288 292 if (use_srtp) { 289 pjmedia_srtp_crypto tx_plc, rx_plc;290 291 293 status = pjmedia_transport_srtp_create(med_endpt, transport, 292 294 NULL, &srtp_tp); … … 294 296 return status; 295 297 296 pj_bzero(&tx_plc, sizeof(pjmedia_srtp_crypto)); 297 pj_bzero(&rx_plc, sizeof(pjmedia_srtp_crypto)); 298 299 tx_plc.key = *srtp_tx_key; 300 tx_plc.name = *crypto_suite; 301 rx_plc.key = *srtp_rx_key; 302 rx_plc.name = *crypto_suite; 303 304 status = pjmedia_transport_srtp_start(srtp_tp, &tx_plc, &rx_plc); 305 if (status != PJ_SUCCESS) 306 return status; 298 if (is_dtls_client || is_dtls_server) { 299 char fp[128]; 300 pj_size_t fp_len = sizeof(fp); 301 pjmedia_srtp_dtls_nego_param dtls_param; 302 303 pjmedia_transport_srtp_dtls_get_fingerprint(srtp_tp, "SHA-256", fp, &fp_len); 304 PJ_LOG(3, (THIS_FILE, "Local cert fingerprint: %s", fp)); 305 306 pj_bzero(&dtls_param, sizeof(dtls_param)); 307 pj_sockaddr_cp(&dtls_param.rem_addr, rem_addr); 308 pj_sockaddr_cp(&dtls_param.rem_rtcp, rem_addr); 309 dtls_param.is_role_active = is_dtls_client; 310 311 status = pjmedia_transport_srtp_dtls_start_nego(srtp_tp, &dtls_param); 312 if (status != PJ_SUCCESS) 313 return status; 314 } else { 315 pjmedia_srtp_crypto tx_plc, rx_plc; 316 317 pj_bzero(&tx_plc, sizeof(pjmedia_srtp_crypto)); 318 pj_bzero(&rx_plc, sizeof(pjmedia_srtp_crypto)); 319 320 tx_plc.key = *srtp_tx_key; 321 tx_plc.name = *crypto_suite; 322 rx_plc.key = *srtp_rx_key; 323 rx_plc.name = *crypto_suite; 324 325 status = pjmedia_transport_srtp_start(srtp_tp, &tx_plc, &rx_plc); 326 if (status != PJ_SUCCESS) 327 return status; 328 } 307 329 308 330 transport = srtp_tp; … … 362 384 pj_str_t srtp_rx_key = {NULL, 0}; 363 385 pj_str_t srtp_crypto_suite = {NULL, 0}; 386 pj_bool_t is_dtls_client = PJ_FALSE; 387 pj_bool_t is_dtls_server = PJ_FALSE; 364 388 int tmp_key_len; 365 389 #endif … … 392 416 OPT_SRTP_TX_KEY = 'x', 393 417 OPT_SRTP_RX_KEY = 'y', 418 OPT_SRTP_DTLS_CLIENT = 'd', 419 OPT_SRTP_DTLS_SERVER = 'D', 394 420 OPT_HELP = 'h', 395 421 }; … … 409 435 { "srtp-tx-key", 1, 0, OPT_SRTP_TX_KEY }, 410 436 { "srtp-rx-key", 1, 0, OPT_SRTP_RX_KEY }, 437 { "srtp-dtls-client", 0, 0, OPT_SRTP_DTLS_CLIENT }, 438 { "srtp-dtls-server", 0, 0, OPT_SRTP_DTLS_SERVER }, 411 439 #endif 412 440 { "help", 0, 0, OPT_HELP }, … … 510 538 pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2); 511 539 break; 540 case OPT_SRTP_DTLS_CLIENT: 541 is_dtls_client = PJ_TRUE; 542 if (is_dtls_server) { 543 printf("Error: Cannot be as both DTLS server & client\n"); 544 return 1; 545 } 546 break; 547 case OPT_SRTP_DTLS_SERVER: 548 is_dtls_server = PJ_TRUE; 549 if (is_dtls_client) { 550 printf("Error: Cannot be as both DTLS server & client\n"); 551 return 1; 552 } 553 break; 512 554 #endif 513 555 … … 525 567 526 568 /* Verify arguments. */ 527 if (dir & PJMEDIA_DIR_ENCODING ) {569 if (dir & PJMEDIA_DIR_ENCODING || is_dtls_client || is_dtls_server) { 528 570 if (remote_addr.sin_addr.s_addr == 0) { 529 571 printf("Error: remote address must be set\n"); … … 540 582 /* SRTP validation */ 541 583 if (use_srtp) { 542 if (!srtp_tx_key.slen || !srtp_rx_key.slen) 584 if (!is_dtls_client && !is_dtls_server && 585 (!srtp_tx_key.slen || !srtp_rx_key.slen)) 543 586 { 544 587 printf("Error: Key for each SRTP stream direction must be set\n"); … … 596 639 use_srtp, &srtp_crypto_suite, 597 640 &srtp_tx_key, &srtp_rx_key, 641 is_dtls_client, is_dtls_server, 598 642 #endif 599 643 &stream);
Note: See TracChangeset
for help on using the changeset viewer.