Skip to content

Commit d19f1fe

Browse files
committed
Added support for Cryptex (RFC 9335)
This is final part of Cryptex (RFC 9335) implementation for pion/webrtc. Public API is based on WebRTC Extensions specification (W3C Editor's Draft from 19 December 2025).
1 parent 374c864 commit d19f1fe

15 files changed

Lines changed: 997 additions & 28 deletions

bundlepolicy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
22
// SPDX-License-Identifier: MIT
33

4+
// nolint:dupl,staticcheck
45
package webrtc
56

67
import (

configuration.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,8 @@ type Configuration struct {
5656
// AlwaysNegotiateDataChannels specifies whether the application prefers
5757
// to always negotiate data channels in the initial SDP offer.
5858
AlwaysNegotiateDataChannels bool `json:"alwaysNegotiateDataChannels,omitempty"`
59+
60+
// RTPHeaderEncryptionPolicy affects whether RTP header extension encryption
61+
// (RFC 9335 Cryptex) is negotiated.
62+
RTPHeaderEncryptionPolicy RTPHeaderEncryptionPolicy `json:"rtpHeaderEncryptionPolicy,omitempty"`
5963
}

configuration_js.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,9 @@ type Configuration struct {
4141
// to always negotiate data channels in the initial SDP offer.
4242
AlwaysNegotiateDataChannels bool
4343

44+
// RTPHeaderEncryptionPolicy affects whether RTP header extension encryption
45+
// (RFC 9335 Cryptex) is negotiated.
46+
RTPHeaderEncryptionPolicy RTPHeaderEncryptionPolicy
47+
4448
Certificates []Certificate `json:"certificates,omitempty"`
4549
}

dtlstransport.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type DTLSTransport struct {
4343
remoteCertificate []byte
4444
state DTLSTransportState
4545
srtpProtectionProfile srtp.ProtectionProfile
46+
cryptexMode srtp.CryptexMode
4647

4748
onStateChangeHandler func(DTLSTransportState)
4849
internalOnCloseHandler func()
@@ -192,12 +193,20 @@ func (t *DTLSTransport) GetRemoteCertificate() []byte {
192193
return t.remoteCertificate
193194
}
194195

195-
func (t *DTLSTransport) startSRTP() error {
196+
// startSRTP requires the caller holds the lock.
197+
func (t *DTLSTransport) startSRTP() error { //nolint:cyclop
196198
srtpConfig := &srtp.Config{
197199
Profile: t.srtpProtectionProfile,
198200
BufferFactory: t.api.settingEngine.BufferFactory,
199201
LoggerFactory: t.api.settingEngine.LoggerFactory,
200202
}
203+
204+
if t.cryptexMode == srtp.CryptexModeEnabled || t.cryptexMode == srtp.CryptexModeRequired {
205+
opt := srtp.Cryptex(t.cryptexMode)
206+
srtpConfig.LocalOptions = append(srtpConfig.LocalOptions, opt)
207+
srtpConfig.RemoteOptions = append(srtpConfig.RemoteOptions, opt)
208+
}
209+
201210
if t.api.settingEngine.replayProtection.SRTP != nil {
202211
srtpConfig.RemoteOptions = append(
203212
srtpConfig.RemoteOptions,
@@ -567,3 +576,12 @@ func (t *DTLSTransport) streamsForSSRC(
567576
rtcpInterceptor: rtcpInterceptor,
568577
}, nil
569578
}
579+
580+
// rtpHeaderEncryptionNegotiated reports if RFC 9335 RTP Header Extension Encryption ("Cryptex")
581+
// has been negotiated and is enabled for this transceiver.
582+
func (t *DTLSTransport) rtpHeaderEncryptionNegotiated() bool {
583+
t.lock.RLock()
584+
defer t.lock.RUnlock()
585+
586+
return t.cryptexMode == srtp.CryptexModeEnabled || t.cryptexMode == srtp.CryptexModeRequired
587+
}

errors.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ var (
5353
// RTCPMuxPolicy was made after PeerConnection has been initialized.
5454
ErrModifyingRTCPMuxPolicy = errors.New("rtcp mux policy cannot be modified")
5555

56+
// errModifyingRTPHeaderEncryptionPolicy indicates that an attempt to modify
57+
// RTPHeaderEncryptionPolicy was made after PeerConnection has been initialized.
58+
errModifyingRTPHeaderEncryptionPolicy = errors.New("rtp header encryption policy cannot be modified")
59+
5660
// ErrModifyingICECandidatePoolSize indicates that an attempt to modify
5761
// ICECandidatePoolSize was made after PeerConnection has been initialized.
5862
ErrModifyingICECandidatePoolSize = errors.New("ice candidate pool size cannot be modified")
@@ -135,6 +139,10 @@ var (
135139
// ErrNoSRTPProtectionProfile indicates that the DTLS handshake completed and no SRTP Protection Profile was chosen.
136140
ErrNoSRTPProtectionProfile = errors.New("DTLS Handshake completed and no SRTP Protection Profile was chosen")
137141

142+
// ErrRTPHeaderEncryptionRequired indicates that the local endpoint requires
143+
// RFC 9335 Cryptex negotiation, but the remote SDP did not negotiate it.
144+
ErrRTPHeaderEncryptionRequired = errors.New("rtp header extension encryption required")
145+
138146
// ErrFailedToGenerateCertificateFingerprint indicates that we failed to generate the fingerprint
139147
// used for comparing certificates.
140148
ErrFailedToGenerateCertificateFingerprint = errors.New("failed to generate certificate fingerprint")

0 commit comments

Comments
 (0)