package tls
import (
)
type marshalingFunction func(b *cryptobyte.Builder) error
func ( marshalingFunction) ( *cryptobyte.Builder) error {
return ()
}
func ( *cryptobyte.Builder, []byte, int) {
.AddValue(marshalingFunction(func( *cryptobyte.Builder) error {
if len() != {
return fmt.Errorf("invalid value length: expected %d, got %d", , len())
}
.AddBytes()
return nil
}))
}
func ( *cryptobyte.Builder, uint64) {
.AddUint32(uint32( >> 32))
.AddUint32(uint32())
}
func ( *cryptobyte.String, *uint64) bool {
var , uint32
if !.ReadUint32(&) || !.ReadUint32(&) {
return false
}
* = uint64()<<32 | uint64()
return true
}
func ( *cryptobyte.String, *[]byte) bool {
return .ReadUint8LengthPrefixed((*cryptobyte.String)())
}
func ( *cryptobyte.String, *[]byte) bool {
return .ReadUint16LengthPrefixed((*cryptobyte.String)())
}
func ( *cryptobyte.String, *[]byte) bool {
return .ReadUint24LengthPrefixed((*cryptobyte.String)())
}
type clientHelloMsg struct {
raw []byte
vers uint16
random []byte
sessionId []byte
cipherSuites []uint16
compressionMethods []uint8
serverName string
ocspStapling bool
supportedCurves []CurveID
supportedPoints []uint8
ticketSupported bool
sessionTicket []uint8
supportedSignatureAlgorithms []SignatureScheme
supportedSignatureAlgorithmsCert []SignatureScheme
secureRenegotiationSupported bool
secureRenegotiation []byte
alpnProtocols []string
scts bool
supportedVersions []uint16
cookie []byte
keyShares []keyShare
earlyData bool
pskModes []uint8
pskIdentities []pskIdentity
pskBinders [][]byte
}
func ( *clientHelloMsg) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeClientHello)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16(.vers)
addBytesWithLength(, .random, 32)
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.sessionId)
})
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .cipherSuites {
.AddUint16()
}
})
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.compressionMethods)
})
var bool
:= *
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
if len(.serverName) > 0 {
.AddUint16(extensionServerName)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8(0)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes([]byte(.serverName))
})
})
})
}
if .ocspStapling {
.AddUint16(extensionStatusRequest)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8(1)
.AddUint16(0)
.AddUint16(0)
})
}
if len(.supportedCurves) > 0 {
.AddUint16(extensionSupportedCurves)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .supportedCurves {
.AddUint16(uint16())
}
})
})
}
if len(.supportedPoints) > 0 {
.AddUint16(extensionSupportedPoints)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.supportedPoints)
})
})
}
if .ticketSupported {
.AddUint16(extensionSessionTicket)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.sessionTicket)
})
}
if len(.supportedSignatureAlgorithms) > 0 {
.AddUint16(extensionSignatureAlgorithms)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .supportedSignatureAlgorithms {
.AddUint16(uint16())
}
})
})
}
if len(.supportedSignatureAlgorithmsCert) > 0 {
.AddUint16(extensionSignatureAlgorithmsCert)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .supportedSignatureAlgorithmsCert {
.AddUint16(uint16())
}
})
})
}
if .secureRenegotiationSupported {
.AddUint16(extensionRenegotiationInfo)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.secureRenegotiation)
})
})
}
if len(.alpnProtocols) > 0 {
.AddUint16(extensionALPN)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .alpnProtocols {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes([]byte())
})
}
})
})
}
if .scts {
.AddUint16(extensionSCT)
.AddUint16(0)
}
if len(.supportedVersions) > 0 {
.AddUint16(extensionSupportedVersions)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .supportedVersions {
.AddUint16()
}
})
})
}
if len(.cookie) > 0 {
.AddUint16(extensionCookie)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.cookie)
})
})
}
if len(.keyShares) > 0 {
.AddUint16(extensionKeyShare)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .keyShares {
.AddUint16(uint16(.group))
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.data)
})
}
})
})
}
if .earlyData {
.AddUint16(extensionEarlyData)
.AddUint16(0)
}
if len(.pskModes) > 0 {
.AddUint16(extensionPSKModes)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.pskModes)
})
})
}
if len(.pskIdentities) > 0 {
.AddUint16(extensionPreSharedKey)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .pskIdentities {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.label)
})
.AddUint32(.obfuscatedTicketAge)
}
})
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .pskBinders {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes()
})
}
})
})
}
= len(.BytesOrPanic()) > 2
})
if ! {
* =
}
})
.raw = .BytesOrPanic()
return .raw
}
func ( *clientHelloMsg) () []byte {
:= 2
for , := range .pskBinders {
+= 1
+= len()
}
:= .marshal()
return [:len()-]
}
func ( *clientHelloMsg) ( [][]byte) {
if len() != len(.pskBinders) {
panic("tls: internal error: pskBinders length mismatch")
}
for := range .pskBinders {
if len([]) != len(.pskBinders[]) {
panic("tls: internal error: pskBinders length mismatch")
}
}
.pskBinders =
if .raw != nil {
:= len(.marshalWithoutBinders())
:= cryptobyte.NewFixedBuilder(.raw[:])
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .pskBinders {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes()
})
}
})
if , := .Bytes(); != nil || len() != len(.raw) {
panic("tls: internal error: failed to update binders")
}
}
}
func ( *clientHelloMsg) ( []byte) bool {
* = clientHelloMsg{raw: }
:= cryptobyte.String()
if !.Skip(4) ||
!.ReadUint16(&.vers) || !.ReadBytes(&.random, 32) ||
!readUint8LengthPrefixed(&, &.sessionId) {
return false
}
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) {
return false
}
.cipherSuites = []uint16{}
.secureRenegotiationSupported = false
for !.Empty() {
var uint16
if !.ReadUint16(&) {
return false
}
if == scsvRenegotiation {
.secureRenegotiationSupported = true
}
.cipherSuites = append(.cipherSuites, )
}
if !readUint8LengthPrefixed(&, &.compressionMethods) {
return false
}
if .Empty() {
return true
}
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || !.Empty() {
return false
}
for !.Empty() {
var uint16
var cryptobyte.String
if !.ReadUint16(&) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
switch {
case extensionServerName:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var uint8
var cryptobyte.String
if !.ReadUint8(&) ||
!.ReadUint16LengthPrefixed(&) ||
.Empty() {
return false
}
if != 0 {
continue
}
if len(.serverName) != 0 {
return false
}
.serverName = string()
if strings.HasSuffix(.serverName, ".") {
return false
}
}
case extensionStatusRequest:
var uint8
var cryptobyte.String
if !.ReadUint8(&) ||
!.ReadUint16LengthPrefixed(&) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
.ocspStapling = == statusTypeOCSP
case extensionSupportedCurves:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var uint16
if !.ReadUint16(&) {
return false
}
.supportedCurves = append(.supportedCurves, CurveID())
}
case extensionSupportedPoints:
if !readUint8LengthPrefixed(&, &.supportedPoints) ||
len(.supportedPoints) == 0 {
return false
}
case extensionSessionTicket:
.ticketSupported = true
.ReadBytes(&.sessionTicket, len())
case extensionSignatureAlgorithms:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var uint16
if !.ReadUint16(&) {
return false
}
.supportedSignatureAlgorithms = append(
.supportedSignatureAlgorithms, SignatureScheme())
}
case extensionSignatureAlgorithmsCert:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var uint16
if !.ReadUint16(&) {
return false
}
.supportedSignatureAlgorithmsCert = append(
.supportedSignatureAlgorithmsCert, SignatureScheme())
}
case extensionRenegotiationInfo:
if !readUint8LengthPrefixed(&, &.secureRenegotiation) {
return false
}
.secureRenegotiationSupported = true
case extensionALPN:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var cryptobyte.String
if !.ReadUint8LengthPrefixed(&) || .Empty() {
return false
}
.alpnProtocols = append(.alpnProtocols, string())
}
case extensionSCT:
.scts = true
case extensionSupportedVersions:
var cryptobyte.String
if !.ReadUint8LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var uint16
if !.ReadUint16(&) {
return false
}
.supportedVersions = append(.supportedVersions, )
}
case extensionCookie:
if !readUint16LengthPrefixed(&, &.cookie) ||
len(.cookie) == 0 {
return false
}
case extensionKeyShare:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) {
return false
}
for !.Empty() {
var keyShare
if !.ReadUint16((*uint16)(&.group)) ||
!readUint16LengthPrefixed(&, &.data) ||
len(.data) == 0 {
return false
}
.keyShares = append(.keyShares, )
}
case extensionEarlyData:
.earlyData = true
case extensionPSKModes:
if !readUint8LengthPrefixed(&, &.pskModes) {
return false
}
case extensionPreSharedKey:
if !.Empty() {
return false
}
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var pskIdentity
if !readUint16LengthPrefixed(&, &.label) ||
!.ReadUint32(&.obfuscatedTicketAge) ||
len(.label) == 0 {
return false
}
.pskIdentities = append(.pskIdentities, )
}
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var []byte
if !readUint8LengthPrefixed(&, &) ||
len() == 0 {
return false
}
.pskBinders = append(.pskBinders, )
}
default:
continue
}
if !.Empty() {
return false
}
}
return true
}
type serverHelloMsg struct {
raw []byte
vers uint16
random []byte
sessionId []byte
cipherSuite uint16
compressionMethod uint8
ocspStapling bool
ticketSupported bool
secureRenegotiationSupported bool
secureRenegotiation []byte
alpnProtocol string
scts [][]byte
supportedVersion uint16
serverShare keyShare
selectedIdentityPresent bool
selectedIdentity uint16
supportedPoints []uint8
cookie []byte
selectedGroup CurveID
}
func ( *serverHelloMsg) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeServerHello)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16(.vers)
addBytesWithLength(, .random, 32)
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.sessionId)
})
.AddUint16(.cipherSuite)
.AddUint8(.compressionMethod)
var bool
:= *
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
if .ocspStapling {
.AddUint16(extensionStatusRequest)
.AddUint16(0)
}
if .ticketSupported {
.AddUint16(extensionSessionTicket)
.AddUint16(0)
}
if .secureRenegotiationSupported {
.AddUint16(extensionRenegotiationInfo)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.secureRenegotiation)
})
})
}
if len(.alpnProtocol) > 0 {
.AddUint16(extensionALPN)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes([]byte(.alpnProtocol))
})
})
})
}
if len(.scts) > 0 {
.AddUint16(extensionSCT)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .scts {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes()
})
}
})
})
}
if .supportedVersion != 0 {
.AddUint16(extensionSupportedVersions)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16(.supportedVersion)
})
}
if .serverShare.group != 0 {
.AddUint16(extensionKeyShare)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16(uint16(.serverShare.group))
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.serverShare.data)
})
})
}
if .selectedIdentityPresent {
.AddUint16(extensionPreSharedKey)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16(.selectedIdentity)
})
}
if len(.cookie) > 0 {
.AddUint16(extensionCookie)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.cookie)
})
})
}
if .selectedGroup != 0 {
.AddUint16(extensionKeyShare)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16(uint16(.selectedGroup))
})
}
if len(.supportedPoints) > 0 {
.AddUint16(extensionSupportedPoints)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.supportedPoints)
})
})
}
= len(.BytesOrPanic()) > 2
})
if ! {
* =
}
})
.raw = .BytesOrPanic()
return .raw
}
func ( *serverHelloMsg) ( []byte) bool {
* = serverHelloMsg{raw: }
:= cryptobyte.String()
if !.Skip(4) ||
!.ReadUint16(&.vers) || !.ReadBytes(&.random, 32) ||
!readUint8LengthPrefixed(&, &.sessionId) ||
!.ReadUint16(&.cipherSuite) ||
!.ReadUint8(&.compressionMethod) {
return false
}
if .Empty() {
return true
}
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || !.Empty() {
return false
}
for !.Empty() {
var uint16
var cryptobyte.String
if !.ReadUint16(&) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
switch {
case extensionStatusRequest:
.ocspStapling = true
case extensionSessionTicket:
.ticketSupported = true
case extensionRenegotiationInfo:
if !readUint8LengthPrefixed(&, &.secureRenegotiation) {
return false
}
.secureRenegotiationSupported = true
case extensionALPN:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
var cryptobyte.String
if !.ReadUint8LengthPrefixed(&) ||
.Empty() || !.Empty() {
return false
}
.alpnProtocol = string()
case extensionSCT:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var []byte
if !readUint16LengthPrefixed(&, &) ||
len() == 0 {
return false
}
.scts = append(.scts, )
}
case extensionSupportedVersions:
if !.ReadUint16(&.supportedVersion) {
return false
}
case extensionCookie:
if !readUint16LengthPrefixed(&, &.cookie) ||
len(.cookie) == 0 {
return false
}
case extensionKeyShare:
if len() == 2 {
if !.ReadUint16((*uint16)(&.selectedGroup)) {
return false
}
} else {
if !.ReadUint16((*uint16)(&.serverShare.group)) ||
!readUint16LengthPrefixed(&, &.serverShare.data) {
return false
}
}
case extensionPreSharedKey:
.selectedIdentityPresent = true
if !.ReadUint16(&.selectedIdentity) {
return false
}
case extensionSupportedPoints:
if !readUint8LengthPrefixed(&, &.supportedPoints) ||
len(.supportedPoints) == 0 {
return false
}
default:
continue
}
if !.Empty() {
return false
}
}
return true
}
type encryptedExtensionsMsg struct {
raw []byte
alpnProtocol string
}
func ( *encryptedExtensionsMsg) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeEncryptedExtensions)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
if len(.alpnProtocol) > 0 {
.AddUint16(extensionALPN)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes([]byte(.alpnProtocol))
})
})
})
}
})
})
.raw = .BytesOrPanic()
return .raw
}
func ( *encryptedExtensionsMsg) ( []byte) bool {
* = encryptedExtensionsMsg{raw: }
:= cryptobyte.String()
var cryptobyte.String
if !.Skip(4) ||
!.ReadUint16LengthPrefixed(&) || !.Empty() {
return false
}
for !.Empty() {
var uint16
var cryptobyte.String
if !.ReadUint16(&) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
switch {
case extensionALPN:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
var cryptobyte.String
if !.ReadUint8LengthPrefixed(&) ||
.Empty() || !.Empty() {
return false
}
.alpnProtocol = string()
default:
continue
}
if !.Empty() {
return false
}
}
return true
}
type endOfEarlyDataMsg struct{}
func ( *endOfEarlyDataMsg) () []byte {
:= make([]byte, 4)
[0] = typeEndOfEarlyData
return
}
func ( *endOfEarlyDataMsg) ( []byte) bool {
return len() == 4
}
type keyUpdateMsg struct {
raw []byte
updateRequested bool
}
func ( *keyUpdateMsg) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeKeyUpdate)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
if .updateRequested {
.AddUint8(1)
} else {
.AddUint8(0)
}
})
.raw = .BytesOrPanic()
return .raw
}
func ( *keyUpdateMsg) ( []byte) bool {
.raw =
:= cryptobyte.String()
var uint8
if !.Skip(4) ||
!.ReadUint8(&) || !.Empty() {
return false
}
switch {
case 0:
.updateRequested = false
case 1:
.updateRequested = true
default:
return false
}
return true
}
type newSessionTicketMsgTLS13 struct {
raw []byte
lifetime uint32
ageAdd uint32
nonce []byte
label []byte
maxEarlyData uint32
}
func ( *newSessionTicketMsgTLS13) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeNewSessionTicket)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint32(.lifetime)
.AddUint32(.ageAdd)
.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.nonce)
})
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.label)
})
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
if .maxEarlyData > 0 {
.AddUint16(extensionEarlyData)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint32(.maxEarlyData)
})
}
})
})
.raw = .BytesOrPanic()
return .raw
}
func ( *newSessionTicketMsgTLS13) ( []byte) bool {
* = newSessionTicketMsgTLS13{raw: }
:= cryptobyte.String()
var cryptobyte.String
if !.Skip(4) ||
!.ReadUint32(&.lifetime) ||
!.ReadUint32(&.ageAdd) ||
!readUint8LengthPrefixed(&, &.nonce) ||
!readUint16LengthPrefixed(&, &.label) ||
!.ReadUint16LengthPrefixed(&) ||
!.Empty() {
return false
}
for !.Empty() {
var uint16
var cryptobyte.String
if !.ReadUint16(&) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
switch {
case extensionEarlyData:
if !.ReadUint32(&.maxEarlyData) {
return false
}
default:
continue
}
if !.Empty() {
return false
}
}
return true
}
type certificateRequestMsgTLS13 struct {
raw []byte
ocspStapling bool
scts bool
supportedSignatureAlgorithms []SignatureScheme
supportedSignatureAlgorithmsCert []SignatureScheme
certificateAuthorities [][]byte
}
func ( *certificateRequestMsgTLS13) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeCertificateRequest)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8(0)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
if .ocspStapling {
.AddUint16(extensionStatusRequest)
.AddUint16(0)
}
if .scts {
.AddUint16(extensionSCT)
.AddUint16(0)
}
if len(.supportedSignatureAlgorithms) > 0 {
.AddUint16(extensionSignatureAlgorithms)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .supportedSignatureAlgorithms {
.AddUint16(uint16())
}
})
})
}
if len(.supportedSignatureAlgorithmsCert) > 0 {
.AddUint16(extensionSignatureAlgorithmsCert)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .supportedSignatureAlgorithmsCert {
.AddUint16(uint16())
}
})
})
}
if len(.certificateAuthorities) > 0 {
.AddUint16(extensionCertificateAuthorities)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .certificateAuthorities {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes()
})
}
})
})
}
})
})
.raw = .BytesOrPanic()
return .raw
}
func ( *certificateRequestMsgTLS13) ( []byte) bool {
* = certificateRequestMsgTLS13{raw: }
:= cryptobyte.String()
var , cryptobyte.String
if !.Skip(4) ||
!.ReadUint8LengthPrefixed(&) || !.Empty() ||
!.ReadUint16LengthPrefixed(&) ||
!.Empty() {
return false
}
for !.Empty() {
var uint16
var cryptobyte.String
if !.ReadUint16(&) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
switch {
case extensionStatusRequest:
.ocspStapling = true
case extensionSCT:
.scts = true
case extensionSignatureAlgorithms:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var uint16
if !.ReadUint16(&) {
return false
}
.supportedSignatureAlgorithms = append(
.supportedSignatureAlgorithms, SignatureScheme())
}
case extensionSignatureAlgorithmsCert:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var uint16
if !.ReadUint16(&) {
return false
}
.supportedSignatureAlgorithmsCert = append(
.supportedSignatureAlgorithmsCert, SignatureScheme())
}
case extensionCertificateAuthorities:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var []byte
if !readUint16LengthPrefixed(&, &) || len() == 0 {
return false
}
.certificateAuthorities = append(.certificateAuthorities, )
}
default:
continue
}
if !.Empty() {
return false
}
}
return true
}
type certificateMsg struct {
raw []byte
certificates [][]byte
}
func ( *certificateMsg) () ( []byte) {
if .raw != nil {
return .raw
}
var int
for , := range .certificates {
+= len()
}
:= 3 + 3*len(.certificates) +
= make([]byte, 4+)
[0] = typeCertificate
[1] = uint8( >> 16)
[2] = uint8( >> 8)
[3] = uint8()
:= - 3
[4] = uint8( >> 16)
[5] = uint8( >> 8)
[6] = uint8()
:= [7:]
for , := range .certificates {
[0] = uint8(len() >> 16)
[1] = uint8(len() >> 8)
[2] = uint8(len())
copy([3:], )
= [3+len():]
}
.raw =
return
}
func ( *certificateMsg) ( []byte) bool {
if len() < 7 {
return false
}
.raw =
:= uint32([4])<<16 | uint32([5])<<8 | uint32([6])
if uint32(len()) != +7 {
return false
}
:= 0
:= [7:]
for > 0 {
if len() < 4 {
return false
}
:= uint32([0])<<16 | uint32([1])<<8 | uint32([2])
if uint32(len()) < 3+ {
return false
}
= [3+:]
-= 3 +
++
}
.certificates = make([][]byte, )
= [7:]
for := 0; < ; ++ {
:= uint32([0])<<16 | uint32([1])<<8 | uint32([2])
.certificates[] = [3 : 3+]
= [3+:]
}
return true
}
type certificateMsgTLS13 struct {
raw []byte
certificate Certificate
ocspStapling bool
scts bool
}
func ( *certificateMsgTLS13) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeCertificate)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8(0)
:= .certificate
if !.ocspStapling {
.OCSPStaple = nil
}
if !.scts {
.SignedCertificateTimestamps = nil
}
marshalCertificate(, )
})
.raw = .BytesOrPanic()
return .raw
}
func ( *cryptobyte.Builder, Certificate) {
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .Certificate {
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes()
})
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
if > 0 {
return
}
if .OCSPStaple != nil {
.AddUint16(extensionStatusRequest)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8(statusTypeOCSP)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.OCSPStaple)
})
})
}
if .SignedCertificateTimestamps != nil {
.AddUint16(extensionSCT)
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
for , := range .SignedCertificateTimestamps {
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes()
})
}
})
})
}
})
}
})
}
func ( *certificateMsgTLS13) ( []byte) bool {
* = certificateMsgTLS13{raw: }
:= cryptobyte.String()
var cryptobyte.String
if !.Skip(4) ||
!.ReadUint8LengthPrefixed(&) || !.Empty() ||
!unmarshalCertificate(&, &.certificate) ||
!.Empty() {
return false
}
.scts = .certificate.SignedCertificateTimestamps != nil
.ocspStapling = .certificate.OCSPStaple != nil
return true
}
func ( *cryptobyte.String, *Certificate) bool {
var cryptobyte.String
if !.ReadUint24LengthPrefixed(&) {
return false
}
for !.Empty() {
var []byte
var cryptobyte.String
if !readUint24LengthPrefixed(&, &) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
.Certificate = append(.Certificate, )
for !.Empty() {
var uint16
var cryptobyte.String
if !.ReadUint16(&) ||
!.ReadUint16LengthPrefixed(&) {
return false
}
if len(.Certificate) > 1 {
continue
}
switch {
case extensionStatusRequest:
var uint8
if !.ReadUint8(&) || != statusTypeOCSP ||
!readUint24LengthPrefixed(&, &.OCSPStaple) ||
len(.OCSPStaple) == 0 {
return false
}
case extensionSCT:
var cryptobyte.String
if !.ReadUint16LengthPrefixed(&) || .Empty() {
return false
}
for !.Empty() {
var []byte
if !readUint16LengthPrefixed(&, &) ||
len() == 0 {
return false
}
.SignedCertificateTimestamps = append(
.SignedCertificateTimestamps, )
}
default:
continue
}
if !.Empty() {
return false
}
}
}
return true
}
type serverKeyExchangeMsg struct {
raw []byte
key []byte
}
func ( *serverKeyExchangeMsg) () []byte {
if .raw != nil {
return .raw
}
:= len(.key)
:= make([]byte, +4)
[0] = typeServerKeyExchange
[1] = uint8( >> 16)
[2] = uint8( >> 8)
[3] = uint8()
copy([4:], .key)
.raw =
return
}
func ( *serverKeyExchangeMsg) ( []byte) bool {
.raw =
if len() < 4 {
return false
}
.key = [4:]
return true
}
type certificateStatusMsg struct {
raw []byte
response []byte
}
func ( *certificateStatusMsg) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeCertificateStatus)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddUint8(statusTypeOCSP)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.response)
})
})
.raw = .BytesOrPanic()
return .raw
}
func ( *certificateStatusMsg) ( []byte) bool {
.raw =
:= cryptobyte.String()
var uint8
if !.Skip(4) ||
!.ReadUint8(&) || != statusTypeOCSP ||
!readUint24LengthPrefixed(&, &.response) ||
len(.response) == 0 || !.Empty() {
return false
}
return true
}
type serverHelloDoneMsg struct{}
func ( *serverHelloDoneMsg) () []byte {
:= make([]byte, 4)
[0] = typeServerHelloDone
return
}
func ( *serverHelloDoneMsg) ( []byte) bool {
return len() == 4
}
type clientKeyExchangeMsg struct {
raw []byte
ciphertext []byte
}
func ( *clientKeyExchangeMsg) () []byte {
if .raw != nil {
return .raw
}
:= len(.ciphertext)
:= make([]byte, +4)
[0] = typeClientKeyExchange
[1] = uint8( >> 16)
[2] = uint8( >> 8)
[3] = uint8()
copy([4:], .ciphertext)
.raw =
return
}
func ( *clientKeyExchangeMsg) ( []byte) bool {
.raw =
if len() < 4 {
return false
}
:= int([1])<<16 | int([2])<<8 | int([3])
if != len()-4 {
return false
}
.ciphertext = [4:]
return true
}
type finishedMsg struct {
raw []byte
verifyData []byte
}
func ( *finishedMsg) () []byte {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeFinished)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.verifyData)
})
.raw = .BytesOrPanic()
return .raw
}
func ( *finishedMsg) ( []byte) bool {
.raw =
:= cryptobyte.String()
return .Skip(1) &&
readUint24LengthPrefixed(&, &.verifyData) &&
.Empty()
}
type certificateRequestMsg struct {
raw []byte
hasSignatureAlgorithm bool
certificateTypes []byte
supportedSignatureAlgorithms []SignatureScheme
certificateAuthorities [][]byte
}
func ( *certificateRequestMsg) () ( []byte) {
if .raw != nil {
return .raw
}
:= 1 + len(.certificateTypes) + 2
:= 0
for , := range .certificateAuthorities {
+= 2 + len()
}
+=
if .hasSignatureAlgorithm {
+= 2 + 2*len(.supportedSignatureAlgorithms)
}
= make([]byte, 4+)
[0] = typeCertificateRequest
[1] = uint8( >> 16)
[2] = uint8( >> 8)
[3] = uint8()
[4] = uint8(len(.certificateTypes))
copy([5:], .certificateTypes)
:= [5+len(.certificateTypes):]
if .hasSignatureAlgorithm {
:= len(.supportedSignatureAlgorithms) * 2
[0] = uint8( >> 8)
[1] = uint8()
= [2:]
for , := range .supportedSignatureAlgorithms {
[0] = uint8( >> 8)
[1] = uint8()
= [2:]
}
}
[0] = uint8( >> 8)
[1] = uint8()
= [2:]
for , := range .certificateAuthorities {
[0] = uint8(len() >> 8)
[1] = uint8(len())
= [2:]
copy(, )
= [len():]
}
.raw =
return
}
func ( *certificateRequestMsg) ( []byte) bool {
.raw =
if len() < 5 {
return false
}
:= uint32([1])<<16 | uint32([2])<<8 | uint32([3])
if uint32(len())-4 != {
return false
}
:= int([4])
= [5:]
if == 0 || len() <= {
return false
}
.certificateTypes = make([]byte, )
if copy(.certificateTypes, ) != {
return false
}
= [:]
if .hasSignatureAlgorithm {
if len() < 2 {
return false
}
:= uint16([0])<<8 | uint16([1])
= [2:]
if &1 != 0 {
return false
}
if len() < int() {
return false
}
:= / 2
.supportedSignatureAlgorithms = make([]SignatureScheme, )
for := range .supportedSignatureAlgorithms {
.supportedSignatureAlgorithms[] = SignatureScheme([0])<<8 | SignatureScheme([1])
= [2:]
}
}
if len() < 2 {
return false
}
:= uint16([0])<<8 | uint16([1])
= [2:]
if len() < int() {
return false
}
:= make([]byte, )
copy(, )
= [:]
.certificateAuthorities = nil
for len() > 0 {
if len() < 2 {
return false
}
:= uint16([0])<<8 | uint16([1])
= [2:]
if len() < int() {
return false
}
.certificateAuthorities = append(.certificateAuthorities, [:])
= [:]
}
return len() == 0
}
type certificateVerifyMsg struct {
raw []byte
hasSignatureAlgorithm bool
signatureAlgorithm SignatureScheme
signature []byte
}
func ( *certificateVerifyMsg) () ( []byte) {
if .raw != nil {
return .raw
}
var cryptobyte.Builder
.AddUint8(typeCertificateVerify)
.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
if .hasSignatureAlgorithm {
.AddUint16(uint16(.signatureAlgorithm))
}
.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
.AddBytes(.signature)
})
})
.raw = .BytesOrPanic()
return .raw
}
func ( *certificateVerifyMsg) ( []byte) bool {
.raw =
:= cryptobyte.String()
if !.Skip(4) {
return false
}
if .hasSignatureAlgorithm {
if !.ReadUint16((*uint16)(&.signatureAlgorithm)) {
return false
}
}
return readUint16LengthPrefixed(&, &.signature) && .Empty()
}
type newSessionTicketMsg struct {
raw []byte
ticket []byte
}
func ( *newSessionTicketMsg) () ( []byte) {
if .raw != nil {
return .raw
}
:= len(.ticket)
:= 2 + 4 +
= make([]byte, 4+)
[0] = typeNewSessionTicket
[1] = uint8( >> 16)
[2] = uint8( >> 8)
[3] = uint8()
[8] = uint8( >> 8)
[9] = uint8()
copy([10:], .ticket)
.raw =
return
}
func ( *newSessionTicketMsg) ( []byte) bool {
.raw =
if len() < 10 {
return false
}
:= uint32([1])<<16 | uint32([2])<<8 | uint32([3])
if uint32(len())-4 != {
return false
}
:= int([8])<<8 + int([9])
if len()-10 != {
return false
}
.ticket = [10:]
return true
}
type helloRequestMsg struct {
}
func (*helloRequestMsg) () []byte {
return []byte{typeHelloRequest, 0, 0, 0}
}
func (*helloRequestMsg) ( []byte) bool {
return len() == 4
}