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

handshake_server.go 21 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>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
před 9 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  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. "io"
  15. )
  16. // serverHandshakeState contains details of a server handshake in progress.
  17. // It's discarded once the handshake has completed.
  18. type serverHandshakeState struct {
  19. c *Conn
  20. clientHello *clientHelloMsg
  21. hello *serverHelloMsg
  22. suite *cipherSuite
  23. ellipticOk bool
  24. ecdsaOk bool
  25. rsaDecryptOk bool
  26. rsaSignOk bool
  27. sessionState *sessionState
  28. finishedHash finishedHash
  29. masterSecret []byte
  30. certsFromClient [][]byte
  31. cert *Certificate
  32. }
  33. // serverHandshake performs a TLS handshake as a server.
  34. func (c *Conn) serverHandshake() error {
  35. config := c.config
  36. // If this is the first server handshake, we generate a random key to
  37. // encrypt the tickets with.
  38. config.serverInitOnce.Do(config.serverInit)
  39. hs := serverHandshakeState{
  40. c: c,
  41. }
  42. isResume, err := hs.readClientHello()
  43. if err != nil {
  44. return err
  45. }
  46. // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
  47. if isResume {
  48. // The client has included a session ticket and so we do an abbreviated handshake.
  49. if err := hs.doResumeHandshake(); err != nil {
  50. return err
  51. }
  52. if err := hs.establishKeys(); err != nil {
  53. return err
  54. }
  55. // ticketSupported is set in a resumption handshake if the
  56. // ticket from the client was encrypted with an old session
  57. // ticket key and thus a refreshed ticket should be sent.
  58. if hs.hello.ticketSupported {
  59. if err := hs.sendSessionTicket(); err != nil {
  60. return err
  61. }
  62. }
  63. if err := hs.sendFinished(c.firstFinished[:]); err != nil {
  64. return err
  65. }
  66. if err := hs.readFinished(nil); err != nil {
  67. return err
  68. }
  69. c.didResume = true
  70. } else {
  71. // The client didn't include a session ticket, or it wasn't
  72. // valid so we do a full handshake.
  73. if err := hs.doFullHandshake(); err != nil {
  74. return err
  75. }
  76. if err := hs.establishKeys(); err != nil {
  77. return err
  78. }
  79. if err := hs.readFinished(c.firstFinished[:]); err != nil {
  80. return err
  81. }
  82. if err := hs.sendSessionTicket(); err != nil {
  83. return err
  84. }
  85. if err := hs.sendFinished(nil); err != nil {
  86. return err
  87. }
  88. }
  89. c.handshakeComplete = true
  90. return nil
  91. }
  92. // readClientHello reads a ClientHello message from the client and decides
  93. // whether we will perform session resumption.
  94. func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
  95. config := hs.c.config
  96. c := hs.c
  97. msg, err := c.readHandshake()
  98. if err != nil {
  99. return false, err
  100. }
  101. var ok bool
  102. hs.clientHello, ok = msg.(*clientHelloMsg)
  103. if !ok {
  104. c.sendAlert(alertUnexpectedMessage)
  105. return false, unexpectedMessageError(hs.clientHello, msg)
  106. }
  107. c.vers, ok = config.mutualVersion(hs.clientHello.vers)
  108. if !ok {
  109. c.sendAlert(alertProtocolVersion)
  110. return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
  111. }
  112. c.haveVers = true
  113. hs.hello = new(serverHelloMsg)
  114. supportedCurve := false
  115. preferredCurves := config.curvePreferences()
  116. Curves:
  117. for _, curve := range hs.clientHello.supportedCurves {
  118. for _, supported := range preferredCurves {
  119. if supported == curve {
  120. supportedCurve = true
  121. break Curves
  122. }
  123. }
  124. }
  125. supportedPointFormat := false
  126. for _, pointFormat := range hs.clientHello.supportedPoints {
  127. if pointFormat == pointFormatUncompressed {
  128. supportedPointFormat = true
  129. break
  130. }
  131. }
  132. hs.ellipticOk = supportedCurve && supportedPointFormat
  133. foundCompression := false
  134. // We only support null compression, so check that the client offered it.
  135. for _, compression := range hs.clientHello.compressionMethods {
  136. if compression == compressionNone {
  137. foundCompression = true
  138. break
  139. }
  140. }
  141. if !foundCompression {
  142. c.sendAlert(alertHandshakeFailure)
  143. return false, errors.New("tls: client does not support uncompressed connections")
  144. }
  145. hs.hello.vers = c.vers
  146. hs.hello.random = make([]byte, 32)
  147. _, err = io.ReadFull(config.rand(), hs.hello.random)
  148. if err != nil {
  149. c.sendAlert(alertInternalError)
  150. return false, err
  151. }
  152. hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
  153. hs.hello.compressionMethod = compressionNone
  154. if len(hs.clientHello.serverName) > 0 {
  155. c.serverName = hs.clientHello.serverName
  156. }
  157. if len(hs.clientHello.alpnProtocols) > 0 {
  158. if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
  159. hs.hello.alpnProtocol = selectedProto
  160. c.clientProtocol = selectedProto
  161. }
  162. } else {
  163. // Although sending an empty NPN extension is reasonable, Firefox has
  164. // had a bug around this. Best to send nothing at all if
  165. // config.NextProtos is empty. See
  166. // https://golang.org/issue/5445.
  167. if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
  168. hs.hello.nextProtoNeg = true
  169. hs.hello.nextProtos = config.NextProtos
  170. }
  171. }
  172. if hs.cert, err = config.getCertificate(&ClientHelloInfo{
  173. CipherSuites: hs.clientHello.cipherSuites,
  174. ServerName: hs.clientHello.serverName,
  175. SupportedCurves: hs.clientHello.supportedCurves,
  176. SupportedPoints: hs.clientHello.supportedPoints,
  177. }); err != nil {
  178. c.sendAlert(alertInternalError)
  179. return false, err
  180. }
  181. if hs.clientHello.scts {
  182. hs.hello.scts = hs.cert.SignedCertificateTimestamps
  183. }
  184. if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
  185. switch priv.Public().(type) {
  186. case *ecdsa.PublicKey:
  187. hs.ecdsaOk = true
  188. case *rsa.PublicKey:
  189. hs.rsaSignOk = true
  190. default:
  191. c.sendAlert(alertInternalError)
  192. return false, fmt.Errorf("crypto/tls: unsupported signing key type (%T)", priv.Public())
  193. }
  194. }
  195. if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
  196. switch priv.Public().(type) {
  197. case *rsa.PublicKey:
  198. hs.rsaDecryptOk = true
  199. default:
  200. c.sendAlert(alertInternalError)
  201. return false, fmt.Errorf("crypto/tls: unsupported decryption key type (%T)", priv.Public())
  202. }
  203. }
  204. if hs.checkForResumption() {
  205. return true, nil
  206. }
  207. var preferenceList, supportedList []uint16
  208. if c.config.PreferServerCipherSuites {
  209. preferenceList = c.config.cipherSuites()
  210. supportedList = hs.clientHello.cipherSuites
  211. } else {
  212. preferenceList = hs.clientHello.cipherSuites
  213. supportedList = c.config.cipherSuites()
  214. }
  215. for _, id := range preferenceList {
  216. if hs.setCipherSuite(id, supportedList, c.vers) {
  217. break
  218. }
  219. }
  220. if hs.suite == nil {
  221. c.sendAlert(alertHandshakeFailure)
  222. return false, errors.New("tls: no cipher suite supported by both client and server")
  223. }
  224. // See https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00.
  225. for _, id := range hs.clientHello.cipherSuites {
  226. if id == TLS_FALLBACK_SCSV {
  227. // The client is doing a fallback connection.
  228. if hs.clientHello.vers < c.config.maxVersion() {
  229. c.sendAlert(alertInappropriateFallback)
  230. return false, errors.New("tls: client using inappropriate protocol fallback")
  231. }
  232. break
  233. }
  234. }
  235. return false, nil
  236. }
  237. // checkForResumption reports whether we should perform resumption on this connection.
  238. func (hs *serverHandshakeState) checkForResumption() bool {
  239. c := hs.c
  240. if c.config.SessionTicketsDisabled {
  241. return false
  242. }
  243. var ok bool
  244. var sessionTicket = append([]uint8{}, hs.clientHello.sessionTicket...)
  245. if hs.sessionState, ok = c.decryptTicket(sessionTicket); !ok {
  246. return false
  247. }
  248. if hs.sessionState.vers > hs.clientHello.vers {
  249. return false
  250. }
  251. if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers {
  252. return false
  253. }
  254. cipherSuiteOk := false
  255. // Check that the client is still offering the ciphersuite in the session.
  256. for _, id := range hs.clientHello.cipherSuites {
  257. if id == hs.sessionState.cipherSuite {
  258. cipherSuiteOk = true
  259. break
  260. }
  261. }
  262. if !cipherSuiteOk {
  263. return false
  264. }
  265. // Check that we also support the ciphersuite from the session.
  266. if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) {
  267. return false
  268. }
  269. sessionHasClientCerts := len(hs.sessionState.certificates) != 0
  270. needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
  271. if needClientCerts && !sessionHasClientCerts {
  272. return false
  273. }
  274. if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
  275. return false
  276. }
  277. return true
  278. }
  279. func (hs *serverHandshakeState) doResumeHandshake() error {
  280. c := hs.c
  281. hs.hello.cipherSuite = hs.suite.id
  282. // We echo the client's session ID in the ServerHello to let it know
  283. // that we're doing a resumption.
  284. hs.hello.sessionId = hs.clientHello.sessionId
  285. hs.hello.ticketSupported = hs.sessionState.usedOldKey
  286. hs.finishedHash = newFinishedHash(c.vers, hs.suite)
  287. hs.finishedHash.discardHandshakeBuffer()
  288. hs.finishedHash.Write(hs.clientHello.marshal())
  289. hs.finishedHash.Write(hs.hello.marshal())
  290. c.writeRecord(recordTypeHandshake, hs.hello.marshal())
  291. if len(hs.sessionState.certificates) > 0 {
  292. if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
  293. return err
  294. }
  295. }
  296. hs.masterSecret = hs.sessionState.masterSecret
  297. return nil
  298. }
  299. func (hs *serverHandshakeState) doFullHandshake() error {
  300. config := hs.c.config
  301. c := hs.c
  302. if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
  303. hs.hello.ocspStapling = true
  304. }
  305. hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled
  306. hs.hello.cipherSuite = hs.suite.id
  307. hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
  308. if config.ClientAuth == NoClientCert {
  309. // No need to keep a full record of the handshake if client
  310. // certificates won't be used.
  311. hs.finishedHash.discardHandshakeBuffer()
  312. }
  313. hs.finishedHash.Write(hs.clientHello.marshal())
  314. hs.finishedHash.Write(hs.hello.marshal())
  315. c.writeRecord(recordTypeHandshake, hs.hello.marshal())
  316. certMsg := new(certificateMsg)
  317. certMsg.certificates = hs.cert.Certificate
  318. hs.finishedHash.Write(certMsg.marshal())
  319. c.writeRecord(recordTypeHandshake, certMsg.marshal())
  320. if hs.hello.ocspStapling {
  321. certStatus := new(certificateStatusMsg)
  322. certStatus.statusType = statusTypeOCSP
  323. certStatus.response = hs.cert.OCSPStaple
  324. hs.finishedHash.Write(certStatus.marshal())
  325. c.writeRecord(recordTypeHandshake, certStatus.marshal())
  326. }
  327. keyAgreement := hs.suite.ka(c.vers)
  328. skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello)
  329. if err != nil {
  330. c.sendAlert(alertHandshakeFailure)
  331. return err
  332. }
  333. if skx != nil {
  334. hs.finishedHash.Write(skx.marshal())
  335. c.writeRecord(recordTypeHandshake, skx.marshal())
  336. }
  337. if config.ClientAuth >= RequestClientCert {
  338. // Request a client certificate
  339. certReq := new(certificateRequestMsg)
  340. certReq.certificateTypes = []byte{
  341. byte(certTypeRSASign),
  342. byte(certTypeECDSASign),
  343. }
  344. if c.vers >= VersionTLS12 {
  345. certReq.hasSignatureAndHash = true
  346. certReq.signatureAndHashes = supportedSignatureAlgorithms
  347. }
  348. // An empty list of certificateAuthorities signals to
  349. // the client that it may send any certificate in response
  350. // to our request. When we know the CAs we trust, then
  351. // we can send them down, so that the client can choose
  352. // an appropriate certificate to give to us.
  353. if config.ClientCAs != nil {
  354. certReq.certificateAuthorities = config.ClientCAs.Subjects()
  355. }
  356. hs.finishedHash.Write(certReq.marshal())
  357. c.writeRecord(recordTypeHandshake, certReq.marshal())
  358. }
  359. helloDone := new(serverHelloDoneMsg)
  360. hs.finishedHash.Write(helloDone.marshal())
  361. c.writeRecord(recordTypeHandshake, helloDone.marshal())
  362. var pub crypto.PublicKey // public key for client auth, if any
  363. msg, err := c.readHandshake()
  364. if err != nil {
  365. return err
  366. }
  367. var ok bool
  368. // If we requested a client certificate, then the client must send a
  369. // certificate message, even if it's empty.
  370. if config.ClientAuth >= RequestClientCert {
  371. if certMsg, ok = msg.(*certificateMsg); !ok {
  372. c.sendAlert(alertUnexpectedMessage)
  373. return unexpectedMessageError(certMsg, msg)
  374. }
  375. hs.finishedHash.Write(certMsg.marshal())
  376. if len(certMsg.certificates) == 0 {
  377. // The client didn't actually send a certificate
  378. switch config.ClientAuth {
  379. case RequireAnyClientCert, RequireAndVerifyClientCert:
  380. c.sendAlert(alertBadCertificate)
  381. return errors.New("tls: client didn't provide a certificate")
  382. }
  383. }
  384. pub, err = hs.processCertsFromClient(certMsg.certificates)
  385. if err != nil {
  386. return err
  387. }
  388. msg, err = c.readHandshake()
  389. if err != nil {
  390. return err
  391. }
  392. }
  393. // Get client key exchange
  394. ckx, ok := msg.(*clientKeyExchangeMsg)
  395. if !ok {
  396. c.sendAlert(alertUnexpectedMessage)
  397. return unexpectedMessageError(ckx, msg)
  398. }
  399. hs.finishedHash.Write(ckx.marshal())
  400. preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers)
  401. if err != nil {
  402. c.sendAlert(alertHandshakeFailure)
  403. return err
  404. }
  405. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
  406. // If we received a client cert in response to our certificate request message,
  407. // the client will send us a certificateVerifyMsg immediately after the
  408. // clientKeyExchangeMsg. This message is a digest of all preceding
  409. // handshake-layer messages that is signed using the private key corresponding
  410. // to the client's certificate. This allows us to verify that the client is in
  411. // possession of the private key of the certificate.
  412. if len(c.peerCertificates) > 0 {
  413. msg, err = c.readHandshake()
  414. if err != nil {
  415. return err
  416. }
  417. certVerify, ok := msg.(*certificateVerifyMsg)
  418. if !ok {
  419. c.sendAlert(alertUnexpectedMessage)
  420. return unexpectedMessageError(certVerify, msg)
  421. }
  422. // Determine the signature type.
  423. var signatureAndHash signatureAndHash
  424. if certVerify.hasSignatureAndHash {
  425. signatureAndHash = certVerify.signatureAndHash
  426. if !isSupportedSignatureAndHash(signatureAndHash, supportedSignatureAlgorithms) {
  427. return errors.New("tls: unsupported hash function for client certificate")
  428. }
  429. } else {
  430. // Before TLS 1.2 the signature algorithm was implicit
  431. // from the key type, and only one hash per signature
  432. // algorithm was possible. Leave the hash as zero.
  433. switch pub.(type) {
  434. case *ecdsa.PublicKey:
  435. signatureAndHash.signature = signatureECDSA
  436. case *rsa.PublicKey:
  437. signatureAndHash.signature = signatureRSA
  438. }
  439. }
  440. switch key := pub.(type) {
  441. case *ecdsa.PublicKey:
  442. if signatureAndHash.signature != signatureECDSA {
  443. err = errors.New("bad signature type for client's ECDSA certificate")
  444. break
  445. }
  446. ecdsaSig := new(ecdsaSignature)
  447. if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
  448. break
  449. }
  450. if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
  451. err = errors.New("ECDSA signature contained zero or negative values")
  452. break
  453. }
  454. var digest []byte
  455. if digest, _, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
  456. break
  457. }
  458. if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
  459. err = errors.New("ECDSA verification failure")
  460. }
  461. case *rsa.PublicKey:
  462. if signatureAndHash.signature != signatureRSA {
  463. err = errors.New("bad signature type for client's RSA certificate")
  464. break
  465. }
  466. var digest []byte
  467. var hashFunc crypto.Hash
  468. if digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
  469. break
  470. }
  471. err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
  472. }
  473. if err != nil {
  474. c.sendAlert(alertBadCertificate)
  475. return errors.New("tls: could not validate signature of connection nonces: " + err.Error())
  476. }
  477. hs.finishedHash.Write(certVerify.marshal())
  478. }
  479. hs.finishedHash.discardHandshakeBuffer()
  480. return nil
  481. }
  482. func (hs *serverHandshakeState) establishKeys() error {
  483. c := hs.c
  484. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  485. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  486. var clientCipher, serverCipher interface{}
  487. var clientHash, serverHash macFunction
  488. if hs.suite.aead == nil {
  489. clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
  490. clientHash = hs.suite.mac(c.vers, clientMAC)
  491. serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
  492. serverHash = hs.suite.mac(c.vers, serverMAC)
  493. } else {
  494. clientCipher = hs.suite.aead(clientKey, clientIV)
  495. serverCipher = hs.suite.aead(serverKey, serverIV)
  496. }
  497. c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
  498. c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
  499. return nil
  500. }
  501. func (hs *serverHandshakeState) readFinished(out []byte) error {
  502. c := hs.c
  503. c.readRecord(recordTypeChangeCipherSpec)
  504. if err := c.in.error(); err != nil {
  505. return err
  506. }
  507. if hs.hello.nextProtoNeg {
  508. msg, err := c.readHandshake()
  509. if err != nil {
  510. return err
  511. }
  512. nextProto, ok := msg.(*nextProtoMsg)
  513. if !ok {
  514. c.sendAlert(alertUnexpectedMessage)
  515. return unexpectedMessageError(nextProto, msg)
  516. }
  517. hs.finishedHash.Write(nextProto.marshal())
  518. c.clientProtocol = nextProto.proto
  519. }
  520. msg, err := c.readHandshake()
  521. if err != nil {
  522. return err
  523. }
  524. clientFinished, ok := msg.(*finishedMsg)
  525. if !ok {
  526. c.sendAlert(alertUnexpectedMessage)
  527. return unexpectedMessageError(clientFinished, msg)
  528. }
  529. verify := hs.finishedHash.clientSum(hs.masterSecret)
  530. if len(verify) != len(clientFinished.verifyData) ||
  531. subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
  532. c.sendAlert(alertHandshakeFailure)
  533. return errors.New("tls: client's Finished message is incorrect")
  534. }
  535. hs.finishedHash.Write(clientFinished.marshal())
  536. copy(out, verify)
  537. return nil
  538. }
  539. func (hs *serverHandshakeState) sendSessionTicket() error {
  540. if !hs.hello.ticketSupported {
  541. return nil
  542. }
  543. c := hs.c
  544. m := new(newSessionTicketMsg)
  545. var err error
  546. state := sessionState{
  547. vers: c.vers,
  548. cipherSuite: hs.suite.id,
  549. masterSecret: hs.masterSecret,
  550. certificates: hs.certsFromClient,
  551. }
  552. m.ticket, err = c.encryptTicket(&state)
  553. if err != nil {
  554. return err
  555. }
  556. hs.finishedHash.Write(m.marshal())
  557. c.writeRecord(recordTypeHandshake, m.marshal())
  558. return nil
  559. }
  560. func (hs *serverHandshakeState) sendFinished(out []byte) error {
  561. c := hs.c
  562. c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
  563. finished := new(finishedMsg)
  564. finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
  565. hs.finishedHash.Write(finished.marshal())
  566. c.writeRecord(recordTypeHandshake, finished.marshal())
  567. c.cipherSuite = hs.suite.id
  568. copy(out, finished.verifyData)
  569. return nil
  570. }
  571. // processCertsFromClient takes a chain of client certificates either from a
  572. // Certificates message or from a sessionState and verifies them. It returns
  573. // the public key of the leaf certificate.
  574. func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
  575. c := hs.c
  576. hs.certsFromClient = certificates
  577. certs := make([]*x509.Certificate, len(certificates))
  578. var err error
  579. for i, asn1Data := range certificates {
  580. if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
  581. c.sendAlert(alertBadCertificate)
  582. return nil, errors.New("tls: failed to parse client certificate: " + err.Error())
  583. }
  584. }
  585. if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
  586. opts := x509.VerifyOptions{
  587. Roots: c.config.ClientCAs,
  588. CurrentTime: c.config.time(),
  589. Intermediates: x509.NewCertPool(),
  590. KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
  591. }
  592. for _, cert := range certs[1:] {
  593. opts.Intermediates.AddCert(cert)
  594. }
  595. chains, err := certs[0].Verify(opts)
  596. if err != nil {
  597. c.sendAlert(alertBadCertificate)
  598. return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
  599. }
  600. c.verifiedChains = chains
  601. }
  602. if len(certs) > 0 {
  603. var pub crypto.PublicKey
  604. switch key := certs[0].PublicKey.(type) {
  605. case *ecdsa.PublicKey, *rsa.PublicKey:
  606. pub = key
  607. default:
  608. c.sendAlert(alertUnsupportedCertificate)
  609. return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
  610. }
  611. c.peerCertificates = certs
  612. return pub, nil
  613. }
  614. return nil, nil
  615. }
  616. // setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState
  617. // suite if that cipher suite is acceptable to use.
  618. // It returns a bool indicating if the suite was set.
  619. func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool {
  620. for _, supported := range supportedCipherSuites {
  621. if id == supported {
  622. var candidate *cipherSuite
  623. for _, s := range cipherSuites {
  624. if s.id == id {
  625. candidate = s
  626. break
  627. }
  628. }
  629. if candidate == nil {
  630. continue
  631. }
  632. // Don't select a ciphersuite which we can't
  633. // support for this client.
  634. if candidate.flags&suiteECDHE != 0 {
  635. if !hs.ellipticOk {
  636. continue
  637. }
  638. if candidate.flags&suiteECDSA != 0 {
  639. if !hs.ecdsaOk {
  640. continue
  641. }
  642. } else if !hs.rsaSignOk {
  643. continue
  644. }
  645. } else if !hs.rsaDecryptOk {
  646. continue
  647. }
  648. if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
  649. continue
  650. }
  651. hs.suite = candidate
  652. return true
  653. }
  654. }
  655. return false
  656. }