WebRTC SRTP decryption
Asked Answered
C

3

9

I am trying to build an SRTP to RTP stream converter and I am having issues getting the Master Key from the WebRTC peerconnection I am creating.

From what I understand, with a DES exchange, the key is exchange via the SDP exchange and is shown in the a=crypto field. So, this situation seems pretty straight forward(please correct me if I am wrong), but ultimately useless as WebRTC standardization is now demanding that DES should not be used(only Chrome supports it now and it may be removed in the future).

For DTLS there is the fingerprint field in the SDP, is that a hash of the certificate desired to be utilized in the future exchange?[EDIT: After doing some reading, I am thinking that that is not the case] I would think with knowledge of the fingerprint along side the ability to parse through the DTLS packets in the exchange I should be able to grab the Master Key to decode the SRTP stream, but I am hitting a wall as I do not know where to look or even 100% sure if it is possible.

So, in short, is it even feasible(without getting into the lower C++ API and creating my own implementation of WebRTC) to decode the SRTP feed that is created with a WebRTC PeerConnection in Chrome and FireFox(possibly through packet sniffing with the information gleaned from the SDP exchange)?[EDIT: depressingly, it seems that access to the private part of the key(aka, the master key) is not possible...please correct if I am wrong]

Catechetical answered 27/3, 2014 at 15:25 Comment(3)
Related: Can I specify my own encryption key in DTLS-SRTP encryptionBigham
I believe the only option currently is to use the native API and not the main stream browser implementationsCatechetical
With the library support from the accepted answer, were you able to finally convert SRTP to RTP (unencrypted)? I am also interested in this approach to implement my WebRTC SFU, but don't know where to start. Have asked few questions with bounties to no luck. See if you can help: How to use libsrtp or similar library to decrypt/encrypt the WebRTC data stream? and How to integrate part of WebRTC... If there is any library for SRTP to RTP, then would love to use it. Thanks.Signalman
M
7

tHere is some code using openssl and libsrtp native api

#define SRTP_MASTER_KEY_KEY_LEN 16
#define SRTP_MASTER_KEY_SALT_LEN 14
static void dtls_srtp_init( struct transport_dtls *dtls )
{

/*
  When SRTP mode is in effect, different keys are used for ordinary
   DTLS record protection and SRTP packet protection.  These keys are
   generated using a TLS exporter [RFC5705] to generate

   2 * (SRTPSecurityParams.master_key_len +
        SRTPSecurityParams.master_salt_len) bytes of data

   which are assigned as shown below.  The per-association context value
   is empty.

   client_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
   server_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
   client_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
   server_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
*/
  int code;
  err_status_t     err;
  srtp_policy_t policy;
  char dtls_buffer[SRTP_MASTER_KEY_KEY_LEN * 2 + SRTP_MASTER_KEY_SALT_LEN * 2];
  char client_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
  char server_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
  size_t offset = 0;

  /*
   The exporter label for this usage is "EXTRACTOR-dtls_srtp".  (The
   "EXTRACTOR" prefix is for historical compatibility.)
   RFC 5764 4.2.  Key Derivation
  */
  const char * label = "EXTRACTOR-dtls_srtp";

  SRTP_PROTECTION_PROFILE * srtp_profile= SSL_get_selected_srtp_profile( dtls->ssl );

/* SSL_export_keying_material exports a value derived from the master secret,
 * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
 * optional context. (Since a zero length context is allowed, the |use_context|
 * flag controls whether a context is included.)
 *
 * It returns 1 on success and zero otherwise.
 */
  code = SSL_export_keying_material(dtls->ssl, 
                                    dtls_buffer, 
                                    sizeof(dtls_buffer),
                                    label, 
                                    strlen( label),
                                    NULL,
                                    0, 
                                    PJ_FALSE);

  memcpy(&client_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
  offset += SRTP_MASTER_KEY_KEY_LEN;
  memcpy(&server_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
  offset += SRTP_MASTER_KEY_KEY_LEN;
  memcpy(&client_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
  offset += SRTP_MASTER_KEY_SALT_LEN;
  memcpy(&server_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN); 

  switch( srtp_profile->id )
  {
  case SRTP_AES128_CM_SHA1_80:
    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
    break;
  case SRTP_AES128_CM_SHA1_32:
    crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);   // rtp is 32,
    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);  // rtcp still 80
    break;
  default:
    assert(0);
  }
  policy.ssrc.value = 0;
  policy.next = NULL;

  /* Init transmit direction */
  policy.ssrc.type = ssrc_any_outbound;  
  policy.key = client_write_key;    

  err = srtp_create(&dtls->srtp_ctx_rx, &policy);
  if (err != err_status_ok) {
    printf("not working\n");
  } 

  /* Init receive direction */
  policy.ssrc.type = ssrc_any_inbound;  
  policy.key = server_write_key;    

  err = srtp_create(&dtls->srtp_ctx_tx, &policy);
  if (err != err_status_ok) {
    printf("not working\n");
  } 

}
Millan answered 24/6, 2014 at 11:16 Comment(2)
dude, love it! Is this part of a particular project?Catechetical
Tanks, bwtrent! It's a part of CrystalVu SDK (integrit.com/products/240-crystalvu-video-conferencing-sdk) providing interoperability with sipml5 (sipml5.org)Millan
R
4

I found 'SSL_export_keying_material' Which can take a key from SSL mechanism (after DTLS handshake) and use it for SRTP.

I am not an expert, Just hitting the wall like you...

Rhinelandpalatinate answered 17/6, 2014 at 12:46 Comment(0)
O
4

It's not clear if this is your case, but note it's not possible to access the audio/video from (i.e.:unencrypt) the SRTP merely being a passive observer - that's the whole point of having transport encryption.

The protocol (DTLS-SRTP) works roughly like this:

If you don't have access to at least one of the private parts of the keypairs, it's not possible at all to decrypt the connection. If the endpoints choose to use a Diffie-Hellman key exchange on the handshake, a passive attacker will not be able to get the derived key, even with access to both private keys. This property is called forward secrecy.

The only reliable way of accessing the SRTP contents is doing the handshake yourself, implementing a active MITM (changing the fingerprints on the SDP) or getting the private key from the browser and restricting DH key-exchange (which, AFAIK, is not possible at all)

Origen answered 5/8, 2014 at 10:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.