소스 검색

tris: implement draft-22 middlebox compatibility mode

Send/Skip CCS, set legacy record version to 3,3 and echo session ID.
CCS must be ignored while the handshake is running, but not thereafter:
https://tools.ietf.org/html/draft-ietf-tls-tls13-22#section-5

Unconditionally send CCS as server because bogo requires it, even if no
session ID is included in the Client Hello. TLS 1.3 clients MUST ignore
it anyway, so it should not hurt.

Fixes interop with boringssl and openssl and passes bogo.
tls13
Peter Wu 7 년 전
committed by Peter Wu
부모
커밋
824987c5ad
4개의 변경된 파일30개의 추가작업 그리고 2개의 파일을 삭제
  1. +11
    -0
      13.go
  2. +13
    -2
      conn.go
  3. +5
    -0
      handshake_client.go
  4. +1
    -0
      handshake_server.go

+ 11
- 0
13.go 파일 보기

@@ -197,6 +197,11 @@ CurvePreferenceLoop:
return err
}

// middlebox compatibility mode: send CCS after first handshake message
if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
return err
}

hs.keySchedule.setSecret(ecdheSecret)
clientCipher, cTrafficSecret := hs.keySchedule.prepareCipher(secretHandshakeClient)
hs.hsClientCipher = clientCipher
@@ -792,6 +797,12 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
hash := hashForSuite(hs.suite)
hashSize := hash.Size()
serverHello := hs.serverHello

// middlebox compatibility mode, send CCS before second flight.
if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
return err
}

// TODO check if keyshare is unacceptable, raise HRR.

clientKS := hs.hello.keyShares[0]


+ 13
- 2
conn.go 파일 보기

@@ -713,6 +713,16 @@ Again:

// Process message.
b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)

// TLS 1.3 middlebox compatibility: skip over unencrypted CCS.
if c.vers >= VersionTLS13 && typ == recordTypeChangeCipherSpec && c.phase != handshakeConfirmed {
if len(b.data) != 6 || b.data[5] != 1 {
c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
}
c.in.freeBlock(b)
return c.in.err
}

peekedAlert := peekAlert(b) // peek at a possible alert before decryption
ok, off, alertValue := c.in.decrypt(b)
switch {
@@ -1044,7 +1054,8 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
if c.vers >= VersionTLS13 {
// TLS 1.3 froze the record layer version at { 3, 1 }.
// See https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-5.1.
vers = VersionTLS10
// But for draft 22, this was changed to { 3, 3 }.
vers = VersionTLS12
}
b.data[1] = byte(vers >> 8)
b.data[2] = byte(vers)
@@ -1069,7 +1080,7 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
data = data[m:]
}

if typ == recordTypeChangeCipherSpec {
if typ == recordTypeChangeCipherSpec && c.vers < VersionTLS13 {
if err := c.out.changeCipherSpec(); err != nil {
return n, c.sendAlertLocked(err.(alert))
}


+ 5
- 0
handshake_client.go 파일 보기

@@ -197,6 +197,11 @@ func (c *Conn) clientHandshake() error {
return err
}
hello.keyShares = []keyShare{clientKS}
// middlebox compatibility mode, provide a non-empty session ID
hello.sessionId = make([]byte, 16)
if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
return errors.New("tls: short read from Rand: " + err.Error())
}
}

if err = hs.handshake(); err != nil {


+ 1
- 0
handshake_server.go 파일 보기

@@ -262,6 +262,7 @@ Curves:
hs.hello13Enc = new(encryptedExtensionsMsg)
hs.hello.vers = c.vers
hs.hello.random = make([]byte, 32)
hs.hello.sessionId = hs.clientHello.sessionId
_, err = io.ReadFull(c.config.rand(), hs.hello.random)
if err != nil {
c.sendAlert(alertInternalError)


불러오는 중...
취소
저장