package tls
import (
)
type sessionState struct {
vers uint16
cipherSuite uint16
createdAt uint64
masterSecret []byte
certificates [][]byte
usedOldKey bool
}
func ( *sessionState) () []byte {
var cryptobyte.Builder
.AddUint16(.vers)
.AddUint16(.cipherSuite)
addUint64(&, .createdAt)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.masterSecret)
})
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .certificates {
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes()
})
}
})
return .BytesOrPanic()
}
func ( *sessionState) ( []byte) bool {
* = sessionState{usedOldKey: .usedOldKey}
:= cryptobyte.String()
if := .ReadUint16(&.vers) &&
.ReadUint16(&.cipherSuite) &&
readUint64(&, &.createdAt) &&
readUint16LengthPrefixed(&, &.masterSecret) &&
len(.masterSecret) != 0; ! {
return false
}
var cryptobyte.String
if !.ReadUint24LengthPrefixed(&) {
return false
}
for !.Empty() {
var []byte
if !readUint24LengthPrefixed(&, &) {
return false
}
.certificates = append(.certificates, )
}
return .Empty()
}
type sessionStateTLS13 struct {
cipherSuite uint16
createdAt uint64
resumptionSecret []byte
certificate Certificate
}
func ( *sessionStateTLS13) () []byte {
var cryptobyte.Builder
.AddUint16(VersionTLS13)
.AddUint8(0)
.AddUint16(.cipherSuite)
addUint64(&, .createdAt)
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.resumptionSecret)
})
marshalCertificate(&, .certificate)
return .BytesOrPanic()
}
func ( *sessionStateTLS13) ( []byte) bool {
* = sessionStateTLS13{}
:= cryptobyte.String()
var uint16
var uint8
return .ReadUint16(&) &&
== VersionTLS13 &&
.ReadUint8(&) &&
== 0 &&
.ReadUint16(&.cipherSuite) &&
readUint64(&, &.createdAt) &&
readUint8LengthPrefixed(&, &.resumptionSecret) &&
len(.resumptionSecret) != 0 &&
unmarshalCertificate(&, &.certificate) &&
.Empty()
}
func ( *Conn) ( []byte) ([]byte, error) {
if len(.ticketKeys) == 0 {
return nil, errors.New("tls: internal error: session ticket keys unavailable")
}
:= make([]byte, ticketKeyNameLen+aes.BlockSize+len()+sha256.Size)
:= [:ticketKeyNameLen]
:= [ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
:= [len()-sha256.Size:]
if , := io.ReadFull(.config.rand(), ); != nil {
return nil,
}
:= .ticketKeys[0]
copy(, .keyName[:])
, := aes.NewCipher(.aesKey[:])
if != nil {
return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + .Error())
}
cipher.NewCTR(, ).XORKeyStream([ticketKeyNameLen+aes.BlockSize:], )
:= hmac.New(sha256.New, .hmacKey[:])
.Write([:len()-sha256.Size])
.Sum([:0])
return , nil
}
func ( *Conn) ( []byte) ( []byte, bool) {
if len() < ticketKeyNameLen+aes.BlockSize+sha256.Size {
return nil, false
}
:= [:ticketKeyNameLen]
:= [ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
:= [len()-sha256.Size:]
:= [ticketKeyNameLen+aes.BlockSize : len()-sha256.Size]
:= -1
for , := range .ticketKeys {
if bytes.Equal(, .keyName[:]) {
=
break
}
}
if == -1 {
return nil, false
}
:= &.ticketKeys[]
:= hmac.New(sha256.New, .hmacKey[:])
.Write([:len()-sha256.Size])
:= .Sum(nil)
if subtle.ConstantTimeCompare(, ) != 1 {
return nil, false
}
, := aes.NewCipher(.aesKey[:])
if != nil {
return nil, false
}
= make([]byte, len())
cipher.NewCTR(, ).XORKeyStream(, )
return , > 0
}