Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
433 changes: 389 additions & 44 deletions conn.go

Large diffs are not rendered by default.

209 changes: 207 additions & 2 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3127,10 +3127,20 @@ func TestEllipticCurveConfiguration(t *testing.T) {
assert.True(t, ok, "Failed to default Elliptic curves")

if len(test.ConfigCurves) != 0 {
assert.Equal(t, len(test.HandshakeCurves), len(server.fsm.cfg.ellipticCurves), "Failed to configure Elliptic curves")
assert.Equal(
t,
len(test.HandshakeCurves),
len(server.fsm.(*handshakeFSM12).cfg.ellipticCurves), //nolint:forcetypeassert
"Failed to configure Elliptic curves",
)

for i, c := range test.ConfigCurves {
assert.Equal(t, c, server.fsm.cfg.ellipticCurves[i], "Failed to maintain Elliptic curve order")
assert.Equal(
t,
c,
server.fsm.(*handshakeFSM12).cfg.ellipticCurves[i], //nolint:forcetypeassert
"Failed to maintain Elliptic curve order",
)
}
}

Expand Down Expand Up @@ -3500,3 +3510,198 @@ func TestCloseWithoutHandshake(t *testing.T) {
assert.NoError(t, err)
assert.NoError(t, server.Close())
}

// WIP! Tests if DTLS 1.3 handshake flow is enabled and the correct error is returned.
func TestDTLS13Enabled(t *testing.T) {
ca, cb := dpipe.Pipe()

// Setup client
clientCert, err := selfsign.GenerateSelfSigned()
assert.NoError(t, err)

clientcfg, err := buildClientConfig(
WithCertificates(clientCert),
WithInsecureSkipVerify(true),
)

assert.NoError(t, err)

clientcfg.minVersion = protocol.Version1_3
clientcfg.maxVersion = protocol.Version1_3

client, err := Client(dtlsnet.PacketConnFromConn(ca), ca.RemoteAddr(), clientcfg)
assert.NoError(t, err)
defer func() {
_ = client.Close()
}()

_, ok := client.ConnectionState()
assert.False(t, ok)

ctxClient, cancelClient := context.WithTimeout(context.Background(), 5*time.Second)
defer cancelClient()
errorChannel := make(chan error)
go func() {
errC := client.HandshakeContext(ctxClient)
errorChannel <- errC
}()

err = <-errorChannel
assert.Error(t, err)
assert.ErrorIs(t, err, errStateUnimplemented13)

// Setup server
serverCert, err := selfsign.GenerateSelfSigned()
assert.NoError(t, err)

servercfg, err := buildServerConfig(
WithCertificates(serverCert),
WithInsecureSkipVerify(true),
)

assert.NoError(t, err)

servercfg.minVersion = protocol.Version1_3
servercfg.maxVersion = protocol.Version1_3

server, err := Server(dtlsnet.PacketConnFromConn(cb), cb.RemoteAddr(), servercfg)
assert.NoError(t, err)
defer func() {
_ = server.Close()
}()

_, ok = server.ConnectionState()
assert.False(t, ok)

ctxServer, cancelServer := context.WithTimeout(context.Background(), 5*time.Second)
defer cancelServer()
go func() {
errS := server.HandshakeContext(ctxServer)
errorChannel <- errS
}()
err = <-errorChannel
assert.Error(t, err)
assert.ErrorIs(t, err, errStateUnimplemented13)
}

// WIP! Tests if the dual stack mode client managed to negotiate a version successfully.
func TestDTLSDualStackClient(t *testing.T) {
defer test.CheckRoutines(t)()
defer test.TimeOut(time.Second * 10).Stop()

// Setup client
clientCert, err := selfsign.GenerateSelfSigned()
assert.NoError(t, err)

clientcfg, err := buildClientConfig(
WithCertificates(clientCert),
WithInsecureSkipVerify(true),
)

assert.NoError(t, err)

clientcfg.minVersion = protocol.Version1_2
clientcfg.maxVersion = protocol.Version1_3

// Setup server
serverCert, err := selfsign.GenerateSelfSigned()
assert.NoError(t, err)

servercfg, err := buildServerConfig(
WithCertificates(serverCert),
WithInsecureSkipVerify(true),
)

assert.NoError(t, err)

servercfg.minVersion = protocol.Version1_2
servercfg.maxVersion = protocol.Version1_2

testDTLSDualStack(t, *clientcfg, *servercfg)
}

// WIP! Tests if the dual stack mode server managed to negotiate a version successfully.
func TestDTLSDualStackServer(t *testing.T) {
defer test.CheckRoutines(t)()
defer test.TimeOut(time.Second * 10).Stop()

// Setup client
clientCert, err := selfsign.GenerateSelfSigned()
assert.NoError(t, err)

clientcfg, err := buildClientConfig(
WithCertificates(clientCert),
WithInsecureSkipVerify(true),
)

assert.NoError(t, err)

clientcfg.minVersion = protocol.Version1_2
clientcfg.maxVersion = protocol.Version1_2

// Setup server
serverCert, err := selfsign.GenerateSelfSigned()
assert.NoError(t, err)

servercfg, err := buildServerConfig(
WithCertificates(serverCert),
WithInsecureSkipVerify(true),
)

assert.NoError(t, err)

servercfg.minVersion = protocol.Version1_2
servercfg.maxVersion = protocol.Version1_3

testDTLSDualStack(t, *clientcfg, *servercfg)
}

// WIP! Tests if the dual stack mode managed to negotiate a version successfully.
func testDTLSDualStack(t *testing.T, clientCfg Config, serverCfg Config) {
t.Helper()
ca, cb := dpipe.Pipe()

client, err := Client(dtlsnet.PacketConnFromConn(ca), ca.RemoteAddr(), &clientCfg)
assert.NoError(t, err)
defer func() {
_ = client.Close()
}()

_, ok := client.ConnectionState()
assert.False(t, ok)

ctxClient, cancelClient := context.WithTimeout(context.Background(), 5*time.Second)
defer cancelClient()
errorChannel := make(chan error, 2)

server, err := Server(dtlsnet.PacketConnFromConn(cb), cb.RemoteAddr(), &serverCfg)
assert.NoError(t, err)
defer func() {
_ = server.Close()
}()

_, ok = server.ConnectionState()
assert.False(t, ok)

ctxServer, cancelServer := context.WithTimeout(context.Background(), 5*time.Second)
defer cancelServer()

go func() {
errC := client.HandshakeContext(ctxClient)
errorChannel <- errC
}()

go func() {
errS := server.HandshakeContext(ctxServer)
errorChannel <- errS
}()

err = <-errorChannel
assert.NoError(t, err)

err = <-errorChannel
assert.NoError(t, err)

assert.NoError(t, server.Close())
assert.NoError(t, client.Close())
}
6 changes: 6 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ var (
//nolint:err113
errUnsupportedProtocolVersion = &FatalError{Err: errors.New("unsupported protocol version")}
//nolint:err113
errNoCommonProtocolVersion = &FatalError{Err: errors.New("no common DTLS version between peer and local")}
//nolint:err113
errPSKAndIdentityMustBeSetForClient = &FatalError{
Err: errors.New("PSK and PSK Identity Hint must both be set for client"),
}
Expand All @@ -128,6 +130,10 @@ var (

//nolint:err113
errInvalidFlight = &InternalError{Err: errors.New("invalid flight number")}
//nolint:err113,unused
errFlightUnimplemented13 = &InternalError{Err: errors.New("unimplemented DTLS 1.3 flight")}
//nolint:err113
errStateUnimplemented13 = &InternalError{Err: errors.New("unimplemented DTLS 1.3 handshake state")}
//nolint:err113
errKeySignatureGenerateUnimplemented = &InternalError{
Err: errors.New("unable to generate key signature, unimplemented"),
Expand Down
Loading
Loading