Skip to content

Commit

Permalink
Add SkipHelloVerify option to dTLS
Browse files Browse the repository at this point in the history
This is a common behavior for WebRTC Peer on browser stack
where DoS resistance on DTLS level is redundant as this is
built into ICE.
  • Loading branch information
xiaokangwang authored and stv0g committed Feb 3, 2023
1 parent 11ea8c2 commit 0473adf
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 4 deletions.
5 changes: 5 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ type Config struct {
// the server. If this is unacceptable to the server then it may abort
// the handshake.
GetClientCertificate func(*CertificateRequestInfo) (*tls.Certificate, error)

// InsecureSkipVerifyHello, if true and when acting as server, allow client to
// skip hello verify phase and receive ServerHello after initial ClientHello.
// This have implication on DoS attack resistance.
InsecureSkipVerifyHello bool
}

func defaultConnectContextMaker() (context.Context, func()) {
Expand Down
1 change: 1 addition & 0 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
ellipticCurves: curves,
localGetCertificate: config.GetCertificate,
localGetClientCertificate: config.GetClientCertificate,
insecureSkipHelloVerify: config.InsecureSkipVerifyHello,
}

// rfc5246#section-7.4.3
Expand Down
56 changes: 56 additions & 0 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/pion/dtls/v2/pkg/protocol/extension"
"github.com/pion/dtls/v2/pkg/protocol/handshake"
"github.com/pion/dtls/v2/pkg/protocol/recordlayer"
"github.com/pion/logging"
"github.com/pion/transport/v2/test"
)

Expand Down Expand Up @@ -2914,3 +2915,58 @@ func TestEllipticCurveConfiguration(t *testing.T) {
}()
}
}

func TestSkipHelloVerify(t *testing.T) {
report := test.CheckRoutines(t)
defer report()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

ca, cb := dpipe.Pipe()
certificate, err := selfsign.GenerateSelfSigned()
if err != nil {
t.Fatal(err)
}
gotHello := make(chan struct{})

go func() {
server, sErr := testServer(ctx, cb, &Config{
Certificates: []tls.Certificate{certificate},
LoggerFactory: logging.NewDefaultLoggerFactory(),
InsecureSkipVerifyHello: true,
}, false)
if sErr != nil {
t.Error(sErr)
return
}
buf := make([]byte, 1024)
if _, sErr = server.Read(buf); sErr != nil {
t.Error(sErr)
}
gotHello <- struct{}{}
if sErr = server.Close(); sErr != nil { //nolint:contextcheck
t.Error(sErr)
}
}()

client, err := testClient(ctx, ca, &Config{
LoggerFactory: logging.NewDefaultLoggerFactory(),
InsecureSkipVerify: true,
}, false)
if err != nil {
t.Fatal(err)
}
if _, err = client.Write([]byte("hello")); err != nil {
t.Error(err)
}
select {
case <-gotHello:
// OK
case <-time.After(time.Second * 5):
t.Error("timeout")
}

if err = client.Close(); err != nil {
t.Error(err)
}
}
16 changes: 12 additions & 4 deletions flight0handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@ func flight0Parse(ctx context.Context, c flightConn, state *State, cache *handsh
}
}

return handleHelloResume(clientHello.SessionID, state, cfg, flight2)
nextFlight := flight2

if cfg.insecureSkipHelloVerify {
nextFlight = flight4
}

return handleHelloResume(clientHello.SessionID, state, cfg, nextFlight)
}

func handleHelloResume(sessionID []byte, state *State, cfg *handshakeConfig, next flightVal) (flightVal, *alert.Alert, error) {
Expand Down Expand Up @@ -109,9 +115,11 @@ func handleHelloResume(sessionID []byte, state *State, cfg *handshakeConfig, nex

func flight0Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) {
// Initialize
state.cookie = make([]byte, cookieLength)
if _, err := rand.Read(state.cookie); err != nil {
return nil, nil, err
if !cfg.insecureSkipHelloVerify {
state.cookie = make([]byte, cookieLength)
if _, err := rand.Read(state.cookie); err != nil {
return nil, nil, err
}
}

var zeroEpoch uint16
Expand Down
1 change: 1 addition & 0 deletions handshaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ type handshakeConfig struct {
retransmitInterval time.Duration
customCipherSuites func() []CipherSuite
ellipticCurves []elliptic.Curve
insecureSkipHelloVerify bool

onFlightState func(flightVal, handshakeState)
log logging.LeveledLogger
Expand Down

0 comments on commit 0473adf

Please sign in to comment.