Alternative TLS implementation in Go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
Merge branch 'pwu/go-update/master' into pwu/master-merge-upstream Merge upstream go post-1.9 crypto/tls changes from master: d8ee5d11e5 crypto/tls: limit number of consecutive warning alerts 96cd66b266 crypto/tls: advertise support for SHA-512 signatures in 1.2 f265f5db5d archive/zip, crypto/tls: use rand.Read instead of casting ints to bytes 54d04c2fcb crypto/tls: remove bookkeeping code from pHash function d1bbdbe760 crypto/tls: replace signatureAndHash by SignatureScheme. cb3b345209 crypto/tls: fix first byte test for 255 CBC padding bytes d153df8e4b all: revert "all: prefer strings.LastIndexByte over strings.LastIndex" 5e42658fc0 all: prefer bytes.IndexByte over bytes.Index d2826d3e06 all: prefer strings.LastIndexByte over strings.LastIndex 5a986eca86 all: fix article typos 0f9a2cf2c4 crypto/tls: fix clientHelloMsg fuzzer not to generate the RI SCSV e7d46cee2f crypto/tls: fix and expand TestVerifyPeerCertificate and TestGetClientCertificate 85deaf6077 crypto/tls: fix docstring of Config.ClientSessionCache 4a5f85babb crypto/tls: disallow handshake messages fragmented across CCS b3465646ff crypto/tls: add BenchmarkHandshakeServer d38d357c78 crypto/tls: don't check whether an ec point is on a curve twice e085a891f0 crypto/tls: split clientHandshake into multiple methods Conflicts: * handshake_client.go: conflict between our ("crypto/tls: allow client to pick TLS 1.3, do not enable it by default.") and upstream ("crypto/tls: split clientHandshake into multiple methods"), resolve by applying the mutualVersion->pickVersion change in pickTLSVersion. * handshake_server.go: trivial conflict due to upstreamed patch ("crypto/tls: replace signatureAndHash by SignatureScheme.") and ("crypto/tls: implement TLS 1.3 server 0-RTT") which added pskBinder. Other merge changes: * tls13.go: signatureAndHashes as added in ("crypto/tls: implement TLS 1.3 minimal server") was renamed as required by ("crypto/tls: replace signatureAndHash by SignatureScheme."). * handshake_client.go: moved check from ("crypto/tls: check that client cipher suite matches version") to pickCipherSuite as required by ("crypto/tls: split clientHandshake into multiple methods").
преди 7 години
Merge branch 'pwu/go-update/master' into pwu/master-merge-upstream Merge upstream go post-1.9 crypto/tls changes from master: d8ee5d11e5 crypto/tls: limit number of consecutive warning alerts 96cd66b266 crypto/tls: advertise support for SHA-512 signatures in 1.2 f265f5db5d archive/zip, crypto/tls: use rand.Read instead of casting ints to bytes 54d04c2fcb crypto/tls: remove bookkeeping code from pHash function d1bbdbe760 crypto/tls: replace signatureAndHash by SignatureScheme. cb3b345209 crypto/tls: fix first byte test for 255 CBC padding bytes d153df8e4b all: revert "all: prefer strings.LastIndexByte over strings.LastIndex" 5e42658fc0 all: prefer bytes.IndexByte over bytes.Index d2826d3e06 all: prefer strings.LastIndexByte over strings.LastIndex 5a986eca86 all: fix article typos 0f9a2cf2c4 crypto/tls: fix clientHelloMsg fuzzer not to generate the RI SCSV e7d46cee2f crypto/tls: fix and expand TestVerifyPeerCertificate and TestGetClientCertificate 85deaf6077 crypto/tls: fix docstring of Config.ClientSessionCache 4a5f85babb crypto/tls: disallow handshake messages fragmented across CCS b3465646ff crypto/tls: add BenchmarkHandshakeServer d38d357c78 crypto/tls: don't check whether an ec point is on a curve twice e085a891f0 crypto/tls: split clientHandshake into multiple methods Conflicts: * handshake_client.go: conflict between our ("crypto/tls: allow client to pick TLS 1.3, do not enable it by default.") and upstream ("crypto/tls: split clientHandshake into multiple methods"), resolve by applying the mutualVersion->pickVersion change in pickTLSVersion. * handshake_server.go: trivial conflict due to upstreamed patch ("crypto/tls: replace signatureAndHash by SignatureScheme.") and ("crypto/tls: implement TLS 1.3 server 0-RTT") which added pskBinder. Other merge changes: * tls13.go: signatureAndHashes as added in ("crypto/tls: implement TLS 1.3 minimal server") was renamed as required by ("crypto/tls: replace signatureAndHash by SignatureScheme."). * handshake_client.go: moved check from ("crypto/tls: check that client cipher suite matches version") to pickCipherSuite as required by ("crypto/tls: split clientHandshake into multiple methods").
преди 7 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
преди 9 години
преди 7 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tls
  5. import (
  6. "bytes"
  7. "crypto"
  8. "crypto/ecdsa"
  9. "crypto/rsa"
  10. "crypto/subtle"
  11. "crypto/x509"
  12. "errors"
  13. "fmt"
  14. "io"
  15. "net"
  16. "strconv"
  17. "strings"
  18. "sync/atomic"
  19. )
  20. type clientHandshakeState struct {
  21. c *Conn
  22. serverHello *serverHelloMsg
  23. hello *clientHelloMsg
  24. suite *cipherSuite
  25. masterSecret []byte
  26. session *ClientSessionState
  27. // TLS 1.0-1.2 fields
  28. finishedHash finishedHash
  29. // TLS 1.3 fields
  30. keySchedule *keySchedule13
  31. privateKey []byte
  32. }
  33. func makeClientHello(config *Config) (*clientHelloMsg, error) {
  34. if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
  35. return nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
  36. }
  37. nextProtosLength := 0
  38. for _, proto := range config.NextProtos {
  39. if l := len(proto); l == 0 || l > 255 {
  40. return nil, errors.New("tls: invalid NextProtos value")
  41. } else {
  42. nextProtosLength += 1 + l
  43. }
  44. }
  45. if nextProtosLength > 0xffff {
  46. return nil, errors.New("tls: NextProtos values too large")
  47. }
  48. hello := &clientHelloMsg{
  49. vers: config.maxVersion(),
  50. compressionMethods: []uint8{compressionNone},
  51. random: make([]byte, 32),
  52. ocspStapling: true,
  53. scts: true,
  54. serverName: hostnameInSNI(config.ServerName),
  55. supportedCurves: config.curvePreferences(),
  56. supportedPoints: []uint8{pointFormatUncompressed},
  57. nextProtoNeg: len(config.NextProtos) > 0,
  58. secureRenegotiationSupported: true,
  59. delegatedCredential: config.AcceptDelegatedCredential,
  60. alpnProtocols: config.NextProtos,
  61. extendedMSSupported: config.UseExtendedMasterSecret,
  62. }
  63. possibleCipherSuites := config.cipherSuites()
  64. hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
  65. NextCipherSuite:
  66. for _, suiteId := range possibleCipherSuites {
  67. for _, suite := range cipherSuites {
  68. if suite.id != suiteId {
  69. continue
  70. }
  71. // Don't advertise TLS 1.2-only cipher suites unless
  72. // we're attempting TLS 1.2.
  73. if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
  74. continue NextCipherSuite
  75. }
  76. // Don't advertise TLS 1.3-only cipher suites unless
  77. // we're attempting TLS 1.3.
  78. if hello.vers < VersionTLS13 && suite.flags&suiteTLS13 != 0 {
  79. continue NextCipherSuite
  80. }
  81. hello.cipherSuites = append(hello.cipherSuites, suiteId)
  82. continue NextCipherSuite
  83. }
  84. }
  85. _, err := io.ReadFull(config.rand(), hello.random)
  86. if err != nil {
  87. return nil, errors.New("tls: short read from Rand: " + err.Error())
  88. }
  89. if hello.vers >= VersionTLS12 {
  90. hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
  91. }
  92. if hello.vers >= VersionTLS13 {
  93. // Version preference is indicated via "supported_extensions",
  94. // set legacy_version to TLS 1.2 for backwards compatibility.
  95. hello.vers = VersionTLS12
  96. hello.supportedVersions = config.getSupportedVersions()
  97. hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms13
  98. hello.supportedSignatureAlgorithmsCert = supportedSigAlgorithmsCert(supportedSignatureAlgorithms13)
  99. }
  100. return hello, nil
  101. }
  102. // c.out.Mutex <= L; c.handshakeMutex <= L.
  103. func (c *Conn) clientHandshake() error {
  104. if c.config == nil {
  105. c.config = defaultConfig()
  106. }
  107. // This may be a renegotiation handshake, in which case some fields
  108. // need to be reset.
  109. c.didResume = false
  110. hello, err := makeClientHello(c.config)
  111. if err != nil {
  112. return err
  113. }
  114. if c.handshakes > 0 {
  115. hello.secureRenegotiation = c.clientFinished[:]
  116. }
  117. var session *ClientSessionState
  118. var cacheKey string
  119. sessionCache := c.config.ClientSessionCache
  120. // TLS 1.3 has no session resumption based on session tickets.
  121. if c.config.SessionTicketsDisabled || c.config.maxVersion() >= VersionTLS13 {
  122. sessionCache = nil
  123. }
  124. if sessionCache != nil {
  125. hello.ticketSupported = true
  126. }
  127. // Session resumption is not allowed if renegotiating because
  128. // renegotiation is primarily used to allow a client to send a client
  129. // certificate, which would be skipped if session resumption occurred.
  130. if sessionCache != nil && c.handshakes == 0 {
  131. // Try to resume a previously negotiated TLS session, if
  132. // available.
  133. cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
  134. candidateSession, ok := sessionCache.Get(cacheKey)
  135. if ok {
  136. // Check that the ciphersuite/version used for the
  137. // previous session are still valid.
  138. cipherSuiteOk := false
  139. for _, id := range hello.cipherSuites {
  140. if id == candidateSession.cipherSuite {
  141. cipherSuiteOk = true
  142. break
  143. }
  144. }
  145. versOk := candidateSession.vers >= c.config.minVersion() &&
  146. candidateSession.vers <= c.config.maxVersion()
  147. if versOk && cipherSuiteOk {
  148. session = candidateSession
  149. }
  150. }
  151. }
  152. if session != nil {
  153. hello.sessionTicket = session.sessionTicket
  154. // A random session ID is used to detect when the
  155. // server accepted the ticket and is resuming a session
  156. // (see RFC 5077).
  157. hello.sessionId = make([]byte, 16)
  158. if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
  159. return errors.New("tls: short read from Rand: " + err.Error())
  160. }
  161. }
  162. hs := &clientHandshakeState{
  163. c: c,
  164. hello: hello,
  165. session: session,
  166. }
  167. var clientKS keyShare
  168. if c.config.maxVersion() >= VersionTLS13 {
  169. // Create one keyshare for the first default curve. If it is not
  170. // appropriate, the server should raise a HRR.
  171. defaultGroup := c.config.curvePreferences()[0]
  172. hs.privateKey, clientKS, err = c.generateKeyShare(defaultGroup)
  173. if err != nil {
  174. c.sendAlert(alertInternalError)
  175. return err
  176. }
  177. hello.keyShares = []keyShare{clientKS}
  178. // middlebox compatibility mode, provide a non-empty session ID
  179. hello.sessionId = make([]byte, 16)
  180. if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
  181. return errors.New("tls: short read from Rand: " + err.Error())
  182. }
  183. }
  184. if err = hs.handshake(); err != nil {
  185. return err
  186. }
  187. // If we had a successful handshake and hs.session is different from
  188. // the one already cached - cache a new one
  189. if sessionCache != nil && hs.session != nil && session != hs.session && c.vers < VersionTLS13 {
  190. sessionCache.Put(cacheKey, hs.session)
  191. }
  192. return nil
  193. }
  194. // Does the handshake, either a full one or resumes old session.
  195. // Requires hs.c, hs.hello, and, optionally, hs.session to be set.
  196. func (hs *clientHandshakeState) handshake() error {
  197. c := hs.c
  198. // send ClientHello
  199. if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
  200. return err
  201. }
  202. msg, err := c.readHandshake()
  203. if err != nil {
  204. return err
  205. }
  206. var ok bool
  207. if hs.serverHello, ok = msg.(*serverHelloMsg); !ok {
  208. c.sendAlert(alertUnexpectedMessage)
  209. return unexpectedMessageError(hs.serverHello, msg)
  210. }
  211. if err = hs.pickTLSVersion(); err != nil {
  212. return err
  213. }
  214. if err = hs.pickCipherSuite(); err != nil {
  215. return err
  216. }
  217. var isResume bool
  218. if c.vers >= VersionTLS13 {
  219. hs.keySchedule = newKeySchedule13(hs.suite, c.config, hs.hello.random)
  220. hs.keySchedule.write(hs.hello.marshal())
  221. hs.keySchedule.write(hs.serverHello.marshal())
  222. } else {
  223. isResume, err = hs.processServerHello()
  224. if err != nil {
  225. return err
  226. }
  227. hs.finishedHash = newFinishedHash(c.vers, hs.suite)
  228. // No signatures of the handshake are needed in a resumption.
  229. // Otherwise, in a full handshake, if we don't have any certificates
  230. // configured then we will never send a CertificateVerify message and
  231. // thus no signatures are needed in that case either.
  232. if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
  233. hs.finishedHash.discardHandshakeBuffer()
  234. }
  235. hs.finishedHash.Write(hs.hello.marshal())
  236. hs.finishedHash.Write(hs.serverHello.marshal())
  237. }
  238. c.buffering = true
  239. if c.vers >= VersionTLS13 {
  240. if err := hs.doTLS13Handshake(); err != nil {
  241. return err
  242. }
  243. if _, err := c.flush(); err != nil {
  244. return err
  245. }
  246. } else if isResume {
  247. if err := hs.establishKeys(); err != nil {
  248. return err
  249. }
  250. if err := hs.readSessionTicket(); err != nil {
  251. return err
  252. }
  253. if err := hs.readFinished(c.serverFinished[:]); err != nil {
  254. return err
  255. }
  256. c.clientFinishedIsFirst = false
  257. if err := hs.sendFinished(c.clientFinished[:]); err != nil {
  258. return err
  259. }
  260. if _, err := c.flush(); err != nil {
  261. return err
  262. }
  263. } else {
  264. if err := hs.doFullHandshake(); err != nil {
  265. return err
  266. }
  267. if err := hs.establishKeys(); err != nil {
  268. return err
  269. }
  270. if err := hs.sendFinished(c.clientFinished[:]); err != nil {
  271. return err
  272. }
  273. if _, err := c.flush(); err != nil {
  274. return err
  275. }
  276. c.clientFinishedIsFirst = true
  277. if err := hs.readSessionTicket(); err != nil {
  278. return err
  279. }
  280. if err := hs.readFinished(c.serverFinished[:]); err != nil {
  281. return err
  282. }
  283. }
  284. c.didResume = isResume
  285. c.phase = handshakeConfirmed
  286. atomic.StoreInt32(&c.handshakeConfirmed, 1)
  287. c.handshakeComplete = true
  288. return nil
  289. }
  290. func (hs *clientHandshakeState) pickTLSVersion() error {
  291. vers, ok := hs.c.config.pickVersion([]uint16{hs.serverHello.vers})
  292. if !ok || vers < VersionTLS10 {
  293. // TLS 1.0 is the minimum version supported as a client.
  294. hs.c.sendAlert(alertProtocolVersion)
  295. return fmt.Errorf("tls: server selected unsupported protocol version %x", hs.serverHello.vers)
  296. }
  297. hs.c.vers = vers
  298. hs.c.haveVers = true
  299. return nil
  300. }
  301. func (hs *clientHandshakeState) pickCipherSuite() error {
  302. if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
  303. hs.c.sendAlert(alertHandshakeFailure)
  304. return errors.New("tls: server chose an unconfigured cipher suite")
  305. }
  306. // Check that the chosen cipher suite matches the protocol version.
  307. if hs.c.vers >= VersionTLS13 && hs.suite.flags&suiteTLS13 == 0 ||
  308. hs.c.vers < VersionTLS13 && hs.suite.flags&suiteTLS13 != 0 {
  309. hs.c.sendAlert(alertHandshakeFailure)
  310. return errors.New("tls: server chose an inappropriate cipher suite")
  311. }
  312. hs.c.cipherSuite = hs.suite.id
  313. return nil
  314. }
  315. // processCertsFromServer takes a chain of server certificates from a
  316. // Certificate message and verifies them.
  317. func (hs *clientHandshakeState) processCertsFromServer(certificates [][]byte) error {
  318. c := hs.c
  319. certs := make([]*x509.Certificate, len(certificates))
  320. for i, asn1Data := range certificates {
  321. cert, err := x509.ParseCertificate(asn1Data)
  322. if err != nil {
  323. c.sendAlert(alertBadCertificate)
  324. return errors.New("tls: failed to parse certificate from server: " + err.Error())
  325. }
  326. certs[i] = cert
  327. }
  328. if !c.config.InsecureSkipVerify {
  329. opts := x509.VerifyOptions{
  330. Roots: c.config.RootCAs,
  331. CurrentTime: c.config.time(),
  332. DNSName: c.config.ServerName,
  333. Intermediates: x509.NewCertPool(),
  334. }
  335. for i, cert := range certs {
  336. if i == 0 {
  337. continue
  338. }
  339. opts.Intermediates.AddCert(cert)
  340. }
  341. var err error
  342. c.verifiedChains, err = certs[0].Verify(opts)
  343. if err != nil {
  344. c.sendAlert(alertBadCertificate)
  345. return err
  346. }
  347. }
  348. if c.config.VerifyPeerCertificate != nil {
  349. if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
  350. c.sendAlert(alertBadCertificate)
  351. return err
  352. }
  353. }
  354. switch certs[0].PublicKey.(type) {
  355. case *rsa.PublicKey, *ecdsa.PublicKey:
  356. break
  357. default:
  358. c.sendAlert(alertUnsupportedCertificate)
  359. return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
  360. }
  361. c.peerCertificates = certs
  362. return nil
  363. }
  364. // processDelegatedCredentialFromServer unmarshals the delegated credential
  365. // offered by the server (if present) and validates it using the peer
  366. // certificate and the signature scheme (`scheme`) indicated by the server in
  367. // the "signature_scheme" extension.
  368. func (hs *clientHandshakeState) processDelegatedCredentialFromServer(serialized []byte, scheme SignatureScheme) error {
  369. c := hs.c
  370. var dc *delegatedCredential
  371. var err error
  372. if serialized != nil {
  373. // Assert that the DC extension was indicated by the client.
  374. if !hs.hello.delegatedCredential {
  375. c.sendAlert(alertUnexpectedMessage)
  376. return errors.New("tls: got delegated credential extension without indication")
  377. }
  378. // Parse the delegated credential.
  379. dc, err = unmarshalDelegatedCredential(serialized)
  380. if err != nil {
  381. c.sendAlert(alertDecodeError)
  382. return fmt.Errorf("tls: delegated credential: %s", err)
  383. }
  384. }
  385. if dc != nil && !c.config.InsecureSkipVerify {
  386. if v, err := dc.validate(c.peerCertificates[0], c.config.time()); err != nil {
  387. c.sendAlert(alertIllegalParameter)
  388. return fmt.Errorf("delegated credential: %s", err)
  389. } else if !v {
  390. c.sendAlert(alertIllegalParameter)
  391. return errors.New("delegated credential: signature invalid")
  392. } else if dc.cred.expectedVersion != hs.c.vers {
  393. c.sendAlert(alertIllegalParameter)
  394. return errors.New("delegated credential: protocol version mismatch")
  395. } else if dc.cred.expectedCertVerifyAlgorithm != scheme {
  396. c.sendAlert(alertIllegalParameter)
  397. return errors.New("delegated credential: signature scheme mismatch")
  398. }
  399. }
  400. c.verifiedDc = dc
  401. return nil
  402. }
  403. func (hs *clientHandshakeState) doFullHandshake() error {
  404. c := hs.c
  405. msg, err := c.readHandshake()
  406. if err != nil {
  407. return err
  408. }
  409. certMsg, ok := msg.(*certificateMsg)
  410. if !ok || len(certMsg.certificates) == 0 {
  411. c.sendAlert(alertUnexpectedMessage)
  412. return unexpectedMessageError(certMsg, msg)
  413. }
  414. hs.finishedHash.Write(certMsg.marshal())
  415. if c.handshakes == 0 {
  416. // If this is the first handshake on a connection, process and
  417. // (optionally) verify the server's certificates.
  418. if err := hs.processCertsFromServer(certMsg.certificates); err != nil {
  419. return err
  420. }
  421. } else {
  422. // This is a renegotiation handshake. We require that the
  423. // server's identity (i.e. leaf certificate) is unchanged and
  424. // thus any previous trust decision is still valid.
  425. //
  426. // See https://mitls.org/pages/attacks/3SHAKE for the
  427. // motivation behind this requirement.
  428. if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
  429. c.sendAlert(alertBadCertificate)
  430. return errors.New("tls: server's identity changed during renegotiation")
  431. }
  432. }
  433. msg, err = c.readHandshake()
  434. if err != nil {
  435. return err
  436. }
  437. cs, ok := msg.(*certificateStatusMsg)
  438. if ok {
  439. // RFC4366 on Certificate Status Request:
  440. // The server MAY return a "certificate_status" message.
  441. if !hs.serverHello.ocspStapling {
  442. // If a server returns a "CertificateStatus" message, then the
  443. // server MUST have included an extension of type "status_request"
  444. // with empty "extension_data" in the extended server hello.
  445. c.sendAlert(alertUnexpectedMessage)
  446. return errors.New("tls: received unexpected CertificateStatus message")
  447. }
  448. hs.finishedHash.Write(cs.marshal())
  449. if cs.statusType == statusTypeOCSP {
  450. c.ocspResponse = cs.response
  451. }
  452. msg, err = c.readHandshake()
  453. if err != nil {
  454. return err
  455. }
  456. }
  457. keyAgreement := hs.suite.ka(c.vers)
  458. // Set the public key used to verify the handshake.
  459. pk := c.peerCertificates[0].PublicKey
  460. skx, ok := msg.(*serverKeyExchangeMsg)
  461. if ok {
  462. hs.finishedHash.Write(skx.marshal())
  463. err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, pk, skx)
  464. if err != nil {
  465. c.sendAlert(alertUnexpectedMessage)
  466. return err
  467. }
  468. msg, err = c.readHandshake()
  469. if err != nil {
  470. return err
  471. }
  472. }
  473. var chainToSend *Certificate
  474. var certRequested bool
  475. certReq, ok := msg.(*certificateRequestMsg)
  476. if ok {
  477. certRequested = true
  478. hs.finishedHash.Write(certReq.marshal())
  479. if chainToSend, err = hs.getCertificate(certReq); err != nil {
  480. c.sendAlert(alertInternalError)
  481. return err
  482. }
  483. msg, err = c.readHandshake()
  484. if err != nil {
  485. return err
  486. }
  487. }
  488. shd, ok := msg.(*serverHelloDoneMsg)
  489. if !ok {
  490. c.sendAlert(alertUnexpectedMessage)
  491. return unexpectedMessageError(shd, msg)
  492. }
  493. hs.finishedHash.Write(shd.marshal())
  494. // If the server requested a certificate then we have to send a
  495. // Certificate message, even if it's empty because we don't have a
  496. // certificate to send.
  497. if certRequested {
  498. certMsg = new(certificateMsg)
  499. certMsg.certificates = chainToSend.Certificate
  500. hs.finishedHash.Write(certMsg.marshal())
  501. if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
  502. return err
  503. }
  504. }
  505. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, pk)
  506. if err != nil {
  507. c.sendAlert(alertInternalError)
  508. return err
  509. }
  510. if ckx != nil {
  511. hs.finishedHash.Write(ckx.marshal())
  512. if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
  513. return err
  514. }
  515. }
  516. c.useEMS = hs.serverHello.extendedMSSupported
  517. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random, hs.finishedHash, c.useEMS)
  518. if err := c.config.writeKeyLog("CLIENT_RANDOM", hs.hello.random, hs.masterSecret); err != nil {
  519. c.sendAlert(alertInternalError)
  520. return errors.New("tls: failed to write to key log: " + err.Error())
  521. }
  522. if chainToSend != nil && len(chainToSend.Certificate) > 0 {
  523. certVerify := &certificateVerifyMsg{
  524. hasSignatureAndHash: c.vers >= VersionTLS12,
  525. }
  526. key, ok := chainToSend.PrivateKey.(crypto.Signer)
  527. if !ok {
  528. c.sendAlert(alertInternalError)
  529. return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
  530. }
  531. signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, hs.hello.supportedSignatureAlgorithms, c.vers)
  532. if err != nil {
  533. c.sendAlert(alertInternalError)
  534. return err
  535. }
  536. // SignatureAndHashAlgorithm was introduced in TLS 1.2.
  537. if certVerify.hasSignatureAndHash {
  538. certVerify.signatureAlgorithm = signatureAlgorithm
  539. }
  540. digest, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret)
  541. if err != nil {
  542. c.sendAlert(alertInternalError)
  543. return err
  544. }
  545. signOpts := crypto.SignerOpts(hashFunc)
  546. if sigType == signatureRSAPSS {
  547. signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
  548. }
  549. certVerify.signature, err = key.Sign(c.config.rand(), digest, signOpts)
  550. if err != nil {
  551. c.sendAlert(alertInternalError)
  552. return err
  553. }
  554. hs.finishedHash.Write(certVerify.marshal())
  555. if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
  556. return err
  557. }
  558. }
  559. hs.finishedHash.discardHandshakeBuffer()
  560. return nil
  561. }
  562. func (hs *clientHandshakeState) establishKeys() error {
  563. c := hs.c
  564. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  565. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  566. var clientCipher, serverCipher interface{}
  567. var clientHash, serverHash macFunction
  568. if hs.suite.cipher != nil {
  569. clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
  570. clientHash = hs.suite.mac(c.vers, clientMAC)
  571. serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
  572. serverHash = hs.suite.mac(c.vers, serverMAC)
  573. } else {
  574. clientCipher = hs.suite.aead(clientKey, clientIV)
  575. serverCipher = hs.suite.aead(serverKey, serverIV)
  576. }
  577. c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
  578. c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
  579. return nil
  580. }
  581. func (hs *clientHandshakeState) serverResumedSession() bool {
  582. // If the server responded with the same sessionId then it means the
  583. // sessionTicket is being used to resume a TLS session.
  584. return hs.session != nil && hs.hello.sessionId != nil &&
  585. bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
  586. }
  587. func (hs *clientHandshakeState) processServerHello() (bool, error) {
  588. c := hs.c
  589. if hs.serverHello.compressionMethod != compressionNone {
  590. c.sendAlert(alertUnexpectedMessage)
  591. return false, errors.New("tls: server selected unsupported compression format")
  592. }
  593. if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
  594. c.secureRenegotiation = true
  595. if len(hs.serverHello.secureRenegotiation) != 0 {
  596. c.sendAlert(alertHandshakeFailure)
  597. return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
  598. }
  599. }
  600. if c.handshakes > 0 && c.secureRenegotiation {
  601. var expectedSecureRenegotiation [24]byte
  602. copy(expectedSecureRenegotiation[:], c.clientFinished[:])
  603. copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
  604. if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
  605. c.sendAlert(alertHandshakeFailure)
  606. return false, errors.New("tls: incorrect renegotiation extension contents")
  607. }
  608. }
  609. if hs.serverHello.extendedMSSupported {
  610. if hs.hello.extendedMSSupported {
  611. c.useEMS = true
  612. } else {
  613. // server wants to calculate master secret in a different way than client
  614. c.sendAlert(alertUnsupportedExtension)
  615. return false, errors.New("tls: unexpected extension (EMS) received in SH")
  616. }
  617. }
  618. clientDidNPN := hs.hello.nextProtoNeg
  619. clientDidALPN := len(hs.hello.alpnProtocols) > 0
  620. serverHasNPN := hs.serverHello.nextProtoNeg
  621. serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
  622. if !clientDidNPN && serverHasNPN {
  623. c.sendAlert(alertHandshakeFailure)
  624. return false, errors.New("tls: server advertised unrequested NPN extension")
  625. }
  626. if !clientDidALPN && serverHasALPN {
  627. c.sendAlert(alertHandshakeFailure)
  628. return false, errors.New("tls: server advertised unrequested ALPN extension")
  629. }
  630. if serverHasNPN && serverHasALPN {
  631. c.sendAlert(alertHandshakeFailure)
  632. return false, errors.New("tls: server advertised both NPN and ALPN extensions")
  633. }
  634. if serverHasALPN {
  635. c.clientProtocol = hs.serverHello.alpnProtocol
  636. c.clientProtocolFallback = false
  637. }
  638. c.scts = hs.serverHello.scts
  639. if !hs.serverResumedSession() {
  640. return false, nil
  641. }
  642. if hs.session.useEMS != c.useEMS {
  643. return false, errors.New("differing EMS state")
  644. }
  645. if hs.session.vers != c.vers {
  646. c.sendAlert(alertHandshakeFailure)
  647. return false, errors.New("tls: server resumed a session with a different version")
  648. }
  649. if hs.session.cipherSuite != hs.suite.id {
  650. c.sendAlert(alertHandshakeFailure)
  651. return false, errors.New("tls: server resumed a session with a different cipher suite")
  652. }
  653. // Restore masterSecret and peerCerts from previous state
  654. hs.masterSecret = hs.session.masterSecret
  655. c.peerCertificates = hs.session.serverCertificates
  656. c.verifiedChains = hs.session.verifiedChains
  657. return true, nil
  658. }
  659. func (hs *clientHandshakeState) readFinished(out []byte) error {
  660. c := hs.c
  661. c.readRecord(recordTypeChangeCipherSpec)
  662. if c.in.err != nil {
  663. return c.in.err
  664. }
  665. msg, err := c.readHandshake()
  666. if err != nil {
  667. return err
  668. }
  669. serverFinished, ok := msg.(*finishedMsg)
  670. if !ok {
  671. c.sendAlert(alertUnexpectedMessage)
  672. return unexpectedMessageError(serverFinished, msg)
  673. }
  674. verify := hs.finishedHash.serverSum(hs.masterSecret)
  675. if len(verify) != len(serverFinished.verifyData) ||
  676. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  677. c.sendAlert(alertDecryptError)
  678. return errors.New("tls: server's Finished message was incorrect")
  679. }
  680. hs.finishedHash.Write(serverFinished.marshal())
  681. copy(out, verify)
  682. return nil
  683. }
  684. func (hs *clientHandshakeState) readSessionTicket() error {
  685. if !hs.serverHello.ticketSupported {
  686. return nil
  687. }
  688. c := hs.c
  689. msg, err := c.readHandshake()
  690. if err != nil {
  691. return err
  692. }
  693. sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
  694. if !ok {
  695. c.sendAlert(alertUnexpectedMessage)
  696. return unexpectedMessageError(sessionTicketMsg, msg)
  697. }
  698. hs.finishedHash.Write(sessionTicketMsg.marshal())
  699. hs.session = &ClientSessionState{
  700. sessionTicket: sessionTicketMsg.ticket,
  701. vers: c.vers,
  702. cipherSuite: hs.suite.id,
  703. masterSecret: hs.masterSecret,
  704. serverCertificates: c.peerCertificates,
  705. verifiedChains: c.verifiedChains,
  706. useEMS: c.useEMS,
  707. }
  708. return nil
  709. }
  710. func (hs *clientHandshakeState) sendFinished(out []byte) error {
  711. c := hs.c
  712. if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
  713. return err
  714. }
  715. if hs.serverHello.nextProtoNeg {
  716. nextProto := new(nextProtoMsg)
  717. proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
  718. nextProto.proto = proto
  719. c.clientProtocol = proto
  720. c.clientProtocolFallback = fallback
  721. hs.finishedHash.Write(nextProto.marshal())
  722. if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
  723. return err
  724. }
  725. }
  726. finished := new(finishedMsg)
  727. finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
  728. hs.finishedHash.Write(finished.marshal())
  729. if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
  730. return err
  731. }
  732. copy(out, finished.verifyData)
  733. return nil
  734. }
  735. // tls11SignatureSchemes contains the signature schemes that we synthesise for
  736. // a TLS <= 1.1 connection, based on the supported certificate types.
  737. var tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1}
  738. const (
  739. // tls11SignatureSchemesNumECDSA is the number of initial elements of
  740. // tls11SignatureSchemes that use ECDSA.
  741. tls11SignatureSchemesNumECDSA = 3
  742. // tls11SignatureSchemesNumRSA is the number of trailing elements of
  743. // tls11SignatureSchemes that use RSA.
  744. tls11SignatureSchemesNumRSA = 4
  745. )
  746. func (hs *clientHandshakeState) getCertificate(certReq *certificateRequestMsg) (*Certificate, error) {
  747. c := hs.c
  748. var rsaAvail, ecdsaAvail bool
  749. for _, certType := range certReq.certificateTypes {
  750. switch certType {
  751. case certTypeRSASign:
  752. rsaAvail = true
  753. case certTypeECDSASign:
  754. ecdsaAvail = true
  755. }
  756. }
  757. if c.config.GetClientCertificate != nil {
  758. var signatureSchemes []SignatureScheme
  759. if !certReq.hasSignatureAndHash {
  760. // Prior to TLS 1.2, the signature schemes were not
  761. // included in the certificate request message. In this
  762. // case we use a plausible list based on the acceptable
  763. // certificate types.
  764. signatureSchemes = tls11SignatureSchemes
  765. if !ecdsaAvail {
  766. signatureSchemes = signatureSchemes[tls11SignatureSchemesNumECDSA:]
  767. }
  768. if !rsaAvail {
  769. signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumRSA]
  770. }
  771. } else {
  772. signatureSchemes = certReq.supportedSignatureAlgorithms
  773. }
  774. return c.config.GetClientCertificate(&CertificateRequestInfo{
  775. AcceptableCAs: certReq.certificateAuthorities,
  776. SignatureSchemes: signatureSchemes,
  777. })
  778. }
  779. // RFC 4346 on the certificateAuthorities field: A list of the
  780. // distinguished names of acceptable certificate authorities.
  781. // These distinguished names may specify a desired
  782. // distinguished name for a root CA or for a subordinate CA;
  783. // thus, this message can be used to describe both known roots
  784. // and a desired authorization space. If the
  785. // certificate_authorities list is empty then the client MAY
  786. // send any certificate of the appropriate
  787. // ClientCertificateType, unless there is some external
  788. // arrangement to the contrary.
  789. // We need to search our list of client certs for one
  790. // where SignatureAlgorithm is acceptable to the server and the
  791. // Issuer is in certReq.certificateAuthorities
  792. findCert:
  793. for i, chain := range c.config.Certificates {
  794. if !rsaAvail && !ecdsaAvail {
  795. continue
  796. }
  797. for j, cert := range chain.Certificate {
  798. x509Cert := chain.Leaf
  799. // parse the certificate if this isn't the leaf
  800. // node, or if chain.Leaf was nil
  801. if j != 0 || x509Cert == nil {
  802. var err error
  803. if x509Cert, err = x509.ParseCertificate(cert); err != nil {
  804. c.sendAlert(alertInternalError)
  805. return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
  806. }
  807. }
  808. switch {
  809. case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
  810. case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
  811. default:
  812. continue findCert
  813. }
  814. if len(certReq.certificateAuthorities) == 0 {
  815. // they gave us an empty list, so just take the
  816. // first cert from c.config.Certificates
  817. return &chain, nil
  818. }
  819. for _, ca := range certReq.certificateAuthorities {
  820. if bytes.Equal(x509Cert.RawIssuer, ca) {
  821. return &chain, nil
  822. }
  823. }
  824. }
  825. }
  826. // No acceptable certificate found. Don't send a certificate.
  827. return new(Certificate), nil
  828. }
  829. // clientSessionCacheKey returns a key used to cache sessionTickets that could
  830. // be used to resume previously negotiated TLS sessions with a server.
  831. func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
  832. if len(config.ServerName) > 0 {
  833. return config.ServerName
  834. }
  835. return serverAddr.String()
  836. }
  837. // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
  838. // given list of possible protocols and a list of the preference order. The
  839. // first list must not be empty. It returns the resulting protocol and flag
  840. // indicating if the fallback case was reached.
  841. func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
  842. for _, s := range preferenceProtos {
  843. for _, c := range protos {
  844. if s == c {
  845. return s, false
  846. }
  847. }
  848. }
  849. return protos[0], true
  850. }
  851. // hostnameInSNI converts name into an appropriate hostname for SNI.
  852. // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
  853. // See https://tools.ietf.org/html/rfc6066#section-3.
  854. func hostnameInSNI(name string) string {
  855. host := name
  856. if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
  857. host = host[1 : len(host)-1]
  858. }
  859. if i := strings.LastIndex(host, "%"); i > 0 {
  860. host = host[:i]
  861. }
  862. if net.ParseIP(host) != nil {
  863. return ""
  864. }
  865. for len(name) > 0 && name[len(name)-1] == '.' {
  866. name = name[:len(name)-1]
  867. }
  868. return name
  869. }