Skip to content

Commit 61b3466

Browse files
mingyechSean-Der
authored andcommitted
Add ability to select cert based on ch rand bytes
1 parent eddca22 commit 61b3466

8 files changed

Lines changed: 93 additions & 0 deletions

File tree

certificate.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"crypto/x509"
1010
"fmt"
1111
"strings"
12+
13+
"github.com/pion/dtls/v2/pkg/protocol/handshake"
1214
)
1315

1416
// ClientHelloInfo contains information from a ClientHello message in order to
@@ -22,6 +24,9 @@ type ClientHelloInfo struct {
2224
// CipherSuites lists the CipherSuites supported by the client (e.g.
2325
// TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).
2426
CipherSuites []CipherSuiteID
27+
28+
// RandomBytes stores the client hello random bytes
29+
RandomBytes [handshake.RandomBytesLength]byte
2530
}
2631

2732
// CertificateRequestInfo contains information from a server's

config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ type Config struct {
198198
// https://datatracker.ietf.org/doc/html/rfc9146#section-4
199199
PaddingLengthGenerator func(uint) uint
200200

201+
// HelloRandomBytesGenerator generates custom client hello random bytes.
202+
HelloRandomBytesGenerator func() [handshake.RandomBytesLength]byte
203+
201204
// Handshake hooks: hooks can be used for testing invalid messages,
202205
// mimicking other implementations or randomizing fields, which is valuable
203206
// for applications that need censorship-resistance by making

conn.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ func handshakeConn(ctx context.Context, conn *Conn, config *Config, isClient boo
212212
localGetClientCertificate: config.GetClientCertificate,
213213
insecureSkipHelloVerify: config.InsecureSkipVerifyHello,
214214
connectionIDGenerator: config.ConnectionIDGenerator,
215+
helloRandomBytesGenerator: config.HelloRandomBytesGenerator,
215216
clientHelloMessageHook: config.ClientHelloMessageHook,
216217
serverHelloMessageHook: config.ServerHelloMessageHook,
217218
certificateRequestMessageHook: config.CertificateRequestMessageHook,

conn_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,3 +3363,76 @@ func TestApplicationDataQueueLimited(t *testing.T) {
33633363
ca.Close() // nolint
33643364
<-done
33653365
}
3366+
3367+
func TestHelloRandom(t *testing.T) {
3368+
report := test.CheckRoutines(t)
3369+
defer report()
3370+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
3371+
defer cancel()
3372+
3373+
ca, cb := dpipe.Pipe()
3374+
certificate, err := selfsign.GenerateSelfSigned()
3375+
if err != nil {
3376+
t.Fatal(err)
3377+
}
3378+
gotHello := make(chan struct{})
3379+
3380+
chRandom := [handshake.RandomBytesLength]byte{}
3381+
_, err = rand.Read(chRandom[:])
3382+
if err != nil {
3383+
t.Fatal(err)
3384+
}
3385+
3386+
go func() {
3387+
server, sErr := testServer(ctx, dtlsnet.PacketConnFromConn(cb), cb.RemoteAddr(), &Config{
3388+
GetCertificate: func(chi *ClientHelloInfo) (*tls.Certificate, error) {
3389+
if len(chi.CipherSuites) == 0 {
3390+
return &certificate, nil
3391+
}
3392+
3393+
if !bytes.Equal(chi.RandomBytes[:], chRandom[:]) {
3394+
t.Error("client hello random differs")
3395+
}
3396+
3397+
return &certificate, nil
3398+
},
3399+
LoggerFactory: logging.NewDefaultLoggerFactory(),
3400+
}, false)
3401+
if sErr != nil {
3402+
t.Error(sErr)
3403+
return
3404+
}
3405+
buf := make([]byte, 1024)
3406+
if _, sErr = server.Read(buf); sErr != nil {
3407+
t.Error(sErr)
3408+
}
3409+
gotHello <- struct{}{}
3410+
if sErr = server.Close(); sErr != nil { //nolint:contextcheck
3411+
t.Error(sErr)
3412+
}
3413+
}()
3414+
3415+
client, err := testClient(ctx, dtlsnet.PacketConnFromConn(ca), ca.RemoteAddr(), &Config{
3416+
LoggerFactory: logging.NewDefaultLoggerFactory(),
3417+
HelloRandomBytesGenerator: func() [handshake.RandomBytesLength]byte {
3418+
return chRandom
3419+
},
3420+
InsecureSkipVerify: true,
3421+
}, false)
3422+
if err != nil {
3423+
t.Fatal(err)
3424+
}
3425+
if _, err = client.Write([]byte("hello")); err != nil {
3426+
t.Error(err)
3427+
}
3428+
select {
3429+
case <-gotHello:
3430+
// OK
3431+
case <-time.After(time.Second * 5):
3432+
t.Error("timeout")
3433+
}
3434+
3435+
if err = client.Close(); err != nil {
3436+
t.Error(err)
3437+
}
3438+
}

flight1handler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ func flight1Generate(c flightConn, state *State, _ *handshakeCache, cfg *handsha
5757
return nil, nil, err
5858
}
5959

60+
if cfg.helloRandomBytesGenerator != nil {
61+
state.localRandom.RandomBytes = cfg.helloRandomBytesGenerator()
62+
}
63+
6064
extensions := []extension.Extension{
6165
&extension.SupportedSignatureAlgorithms{
6266
SignatureHashAlgorithms: cfg.localSignatureSchemes,

flight4handler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha
300300
certificate, err := cfg.getCertificate(&ClientHelloInfo{
301301
ServerName: state.serverName,
302302
CipherSuites: []ciphersuite.ID{state.cipherSuite.ID()},
303+
RandomBytes: state.remoteRandom.RandomBytes,
303304
})
304305
if err != nil {
305306
return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, err

handshaker.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ type handshakeConfig struct {
114114
ellipticCurves []elliptic.Curve
115115
insecureSkipHelloVerify bool
116116
connectionIDGenerator func() []byte
117+
helloRandomBytesGenerator func() [handshake.RandomBytesLength]byte
117118

118119
onFlightState func(flightVal, handshakeState)
119120
log logging.LeveledLogger

state.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,8 @@ func (s *State) getSRTPProtectionProfile() SRTPProtectionProfile {
258258

259259
return 0
260260
}
261+
262+
// RemoteRandomBytes returns the remote client hello random bytes
263+
func (s *State) RemoteRandomBytes() [handshake.RandomBytesLength]byte {
264+
return s.remoteRandom.RandomBytes
265+
}

0 commit comments

Comments
 (0)