Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

handshake_client.go 24 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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
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>
pirms 9 gadiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  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(c.vers)
  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 occurred.
  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 && c.config.GetClientCertificate == nil) {
  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. if c.config.VerifyPeerCertificate != nil {
  273. if err := c.config.VerifyPeerCertificate(certMsg.certificates, c.verifiedChains); err != nil {
  274. c.sendAlert(alertBadCertificate)
  275. return err
  276. }
  277. }
  278. switch certs[0].PublicKey.(type) {
  279. case *rsa.PublicKey, *ecdsa.PublicKey:
  280. break
  281. default:
  282. c.sendAlert(alertUnsupportedCertificate)
  283. return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
  284. }
  285. c.peerCertificates = certs
  286. } else {
  287. // This is a renegotiation handshake. We require that the
  288. // server's identity (i.e. leaf certificate) is unchanged and
  289. // thus any previous trust decision is still valid.
  290. //
  291. // See https://mitls.org/pages/attacks/3SHAKE for the
  292. // motivation behind this requirement.
  293. if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
  294. c.sendAlert(alertBadCertificate)
  295. return errors.New("tls: server's identity changed during renegotiation")
  296. }
  297. }
  298. if hs.serverHello.ocspStapling {
  299. msg, err = c.readHandshake()
  300. if err != nil {
  301. return err
  302. }
  303. cs, ok := msg.(*certificateStatusMsg)
  304. if !ok {
  305. c.sendAlert(alertUnexpectedMessage)
  306. return unexpectedMessageError(cs, msg)
  307. }
  308. hs.finishedHash.Write(cs.marshal())
  309. if cs.statusType == statusTypeOCSP {
  310. c.ocspResponse = cs.response
  311. }
  312. }
  313. msg, err = c.readHandshake()
  314. if err != nil {
  315. return err
  316. }
  317. keyAgreement := hs.suite.ka(c.vers)
  318. skx, ok := msg.(*serverKeyExchangeMsg)
  319. if ok {
  320. hs.finishedHash.Write(skx.marshal())
  321. err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
  322. if err != nil {
  323. c.sendAlert(alertUnexpectedMessage)
  324. return err
  325. }
  326. msg, err = c.readHandshake()
  327. if err != nil {
  328. return err
  329. }
  330. }
  331. var chainToSend *Certificate
  332. var certRequested bool
  333. certReq, ok := msg.(*certificateRequestMsg)
  334. if ok {
  335. certRequested = true
  336. hs.finishedHash.Write(certReq.marshal())
  337. if chainToSend, err = hs.getCertificate(certReq); err != nil {
  338. c.sendAlert(alertInternalError)
  339. return err
  340. }
  341. msg, err = c.readHandshake()
  342. if err != nil {
  343. return err
  344. }
  345. }
  346. shd, ok := msg.(*serverHelloDoneMsg)
  347. if !ok {
  348. c.sendAlert(alertUnexpectedMessage)
  349. return unexpectedMessageError(shd, msg)
  350. }
  351. hs.finishedHash.Write(shd.marshal())
  352. // If the server requested a certificate then we have to send a
  353. // Certificate message, even if it's empty because we don't have a
  354. // certificate to send.
  355. if certRequested {
  356. certMsg = new(certificateMsg)
  357. certMsg.certificates = chainToSend.Certificate
  358. hs.finishedHash.Write(certMsg.marshal())
  359. if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
  360. return err
  361. }
  362. }
  363. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
  364. if err != nil {
  365. c.sendAlert(alertInternalError)
  366. return err
  367. }
  368. if ckx != nil {
  369. hs.finishedHash.Write(ckx.marshal())
  370. if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
  371. return err
  372. }
  373. }
  374. if chainToSend != nil && len(chainToSend.Certificate) > 0 {
  375. certVerify := &certificateVerifyMsg{
  376. hasSignatureAndHash: c.vers >= VersionTLS12,
  377. }
  378. key, ok := chainToSend.PrivateKey.(crypto.Signer)
  379. if !ok {
  380. c.sendAlert(alertInternalError)
  381. return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
  382. }
  383. var signatureType uint8
  384. switch key.Public().(type) {
  385. case *ecdsa.PublicKey:
  386. signatureType = signatureECDSA
  387. case *rsa.PublicKey:
  388. signatureType = signatureRSA
  389. default:
  390. c.sendAlert(alertInternalError)
  391. return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key)
  392. }
  393. certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureType)
  394. if err != nil {
  395. c.sendAlert(alertInternalError)
  396. return err
  397. }
  398. digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
  399. if err != nil {
  400. c.sendAlert(alertInternalError)
  401. return err
  402. }
  403. certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc)
  404. if err != nil {
  405. c.sendAlert(alertInternalError)
  406. return err
  407. }
  408. hs.finishedHash.Write(certVerify.marshal())
  409. if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
  410. return err
  411. }
  412. }
  413. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
  414. if err := c.config.writeKeyLog(hs.hello.random, hs.masterSecret); err != nil {
  415. c.sendAlert(alertInternalError)
  416. return errors.New("tls: failed to write to key log: " + err.Error())
  417. }
  418. hs.finishedHash.discardHandshakeBuffer()
  419. return nil
  420. }
  421. func (hs *clientHandshakeState) establishKeys() error {
  422. c := hs.c
  423. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  424. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  425. var clientCipher, serverCipher interface{}
  426. var clientHash, serverHash macFunction
  427. if hs.suite.cipher != nil {
  428. clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
  429. clientHash = hs.suite.mac(c.vers, clientMAC)
  430. serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
  431. serverHash = hs.suite.mac(c.vers, serverMAC)
  432. } else {
  433. clientCipher = hs.suite.aead(clientKey, clientIV)
  434. serverCipher = hs.suite.aead(serverKey, serverIV)
  435. }
  436. c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
  437. c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
  438. return nil
  439. }
  440. func (hs *clientHandshakeState) serverResumedSession() bool {
  441. // If the server responded with the same sessionId then it means the
  442. // sessionTicket is being used to resume a TLS session.
  443. return hs.session != nil && hs.hello.sessionId != nil &&
  444. bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
  445. }
  446. func (hs *clientHandshakeState) processServerHello() (bool, error) {
  447. c := hs.c
  448. if hs.serverHello.compressionMethod != compressionNone {
  449. c.sendAlert(alertUnexpectedMessage)
  450. return false, errors.New("tls: server selected unsupported compression format")
  451. }
  452. if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
  453. c.secureRenegotiation = true
  454. if len(hs.serverHello.secureRenegotiation) != 0 {
  455. c.sendAlert(alertHandshakeFailure)
  456. return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
  457. }
  458. }
  459. if c.handshakes > 0 && c.secureRenegotiation {
  460. var expectedSecureRenegotiation [24]byte
  461. copy(expectedSecureRenegotiation[:], c.clientFinished[:])
  462. copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
  463. if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
  464. c.sendAlert(alertHandshakeFailure)
  465. return false, errors.New("tls: incorrect renegotiation extension contents")
  466. }
  467. }
  468. clientDidNPN := hs.hello.nextProtoNeg
  469. clientDidALPN := len(hs.hello.alpnProtocols) > 0
  470. serverHasNPN := hs.serverHello.nextProtoNeg
  471. serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
  472. if !clientDidNPN && serverHasNPN {
  473. c.sendAlert(alertHandshakeFailure)
  474. return false, errors.New("tls: server advertised unrequested NPN extension")
  475. }
  476. if !clientDidALPN && serverHasALPN {
  477. c.sendAlert(alertHandshakeFailure)
  478. return false, errors.New("tls: server advertised unrequested ALPN extension")
  479. }
  480. if serverHasNPN && serverHasALPN {
  481. c.sendAlert(alertHandshakeFailure)
  482. return false, errors.New("tls: server advertised both NPN and ALPN extensions")
  483. }
  484. if serverHasALPN {
  485. c.clientProtocol = hs.serverHello.alpnProtocol
  486. c.clientProtocolFallback = false
  487. }
  488. c.scts = hs.serverHello.scts
  489. if !hs.serverResumedSession() {
  490. return false, nil
  491. }
  492. if hs.session.vers != c.vers {
  493. c.sendAlert(alertHandshakeFailure)
  494. return false, errors.New("tls: server resumed a session with a different version")
  495. }
  496. if hs.session.cipherSuite != hs.suite.id {
  497. c.sendAlert(alertHandshakeFailure)
  498. return false, errors.New("tls: server resumed a session with a different cipher suite")
  499. }
  500. // Restore masterSecret and peerCerts from previous state
  501. hs.masterSecret = hs.session.masterSecret
  502. c.peerCertificates = hs.session.serverCertificates
  503. c.verifiedChains = hs.session.verifiedChains
  504. return true, nil
  505. }
  506. func (hs *clientHandshakeState) readFinished(out []byte) error {
  507. c := hs.c
  508. c.readRecord(recordTypeChangeCipherSpec)
  509. if c.in.err != nil {
  510. return c.in.err
  511. }
  512. msg, err := c.readHandshake()
  513. if err != nil {
  514. return err
  515. }
  516. serverFinished, ok := msg.(*finishedMsg)
  517. if !ok {
  518. c.sendAlert(alertUnexpectedMessage)
  519. return unexpectedMessageError(serverFinished, msg)
  520. }
  521. verify := hs.finishedHash.serverSum(hs.masterSecret)
  522. if len(verify) != len(serverFinished.verifyData) ||
  523. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  524. c.sendAlert(alertHandshakeFailure)
  525. return errors.New("tls: server's Finished message was incorrect")
  526. }
  527. hs.finishedHash.Write(serverFinished.marshal())
  528. copy(out, verify)
  529. return nil
  530. }
  531. func (hs *clientHandshakeState) readSessionTicket() error {
  532. if !hs.serverHello.ticketSupported {
  533. return nil
  534. }
  535. c := hs.c
  536. msg, err := c.readHandshake()
  537. if err != nil {
  538. return err
  539. }
  540. sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
  541. if !ok {
  542. c.sendAlert(alertUnexpectedMessage)
  543. return unexpectedMessageError(sessionTicketMsg, msg)
  544. }
  545. hs.finishedHash.Write(sessionTicketMsg.marshal())
  546. hs.session = &ClientSessionState{
  547. sessionTicket: sessionTicketMsg.ticket,
  548. vers: c.vers,
  549. cipherSuite: hs.suite.id,
  550. masterSecret: hs.masterSecret,
  551. serverCertificates: c.peerCertificates,
  552. verifiedChains: c.verifiedChains,
  553. }
  554. return nil
  555. }
  556. func (hs *clientHandshakeState) sendFinished(out []byte) error {
  557. c := hs.c
  558. if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
  559. return err
  560. }
  561. if hs.serverHello.nextProtoNeg {
  562. nextProto := new(nextProtoMsg)
  563. proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
  564. nextProto.proto = proto
  565. c.clientProtocol = proto
  566. c.clientProtocolFallback = fallback
  567. hs.finishedHash.Write(nextProto.marshal())
  568. if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
  569. return err
  570. }
  571. }
  572. finished := new(finishedMsg)
  573. finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
  574. hs.finishedHash.Write(finished.marshal())
  575. if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
  576. return err
  577. }
  578. copy(out, finished.verifyData)
  579. return nil
  580. }
  581. // tls11SignatureSchemes contains the signature schemes that we synthesise for
  582. // a TLS <= 1.1 connection, based on the supported certificate types.
  583. var tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1}
  584. const (
  585. // tls11SignatureSchemesNumECDSA is the number of initial elements of
  586. // tls11SignatureSchemes that use ECDSA.
  587. tls11SignatureSchemesNumECDSA = 3
  588. // tls11SignatureSchemesNumRSA is the number of trailing elements of
  589. // tls11SignatureSchemes that use RSA.
  590. tls11SignatureSchemesNumRSA = 4
  591. )
  592. func (hs *clientHandshakeState) getCertificate(certReq *certificateRequestMsg) (*Certificate, error) {
  593. c := hs.c
  594. var rsaAvail, ecdsaAvail bool
  595. for _, certType := range certReq.certificateTypes {
  596. switch certType {
  597. case certTypeRSASign:
  598. rsaAvail = true
  599. case certTypeECDSASign:
  600. ecdsaAvail = true
  601. }
  602. }
  603. if c.config.GetClientCertificate != nil {
  604. var signatureSchemes []SignatureScheme
  605. if !certReq.hasSignatureAndHash {
  606. // Prior to TLS 1.2, the signature schemes were not
  607. // included in the certificate request message. In this
  608. // case we use a plausible list based on the acceptable
  609. // certificate types.
  610. signatureSchemes = tls11SignatureSchemes
  611. if !ecdsaAvail {
  612. signatureSchemes = signatureSchemes[tls11SignatureSchemesNumECDSA:]
  613. }
  614. if !rsaAvail {
  615. signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumRSA]
  616. }
  617. } else {
  618. signatureSchemes = make([]SignatureScheme, 0, len(certReq.signatureAndHashes))
  619. for _, sah := range certReq.signatureAndHashes {
  620. signatureSchemes = append(signatureSchemes, SignatureScheme(sah.hash)<<8+SignatureScheme(sah.signature))
  621. }
  622. }
  623. return c.config.GetClientCertificate(&CertificateRequestInfo{
  624. AcceptableCAs: certReq.certificateAuthorities,
  625. SignatureSchemes: signatureSchemes,
  626. })
  627. }
  628. // RFC 4346 on the certificateAuthorities field: A list of the
  629. // distinguished names of acceptable certificate authorities.
  630. // These distinguished names may specify a desired
  631. // distinguished name for a root CA or for a subordinate CA;
  632. // thus, this message can be used to describe both known roots
  633. // and a desired authorization space. If the
  634. // certificate_authorities list is empty then the client MAY
  635. // send any certificate of the appropriate
  636. // ClientCertificateType, unless there is some external
  637. // arrangement to the contrary.
  638. // We need to search our list of client certs for one
  639. // where SignatureAlgorithm is acceptable to the server and the
  640. // Issuer is in certReq.certificateAuthorities
  641. findCert:
  642. for i, chain := range c.config.Certificates {
  643. if !rsaAvail && !ecdsaAvail {
  644. continue
  645. }
  646. for j, cert := range chain.Certificate {
  647. x509Cert := chain.Leaf
  648. // parse the certificate if this isn't the leaf
  649. // node, or if chain.Leaf was nil
  650. if j != 0 || x509Cert == nil {
  651. var err error
  652. if x509Cert, err = x509.ParseCertificate(cert); err != nil {
  653. c.sendAlert(alertInternalError)
  654. return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
  655. }
  656. }
  657. switch {
  658. case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
  659. case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
  660. default:
  661. continue findCert
  662. }
  663. if len(certReq.certificateAuthorities) == 0 {
  664. // they gave us an empty list, so just take the
  665. // first cert from c.config.Certificates
  666. return &chain, nil
  667. }
  668. for _, ca := range certReq.certificateAuthorities {
  669. if bytes.Equal(x509Cert.RawIssuer, ca) {
  670. return &chain, nil
  671. }
  672. }
  673. }
  674. }
  675. // No acceptable certificate found. Don't send a certificate.
  676. return new(Certificate), nil
  677. }
  678. // clientSessionCacheKey returns a key used to cache sessionTickets that could
  679. // be used to resume previously negotiated TLS sessions with a server.
  680. func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
  681. if len(config.ServerName) > 0 {
  682. return config.ServerName
  683. }
  684. return serverAddr.String()
  685. }
  686. // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
  687. // given list of possible protocols and a list of the preference order. The
  688. // first list must not be empty. It returns the resulting protocol and flag
  689. // indicating if the fallback case was reached.
  690. func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
  691. for _, s := range preferenceProtos {
  692. for _, c := range protos {
  693. if s == c {
  694. return s, false
  695. }
  696. }
  697. }
  698. return protos[0], true
  699. }
  700. // hostnameInSNI converts name into an approriate hostname for SNI.
  701. // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
  702. // See https://tools.ietf.org/html/rfc6066#section-3.
  703. func hostnameInSNI(name string) string {
  704. host := name
  705. if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
  706. host = host[1 : len(host)-1]
  707. }
  708. if i := strings.LastIndex(host, "%"); i > 0 {
  709. host = host[:i]
  710. }
  711. if net.ParseIP(host) != nil {
  712. return ""
  713. }
  714. for len(name) > 0 && name[len(name)-1] == '.' {
  715. name = name[:len(name)-1]
  716. }
  717. return name
  718. }