-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add support for verifying S/MIME messages #12267
base: main
Are you sure you want to change the base?
Conversation
The existing apis for cert verification are in
cryptography.x509.verification
…On Fri, Jan 10, 2025, 9:32 AM Quentin Retourne ***@***.***> wrote:
As promised in #11555 <#11555>,
I'm opening this PR with an initial implementation of S/MIME verification,
in order to better discuss the API design, and to start the reviews while I
finish some other features.
Namely, the new pkcs7_verify functions do not handle the certificate
verification feature as of now. It as similar to a openssl smime -verify
with the -noverify flag, to verify the signature but not the certificates
(similar to what #12116 <#12116>
needs). Can you point me towards some existing code verifying X.509
certificates, if some exists?
Also, I have one question about the certificate parameter in the
functions: should we verify against one certificates? Multiple ones? All
the ones that are stored in the signature (if any)?
My essential thoughts for testing were to do the round-trip: signature
using the PKCS7SignatureBuilder and verifying using the pkcs_decrypt
functions. For now, I've not replaced the test_support.pkcs7_verify
function, but I'm planning to do so as soon as the certificate verification
feature is developed.
I'm still new to rust, so please let me know if you see some issues in
variable lifetime, or some unnecessary copying between Python & Rust.
cc @alex <https://github.com/alex>
------------------------------
You can view, comment on, or merge this pull request online at:
#12267
Commit Summary
- 794db04
<794db04>
PKCS7 signing (first version)
File Changes
(9 files <https://github.com/pyca/cryptography/pull/12267/files>)
- *M* CHANGELOG.rst
<https://github.com/pyca/cryptography/pull/12267/files#diff-2c623f3c6a917be56c59d43279244996836262cb1e12d9d0786c9c49eef6b43c>
(4)
- *M* docs/development/test-vectors.rst
<https://github.com/pyca/cryptography/pull/12267/files#diff-abc63e746ffc66f83cffdf369028671e53de77b100eb528f517f16f41201f3f7>
(3)
- *M* docs/hazmat/primitives/asymmetric/serialization.rst
<https://github.com/pyca/cryptography/pull/12267/files#diff-7c2790036c595946b546ceec3cb5dc5125b4f6223761a6684f577e70fb49d458>
(148)
- *M* src/cryptography/hazmat/bindings/_rust/pkcs7.pyi
<https://github.com/pyca/cryptography/pull/12267/files#diff-836c9b03108b81b3659a23a89d2c5fdddab94ca204686c4e71afcb7e433a7f87>
(28)
- *M* src/cryptography/hazmat/primitives/serialization/pkcs7.py
<https://github.com/pyca/cryptography/pull/12267/files#diff-0075be2b09cefb4b36a4646255d3e1bea05c99b6e3ffd141a08aa528de9741c3>
(34)
- *M* src/rust/src/pkcs7.rs
<https://github.com/pyca/cryptography/pull/12267/files#diff-8ca3ed0edb153cd77f373e5e5856e6f1fc559cddcc5ebf91cc690a7aed7f0a3a>
(167)
- *M* src/rust/src/types.rs
<https://github.com/pyca/cryptography/pull/12267/files#diff-4eb6bcd40dbc27bf39e7b1c1e694d48c28fec6579d4ab1cb0a7b3ad65f9d2228>
(5)
- *M* tests/hazmat/primitives/test_pkcs7.py
<https://github.com/pyca/cryptography/pull/12267/files#diff-ee3cc87634fba3d98c17ee2dbcb575f63f33603a5ab7ac9fa7bcc3b17bced6a3>
(169)
- *A* vectors/cryptography_vectors/pkcs7/signed-opaque.msg
<https://github.com/pyca/cryptography/pull/12267/files#diff-566d9755c6ec5055a0a4ca69a7a0b94f91d23d42491be4d6a591e88fad57f0f4>
(21)
Patch Links:
- https://github.com/pyca/cryptography/pull/12267.patch
- https://github.com/pyca/cryptography/pull/12267.diff
—
Reply to this email directly, view it on GitHub
<#12267>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAAGBF2ULFD3GXMBFEJ3432J7KZJAVCNFSM6AAAAABU6QAS7KVHI2DSMVQWIX3LMV43ASLTON2WKOZSG44DAMZSG42DQNY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
raise ValueError( | ||
"Malformed multipart/signed message: must be multipart" | ||
) | ||
if not isinstance(payload[0], email.message.Message): |
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.
Here, I'm not managing to create any test case (specific MIME message) that would raise this error. However, according to mypy
, the case is still possible. Should I go with an assert
in order to please mypy
or have you got any idea on how the parts could be some text and not an email.message.Message
?
@alex, for now I'm trying the following code: def _verify_pkcs7_certificates(certificates: list[x509.Certificate]) -> None:
builder = PolicyBuilder().store(Store(certificates))
verifier = builder.build_client_verifier()
verifier.verify(certificates[0], certificates[1:]) However, I'm getting the following error:
To be honest, I'm not clear as to what we are supposed to do in certificate verification. I've not found anything specific in the RFC, but I'll keep looking. If you can guide me through this, I'd love some help 🛩️ |
Basically certificates used as end entities (i.e., the cert used to sign a PKCS#7/SMIME message) should not hvae ca=true in their basic constraints extension. I can't remember which spec that comes from, but its a general best practice in any event /cc @woodruffw |
Yep, that comes from CABF -- we have a test and cite for it here: https://x509-limbo.com/testcases/webpki/#webpkica-as-leaf. (RFC 5280 doesn't impose the requirement that the EE not be a CA, but firmly agreed about it being best practice.) |
OK, that raises two things for me:
let certs = openssl::stack::Stack::new()?;
p7.verify(
&certs,
&store,
msg.as_ref().map(|m| m.as_bytes()),
None,
flags,
)?; |
no certificate verification as of now handling PEM, DER, SMIME formats added tests & documentation accordingly
5f06262
to
f2f9be4
Compare
certificate is now optional feat: handling RSA case feat: No signature parameter adapted tests accordingly
fix: passed into Cow again coverage: added one test case
@alex this should be ready for review, the tests are passing. A few considerations to keep in mind:
Keep in mind that for now, I've used a certificate chain from endesive to make the tests pass, but I'll work on creating new Some more things about the certs:
CC @reaperhulk @facutuesca if you miraculously have time for a review 😄 |
Stumbled on #12104 and realized we might have the same issue with the certificate verification code! |
Sorry I've been slow here, it's on my TODO list for this week.
…On Mon, Jan 20, 2025 at 10:13 AM Quentin Retourne ***@***.***> wrote:
@nitneuqr <https://github.com/nitneuqr> requested your review on: #12267
<#12267> Add support for
verifying S/MIME messages.
—
Reply to this email directly, view it on GitHub
<#12267 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAAGBBDZHEQAET2H44MH7L2LUHAXAVCNFSM6AAAAABU6QAS7KVHI2DSMVQWIX3LMV45UABCJFZXG5LFIV3GK3TUJZXXI2LGNFRWC5DJN5XDWMJWGAYDANBRG4ZDKMY>
.
You are receiving this because your review was requested.Message ID:
***@***.***>
--
All that is necessary for evil to succeed is for good people to do nothing.
|
No worries! Just checking in in case you forgot about it 😊 |
As promised in #11555, I'm opening this PR with an initial implementation of S/MIME verification, in order to better discuss the API design, and to start the reviews while I finish some other features.
Namely, the new
pkcs7_verify
functions do not handle the certificate verification feature as of now. It as similar to aopenssl smime -verify
with the-noverify
flag, to verify the signature but not the certificates (similar to what #12116 needs). Can you point me towards some existing code verifying X.509 certificates, if some exists?Also, I have one question about the
certificate
parameter in the functions: should we verify against one certificates? Multiple ones? All the ones that are stored in the signature (if any)?My essential thoughts for testing were to do the round-trip: signature using the
PKCS7SignatureBuilder
and verifying using thepkcs_decrypt
functions. For now, I've not replaced thetest_support.pkcs7_verify
function, but I'm planning to do so as soon as the certificate verification feature is developed.I'm still new to rust, so please let me know if you see some issues in variable lifetime, or some unnecessary copying between Python & Rust.
cc @alex