Fix ASN.1 issues in PKCS#7 and S/MIME signing#10373
Merged
Conversation
Member
|
Haven't re-reviewed the RFC, but we should add a test for this. |
2e5b1e2 to
67c1a60
Compare
2755b62 to
1f797f8
Compare
alex
reviewed
Feb 18, 2024
src/rust/src/pkcs7.rs
Outdated
| if key_type == x509::sign::KeyType::Rsa && !has_pss_padding { | ||
| Ok(common::AlgorithmIdentifier { | ||
| oid: asn1::DefinedByMarker::marker(), | ||
| params: common::AlgorithmParameters::Rsa(None), |
Member
There was a problem hiding this comment.
Suggested change
| params: common::AlgorithmParameters::Rsa(None), | |
| params: common::AlgorithmParameters::Rsa(Some(())), |
src/rust/src/pkcs7.rs
Outdated
| rsa_padding: &'p pyo3::PyAny, | ||
| ) -> pyo3::PyResult<common::AlgorithmIdentifier<'static>> { | ||
| let key_type = x509::sign::identify_key_type(py, private_key)?; | ||
| let has_pss_padding = !rsa_padding.is_none() && rsa_padding.is_instance(types::PSS.get(py)?)?; |
Member
There was a problem hiding this comment.
Suggested change
| let has_pss_padding = !rsa_padding.is_none() && rsa_padding.is_instance(types::PSS.get(py)?)?; | |
| let has_pss_padding = rsa_padding.is_instance(types::PSS.get(py)?)?; |
I don't think the is_none() check is required? None isn't an instance of PSS :-)
Contributor
Author
There was a problem hiding this comment.
Ah, I got that code from
cryptography/src/rust/src/x509/sign.rs
Lines 135 to 137 in 50ea0fa
Member
There was a problem hiding this comment.
Probably that should be fixed, but no need to do it in this PR.
The current implementation defines the SMIMECapabilities attribute
so that its value is a SEQUENCE of all the algorithm OIDs that are
supported.
However, the S/MIME v3 spec (RFC 2633) specifies that each algorithm
should be specified in its own SEQUENCE:
SMIMECapabilities ::= SEQUENCE OF SMIMECapability
SMIMECapability ::= SEQUENCE {
capabilityID OBJECT IDENTIFIER,
parameters ANY DEFINED BY capabilityID OPTIONAL }
(RFC 2633, Appendix A)
This commit changes the implementation so that each algorithm
is inside its own SEQUENCE. This also matches the OpenSSL
implementation.
The current implementation computes the algorithm identifier used
in the `digest_encryption_algorithm` PKCS#7 field
(or `SignatureAlgorithmIdentifier` in S/MIME) based on both the
algorithm used to sign (e.g. RSA) and the digest algorithm (e.g. SHA512).
This is correct for ECDSA signatures, where the OIDs used include the
digest algorithm (e.g: ecdsa-with-SHA512). However, due to historical
reasons, when signing with RSA the OID specified should be the one
corresponding to just RSA ("1.2.840.113549.1.1.1" rsaEncryption),
rather than OIDs which also include the digest algorithm (such as
"1.2.840.113549.1.1.13", sha512WithRSAEncryption).
This means that the logic to compute the algorithm identifier is the
same except when signing with RSA, in which case the OID will always
be `rsaEncryption`. This is consistent with the OpenSSL implementation,
and the RFCs that define PKCS#7 and S/MIME.
See RFC 3851 (section 2.2), and RFC 3370 (section 3.2) for more details.
1f797f8 to
99f6aba
Compare
Contributor
Author
|
@alex I also added an item to the CHANGELOG |
alex
approved these changes
Feb 20, 2024
alex
pushed a commit
to alex/cryptography
that referenced
this pull request
Feb 20, 2024
* Fix ASN.1 for S/MIME capabilities.
The current implementation defines the SMIMECapabilities attribute
so that its value is a SEQUENCE of all the algorithm OIDs that are
supported.
However, the S/MIME v3 spec (RFC 2633) specifies that each algorithm
should be specified in its own SEQUENCE:
SMIMECapabilities ::= SEQUENCE OF SMIMECapability
SMIMECapability ::= SEQUENCE {
capabilityID OBJECT IDENTIFIER,
parameters ANY DEFINED BY capabilityID OPTIONAL }
(RFC 2633, Appendix A)
This commit changes the implementation so that each algorithm
is inside its own SEQUENCE. This also matches the OpenSSL
implementation.
* Fix the RSA OID used for signing PKCS#7/SMIME
The current implementation computes the algorithm identifier used
in the `digest_encryption_algorithm` PKCS#7 field
(or `SignatureAlgorithmIdentifier` in S/MIME) based on both the
algorithm used to sign (e.g. RSA) and the digest algorithm (e.g. SHA512).
This is correct for ECDSA signatures, where the OIDs used include the
digest algorithm (e.g: ecdsa-with-SHA512). However, due to historical
reasons, when signing with RSA the OID specified should be the one
corresponding to just RSA ("1.2.840.113549.1.1.1" rsaEncryption),
rather than OIDs which also include the digest algorithm (such as
"1.2.840.113549.1.1.13", sha512WithRSAEncryption).
This means that the logic to compute the algorithm identifier is the
same except when signing with RSA, in which case the OID will always
be `rsaEncryption`. This is consistent with the OpenSSL implementation,
and the RFCs that define PKCS#7 and S/MIME.
See RFC 3851 (section 2.2), and RFC 3370 (section 3.2) for more details.
* Add tests for the changes in PKCS7 signing
* PKCS7 fixes from code review
* Update CHANGELOG
reaperhulk
pushed a commit
that referenced
this pull request
Feb 21, 2024
* Fix ASN.1 for S/MIME capabilities.
The current implementation defines the SMIMECapabilities attribute
so that its value is a SEQUENCE of all the algorithm OIDs that are
supported.
However, the S/MIME v3 spec (RFC 2633) specifies that each algorithm
should be specified in its own SEQUENCE:
SMIMECapabilities ::= SEQUENCE OF SMIMECapability
SMIMECapability ::= SEQUENCE {
capabilityID OBJECT IDENTIFIER,
parameters ANY DEFINED BY capabilityID OPTIONAL }
(RFC 2633, Appendix A)
This commit changes the implementation so that each algorithm
is inside its own SEQUENCE. This also matches the OpenSSL
implementation.
* Fix the RSA OID used for signing PKCS#7/SMIME
The current implementation computes the algorithm identifier used
in the `digest_encryption_algorithm` PKCS#7 field
(or `SignatureAlgorithmIdentifier` in S/MIME) based on both the
algorithm used to sign (e.g. RSA) and the digest algorithm (e.g. SHA512).
This is correct for ECDSA signatures, where the OIDs used include the
digest algorithm (e.g: ecdsa-with-SHA512). However, due to historical
reasons, when signing with RSA the OID specified should be the one
corresponding to just RSA ("1.2.840.113549.1.1.1" rsaEncryption),
rather than OIDs which also include the digest algorithm (such as
"1.2.840.113549.1.1.13", sha512WithRSAEncryption).
This means that the logic to compute the algorithm identifier is the
same except when signing with RSA, in which case the OID will always
be `rsaEncryption`. This is consistent with the OpenSSL implementation,
and the RFCs that define PKCS#7 and S/MIME.
See RFC 3851 (section 2.2), and RFC 3370 (section 3.2) for more details.
* Add tests for the changes in PKCS7 signing
* PKCS7 fixes from code review
* Update CHANGELOG
Co-authored-by: Facundo Tuesca <facundo.tuesca@trailofbits.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes two issues with the ASN.1 generated when signing using PKCS#7:
First issue
The current implementation defines the SMIMECapabilities attribute so that its value is a SEQUENCE of all the algorithm OIDs that are supported. This is what the ASN.1 currently looks like for a signed message using
cryptography:However, the S/MIME v3 spec (RFC 2633) specifies that each algorithm should be specified in its own SEQUENCE:
(RFC 2633, Appendix A)
The spec matches what OpenSSL outputs (using
openssl smime -sign):This PR changes the implementation so that each algorithm is inside its own SEQUENCE. After the changes in this PR, the ASN.1 output looks like:
Second issue
There is an issue with the RSA OID used for signing PKCS#7/SMIME, in the
SignatureAlgorithmIdentifierfield.The current implementation computes the algorithm identifier used in the
digest_encryption_algorithmPKCS#7 field(or
SignatureAlgorithmIdentifierin S/MIME) based on both the algorithm used to sign (e.g. RSA) and the digest algorithm (e.g. SHA512).This is correct for ECDSA signatures, where the OIDs used include the digest algorithm (e.g:
ecdsa-with-SHA512). However, due to historical reasons, when signing with RSA the OID specified should be the onecorresponding to just RSA (
"1.2.840.113549.1.1.1" rsaEncryption), rather than OIDs which also include the digest algorithm (such as"1.2.840.113549.1.1.13" sha512WithRSAEncryption).This means that the logic to compute the algorithm identifier is the same except when signing with RSA, in which case the OID will always be
rsaEncryption. This is consistent with the OpenSSL implementation, and the RFCs that define PKCS#7 and S/MIME.See RFC 3851 (section 2.2), and RFC 3370 (section 3.2) for more details.