crypto/tls: replace all usages of BytesOrPanic

Message marshalling makes use of BytesOrPanic a lot, under the
assumption that it will never panic. This assumption was incorrect, and
specifically crafted handshakes could trigger panics. Rather than just
surgically replacing the usages of BytesOrPanic in paths that could
panic, replace all usages of it with proper error returns in case there
are other ways of triggering panics which we didn't find.

In one specific case, the tree routed by expandLabel, we replace the
usage of BytesOrPanic, but retain a panic. This function already
explicitly panicked elsewhere, and returning an error from it becomes
rather painful because it requires changing a large number of APIs.
The marshalling is unlikely to ever panic, as the inputs are all either
fixed length, or already limited to the sizes required. If it were to
panic, it'd likely only be during development. A close inspection shows
no paths for a user to cause a panic currently.

This patches ends up being rather large, since it requires routing
errors back through functions which previously had no error returns.
Where possible I've tried to use helpers that reduce the verbosity
of frequently repeated stanzas, and to make the diffs as minimal as
possible.

Thanks to Marten Seemann for reporting this issue.

Fixes #58001
Fixes CVE-2022-41724

Change-Id: Ieb55867ef0a3e1e867b33f09421932510cb58851
Reviewed-on: 1679436
Reviewed-by: Julie Qiu <julieqiu@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/468125
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Michael Pratt <mpratt@google.com>
This commit is contained in:
Roland Shoemaker 2022-12-14 09:43:16 -08:00 committed by Gopher Robot
parent 58e7190673
commit ba1a41d66f
13 changed files with 657 additions and 503 deletions

View file

