| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894 |
- // 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 (
- "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
- nextProtoNeg bool
- serverName string
- ocspStapling bool
- supportedCurves []CurveID
- supportedPoints []uint8
- ticketSupported bool
- sessionTicket []uint8
- supportedSignatureAlgorithms []SignatureScheme
- supportedSignatureAlgorithmsCert []SignatureScheme
- secureRenegotiationSupported bool
- secureRenegotiation []byte
- alpnProtocols []string
- scts bool
- ems bool // [UTLS] actually implemented due to its prevalence
- supportedVersions []uint16
- cookie []byte
- keyShares []keyShare
- earlyData bool
- pskModes []uint8
- pskIdentities []pskIdentity
- pskBinders [][]byte
- }
- func (m *clientHelloMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
- var b cryptobyte.Builder
- b.AddUint8(typeClientHello)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- //b.AddUint16(m.vers)
- b.AddUint16(0x0505)
- 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 extensions aren't present, omit them.
- var extensionsPresent bool
- bWithoutExtensions := *b
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.nextProtoNeg {
- // draft-agl-tls-nextprotoneg-04
- b.AddUint16(extensionNextProtoNeg)
- b.AddUint16(0) // empty extension_data
- }
- 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
- }
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- // 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 {
- 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]
- }
- // updateBinders updates the m.pskBinders field, if necessary updating the
- // cached marshalled representation. The supplied binders must have the same
- // length as the current m.pskBinders.
- func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {
- if len(pskBinders) != len(m.pskBinders) {
- panic("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")
- }
- }
- m.pskBinders = pskBinders
- if m.raw != nil {
- lenWithoutBinders := len(m.marshalWithoutBinders())
- // TODO(filippo): replace with NewFixedBuilder once CL 148882 is imported.
- b := cryptobyte.NewBuilder(m.raw[:lenWithoutBinders])
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, binder := range m.pskBinders {
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(binder)
- })
- }
- })
- if len(b.BytesOrPanic()) != len(m.raw) {
- panic("tls: internal error: failed to update binders")
- }
- }
- }
- 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
- }
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- 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 extensionNextProtoNeg:
- // draft-agl-tls-nextprotoneg-04
- m.nextProtoNeg = true
- 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 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 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
- nextProtoNeg bool
- nextProtos []string
- ocspStapling bool
- ticketSupported bool
- secureRenegotiationSupported bool
- secureRenegotiation []byte
- alpnProtocol string
- ems bool
- scts [][]byte
- supportedVersion uint16
- serverShare keyShare
- selectedIdentityPresent bool
- selectedIdentity uint16
- // HelloRetryRequest extensions
- cookie []byte
- selectedGroup CurveID
- }
- func (m *serverHelloMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
- 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 extensions aren't present, omit them.
- var extensionsPresent bool
- bWithoutExtensions := *b
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.nextProtoNeg {
- b.AddUint16(extensionNextProtoNeg)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, proto := range m.nextProtos {
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes([]byte(proto))
- })
- }
- })
- }
- 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))
- })
- }
- extensionsPresent = len(b.BytesOrPanic()) > 2
- })
- if !extensionsPresent {
- *b = bWithoutExtensions
- }
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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
- }
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- switch extension {
- case extensionNextProtoNeg:
- m.nextProtoNeg = true
- for !extData.Empty() {
- var proto cryptobyte.String
- if !extData.ReadUint8LengthPrefixed(&proto) ||
- proto.Empty() {
- return false
- }
- m.nextProtos = append(m.nextProtos, string(proto))
- }
- case extensionStatusRequest:
- m.ocspStapling = true
- case extensionSessionTicket:
- m.ticketSupported = true
- 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 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
- }
- default:
- // Ignore unknown extensions.
- continue
- }
- if !extData.Empty() {
- return false
- }
- }
- return true
- }
- type encryptedExtensionsMsg struct {
- raw []byte
- alpnProtocol string
- }
- func (m *encryptedExtensionsMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
- 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))
- })
- })
- })
- }
- })
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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)
- default:
- // Ignore unknown extensions.
- continue
- }
- if !extData.Empty() {
- return false
- }
- }
- return true
- }
- type endOfEarlyDataMsg struct{}
- func (m *endOfEarlyDataMsg) marshal() []byte {
- x := make([]byte, 4)
- x[0] = typeEndOfEarlyData
- return x
- }
- func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
- return len(data) == 4
- }
- type keyUpdateMsg struct {
- raw []byte
- updateRequested bool
- }
- func (m *keyUpdateMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
- var b cryptobyte.Builder
- b.AddUint8(typeKeyUpdate)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.updateRequested {
- b.AddUint8(1)
- } else {
- b.AddUint8(0)
- }
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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 {
- if m.raw != nil {
- return m.raw
- }
- 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)
- })
- }
- })
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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 {
- if m.raw != nil {
- return m.raw
- }
- 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)
- })
- }
- })
- })
- }
- })
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
- 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
- }
- 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 {
- if m.raw != nil {
- return m.raw
- }
- 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)
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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 {
- if m.raw != nil {
- return m.raw
- }
- 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
- }
- 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 {
- if m.raw != nil {
- return m.raw
- }
- 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)
- })
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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 {
- x := make([]byte, 4)
- x[0] = typeServerHelloDone
- return x
- }
- func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
- return len(data) == 4
- }
- type clientKeyExchangeMsg struct {
- raw []byte
- ciphertext []byte
- }
- func (m *clientKeyExchangeMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
- 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
- }
- 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 {
- if m.raw != nil {
- return m.raw
- }
- var b cryptobyte.Builder
- b.AddUint8(typeFinished)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.verifyData)
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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 nextProtoMsg struct {
- raw []byte
- proto string
- }
- func (m *nextProtoMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
- l := len(m.proto)
- if l > 255 {
- l = 255
- }
- padding := 32 - (l+2)%32
- length := l + padding + 2
- x := make([]byte, length+4)
- x[0] = typeNextProtocol
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- y := x[4:]
- y[0] = byte(l)
- copy(y[1:], []byte(m.proto[0:l]))
- y = y[1+l:]
- y[0] = byte(padding)
- m.raw = x
- return x
- }
- func (m *nextProtoMsg) unmarshal(data []byte) bool {
- m.raw = data
- if len(data) < 5 {
- return false
- }
- data = data[4:]
- protoLen := int(data[0])
- data = data[1:]
- if len(data) < protoLen {
- return false
- }
- m.proto = string(data[0:protoLen])
- data = data[protoLen:]
- if len(data) < 1 {
- return false
- }
- paddingLen := int(data[0])
- data = data[1:]
- if len(data) != paddingLen {
- return false
- }
- return true
- }
- 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() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
- // 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
- }
- 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() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
- 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)
- })
- })
- m.raw = b.BytesOrPanic()
- return m.raw
- }
- 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() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
- // 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
- }
- 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 {
- return []byte{typeHelloRequest, 0, 0, 0}
- }
- func (*helloRequestMsg) unmarshal(data []byte) bool {
- return len(data) == 4
- }
|