Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  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. )
  19. type clientHandshakeState struct {
  20. c *Conn
  21. serverHello *serverHelloMsg
  22. hello *clientHelloMsg
  23. suite *cipherSuite
  24. finishedHash finishedHash
  25. masterSecret []byte
  26. session *ClientSessionState
  27. }
  28. // c.out.Mutex <= L; c.handshakeMutex <= L.
  29. func (c *Conn) clientHandshake() error {
  30. if c.config == nil {
  31. c.config = defaultConfig()
  32. }
  33. // This may be a renegotiation handshake, in which case some fields
  34. // need to be reset.
  35. c.didResume = false
  36. if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
  37. return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
  38. }
  39. nextProtosLength := 0
  40. for _, proto := range c.config.NextProtos {
  41. if l := len(proto); l == 0 || l > 255 {
  42. return errors.New("tls: invalid NextProtos value")
  43. } else {
  44. nextProtosLength += 1 + l
  45. }
  46. }
  47. if nextProtosLength > 0xffff {
  48. return errors.New("tls: NextProtos values too large")
  49. }
  50. hello := &clientHelloMsg{
  51. vers: c.config.maxVersion(),
  52. compressionMethods: []uint8{compressionNone},
  53. random: make([]byte, 32),
  54. ocspStapling: true,
  55. scts: true,
  56. serverName: hostnameInSNI(c.config.ServerName),
  57. supportedCurves: c.config.curvePreferences(),
  58. supportedPoints: []uint8{pointFormatUncompressed},
  59. nextProtoNeg: len(c.config.NextProtos) > 0,
  60. secureRenegotiationSupported: true,
  61. alpnProtocols: c.config.NextProtos,
  62. }
  63. if c.handshakes > 0 {
  64. hello.secureRenegotiation = c.clientFinished[:]
  65. }
  66. possibleCipherSuites := c.config.cipherSuites()
  67. hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
  68. NextCipherSuite:
  69. for _, suiteId := range possibleCipherSuites {
  70. for _, suite := range cipherSuites {
  71. if suite.id != suiteId {
  72. continue
  73. }
  74. // Don't advertise TLS 1.2-only cipher suites unless
  75. // we're attempting TLS 1.2.
  76. if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
  77. continue
  78. }
  79. hello.cipherSuites = append(hello.cipherSuites, suiteId)
  80. continue NextCipherSuite
  81. }
  82. }
  83. _, err := io.ReadFull(c.config.rand(), hello.random)
  84. if err != nil {
  85. c.sendAlert(alertInternalError)
  86. return errors.New("tls: short read from Rand: " + err.Error())
  87. }
  88. if hello.vers >= VersionTLS12 {
  89. hello.signatureAndHashes = supportedSignatureAlgorithms
  90. }
  91. var session *ClientSessionState
  92. var cacheKey string
  93. sessionCache := c.config.ClientSessionCache
  94. if c.config.SessionTicketsDisabled {
  95. sessionCache = nil
  96. }
  97. if sessionCache != nil {
  98. hello.ticketSupported = true
  99. }
  100. // Session resumption is not allowed if renegotiating because
  101. // renegotiation is primarily used to allow a client to send a client
  102. // certificate, which would be skipped if session resumption occured.
  103. if sessionCache != nil && c.handshakes == 0 {
  104. // Try to resume a previously negotiated TLS session, if
  105. // available.
  106. cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
  107. candidateSession, ok := sessionCache.Get(cacheKey)
  108. if ok {
  109. // Check that the ciphersuite/version used for the
  110. // previous session are still valid.
  111. cipherSuiteOk := false
  112. for _, id := range hello.cipherSuites {
  113. if id == candidateSession.cipherSuite {
  114. cipherSuiteOk = true
  115. break
  116. }
  117. }
  118. versOk := candidateSession.vers >= c.config.minVersion() &&
  119. candidateSession.vers <= c.config.maxVersion()
  120. if versOk && cipherSuiteOk {
  121. session = candidateSession
  122. }
  123. }
  124. }
  125. if session != nil {
  126. hello.sessionTicket = session.sessionTicket
  127. // A random session ID is used to detect when the
  128. // server accepted the ticket and is resuming a session
  129. // (see RFC 5077).
  130. hello.sessionId = make([]byte, 16)
  131. if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
  132. c.sendAlert(alertInternalError)
  133. return errors.New("tls: short read from Rand: " + err.Error())
  134. }
  135. }
  136. if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil {
  137. return err
  138. }
  139. msg, err := c.readHandshake()
  140. if err != nil {
  141. return err
  142. }
  143. serverHello, ok := msg.(*serverHelloMsg)
  144. if !ok {
  145. c.sendAlert(alertUnexpectedMessage)
  146. return unexpectedMessageError(serverHello, msg)
  147. }
  148. vers, ok := c.config.mutualVersion(serverHello.vers)
  149. if !ok || vers < VersionTLS10 {
  150. // TLS 1.0 is the minimum version supported as a client.
  151. c.sendAlert(alertProtocolVersion)
  152. return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers)
  153. }
  154. c.vers = vers
  155. c.haveVers = true
  156. suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite)
  157. if suite == nil {
  158. c.sendAlert(alertHandshakeFailure)
  159. return errors.New("tls: server chose an unconfigured cipher suite")
  160. }
  161. hs := &clientHandshakeState{
  162. c: c,
  163. serverHello: serverHello,
  164. hello: hello,
  165. suite: suite,
  166. finishedHash: newFinishedHash(c.vers, suite),
  167. session: session,
  168. }
  169. isResume, err := hs.processServerHello()
  170. if err != nil {
  171. return err
  172. }
  173. // No signatures of the handshake are needed in a resumption.
  174. // Otherwise, in a full handshake, if we don't have any certificates
  175. // configured then we will never send a CertificateVerify message and
  176. // thus no signatures are needed in that case either.
  177. if isResume || len(c.config.Certificates) == 0 {
  178. hs.finishedHash.discardHandshakeBuffer()
  179. }
  180. hs.finishedHash.Write(hs.hello.marshal())
  181. hs.finishedHash.Write(hs.serverHello.marshal())
  182. c.buffering = true
  183. if isResume {
  184. if err := hs.establishKeys(); err != nil {
  185. return err
  186. }
  187. if err := hs.readSessionTicket(); err != nil {
  188. return err
  189. }
  190. if err := hs.readFinished(c.serverFinished[:]); err != nil {
  191. return err
  192. }
  193. c.clientFinishedIsFirst = false
  194. if err := hs.sendFinished(c.clientFinished[:]); err != nil {
  195. return err
  196. }
  197. if _, err := c.flush(); err != nil {
  198. return err
  199. }
  200. } else {
  201. if err := hs.doFullHandshake(); err != nil {
  202. return err
  203. }
  204. if err := hs.establishKeys(); err != nil {
  205. return err
  206. }
  207. if err := hs.sendFinished(c.clientFinished[:]); err != nil {
  208. return err
  209. }
  210. if _, err := c.flush(); err != nil {
  211. return err
  212. }
  213. c.clientFinishedIsFirst = true
  214. if err := hs.readSessionTicket(); err != nil {
  215. return err
  216. }
  217. if err := hs.readFinished(c.serverFinished[:]); err != nil {
  218. return err
  219. }
  220. }
  221. if sessionCache != nil && hs.session != nil && session != hs.session {
  222. sessionCache.Put(cacheKey, hs.session)
  223. }
  224. c.didResume = isResume
  225. c.handshakeComplete = true
  226. c.cipherSuite = suite.id
  227. return nil
  228. }
  229. func (hs *clientHandshakeState) doFullHandshake() error {
  230. c := hs.c
  231. msg, err := c.readHandshake()
  232. if err != nil {
  233. return err
  234. }
  235. certMsg, ok := msg.(*certificateMsg)
  236. if !ok || len(certMsg.certificates) == 0 {
  237. c.sendAlert(alertUnexpectedMessage)
  238. return unexpectedMessageError(certMsg, msg)
  239. }
  240. hs.finishedHash.Write(certMsg.marshal())
  241. if c.handshakes == 0 {
  242. // If this is the first handshake on a connection, process and
  243. // (optionally) verify the server's certificates.
  244. certs := make([]*x509.Certificate, len(certMsg.certificates))
  245. for i, asn1Data := range certMsg.certificates {
  246. cert, err := x509.ParseCertificate(asn1Data)
  247. if err != nil {
  248. c.sendAlert(alertBadCertificate)
  249. return errors.New("tls: failed to parse certificate from server: " + err.Error())
  250. }
  251. certs[i] = cert
  252. }
  253. if !c.config.InsecureSkipVerify {
  254. opts := x509.VerifyOptions{
  255. Roots: c.config.RootCAs,
  256. CurrentTime: c.config.time(),
  257. DNSName: c.config.ServerName,
  258. Intermediates: x509.NewCertPool(),
  259. }
  260. for i, cert := range certs {
  261. if i == 0 {
  262. continue
  263. }
  264. opts.Intermediates.AddCert(cert)
  265. }
  266. c.verifiedChains, err = certs[0].Verify(opts)
  267. if err != nil {
  268. c.sendAlert(alertBadCertificate)
  269. return err
  270. }
  271. }
  272. switch certs[0].PublicKey.(type) {
  273. case *rsa.PublicKey, *ecdsa.PublicKey:
  274. break
  275. default:
  276. c.sendAlert(alertUnsupportedCertificate)
  277. return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
  278. }
  279. c.peerCertificates = certs
  280. } else {
  281. // This is a renegotiation handshake. We require that the
  282. // server's identity (i.e. leaf certificate) is unchanged and
  283. // thus any previous trust decision is still valid.
  284. //
  285. // See https://mitls.org/pages/attacks/3SHAKE for the
  286. // motivation behind this requirement.
  287. if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
  288. c.sendAlert(alertBadCertificate)
  289. return errors.New("tls: server's identity changed during renegotiation")
  290. }
  291. }
  292. if hs.serverHello.ocspStapling {
  293. msg, err = c.readHandshake()
  294. if err != nil {
  295. return err
  296. }
  297. cs, ok := msg.(*certificateStatusMsg)
  298. if !ok {
  299. c.sendAlert(alertUnexpectedMessage)
  300. return unexpectedMessageError(cs, msg)
  301. }
  302. hs.finishedHash.Write(cs.marshal())
  303. if cs.statusType == statusTypeOCSP {
  304. c.ocspResponse = cs.response
  305. }
  306. }
  307. msg, err = c.readHandshake()
  308. if err != nil {
  309. return err
  310. }
  311. keyAgreement := hs.suite.ka(c.vers)
  312. skx, ok := msg.(*serverKeyExchangeMsg)
  313. if ok {
  314. hs.finishedHash.Write(skx.marshal())
  315. err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
  316. if err != nil {
  317. c.sendAlert(alertUnexpectedMessage)
  318. return err
  319. }
  320. msg, err = c.readHandshake()
  321. if err != nil {
  322. return err
  323. }
  324. }
  325. var chainToSend *Certificate
  326. var certRequested bool
  327. certReq, ok := msg.(*certificateRequestMsg)
  328. if ok {
  329. certRequested = true
  330. // RFC 4346 on the certificateAuthorities field:
  331. // A list of the distinguished names of acceptable certificate
  332. // authorities. These distinguished names may specify a desired
  333. // distinguished name for a root CA or for a subordinate CA;
  334. // thus, this message can be used to describe both known roots
  335. // and a desired authorization space. If the
  336. // certificate_authorities list is empty then the client MAY
  337. // send any certificate of the appropriate
  338. // ClientCertificateType, unless there is some external
  339. // arrangement to the contrary.
  340. hs.finishedHash.Write(certReq.marshal())
  341. var rsaAvail, ecdsaAvail bool
  342. for _, certType := range certReq.certificateTypes {
  343. switch certType {
  344. case certTypeRSASign:
  345. rsaAvail = true
  346. case certTypeECDSASign:
  347. ecdsaAvail = true
  348. }
  349. }
  350. // We need to search our list of client certs for one
  351. // where SignatureAlgorithm is acceptable to the server and the
  352. // Issuer is in certReq.certificateAuthorities
  353. findCert:
  354. for i, chain := range c.config.Certificates {
  355. if !rsaAvail && !ecdsaAvail {
  356. continue
  357. }
  358. for j, cert := range chain.Certificate {
  359. x509Cert := chain.Leaf
  360. // parse the certificate if this isn't the leaf
  361. // node, or if chain.Leaf was nil
  362. if j != 0 || x509Cert == nil {
  363. if x509Cert, err = x509.ParseCertificate(cert); err != nil {
  364. c.sendAlert(alertInternalError)
  365. return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
  366. }
  367. }
  368. switch {
  369. case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
  370. case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
  371. default:
  372. continue findCert
  373. }
  374. if len(certReq.certificateAuthorities) == 0 {
  375. // they gave us an empty list, so just take the
  376. // first cert from c.config.Certificates
  377. chainToSend = &chain
  378. break findCert
  379. }
  380. for _, ca := range certReq.certificateAuthorities {
  381. if bytes.Equal(x509Cert.RawIssuer, ca) {
  382. chainToSend = &chain
  383. break findCert
  384. }
  385. }
  386. }
  387. }
  388. msg, err = c.readHandshake()
  389. if err != nil {
  390. return err
  391. }
  392. }
  393. shd, ok := msg.(*serverHelloDoneMsg)
  394. if !ok {
  395. c.sendAlert(alertUnexpectedMessage)
  396. return unexpectedMessageError(shd, msg)
  397. }
  398. hs.finishedHash.Write(shd.marshal())
  399. // If the server requested a certificate then we have to send a
  400. // Certificate message, even if it's empty because we don't have a
  401. // certificate to send.
  402. if certRequested {
  403. certMsg = new(certificateMsg)
  404. if chainToSend != nil {
  405. certMsg.certificates = chainToSend.Certificate
  406. }
  407. hs.finishedHash.Write(certMsg.marshal())
  408. if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
  409. return err
  410. }
  411. }
  412. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
  413. if err != nil {
  414. c.sendAlert(alertInternalError)
  415. return err
  416. }
  417. if ckx != nil {
  418. hs.finishedHash.Write(ckx.marshal())
  419. if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
  420. return err
  421. }
  422. }
  423. if chainToSend != nil {
  424. certVerify := &certificateVerifyMsg{
  425. hasSignatureAndHash: c.vers >= VersionTLS12,
  426. }
  427. key, ok := chainToSend.PrivateKey.(crypto.Signer)
  428. if !ok {
  429. c.sendAlert(alertInternalError)
  430. return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
  431. }
  432. var signatureType uint8
  433. switch key.Public().(type) {
  434. case *ecdsa.PublicKey:
  435. signatureType = signatureECDSA
  436. case *rsa.PublicKey:
  437. signatureType = signatureRSA
  438. default:
  439. c.sendAlert(alertInternalError)
  440. return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key)
  441. }
  442. certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureType)
  443. if err != nil {
  444. c.sendAlert(alertInternalError)
  445. return err
  446. }
  447. digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
  448. if err != nil {
  449. c.sendAlert(alertInternalError)
  450. return err
  451. }
  452. certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc)
  453. if err != nil {
  454. c.sendAlert(alertInternalError)
  455. return err
  456. }
  457. hs.finishedHash.Write(certVerify.marshal())
  458. if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
  459. return err
  460. }
  461. }
  462. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
  463. if err := c.config.writeKeyLog(hs.hello.random, hs.masterSecret); err != nil {
  464. c.sendAlert(alertInternalError)
  465. return errors.New("tls: failed to write to key log: " + err.Error())
  466. }
  467. hs.finishedHash.discardHandshakeBuffer()
  468. return nil
  469. }
  470. func (hs *clientHandshakeState) establishKeys() error {
  471. c := hs.c
  472. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  473. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  474. var clientCipher, serverCipher interface{}
  475. var clientHash, serverHash macFunction
  476. if hs.suite.cipher != nil {
  477. clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
  478. clientHash = hs.suite.mac(c.vers, clientMAC)
  479. serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
  480. serverHash = hs.suite.mac(c.vers, serverMAC)
  481. } else {
  482. clientCipher = hs.suite.aead(clientKey, clientIV)
  483. serverCipher = hs.suite.aead(serverKey, serverIV)
  484. }
  485. c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
  486. c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
  487. return nil
  488. }
  489. func (hs *clientHandshakeState) serverResumedSession() bool {
  490. // If the server responded with the same sessionId then it means the
  491. // sessionTicket is being used to resume a TLS session.
  492. return hs.session != nil && hs.hello.sessionId != nil &&
  493. bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
  494. }
  495. func (hs *clientHandshakeState) processServerHello() (bool, error) {
  496. c := hs.c
  497. if hs.serverHello.compressionMethod != compressionNone {
  498. c.sendAlert(alertUnexpectedMessage)
  499. return false, errors.New("tls: server selected unsupported compression format")
  500. }
  501. if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
  502. c.secureRenegotiation = true
  503. if len(hs.serverHello.secureRenegotiation) != 0 {
  504. c.sendAlert(alertHandshakeFailure)
  505. return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
  506. }
  507. }
  508. if c.handshakes > 0 && c.secureRenegotiation {
  509. var expectedSecureRenegotiation [24]byte
  510. copy(expectedSecureRenegotiation[:], c.clientFinished[:])
  511. copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
  512. if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
  513. c.sendAlert(alertHandshakeFailure)
  514. return false, errors.New("tls: incorrect renegotiation extension contents")
  515. }
  516. }
  517. clientDidNPN := hs.hello.nextProtoNeg
  518. clientDidALPN := len(hs.hello.alpnProtocols) > 0
  519. serverHasNPN := hs.serverHello.nextProtoNeg
  520. serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
  521. if !clientDidNPN && serverHasNPN {
  522. c.sendAlert(alertHandshakeFailure)
  523. return false, errors.New("tls: server advertised unrequested NPN extension")
  524. }
  525. if !clientDidALPN && serverHasALPN {
  526. c.sendAlert(alertHandshakeFailure)
  527. return false, errors.New("tls: server advertised unrequested ALPN extension")
  528. }
  529. if serverHasNPN && serverHasALPN {
  530. c.sendAlert(alertHandshakeFailure)
  531. return false, errors.New("tls: server advertised both NPN and ALPN extensions")
  532. }
  533. if serverHasALPN {
  534. c.clientProtocol = hs.serverHello.alpnProtocol
  535. c.clientProtocolFallback = false
  536. }
  537. c.scts = hs.serverHello.scts
  538. if !hs.serverResumedSession() {
  539. return false, nil
  540. }
  541. if hs.session.vers != c.vers {
  542. c.sendAlert(alertHandshakeFailure)
  543. return false, errors.New("tls: server resumed a session with a different version")
  544. }
  545. if hs.session.cipherSuite != hs.suite.id {
  546. c.sendAlert(alertHandshakeFailure)
  547. return false, errors.New("tls: server resumed a session with a different cipher suite")
  548. }
  549. // Restore masterSecret and peerCerts from previous state
  550. hs.masterSecret = hs.session.masterSecret
  551. c.peerCertificates = hs.session.serverCertificates
  552. c.verifiedChains = hs.session.verifiedChains
  553. return true, nil
  554. }
  555. func (hs *clientHandshakeState) readFinished(out []byte) error {
  556. c := hs.c
  557. c.readRecord(recordTypeChangeCipherSpec)
  558. if c.in.err != nil {
  559. return c.in.err
  560. }
  561. msg, err := c.readHandshake()
  562. if err != nil {
  563. return err
  564. }
  565. serverFinished, ok := msg.(*finishedMsg)
  566. if !ok {
  567. c.sendAlert(alertUnexpectedMessage)
  568. return unexpectedMessageError(serverFinished, msg)
  569. }
  570. verify := hs.finishedHash.serverSum(hs.masterSecret)
  571. if len(verify) != len(serverFinished.verifyData) ||
  572. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  573. c.sendAlert(alertHandshakeFailure)
  574. return errors.New("tls: server's Finished message was incorrect")
  575. }
  576. hs.finishedHash.Write(serverFinished.marshal())
  577. copy(out, verify)
  578. return nil
  579. }
  580. func (hs *clientHandshakeState) readSessionTicket() error {
  581. if !hs.serverHello.ticketSupported {
  582. return nil
  583. }
  584. c := hs.c
  585. msg, err := c.readHandshake()
  586. if err != nil {
  587. return err
  588. }
  589. sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
  590. if !ok {
  591. c.sendAlert(alertUnexpectedMessage)
  592. return unexpectedMessageError(sessionTicketMsg, msg)
  593. }
  594. hs.finishedHash.Write(sessionTicketMsg.marshal())
  595. hs.session = &ClientSessionState{
  596. sessionTicket: sessionTicketMsg.ticket,
  597. vers: c.vers,
  598. cipherSuite: hs.suite.id,
  599. masterSecret: hs.masterSecret,
  600. serverCertificates: c.peerCertificates,
  601. verifiedChains: c.verifiedChains,
  602. }
  603. return nil
  604. }
  605. func (hs *clientHandshakeState) sendFinished(out []byte) error {
  606. c := hs.c
  607. if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
  608. return err
  609. }
  610. if hs.serverHello.nextProtoNeg {
  611. nextProto := new(nextProtoMsg)
  612. proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
  613. nextProto.proto = proto
  614. c.clientProtocol = proto
  615. c.clientProtocolFallback = fallback
  616. hs.finishedHash.Write(nextProto.marshal())
  617. if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
  618. return err
  619. }
  620. }
  621. finished := new(finishedMsg)
  622. finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
  623. hs.finishedHash.Write(finished.marshal())
  624. if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
  625. return err
  626. }
  627. copy(out, finished.verifyData)
  628. return nil
  629. }
  630. // clientSessionCacheKey returns a key used to cache sessionTickets that could
  631. // be used to resume previously negotiated TLS sessions with a server.
  632. func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
  633. if len(config.ServerName) > 0 {
  634. return config.ServerName
  635. }
  636. return serverAddr.String()
  637. }
  638. // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
  639. // given list of possible protocols and a list of the preference order. The
  640. // first list must not be empty. It returns the resulting protocol and flag
  641. // indicating if the fallback case was reached.
  642. func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
  643. for _, s := range preferenceProtos {
  644. for _, c := range protos {
  645. if s == c {
  646. return s, false
  647. }
  648. }
  649. }
  650. return protos[0], true
  651. }
  652. // hostnameInSNI converts name into an approriate hostname for SNI.
  653. // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
  654. // See https://tools.ietf.org/html/rfc6066#section-3.
  655. func hostnameInSNI(name string) string {
  656. host := name
  657. if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
  658. host = host[1 : len(host)-1]
  659. }
  660. if i := strings.LastIndex(host, "%"); i > 0 {
  661. host = host[:i]
  662. }
  663. if net.ParseIP(host) != nil {
  664. return ""
  665. }
  666. if len(name) > 0 && name[len(name)-1] == '.' {
  667. name = name[:len(name)-1]
  668. }
  669. return name
  670. }