|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682 |
- // 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 (
- "bytes"
- "encoding/binary"
- "strings"
- )
-
- // signAlgosCertList helper function returns either list of signature algorithms in case
- // signature_algorithms_cert extension should be marshalled or nil in the other case.
- // signAlgos is a list of algorithms from signature_algorithms extension. signAlgosCert is a list
- // of algorithms from signature_algorithms_cert extension.
- func signAlgosCertList(signAlgos, signAlgosCert []SignatureScheme) []SignatureScheme {
- if eqSignatureAlgorithms(signAlgos, signAlgosCert) {
- // ensure that only supported_algorithms extension is send if supported_algorithms_cert
- // has identical content
- return nil
- }
- return signAlgosCert
- }
-
- type clientHelloMsg struct {
- raw []byte
- rawTruncated []byte // for PSK binding
- vers uint16
- random []byte
- sessionId []byte
- cipherSuites []uint16
- compressionMethods []uint8
- nextProtoNeg bool
- serverName string
- ocspStapling bool
- scts bool
- supportedCurves []CurveID
- supportedPoints []uint8
- ticketSupported bool
- sessionTicket []uint8
- supportedSignatureAlgorithms []SignatureScheme
- supportedSignatureAlgorithmsCert []SignatureScheme
- secureRenegotiation []byte
- secureRenegotiationSupported bool
- alpnProtocols []string
- keyShares []keyShare
- supportedVersions []uint16
- psks []psk
- pskKeyExchangeModes []uint8
- earlyData bool
- }
-
- // Helpers
- // Function used for signature_algorithms and signature_algorithrms_cert extensions only
- // (for more details, see TLS 1.3 draft 28, 4.2.3)
- // Function advances data slice and returns it, so that it can be used for further processing
- func marshalExtensionSignatureAlgorithms(extension uint16, data []byte, schemes []SignatureScheme) []byte {
- algNum := uint16(len(schemes))
- if algNum == 0 {
- return data
- }
-
- binary.BigEndian.PutUint16(data, extension)
- data = data[2:]
- binary.BigEndian.PutUint16(data, (2*algNum)+2) // +1 for length
- data = data[2:]
- binary.BigEndian.PutUint16(data, (2 * algNum))
- data = data[2:]
-
- for _, algo := range schemes {
- binary.BigEndian.PutUint16(data, uint16(algo))
- data = data[2:]
- }
- return data
- }
-
- // Function used for unmarshalling signature_algorithms or signature_algorithms_cert extensions only
- // (for more details, see TLS 1.3 draft 28, 4.2.3)
- // In case of error function returns alertDecoderError otherwise filled SignatureScheme slice and alertSuccess
- func unmarshalExtensionSignatureAlgorithms(data []byte, length int) ([]SignatureScheme, alert) {
-
- if length < 2 || length&1 != 0 {
- return nil, alertDecodeError
- }
-
- algLen := binary.BigEndian.Uint16(data)
- idx := 2
-
- if int(algLen) != length-2 {
- return nil, alertDecodeError
- }
-
- schemes := make([]SignatureScheme, algLen/2)
- for i := range schemes {
- schemes[i] = SignatureScheme(binary.BigEndian.Uint16(data[idx:]))
- idx += 2
- }
- return schemes, alertSuccess
- }
-
- func (m *clientHelloMsg) equal(i interface{}) bool {
- m1, ok := i.(*clientHelloMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.vers == m1.vers &&
- bytes.Equal(m.random, m1.random) &&
- bytes.Equal(m.sessionId, m1.sessionId) &&
- eqUint16s(m.cipherSuites, m1.cipherSuites) &&
- bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
- m.nextProtoNeg == m1.nextProtoNeg &&
- m.serverName == m1.serverName &&
- m.ocspStapling == m1.ocspStapling &&
- m.scts == m1.scts &&
- eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
- bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
- m.ticketSupported == m1.ticketSupported &&
- bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
- eqSignatureAlgorithms(m.supportedSignatureAlgorithms, m1.supportedSignatureAlgorithms) &&
- eqSignatureAlgorithms(m.supportedSignatureAlgorithmsCert, m1.supportedSignatureAlgorithmsCert) &&
- m.secureRenegotiationSupported == m1.secureRenegotiationSupported &&
- bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
- eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
- eqKeyShares(m.keyShares, m1.keyShares) &&
- eqUint16s(m.supportedVersions, m1.supportedVersions) &&
- m.earlyData == m1.earlyData
- }
-
- func (m *clientHelloMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
-
- length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
- numExtensions := 0
- extensionsLength := 0
-
- // Indicates wether to send signature_algorithms_cert extension
- if m.nextProtoNeg {
- numExtensions++
- }
- if m.ocspStapling {
- extensionsLength += 1 + 2 + 2
- numExtensions++
- }
- if len(m.serverName) > 0 {
- extensionsLength += 5 + len(m.serverName)
- numExtensions++
- }
- if len(m.supportedCurves) > 0 {
- extensionsLength += 2 + 2*len(m.supportedCurves)
- numExtensions++
- }
- if len(m.supportedPoints) > 0 {
- extensionsLength += 1 + len(m.supportedPoints)
- numExtensions++
- }
- if m.ticketSupported {
- extensionsLength += len(m.sessionTicket)
- numExtensions++
- }
- if len(m.supportedSignatureAlgorithms) > 0 {
- extensionsLength += 2 + 2*len(m.supportedSignatureAlgorithms)
- numExtensions++
- }
- if m.getSignatureAlgorithmsCert() != nil {
- extensionsLength += 2 + 2*len(m.getSignatureAlgorithmsCert())
- numExtensions++
- }
- if m.secureRenegotiationSupported {
- extensionsLength += 1 + len(m.secureRenegotiation)
- numExtensions++
- }
- if len(m.alpnProtocols) > 0 {
- extensionsLength += 2
- for _, s := range m.alpnProtocols {
- if l := len(s); l == 0 || l > 255 {
- panic("invalid ALPN protocol")
- }
- extensionsLength++
- extensionsLength += len(s)
- }
- numExtensions++
- }
- if m.scts {
- numExtensions++
- }
- if len(m.keyShares) > 0 {
- extensionsLength += 2
- for _, k := range m.keyShares {
- extensionsLength += 4 + len(k.data)
- }
- numExtensions++
- }
- if len(m.supportedVersions) > 0 {
- extensionsLength += 1 + 2*len(m.supportedVersions)
- numExtensions++
- }
- if m.earlyData {
- numExtensions++
- }
- if numExtensions > 0 {
- extensionsLength += 4 * numExtensions
- length += 2 + extensionsLength
- }
-
- x := make([]byte, 4+length)
- x[0] = typeClientHello
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- x[4] = uint8(m.vers >> 8)
- x[5] = uint8(m.vers)
- copy(x[6:38], m.random)
- x[38] = uint8(len(m.sessionId))
- copy(x[39:39+len(m.sessionId)], m.sessionId)
- y := x[39+len(m.sessionId):]
- y[0] = uint8(len(m.cipherSuites) >> 7)
- y[1] = uint8(len(m.cipherSuites) << 1)
- for i, suite := range m.cipherSuites {
- y[2+i*2] = uint8(suite >> 8)
- y[3+i*2] = uint8(suite)
- }
- z := y[2+len(m.cipherSuites)*2:]
- z[0] = uint8(len(m.compressionMethods))
- copy(z[1:], m.compressionMethods)
-
- z = z[1+len(m.compressionMethods):]
- if numExtensions > 0 {
- z[0] = byte(extensionsLength >> 8)
- z[1] = byte(extensionsLength)
- z = z[2:]
- }
- if m.nextProtoNeg {
- z[0] = byte(extensionNextProtoNeg >> 8)
- z[1] = byte(extensionNextProtoNeg & 0xff)
- // The length is always 0
- z = z[4:]
- }
- if len(m.serverName) > 0 {
- z[0] = byte(extensionServerName >> 8)
- z[1] = byte(extensionServerName & 0xff)
- l := len(m.serverName) + 5
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- z = z[4:]
-
- // RFC 3546, section 3.1
- //
- // struct {
- // NameType name_type;
- // select (name_type) {
- // case host_name: HostName;
- // } name;
- // } ServerName;
- //
- // enum {
- // host_name(0), (255)
- // } NameType;
- //
- // opaque HostName<1..2^16-1>;
- //
- // struct {
- // ServerName server_name_list<1..2^16-1>
- // } ServerNameList;
-
- z[0] = byte((len(m.serverName) + 3) >> 8)
- z[1] = byte(len(m.serverName) + 3)
- z[3] = byte(len(m.serverName) >> 8)
- z[4] = byte(len(m.serverName))
- copy(z[5:], []byte(m.serverName))
- z = z[l:]
- }
- if m.ocspStapling {
- // RFC 4366, section 3.6
- z[0] = byte(extensionStatusRequest >> 8)
- z[1] = byte(extensionStatusRequest)
- z[2] = 0
- z[3] = 5
- z[4] = 1 // OCSP type
- // Two zero valued uint16s for the two lengths.
- z = z[9:]
- }
- if len(m.supportedCurves) > 0 {
- // http://tools.ietf.org/html/rfc4492#section-5.5.1
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.4
- z[0] = byte(extensionSupportedCurves >> 8)
- z[1] = byte(extensionSupportedCurves)
- l := 2 + 2*len(m.supportedCurves)
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- l -= 2
- z[4] = byte(l >> 8)
- z[5] = byte(l)
- z = z[6:]
- for _, curve := range m.supportedCurves {
- z[0] = byte(curve >> 8)
- z[1] = byte(curve)
- z = z[2:]
- }
- }
- if len(m.supportedPoints) > 0 {
- // http://tools.ietf.org/html/rfc4492#section-5.5.2
- z[0] = byte(extensionSupportedPoints >> 8)
- z[1] = byte(extensionSupportedPoints)
- l := 1 + len(m.supportedPoints)
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- l--
- z[4] = byte(l)
- z = z[5:]
- for _, pointFormat := range m.supportedPoints {
- z[0] = pointFormat
- z = z[1:]
- }
- }
- if m.ticketSupported {
- // http://tools.ietf.org/html/rfc5077#section-3.2
- z[0] = byte(extensionSessionTicket >> 8)
- z[1] = byte(extensionSessionTicket)
- l := len(m.sessionTicket)
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- z = z[4:]
- copy(z, m.sessionTicket)
- z = z[len(m.sessionTicket):]
- }
-
- if len(m.supportedSignatureAlgorithms) > 0 {
- z = marshalExtensionSignatureAlgorithms(extensionSignatureAlgorithms, z, m.supportedSignatureAlgorithms)
- }
- if m.getSignatureAlgorithmsCert() != nil {
- // Ensure only one list of algorithms is sent if supported_algorithms and supported_algorithms_cert are the same
- z = marshalExtensionSignatureAlgorithms(extensionSignatureAlgorithmsCert, z, m.getSignatureAlgorithmsCert())
- }
-
- if m.secureRenegotiationSupported {
- z[0] = byte(extensionRenegotiationInfo >> 8)
- z[1] = byte(extensionRenegotiationInfo & 0xff)
- z[2] = 0
- z[3] = byte(len(m.secureRenegotiation) + 1)
- z[4] = byte(len(m.secureRenegotiation))
- z = z[5:]
- copy(z, m.secureRenegotiation)
- z = z[len(m.secureRenegotiation):]
- }
- if len(m.alpnProtocols) > 0 {
- z[0] = byte(extensionALPN >> 8)
- z[1] = byte(extensionALPN & 0xff)
- lengths := z[2:]
- z = z[6:]
-
- stringsLength := 0
- for _, s := range m.alpnProtocols {
- l := len(s)
- z[0] = byte(l)
- copy(z[1:], s)
- z = z[1+l:]
- stringsLength += 1 + l
- }
-
- lengths[2] = byte(stringsLength >> 8)
- lengths[3] = byte(stringsLength)
- stringsLength += 2
- lengths[0] = byte(stringsLength >> 8)
- lengths[1] = byte(stringsLength)
- }
- if m.scts {
- // https://tools.ietf.org/html/rfc6962#section-3.3.1
- z[0] = byte(extensionSCT >> 8)
- z[1] = byte(extensionSCT)
- // zero uint16 for the zero-length extension_data
- z = z[4:]
- }
- if len(m.keyShares) > 0 {
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.5
- z[0] = byte(extensionKeyShare >> 8)
- z[1] = byte(extensionKeyShare)
- lengths := z[2:]
- z = z[6:]
-
- totalLength := 0
- for _, ks := range m.keyShares {
- z[0] = byte(ks.group >> 8)
- z[1] = byte(ks.group)
- z[2] = byte(len(ks.data) >> 8)
- z[3] = byte(len(ks.data))
- copy(z[4:], ks.data)
- z = z[4+len(ks.data):]
- totalLength += 4 + len(ks.data)
- }
-
- lengths[2] = byte(totalLength >> 8)
- lengths[3] = byte(totalLength)
- totalLength += 2
- lengths[0] = byte(totalLength >> 8)
- lengths[1] = byte(totalLength)
- }
- if len(m.supportedVersions) > 0 {
- z[0] = byte(extensionSupportedVersions >> 8)
- z[1] = byte(extensionSupportedVersions)
- l := 1 + 2*len(m.supportedVersions)
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- l -= 1
- z[4] = byte(l)
- z = z[5:]
- for _, v := range m.supportedVersions {
- z[0] = byte(v >> 8)
- z[1] = byte(v)
- z = z[2:]
- }
- }
- if m.earlyData {
- z[0] = byte(extensionEarlyData >> 8)
- z[1] = byte(extensionEarlyData)
- z = z[4:]
- }
-
- m.raw = x
-
- return x
- }
-
- func (m *clientHelloMsg) unmarshal(data []byte) alert {
- if len(data) < 42 {
- return alertDecodeError
- }
- m.raw = data
- m.vers = uint16(data[4])<<8 | uint16(data[5])
- m.random = data[6:38]
- sessionIdLen := int(data[38])
- if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
- return alertDecodeError
- }
- m.sessionId = data[39 : 39+sessionIdLen]
- data = data[39+sessionIdLen:]
- bindersOffset := 39 + sessionIdLen
- if len(data) < 2 {
- return alertDecodeError
- }
- // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
- // they are uint16s, the number must be even.
- cipherSuiteLen := int(data[0])<<8 | int(data[1])
- if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
- return alertDecodeError
- }
- numCipherSuites := cipherSuiteLen / 2
- m.cipherSuites = make([]uint16, numCipherSuites)
- for i := 0; i < numCipherSuites; i++ {
- m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
- if m.cipherSuites[i] == scsvRenegotiation {
- m.secureRenegotiationSupported = true
- }
- }
- data = data[2+cipherSuiteLen:]
- bindersOffset += 2 + cipherSuiteLen
- if len(data) < 1 {
- return alertDecodeError
- }
- compressionMethodsLen := int(data[0])
- if len(data) < 1+compressionMethodsLen {
- return alertDecodeError
- }
- m.compressionMethods = data[1 : 1+compressionMethodsLen]
-
- data = data[1+compressionMethodsLen:]
- bindersOffset += 1 + compressionMethodsLen
-
- m.nextProtoNeg = false
- m.serverName = ""
- m.ocspStapling = false
- m.ticketSupported = false
- m.sessionTicket = nil
- m.supportedSignatureAlgorithms = nil
- m.alpnProtocols = nil
- m.scts = false
- m.keyShares = nil
- m.supportedVersions = nil
- m.psks = nil
- m.pskKeyExchangeModes = nil
- m.earlyData = false
-
- if len(data) == 0 {
- // ClientHello is optionally followed by extension data
- return alertSuccess
- }
- if len(data) < 2 {
- return alertDecodeError
- }
-
- extensionsLength := int(data[0])<<8 | int(data[1])
- data = data[2:]
- bindersOffset += 2
- if extensionsLength != len(data) {
- return alertDecodeError
- }
-
- for len(data) != 0 {
- if len(data) < 4 {
- return alertDecodeError
- }
- extension := uint16(data[0])<<8 | uint16(data[1])
- length := int(data[2])<<8 | int(data[3])
- data = data[4:]
- bindersOffset += 4
- if len(data) < length {
- return alertDecodeError
- }
-
- switch extension {
- case extensionServerName:
- d := data[:length]
- if len(d) < 2 {
- return alertDecodeError
- }
- namesLen := int(d[0])<<8 | int(d[1])
- d = d[2:]
- if len(d) != namesLen {
- return alertDecodeError
- }
- for len(d) > 0 {
- if len(d) < 3 {
- return alertDecodeError
- }
- nameType := d[0]
- nameLen := int(d[1])<<8 | int(d[2])
- d = d[3:]
- if len(d) < nameLen {
- return alertDecodeError
- }
- if nameType == 0 {
- m.serverName = string(d[:nameLen])
- // An SNI value may not include a
- // trailing dot. See
- // https://tools.ietf.org/html/rfc6066#section-3.
- if strings.HasSuffix(m.serverName, ".") {
- // TODO use alertDecodeError?
- return alertUnexpectedMessage
- }
- break
- }
- d = d[nameLen:]
- }
- case extensionNextProtoNeg:
- if length > 0 {
- return alertDecodeError
- }
- m.nextProtoNeg = true
- case extensionStatusRequest:
- m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
- case extensionSupportedCurves:
- // http://tools.ietf.org/html/rfc4492#section-5.5.1
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.4
- if length < 2 {
- return alertDecodeError
- }
- l := int(data[0])<<8 | int(data[1])
- if l%2 == 1 || length != l+2 {
- return alertDecodeError
- }
- numCurves := l / 2
- m.supportedCurves = make([]CurveID, numCurves)
- d := data[2:]
- for i := 0; i < numCurves; i++ {
- m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
- d = d[2:]
- }
- case extensionSupportedPoints:
- // http://tools.ietf.org/html/rfc4492#section-5.5.2
- if length < 1 {
- return alertDecodeError
- }
- l := int(data[0])
- if length != l+1 {
- return alertDecodeError
- }
- m.supportedPoints = make([]uint8, l)
- copy(m.supportedPoints, data[1:])
- case extensionSessionTicket:
- // http://tools.ietf.org/html/rfc5077#section-3.2
- m.ticketSupported = true
- m.sessionTicket = data[:length]
- case extensionSignatureAlgorithms:
- // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.3
- if length < 2 || length&1 != 0 {
- return alertDecodeError
- }
- l := int(data[0])<<8 | int(data[1])
- if l != length-2 {
- return alertDecodeError
- }
- n := l / 2
- d := data[2:]
- m.supportedSignatureAlgorithms = make([]SignatureScheme, n)
- for i := range m.supportedSignatureAlgorithms {
- m.supportedSignatureAlgorithms[i] = SignatureScheme(d[0])<<8 | SignatureScheme(d[1])
- d = d[2:]
- }
- case extensionRenegotiationInfo:
- if length == 0 {
- return alertDecodeError
- }
- d := data[:length]
- l := int(d[0])
- d = d[1:]
- if l != len(d) {
- return alertDecodeError
- }
-
- m.secureRenegotiation = d
- m.secureRenegotiationSupported = true
- case extensionALPN:
- if length < 2 {
- return alertDecodeError
- }
- l := int(data[0])<<8 | int(data[1])
- if l != length-2 {
- return alertDecodeError
- }
- d := data[2:length]
- for len(d) != 0 {
- stringLen := int(d[0])
- d = d[1:]
- if stringLen == 0 || stringLen > len(d) {
- return alertDecodeError
- }
- m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
- d = d[stringLen:]
- }
- case extensionSCT:
- m.scts = true
- if length != 0 {
- return alertDecodeError
- }
- case extensionKeyShare:
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.5
- if length < 2 {
- return alertDecodeError
- }
- l := int(data[0])<<8 | int(data[1])
- if l != length-2 {
- return alertDecodeError
- }
- d := data[2:length]
- for len(d) != 0 {
- if len(d) < 4 {
- return alertDecodeError
- }
- dataLen := int(d[2])<<8 | int(d[3])
- if dataLen == 0 || 4+dataLen > len(d) {
- return alertDecodeError
- }
- m.keyShares = append(m.keyShares, keyShare{
- group: CurveID(d[0])<<8 | CurveID(d[1]),
- data: d[4 : 4+dataLen],
- })
- d = d[4+dataLen:]
- }
- case extensionSupportedVersions:
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.1
- if length < 1 {
- return alertDecodeError
- }
- l := int(data[0])
- if l%2 == 1 || length != l+1 {
- return alertDecodeError
- }
- n := l / 2
- d := data[1:]
- for i := 0; i < n; i++ {
- v := uint16(d[0])<<8 + uint16(d[1])
- m.supportedVersions = append(m.supportedVersions, v)
- d = d[2:]
- }
- case extensionPreSharedKey:
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.6
- if length < 2 {
- return alertDecodeError
- }
- // Ensure this extension is the last one in the Client Hello
- if len(data) != length {
- return alertIllegalParameter
- }
- li := int(data[0])<<8 | int(data[1])
- if 2+li+2 > length {
- return alertDecodeError
- }
- d := data[2 : 2+li]
- bindersOffset += 2 + li
- for len(d) > 0 {
- if len(d) < 6 {
- return alertDecodeError
- }
- l := int(d[0])<<8 | int(d[1])
- if len(d) < 2+l+4 {
- return alertDecodeError
- }
- m.psks = append(m.psks, psk{
- identity: d[2 : 2+l],
- obfTicketAge: uint32(d[l+2])<<24 | uint32(d[l+3])<<16 |
- uint32(d[l+4])<<8 | uint32(d[l+5]),
- })
- d = d[2+l+4:]
- }
- lb := int(data[li+2])<<8 | int(data[li+3])
- d = data[2+li+2:]
- if lb != len(d) || lb == 0 {
- return alertDecodeError
- }
- i := 0
- for len(d) > 0 {
- if i >= len(m.psks) {
- return alertIllegalParameter
- }
- if len(d) < 1 {
- return alertDecodeError
- }
- l := int(d[0])
- if l > len(d)-1 {
- return alertDecodeError
- }
- if i >= len(m.psks) {
- return alertIllegalParameter
- }
- m.psks[i].binder = d[1 : 1+l]
- d = d[1+l:]
- i++
- }
- if i != len(m.psks) {
- return alertIllegalParameter
- }
- m.rawTruncated = m.raw[:bindersOffset]
- case extensionPSKKeyExchangeModes:
- if length < 2 {
- return alertDecodeError
- }
- l := int(data[0])
- if length != l+1 {
- return alertDecodeError
- }
- m.pskKeyExchangeModes = data[1:length]
- case extensionEarlyData:
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.8
- m.earlyData = true
- }
- data = data[length:]
- bindersOffset += length
- }
-
- return alertSuccess
- }
-
- func (m *clientHelloMsg) getSignatureAlgorithmsCert() []SignatureScheme {
- return signAlgosCertList(m.supportedSignatureAlgorithms, m.supportedSignatureAlgorithmsCert)
- }
-
- type serverHelloMsg struct {
- raw []byte
- vers uint16
- random []byte
- sessionId []byte
- cipherSuite uint16
- compressionMethod uint8
- nextProtoNeg bool
- nextProtos []string
- ocspStapling bool
- scts [][]byte
- ticketSupported bool
- secureRenegotiation []byte
- secureRenegotiationSupported bool
- alpnProtocol string
-
- // TLS 1.3
- keyShare keyShare
- psk bool
- pskIdentity uint16
- }
-
- func (m *serverHelloMsg) equal(i interface{}) bool {
- m1, ok := i.(*serverHelloMsg)
- if !ok {
- return false
- }
-
- if len(m.scts) != len(m1.scts) {
- return false
- }
- for i, sct := range m.scts {
- if !bytes.Equal(sct, m1.scts[i]) {
- return false
- }
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.vers == m1.vers &&
- bytes.Equal(m.random, m1.random) &&
- bytes.Equal(m.sessionId, m1.sessionId) &&
- m.cipherSuite == m1.cipherSuite &&
- m.compressionMethod == m1.compressionMethod &&
- m.nextProtoNeg == m1.nextProtoNeg &&
- eqStrings(m.nextProtos, m1.nextProtos) &&
- m.ocspStapling == m1.ocspStapling &&
- m.ticketSupported == m1.ticketSupported &&
- m.secureRenegotiationSupported == m1.secureRenegotiationSupported &&
- bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
- m.alpnProtocol == m1.alpnProtocol &&
- m.keyShare.group == m1.keyShare.group &&
- bytes.Equal(m.keyShare.data, m1.keyShare.data) &&
- m.psk == m1.psk &&
- m.pskIdentity == m1.pskIdentity
- }
-
- func (m *serverHelloMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
-
- oldTLS13Draft := m.vers >= VersionTLS13Draft18 && m.vers <= VersionTLS13Draft21
- length := 38 + len(m.sessionId)
- if oldTLS13Draft {
- // no compression method, no session ID.
- length = 36
- }
- numExtensions := 0
- extensionsLength := 0
-
- nextProtoLen := 0
- if m.nextProtoNeg {
- numExtensions++
- for _, v := range m.nextProtos {
- nextProtoLen += len(v)
- }
- nextProtoLen += len(m.nextProtos)
- extensionsLength += nextProtoLen
- }
- if m.ocspStapling {
- numExtensions++
- }
- if m.ticketSupported {
- numExtensions++
- }
- if m.secureRenegotiationSupported {
- extensionsLength += 1 + len(m.secureRenegotiation)
- numExtensions++
- }
- if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
- if alpnLen >= 256 {
- panic("invalid ALPN protocol")
- }
- extensionsLength += 2 + 1 + alpnLen
- numExtensions++
- }
- sctLen := 0
- if len(m.scts) > 0 {
- for _, sct := range m.scts {
- sctLen += len(sct) + 2
- }
- extensionsLength += 2 + sctLen
- numExtensions++
- }
- if m.keyShare.group != 0 {
- extensionsLength += 4 + len(m.keyShare.data)
- numExtensions++
- }
- if m.psk {
- extensionsLength += 2
- numExtensions++
- }
- // supported_versions extension
- if m.vers >= VersionTLS13 {
- extensionsLength += 2
- numExtensions++
- }
-
- if numExtensions > 0 {
- extensionsLength += 4 * numExtensions
- length += 2 + extensionsLength
- }
-
- x := make([]byte, 4+length)
- x[0] = typeServerHello
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- if m.vers >= VersionTLS13 {
- x[4] = 3
- x[5] = 3
- } else {
- x[4] = uint8(m.vers >> 8)
- x[5] = uint8(m.vers)
- }
- copy(x[6:38], m.random)
- z := x[38:]
- if !oldTLS13Draft {
- x[38] = uint8(len(m.sessionId))
- copy(x[39:39+len(m.sessionId)], m.sessionId)
- z = x[39+len(m.sessionId):]
- }
- z[0] = uint8(m.cipherSuite >> 8)
- z[1] = uint8(m.cipherSuite)
- if oldTLS13Draft {
- // no compression method in older TLS 1.3 drafts.
- z = z[2:]
- } else {
- z[2] = m.compressionMethod
- z = z[3:]
- }
-
- if numExtensions > 0 {
- z[0] = byte(extensionsLength >> 8)
- z[1] = byte(extensionsLength)
- z = z[2:]
- }
- if m.vers >= VersionTLS13 {
- z[0] = byte(extensionSupportedVersions >> 8)
- z[1] = byte(extensionSupportedVersions)
- z[3] = 2
- z[4] = uint8(m.vers >> 8)
- z[5] = uint8(m.vers)
- z = z[6:]
- }
- if m.nextProtoNeg {
- z[0] = byte(extensionNextProtoNeg >> 8)
- z[1] = byte(extensionNextProtoNeg & 0xff)
- z[2] = byte(nextProtoLen >> 8)
- z[3] = byte(nextProtoLen)
- z = z[4:]
-
- for _, v := range m.nextProtos {
- l := len(v)
- if l > 255 {
- l = 255
- }
- z[0] = byte(l)
- copy(z[1:], []byte(v[0:l]))
- z = z[1+l:]
- }
- }
- if m.ocspStapling {
- z[0] = byte(extensionStatusRequest >> 8)
- z[1] = byte(extensionStatusRequest)
- z = z[4:]
- }
- if m.ticketSupported {
- z[0] = byte(extensionSessionTicket >> 8)
- z[1] = byte(extensionSessionTicket)
- z = z[4:]
- }
- if m.secureRenegotiationSupported {
- z[0] = byte(extensionRenegotiationInfo >> 8)
- z[1] = byte(extensionRenegotiationInfo & 0xff)
- z[2] = 0
- z[3] = byte(len(m.secureRenegotiation) + 1)
- z[4] = byte(len(m.secureRenegotiation))
- z = z[5:]
- copy(z, m.secureRenegotiation)
- z = z[len(m.secureRenegotiation):]
- }
- if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
- z[0] = byte(extensionALPN >> 8)
- z[1] = byte(extensionALPN & 0xff)
- l := 2 + 1 + alpnLen
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- l -= 2
- z[4] = byte(l >> 8)
- z[5] = byte(l)
- l -= 1
- z[6] = byte(l)
- copy(z[7:], []byte(m.alpnProtocol))
- z = z[7+alpnLen:]
- }
- if sctLen > 0 {
- z[0] = byte(extensionSCT >> 8)
- z[1] = byte(extensionSCT)
- l := sctLen + 2
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- z[4] = byte(sctLen >> 8)
- z[5] = byte(sctLen)
-
- z = z[6:]
- for _, sct := range m.scts {
- z[0] = byte(len(sct) >> 8)
- z[1] = byte(len(sct))
- copy(z[2:], sct)
- z = z[len(sct)+2:]
- }
- }
-
- if m.keyShare.group != 0 {
- z[0] = uint8(extensionKeyShare >> 8)
- z[1] = uint8(extensionKeyShare)
- l := 4 + len(m.keyShare.data)
- z[2] = uint8(l >> 8)
- z[3] = uint8(l)
- z[4] = uint8(m.keyShare.group >> 8)
- z[5] = uint8(m.keyShare.group)
- l -= 4
- z[6] = uint8(l >> 8)
- z[7] = uint8(l)
- copy(z[8:], m.keyShare.data)
- z = z[8+l:]
- }
-
- if m.psk {
- z[0] = byte(extensionPreSharedKey >> 8)
- z[1] = byte(extensionPreSharedKey)
- z[3] = 2
- z[4] = byte(m.pskIdentity >> 8)
- z[5] = byte(m.pskIdentity)
- z = z[6:]
- }
-
- m.raw = x
-
- return x
- }
-
- func (m *serverHelloMsg) unmarshal(data []byte) alert {
- if len(data) < 42 {
- return alertDecodeError
- }
- m.raw = data
- m.vers = uint16(data[4])<<8 | uint16(data[5])
- oldTLS13Draft := m.vers >= VersionTLS13Draft18 && m.vers <= VersionTLS13Draft21
- m.random = data[6:38]
- if !oldTLS13Draft {
- sessionIdLen := int(data[38])
- if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
- return alertDecodeError
- }
- m.sessionId = data[39 : 39+sessionIdLen]
- data = data[39+sessionIdLen:]
- } else {
- data = data[38:]
- }
- if len(data) < 3 {
- return alertDecodeError
- }
- m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
- if oldTLS13Draft {
- // no compression method in older TLS 1.3 drafts.
- data = data[2:]
- } else {
- m.compressionMethod = data[2]
- data = data[3:]
- }
-
- m.nextProtoNeg = false
- m.nextProtos = nil
- m.ocspStapling = false
- m.scts = nil
- m.ticketSupported = false
- m.alpnProtocol = ""
- m.keyShare.group = 0
- m.keyShare.data = nil
- m.psk = false
- m.pskIdentity = 0
-
- if len(data) == 0 {
- // ServerHello is optionally followed by extension data
- return alertSuccess
- }
- if len(data) < 2 {
- return alertDecodeError
- }
-
- extensionsLength := int(data[0])<<8 | int(data[1])
- data = data[2:]
- if len(data) != extensionsLength {
- return alertDecodeError
- }
-
- svData := findExtension(data, extensionSupportedVersions)
- if svData != nil {
- if len(svData) != 2 {
- return alertDecodeError
- }
- if m.vers != VersionTLS12 {
- return alertDecodeError
- }
- m.vers = uint16(svData[0])<<8 | uint16(svData[1])
- }
-
- for len(data) != 0 {
- if len(data) < 4 {
- return alertDecodeError
- }
- extension := uint16(data[0])<<8 | uint16(data[1])
- length := int(data[2])<<8 | int(data[3])
- data = data[4:]
- if len(data) < length {
- return alertDecodeError
- }
-
- switch extension {
- case extensionNextProtoNeg:
- m.nextProtoNeg = true
- d := data[:length]
- for len(d) > 0 {
- l := int(d[0])
- d = d[1:]
- if l == 0 || l > len(d) {
- return alertDecodeError
- }
- m.nextProtos = append(m.nextProtos, string(d[:l]))
- d = d[l:]
- }
- case extensionStatusRequest:
- if length > 0 {
- return alertDecodeError
- }
- m.ocspStapling = true
- case extensionSessionTicket:
- if length > 0 {
- return alertDecodeError
- }
- m.ticketSupported = true
- case extensionRenegotiationInfo:
- if length == 0 {
- return alertDecodeError
- }
- d := data[:length]
- l := int(d[0])
- d = d[1:]
- if l != len(d) {
- return alertDecodeError
- }
-
- m.secureRenegotiation = d
- m.secureRenegotiationSupported = true
- case extensionALPN:
- d := data[:length]
- if len(d) < 3 {
- return alertDecodeError
- }
- l := int(d[0])<<8 | int(d[1])
- if l != len(d)-2 {
- return alertDecodeError
- }
- d = d[2:]
- l = int(d[0])
- if l != len(d)-1 {
- return alertDecodeError
- }
- d = d[1:]
- if len(d) == 0 {
- // ALPN protocols must not be empty.
- return alertDecodeError
- }
- m.alpnProtocol = string(d)
- case extensionSCT:
- d := data[:length]
-
- if len(d) < 2 {
- return alertDecodeError
- }
- l := int(d[0])<<8 | int(d[1])
- d = d[2:]
- if len(d) != l || l == 0 {
- return alertDecodeError
- }
-
- m.scts = make([][]byte, 0, 3)
- for len(d) != 0 {
- if len(d) < 2 {
- return alertDecodeError
- }
- sctLen := int(d[0])<<8 | int(d[1])
- d = d[2:]
- if sctLen == 0 || len(d) < sctLen {
- return alertDecodeError
- }
- m.scts = append(m.scts, d[:sctLen])
- d = d[sctLen:]
- }
- case extensionKeyShare:
- d := data[:length]
-
- if len(d) < 4 {
- return alertDecodeError
- }
- m.keyShare.group = CurveID(d[0])<<8 | CurveID(d[1])
- l := int(d[2])<<8 | int(d[3])
- d = d[4:]
- if len(d) != l {
- return alertDecodeError
- }
- m.keyShare.data = d[:l]
- case extensionPreSharedKey:
- if length != 2 {
- return alertDecodeError
- }
- m.psk = true
- m.pskIdentity = uint16(data[0])<<8 | uint16(data[1])
- }
- data = data[length:]
- }
-
- return alertSuccess
- }
-
- type encryptedExtensionsMsg struct {
- raw []byte
- alpnProtocol string
- earlyData bool
- }
-
- func (m *encryptedExtensionsMsg) equal(i interface{}) bool {
- m1, ok := i.(*encryptedExtensionsMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.alpnProtocol == m1.alpnProtocol &&
- m.earlyData == m1.earlyData
- }
-
- func (m *encryptedExtensionsMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
-
- length := 2
-
- if m.earlyData {
- length += 4
- }
- alpnLen := len(m.alpnProtocol)
- if alpnLen > 0 {
- if alpnLen >= 256 {
- panic("invalid ALPN protocol")
- }
- length += 2 + 2 + 2 + 1 + alpnLen
- }
-
- x := make([]byte, 4+length)
- x[0] = typeEncryptedExtensions
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- length -= 2
- x[4] = uint8(length >> 8)
- x[5] = uint8(length)
-
- z := x[6:]
- if alpnLen > 0 {
- z[0] = byte(extensionALPN >> 8)
- z[1] = byte(extensionALPN)
- l := 2 + 1 + alpnLen
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- l -= 2
- z[4] = byte(l >> 8)
- z[5] = byte(l)
- l -= 1
- z[6] = byte(l)
- copy(z[7:], []byte(m.alpnProtocol))
- z = z[7+alpnLen:]
- }
-
- if m.earlyData {
- z[0] = byte(extensionEarlyData >> 8)
- z[1] = byte(extensionEarlyData)
- z = z[4:]
- }
-
- m.raw = x
- return x
- }
-
- func (m *encryptedExtensionsMsg) unmarshal(data []byte) alert {
- if len(data) < 6 {
- return alertDecodeError
- }
- m.raw = data
-
- m.alpnProtocol = ""
- m.earlyData = false
-
- extensionsLength := int(data[4])<<8 | int(data[5])
- data = data[6:]
- if len(data) != extensionsLength {
- return alertDecodeError
- }
-
- for len(data) != 0 {
- if len(data) < 4 {
- return alertDecodeError
- }
- extension := uint16(data[0])<<8 | uint16(data[1])
- length := int(data[2])<<8 | int(data[3])
- data = data[4:]
- if len(data) < length {
- return alertDecodeError
- }
-
- switch extension {
- case extensionALPN:
- d := data[:length]
- if len(d) < 3 {
- return alertDecodeError
- }
- l := int(d[0])<<8 | int(d[1])
- if l != len(d)-2 {
- return alertDecodeError
- }
- d = d[2:]
- l = int(d[0])
- if l != len(d)-1 {
- return alertDecodeError
- }
- d = d[1:]
- if len(d) == 0 {
- // ALPN protocols must not be empty.
- return alertDecodeError
- }
- m.alpnProtocol = string(d)
- case extensionEarlyData:
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.8
- m.earlyData = true
- }
-
- data = data[length:]
- }
-
- return alertSuccess
- }
-
- type certificateMsg struct {
- raw []byte
- certificates [][]byte
- }
-
- func (m *certificateMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- eqByteSlices(m.certificates, m1.certificates)
- }
-
- 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) alert {
- if len(data) < 7 {
- return alertDecodeError
- }
-
- m.raw = data
- certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
- if uint32(len(data)) != certsLen+7 {
- return alertDecodeError
- }
-
- numCerts := 0
- d := data[7:]
- for certsLen > 0 {
- if len(d) < 4 {
- return alertDecodeError
- }
- certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- if uint32(len(d)) < 3+certLen {
- return alertDecodeError
- }
- 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 alertSuccess
- }
-
- type certificateEntry struct {
- data []byte
- ocspStaple []byte
- sctList [][]byte
- }
-
- type certificateMsg13 struct {
- raw []byte
- requestContext []byte
- certificates []certificateEntry
- }
-
- func (m *certificateMsg13) equal(i interface{}) bool {
- m1, ok := i.(*certificateMsg13)
- if !ok {
- return false
- }
-
- if len(m.certificates) != len(m1.certificates) {
- return false
- }
- for i, _ := range m.certificates {
- ok := bytes.Equal(m.certificates[i].data, m1.certificates[i].data)
- ok = ok && bytes.Equal(m.certificates[i].ocspStaple, m1.certificates[i].ocspStaple)
- ok = ok && eqByteSlices(m.certificates[i].sctList, m1.certificates[i].sctList)
- if !ok {
- return false
- }
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.requestContext, m1.requestContext)
- }
-
- func (m *certificateMsg13) marshal() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
-
- var i int
- for _, cert := range m.certificates {
- i += len(cert.data)
- if len(cert.ocspStaple) != 0 {
- i += 8 + len(cert.ocspStaple)
- }
- if len(cert.sctList) != 0 {
- i += 6
- for _, sct := range cert.sctList {
- i += 2 + len(sct)
- }
- }
- }
-
- length := 3 + 3*len(m.certificates) + i
- length += 2 * len(m.certificates) // extensions
- length += 1 + len(m.requestContext)
- x = make([]byte, 4+length)
- x[0] = typeCertificate
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
-
- z := x[4:]
-
- z[0] = byte(len(m.requestContext))
- copy(z[1:], m.requestContext)
- z = z[1+len(m.requestContext):]
-
- certificateOctets := len(z) - 3
- z[0] = uint8(certificateOctets >> 16)
- z[1] = uint8(certificateOctets >> 8)
- z[2] = uint8(certificateOctets)
-
- z = z[3:]
- for _, cert := range m.certificates {
- z[0] = uint8(len(cert.data) >> 16)
- z[1] = uint8(len(cert.data) >> 8)
- z[2] = uint8(len(cert.data))
- copy(z[3:], cert.data)
- z = z[3+len(cert.data):]
-
- extLenPos := z[:2]
- z = z[2:]
-
- extensionLen := 0
- if len(cert.ocspStaple) != 0 {
- stapleLen := 4 + len(cert.ocspStaple)
- z[0] = uint8(extensionStatusRequest >> 8)
- z[1] = uint8(extensionStatusRequest)
- z[2] = uint8(stapleLen >> 8)
- z[3] = uint8(stapleLen)
-
- stapleLen -= 4
- z[4] = statusTypeOCSP
- z[5] = uint8(stapleLen >> 16)
- z[6] = uint8(stapleLen >> 8)
- z[7] = uint8(stapleLen)
- copy(z[8:], cert.ocspStaple)
- z = z[8+stapleLen:]
-
- extensionLen += 8 + stapleLen
- }
- if len(cert.sctList) != 0 {
- z[0] = uint8(extensionSCT >> 8)
- z[1] = uint8(extensionSCT)
- sctLenPos := z[2:6]
- z = z[6:]
- extensionLen += 6
-
- sctLen := 2
- for _, sct := range cert.sctList {
- z[0] = uint8(len(sct) >> 8)
- z[1] = uint8(len(sct))
- copy(z[2:], sct)
- z = z[2+len(sct):]
-
- extensionLen += 2 + len(sct)
- sctLen += 2 + len(sct)
- }
- sctLenPos[0] = uint8(sctLen >> 8)
- sctLenPos[1] = uint8(sctLen)
- sctLen -= 2
- sctLenPos[2] = uint8(sctLen >> 8)
- sctLenPos[3] = uint8(sctLen)
- }
- extLenPos[0] = uint8(extensionLen >> 8)
- extLenPos[1] = uint8(extensionLen)
- }
-
- m.raw = x
- return
- }
-
- func (m *certificateMsg13) unmarshal(data []byte) alert {
- if len(data) < 5 {
- return alertDecodeError
- }
-
- m.raw = data
-
- ctxLen := data[4]
- if len(data) < int(ctxLen)+5+3 {
- return alertDecodeError
- }
- m.requestContext = data[5 : 5+ctxLen]
-
- d := data[5+ctxLen:]
- certsLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- if uint32(len(d)) != certsLen+3 {
- return alertDecodeError
- }
-
- numCerts := 0
- d = d[3:]
- for certsLen > 0 {
- if len(d) < 4 {
- return alertDecodeError
- }
- certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- if uint32(len(d)) < 3+certLen {
- return alertDecodeError
- }
- d = d[3+certLen:]
-
- if len(d) < 2 {
- return alertDecodeError
- }
- extLen := uint16(d[0])<<8 | uint16(d[1])
- if uint16(len(d)) < 2+extLen {
- return alertDecodeError
- }
- d = d[2+extLen:]
-
- certsLen -= 3 + certLen + 2 + uint32(extLen)
- numCerts++
- }
-
- m.certificates = make([]certificateEntry, numCerts)
- d = data[8+ctxLen:]
- for i := 0; i < numCerts; i++ {
- certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- m.certificates[i].data = d[3 : 3+certLen]
- d = d[3+certLen:]
-
- extLen := uint16(d[0])<<8 | uint16(d[1])
- d = d[2:]
- for extLen > 0 {
- if extLen < 4 {
- return alertDecodeError
- }
- typ := uint16(d[0])<<8 | uint16(d[1])
- bodyLen := uint16(d[2])<<8 | uint16(d[3])
- if extLen < 4+bodyLen {
- return alertDecodeError
- }
- body := d[4 : 4+bodyLen]
- d = d[4+bodyLen:]
- extLen -= 4 + bodyLen
-
- switch typ {
- case extensionStatusRequest:
- if len(body) < 4 || body[0] != 0x01 {
- return alertDecodeError
- }
- ocspLen := int(body[1])<<16 | int(body[2])<<8 | int(body[3])
- if len(body) != 4+ocspLen {
- return alertDecodeError
- }
- m.certificates[i].ocspStaple = body[4:]
-
- case extensionSCT:
- if len(body) < 2 {
- return alertDecodeError
- }
- listLen := int(body[0])<<8 | int(body[1])
- body = body[2:]
- if len(body) != listLen {
- return alertDecodeError
- }
- for len(body) > 0 {
- if len(body) < 2 {
- return alertDecodeError
- }
- sctLen := int(body[0])<<8 | int(body[1])
- if len(body) < 2+sctLen {
- return alertDecodeError
- }
- m.certificates[i].sctList = append(m.certificates[i].sctList, body[2:2+sctLen])
- body = body[2+sctLen:]
- }
- }
- }
- }
-
- return alertSuccess
- }
-
- type serverKeyExchangeMsg struct {
- raw []byte
- key []byte
- }
-
- func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
- m1, ok := i.(*serverKeyExchangeMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.key, m1.key)
- }
-
- 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) alert {
- m.raw = data
- if len(data) < 4 {
- return alertDecodeError
- }
- m.key = data[4:]
- return alertSuccess
- }
-
- type certificateStatusMsg struct {
- raw []byte
- statusType uint8
- response []byte
- }
-
- func (m *certificateStatusMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateStatusMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.statusType == m1.statusType &&
- bytes.Equal(m.response, m1.response)
- }
-
- func (m *certificateStatusMsg) marshal() []byte {
- if m.raw != nil {
- return m.raw
- }
-
- var x []byte
- if m.statusType == statusTypeOCSP {
- x = make([]byte, 4+4+len(m.response))
- x[0] = typeCertificateStatus
- l := len(m.response) + 4
- x[1] = byte(l >> 16)
- x[2] = byte(l >> 8)
- x[3] = byte(l)
- x[4] = statusTypeOCSP
-
- l -= 4
- x[5] = byte(l >> 16)
- x[6] = byte(l >> 8)
- x[7] = byte(l)
- copy(x[8:], m.response)
- } else {
- x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
- }
-
- m.raw = x
- return x
- }
-
- func (m *certificateStatusMsg) unmarshal(data []byte) alert {
- m.raw = data
- if len(data) < 5 {
- return alertDecodeError
- }
- m.statusType = data[4]
-
- m.response = nil
- if m.statusType == statusTypeOCSP {
- if len(data) < 8 {
- return alertDecodeError
- }
- respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
- if uint32(len(data)) != 4+4+respLen {
- return alertDecodeError
- }
- m.response = data[8:]
- }
- return alertSuccess
- }
-
- type serverHelloDoneMsg struct{}
-
- func (m *serverHelloDoneMsg) equal(i interface{}) bool {
- _, ok := i.(*serverHelloDoneMsg)
- return ok
- }
-
- func (m *serverHelloDoneMsg) marshal() []byte {
- x := make([]byte, 4)
- x[0] = typeServerHelloDone
- return x
- }
-
- func (m *serverHelloDoneMsg) unmarshal(data []byte) alert {
- if len(data) != 4 {
- return alertDecodeError
- }
- return alertSuccess
- }
-
- type clientKeyExchangeMsg struct {
- raw []byte
- ciphertext []byte
- }
-
- func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
- m1, ok := i.(*clientKeyExchangeMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.ciphertext, m1.ciphertext)
- }
-
- 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) alert {
- m.raw = data
- if len(data) < 4 {
- return alertDecodeError
- }
- l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
- if l != len(data)-4 {
- return alertDecodeError
- }
- m.ciphertext = data[4:]
- return alertSuccess
- }
-
- type finishedMsg struct {
- raw []byte
- verifyData []byte
- }
-
- func (m *finishedMsg) equal(i interface{}) bool {
- m1, ok := i.(*finishedMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.verifyData, m1.verifyData)
- }
-
- func (m *finishedMsg) marshal() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
-
- x = make([]byte, 4+len(m.verifyData))
- x[0] = typeFinished
- x[3] = byte(len(m.verifyData))
- copy(x[4:], m.verifyData)
- m.raw = x
- return
- }
-
- func (m *finishedMsg) unmarshal(data []byte) alert {
- m.raw = data
- if len(data) < 4 {
- return alertDecodeError
- }
- m.verifyData = data[4:]
- return alertSuccess
- }
-
- type nextProtoMsg struct {
- raw []byte
- proto string
- }
-
- func (m *nextProtoMsg) equal(i interface{}) bool {
- m1, ok := i.(*nextProtoMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.proto == m1.proto
- }
-
- 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) alert {
- m.raw = data
-
- if len(data) < 5 {
- return alertDecodeError
- }
- data = data[4:]
- protoLen := int(data[0])
- data = data[1:]
- if len(data) < protoLen {
- return alertDecodeError
- }
- m.proto = string(data[0:protoLen])
- data = data[protoLen:]
-
- if len(data) < 1 {
- return alertDecodeError
- }
- paddingLen := int(data[0])
- data = data[1:]
- if len(data) != paddingLen {
- return alertDecodeError
- }
-
- return alertSuccess
- }
-
- type certificateRequestMsg struct {
- raw []byte
- // hasSignatureAndHash indicates whether this message includes a list
- // of signature and hash functions. This change was introduced with TLS
- // 1.2.
- hasSignatureAndHash bool
-
- certificateTypes []byte
- supportedSignatureAlgorithms []SignatureScheme
- certificateAuthorities [][]byte
- }
-
- func (m *certificateRequestMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateRequestMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
- eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
- eqSignatureAlgorithms(m.supportedSignatureAlgorithms, m1.supportedSignatureAlgorithms)
- }
-
- func (m *certificateRequestMsg) marshal() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
-
- // See http://tools.ietf.org/html/rfc4346#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.hasSignatureAndHash {
- 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.hasSignatureAndHash {
- 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) alert {
- m.raw = data
-
- if len(data) < 5 {
- return alertDecodeError
- }
-
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return alertDecodeError
- }
-
- numCertTypes := int(data[4])
- data = data[5:]
- if numCertTypes == 0 || len(data) <= numCertTypes {
- return alertDecodeError
- }
-
- m.certificateTypes = make([]byte, numCertTypes)
- if copy(m.certificateTypes, data) != numCertTypes {
- return alertDecodeError
- }
-
- data = data[numCertTypes:]
-
- if m.hasSignatureAndHash {
- if len(data) < 2 {
- return alertDecodeError
- }
- sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
- data = data[2:]
- if sigAndHashLen&1 != 0 {
- return alertDecodeError
- }
- if len(data) < int(sigAndHashLen) {
- return alertDecodeError
- }
- 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 alertDecodeError
- }
- casLength := uint16(data[0])<<8 | uint16(data[1])
- data = data[2:]
- if len(data) < int(casLength) {
- return alertDecodeError
- }
- cas := make([]byte, casLength)
- copy(cas, data)
- data = data[casLength:]
-
- m.certificateAuthorities = nil
- for len(cas) > 0 {
- if len(cas) < 2 {
- return alertDecodeError
- }
- caLen := uint16(cas[0])<<8 | uint16(cas[1])
- cas = cas[2:]
-
- if len(cas) < int(caLen) {
- return alertDecodeError
- }
-
- m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
- cas = cas[caLen:]
- }
-
- if len(data) != 0 {
- return alertDecodeError
- }
-
- return alertSuccess
- }
-
- type certificateRequestMsg13 struct {
- raw []byte
-
- requestContext []byte
- supportedSignatureAlgorithms []SignatureScheme
- supportedSignatureAlgorithmsCert []SignatureScheme
- certificateAuthorities [][]byte
- }
-
- func (m *certificateRequestMsg13) equal(i interface{}) bool {
- m1, ok := i.(*certificateRequestMsg13)
- return ok &&
- bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.requestContext, m1.requestContext) &&
- eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
- eqSignatureAlgorithms(m.supportedSignatureAlgorithms, m1.supportedSignatureAlgorithms) &&
- eqSignatureAlgorithms(m.supportedSignatureAlgorithmsCert, m1.supportedSignatureAlgorithmsCert)
- }
-
- func (m *certificateRequestMsg13) marshal() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
-
- // See https://tools.ietf.org/html/draft-ietf-tls-tls13-21#section-4.3.2
- length := 1 + len(m.requestContext)
- numExtensions := 1
- extensionsLength := 2 + 2*len(m.supportedSignatureAlgorithms)
-
- if m.getSignatureAlgorithmsCert() != nil {
- numExtensions += 1
- extensionsLength += 2 + 2*len(m.getSignatureAlgorithmsCert())
- }
-
- casLength := 0
- if len(m.certificateAuthorities) > 0 {
- for _, ca := range m.certificateAuthorities {
- casLength += 2 + len(ca)
- }
- extensionsLength += 2 + casLength
- numExtensions++
- }
-
- extensionsLength += 4 * numExtensions
- length += 2 + extensionsLength
-
- 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.requestContext))
- copy(x[5:], m.requestContext)
- z := x[5+len(m.requestContext):]
-
- z[0] = byte(extensionsLength >> 8)
- z[1] = byte(extensionsLength)
- z = z[2:]
-
- // TODO: this function should be reused by CH
- z = marshalExtensionSignatureAlgorithms(extensionSignatureAlgorithms, z, m.supportedSignatureAlgorithms)
-
- if m.getSignatureAlgorithmsCert() != nil {
- z = marshalExtensionSignatureAlgorithms(extensionSignatureAlgorithmsCert, z, m.getSignatureAlgorithmsCert())
- }
- // certificate_authorities
- if casLength > 0 {
- z[0] = byte(extensionCAs >> 8)
- z[1] = byte(extensionCAs)
- l := 2 + casLength
- z[2] = byte(l >> 8)
- z[3] = byte(l)
- z = z[4:]
-
- z[0] = uint8(casLength >> 8)
- z[1] = uint8(casLength)
- z = z[2:]
- for _, ca := range m.certificateAuthorities {
- z[0] = uint8(len(ca) >> 8)
- z[1] = uint8(len(ca))
- z = z[2:]
- copy(z, ca)
- z = z[len(ca):]
- }
- }
-
- m.raw = x
- return
- }
-
- func (m *certificateRequestMsg13) unmarshal(data []byte) alert {
- m.raw = data
- m.supportedSignatureAlgorithms = nil
- m.certificateAuthorities = nil
-
- if len(data) < 5 {
- return alertDecodeError
- }
-
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return alertDecodeError
- }
-
- ctxLen := data[4]
- if len(data) < 5+int(ctxLen)+2 {
- return alertDecodeError
- }
- m.requestContext = data[5 : 5+ctxLen]
- data = data[5+ctxLen:]
-
- extensionsLength := int(data[0])<<8 | int(data[1])
- data = data[2:]
- if len(data) != extensionsLength {
- return alertDecodeError
- }
-
- for len(data) != 0 {
- if len(data) < 4 {
- return alertDecodeError
- }
- extension := uint16(data[0])<<8 | uint16(data[1])
- length := int(data[2])<<8 | int(data[3])
- data = data[4:]
- if len(data) < length {
- return alertDecodeError
- }
-
- switch extension {
- case extensionSignatureAlgorithms:
- // TODO: unmarshalExtensionSignatureAlgorithms should be shared with CH and pre-1.3 CV
- // https://tools.ietf.org/html/draft-ietf-tls-tls13-21#section-4.2.3
- var err alert
- m.supportedSignatureAlgorithms, err = unmarshalExtensionSignatureAlgorithms(data, length)
- if err != alertSuccess {
- return err
- }
- case extensionSignatureAlgorithmsCert:
- var err alert
- m.supportedSignatureAlgorithmsCert, err = unmarshalExtensionSignatureAlgorithms(data, length)
- if err != alertSuccess {
- return err
- }
- case extensionCAs:
- // TODO DRY: share code with CH
- if length < 2 {
- return alertDecodeError
- }
- l := int(data[0])<<8 | int(data[1])
- if l != length-2 || l < 3 {
- return alertDecodeError
- }
- cas := make([]byte, l)
- copy(cas, data[2:])
- m.certificateAuthorities = nil
- for len(cas) > 0 {
- if len(cas) < 2 {
- return alertDecodeError
- }
- caLen := uint16(cas[0])<<8 | uint16(cas[1])
- cas = cas[2:]
-
- if len(cas) < int(caLen) {
- return alertDecodeError
- }
-
- m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
- cas = cas[caLen:]
- }
- }
- data = data[length:]
- }
-
- if len(m.supportedSignatureAlgorithms) == 0 {
- return alertDecodeError
- }
- return alertSuccess
- }
-
- func (m *certificateRequestMsg13) getSignatureAlgorithmsCert() []SignatureScheme {
- return signAlgosCertList(m.supportedSignatureAlgorithms, m.supportedSignatureAlgorithmsCert)
- }
-
- type certificateVerifyMsg struct {
- raw []byte
- hasSignatureAndHash bool
- signatureAlgorithm SignatureScheme
- signature []byte
- }
-
- func (m *certificateVerifyMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateVerifyMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.hasSignatureAndHash == m1.hasSignatureAndHash &&
- m.signatureAlgorithm == m1.signatureAlgorithm &&
- bytes.Equal(m.signature, m1.signature)
- }
-
- func (m *certificateVerifyMsg) marshal() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
-
- // See http://tools.ietf.org/html/rfc4346#section-7.4.8
- siglength := len(m.signature)
- length := 2 + siglength
- if m.hasSignatureAndHash {
- length += 2
- }
- x = make([]byte, 4+length)
- x[0] = typeCertificateVerify
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- y := x[4:]
- if m.hasSignatureAndHash {
- y[0] = uint8(m.signatureAlgorithm >> 8)
- y[1] = uint8(m.signatureAlgorithm)
- y = y[2:]
- }
- y[0] = uint8(siglength >> 8)
- y[1] = uint8(siglength)
- copy(y[2:], m.signature)
-
- m.raw = x
-
- return
- }
-
- func (m *certificateVerifyMsg) unmarshal(data []byte) alert {
- m.raw = data
-
- if len(data) < 6 {
- return alertDecodeError
- }
-
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return alertDecodeError
- }
-
- data = data[4:]
- if m.hasSignatureAndHash {
- m.signatureAlgorithm = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
- data = data[2:]
- }
-
- if len(data) < 2 {
- return alertDecodeError
- }
- siglength := int(data[0])<<8 + int(data[1])
- data = data[2:]
- if len(data) != siglength {
- return alertDecodeError
- }
-
- m.signature = data
-
- return alertSuccess
- }
-
- type newSessionTicketMsg struct {
- raw []byte
- ticket []byte
- }
-
- func (m *newSessionTicketMsg) equal(i interface{}) bool {
- m1, ok := i.(*newSessionTicketMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.ticket, m1.ticket)
- }
-
- func (m *newSessionTicketMsg) marshal() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
-
- // See http://tools.ietf.org/html/rfc5077#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) alert {
- m.raw = data
-
- if len(data) < 10 {
- return alertDecodeError
- }
-
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return alertDecodeError
- }
-
- ticketLen := int(data[8])<<8 + int(data[9])
- if len(data)-10 != ticketLen {
- return alertDecodeError
- }
-
- m.ticket = data[10:]
-
- return alertSuccess
- }
-
- type newSessionTicketMsg13 struct {
- raw []byte
- lifetime uint32
- ageAdd uint32
- nonce []byte
- ticket []byte
- withEarlyDataInfo bool
- maxEarlyDataLength uint32
- }
-
- func (m *newSessionTicketMsg13) equal(i interface{}) bool {
- m1, ok := i.(*newSessionTicketMsg13)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.lifetime == m1.lifetime &&
- m.ageAdd == m1.ageAdd &&
- bytes.Equal(m.nonce, m1.nonce) &&
- bytes.Equal(m.ticket, m1.ticket) &&
- m.withEarlyDataInfo == m1.withEarlyDataInfo &&
- m.maxEarlyDataLength == m1.maxEarlyDataLength
- }
-
- func (m *newSessionTicketMsg13) marshal() (x []byte) {
- if m.raw != nil {
- return m.raw
- }
-
- // See https://tools.ietf.org/html/draft-ietf-tls-tls13-21#section-4.6.1
- nonceLen := len(m.nonce)
- ticketLen := len(m.ticket)
- length := 13 + nonceLen + ticketLen
- if m.withEarlyDataInfo {
- length += 8
- }
- x = make([]byte, 4+length)
- x[0] = typeNewSessionTicket
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
-
- x[4] = uint8(m.lifetime >> 24)
- x[5] = uint8(m.lifetime >> 16)
- x[6] = uint8(m.lifetime >> 8)
- x[7] = uint8(m.lifetime)
- x[8] = uint8(m.ageAdd >> 24)
- x[9] = uint8(m.ageAdd >> 16)
- x[10] = uint8(m.ageAdd >> 8)
- x[11] = uint8(m.ageAdd)
-
- x[12] = uint8(nonceLen)
- copy(x[13:13+nonceLen], m.nonce)
-
- y := x[13+nonceLen:]
- y[0] = uint8(ticketLen >> 8)
- y[1] = uint8(ticketLen)
- copy(y[2:2+ticketLen], m.ticket)
-
- if m.withEarlyDataInfo {
- z := y[2+ticketLen:]
- // z[0] is already 0, this is the extensions vector length.
- z[1] = 8
- z[2] = uint8(extensionEarlyData >> 8)
- z[3] = uint8(extensionEarlyData)
- z[5] = 4
- z[6] = uint8(m.maxEarlyDataLength >> 24)
- z[7] = uint8(m.maxEarlyDataLength >> 16)
- z[8] = uint8(m.maxEarlyDataLength >> 8)
- z[9] = uint8(m.maxEarlyDataLength)
- }
-
- m.raw = x
-
- return
- }
-
- func (m *newSessionTicketMsg13) unmarshal(data []byte) alert {
- m.raw = data
- m.maxEarlyDataLength = 0
- m.withEarlyDataInfo = false
-
- if len(data) < 17 {
- return alertDecodeError
- }
-
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return alertDecodeError
- }
-
- m.lifetime = uint32(data[4])<<24 | uint32(data[5])<<16 |
- uint32(data[6])<<8 | uint32(data[7])
- m.ageAdd = uint32(data[8])<<24 | uint32(data[9])<<16 |
- uint32(data[10])<<8 | uint32(data[11])
-
- nonceLen := int(data[12])
- if nonceLen == 0 || 13+nonceLen+2 > len(data) {
- return alertDecodeError
- }
- m.nonce = data[13 : 13+nonceLen]
-
- data = data[13+nonceLen:]
- ticketLen := int(data[0])<<8 + int(data[1])
- if ticketLen == 0 || 2+ticketLen+2 > len(data) {
- return alertDecodeError
- }
- m.ticket = data[2 : 2+ticketLen]
-
- data = data[2+ticketLen:]
- extLen := int(data[0])<<8 + int(data[1])
- if extLen != len(data)-2 {
- return alertDecodeError
- }
-
- data = data[2:]
- for len(data) > 0 {
- if len(data) < 4 {
- return alertDecodeError
- }
- extType := uint16(data[0])<<8 + uint16(data[1])
- length := int(data[2])<<8 + int(data[3])
- data = data[4:]
-
- switch extType {
- case extensionEarlyData:
- if length != 4 {
- return alertDecodeError
- }
- m.withEarlyDataInfo = true
- m.maxEarlyDataLength = uint32(data[0])<<24 | uint32(data[1])<<16 |
- uint32(data[2])<<8 | uint32(data[3])
- }
- data = data[length:]
- }
-
- return alertSuccess
- }
-
- type endOfEarlyDataMsg struct {
- }
-
- func (*endOfEarlyDataMsg) marshal() []byte {
- return []byte{typeEndOfEarlyData, 0, 0, 0}
- }
-
- func (*endOfEarlyDataMsg) unmarshal(data []byte) alert {
- if len(data) != 4 {
- return alertDecodeError
- }
- return alertSuccess
- }
-
- type helloRequestMsg struct {
- }
-
- func (*helloRequestMsg) marshal() []byte {
- return []byte{typeHelloRequest, 0, 0, 0}
- }
-
- func (*helloRequestMsg) unmarshal(data []byte) alert {
- if len(data) != 4 {
- return alertDecodeError
- }
- return alertSuccess
- }
-
- func eqUint16s(x, y []uint16) bool {
- if len(x) != len(y) {
- return false
- }
- for i, v := range x {
- if y[i] != v {
- return false
- }
- }
- return true
- }
-
- func eqCurveIDs(x, y []CurveID) bool {
- if len(x) != len(y) {
- return false
- }
- for i, v := range x {
- if y[i] != v {
- return false
- }
- }
- return true
- }
-
- func eqStrings(x, y []string) bool {
- if len(x) != len(y) {
- return false
- }
- for i, v := range x {
- if y[i] != v {
- return false
- }
- }
- return true
- }
-
- func eqByteSlices(x, y [][]byte) bool {
- if len(x) != len(y) {
- return false
- }
- for i, v := range x {
- if !bytes.Equal(v, y[i]) {
- return false
- }
- }
- return true
- }
-
- func eqSignatureAlgorithms(x, y []SignatureScheme) bool {
- if len(x) != len(y) {
- return false
- }
- for i, v := range x {
- if v != y[i] {
- return false
- }
- }
- return true
- }
-
- func eqKeyShares(x, y []keyShare) bool {
- if len(x) != len(y) {
- return false
- }
- for i := range x {
- if x[i].group != y[i].group {
- return false
- }
- if !bytes.Equal(x[i].data, y[i].data) {
- return false
- }
- }
- return true
- }
-
- func findExtension(data []byte, extensionType uint16) []byte {
- for len(data) != 0 {
- if len(data) < 4 {
- return nil
- }
- extension := uint16(data[0])<<8 | uint16(data[1])
- length := int(data[2])<<8 | int(data[3])
- data = data[4:]
- if len(data) < length {
- return nil
- }
- if extension == extensionType {
- return data[:length]
- }
- data = data[length:]
- }
- return nil
- }
|