| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925 |
- // Copyright 2009 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package tls
- import (
- "errors"
- "fmt"
- "strings"
- "golang.org/x/crypto/cryptobyte"
- )
- // The marshalingFunction type is an adapter to allow the use of ordinary
- // functions as cryptobyte.MarshalingValue.
- type marshalingFunction func(b *cryptobyte.Builder) error
- func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {
- return f(b)
- }
- // addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If
- // the length of the sequence is not the value specified, it produces an error.
- func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
- b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error {
- if len(v) != n {
- return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v))
- }
- b.AddBytes(v)
- return nil
- }))
- }
- // addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder.
- func addUint64(b *cryptobyte.Builder, v uint64) {
- b.AddUint32(uint32(v >> 32))
- b.AddUint32(uint32(v))
- }
- // readUint64 decodes a big-endian, 64-bit value into out and advances over it.
- // It reports whether the read was successful.
- func readUint64(s *cryptobyte.String, out *uint64) bool {
- var hi, lo uint32
- if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) {
- return false
- }
- *out = uint64(hi)<<32 | uint64(lo)
- return true
- }
- // readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a
- // []byte instead of a cryptobyte.String.
- func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
- return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out))
- }
- // readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a
- // []byte instead of a cryptobyte.String.
- func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
- return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out))
- }
- // readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a
- // []byte instead of a cryptobyte.String.
- func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
- return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out))
- }
- 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
- extendedMasterSecret bool
- alpnProtocols []string
- scts bool
- // ems bool // [uTLS] actually implemented due to its prevalence // removed since crypto/tls implements it
- supportedVersions []uint16
- cookie []byte
- keyShares []keyShare
- earlyData bool
- pskModes []uint8
- pskIdentities []pskIdentity
- pskBinders [][]byte
- quicTransportParameters []byte
- // [uTLS]
- nextProtoNeg bool
- }
- func (m *clientHelloMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- 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 m.extendedMasterSecret {
- // RFC 7627
- exts.AddUint16(extensionExtendedMasterSecret)
- exts.AddUint16(0) // empty extension_data
- }
- 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 m.quicTransportParameters != nil { // marshal zero-length parameters when present
- // RFC 9001, Section 8.2
- exts.AddUint16(extensionQUICTransportParameters)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.quicTransportParameters)
- })
- }
- 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
- b.AddUint8(typeClientHello)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16(m.vers)
- addBytesWithLength(b, m.random, 32)
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.sessionId)
- })
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, suite := range m.cipherSuites {
- b.AddUint16(suite)
- }
- })
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.compressionMethods)
- })
- if len(extBytes) > 0 {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(extBytes)
- })
- }
- })
- 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, error) {
- bindersLen := 2 // uint16 length prefix
- for _, binder := range m.pskBinders {
- bindersLen += 1 // uint8 length prefix
- bindersLen += len(binder)
- }
- 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) error {
- if len(pskBinders) != len(m.pskBinders) {
- return errors.New("tls: internal error: pskBinders length mismatch")
- }
- for i := range m.pskBinders {
- if len(pskBinders[i]) != len(m.pskBinders[i]) {
- return errors.New("tls: internal error: pskBinders length mismatch")
- }
- }
- m.pskBinders = pskBinders
- if m.raw != nil {
- 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 {
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(binder)
- })
- }
- })
- if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
- return errors.New("tls: internal error: failed to update binders")
- }
- }
- return nil
- }
- func (m *clientHelloMsg) unmarshal(data []byte) bool {
- *m = clientHelloMsg{raw: data}
- s := cryptobyte.String(data)
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
- !readUint8LengthPrefixed(&s, &m.sessionId) {
- return false
- }
- var cipherSuites cryptobyte.String
- if !s.ReadUint16LengthPrefixed(&cipherSuites) {
- return false
- }
- m.cipherSuites = []uint16{}
- m.secureRenegotiationSupported = false
- for !cipherSuites.Empty() {
- var suite uint16
- if !cipherSuites.ReadUint16(&suite) {
- return false
- }
- if suite == scsvRenegotiation {
- m.secureRenegotiationSupported = true
- }
- m.cipherSuites = append(m.cipherSuites, suite)
- }
- if !readUint8LengthPrefixed(&s, &m.compressionMethods) {
- return false
- }
- if s.Empty() {
- // ClientHello is optionally followed by extension data
- return true
- }
- var extensions cryptobyte.String
- if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
- return false
- }
- seenExts := make(map[uint16]bool)
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- if seenExts[extension] {
- return false
- }
- seenExts[extension] = true
- switch extension {
- case extensionServerName:
- // RFC 6066, Section 3
- var nameList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
- return false
- }
- for !nameList.Empty() {
- var nameType uint8
- var serverName cryptobyte.String
- if !nameList.ReadUint8(&nameType) ||
- !nameList.ReadUint16LengthPrefixed(&serverName) ||
- serverName.Empty() {
- return false
- }
- if nameType != 0 {
- continue
- }
- if len(m.serverName) != 0 {
- // Multiple names of the same name_type are prohibited.
- return false
- }
- m.serverName = string(serverName)
- // An SNI value may not include a trailing dot.
- if strings.HasSuffix(m.serverName, ".") {
- return false
- }
- }
- case extensionStatusRequest:
- // RFC 4366, Section 3.6
- var statusType uint8
- var ignored cryptobyte.String
- if !extData.ReadUint8(&statusType) ||
- !extData.ReadUint16LengthPrefixed(&ignored) ||
- !extData.ReadUint16LengthPrefixed(&ignored) {
- return false
- }
- m.ocspStapling = statusType == statusTypeOCSP
- case extensionSupportedCurves:
- // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
- var curves cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() {
- return false
- }
- for !curves.Empty() {
- var curve uint16
- if !curves.ReadUint16(&curve) {
- return false
- }
- m.supportedCurves = append(m.supportedCurves, CurveID(curve))
- }
- case extensionSupportedPoints:
- // RFC 4492, Section 5.1.2
- if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
- len(m.supportedPoints) == 0 {
- return false
- }
- case extensionSessionTicket:
- // RFC 5077, Section 3.2
- m.ticketSupported = true
- extData.ReadBytes(&m.sessionTicket, len(extData))
- case extensionSignatureAlgorithms:
- // RFC 5246, Section 7.4.1.4.1
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithms = append(
- m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
- }
- case extensionSignatureAlgorithmsCert:
- // RFC 8446, Section 4.2.3
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithmsCert = append(
- m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
- }
- case extensionRenegotiationInfo:
- // RFC 5746, Section 3.2
- if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
- return false
- }
- m.secureRenegotiationSupported = true
- case extensionExtendedMasterSecret:
- // RFC 7627
- m.extendedMasterSecret = true
- case extensionALPN:
- // RFC 7301, Section 3.1
- var protoList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
- return false
- }
- for !protoList.Empty() {
- var proto cryptobyte.String
- if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() {
- return false
- }
- m.alpnProtocols = append(m.alpnProtocols, string(proto))
- }
- case extensionSCT:
- // RFC 6962, Section 3.3.1
- m.scts = true
- case extensionSupportedVersions:
- // RFC 8446, Section 4.2.1
- var versList cryptobyte.String
- if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() {
- return false
- }
- for !versList.Empty() {
- var vers uint16
- if !versList.ReadUint16(&vers) {
- return false
- }
- m.supportedVersions = append(m.supportedVersions, vers)
- }
- case extensionCookie:
- // RFC 8446, Section 4.2.2
- if !readUint16LengthPrefixed(&extData, &m.cookie) ||
- len(m.cookie) == 0 {
- return false
- }
- case extensionKeyShare:
- // RFC 8446, Section 4.2.8
- var clientShares cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&clientShares) {
- return false
- }
- for !clientShares.Empty() {
- var ks keyShare
- if !clientShares.ReadUint16((*uint16)(&ks.group)) ||
- !readUint16LengthPrefixed(&clientShares, &ks.data) ||
- len(ks.data) == 0 {
- return false
- }
- m.keyShares = append(m.keyShares, ks)
- }
- case extensionEarlyData:
- // RFC 8446, Section 4.2.10
- m.earlyData = true
- case extensionPSKModes:
- // RFC 8446, Section 4.2.9
- if !readUint8LengthPrefixed(&extData, &m.pskModes) {
- return false
- }
- case extensionQUICTransportParameters:
- m.quicTransportParameters = make([]byte, len(extData))
- if !extData.CopyBytes(m.quicTransportParameters) {
- return false
- }
- case extensionPreSharedKey:
- // RFC 8446, Section 4.2.11
- if !extensions.Empty() {
- return false // pre_shared_key must be the last extension
- }
- var identities cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() {
- return false
- }
- for !identities.Empty() {
- var psk pskIdentity
- if !readUint16LengthPrefixed(&identities, &psk.label) ||
- !identities.ReadUint32(&psk.obfuscatedTicketAge) ||
- len(psk.label) == 0 {
- return false
- }
- m.pskIdentities = append(m.pskIdentities, psk)
- }
- var binders cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() {
- return false
- }
- for !binders.Empty() {
- var binder []byte
- if !readUint8LengthPrefixed(&binders, &binder) ||
- len(binder) == 0 {
- return false
- }
- m.pskBinders = append(m.pskBinders, binder)
- }
- default:
- // Ignore unknown extensions.
- continue
- }
- if !extData.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
- extendedMasterSecret bool
- alpnProtocol string
- scts [][]byte
- supportedVersion uint16
- serverShare keyShare
- selectedIdentityPresent bool
- selectedIdentity uint16
- supportedPoints []uint8
- // HelloRetryRequest extensions
- cookie []byte
- selectedGroup CurveID
- // [uTLS]
- nextProtoNeg bool
- nextProtos []string
- }
- func (m *serverHelloMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- 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 m.extendedMasterSecret {
- exts.AddUint16(extensionExtendedMasterSecret)
- exts.AddUint16(0) // empty extension_data
- }
- 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
- b.AddUint8(typeServerHello)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16(m.vers)
- addBytesWithLength(b, m.random, 32)
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.sessionId)
- })
- b.AddUint16(m.cipherSuite)
- b.AddUint8(m.compressionMethod)
- if len(extBytes) > 0 {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(extBytes)
- })
- }
- })
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *serverHelloMsg) unmarshal(data []byte) bool {
- *m = serverHelloMsg{raw: data}
- s := cryptobyte.String(data)
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
- !readUint8LengthPrefixed(&s, &m.sessionId) ||
- !s.ReadUint16(&m.cipherSuite) ||
- !s.ReadUint8(&m.compressionMethod) {
- return false
- }
- if s.Empty() {
- // ServerHello is optionally followed by extension data
- return true
- }
- var extensions cryptobyte.String
- if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
- return false
- }
- seenExts := make(map[uint16]bool)
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- if seenExts[extension] {
- return false
- }
- seenExts[extension] = true
- switch extension {
- case extensionStatusRequest:
- m.ocspStapling = true
- case extensionSessionTicket:
- m.ticketSupported = true
- // [UTLS] crypto/tls finally supports EMS! Now we don't do anything special here.
- // case utlsExtensionExtendedMasterSecret:
- // // No sanity check for this extension: pretending not to know it.
- // // if length > 0 {
- // // return false
- // // }
- // m.ems = true
- case extensionRenegotiationInfo:
- if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
- return false
- }
- m.secureRenegotiationSupported = true
- case extensionExtendedMasterSecret:
- m.extendedMasterSecret = true
- case extensionALPN:
- var protoList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
- return false
- }
- var proto cryptobyte.String
- if !protoList.ReadUint8LengthPrefixed(&proto) ||
- proto.Empty() || !protoList.Empty() {
- return false
- }
- m.alpnProtocol = string(proto)
- case extensionSCT:
- var sctList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
- return false
- }
- for !sctList.Empty() {
- var sct []byte
- if !readUint16LengthPrefixed(&sctList, &sct) ||
- len(sct) == 0 {
- return false
- }
- m.scts = append(m.scts, sct)
- }
- case extensionSupportedVersions:
- if !extData.ReadUint16(&m.supportedVersion) {
- return false
- }
- case extensionCookie:
- if !readUint16LengthPrefixed(&extData, &m.cookie) ||
- len(m.cookie) == 0 {
- return false
- }
- case extensionKeyShare:
- // This extension has different formats in SH and HRR, accept either
- // and let the handshake logic decide. See RFC 8446, Section 4.2.8.
- if len(extData) == 2 {
- if !extData.ReadUint16((*uint16)(&m.selectedGroup)) {
- return false
- }
- } else {
- if !extData.ReadUint16((*uint16)(&m.serverShare.group)) ||
- !readUint16LengthPrefixed(&extData, &m.serverShare.data) {
- return false
- }
- }
- case extensionPreSharedKey:
- m.selectedIdentityPresent = true
- if !extData.ReadUint16(&m.selectedIdentity) {
- return false
- }
- case extensionSupportedPoints:
- // RFC 4492, Section 5.1.2
- if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
- len(m.supportedPoints) == 0 {
- return false
- }
- default:
- // Ignore unknown extensions.
- continue
- }
- if !extData.Empty() {
- return false
- }
- }
- return true
- }
- type encryptedExtensionsMsg struct {
- raw []byte
- alpnProtocol string
- quicTransportParameters []byte
- earlyData bool
- utls utlsEncryptedExtensionsMsgExtraFields // [uTLS]
- }
- func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeEncryptedExtensions)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- 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 m.quicTransportParameters != nil { // marshal zero-length parameters when present
- // draft-ietf-quic-tls-32, Section 8.2
- b.AddUint16(extensionQUICTransportParameters)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.quicTransportParameters)
- })
- }
- if m.earlyData {
- // RFC 8446, Section 4.2.10
- b.AddUint16(extensionEarlyData)
- b.AddUint16(0) // empty extension_data
- }
- })
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
- *m = encryptedExtensionsMsg{raw: data}
- s := cryptobyte.String(data)
- var extensions cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
- return false
- }
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- switch extension {
- case extensionALPN:
- var protoList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
- return false
- }
- var proto cryptobyte.String
- if !protoList.ReadUint8LengthPrefixed(&proto) ||
- proto.Empty() || !protoList.Empty() {
- return false
- }
- m.alpnProtocol = string(proto)
- case extensionQUICTransportParameters:
- m.quicTransportParameters = make([]byte, len(extData))
- if !extData.CopyBytes(m.quicTransportParameters) {
- return false
- }
- case extensionEarlyData:
- // RFC 8446, Section 4.2.10
- m.earlyData = true
- default:
- // [UTLS SECTION START]
- if !m.utlsUnmarshal(extension, extData) {
- return false // return false when ERROR
- }
- // [UTLS SECTION END]
- // Ignore unknown extensions.
- continue
- }
- if !extData.Empty() {
- return false
- }
- }
- return true
- }
- type endOfEarlyDataMsg struct{}
- func (m *endOfEarlyDataMsg) marshal() ([]byte, error) {
- x := make([]byte, 4)
- x[0] = typeEndOfEarlyData
- return x, nil
- }
- func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
- return len(data) == 4
- }
- type keyUpdateMsg struct {
- raw []byte
- updateRequested bool
- }
- func (m *keyUpdateMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeKeyUpdate)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.updateRequested {
- b.AddUint8(1)
- } else {
- b.AddUint8(0)
- }
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *keyUpdateMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
- var updateRequested uint8
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8(&updateRequested) || !s.Empty() {
- return false
- }
- switch updateRequested {
- case 0:
- m.updateRequested = false
- case 1:
- m.updateRequested = true
- default:
- return false
- }
- return true
- }
- type newSessionTicketMsgTLS13 struct {
- raw []byte
- lifetime uint32
- ageAdd uint32
- nonce []byte
- label []byte
- maxEarlyData uint32
- }
- func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeNewSessionTicket)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint32(m.lifetime)
- b.AddUint32(m.ageAdd)
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.nonce)
- })
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.label)
- })
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.maxEarlyData > 0 {
- b.AddUint16(extensionEarlyData)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint32(m.maxEarlyData)
- })
- }
- })
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
- *m = newSessionTicketMsgTLS13{raw: data}
- s := cryptobyte.String(data)
- var extensions cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint32(&m.lifetime) ||
- !s.ReadUint32(&m.ageAdd) ||
- !readUint8LengthPrefixed(&s, &m.nonce) ||
- !readUint16LengthPrefixed(&s, &m.label) ||
- !s.ReadUint16LengthPrefixed(&extensions) ||
- !s.Empty() {
- return false
- }
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- switch extension {
- case extensionEarlyData:
- if !extData.ReadUint32(&m.maxEarlyData) {
- return false
- }
- default:
- // Ignore unknown extensions.
- continue
- }
- if !extData.Empty() {
- return false
- }
- }
- return true
- }
- type certificateRequestMsgTLS13 struct {
- raw []byte
- ocspStapling bool
- scts bool
- supportedSignatureAlgorithms []SignatureScheme
- supportedSignatureAlgorithmsCert []SignatureScheme
- certificateAuthorities [][]byte
- }
- func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeCertificateRequest)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- // certificate_request_context (SHALL be zero length unless used for
- // post-handshake authentication)
- b.AddUint8(0)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.ocspStapling {
- b.AddUint16(extensionStatusRequest)
- b.AddUint16(0) // empty extension_data
- }
- if m.scts {
- // RFC 8446, Section 4.4.2.1 makes no mention of
- // signed_certificate_timestamp in CertificateRequest, but
- // "Extensions in the Certificate message from the client MUST
- // correspond to extensions in the CertificateRequest message
- // from the server." and it appears in the table in Section 4.2.
- b.AddUint16(extensionSCT)
- b.AddUint16(0) // empty extension_data
- }
- if len(m.supportedSignatureAlgorithms) > 0 {
- 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 {
- 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 len(m.certificateAuthorities) > 0 {
- b.AddUint16(extensionCertificateAuthorities)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, ca := range m.certificateAuthorities {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(ca)
- })
- }
- })
- })
- }
- })
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
- *m = certificateRequestMsgTLS13{raw: data}
- s := cryptobyte.String(data)
- var context, extensions cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
- !s.ReadUint16LengthPrefixed(&extensions) ||
- !s.Empty() {
- return false
- }
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- switch extension {
- case extensionStatusRequest:
- m.ocspStapling = true
- case extensionSCT:
- m.scts = true
- case extensionSignatureAlgorithms:
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithms = append(
- m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
- }
- case extensionSignatureAlgorithmsCert:
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithmsCert = append(
- m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
- }
- case extensionCertificateAuthorities:
- var auths cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() {
- return false
- }
- for !auths.Empty() {
- var ca []byte
- if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 {
- return false
- }
- m.certificateAuthorities = append(m.certificateAuthorities, ca)
- }
- default:
- // Ignore unknown extensions.
- continue
- }
- if !extData.Empty() {
- return false
- }
- }
- return true
- }
- type certificateMsg struct {
- raw []byte
- certificates [][]byte
- }
- func (m *certificateMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var i int
- for _, slice := range m.certificates {
- i += len(slice)
- }
- length := 3 + 3*len(m.certificates) + i
- x := make([]byte, 4+length)
- x[0] = typeCertificate
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- certificateOctets := length - 3
- x[4] = uint8(certificateOctets >> 16)
- x[5] = uint8(certificateOctets >> 8)
- x[6] = uint8(certificateOctets)
- y := x[7:]
- for _, slice := range m.certificates {
- y[0] = uint8(len(slice) >> 16)
- y[1] = uint8(len(slice) >> 8)
- y[2] = uint8(len(slice))
- copy(y[3:], slice)
- y = y[3+len(slice):]
- }
- m.raw = x
- return m.raw, nil
- }
- func (m *certificateMsg) unmarshal(data []byte) bool {
- if len(data) < 7 {
- return false
- }
- m.raw = data
- certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
- if uint32(len(data)) != certsLen+7 {
- return false
- }
- numCerts := 0
- d := data[7:]
- for certsLen > 0 {
- if len(d) < 4 {
- return false
- }
- certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- if uint32(len(d)) < 3+certLen {
- return false
- }
- d = d[3+certLen:]
- certsLen -= 3 + certLen
- numCerts++
- }
- m.certificates = make([][]byte, numCerts)
- d = data[7:]
- for i := 0; i < numCerts; i++ {
- certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- m.certificates[i] = d[3 : 3+certLen]
- d = d[3+certLen:]
- }
- return true
- }
- type certificateMsgTLS13 struct {
- raw []byte
- certificate Certificate
- ocspStapling bool
- scts bool
- }
- func (m *certificateMsgTLS13) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeCertificate)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8(0) // certificate_request_context
- certificate := m.certificate
- if !m.ocspStapling {
- certificate.OCSPStaple = nil
- }
- if !m.scts {
- certificate.SignedCertificateTimestamps = nil
- }
- marshalCertificate(b, certificate)
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- for i, cert := range certificate.Certificate {
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(cert)
- })
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if i > 0 {
- // This library only supports OCSP and SCT for leaf certificates.
- return
- }
- if certificate.OCSPStaple != nil {
- b.AddUint16(extensionStatusRequest)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8(statusTypeOCSP)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(certificate.OCSPStaple)
- })
- })
- }
- if certificate.SignedCertificateTimestamps != nil {
- b.AddUint16(extensionSCT)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, sct := range certificate.SignedCertificateTimestamps {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(sct)
- })
- }
- })
- })
- }
- })
- }
- })
- }
- func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
- *m = certificateMsgTLS13{raw: data}
- s := cryptobyte.String(data)
- var context cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
- !unmarshalCertificate(&s, &m.certificate) ||
- !s.Empty() {
- return false
- }
- m.scts = m.certificate.SignedCertificateTimestamps != nil
- m.ocspStapling = m.certificate.OCSPStaple != nil
- return true
- }
- func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool {
- var certList cryptobyte.String
- if !s.ReadUint24LengthPrefixed(&certList) {
- return false
- }
- for !certList.Empty() {
- var cert []byte
- var extensions cryptobyte.String
- if !readUint24LengthPrefixed(&certList, &cert) ||
- !certList.ReadUint16LengthPrefixed(&extensions) {
- return false
- }
- certificate.Certificate = append(certificate.Certificate, cert)
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- if len(certificate.Certificate) > 1 {
- // This library only supports OCSP and SCT for leaf certificates.
- continue
- }
- switch extension {
- case extensionStatusRequest:
- var statusType uint8
- if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
- !readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) ||
- len(certificate.OCSPStaple) == 0 {
- return false
- }
- case extensionSCT:
- var sctList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
- return false
- }
- for !sctList.Empty() {
- var sct []byte
- if !readUint16LengthPrefixed(&sctList, &sct) ||
- len(sct) == 0 {
- return false
- }
- certificate.SignedCertificateTimestamps = append(
- certificate.SignedCertificateTimestamps, sct)
- }
- default:
- // Ignore unknown extensions.
- continue
- }
- if !extData.Empty() {
- return false
- }
- }
- }
- return true
- }
- type serverKeyExchangeMsg struct {
- raw []byte
- key []byte
- }
- func (m *serverKeyExchangeMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- length := len(m.key)
- x := make([]byte, length+4)
- x[0] = typeServerKeyExchange
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- copy(x[4:], m.key)
- m.raw = x
- return x, nil
- }
- func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
- m.raw = data
- if len(data) < 4 {
- return false
- }
- m.key = data[4:]
- return true
- }
- type certificateStatusMsg struct {
- raw []byte
- response []byte
- }
- func (m *certificateStatusMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeCertificateStatus)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8(statusTypeOCSP)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.response)
- })
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *certificateStatusMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
- var statusType uint8
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
- !readUint24LengthPrefixed(&s, &m.response) ||
- len(m.response) == 0 || !s.Empty() {
- return false
- }
- return true
- }
- type serverHelloDoneMsg struct{}
- func (m *serverHelloDoneMsg) marshal() ([]byte, error) {
- x := make([]byte, 4)
- x[0] = typeServerHelloDone
- return x, nil
- }
- func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
- return len(data) == 4
- }
- type clientKeyExchangeMsg struct {
- raw []byte
- ciphertext []byte
- }
- func (m *clientKeyExchangeMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- length := len(m.ciphertext)
- x := make([]byte, length+4)
- x[0] = typeClientKeyExchange
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- copy(x[4:], m.ciphertext)
- m.raw = x
- return x, nil
- }
- func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
- m.raw = data
- if len(data) < 4 {
- return false
- }
- l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
- if l != len(data)-4 {
- return false
- }
- m.ciphertext = data[4:]
- return true
- }
- type finishedMsg struct {
- raw []byte
- verifyData []byte
- }
- func (m *finishedMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeFinished)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.verifyData)
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *finishedMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
- return s.Skip(1) &&
- readUint24LengthPrefixed(&s, &m.verifyData) &&
- s.Empty()
- }
- type certificateRequestMsg struct {
- raw []byte
- // hasSignatureAlgorithm indicates whether this message includes a list of
- // supported signature algorithms. This change was introduced with TLS 1.2.
- hasSignatureAlgorithm bool
- certificateTypes []byte
- supportedSignatureAlgorithms []SignatureScheme
- certificateAuthorities [][]byte
- }
- func (m *certificateRequestMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- // See RFC 4346, Section 7.4.4.
- length := 1 + len(m.certificateTypes) + 2
- casLength := 0
- for _, ca := range m.certificateAuthorities {
- casLength += 2 + len(ca)
- }
- length += casLength
- if m.hasSignatureAlgorithm {
- length += 2 + 2*len(m.supportedSignatureAlgorithms)
- }
- x := make([]byte, 4+length)
- x[0] = typeCertificateRequest
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- x[4] = uint8(len(m.certificateTypes))
- copy(x[5:], m.certificateTypes)
- y := x[5+len(m.certificateTypes):]
- if m.hasSignatureAlgorithm {
- n := len(m.supportedSignatureAlgorithms) * 2
- y[0] = uint8(n >> 8)
- y[1] = uint8(n)
- y = y[2:]
- for _, sigAlgo := range m.supportedSignatureAlgorithms {
- y[0] = uint8(sigAlgo >> 8)
- y[1] = uint8(sigAlgo)
- y = y[2:]
- }
- }
- y[0] = uint8(casLength >> 8)
- y[1] = uint8(casLength)
- y = y[2:]
- for _, ca := range m.certificateAuthorities {
- y[0] = uint8(len(ca) >> 8)
- y[1] = uint8(len(ca))
- y = y[2:]
- copy(y, ca)
- y = y[len(ca):]
- }
- m.raw = x
- return m.raw, nil
- }
- func (m *certificateRequestMsg) unmarshal(data []byte) bool {
- m.raw = data
- if len(data) < 5 {
- return false
- }
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return false
- }
- numCertTypes := int(data[4])
- data = data[5:]
- if numCertTypes == 0 || len(data) <= numCertTypes {
- return false
- }
- m.certificateTypes = make([]byte, numCertTypes)
- if copy(m.certificateTypes, data) != numCertTypes {
- return false
- }
- data = data[numCertTypes:]
- if m.hasSignatureAlgorithm {
- if len(data) < 2 {
- return false
- }
- sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
- data = data[2:]
- if sigAndHashLen&1 != 0 {
- return false
- }
- if len(data) < int(sigAndHashLen) {
- return false
- }
- numSigAlgos := sigAndHashLen / 2
- m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos)
- for i := range m.supportedSignatureAlgorithms {
- m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
- data = data[2:]
- }
- }
- if len(data) < 2 {
- return false
- }
- casLength := uint16(data[0])<<8 | uint16(data[1])
- data = data[2:]
- if len(data) < int(casLength) {
- return false
- }
- cas := make([]byte, casLength)
- copy(cas, data)
- data = data[casLength:]
- m.certificateAuthorities = nil
- for len(cas) > 0 {
- if len(cas) < 2 {
- return false
- }
- caLen := uint16(cas[0])<<8 | uint16(cas[1])
- cas = cas[2:]
- if len(cas) < int(caLen) {
- return false
- }
- m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
- cas = cas[caLen:]
- }
- return len(data) == 0
- }
- type certificateVerifyMsg struct {
- raw []byte
- hasSignatureAlgorithm bool // format change introduced in TLS 1.2
- signatureAlgorithm SignatureScheme
- signature []byte
- }
- func (m *certificateVerifyMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- var b cryptobyte.Builder
- b.AddUint8(typeCertificateVerify)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.hasSignatureAlgorithm {
- b.AddUint16(uint16(m.signatureAlgorithm))
- }
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.signature)
- })
- })
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
- }
- func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
- if !s.Skip(4) { // message type and uint24 length field
- return false
- }
- if m.hasSignatureAlgorithm {
- if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) {
- return false
- }
- }
- return readUint16LengthPrefixed(&s, &m.signature) && s.Empty()
- }
- type newSessionTicketMsg struct {
- raw []byte
- ticket []byte
- }
- func (m *newSessionTicketMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- // See RFC 5077, Section 3.3.
- ticketLen := len(m.ticket)
- length := 2 + 4 + ticketLen
- x := make([]byte, 4+length)
- x[0] = typeNewSessionTicket
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- x[8] = uint8(ticketLen >> 8)
- x[9] = uint8(ticketLen)
- copy(x[10:], m.ticket)
- m.raw = x
- return m.raw, nil
- }
- func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
- m.raw = data
- if len(data) < 10 {
- return false
- }
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return false
- }
- ticketLen := int(data[8])<<8 + int(data[9])
- if len(data)-10 != ticketLen {
- return false
- }
- m.ticket = data[10:]
- return true
- }
- type helloRequestMsg struct {
- }
- 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
- }
|