Skip to content

Commit c9332d7

Browse files
authored
Expect non-padded crypto profile key in SDP (fallback to padded) (#16)
RFC 4568 section 6.1: ``` When base64 decoding the key and salt, padding characters (i.e., one or two "=" at the end of the base64-encoded data) are discarded ```
1 parent c86da91 commit c9332d7

2 files changed

Lines changed: 61 additions & 28 deletions

File tree

sdp/offer.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,12 @@ func parseSRTPProfile(val string) (*srtp.Profile, error) {
399399
if !ok {
400400
return nil, nil // ignore
401401
}
402-
keys, err := base64.StdEncoding.WithPadding(base64.StdPadding).DecodeString(skey)
402+
keys, err := base64.RawStdEncoding.DecodeString(skey)
403403
if err != nil {
404-
return nil, fmt.Errorf("cannot parse crypto key %q: %v", skey, err)
404+
// Fallback to padded encoding if raw fails
405+
if keys, err = base64.StdEncoding.DecodeString(skey); err != nil {
406+
return nil, fmt.Errorf("cannot parse crypto key %q: %v", skey, err)
407+
}
405408
}
406409
var salt []byte
407410
if sp, err := prof.Parse(); err == nil {

sdp/offer_test.go

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -412,30 +412,7 @@ a=sendrecv
412412
}
413413

414414
func TestParseOfferSRTP(t *testing.T) {
415-
const sdpData = `v=0
416-
o=lin 3723 713 IN IP4 192.168.0.2
417-
s=Talk
418-
c=IN IP4 192.168.0.2
419-
t=0 0
420-
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
421-
a=record:off
422-
m=audio 11200 RTP/SAVP 96 0 9 97 101
423-
a=rtpmap:96 opus/48000/2
424-
a=fmtp:96 useinbandfec=1
425-
a=rtpmap:97 telephone-event/48000
426-
a=rtpmap:101 telephone-event/8000
427-
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:pMIPxjzYIG5TQuIWfkjTnaACVrzohhFfOGhSMgV1
428-
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:ZKkTQfuCsliegVZtFSya3Z6oEVUtSwjGCfHlbrMf
429-
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:BvoLeRu5IcBkgNN14qtqaxi0r7ei2rwuBSodd0SANggS9JHsp5IU7lhEsyna1A==
430-
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:j92SDyNTUe0BNGk4LeeCsPqX0qwPP/e9TLafvd7L9waM8r4arjzgUqs7uUERyg==
431-
a=crypto:5 AEAD_AES_128_GCM inline:gGetEkQgGk4NZIoKj/cbFpRkHdocmKlP0u3VMw==
432-
a=crypto:6 AEAD_AES_256_GCM inline:EFFzS2FMyNoYcVcaARU+nvk+JhHmVbvdFtRxZuRi9rDmLYpLms5ySv93iy0=
433-
a=rtcp-fb:* trr-int 5000
434-
a=rtcp-fb:* ccm tmmbr
435-
`
436-
v, err := ParseOffer([]byte(sdpData))
437-
require.NoError(t, err)
438-
require.Equal(t, []srtp.Profile{
415+
vProfiles := []srtp.Profile{
439416
{
440417
Index: 1,
441418
Profile: "AES_CM_128_HMAC_SHA1_80",
@@ -470,6 +447,59 @@ a=rtcp-fb:* ccm tmmbr
470447
Profile: "AEAD_AES_256_GCM",
471448
Key: []uint8{0x10, 0x51, 0x73, 0x4b, 0x61, 0x4c, 0xc8, 0xda, 0x18, 0x71, 0x57, 0x1a, 0x1, 0x15, 0x3e, 0x9e, 0xf9, 0x3e, 0x26, 0x11, 0xe6, 0x55, 0xbb, 0xdd, 0x16, 0xd4, 0x71, 0x66, 0xe4, 0x62, 0xf6, 0xb0, 0xe6, 0x2d, 0x8a, 0x4b, 0x9a, 0xce, 0x72, 0x4a, 0xff, 0x77, 0x8b, 0x2d},
472449
},
473-
},
474-
v.CryptoProfiles)
450+
}
451+
452+
t.Run("CryptoProfileBase64Padding", func(t *testing.T) {
453+
const sdpData = `v=0
454+
o=lin 3723 713 IN IP4 192.168.0.2
455+
s=Talk
456+
c=IN IP4 192.168.0.2
457+
t=0 0
458+
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
459+
a=record:off
460+
m=audio 11200 RTP/SAVP 96 0 9 97 101
461+
a=rtpmap:96 opus/48000/2
462+
a=fmtp:96 useinbandfec=1
463+
a=rtpmap:97 telephone-event/48000
464+
a=rtpmap:101 telephone-event/8000
465+
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:pMIPxjzYIG5TQuIWfkjTnaACVrzohhFfOGhSMgV1
466+
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:ZKkTQfuCsliegVZtFSya3Z6oEVUtSwjGCfHlbrMf
467+
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:BvoLeRu5IcBkgNN14qtqaxi0r7ei2rwuBSodd0SANggS9JHsp5IU7lhEsyna1A==
468+
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:j92SDyNTUe0BNGk4LeeCsPqX0qwPP/e9TLafvd7L9waM8r4arjzgUqs7uUERyg==
469+
a=crypto:5 AEAD_AES_128_GCM inline:gGetEkQgGk4NZIoKj/cbFpRkHdocmKlP0u3VMw==
470+
a=crypto:6 AEAD_AES_256_GCM inline:EFFzS2FMyNoYcVcaARU+nvk+JhHmVbvdFtRxZuRi9rDmLYpLms5ySv93iy0=
471+
a=rtcp-fb:* trr-int 5000
472+
a=rtcp-fb:* ccm tmmbr
473+
`
474+
v, err := ParseOffer([]byte(sdpData))
475+
require.NoError(t, err)
476+
require.Equal(t, vProfiles, v.CryptoProfiles)
477+
})
478+
479+
t.Run("CryptoProfileBase64NoPadding", func(t *testing.T) {
480+
const sdpData = `v=0
481+
o=lin 3723 713 IN IP4 192.168.0.2
482+
s=Talk
483+
c=IN IP4 192.168.0.2
484+
t=0 0
485+
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
486+
a=record:off
487+
m=audio 11200 RTP/SAVP 96 0 9 97 101
488+
a=rtpmap:96 opus/48000/2
489+
a=fmtp:96 useinbandfec=1
490+
a=rtpmap:97 telephone-event/48000
491+
a=rtpmap:101 telephone-event/8000
492+
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:pMIPxjzYIG5TQuIWfkjTnaACVrzohhFfOGhSMgV1
493+
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:ZKkTQfuCsliegVZtFSya3Z6oEVUtSwjGCfHlbrMf
494+
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:BvoLeRu5IcBkgNN14qtqaxi0r7ei2rwuBSodd0SANggS9JHsp5IU7lhEsyna1A
495+
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:j92SDyNTUe0BNGk4LeeCsPqX0qwPP/e9TLafvd7L9waM8r4arjzgUqs7uUERyg
496+
a=crypto:5 AEAD_AES_128_GCM inline:gGetEkQgGk4NZIoKj/cbFpRkHdocmKlP0u3VMw
497+
a=crypto:6 AEAD_AES_256_GCM inline:EFFzS2FMyNoYcVcaARU+nvk+JhHmVbvdFtRxZuRi9rDmLYpLms5ySv93iy0
498+
a=rtcp-fb:* trr-int 5000
499+
a=rtcp-fb:* ccm tmmbr
500+
`
501+
v, err := ParseOffer([]byte(sdpData))
502+
require.NoError(t, err)
503+
require.Equal(t, vProfiles, v.CryptoProfiles)
504+
})
475505
}

0 commit comments

Comments
 (0)