Skip to content

Commit fd27a52

Browse files
authored
Add private min and max version API (#823)
1 parent 620d642 commit fd27a52

7 files changed

Lines changed: 68 additions & 5 deletions

File tree

config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"time"
1616

1717
"github.com/pion/dtls/v3/pkg/crypto/elliptic"
18+
"github.com/pion/dtls/v3/pkg/protocol"
1819
"github.com/pion/dtls/v3/pkg/protocol/handshake"
1920
"github.com/pion/logging"
2021
)
@@ -236,6 +237,10 @@ type Config struct { //nolint:dupl
236237

237238
// ListenConfig used to create the underlying listener socket.
238239
listenConfig net.ListenConfig
240+
241+
minVersion protocol.Version
242+
243+
maxVersion protocol.Version
239244
}
240245

241246
func (c *Config) includeCertificateSuites() bool {

conn.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ func createConn(
191191
curves = filtered
192192
}
193193

194+
minVersion := config.minVersion
195+
if !minVersion.Equal(protocol.Version1_2) || !minVersion.Equal(protocol.Version1_3) {
196+
minVersion = protocol.Version1_2
197+
}
198+
199+
maxVersion := config.minVersion
200+
if !maxVersion.Equal(protocol.Version1_2) || !maxVersion.Equal(protocol.Version1_3) {
201+
maxVersion = protocol.Version1_2
202+
}
203+
194204
handshakeConfig := &handshakeConfig{
195205
localPSKCallback: config.PSK,
196206
localPSKIdentityHint: config.PSKIdentityHint,
@@ -226,6 +236,8 @@ func createConn(
226236
serverHelloMessageHook: config.ServerHelloMessageHook,
227237
certificateRequestMessageHook: config.CertificateRequestMessageHook,
228238
resumeState: resumeState,
239+
minVersion: minVersion,
240+
maxVersion: maxVersion,
229241
}
230242

231243
conn := &Conn{

handshaker.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"github.com/pion/dtls/v3/pkg/crypto/elliptic"
1616
"github.com/pion/dtls/v3/pkg/crypto/signaturehash"
17+
"github.com/pion/dtls/v3/pkg/protocol"
1718
"github.com/pion/dtls/v3/pkg/protocol/alert"
1819
"github.com/pion/dtls/v3/pkg/protocol/handshake"
1920
"github.com/pion/logging"
@@ -136,6 +137,9 @@ type handshakeConfig struct {
136137
certificateRequestMessageHook func(handshake.MessageCertificateRequest) handshake.Message
137138

138139
resumeState *State
140+
141+
minVersion protocol.Version
142+
maxVersion protocol.Version
139143
}
140144

141145
type flightConn interface {

options.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/pion/dtls/v3/pkg/crypto/elliptic"
14+
"github.com/pion/dtls/v3/pkg/protocol"
1415
"github.com/pion/dtls/v3/pkg/protocol/handshake"
1516
"github.com/pion/logging"
1617
)
@@ -80,6 +81,8 @@ type dtlsConfig struct { //nolint:dupl
8081
certificateRequestMessageHook func(handshake.MessageCertificateRequest) handshake.Message
8182
onConnectionAttempt func(net.Addr) error
8283
listenConfig net.ListenConfig
84+
minVersion protocol.Version
85+
maxVersion protocol.Version
8386
}
8487

8588
// applyDefaults applies default values to the config.
@@ -124,6 +127,8 @@ func (c *dtlsConfig) toConfig() *Config {
124127
CertificateRequestMessageHook: c.certificateRequestMessageHook,
125128
OnConnectionAttempt: c.onConnectionAttempt,
126129
listenConfig: c.listenConfig,
130+
minVersion: c.minVersion,
131+
maxVersion: c.maxVersion,
127132
}
128133

129134
if len(c.certificates) > 0 {
@@ -561,6 +566,34 @@ func WithClientHelloMessageHook(fn func(handshake.MessageClientHello) handshake.
561566
})
562567
}
563568

569+
// MinVersion sets the minimum TLS version that is acceptable.
570+
// By default, DTLS 1.2 is currently used as the minimum as it's the only supported version.
571+
func withMinVersion(version protocol.Version) Option { // nolint:unused
572+
return sharedOption(func(c *dtlsConfig) error {
573+
if protocol.IsSupportedVersion(version) {
574+
c.minVersion = version
575+
576+
return nil
577+
}
578+
579+
return errUnsupportedProtocolVersion
580+
})
581+
}
582+
583+
// MaxVersion sets the maxiumum TLS version that is acceptable.
584+
// By default, DTLS 1.2 is currently used as the minimum as it's the only supported version.
585+
func withMaxVersion(version protocol.Version) Option { // nolint:unused
586+
return sharedOption(func(c *dtlsConfig) error {
587+
if protocol.IsSupportedVersion(version) {
588+
c.maxVersion = version
589+
590+
return nil
591+
}
592+
593+
return errUnsupportedProtocolVersion
594+
})
595+
}
596+
564597
// serverOnlyOption wraps an apply function for server-only options.
565598
type serverOnlyOption func(*dtlsConfig) error
566599

options_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/pion/dtls/v3/pkg/crypto/elliptic"
1414
"github.com/pion/dtls/v3/pkg/crypto/selfsign"
1515
dtlsnet "github.com/pion/dtls/v3/pkg/net"
16+
"github.com/pion/dtls/v3/pkg/protocol"
1617
"github.com/pion/transport/v4/dpipe"
1718
"github.com/stretchr/testify/require"
1819
)
@@ -268,6 +269,14 @@ func TestInvalidNumericOptionsReturnError(t *testing.T) {
268269
_, err = buildServerConfig(WithExtendedMasterSecret(ExtendedMasterSecretType(100)))
269270
require.ErrorIs(t, err, errInvalidExtendedMasterSecretType)
270271
})
272+
273+
t.Run("InvalidVersions", func(t *testing.T) {
274+
_, err := buildClientConfig(withMinVersion(protocol.Version{}))
275+
require.ErrorIs(t, err, errUnsupportedProtocolVersion)
276+
277+
_, err = buildClientConfig(withMaxVersion(protocol.Version{}))
278+
require.ErrorIs(t, err, errUnsupportedProtocolVersion)
279+
})
271280
}
272281

