-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial support for RSA-PSS (preparation for client) #35
Conversation
handshake_client.go
Outdated
switch key.Public().(type) { | ||
case *ecdsa.PublicKey: | ||
signatureType = signatureECDSA | ||
case *rsa.PublicKey: | ||
signatureType = signatureRSA | ||
signatureType = signatureRSAPKCS1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so now this value will be 0? I have a feeling something is not quite right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not sent over the network, so the exact value does not matter. Maybe I should use iota + 1
though to allow for "uninitialized" values to be recognized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That could work, or we just assign 0 to some None
constant.
common.go
Outdated
const ( | ||
signatureRSA uint8 = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I missed something. Now signatureRSAPKCS1=0, RSAPSS=1, and signatureECDSA=2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, the exact values do not exactly matter since the signatureType
is not sent over the network, it is used only internally to track what signature verification method needs to be called.
In TLS 1.2 the SignatureAndHash (SAH) type consisted of two fields, these were merged in TLS 1.3 into a single 16-bit number. The hash type and the SAH types have been removed in the previous patch, this one removed the signature type from SAH as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense. I only briefly touched those code before, I didn't know the change in progress.
can we push this change upstream to go master branch? I am not feeling super comfortable about remove some RFC-specific constants? I might be wrong. I need to learn. |
Upstream had no objections for the patch, I'll poke again. Ideally the patches are reviewed+merged first in upstream to reduce the changes that we have to carry. |
Thanks, I will look again. |
We have |
I tried to follow the TLS 1.3 draft closely here, we have two types:
The type is named "SignatureScheme" in TLS 1.3 because TLS 1.2 defined the "SignatureAlgorithm" type differently. But I actually use "signatureAlgorithm" as variable name since that's the draft says that throughout the document, it will refer to SignatureScheme as "SignatureAlgorithm". It is called "SignatureScheme" because there are also signature algorithms without configurable hash, so SignatureAndHashAlgorithm would not be entirely accurate. Some combinations of hash functions and signature algorithms are also incompatible. |
By the way, I have updated the patches upstream to use iota+1 for the two types (signatureType and pubkeyType) and renamed signatureRSAPKCS1 to signaturePKCS1v15, but the functionally the patches are still the same. |
LGTM, I understand that now. |
Consolidate the signature and hash fields (SignatureAndHashAlgorithm in TLS 1.2) into a single uint16 (SignatureScheme in TLS 1.3 draft 21). This makes it easier to add RSASSA-PSS for TLS 1.2 in the future. Fields were named like "signatureAlgorithm" rather than "signatureScheme" since that name is also used throughout the 1.3 draft. The only new public symbol is ECDSAWithSHA1, other than that this is an internal change with no new functionality. Change-Id: Iba63d262ab1af895420583ac9e302d9705a7e0f0
A public key algorithm like RSA can be used in multiple different signature algorithms (e.g. RSASSA-PKCS1-v1_5 and RSASSA-PSS). Introduce two special types to prevent confusion. Change-Id: Ia4a59f63ab7f377d46afc792f53755296762f300
TODO squash this into "crypto/tls: implement TLS 1.3 minimal server" when "crypto/tls: replace signatureAndHash by SignatureScheme." is merged upstream.
Accept RSASSA-PSS for CertificateVerify and ServerKeyExchange messages. This signature algorithm was defined in the TLS 1.3 draft for TLS 1.2. Note that the algorithms are not advertised in ClientHello because PSS certificates are not supported yet, see also http://ietf.org/mail-archive/web/tls/current/msg24440.html Now it passes the RSA-PSS-Default-Sign bogo test. TODO advertise PSS in CH and refresh testdata TODO implement support for PSS public keys, needs changes in crypto/x509
Since we advertise RSASSA-PSS support when maxVersion is VersionTLS13, be sure to implement at accept such signatures in SKE. TODO refactor code to share signature verification with doFullHandshake
81c69e0
to
66fb268
Compare
I've rebased the patch on the latest master branch and changed the following:
The tree patches consist of two upstream patches (still in review) plus a change needed due to our TLS 1.3 changes (see the commit message). |
Replaced by #54 |
This is part of the changes that are required for a TLS 1.3 client.
It refactors the SAH type from TLS 1.2 to SignatureScheme in TLS 1.3, these changes have been proposed upstream:
https://go-review.googlesource.com/c/go/+/62210(merged upstream)https://go-review.googlesource.com/c/go/+/64610abandonedThis PR might change based on upstream feedback,
but so far the only concern is about naming.Based on feedback to the above abandoned patch, here is another shot at preparing for and actually implementing PSS:
https://go-review.googlesource.com/c/go/+/79735 (preparation patch)
https://go-review.googlesource.com/c/go/+/79736 (PSS support for handshake messages)
https://go-review.googlesource.com/c/go/+/79738 (RFC: enable PSS and add tests)
EDIT: this PR will likely be superseded by the contents of https://github.com/cloudflare/tls-tris/tree/pwu/sigalgs-pss but is pending (upstream) review!
After that, adding support for RSASSA-PSS signatures for handshake messages becomes easier.
NOTE: RSASSA-PSS is not advertised yet in the TLS 1.2 client handshake because it technically does not support RSASSA-PSS public keys or signatures in certificates. Furthermore, all testdata would have to be updated after such a change, so I was hesitant to do that now.
To implement full RSASSA-PSS support, upstream crypto/x509 would need to be changed and the TLS WG must settle on the required functionality (see this list post).
As a hack, a future TLS 1.3 client change will include PSS anyway in the supported_algorithms extension (but only for 1.3, not for 1.2) because the handshake will fail otherwise (PSS is currently mandatory up to at least draft -21).