25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

handshake_client.go 27 KiB

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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
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 yıl önce
7 yıl önce
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  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. if hs.serverHello.ocspStapling {
  392. msg, err = c.readHandshake()
  393. if err != nil {
  394. return err
  395. }
  396. cs, ok := msg.(*certificateStatusMsg)
  397. if !ok {
  398. c.sendAlert(alertUnexpectedMessage)
  399. return unexpectedMessageError(cs, msg)
  400. }
  401. hs.finishedHash.Write(cs.marshal())
  402. if cs.statusType == statusTypeOCSP {
  403. c.ocspResponse = cs.response
  404. }
  405. }
  406. msg, err = c.readHandshake()
  407. if err != nil {
  408. return err
  409. }
  410. keyAgreement := hs.suite.ka(c.vers)
  411. skx, ok := msg.(*serverKeyExchangeMsg)
  412. if ok {
  413. hs.finishedHash.Write(skx.marshal())
  414. err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
  415. if err != nil {
  416. c.sendAlert(alertUnexpectedMessage)
  417. return err
  418. }
  419. msg, err = c.readHandshake()
  420. if err != nil {
  421. return err
  422. }
  423. }
  424. var chainToSend *Certificate
  425. var certRequested bool
  426. certReq, ok := msg.(*certificateRequestMsg)
  427. if ok {
  428. certRequested = true
  429. hs.finishedHash.Write(certReq.marshal())
  430. if chainToSend, err = hs.getCertificate(certReq); err != nil {
  431. c.sendAlert(alertInternalError)
  432. return err
  433. }
  434. msg, err = c.readHandshake()
  435. if err != nil {
  436. return err
  437. }
  438. }
  439. shd, ok := msg.(*serverHelloDoneMsg)
  440. if !ok {
  441. c.sendAlert(alertUnexpectedMessage)
  442. return unexpectedMessageError(shd, msg)
  443. }
  444. hs.finishedHash.Write(shd.marshal())
  445. // If the server requested a certificate then we have to send a
  446. // Certificate message, even if it's empty because we don't have a
  447. // certificate to send.
  448. if certRequested {
  449. certMsg = new(certificateMsg)
  450. certMsg.certificates = chainToSend.Certificate
  451. hs.finishedHash.Write(certMsg.marshal())
  452. if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
  453. return err
  454. }
  455. }
  456. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
  457. if err != nil {
  458. c.sendAlert(alertInternalError)
  459. return err
  460. }
  461. if ckx != nil {
  462. hs.finishedHash.Write(ckx.marshal())
  463. if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
  464. return err
  465. }
  466. }
  467. if chainToSend != nil && len(chainToSend.Certificate) > 0 {
  468. certVerify := &certificateVerifyMsg{
  469. hasSignatureAndHash: c.vers >= VersionTLS12,
  470. }
  471. key, ok := chainToSend.PrivateKey.(crypto.Signer)
  472. if !ok {
  473. c.sendAlert(alertInternalError)
  474. return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
  475. }
  476. signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, hs.hello.supportedSignatureAlgorithms, c.vers)
  477. if err != nil {
  478. c.sendAlert(alertInternalError)
  479. return err
  480. }
  481. // SignatureAndHashAlgorithm was introduced in TLS 1.2.
  482. if certVerify.hasSignatureAndHash {
  483. certVerify.signatureAlgorithm = signatureAlgorithm
  484. }
  485. digest, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret)
  486. if err != nil {
  487. c.sendAlert(alertInternalError)
  488. return err
  489. }
  490. signOpts := crypto.SignerOpts(hashFunc)
  491. if sigType == signatureRSAPSS {
  492. signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
  493. }
  494. certVerify.signature, err = key.Sign(c.config.rand(), digest, signOpts)
  495. if err != nil {
  496. c.sendAlert(alertInternalError)
  497. return err
  498. }
  499. hs.finishedHash.Write(certVerify.marshal())
  500. if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
  501. return err
  502. }
  503. }
  504. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
  505. if err := c.config.writeKeyLog("CLIENT_RANDOM", hs.hello.random, hs.masterSecret); err != nil {
  506. c.sendAlert(alertInternalError)
  507. return errors.New("tls: failed to write to key log: " + err.Error())
  508. }
  509. hs.finishedHash.discardHandshakeBuffer()
  510. return nil
  511. }
  512. func (hs *clientHandshakeState) establishKeys() error {
  513. c := hs.c
  514. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  515. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  516. var clientCipher, serverCipher interface{}
  517. var clientHash, serverHash macFunction
  518. if hs.suite.cipher != nil {
  519. clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
  520. clientHash = hs.suite.mac(c.vers, clientMAC)
  521. serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
  522. serverHash = hs.suite.mac(c.vers, serverMAC)
  523. } else {
  524. clientCipher = hs.suite.aead(clientKey, clientIV)
  525. serverCipher = hs.suite.aead(serverKey, serverIV)
  526. }
  527. c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
  528. c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
  529. return nil
  530. }
  531. func (hs *clientHandshakeState) serverResumedSession() bool {
  532. // If the server responded with the same sessionId then it means the
  533. // sessionTicket is being used to resume a TLS session.
  534. return hs.session != nil && hs.hello.sessionId != nil &&
  535. bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
  536. }
  537. func (hs *clientHandshakeState) processServerHello() (bool, error) {
  538. c := hs.c
  539. if hs.serverHello.compressionMethod != compressionNone {
  540. c.sendAlert(alertUnexpectedMessage)
  541. return false, errors.New("tls: server selected unsupported compression format")
  542. }
  543. if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
  544. c.secureRenegotiation = true
  545. if len(hs.serverHello.secureRenegotiation) != 0 {
  546. c.sendAlert(alertHandshakeFailure)
  547. return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
  548. }
  549. }
  550. if c.handshakes > 0 && c.secureRenegotiation {
  551. var expectedSecureRenegotiation [24]byte
  552. copy(expectedSecureRenegotiation[:], c.clientFinished[:])
  553. copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
  554. if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
  555. c.sendAlert(alertHandshakeFailure)
  556. return false, errors.New("tls: incorrect renegotiation extension contents")
  557. }
  558. }
  559. clientDidNPN := hs.hello.nextProtoNeg
  560. clientDidALPN := len(hs.hello.alpnProtocols) > 0
  561. serverHasNPN := hs.serverHello.nextProtoNeg
  562. serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
  563. if !clientDidNPN && serverHasNPN {
  564. c.sendAlert(alertHandshakeFailure)
  565. return false, errors.New("tls: server advertised unrequested NPN extension")
  566. }
  567. if !clientDidALPN && serverHasALPN {
  568. c.sendAlert(alertHandshakeFailure)
  569. return false, errors.New("tls: server advertised unrequested ALPN extension")
  570. }
  571. if serverHasNPN && serverHasALPN {
  572. c.sendAlert(alertHandshakeFailure)
  573. return false, errors.New("tls: server advertised both NPN and ALPN extensions")
  574. }
  575. if serverHasALPN {
  576. c.clientProtocol = hs.serverHello.alpnProtocol
  577. c.clientProtocolFallback = false
  578. }
  579. c.scts = hs.serverHello.scts
  580. if !hs.serverResumedSession() {
  581. return false, nil
  582. }
  583. if hs.session.vers != c.vers {
  584. c.sendAlert(alertHandshakeFailure)
  585. return false, errors.New("tls: server resumed a session with a different version")
  586. }
  587. if hs.session.cipherSuite != hs.suite.id {
  588. c.sendAlert(alertHandshakeFailure)
  589. return false, errors.New("tls: server resumed a session with a different cipher suite")
  590. }
  591. // Restore masterSecret and peerCerts from previous state
  592. hs.masterSecret = hs.session.masterSecret
  593. c.peerCertificates = hs.session.serverCertificates
  594. c.verifiedChains = hs.session.verifiedChains
  595. return true, nil
  596. }
  597. func (hs *clientHandshakeState) readFinished(out []byte) error {
  598. c := hs.c
  599. c.readRecord(recordTypeChangeCipherSpec)
  600. if c.in.err != nil {
  601. return c.in.err
  602. }
  603. msg, err := c.readHandshake()
  604. if err != nil {
  605. return err
  606. }
  607. serverFinished, ok := msg.(*finishedMsg)
  608. if !ok {
  609. c.sendAlert(alertUnexpectedMessage)
  610. return unexpectedMessageError(serverFinished, msg)
  611. }
  612. verify := hs.finishedHash.serverSum(hs.masterSecret)
  613. if len(verify) != len(serverFinished.verifyData) ||
  614. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  615. c.sendAlert(alertDecryptError)
  616. return errors.New("tls: server's Finished message was incorrect")
  617. }
  618. hs.finishedHash.Write(serverFinished.marshal())
  619. copy(out, verify)
  620. return nil
  621. }
  622. func (hs *clientHandshakeState) readSessionTicket() error {
  623. if !hs.serverHello.ticketSupported {
  624. return nil
  625. }
  626. c := hs.c
  627. msg, err := c.readHandshake()
  628. if err != nil {
  629. return err
  630. }
  631. sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
  632. if !ok {
  633. c.sendAlert(alertUnexpectedMessage)
  634. return unexpectedMessageError(sessionTicketMsg, msg)
  635. }
  636. hs.finishedHash.Write(sessionTicketMsg.marshal())
  637. hs.session = &ClientSessionState{
  638. sessionTicket: sessionTicketMsg.ticket,
  639. vers: c.vers,
  640. cipherSuite: hs.suite.id,
  641. masterSecret: hs.masterSecret,
  642. serverCertificates: c.peerCertificates,
  643. verifiedChains: c.verifiedChains,
  644. }
  645. return nil
  646. }
  647. func (hs *clientHandshakeState) sendFinished(out []byte) error {
  648. c := hs.c
  649. if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
  650. return err
  651. }
  652. if hs.serverHello.nextProtoNeg {
  653. nextProto := new(nextProtoMsg)
  654. proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
  655. nextProto.proto = proto
  656. c.clientProtocol = proto
  657. c.clientProtocolFallback = fallback
  658. hs.finishedHash.Write(nextProto.marshal())
  659. if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
  660. return err
  661. }
  662. }
  663. finished := new(finishedMsg)
  664. finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
  665. hs.finishedHash.Write(finished.marshal())
  666. if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
  667. return err
  668. }
  669. copy(out, finished.verifyData)
  670. return nil
  671. }
  672. // tls11SignatureSchemes contains the signature schemes that we synthesise for
  673. // a TLS <= 1.1 connection, based on the supported certificate types.
  674. var tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1}
  675. const (
  676. // tls11SignatureSchemesNumECDSA is the number of initial elements of
  677. // tls11SignatureSchemes that use ECDSA.
  678. tls11SignatureSchemesNumECDSA = 3
  679. // tls11SignatureSchemesNumRSA is the number of trailing elements of
  680. // tls11SignatureSchemes that use RSA.
  681. tls11SignatureSchemesNumRSA = 4
  682. )
  683. func (hs *clientHandshakeState) getCertificate(certReq *certificateRequestMsg) (*Certificate, error) {
  684. c := hs.c
  685. var rsaAvail, ecdsaAvail bool
  686. for _, certType := range certReq.certificateTypes {
  687. switch certType {
  688. case certTypeRSASign:
  689. rsaAvail = true
  690. case certTypeECDSASign:
  691. ecdsaAvail = true
  692. }
  693. }
  694. if c.config.GetClientCertificate != nil {
  695. var signatureSchemes []SignatureScheme
  696. if !certReq.hasSignatureAndHash {
  697. // Prior to TLS 1.2, the signature schemes were not
  698. // included in the certificate request message. In this
  699. // case we use a plausible list based on the acceptable
  700. // certificate types.
  701. signatureSchemes = tls11SignatureSchemes
  702. if !ecdsaAvail {
  703. signatureSchemes = signatureSchemes[tls11SignatureSchemesNumECDSA:]
  704. }
  705. if !rsaAvail {
  706. signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumRSA]
  707. }
  708. } else {
  709. signatureSchemes = certReq.supportedSignatureAlgorithms
  710. }
  711. return c.config.GetClientCertificate(&CertificateRequestInfo{
  712. AcceptableCAs: certReq.certificateAuthorities,
  713. SignatureSchemes: signatureSchemes,
  714. })
  715. }
  716. // RFC 4346 on the certificateAuthorities field: A list of the
  717. // distinguished names of acceptable certificate authorities.
  718. // These distinguished names may specify a desired
  719. // distinguished name for a root CA or for a subordinate CA;
  720. // thus, this message can be used to describe both known roots
  721. // and a desired authorization space. If the
  722. // certificate_authorities list is empty then the client MAY
  723. // send any certificate of the appropriate
  724. // ClientCertificateType, unless there is some external
  725. // arrangement to the contrary.
  726. // We need to search our list of client certs for one
  727. // where SignatureAlgorithm is acceptable to the server and the
  728. // Issuer is in certReq.certificateAuthorities
  729. findCert:
  730. for i, chain := range c.config.Certificates {
  731. if !rsaAvail && !ecdsaAvail {
  732. continue
  733. }
  734. for j, cert := range chain.Certificate {
  735. x509Cert := chain.Leaf
  736. // parse the certificate if this isn't the leaf
  737. // node, or if chain.Leaf was nil
  738. if j != 0 || x509Cert == nil {
  739. var err error
  740. if x509Cert, err = x509.ParseCertificate(cert); err != nil {
  741. c.sendAlert(alertInternalError)
  742. return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
  743. }
  744. }
  745. switch {
  746. case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
  747. case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
  748. default:
  749. continue findCert
  750. }
  751. if len(certReq.certificateAuthorities) == 0 {
  752. // they gave us an empty list, so just take the
  753. // first cert from c.config.Certificates
  754. return &chain, nil
  755. }
  756. for _, ca := range certReq.certificateAuthorities {
  757. if bytes.Equal(x509Cert.RawIssuer, ca) {
  758. return &chain, nil
  759. }
  760. }
  761. }
  762. }
  763. // No acceptable certificate found. Don't send a certificate.
  764. return new(Certificate), nil
  765. }
  766. // clientSessionCacheKey returns a key used to cache sessionTickets that could
  767. // be used to resume previously negotiated TLS sessions with a server.
  768. func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
  769. if len(config.ServerName) > 0 {
  770. return config.ServerName
  771. }
  772. return serverAddr.String()
  773. }
  774. // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
  775. // given list of possible protocols and a list of the preference order. The
  776. // first list must not be empty. It returns the resulting protocol and flag
  777. // indicating if the fallback case was reached.
  778. func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
  779. for _, s := range preferenceProtos {
  780. for _, c := range protos {
  781. if s == c {
  782. return s, false
  783. }
  784. }
  785. }
  786. return protos[0], true
  787. }
  788. // hostnameInSNI converts name into an appropriate hostname for SNI.
  789. // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
  790. // See https://tools.ietf.org/html/rfc6066#section-3.
  791. func hostnameInSNI(name string) string {
  792. host := name
  793. if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
  794. host = host[1 : len(host)-1]
  795. }
  796. if i := strings.LastIndex(host, "%"); i > 0 {
  797. host = host[:i]
  798. }
  799. if net.ParseIP(host) != nil {
  800. return ""
  801. }
  802. for len(name) > 0 && name[len(name)-1] == '.' {
  803. name = name[:len(name)-1]
  804. }
  805. return name
  806. }