Implement RSASSA-PKCS1-v1_5 as specified.#1474
Implement RSASSA-PKCS1-v1_5 as specified.#1474davidben wants to merge 5 commits intoopenssl:masterfrom
Conversation
|
Could you add some minimal documentation to the new functions? |
|
Done. Is something like that close to the preferred style? (There's only one new function, I think. Just the helper function which now is shared between sign and verify.) |
|
Huh. I think that's a mistake in RSA_sign.pod. Or at least is confusing. PKCS#1 v2.0 specifies the v1.5 algorithm in it, alongside with the v2.0 one. v2.0 is PSS which takes a lot more parameters than RSA_sign. |
|
Oh, sorry, I got that wrong. v2.0 still only specifies RSASSA-PKCS1-v1_5. v2.1 specifies two algorithms, RSASSA-PSS and RSASSA-PKCS1-v1_5. I'll update RSA_sign.pod to be clearer. |
|
(Updated) |
crypto/rsa/rsa_sign.c
Outdated
|
So travis complains about: |
|
Huh, I wonder why that didn't flag in my local build. Fixed. |
05414b4 to
fa56e99
Compare
|
Rebased, largely to rerun the CI. I can't reproduce the failure from the last run and, having dug into it, it looks very much like TLSProxy is just flaky since the divergence happens long after any PKCS1 bits happen. We'll see if a rerun does it again. |
|
(Travis appears to be happy now.) |
|
ping @kroeckx |
crypto/rsa/rsa_sign.c
Outdated
There was a problem hiding this comment.
I really dislike undocumented functions. Can you add something short there?
There was a problem hiding this comment.
Can you add something about the return values?
crypto/rsa/rsa_sign.c
Outdated
There was a problem hiding this comment.
EVP_MD_size() can actually handle NULL, but it seems to be a bad style to first call a function with NULL and then later check that it the variable was NULL and give an error.
crypto/rsa/rsa_sign.c
Outdated
There was a problem hiding this comment.
I know you didn't name this variable, but care to rename it?
There was a problem hiding this comment.
Done. Also tweaked a few other variables to be more consistent and fixed some style problems (I managed to get tab characters in there apparently).
crypto/rsa/rsa_sign.c
Outdated
There was a problem hiding this comment.
This check doesn't seem to happen anymore, not sure it's important.
There was a problem hiding this comment.
Oops, fixed. Also fixed the missing equivalent check in the MDC2 special-case.
|
@davidben: ping |
|
Updated. (Let me know if you'd like this squashed or rebased. I'm not sure what the usual preference is.) |
RFC 3447, section 8.2.2, steps 3 and 4 states that verifiers must encode the DigestInfo struct and then compare the result against the public key operation result. This implies that one and only one encoding is legal. OpenSSL instead parses with crypto/asn1, then checks that the encoding round-trips, and allows some variations for the parameter. Sufficient laxness in this area can allow signature forgeries, as described in https://www.imperialviolet.org/2014/09/26/pkcs1.html Although there aren't known attacks against OpenSSL's current scheme, this change makes OpenSSL implement the algorithm as specified. This avoids the uncertainty and, more importantly, helps grow a healthy ecosystem. Laxness beyond the spec, particularly in implementations which enjoy wide use, risks harm to the ecosystem for all. A signature producer which only tests against OpenSSL may not notice bugs and accidentally become widely deployed. Thus implementations have a responsibility to honor the specification as tightly as is practical. In some cases, the damage is permanent and the spec deviation and security risk becomes a tax all implementors must forever pay, but not here. Both BoringSSL and Go successfully implemented and deployed RSASSA-PKCS1-v1_5 as specified since their respective beginnings, so this change should be compatible enough to pin down in future OpenSSL releases. See also https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00 As a bonus, by not having to deal with sign/verify differences, this version is also somewhat clearer. It also more consistently enforces digest lengths in the verify_recover codepath. The NID_md5_sha1 codepath wasn't quite doing this right.
PKCS openssl#1 v2.0 is the name of a document which specifies an algorithm RSASSA-PKCS1-v1_5, often referred to as "PKCS openssl#1 v1.5" after an earlier document which specified it. This gets further confusing because the document PKCS openssl#1 v2.1 specifies two signature algorithms, RSASSA-PKCS1-v1_5 and RSASSA-PSS. RSA_sign implements RSASSA-PKCS1-v1_5. Refer to the document using the RFC number which is easier to find anyway, and refer to the algorithm by its name.
1eacf71 to
4a23ebf
Compare
|
(And rebased since GitHub was complaining about RSA_sign.pod conflicts.) |
crypto/rsa/rsa_sign.c
Outdated
There was a problem hiding this comment.
Can you add something about the return values?
|
gee, I dunnot about the -.006% coverage drop :) |
|
Probably not, actually. I didn't touch the test program. I'm not entirely clear on how to read the coveralls output. It lists even apps/s_client.c changed which doesn't make sense. I'm probably reading it wrong. Regardless, the only file that could have had meaningful coverage change is
I can see about adding tests for these. |
MD5/SHA1 and MDC-2 have special-case logic beyond the generic DigestInfo wrapping. Test that each of these works, including hash and length mismatches (both input and signature). Also add VerifyRecover tests. It appears 5824cc2 added support for VerifyRecover, but forgot to add the test data.
|
There. That should make the coverage bot happier. :-) |
|
@richsalz: 1.1.0 + master? |
|
yes, both! |
RFC 3447, section 8.2.2, steps 3 and 4 states that verifiers must encode the DigestInfo struct and then compare the result against the public key operation result. This implies that one and only one encoding is legal. OpenSSL instead parses with crypto/asn1, then checks that the encoding round-trips, and allows some variations for the parameter. Sufficient laxness in this area can allow signature forgeries, as described in https://www.imperialviolet.org/2014/09/26/pkcs1.html Although there aren't known attacks against OpenSSL's current scheme, this change makes OpenSSL implement the algorithm as specified. This avoids the uncertainty and, more importantly, helps grow a healthy ecosystem. Laxness beyond the spec, particularly in implementations which enjoy wide use, risks harm to the ecosystem for all. A signature producer which only tests against OpenSSL may not notice bugs and accidentally become widely deployed. Thus implementations have a responsibility to honor the specification as tightly as is practical. In some cases, the damage is permanent and the spec deviation and security risk becomes a tax all implementors must forever pay, but not here. Both BoringSSL and Go successfully implemented and deployed RSASSA-PKCS1-v1_5 as specified since their respective beginnings, so this change should be compatible enough to pin down in future OpenSSL releases. See also https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00 As a bonus, by not having to deal with sign/verify differences, this version is also somewhat clearer. It also more consistently enforces digest lengths in the verify_recover codepath. The NID_md5_sha1 codepath wasn't quite doing this right. Reviewed-by: Kurt Roeckx <[email protected]> Reviewed-by: Rich Salz <[email protected]> GH: #1474
PKCS #1 v2.0 is the name of a document which specifies an algorithm RSASSA-PKCS1-v1_5, often referred to as "PKCS #1 v1.5" after an earlier document which specified it. This gets further confusing because the document PKCS #1 v2.1 specifies two signature algorithms, RSASSA-PKCS1-v1_5 and RSASSA-PSS. RSA_sign implements RSASSA-PKCS1-v1_5. Refer to the document using the RFC number which is easier to find anyway, and refer to the algorithm by its name. Reviewed-by: Kurt Roeckx <[email protected]> Reviewed-by: Rich Salz <[email protected]> GH: #1474
MD5/SHA1 and MDC-2 have special-case logic beyond the generic DigestInfo wrapping. Test that each of these works, including hash and length mismatches (both input and signature). Also add VerifyRecover tests. It appears 5824cc2 added support for VerifyRecover, but forgot to add the test data. Reviewed-by: Kurt Roeckx <[email protected]> Reviewed-by: Rich Salz <[email protected]> GH: #1474
RFC 3447, section 8.2.2, steps 3 and 4 states that verifiers must encode the DigestInfo struct and then compare the result against the public key operation result. This implies that one and only one encoding is legal. OpenSSL instead parses with crypto/asn1, then checks that the encoding round-trips, and allows some variations for the parameter. Sufficient laxness in this area can allow signature forgeries, as described in https://www.imperialviolet.org/2014/09/26/pkcs1.html Although there aren't known attacks against OpenSSL's current scheme, this change makes OpenSSL implement the algorithm as specified. This avoids the uncertainty and, more importantly, helps grow a healthy ecosystem. Laxness beyond the spec, particularly in implementations which enjoy wide use, risks harm to the ecosystem for all. A signature producer which only tests against OpenSSL may not notice bugs and accidentally become widely deployed. Thus implementations have a responsibility to honor the specification as tightly as is practical. In some cases, the damage is permanent and the spec deviation and security risk becomes a tax all implementors must forever pay, but not here. Both BoringSSL and Go successfully implemented and deployed RSASSA-PKCS1-v1_5 as specified since their respective beginnings, so this change should be compatible enough to pin down in future OpenSSL releases. See also https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00 As a bonus, by not having to deal with sign/verify differences, this version is also somewhat clearer. It also more consistently enforces digest lengths in the verify_recover codepath. The NID_md5_sha1 codepath wasn't quite doing this right. Reviewed-by: Kurt Roeckx <[email protected]> Reviewed-by: Rich Salz <[email protected]> GH: #1474 (cherry picked from commit 608a026)
PKCS #1 v2.0 is the name of a document which specifies an algorithm RSASSA-PKCS1-v1_5, often referred to as "PKCS #1 v1.5" after an earlier document which specified it. This gets further confusing because the document PKCS #1 v2.1 specifies two signature algorithms, RSASSA-PKCS1-v1_5 and RSASSA-PSS. RSA_sign implements RSASSA-PKCS1-v1_5. Refer to the document using the RFC number which is easier to find anyway, and refer to the algorithm by its name. Reviewed-by: Kurt Roeckx <[email protected]> Reviewed-by: Rich Salz <[email protected]> GH: #1474 (cherry picked from commit aa90ca1)
MD5/SHA1 and MDC-2 have special-case logic beyond the generic DigestInfo wrapping. Test that each of these works, including hash and length mismatches (both input and signature). Also add VerifyRecover tests. It appears 5824cc2 added support for VerifyRecover, but forgot to add the test data. Reviewed-by: Kurt Roeckx <[email protected]> Reviewed-by: Rich Salz <[email protected]> GH: #1474 (cherry picked from commit f320555)
RFC 3447, section 8.2.2, steps 3 and 4 states that verifiers must encode
the DigestInfo struct and then compare the result against the public key
operation result. This implies that one and only one encoding is legal.
OpenSSL instead parses with crypto/asn1, then checks that the encoding
round-trips, and allows some variations for the parameter. Sufficient
laxness in this area can allow signature forgeries, as described in
https://www.imperialviolet.org/2014/09/26/pkcs1.html
Although there aren't known attacks against OpenSSL's current scheme,
this change makes OpenSSL implement the algorithm as specified. This
avoids the uncertainty and, more importantly, helps grow a healthy
ecosystem. Laxness beyond the spec, particularly in implementations
which enjoy wide use, risks harm to the ecosystem for all. A signature
producer which only tests against OpenSSL may not notice bugs and
accidentally become widely deployed. Thus implementations have a
responsibility to honor the specification as tightly as is practical.
In some cases, the damage is permanent and the spec deviation and
security risk becomes a tax all implementors must forever pay, but not
here. Both BoringSSL and Go successfully implemented and deployed
RSASSA-PKCS1-v1_5 as specified since their respective beginnings, so
this change should be compatible enough to pin down in future OpenSSL
releases.
See also https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00
As a bonus, by not having to deal with sign/verify differences, this
version is also somewhat clearer. It also more consistently enforces
digest lengths in the verify_recover codepath. The NID_md5_sha1 codepath
wasn't quite doing this right.