273282
// TestDefaultsAreApplied verifies that defaults are applied before options.

pkg/protocol/version.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ func (v Version) Equal(x Version) bool {
2727
// IsSupportedBytes returns true if it's supported by Pion. Only DTLS 1.2 is currently supported.
2828
// DTLS 1.3 is a work in progress and is currently being implemented.
2929
func IsSupportedBytes(major uint8, minor uint8) bool {
30-
return major == 0xfe && (minor == 0xfd || minor == 0xfc)
30+
return major == Version1_2.Major && minor == Version1_2.Minor
3131
}
3232

3333
// IsSupportedVersion returns true if it's supported by Pion. Only DTLS 1.2 is currently supported.
3434
// DTLS 1.3 is a work in progress and is currently being implemented.
3535
func IsSupportedVersion(v Version) bool {
36-
return v.Equal(Version1_2) || v.Equal(Version1_3)
36+
return v.Equal(Version1_2)
3737
}
3838

3939
// IsValidBytes returns true if the bytes represent a valid DTLS version as defined in RFC9147 below.
40-
// Note that this is not the same as whether it's *supported* by Pion. Please see IsSupportedBytes() for more info.
40+
// Note that this is not the same as whether it's *supported* by Pion. Please see IsSupportedBytes() for more info.
4141
//
4242
// https://tools.ietf.org/html/rfc9147#section-5.3 (see legacy_version)
4343
func IsValidBytes(major uint8, minor uint8) bool {

pkg/protocol/version_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestIsSupportedBytes(t *testing.T) {
3838
want bool
3939
}{
4040
{0xfe, 0xfd, true}, // DTLS 1.2
41-
{0xfe, 0xfc, true}, // DTLS 1.3 (work in progress)
41+
{0xfe, 0xfc, false}, // DTLS 1.3 (WIP)
4242
{0xfe, 0xff, false}, // DTLS 1.0 not supported
4343
{0x03, 0x03, false}, // TLS 1.2, not DTLS
4444
{0x00, 0x00, false},
@@ -56,7 +56,7 @@ func TestIsSupportedVersion(t *testing.T) {
5656
want bool
5757
}{
5858
{Version1_2, true},
59-
{Version1_3, true}, // WIP, supported
59+
{Version1_3, false}, // WIP
6060
{Version1_0, false}, // not supported
6161
{Version{Major: 0x03, Minor: 0x03}, false}, // TLS 1.2, not DTLS
6262
}

0 commit comments

Comments
 (0)