-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Add an abstraction to exchange keying material between the DTLS and SRTP package. - Construct & start the Session at the same time to avoid races.
- Loading branch information
Showing
5 changed files
with
175 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package srtp | ||
|
||
const labelExtractorDtlsSrtp = "EXTRACTOR-dtls_srtp" | ||
|
||
// KeyingMaterialExporter allows package SRTP to extract keying material | ||
type KeyingMaterialExporter interface { | ||
ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) | ||
} | ||
|
||
// ExtractSessionKeysFromDTLS allows setting the Config SessionKeys by | ||
// extracting them from DTLS. This behavior is defined in RFC5764: | ||
// https://tools.ietf.org/html/rfc5764 | ||
func (c *Config) ExtractSessionKeysFromDTLS(exporter KeyingMaterialExporter, isClient bool) error { | ||
keyingMaterial, err := exporter.ExportKeyingMaterial(labelExtractorDtlsSrtp, nil, (keyLen*2)+(saltLen*2)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
offset := 0 | ||
clientWriteKey := append([]byte{}, keyingMaterial[offset:offset+keyLen]...) | ||
offset += keyLen | ||
|
||
serverWriteKey := append([]byte{}, keyingMaterial[offset:offset+keyLen]...) | ||
offset += keyLen | ||
|
||
clientWriteKey = append(clientWriteKey, keyingMaterial[offset:offset+saltLen]...) | ||
offset += saltLen | ||
|
||
serverWriteKey = append(serverWriteKey, keyingMaterial[offset:offset+saltLen]...) | ||
|
||
if isClient { | ||
c.Keys.LocalMasterKey = clientWriteKey[0:keyLen] | ||
c.Keys.LocalMasterSalt = clientWriteKey[keyLen:] | ||
c.Keys.RemoteMasterKey = serverWriteKey[0:keyLen] | ||
c.Keys.RemoteMasterSalt = serverWriteKey[keyLen:] | ||
return nil | ||
} | ||
|
||
c.Keys.LocalMasterKey = serverWriteKey[0:keyLen] | ||
c.Keys.LocalMasterSalt = serverWriteKey[keyLen:] | ||
c.Keys.RemoteMasterKey = clientWriteKey[0:keyLen] | ||
c.Keys.RemoteMasterSalt = clientWriteKey[keyLen:] | ||
return nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package srtp | ||
|
||
import ( | ||
"bytes" | ||
"crypto/rand" | ||
"fmt" | ||
"testing" | ||
) | ||
|
||
type mockKeyingMaterialExporter struct { | ||
exported []byte | ||
} | ||
|
||
func (m *mockKeyingMaterialExporter) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) { | ||
if label != labelExtractorDtlsSrtp { | ||
return nil, fmt.Errorf("exporter called with wrong label: %s", label) | ||
} | ||
|
||
m.exported = make([]byte, length) | ||
if _, err := rand.Read(m.exported); err != nil { | ||
return nil, fmt.Errorf("failed to create random bytes: %v", err) | ||
} | ||
|
||
return m.exported, nil | ||
} | ||
|
||
func TestExtractSessionKeysFromDTLS(t *testing.T) { | ||
tt := []struct { | ||
config *Config | ||
}{ | ||
{&Config{Profile: ProtectionProfileAes128CmHmacSha1_80}}, | ||
} | ||
|
||
m := &mockKeyingMaterialExporter{} | ||
|
||
for i, tc := range tt { | ||
// Test client | ||
err := tc.config.ExtractSessionKeysFromDTLS(m, true) | ||
if err != nil { | ||
t.Errorf("failed to extract keys for %d-client: %v", i, err) | ||
} | ||
|
||
keys := tc.config.Keys | ||
clientMaterial := append([]byte{}, keys.LocalMasterKey...) | ||
clientMaterial = append(clientMaterial, keys.RemoteMasterKey...) | ||
clientMaterial = append(clientMaterial, keys.LocalMasterSalt...) | ||
clientMaterial = append(clientMaterial, keys.RemoteMasterSalt...) | ||
|
||
if !bytes.Equal(clientMaterial, m.exported) { | ||
t.Errorf("material reconstruction failed for %d-client:\n%#v\nexpected\n%#v", i, clientMaterial, m.exported) | ||
} | ||
|
||
// Test server | ||
err = tc.config.ExtractSessionKeysFromDTLS(m, false) | ||
if err != nil { | ||
t.Errorf("failed to extract keys for %d-server: %v", i, err) | ||
} | ||
|
||
keys = tc.config.Keys | ||
serverMaterial := append([]byte{}, keys.RemoteMasterKey...) | ||
serverMaterial = append(serverMaterial, keys.LocalMasterKey...) | ||
serverMaterial = append(serverMaterial, keys.RemoteMasterSalt...) | ||
serverMaterial = append(serverMaterial, keys.LocalMasterSalt...) | ||
|
||
if !bytes.Equal(serverMaterial, m.exported) { | ||
t.Errorf("material reconstruction failed for %d-server:\n%#v\nexpected\n%#v", i, serverMaterial, m.exported) | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters