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

handshake_server.go 26 KiB

8 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
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 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  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. "crypto"
  7. "crypto/ecdsa"
  8. "crypto/rsa"
  9. "crypto/subtle"
  10. "crypto/x509"
  11. "encoding/asn1"
  12. "errors"
  13. "fmt"
  14. "hash"
  15. "io"
  16. "sync/atomic"
  17. )
  18. type Committer interface {
  19. Commit() error
  20. }
  21. // serverHandshakeState contains details of a server handshake in progress.
  22. // It's discarded once the handshake has completed.
  23. type serverHandshakeState struct {
  24. c *Conn
  25. suite *cipherSuite
  26. masterSecret []byte
  27. cachedClientHelloInfo *ClientHelloInfo
  28. clientHello *clientHelloMsg
  29. cert *Certificate
  30. // TLS 1.0-1.2 fields
  31. hello *serverHelloMsg
  32. ellipticOk bool
  33. ecdsaOk bool
  34. rsaDecryptOk bool
  35. rsaSignOk bool
  36. sessionState *sessionState
  37. finishedHash finishedHash
  38. certsFromClient [][]byte
  39. // TLS 1.3 fields
  40. hello13 *serverHelloMsg13
  41. hello13Enc *encryptedExtensionsMsg
  42. finishedHash13 hash.Hash
  43. clientFinishedKey []byte
  44. hsClientCipher interface{}
  45. appClientCipher interface{}
  46. }
  47. // serverHandshake performs a TLS handshake as a server.
  48. // c.out.Mutex <= L; c.handshakeMutex <= L.
  49. func (c *Conn) serverHandshake() error {
  50. // If this is the first server handshake, we generate a random key to
  51. // encrypt the tickets with.
  52. c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) })
  53. hs := serverHandshakeState{
  54. c: c,
  55. }
  56. c.in.traceErr = hs.traceErr
  57. c.out.traceErr = hs.traceErr
  58. isResume, err := hs.readClientHello()
  59. if err != nil {
  60. return err
  61. }
  62. // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
  63. // and https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-2
  64. c.buffering = true
  65. if hs.hello13 != nil {
  66. if err := hs.doTLS13Handshake(); err != nil {
  67. return err
  68. }
  69. if _, err := c.flush(); err != nil {
  70. return err
  71. }
  72. c.hs = &hs
  73. c.handshakeComplete = true
  74. return nil
  75. } else if isResume {
  76. // The client has included a session ticket and so we do an abbreviated handshake.
  77. if err := hs.doResumeHandshake(); err != nil {
  78. return err
  79. }
  80. if err := hs.establishKeys(); err != nil {
  81. return err
  82. }
  83. // ticketSupported is set in a resumption handshake if the
  84. // ticket from the client was encrypted with an old session
  85. // ticket key and thus a refreshed ticket should be sent.
  86. if hs.hello.ticketSupported {
  87. if err := hs.sendSessionTicket(); err != nil {
  88. return err
  89. }
  90. }
  91. if err := hs.sendFinished(c.serverFinished[:]); err != nil {
  92. return err
  93. }
  94. if _, err := c.flush(); err != nil {
  95. return err
  96. }
  97. c.clientFinishedIsFirst = false
  98. if err := hs.readFinished(nil); err != nil {
  99. return err
  100. }
  101. c.didResume = true
  102. } else {
  103. // The client didn't include a session ticket, or it wasn't
  104. // valid so we do a full handshake.
  105. if err := hs.doFullHandshake(); err != nil {
  106. return err
  107. }
  108. if err := hs.establishKeys(); err != nil {
  109. return err
  110. }
  111. if err := hs.readFinished(c.clientFinished[:]); err != nil {
  112. return err
  113. }
  114. c.clientFinishedIsFirst = true
  115. c.buffering = true
  116. if err := hs.sendSessionTicket(); err != nil {
  117. return err
  118. }
  119. if err := hs.sendFinished(nil); err != nil {
  120. return err
  121. }
  122. if _, err := c.flush(); err != nil {
  123. return err
  124. }
  125. }
  126. c.phase = handshakeConfirmed
  127. atomic.StoreInt32(&c.handshakeConfirmed, 1)
  128. c.handshakeComplete = true
  129. return nil
  130. }
  131. // readClientHello reads a ClientHello message from the client and decides
  132. // whether we will perform session resumption.
  133. func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
  134. c := hs.c
  135. msg, err := c.readHandshake()
  136. if err != nil {
  137. return false, err
  138. }
  139. var ok bool
  140. hs.clientHello, ok = msg.(*clientHelloMsg)
  141. if !ok {
  142. c.sendAlert(alertUnexpectedMessage)
  143. return false, unexpectedMessageError(hs.clientHello, msg)
  144. }
  145. if c.config.GetConfigForClient != nil {
  146. if newConfig, err := c.config.GetConfigForClient(hs.clientHelloInfo()); err != nil {
  147. c.sendAlert(alertInternalError)
  148. return false, err
  149. } else if newConfig != nil {
  150. newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) })
  151. c.config = newConfig
  152. }
  153. }
  154. var keyShares []CurveID
  155. for _, ks := range hs.clientHello.keyShares {
  156. keyShares = append(keyShares, ks.group)
  157. }
  158. if hs.clientHello.supportedVersions != nil {
  159. for _, v := range hs.clientHello.supportedVersions {
  160. if (v >= c.config.minVersion() && v <= c.config.maxVersion()) ||
  161. v == VersionTLS13Draft18 {
  162. c.vers = v
  163. break
  164. }
  165. }
  166. if c.vers == 0 {
  167. c.sendAlert(alertProtocolVersion)
  168. return false, fmt.Errorf("tls: none of the client versions (%x) are supported", hs.clientHello.supportedVersions)
  169. }
  170. } else {
  171. c.vers, ok = c.config.mutualVersion(hs.clientHello.vers)
  172. if !ok {
  173. c.sendAlert(alertProtocolVersion)
  174. return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
  175. }
  176. }
  177. c.haveVers = true
  178. supportedCurve := false
  179. preferredCurves := c.config.curvePreferences()
  180. Curves:
  181. for _, curve := range hs.clientHello.supportedCurves {
  182. for _, supported := range preferredCurves {
  183. if supported == curve {
  184. supportedCurve = true
  185. break Curves
  186. }
  187. }
  188. }
  189. supportedPointFormat := false
  190. for _, pointFormat := range hs.clientHello.supportedPoints {
  191. if pointFormat == pointFormatUncompressed {
  192. supportedPointFormat = true
  193. break
  194. }
  195. }
  196. // TLS 1.3 has removed point format negotiation.
  197. supportedPointFormat = supportedPointFormat || c.vers >= VersionTLS13
  198. hs.ellipticOk = supportedCurve && supportedPointFormat
  199. foundCompression := false
  200. // We only support null compression, so check that the client offered it.
  201. for _, compression := range hs.clientHello.compressionMethods {
  202. if compression == compressionNone {
  203. foundCompression = true
  204. break
  205. }
  206. }
  207. if !foundCompression {
  208. c.sendAlert(alertHandshakeFailure)
  209. return false, errors.New("tls: client does not support uncompressed connections")
  210. }
  211. if len(hs.clientHello.compressionMethods) != 1 && c.vers >= VersionTLS13 {
  212. c.sendAlert(alertIllegalParameter)
  213. return false, errors.New("tls: 1.3 client offered compression")
  214. }
  215. if len(hs.clientHello.secureRenegotiation) != 0 {
  216. c.sendAlert(alertHandshakeFailure)
  217. return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
  218. }
  219. if c.vers < VersionTLS13 {
  220. hs.hello = new(serverHelloMsg)
  221. hs.hello.vers = c.vers
  222. hs.hello.random = make([]byte, 32)
  223. _, err = io.ReadFull(c.config.rand(), hs.hello.random)
  224. if err != nil {
  225. c.sendAlert(alertInternalError)
  226. return false, err
  227. }
  228. hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
  229. hs.hello.compressionMethod = compressionNone
  230. } else {
  231. hs.hello13 = new(serverHelloMsg13)
  232. hs.hello13Enc = new(encryptedExtensionsMsg)
  233. hs.hello13.vers = c.vers
  234. hs.hello13.random = make([]byte, 32)
  235. _, err = io.ReadFull(c.config.rand(), hs.hello13.random)
  236. if err != nil {
  237. c.sendAlert(alertInternalError)
  238. return false, err
  239. }
  240. }
  241. if len(hs.clientHello.serverName) > 0 {
  242. c.serverName = hs.clientHello.serverName
  243. }
  244. if len(hs.clientHello.alpnProtocols) > 0 {
  245. if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
  246. if hs.hello != nil {
  247. hs.hello.alpnProtocol = selectedProto
  248. } else {
  249. hs.hello13Enc.alpnProtocol = selectedProto
  250. }
  251. c.clientProtocol = selectedProto
  252. }
  253. } else {
  254. // Although sending an empty NPN extension is reasonable, Firefox has
  255. // had a bug around this. Best to send nothing at all if
  256. // c.config.NextProtos is empty. See
  257. // https://golang.org/issue/5445.
  258. if hs.clientHello.nextProtoNeg && len(c.config.NextProtos) > 0 && c.vers < VersionTLS13 {
  259. hs.hello.nextProtoNeg = true
  260. hs.hello.nextProtos = c.config.NextProtos
  261. }
  262. }
  263. hs.cert, err = c.config.getCertificate(hs.clientHelloInfo())
  264. if err != nil {
  265. c.out.traceErr, c.in.traceErr = nil, nil // disable tracing
  266. c.sendAlert(alertInternalError)
  267. return false, err
  268. }
  269. if hs.clientHello.scts && hs.hello != nil { // TODO: TLS 1.3 SCTs
  270. hs.hello.scts = hs.cert.SignedCertificateTimestamps
  271. }
  272. if committer, ok := c.conn.(Committer); ok { // TODO: probably committing too early
  273. err = committer.Commit()
  274. if err != nil {
  275. return false, err
  276. }
  277. }
  278. if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
  279. switch priv.Public().(type) {
  280. case *ecdsa.PublicKey:
  281. hs.ecdsaOk = true
  282. case *rsa.PublicKey:
  283. hs.rsaSignOk = true
  284. default:
  285. c.sendAlert(alertInternalError)
  286. return false, fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
  287. }
  288. }
  289. if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
  290. switch priv.Public().(type) {
  291. case *rsa.PublicKey:
  292. hs.rsaDecryptOk = true
  293. default:
  294. c.sendAlert(alertInternalError)
  295. return false, fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
  296. }
  297. }
  298. if c.vers != VersionTLS13 && hs.checkForResumption() {
  299. return true, nil
  300. }
  301. var preferenceList, supportedList []uint16
  302. if c.config.PreferServerCipherSuites {
  303. preferenceList = c.config.cipherSuites(c.vers)
  304. supportedList = hs.clientHello.cipherSuites
  305. } else {
  306. preferenceList = hs.clientHello.cipherSuites
  307. supportedList = c.config.cipherSuites(c.vers)
  308. }
  309. for _, id := range preferenceList {
  310. if hs.setCipherSuite(id, supportedList, c.vers) {
  311. break
  312. }
  313. }
  314. if hs.suite == nil {
  315. c.sendAlert(alertHandshakeFailure)
  316. return false, errors.New("tls: no cipher suite supported by both client and server")
  317. }
  318. // See https://tools.ietf.org/html/rfc7507.
  319. for _, id := range hs.clientHello.cipherSuites {
  320. if id == TLS_FALLBACK_SCSV {
  321. // The client is doing a fallback connection.
  322. if hs.clientHello.vers < c.config.maxVersion() {
  323. c.sendAlert(alertInappropriateFallback)
  324. return false, errors.New("tls: client using inappropriate protocol fallback")
  325. }
  326. break
  327. }
  328. }
  329. return false, nil
  330. }
  331. // checkForResumption reports whether we should perform resumption on this connection.
  332. func (hs *serverHandshakeState) checkForResumption() bool {
  333. c := hs.c
  334. if c.config.SessionTicketsDisabled {
  335. return false
  336. }
  337. sessionTicket := append([]uint8{}, hs.clientHello.sessionTicket...)
  338. serializedState, usedOldKey := c.decryptTicket(sessionTicket)
  339. hs.sessionState = &sessionState{usedOldKey: usedOldKey}
  340. if ok := hs.sessionState.unmarshal(serializedState); !ok {
  341. return false
  342. }
  343. // Never resume a session for a different TLS version.
  344. if c.vers != hs.sessionState.vers {
  345. return false
  346. }
  347. cipherSuiteOk := false
  348. // Check that the client is still offering the ciphersuite in the session.
  349. for _, id := range hs.clientHello.cipherSuites {
  350. if id == hs.sessionState.cipherSuite {
  351. cipherSuiteOk = true
  352. break
  353. }
  354. }
  355. if !cipherSuiteOk {
  356. return false
  357. }
  358. // Check that we also support the ciphersuite from the session.
  359. if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(c.vers), hs.sessionState.vers) {
  360. return false
  361. }
  362. sessionHasClientCerts := len(hs.sessionState.certificates) != 0
  363. needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
  364. if needClientCerts && !sessionHasClientCerts {
  365. return false
  366. }
  367. if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
  368. return false
  369. }
  370. return true
  371. }
  372. func (hs *serverHandshakeState) doResumeHandshake() error {
  373. c := hs.c
  374. hs.hello.cipherSuite = hs.suite.id
  375. // We echo the client's session ID in the ServerHello to let it know
  376. // that we're doing a resumption.
  377. hs.hello.sessionId = hs.clientHello.sessionId
  378. hs.hello.ticketSupported = hs.sessionState.usedOldKey
  379. hs.finishedHash = newFinishedHash(c.vers, hs.suite)
  380. hs.finishedHash.discardHandshakeBuffer()
  381. hs.finishedHash.Write(hs.clientHello.marshal())
  382. hs.finishedHash.Write(hs.hello.marshal())
  383. if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
  384. return err
  385. }
  386. if len(hs.sessionState.certificates) > 0 {
  387. if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
  388. return err
  389. }
  390. }
  391. hs.masterSecret = hs.sessionState.masterSecret
  392. return nil
  393. }
  394. func (hs *serverHandshakeState) doFullHandshake() error {
  395. c := hs.c
  396. if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
  397. hs.hello.ocspStapling = true
  398. }
  399. hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
  400. hs.hello.cipherSuite = hs.suite.id
  401. hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
  402. if c.config.ClientAuth == NoClientCert {
  403. // No need to keep a full record of the handshake if client
  404. // certificates won't be used.
  405. hs.finishedHash.discardHandshakeBuffer()
  406. }
  407. hs.finishedHash.Write(hs.clientHello.marshal())
  408. hs.finishedHash.Write(hs.hello.marshal())
  409. if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
  410. return err
  411. }
  412. certMsg := new(certificateMsg)
  413. certMsg.certificates = hs.cert.Certificate
  414. hs.finishedHash.Write(certMsg.marshal())
  415. if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
  416. return err
  417. }
  418. if hs.hello.ocspStapling {
  419. certStatus := new(certificateStatusMsg)
  420. certStatus.statusType = statusTypeOCSP
  421. certStatus.response = hs.cert.OCSPStaple
  422. hs.finishedHash.Write(certStatus.marshal())
  423. if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
  424. return err
  425. }
  426. }
  427. keyAgreement := hs.suite.ka(c.vers)
  428. skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello)
  429. if err != nil {
  430. c.sendAlert(alertHandshakeFailure)
  431. return err
  432. }
  433. if skx != nil {
  434. hs.finishedHash.Write(skx.marshal())
  435. if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil {
  436. return err
  437. }
  438. }
  439. if c.config.ClientAuth >= RequestClientCert {
  440. // Request a client certificate
  441. certReq := new(certificateRequestMsg)
  442. certReq.certificateTypes = []byte{
  443. byte(certTypeRSASign),
  444. byte(certTypeECDSASign),
  445. }
  446. if c.vers >= VersionTLS12 {
  447. certReq.hasSignatureAndHash = true
  448. certReq.signatureAndHashes = supportedSignatureAlgorithms
  449. }
  450. // An empty list of certificateAuthorities signals to
  451. // the client that it may send any certificate in response
  452. // to our request. When we know the CAs we trust, then
  453. // we can send them down, so that the client can choose
  454. // an appropriate certificate to give to us.
  455. if c.config.ClientCAs != nil {
  456. certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
  457. }
  458. hs.finishedHash.Write(certReq.marshal())
  459. if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
  460. return err
  461. }
  462. }
  463. helloDone := new(serverHelloDoneMsg)
  464. hs.finishedHash.Write(helloDone.marshal())
  465. if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil {
  466. return err
  467. }
  468. if _, err := c.flush(); err != nil {
  469. return err
  470. }
  471. var pub crypto.PublicKey // public key for client auth, if any
  472. msg, err := c.readHandshake()
  473. if err != nil {
  474. return err
  475. }
  476. var ok bool
  477. // If we requested a client certificate, then the client must send a
  478. // certificate message, even if it's empty.
  479. if c.config.ClientAuth >= RequestClientCert {
  480. if certMsg, ok = msg.(*certificateMsg); !ok {
  481. c.sendAlert(alertUnexpectedMessage)
  482. return unexpectedMessageError(certMsg, msg)
  483. }
  484. hs.finishedHash.Write(certMsg.marshal())
  485. if len(certMsg.certificates) == 0 {
  486. // The client didn't actually send a certificate
  487. switch c.config.ClientAuth {
  488. case RequireAnyClientCert, RequireAndVerifyClientCert:
  489. c.sendAlert(alertBadCertificate)
  490. return errors.New("tls: client didn't provide a certificate")
  491. }
  492. }
  493. pub, err = hs.processCertsFromClient(certMsg.certificates)
  494. if err != nil {
  495. return err
  496. }
  497. msg, err = c.readHandshake()
  498. if err != nil {
  499. return err
  500. }
  501. }
  502. // Get client key exchange
  503. ckx, ok := msg.(*clientKeyExchangeMsg)
  504. if !ok {
  505. c.sendAlert(alertUnexpectedMessage)
  506. return unexpectedMessageError(ckx, msg)
  507. }
  508. hs.finishedHash.Write(ckx.marshal())
  509. preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
  510. if err != nil {
  511. c.sendAlert(alertHandshakeFailure)
  512. return err
  513. }
  514. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
  515. if err := c.config.writeKeyLog(hs.clientHello.random, hs.masterSecret); err != nil {
  516. c.sendAlert(alertInternalError)
  517. return err
  518. }
  519. // If we received a client cert in response to our certificate request message,
  520. // the client will send us a certificateVerifyMsg immediately after the
  521. // clientKeyExchangeMsg. This message is a digest of all preceding
  522. // handshake-layer messages that is signed using the private key corresponding
  523. // to the client's certificate. This allows us to verify that the client is in
  524. // possession of the private key of the certificate.
  525. if len(c.peerCertificates) > 0 {
  526. msg, err = c.readHandshake()
  527. if err != nil {
  528. return err
  529. }
  530. certVerify, ok := msg.(*certificateVerifyMsg)
  531. if !ok {
  532. c.sendAlert(alertUnexpectedMessage)
  533. return unexpectedMessageError(certVerify, msg)
  534. }
  535. // Determine the signature type.
  536. var signatureAndHash signatureAndHash
  537. if certVerify.hasSignatureAndHash {
  538. signatureAndHash = certVerify.signatureAndHash
  539. if !isSupportedSignatureAndHash(signatureAndHash, supportedSignatureAlgorithms) {
  540. return errors.New("tls: unsupported hash function for client certificate")
  541. }
  542. } else {
  543. // Before TLS 1.2 the signature algorithm was implicit
  544. // from the key type, and only one hash per signature
  545. // algorithm was possible. Leave the hash as zero.
  546. switch pub.(type) {
  547. case *ecdsa.PublicKey:
  548. signatureAndHash.signature = signatureECDSA
  549. case *rsa.PublicKey:
  550. signatureAndHash.signature = signatureRSA
  551. }
  552. }
  553. switch key := pub.(type) {
  554. case *ecdsa.PublicKey:
  555. if signatureAndHash.signature != signatureECDSA {
  556. err = errors.New("tls: bad signature type for client's ECDSA certificate")
  557. break
  558. }
  559. ecdsaSig := new(ecdsaSignature)
  560. if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
  561. break
  562. }
  563. if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
  564. err = errors.New("tls: ECDSA signature contained zero or negative values")
  565. break
  566. }
  567. var digest []byte
  568. if digest, _, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
  569. break
  570. }
  571. if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
  572. err = errors.New("tls: ECDSA verification failure")
  573. }
  574. case *rsa.PublicKey:
  575. if signatureAndHash.signature != signatureRSA {
  576. err = errors.New("tls: bad signature type for client's RSA certificate")
  577. break
  578. }
  579. var digest []byte
  580. var hashFunc crypto.Hash
  581. if digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
  582. break
  583. }
  584. err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
  585. }
  586. if err != nil {
  587. c.sendAlert(alertBadCertificate)
  588. return errors.New("tls: could not validate signature of connection nonces: " + err.Error())
  589. }
  590. hs.finishedHash.Write(certVerify.marshal())
  591. }
  592. hs.finishedHash.discardHandshakeBuffer()
  593. return nil
  594. }
  595. func (hs *serverHandshakeState) establishKeys() error {
  596. c := hs.c
  597. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  598. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  599. var clientCipher, serverCipher interface{}
  600. var clientHash, serverHash macFunction
  601. if hs.suite.aead == nil {
  602. clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
  603. clientHash = hs.suite.mac(c.vers, clientMAC)
  604. serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
  605. serverHash = hs.suite.mac(c.vers, serverMAC)
  606. } else {
  607. clientCipher = hs.suite.aead(clientKey, clientIV)
  608. serverCipher = hs.suite.aead(serverKey, serverIV)
  609. }
  610. c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
  611. c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
  612. return nil
  613. }
  614. func (hs *serverHandshakeState) readFinished(out []byte) error {
  615. c := hs.c
  616. c.readRecord(recordTypeChangeCipherSpec)
  617. if c.in.err != nil {
  618. return c.in.err
  619. }
  620. if hs.hello.nextProtoNeg {
  621. msg, err := c.readHandshake()
  622. if err != nil {
  623. return err
  624. }
  625. nextProto, ok := msg.(*nextProtoMsg)
  626. if !ok {
  627. c.sendAlert(alertUnexpectedMessage)
  628. return unexpectedMessageError(nextProto, msg)
  629. }
  630. hs.finishedHash.Write(nextProto.marshal())
  631. c.clientProtocol = nextProto.proto
  632. }
  633. msg, err := c.readHandshake()
  634. if err != nil {
  635. return err
  636. }
  637. clientFinished, ok := msg.(*finishedMsg)
  638. if !ok {
  639. c.sendAlert(alertUnexpectedMessage)
  640. return unexpectedMessageError(clientFinished, msg)
  641. }
  642. verify := hs.finishedHash.clientSum(hs.masterSecret)
  643. if len(verify) != len(clientFinished.verifyData) ||
  644. subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
  645. c.sendAlert(alertHandshakeFailure)
  646. return errors.New("tls: client's Finished message is incorrect")
  647. }
  648. hs.finishedHash.Write(clientFinished.marshal())
  649. copy(out, verify)
  650. return nil
  651. }
  652. func (hs *serverHandshakeState) sendSessionTicket() error {
  653. if !hs.hello.ticketSupported {
  654. return nil
  655. }
  656. c := hs.c
  657. m := new(newSessionTicketMsg)
  658. var err error
  659. state := sessionState{
  660. vers: c.vers,
  661. cipherSuite: hs.suite.id,
  662. masterSecret: hs.masterSecret,
  663. certificates: hs.certsFromClient,
  664. }
  665. m.ticket, err = c.encryptTicket(state.marshal())
  666. if err != nil {
  667. return err
  668. }
  669. hs.finishedHash.Write(m.marshal())
  670. if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
  671. return err
  672. }
  673. return nil
  674. }
  675. func (hs *serverHandshakeState) sendFinished(out []byte) error {
  676. c := hs.c
  677. if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
  678. return err
  679. }
  680. finished := new(finishedMsg)
  681. finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
  682. hs.finishedHash.Write(finished.marshal())
  683. if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
  684. return err
  685. }
  686. c.cipherSuite = hs.suite.id
  687. copy(out, finished.verifyData)
  688. return nil
  689. }
  690. // processCertsFromClient takes a chain of client certificates either from a
  691. // Certificates message or from a sessionState and verifies them. It returns
  692. // the public key of the leaf certificate.
  693. func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
  694. c := hs.c
  695. hs.certsFromClient = certificates
  696. certs := make([]*x509.Certificate, len(certificates))
  697. var err error
  698. for i, asn1Data := range certificates {
  699. if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
  700. c.sendAlert(alertBadCertificate)
  701. return nil, errors.New("tls: failed to parse client certificate: " + err.Error())
  702. }
  703. }
  704. if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
  705. opts := x509.VerifyOptions{
  706. Roots: c.config.ClientCAs,
  707. CurrentTime: c.config.time(),
  708. Intermediates: x509.NewCertPool(),
  709. KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
  710. }
  711. for _, cert := range certs[1:] {
  712. opts.Intermediates.AddCert(cert)
  713. }
  714. chains, err := certs[0].Verify(opts)
  715. if err != nil {
  716. c.sendAlert(alertBadCertificate)
  717. return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
  718. }
  719. c.verifiedChains = chains
  720. }
  721. if c.config.VerifyPeerCertificate != nil {
  722. if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
  723. c.sendAlert(alertBadCertificate)
  724. return nil, err
  725. }
  726. }
  727. if len(certs) == 0 {
  728. return nil, nil
  729. }
  730. var pub crypto.PublicKey
  731. switch key := certs[0].PublicKey.(type) {
  732. case *ecdsa.PublicKey, *rsa.PublicKey:
  733. pub = key
  734. default:
  735. c.sendAlert(alertUnsupportedCertificate)
  736. return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
  737. }
  738. c.peerCertificates = certs
  739. return pub, nil
  740. }
  741. // setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState
  742. // suite if that cipher suite is acceptable to use.
  743. // It returns a bool indicating if the suite was set.
  744. func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool {
  745. for _, supported := range supportedCipherSuites {
  746. if id == supported {
  747. var candidate *cipherSuite
  748. for _, s := range cipherSuites {
  749. if s.id == id {
  750. candidate = s
  751. break
  752. }
  753. }
  754. if candidate == nil {
  755. continue
  756. }
  757. if version >= VersionTLS13 && candidate.flags&suiteTLS13 != 0 {
  758. hs.suite = candidate
  759. return true
  760. }
  761. if version < VersionTLS13 && candidate.flags&suiteTLS13 != 0 {
  762. continue
  763. }
  764. // Don't select a ciphersuite which we can't
  765. // support for this client.
  766. if candidate.flags&suiteECDHE != 0 {
  767. if !hs.ellipticOk {
  768. continue
  769. }
  770. if candidate.flags&suiteECDSA != 0 {
  771. if !hs.ecdsaOk {
  772. continue
  773. }
  774. } else if !hs.rsaSignOk {
  775. continue
  776. }
  777. } else if !hs.rsaDecryptOk {
  778. continue
  779. }
  780. if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
  781. continue
  782. }
  783. hs.suite = candidate
  784. return true
  785. }
  786. }
  787. return false
  788. }
  789. // suppVersArray is the backing array of ClientHelloInfo.SupportedVersions
  790. var suppVersArray = [...]uint16{VersionTLS12, VersionTLS11, VersionTLS10, VersionSSL30}
  791. func (hs *serverHandshakeState) clientHelloInfo() *ClientHelloInfo {
  792. if hs.cachedClientHelloInfo != nil {
  793. return hs.cachedClientHelloInfo
  794. }
  795. var supportedVersions []uint16
  796. if hs.clientHello.supportedVersions != nil {
  797. supportedVersions = hs.clientHello.supportedVersions
  798. } else if hs.clientHello.vers > VersionTLS12 {
  799. supportedVersions = suppVersArray[:]
  800. } else if hs.clientHello.vers >= VersionSSL30 {
  801. supportedVersions = suppVersArray[VersionTLS12-hs.clientHello.vers:]
  802. }
  803. signatureSchemes := make([]SignatureScheme, 0, len(hs.clientHello.signatureAndHashes))
  804. for _, sah := range hs.clientHello.signatureAndHashes {
  805. signatureSchemes = append(signatureSchemes, SignatureScheme(sah.hash)<<8+SignatureScheme(sah.signature))
  806. }
  807. var pskBinder []byte
  808. if len(hs.clientHello.psks) > 0 {
  809. pskBinder = hs.clientHello.psks[0].binder
  810. }
  811. hs.cachedClientHelloInfo = &ClientHelloInfo{
  812. CipherSuites: hs.clientHello.cipherSuites,
  813. ServerName: hs.clientHello.serverName,
  814. SupportedCurves: hs.clientHello.supportedCurves,
  815. SupportedPoints: hs.clientHello.supportedPoints,
  816. SignatureSchemes: signatureSchemes,
  817. SupportedProtos: hs.clientHello.alpnProtocols,
  818. SupportedVersions: supportedVersions,
  819. Conn: hs.c.conn,
  820. Offered0RTTData: hs.clientHello.earlyData,
  821. Fingerprint: pskBinder,
  822. }
  823. return hs.cachedClientHelloInfo
  824. }