Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

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>
před 9 roky
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>
před 9 roky
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").
před 7 roky
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").
před 7 roky
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>
před 9 roky
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>
před 9 roky
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>
před 9 roky
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>
před 9 roky
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>
před 9 roky
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>
před 9 roky
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>
před 9 roky
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>
před 9 roky
před 7 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  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. alpnProtocols: config.NextProtos,
  60. }
  61. possibleCipherSuites := config.cipherSuites()
  62. hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
  63. NextCipherSuite:
  64. for _, suiteId := range possibleCipherSuites {
  65. for _, suite := range cipherSuites {
  66. if suite.id != suiteId {
  67. continue
  68. }
  69. // Don't advertise TLS 1.2-only cipher suites unless
  70. // we're attempting TLS 1.2.
  71. if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
  72. continue NextCipherSuite
  73. }
  74. // Don't advertise TLS 1.3-only cipher suites unless
  75. // we're attempting TLS 1.3.
  76. if hello.vers < VersionTLS13 && suite.flags&suiteTLS13 != 0 {
  77. continue NextCipherSuite
  78. }
  79. hello.cipherSuites = append(hello.cipherSuites, suiteId)
  80. continue NextCipherSuite
  81. }
  82. }
  83. _, err := io.ReadFull(config.rand(), hello.random)
  84. if err != nil {
  85. return nil, errors.New("tls: short read from Rand: " + err.Error())
  86. }
  87. if hello.vers >= VersionTLS12 {
  88. hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
  89. }
  90. if hello.vers >= VersionTLS13 {
  91. // Version preference is indicated via "supported_extensions",
  92. // set legacy_version to TLS 1.2 for backwards compatibility.
  93. hello.vers = VersionTLS12
  94. hello.supportedVersions = config.getSupportedVersions()
  95. hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms13
  96. }
  97. return hello, nil
  98. }
  99. // c.out.Mutex <= L; c.handshakeMutex <= L.
  100. func (c *Conn) clientHandshake() error {
  101. if c.config == nil {
  102. c.config = defaultConfig()
  103. }
  104. // This may be a renegotiation handshake, in which case some fields
  105. // need to be reset.
  106. c.didResume = false
  107. hello, err := makeClientHello(c.config)
  108. if err != nil {
  109. return err
  110. }
  111. if c.handshakes > 0 {
  112. hello.secureRenegotiation = c.clientFinished[:]
  113. }
  114. var session *ClientSessionState
  115. var cacheKey string
  116. sessionCache := c.config.ClientSessionCache
  117. // TLS 1.3 has no session resumption based on session tickets.
  118. if c.config.SessionTicketsDisabled || c.config.maxVersion() >= VersionTLS13 {
  119. sessionCache = nil
  120. }
  121. if sessionCache != nil {
  122. hello.ticketSupported = true
  123. }
  124. // Session resumption is not allowed if renegotiating because
  125. // renegotiation is primarily used to allow a client to send a client
  126. // certificate, which would be skipped if session resumption occurred.
  127. if sessionCache != nil && c.handshakes == 0 {
  128. // Try to resume a previously negotiated TLS session, if
  129. // available.
  130. cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
  131. candidateSession, ok := sessionCache.Get(cacheKey)
  132. if ok {
  133. // Check that the ciphersuite/version used for the
  134. // previous session are still valid.
  135. cipherSuiteOk := false
  136. for _, id := range hello.cipherSuites {
  137. if id == candidateSession.cipherSuite {
  138. cipherSuiteOk = true
  139. break
  140. }
  141. }
  142. versOk := candidateSession.vers >= c.config.minVersion() &&
  143. candidateSession.vers <= c.config.maxVersion()
  144. if versOk && cipherSuiteOk {
  145. session = candidateSession
  146. }
  147. }
  148. }
  149. if session != nil {
  150. hello.sessionTicket = session.sessionTicket
  151. // A random session ID is used to detect when the
  152. // server accepted the ticket and is resuming a session
  153. // (see RFC 5077).
  154. hello.sessionId = make([]byte, 16)
  155. if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
  156. return errors.New("tls: short read from Rand: " + err.Error())
  157. }
  158. }
  159. hs := &clientHandshakeState{
  160. c: c,
  161. hello: hello,
  162. session: session,
  163. }
  164. var clientKS keyShare
  165. if c.config.maxVersion() >= VersionTLS13 {
  166. // Create one keyshare for the first default curve. If it is not
  167. // appropriate, the server should raise a HRR.
  168. defaultGroup := c.config.curvePreferences()[0]
  169. hs.privateKey, clientKS, err = c.config.generateKeyShare(defaultGroup)
  170. if err != nil {
  171. c.sendAlert(alertInternalError)
  172. return err
  173. }
  174. hello.keyShares = []keyShare{clientKS}
  175. // middlebox compatibility mode, provide a non-empty session ID
  176. hello.sessionId = make([]byte, 16)
  177. if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
  178. return errors.New("tls: short read from Rand: " + err.Error())
  179. }
  180. }
  181. if err = hs.handshake(); err != nil {
  182. return err
  183. }
  184. // If we had a successful handshake and hs.session is different from
  185. // the one already cached - cache a new one
  186. if sessionCache != nil && hs.session != nil && session != hs.session && c.vers < VersionTLS13 {
  187. sessionCache.Put(cacheKey, hs.session)
  188. }
  189. return nil
  190. }
  191. // Does the handshake, either a full one or resumes old session.
  192. // Requires hs.c, hs.hello, and, optionally, hs.session to be set.
  193. func (hs *clientHandshakeState) handshake() error {
  194. c := hs.c
  195. // send ClientHello
  196. if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
  197. return err
  198. }
  199. msg, err := c.readHandshake()
  200. if err != nil {
  201. return err
  202. }
  203. var ok bool
  204. if hs.serverHello, ok = msg.(*serverHelloMsg); !ok {
  205. c.sendAlert(alertUnexpectedMessage)
  206. return unexpectedMessageError(hs.serverHello, msg)
  207. }
  208. if err = hs.pickTLSVersion(); err != nil {
  209. return err
  210. }
  211. if err = hs.pickCipherSuite(); err != nil {
  212. return err
  213. }
  214. var isResume bool
  215. if c.vers >= VersionTLS13 {
  216. hs.keySchedule = newKeySchedule13(hs.suite, c.config, hs.hello.random)
  217. hs.keySchedule.write(hs.hello.marshal())
  218. hs.keySchedule.write(hs.serverHello.marshal())
  219. } else {
  220. isResume, err = hs.processServerHello()
  221. if err != nil {
  222. return err
  223. }
  224. hs.finishedHash = newFinishedHash(c.vers, hs.suite)
  225. // No signatures of the handshake are needed in a resumption.
  226. // Otherwise, in a full handshake, if we don't have any certificates
  227. // configured then we will never send a CertificateVerify message and
  228. // thus no signatures are needed in that case either.
  229. if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
  230. hs.finishedHash.discardHandshakeBuffer()
  231. }
  232. hs.finishedHash.Write(hs.hello.marshal())
  233. hs.finishedHash.Write(hs.serverHello.marshal())
  234. }
  235. c.buffering = true
  236. if c.vers >= VersionTLS13 {
  237. if err := hs.doTLS13Handshake(); err != nil {
  238. return err
  239. }
  240. if _, err := c.flush(); err != nil {
  241. return err
  242. }
  243. } else if isResume {
  244. if err := hs.establishKeys(); err != nil {
  245. return err
  246. }
  247. if err := hs.readSessionTicket(); err != nil {
  248. return err
  249. }
  250. if err := hs.readFinished(c.serverFinished[:]); err != nil {
  251. return err
  252. }
  253. c.clientFinishedIsFirst = false
  254. if err := hs.sendFinished(c.clientFinished[:]); err != nil {
  255. return err
  256. }
  257. if _, err := c.flush(); err != nil {
  258. return err
  259. }
  260. } else {
  261. if err := hs.doFullHandshake(); err != nil {
  262. return err
  263. }
  264. if err := hs.establishKeys(); err != nil {
  265. return err
  266. }
  267. if err := hs.sendFinished(c.clientFinished[:]); err != nil {
  268. return err
  269. }
  270. if _, err := c.flush(); err != nil {
  271. return err
  272. }
  273. c.clientFinishedIsFirst = true
  274. if err := hs.readSessionTicket(); err != nil {
  275. return err
  276. }
  277. if err := hs.readFinished(c.serverFinished[:]); err != nil {
  278. return err
  279. }
  280. }
  281. c.didResume = isResume
  282. c.phase = handshakeConfirmed
  283. atomic.StoreInt32(&c.handshakeConfirmed, 1)
  284. c.handshakeComplete = true
  285. return nil
  286. }
  287. func (hs *clientHandshakeState) pickTLSVersion() error {
  288. vers, ok := hs.c.config.pickVersion([]uint16{hs.serverHello.vers})
  289. if !ok || vers < VersionTLS10 {
  290. // TLS 1.0 is the minimum version supported as a client.
  291. hs.c.sendAlert(alertProtocolVersion)
  292. return fmt.Errorf("tls: server selected unsupported protocol version %x", hs.serverHello.vers)
  293. }
  294. hs.c.vers = vers
  295. hs.c.haveVers = true
  296. return nil
  297. }
  298. func (hs *clientHandshakeState) pickCipherSuite() error {
  299. if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
  300. hs.c.sendAlert(alertHandshakeFailure)
  301. return errors.New("tls: server chose an unconfigured cipher suite")
  302. }
  303. // Check that the chosen cipher suite matches the protocol version.
  304. if hs.c.vers >= VersionTLS13 && hs.suite.flags&suiteTLS13 == 0 ||
  305. hs.c.vers < VersionTLS13 && hs.suite.flags&suiteTLS13 != 0 {
  306. hs.c.sendAlert(alertHandshakeFailure)
  307. return errors.New("tls: server chose an inappropriate cipher suite")
  308. }
  309. hs.c.cipherSuite = hs.suite.id
  310. return nil
  311. }
  312. // processCertsFromServer takes a chain of server certificates from a
  313. // Certificate message and verifies them.
  314. func (hs *clientHandshakeState) processCertsFromServer(certificates [][]byte) error {
  315. c := hs.c
  316. certs := make([]*x509.Certificate, len(certificates))
  317. for i, asn1Data := range certificates {
  318. cert, err := x509.ParseCertificate(asn1Data)
  319. if err != nil {
  320. c.sendAlert(alertBadCertificate)
  321. return errors.New("tls: failed to parse certificate from server: " + err.Error())
  322. }
  323. certs[i] = cert
  324. }
  325. if !c.config.InsecureSkipVerify {
  326. opts := x509.VerifyOptions{
  327. Roots: c.config.RootCAs,
  328. CurrentTime: c.config.time(),
  329. DNSName: c.config.ServerName,
  330. Intermediates: x509.NewCertPool(),
  331. }
  332. for i, cert := range certs {
  333. if i == 0 {
  334. continue
  335. }
  336. opts.Intermediates.AddCert(cert)
  337. }
  338. var err error
  339. c.verifiedChains, err = certs[0].Verify(opts)
  340. if err != nil {
  341. c.sendAlert(alertBadCertificate)
  342. return err
  343. }
  344. }
  345. if c.config.VerifyPeerCertificate != nil {
  346. if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
  347. c.sendAlert(alertBadCertificate)
  348. return err
  349. }
  350. }
  351. switch certs[0].PublicKey.(type) {
  352. case *rsa.PublicKey, *ecdsa.PublicKey:
  353. break
  354. default:
  355. c.sendAlert(alertUnsupportedCertificate)
  356. return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
  357. }
  358. c.peerCertificates = certs
  359. return nil
  360. }
  361. func (hs *clientHandshakeState) doFullHandshake() error {
  362. c := hs.c
  363. msg, err := c.readHandshake()
  364. if err != nil {
  365. return err
  366. }
  367. certMsg, ok := msg.(*certificateMsg)
  368. if !ok || len(certMsg.certificates) == 0 {
  369. c.sendAlert(alertUnexpectedMessage)
  370. return unexpectedMessageError(certMsg, msg)
  371. }
  372. hs.finishedHash.Write(certMsg.marshal())
  373. if c.handshakes == 0 {
  374. // If this is the first handshake on a connection, process and
  375. // (optionally) verify the server's certificates.
  376. if err := hs.processCertsFromServer(certMsg.certificates); err != nil {
  377. return err
  378. }
  379. } else {
  380. // This is a renegotiation handshake. We require that the
  381. // server's identity (i.e. leaf certificate) is unchanged and
  382. // thus any previous trust decision is still valid.
  383. //
  384. // See https://mitls.org/pages/attacks/3SHAKE for the
  385. // motivation behind this requirement.
  386. if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
  387. c.sendAlert(alertBadCertificate)
  388. return errors.New("tls: server's identity changed during renegotiation")
  389. }
  390. }
  391. msg, err = c.readHandshake()
  392. if err != nil {
  393. return err
  394. }
  395. cs, ok := msg.(*certificateStatusMsg)
  396. if ok {
  397. // RFC4366 on Certificate Status Request:
  398. // The server MAY return a "certificate_status" message.
  399. if !hs.serverHello.ocspStapling {
  400. // If a server returns a "CertificateStatus" message, then the
  401. // server MUST have included an extension of type "status_request"
  402. // with empty "extension_data" in the extended server hello.
  403. c.sendAlert(alertUnexpectedMessage)
  404. return errors.New("tls: received unexpected CertificateStatus message")
  405. }
  406. hs.finishedHash.Write(cs.marshal())
  407. if cs.statusType == statusTypeOCSP {
  408. c.ocspResponse = cs.response
  409. }
  410. msg, err = c.readHandshake()
  411. if err != nil {
  412. return err
  413. }
  414. }
  415. keyAgreement := hs.suite.ka(c.vers)
  416. skx, ok := msg.(*serverKeyExchangeMsg)
  417. if ok {
  418. hs.finishedHash.Write(skx.marshal())
  419. err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
  420. if err != nil {
  421. c.sendAlert(alertUnexpectedMessage)
  422. return err
  423. }
  424. msg, err = c.readHandshake()
  425. if err != nil {
  426. return err
  427. }
  428. }
  429. var chainToSend *Certificate
  430. var certRequested bool
  431. certReq, ok := msg.(*certificateRequestMsg)
  432. if ok {
  433. certRequested = true
  434. hs.finishedHash.Write(certReq.marshal())
  435. if chainToSend, err = hs.getCertificate(certReq); err != nil {
  436. c.sendAlert(alertInternalError)
  437. return err
  438. }
  439. msg, err = c.readHandshake()
  440. if err != nil {
  441. return err
  442. }
  443. }
  444. shd, ok := msg.(*serverHelloDoneMsg)
  445. if !ok {
  446. c.sendAlert(alertUnexpectedMessage)
  447. return unexpectedMessageError(shd, msg)
  448. }
  449. hs.finishedHash.Write(shd.marshal())
  450. // If the server requested a certificate then we have to send a
  451. // Certificate message, even if it's empty because we don't have a
  452. // certificate to send.
  453. if certRequested {
  454. certMsg = new(certificateMsg)
  455. certMsg.certificates = chainToSend.Certificate
  456. hs.finishedHash.Write(certMsg.marshal())
  457. if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
  458. return err
  459. }
  460. }
  461. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
  462. if err != nil {
  463. c.sendAlert(alertInternalError)
  464. return err
  465. }
  466. if ckx != nil {
  467. hs.finishedHash.Write(ckx.marshal())
  468. if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
  469. return err
  470. }
  471. }
  472. if chainToSend != nil && len(chainToSend.Certificate) > 0 {
  473. certVerify := &certificateVerifyMsg{
  474. hasSignatureAndHash: c.vers >= VersionTLS12,
  475. }
  476. key, ok := chainToSend.PrivateKey.(crypto.Signer)
  477. if !ok {
  478. c.sendAlert(alertInternalError)
  479. return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
  480. }
  481. signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, hs.hello.supportedSignatureAlgorithms, c.vers)
  482. if err != nil {
  483. c.sendAlert(alertInternalError)
  484. return err
  485. }
  486. // SignatureAndHashAlgorithm was introduced in TLS 1.2.
  487. if certVerify.hasSignatureAndHash {
  488. certVerify.signatureAlgorithm = signatureAlgorithm
  489. }
  490. digest, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret)
  491. if err != nil {
  492. c.sendAlert(alertInternalError)
  493. return err
  494. }
  495. signOpts := crypto.SignerOpts(hashFunc)
  496. if sigType == signatureRSAPSS {
  497. signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
  498. }
  499. certVerify.signature, err = key.Sign(c.config.rand(), digest, signOpts)
  500. if err != nil {
  501. c.sendAlert(alertInternalError)
  502. return err
  503. }
  504. hs.finishedHash.Write(certVerify.marshal())
  505. if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
  506. return err
  507. }
  508. }
  509. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
  510. if err := c.config.writeKeyLog("CLIENT_RANDOM", hs.hello.random, hs.masterSecret); err != nil {
  511. c.sendAlert(alertInternalError)
  512. return errors.New("tls: failed to write to key log: " + err.Error())
  513. }
  514. hs.finishedHash.discardHandshakeBuffer()
  515. return nil
  516. }
  517. func (hs *clientHandshakeState) establishKeys() error {
  518. c := hs.c
  519. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  520. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  521. var clientCipher, serverCipher interface{}
  522. var clientHash, serverHash macFunction
  523. if hs.suite.cipher != nil {
  524. clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
  525. clientHash = hs.suite.mac(c.vers, clientMAC)
  526. serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
  527. serverHash = hs.suite.mac(c.vers, serverMAC)
  528. } else {
  529. clientCipher = hs.suite.aead(clientKey, clientIV)
  530. serverCipher = hs.suite.aead(serverKey, serverIV)
  531. }
  532. c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
  533. c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
  534. return nil
  535. }
  536. func (hs *clientHandshakeState) serverResumedSession() bool {
  537. // If the server responded with the same sessionId then it means the
  538. // sessionTicket is being used to resume a TLS session.
  539. return hs.session != nil && hs.hello.sessionId != nil &&
  540. bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
  541. }
  542. func (hs *clientHandshakeState) processServerHello() (bool, error) {
  543. c := hs.c
  544. if hs.serverHello.compressionMethod != compressionNone {
  545. c.sendAlert(alertUnexpectedMessage)
  546. return false, errors.New("tls: server selected unsupported compression format")
  547. }
  548. if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
  549. c.secureRenegotiation = true
  550. if len(hs.serverHello.secureRenegotiation) != 0 {
  551. c.sendAlert(alertHandshakeFailure)
  552. return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
  553. }
  554. }
  555. if c.handshakes > 0 && c.secureRenegotiation {
  556. var expectedSecureRenegotiation [24]byte
  557. copy(expectedSecureRenegotiation[:], c.clientFinished[:])
  558. copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
  559. if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
  560. c.sendAlert(alertHandshakeFailure)
  561. return false, errors.New("tls: incorrect renegotiation extension contents")
  562. }
  563. }
  564. clientDidNPN := hs.hello.nextProtoNeg
  565. clientDidALPN := len(hs.hello.alpnProtocols) > 0
  566. serverHasNPN := hs.serverHello.nextProtoNeg
  567. serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
  568. if !clientDidNPN && serverHasNPN {
  569. c.sendAlert(alertHandshakeFailure)
  570. return false, errors.New("tls: server advertised unrequested NPN extension")
  571. }
  572. if !clientDidALPN && serverHasALPN {
  573. c.sendAlert(alertHandshakeFailure)
  574. return false, errors.New("tls: server advertised unrequested ALPN extension")
  575. }
  576. if serverHasNPN && serverHasALPN {
  577. c.sendAlert(alertHandshakeFailure)
  578. return false, errors.New("tls: server advertised both NPN and ALPN extensions")
  579. }
  580. if serverHasALPN {
  581. c.clientProtocol = hs.serverHello.alpnProtocol
  582. c.clientProtocolFallback = false
  583. }
  584. c.scts = hs.serverHello.scts
  585. if !hs.serverResumedSession() {
  586. return false, nil
  587. }
  588. if hs.session.vers != c.vers {
  589. c.sendAlert(alertHandshakeFailure)
  590. return false, errors.New("tls: server resumed a session with a different version")
  591. }
  592. if hs.session.cipherSuite != hs.suite.id {
  593. c.sendAlert(alertHandshakeFailure)
  594. return false, errors.New("tls: server resumed a session with a different cipher suite")
  595. }
  596. // Restore masterSecret and peerCerts from previous state
  597. hs.masterSecret = hs.session.masterSecret
  598. c.peerCertificates = hs.session.serverCertificates
  599. c.verifiedChains = hs.session.verifiedChains
  600. return true, nil
  601. }
  602. func (hs *clientHandshakeState) readFinished(out []byte) error {
  603. c := hs.c
  604. c.readRecord(recordTypeChangeCipherSpec)
  605. if c.in.err != nil {
  606. return c.in.err
  607. }
  608. msg, err := c.readHandshake()
  609. if err != nil {
  610. return err
  611. }
  612. serverFinished, ok := msg.(*finishedMsg)
  613. if !ok {
  614. c.sendAlert(alertUnexpectedMessage)
  615. return unexpectedMessageError(serverFinished, msg)
  616. }
  617. verify := hs.finishedHash.serverSum(hs.masterSecret)
  618. if len(verify) != len(serverFinished.verifyData) ||
  619. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  620. c.sendAlert(alertDecryptError)
  621. return errors.New("tls: server's Finished message was incorrect")
  622. }
  623. hs.finishedHash.Write(serverFinished.marshal())
  624. copy(out, verify)
  625. return nil
  626. }
  627. func (hs *clientHandshakeState) readSessionTicket() error {
  628. if !hs.serverHello.ticketSupported {
  629. return nil
  630. }
  631. c := hs.c
  632. msg, err := c.readHandshake()
  633. if err != nil {
  634. return err
  635. }
  636. sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
  637. if !ok {
  638. c.sendAlert(alertUnexpectedMessage)
  639. return unexpectedMessageError(sessionTicketMsg, msg)
  640. }
  641. hs.finishedHash.Write(sessionTicketMsg.marshal())
  642. hs.session = &ClientSessionState{
  643. sessionTicket: sessionTicketMsg.ticket,
  644. vers: c.vers,
  645. cipherSuite: hs.suite.id,
  646. masterSecret: hs.masterSecret,
  647. serverCertificates: c.peerCertificates,
  648. verifiedChains: c.verifiedChains,
  649. }
  650. return nil
  651. }
  652. func (hs *clientHandshakeState) sendFinished(out []byte) error {
  653. c := hs.c
  654. if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
  655. return err
  656. }
  657. if hs.serverHello.nextProtoNeg {
  658. nextProto := new(nextProtoMsg)
  659. proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
  660. nextProto.proto = proto
  661. c.clientProtocol = proto
  662. c.clientProtocolFallback = fallback
  663. hs.finishedHash.Write(nextProto.marshal())
  664. if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
  665. return err
  666. }
  667. }
  668. finished := new(finishedMsg)
  669. finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
  670. hs.finishedHash.Write(finished.marshal())
  671. if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
  672. return err
  673. }
  674. copy(out, finished.verifyData)
  675. return nil
  676. }
  677. // tls11SignatureSchemes contains the signature schemes that we synthesise for
  678. // a TLS <= 1.1 connection, based on the supported certificate types.
  679. var tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1}
  680. const (
  681. // tls11SignatureSchemesNumECDSA is the number of initial elements of
  682. // tls11SignatureSchemes that use ECDSA.
  683. tls11SignatureSchemesNumECDSA = 3
  684. // tls11SignatureSchemesNumRSA is the number of trailing elements of
  685. // tls11SignatureSchemes that use RSA.
  686. tls11SignatureSchemesNumRSA = 4
  687. )
  688. func (hs *clientHandshakeState) getCertificate(certReq *certificateRequestMsg) (*Certificate, error) {
  689. c := hs.c
  690. var rsaAvail, ecdsaAvail bool
  691. for _, certType := range certReq.certificateTypes {
  692. switch certType {
  693. case certTypeRSASign:
  694. rsaAvail = true
  695. case certTypeECDSASign:
  696. ecdsaAvail = true
  697. }
  698. }
  699. if c.config.GetClientCertificate != nil {
  700. var signatureSchemes []SignatureScheme
  701. if !certReq.hasSignatureAndHash {
  702. // Prior to TLS 1.2, the signature schemes were not
  703. // included in the certificate request message. In this
  704. // case we use a plausible list based on the acceptable
  705. // certificate types.
  706. signatureSchemes = tls11SignatureSchemes
  707. if !ecdsaAvail {
  708. signatureSchemes = signatureSchemes[tls11SignatureSchemesNumECDSA:]
  709. }
  710. if !rsaAvail {
  711. signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumRSA]
  712. }
  713. } else {
  714. signatureSchemes = certReq.supportedSignatureAlgorithms
  715. }
  716. return c.config.GetClientCertificate(&CertificateRequestInfo{
  717. AcceptableCAs: certReq.certificateAuthorities,
  718. SignatureSchemes: signatureSchemes,
  719. })
  720. }
  721. // RFC 4346 on the certificateAuthorities field: A list of the
  722. // distinguished names of acceptable certificate authorities.
  723. // These distinguished names may specify a desired
  724. // distinguished name for a root CA or for a subordinate CA;
  725. // thus, this message can be used to describe both known roots
  726. // and a desired authorization space. If the
  727. // certificate_authorities list is empty then the client MAY
  728. // send any certificate of the appropriate
  729. // ClientCertificateType, unless there is some external
  730. // arrangement to the contrary.
  731. // We need to search our list of client certs for one
  732. // where SignatureAlgorithm is acceptable to the server and the
  733. // Issuer is in certReq.certificateAuthorities
  734. findCert:
  735. for i, chain := range c.config.Certificates {
  736. if !rsaAvail && !ecdsaAvail {
  737. continue
  738. }
  739. for j, cert := range chain.Certificate {
  740. x509Cert := chain.Leaf
  741. // parse the certificate if this isn't the leaf
  742. // node, or if chain.Leaf was nil
  743. if j != 0 || x509Cert == nil {
  744. var err error
  745. if x509Cert, err = x509.ParseCertificate(cert); err != nil {
  746. c.sendAlert(alertInternalError)
  747. return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
  748. }
  749. }
  750. switch {
  751. case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
  752. case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
  753. default:
  754. continue findCert
  755. }
  756. if len(certReq.certificateAuthorities) == 0 {
  757. // they gave us an empty list, so just take the
  758. // first cert from c.config.Certificates
  759. return &chain, nil
  760. }
  761. for _, ca := range certReq.certificateAuthorities {
  762. if bytes.Equal(x509Cert.RawIssuer, ca) {
  763. return &chain, nil
  764. }
  765. }
  766. }
  767. }
  768. // No acceptable certificate found. Don't send a certificate.
  769. return new(Certificate), nil
  770. }
  771. // clientSessionCacheKey returns a key used to cache sessionTickets that could
  772. // be used to resume previously negotiated TLS sessions with a server.
  773. func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
  774. if len(config.ServerName) > 0 {
  775. return config.ServerName
  776. }
  777. return serverAddr.String()
  778. }
  779. // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
  780. // given list of possible protocols and a list of the preference order. The
  781. // first list must not be empty. It returns the resulting protocol and flag
  782. // indicating if the fallback case was reached.
  783. func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
  784. for _, s := range preferenceProtos {
  785. for _, c := range protos {
  786. if s == c {
  787. return s, false
  788. }
  789. }
  790. }
  791. return protos[0], true
  792. }
  793. // hostnameInSNI converts name into an appropriate hostname for SNI.
  794. // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
  795. // See https://tools.ietf.org/html/rfc6066#section-3.
  796. func hostnameInSNI(name string) string {
  797. host := name
  798. if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
  799. host = host[1 : len(host)-1]
  800. }
  801. if i := strings.LastIndex(host, "%"); i > 0 {
  802. host = host[:i]
  803. }
  804. if net.ParseIP(host) != nil {
  805. return ""
  806. }
  807. for len(name) > 0 && name[len(name)-1] == '.' {
  808. name = name[:len(name)-1]
  809. }
  810. return name
  811. }