@ -5,6 +5,7 @@
package tls
import (
"errors"
"fmt"
"strings"
@ -94,9 +95,181 @@ type clientHelloMsg struct {
pskBinders [][]byte
}
func (m *clientHelloMsg) marshal() []byte {
func (m *clientHelloMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var exts cryptobyte.Builder
if len(m.serverName) > 0 {
// RFC 6066, Section 3
exts.AddUint16(extensionServerName)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8(0) // name_type = host_name
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes([]byte(m.serverName))
})
})
})
}
if m.ocspStapling {
// RFC 4366, Section 3.6
exts.AddUint16(extensionStatusRequest)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8(1) // status_type = ocsp
exts.AddUint16(0) // empty responder_id_list
exts.AddUint16(0) // empty request_extensions
})
}
if len(m.supportedCurves) > 0 {
// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
exts.AddUint16(extensionSupportedCurves)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, curve := range m.supportedCurves {
exts.AddUint16(uint16(curve))
}
})
})
}
if len(m.supportedPoints) > 0 {
// RFC 4492, Section 5.1.2
exts.AddUint16(extensionSupportedPoints)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.supportedPoints)
})
})
}
if m.ticketSupported {
// RFC 5077, Section 3.2
exts.AddUint16(extensionSessionTicket)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.sessionTicket)
})
}
if len(m.supportedSignatureAlgorithms) > 0 {
// RFC 5246, Section 7.4.1.4.1
exts.AddUint16(extensionSignatureAlgorithms)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, sigAlgo := range m.supportedSignatureAlgorithms {
exts.AddUint16(uint16(sigAlgo))
}
})
})
}
if len(m.supportedSignatureAlgorithmsCert) > 0 {
// RFC 8446, Section 4.2.3
exts.AddUint16(extensionSignatureAlgorithmsCert)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
exts.AddUint16(uint16(sigAlgo))
}
})
})
}
if m.secureRenegotiationSupported {
// RFC 5746, Section 3.2
exts.AddUint16(extensionRenegotiationInfo)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.secureRenegotiation)
})
})
}
if len(m.alpnProtocols) > 0 {
// RFC 7301, Section 3.1
exts.AddUint16(extensionALPN)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, proto := range m.alpnProtocols {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes([]byte(proto))
})
}
})
})
}
if m.scts {
// RFC 6962, Section 3.3.1
exts.AddUint16(extensionSCT)
exts.AddUint16(0) // empty extension_data
}
if len(m.supportedVersions) > 0 {
// RFC 8446, Section 4.2.1
exts.AddUint16(extensionSupportedVersions)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, vers := range m.supportedVersions {
exts.AddUint16(vers)
}
})
})
}
if len(m.cookie) > 0 {
// RFC 8446, Section 4.2.2
exts.AddUint16(extensionCookie)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.cookie)
})
})
}
if len(m.keyShares) > 0 {
// RFC 8446, Section 4.2.8
exts.AddUint16(extensionKeyShare)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, ks := range m.keyShares {
exts.AddUint16(uint16(ks.group))
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(ks.data)
})
}
})
})
}
if m.earlyData {
// RFC 8446, Section 4.2.10
exts.AddUint16(extensionEarlyData)
exts.AddUint16(0) // empty extension_data
}
if len(m.pskModes) > 0 {
// RFC 8446, Section 4.2.9
exts.AddUint16(extensionPSKModes)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.pskModes)
})
})
}
if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
// RFC 8446, Section 4.2.11
exts.AddUint16(extensionPreSharedKey)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, psk := range m.pskIdentities {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(psk.label)
})
exts.AddUint32(psk.obfuscatedTicketAge)
}
})
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, binder := range m.pskBinders {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(binder)
})
}
})
})
}
extBytes, err := exts.Bytes()
if err != nil {
return nil, err
}
var b cryptobyte.Builder
@ -116,219 +289,53 @@ func (m *clientHelloMsg) marshal() []byte {
b.AddBytes(m.compressionMethods)
})
// If extensions aren't present, omit them.
var extensionsPresent bool
bWithoutExtensions := *b
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
if len(m.serverName) > 0 {
// RFC 6066, Section 3
b.AddUint16(extensionServerName)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8(0) // name_type = host_name
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes([]byte(m.serverName))
})
})
})
}
if m.ocspStapling {
// RFC 4366, Section 3.6
b.AddUint16(extensionStatusRequest)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8(1) // status_type = ocsp
b.AddUint16(0) // empty responder_id_list
b.AddUint16(0) // empty request_extensions
})
}
if len(m.supportedCurves) > 0 {
// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
b.AddUint16(extensionSupportedCurves)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, curve := range m.supportedCurves {
b.AddUint16(uint16(curve))
}
})
})
}
if len(m.supportedPoints) > 0 {
// RFC 4492, Section 5.1.2
b.AddUint16(extensionSupportedPoints)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.supportedPoints)
})
})
}
if m.ticketSupported {
// RFC 5077, Section 3.2
b.AddUint16(extensionSessionTicket)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.sessionTicket)
})
}
if len(m.supportedSignatureAlgorithms) > 0 {
// RFC 5246, Section 7.4.1.4.1
b.AddUint16(extensionSignatureAlgorithms)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, sigAlgo := range m.supportedSignatureAlgorithms {
b.AddUint16(uint16(sigAlgo))
}
})
})
}
if len(m.supportedSignatureAlgorithmsCert) > 0 {
// RFC 8446, Section 4.2.3
b.AddUint16(extensionSignatureAlgorithmsCert)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
b.AddUint16(uint16(sigAlgo))
}
})
})
}
if m.secureRenegotiationSupported {
// RFC 5746, Section 3.2
b.AddUint16(extensionRenegotiationInfo)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.secureRenegotiation)
})
})
}
if len(m.alpnProtocols) > 0 {
// RFC 7301, Section 3.1
b.AddUint16(extensionALPN)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, proto := range m.alpnProtocols {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes([]byte(proto))
})
}
})
})
}
if m.scts {
// RFC 6962, Section 3.3.1
b.AddUint16(extensionSCT)
b.AddUint16(0) // empty extension_data
}
if len(m.supportedVersions) > 0 {
// RFC 8446, Section 4.2.1
b.AddUint16(extensionSupportedVersions)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
for _, vers := range m.supportedVersions {
b.AddUint16(vers)
}
})
})
}
if len(m.cookie) > 0 {
// RFC 8446, Section 4.2.2
b.AddUint16(extensionCookie)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.cookie)
})
})
}
if len(m.keyShares) > 0 {
// RFC 8446, Section 4.2.8
b.AddUint16(extensionKeyShare)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, ks := range m.keyShares {
b.AddUint16(uint16(ks.group))
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(ks.data)
})
}
})
})
}
if m.earlyData {
// RFC 8446, Section 4.2.10
b.AddUint16(extensionEarlyData)
b.AddUint16(0) // empty extension_data
}
if len(m.pskModes) > 0 {
// RFC 8446, Section 4.2.9
b.AddUint16(extensionPSKModes)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.pskModes)
})
})
}
if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
// RFC 8446, Section 4.2.11
b.AddUint16(extensionPreSharedKey)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, psk := range m.pskIdentities {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(psk.label)
})
b.AddUint32(psk.obfuscatedTicketAge)
}
})
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, binder := range m.pskBinders {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(binder)
})
}
})
})
}
extensionsPresent = len(b.BytesOrPanic()) > 2
})
if !extensionsPresent {
*b = bWithoutExtensions
if len(extBytes) > 0 {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(extBytes)
})
}
})
m.raw = b.BytesOrPanic()
return m.raw
m.raw, err = b.Bytes()
return m.raw, err
}
// marshalWithoutBinders returns the ClientHello through the
// PreSharedKeyExtension.identities field, according to RFC 8446, Section
// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.
func (m *clientHelloMsg) marshalWithoutBinders() []byte {
func (m *clientHelloMsg) marshalWithoutBinders() ([]byte, error) {
bindersLen := 2 // uint16 length prefix
for _, binder := range m.pskBinders {
bindersLen += 1 // uint8 length prefix
bindersLen += len(binder)
}
fullMessage := m.marshal()
return fullMessage[:len(fullMessage)-bindersLen]
fullMessage, err := m.marshal()
if err != nil {
return nil, err
}
return fullMessage[:len(fullMessage)-bindersLen], nil
}
// updateBinders updates the m.pskBinders field, if necessary updating the
// cached marshaled representation. The supplied binders must have the same
// length as the current m.pskBinders.
func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {
func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) error {
if len(pskBinders) != len(m.pskBinders) {
panic("tls: internal error: pskBinders length mismatch")
return errors.New("tls: internal error: pskBinders length mismatch")
}
for i := range m.pskBinders {
if len(pskBinders[i]) != len(m.pskBinders[i]) {
panic("tls: internal error: pskBinders length mismatch")
return errors.New("tls: internal error: pskBinders length mismatch")
}
}
m.pskBinders = pskBinders
if m.raw != nil {
lenWithoutBinders := len(m.marshalWithoutBinders())
helloBytes, err := m.marshalWithoutBinders()
if err != nil {
return err
}
lenWithoutBinders := len(helloBytes)
b := cryptobyte.NewFixedBuilder(m.raw[:lenWithoutBinders])
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, binder := range m.pskBinders {
@ -338,9 +345,11 @@ func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {
}
})
if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
panic("tls: internal error: failed to update binders")
return errors.New("tls: internal error: failed to update binders")
}
}
return nil
}
func (m *clientHelloMsg) unmarshal(data []byte) bool {
@ -618,9 +627,98 @@ type serverHelloMsg struct {
selectedGroup CurveID
}
func (m *serverHelloMsg) marshal() []byte {
func (m *serverHelloMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var exts cryptobyte.Builder
if m.ocspStapling {
exts.AddUint16(extensionStatusRequest)
exts.AddUint16(0) // empty extension_data
}
if m.ticketSupported {
exts.AddUint16(extensionSessionTicket)
exts.AddUint16(0) // empty extension_data
}
if m.secureRenegotiationSupported {
exts.AddUint16(extensionRenegotiationInfo)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.secureRenegotiation)
})
})
}
if len(m.alpnProtocol) > 0 {
exts.AddUint16(extensionALPN)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes([]byte(m.alpnProtocol))
})
})
})
}
if len(m.scts) > 0 {
exts.AddUint16(extensionSCT)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
for _, sct := range m.scts {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(sct)
})
}
})
})
}
if m.supportedVersion != 0 {
exts.AddUint16(extensionSupportedVersions)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16(m.supportedVersion)
})
}
if m.serverShare.group != 0 {
exts.AddUint16(extensionKeyShare)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16(uint16(m.serverShare.group))
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.serverShare.data)
})
})
}
if m.selectedIdentityPresent {
exts.AddUint16(extensionPreSharedKey)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16(m.selectedIdentity)
})
}
if len(m.cookie) > 0 {
exts.AddUint16(extensionCookie)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.cookie)
})
})
}
if m.selectedGroup != 0 {
exts.AddUint16(extensionKeyShare)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16(uint16(m.selectedGroup))
})
}
if len(m.supportedPoints) > 0 {
exts.AddUint16(extensionSupportedPoints)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddBytes(m.supportedPoints)
})
})
}
extBytes, err := exts.Bytes()
if err != nil {
return nil, err
}
var b cryptobyte.Builder
@ -634,104 +732,15 @@ func (m *serverHelloMsg) marshal() []byte {
b.AddUint16(m.cipherSuite)
b.AddUint8(m.compressionMethod)
// If extensions aren't present, omit them.
var extensionsPresent bool
bWithoutExtensions := *b
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
if m.ocspStapling {
b.AddUint16(extensionStatusRequest)
b.AddUint16(0) // empty extension_data
}
if m.ticketSupported {
b.AddUint16(extensionSessionTicket)
b.AddUint16(0) // empty extension_data
}
if m.secureRenegotiationSupported {
b.AddUint16(extensionRenegotiationInfo)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.secureRenegotiation)
})
})
}
if len(m.alpnProtocol) > 0 {
b.AddUint16(extensionALPN)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes([]byte(m.alpnProtocol))
})
})
})
}
if len(m.scts) > 0 {
b.AddUint16(extensionSCT)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, sct := range m.scts {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(sct)
})
}
})
})
}
if m.supportedVersion != 0 {
b.AddUint16(extensionSupportedVersions)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16(m.supportedVersion)
})
}
if m.serverShare.group != 0 {
b.AddUint16(extensionKeyShare)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16(uint16(m.serverShare.group))
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.serverShare.data)
})
})
}
if m.selectedIdentityPresent {
b.AddUint16(extensionPreSharedKey)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16(m.selectedIdentity)
})
}
if len(m.cookie) > 0 {
b.AddUint16(extensionCookie)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.cookie)
})
})
}
if m.selectedGroup != 0 {
b.AddUint16(extensionKeyShare)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16(uint16(m.selectedGroup))
})
}
if len(m.supportedPoints) > 0 {
b.AddUint16(extensionSupportedPoints)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.supportedPoints)
})
})
}
extensionsPresent = len(b.BytesOrPanic()) > 2
})
if !extensionsPresent {
*b = bWithoutExtensions
if len(extBytes) > 0 {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(extBytes)
})
}
})
m.raw = b.BytesOrPanic()
return m.raw
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *serverHelloMsg) unmarshal(data []byte) bool {
@ -855,9 +864,9 @@ type encryptedExtensionsMsg struct {
alpnProtocol string
}
func (m *encryptedExtensionsMsg) marshal() []byte {
func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -877,8 +886,9 @@ func (m *encryptedExtensionsMsg) marshal() []byte {
})
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
@ -926,10 +936,10 @@ func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
type endOfEarlyDataMsg struct{}
func (m *endOfEarlyDataMsg) marshal() []byte {
func (m *endOfEarlyDataMsg) marshal() ([]byte, error) {
x := make([]byte, 4)
x[0] = typeEndOfEarlyData
return x
return x, nil
}
func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
@ -941,9 +951,9 @@ type keyUpdateMsg struct {
updateRequested bool
}
func (m *keyUpdateMsg) marshal() []byte {
func (m *keyUpdateMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -956,8 +966,9 @@ func (m *keyUpdateMsg) marshal() []byte {
}
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *keyUpdateMsg) unmarshal(data []byte) bool {
@ -989,9 +1000,9 @@ type newSessionTicketMsgTLS13 struct {
maxEarlyData uint32
}
func (m *newSessionTicketMsgTLS13) marshal() []byte {
func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -1016,8 +1027,9 @@ func (m *newSessionTicketMsgTLS13) marshal() []byte {
})
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
@ -1070,9 +1082,9 @@ type certificateRequestMsgTLS13 struct {
certificateAuthorities [][]byte
}
func (m *certificateRequestMsgTLS13) marshal() []byte {
func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -1131,8 +1143,9 @@ func (m *certificateRequestMsgTLS13) marshal() []byte {
})
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
@ -1216,9 +1229,9 @@ type certificateMsg struct {
certificates [][]byte
}
func (m *certificateMsg) marshal() (x []byte) {
func (m *certificateMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var i int
@ -1227,7 +1240,7 @@ func (m *certificateMsg) marshal() (x []byte) {
}
length := 3 + 3*len(m.certificates) + i
x = make([]byte, 4+length)
x := make([]byte, 4+length)
x[0] = typeCertificate
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
@ -1248,7 +1261,7 @@ func (m *certificateMsg) marshal() (x []byte) {
}
m.raw = x
return
return m.raw, nil
}
func (m *certificateMsg) unmarshal(data []byte) bool {
@ -1295,9 +1308,9 @@ type certificateMsgTLS13 struct {
scts bool
}
func (m *certificateMsgTLS13) marshal() []byte {
func (m *certificateMsgTLS13) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -1315,8 +1328,9 @@ func (m *certificateMsgTLS13) marshal() []byte {
marshalCertificate(b, certificate)
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
@ -1439,9 +1453,9 @@ type serverKeyExchangeMsg struct {
key []byte
}
func (m *serverKeyExchangeMsg) marshal() []byte {
func (m *serverKeyExchangeMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
length := len(m.key)
x := make([]byte, length+4)
@ -1452,7 +1466,7 @@ func (m *serverKeyExchangeMsg) marshal() []byte {
copy(x[4:], m.key)
m.raw = x
return x
return x, nil
}
func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
@ -1469,9 +1483,9 @@ type certificateStatusMsg struct {
response []byte
}
func (m *certificateStatusMsg) marshal() []byte {
func (m *certificateStatusMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -1483,8 +1497,9 @@ func (m *certificateStatusMsg) marshal() []byte {
})
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *certificateStatusMsg) unmarshal(data []byte) bool {
@ -1503,10 +1518,10 @@ func (m *certificateStatusMsg) unmarshal(data []byte) bool {
type serverHelloDoneMsg struct{}
func (m *serverHelloDoneMsg) marshal() []byte {
func (m *serverHelloDoneMsg) marshal() ([]byte, error) {
x := make([]byte, 4)
x[0] = typeServerHelloDone
return x
return x, nil
}
func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
@ -1518,9 +1533,9 @@ type clientKeyExchangeMsg struct {
ciphertext []byte
}
func (m *clientKeyExchangeMsg) marshal() []byte {
func (m *clientKeyExchangeMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
length := len(m.ciphertext)
x := make([]byte, length+4)
@ -1531,7 +1546,7 @@ func (m *clientKeyExchangeMsg) marshal() []byte {
copy(x[4:], m.ciphertext)
m.raw = x
return x
return x, nil
}
func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
@ -1552,9 +1567,9 @@ type finishedMsg struct {
verifyData []byte
}
func (m *finishedMsg) marshal() []byte {
func (m *finishedMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -1563,8 +1578,9 @@ func (m *finishedMsg) marshal() []byte {
b.AddBytes(m.verifyData)
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *finishedMsg) unmarshal(data []byte) bool {
@ -1586,9 +1602,9 @@ type certificateRequestMsg struct {
certificateAuthorities [][]byte
}
func (m *certificateRequestMsg) marshal() (x []byte) {
func (m *certificateRequestMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
// See RFC 4346, Section 7.4.4.
@ -1603,7 +1619,7 @@ func (m *certificateRequestMsg) marshal() (x []byte) {
length += 2 + 2*len(m.supportedSignatureAlgorithms)
}
x = make([]byte, 4+length)
x := make([]byte, 4+length)
x[0] = typeCertificateRequest
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
@ -1638,7 +1654,7 @@ func (m *certificateRequestMsg) marshal() (x []byte) {
}
m.raw = x
return
return m.raw, nil
}
func (m *certificateRequestMsg) unmarshal(data []byte) bool {
@ -1724,9 +1740,9 @@ type certificateVerifyMsg struct {
signature []byte
}
func (m *certificateVerifyMsg) marshal() (x []byte) {
func (m *certificateVerifyMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
var b cryptobyte.Builder
@ -1740,8 +1756,9 @@ func (m *certificateVerifyMsg) marshal() (x []byte) {
})
})
m.raw = b.BytesOrPanic()
return m.raw
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
@ -1764,15 +1781,15 @@ type newSessionTicketMsg struct {
ticket []byte
}
func (m *newSessionTicketMsg) marshal() (x []byte) {
func (m *newSessionTicketMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw
return m.raw, nil
}
// See RFC 5077, Section 3.3.
ticketLen := len(m.ticket)
length := 2 + 4 + ticketLen
x = make([]byte, 4+length)
x := make([]byte, 4+length)
x[0] = typeNewSessionTicket
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
@ -1783,7 +1800,7 @@ func (m *newSessionTicketMsg) marshal() (x []byte) {
m.raw = x
return
return m.raw, nil
}
func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
@ -1811,10 +1828,25 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
type helloRequestMsg struct {
}
func (*helloRequestMsg) marshal() []byte {
return []byte{typeHelloRequest, 0, 0, 0}
func (*helloRequestMsg) marshal() ([]byte, error) {
return []byte{typeHelloRequest, 0, 0, 0}, nil
}
func (*helloRequestMsg) unmarshal(data []byte) bool {
return len(data) == 4
}
type transcriptHash interface {
Write([]byte) (int, error)
}
// transcriptMsg is a helper used to marshal and hash messages which typically
// are not written to the wire, and as such aren't hashed during Conn.writeRecord.
func transcriptMsg(msg handshakeMessage, h transcriptHash) error {
data, err := msg.marshal()
if err != nil {
return err
}
h.Write(data)
return nil
}