* first python API proposition
first round-trip tests
feat: made asn1 structures readable
refacto: adapted existing functions accordingly
feat/pkcs12: added symmetric_decrypt
feat: deserialize 3 possible encodings
feat: handling AES-128
feat: raise error when no recipient is found
feat/pkcs7: added decanonicalize function
feat/asn1: added decode_der_data
feat/pkcs7: added smime_enveloped_decode
tests are the round-trip (encrypt & decrypt)
more tests for 100% python coverage
test support pkcs7_encrypt with openssl
added algorithm to pkcs7_encrypt signature
refacto: decrypt function is clearer
flow is more natural
refacto: added all rust error tests
refacto: added another CA chain for checking
fix: const handling
Refactor PKCS7Decryptor to pkcs7_decrypt
refacto: removed SMIME_ENVELOPED_DECODE from rust code
refacto: removed decode_der_data
adapted tests accordingly
removed the PEM tag check
added tests for smime_decnonicalize
one more test case
Update src/rust/src/pkcs7.rs
Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>
took comments into account
pem to der is now outside of decrypt
fix: removed test_support pkcs7_encrypt
added vector for aes_256_cbc encrypted pkcs7
feat: not using test_support decrypt anymore
added new vectors for PKCS7 tests
feat: using pkcs7 vectors
removed previous ones
fix: changed wrong function
feat: added certificate issuer check
test: generating the RSA chain
removed the vectors accordingly
moved symmetric_decrypt to pkcs7.rs
* Update src/cryptography/hazmat/primitives/serialization/pkcs7.py
Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>
* fix: removed use of deprecated new_bound for PyBytes
* corrected some error types
* updated tests accordingly
* fix: handling other key encryption algorithms
added vectors & tests accordingly
* first attempts raising error when no header to remove
* one more test to handle text data without header
* fix: went back to the previous implementation
* refacto: removed the return part
* feat: Binary option does not seem useful for decryption
removed decanonicalization function
adapted tests accordingly
* moved logic into rust
only left some checks (for now?)
* removed pyfunction for the inner decrypt one
* added checks in rust now :)
changed name for clarity
* removed unused function
* some checks not needed anymore
* removed a parameter
* took comments into account
* removed unused import
removed excess get_type
* added first unwrap corrections
cleaned tests, added some others
added more vectors
* no more unwrap for parameter checks
* removing headers is Python now
added tests accordingly
will compare with OpenSSL
* final corrections?
* first version of documentation
some minor refactoring
* corrected doctests
* better indentation
* doctest: added RSA private key
* oops
---------
Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>
* argon2id support
* make it all rust now
* set a threadpool number
* address comments
* set threadpool to max(available, current)
* review comments
* a few more improvements
* Update docs/hazmat/primitives/key-derivation-functions.rst
Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>
---------
Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>
* feat: implement parsing of admissions extension
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: add tests for admissions extension parsing
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: use cryptography result return type
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: apply fixes done by cargo fmt and clippy
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* add gematik company name and the gmbh abbreviations to known words
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: regenerate the synthetic certificate with additional admission covering the case of naming authority with no data
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: parse none for profession_oids if profession_oids is none
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: apply formatting to changes in rust codebase
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* refactor: switch return type of parse_profession_infos from PyObject to Bound<PyAny>
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* refactor: switch return type of parse_naming_authority from PyObject to Bound<PyAny>
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* refactor: switch return type of parse_admissions from PyObject to Bound<PyAny>
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* chore: remove gematik certs from repo
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* chore: remove gematik certs from this pr
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* chore: extend parser tests with an additional synthetic certificate to complete rust coverage
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* chore: add description for the additional certificate without authority
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* use into_bound(py) as shortcut, refrain from using to_object() in all added functions
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* add better description for the admissions synthetic cert
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* adjust description to avoid using misspelled words
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
---------
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* Speedup rsa_recover_prime_factors() by using random value
* Comply with ruff codingstyle
* Reject invalid combinations of n, d, e early to avoid excessive runtime
* Add second failure test case for rsa_recover_prime_factors to hit early error path
* Remove leftover debug code
* Reduce _MAX_RECOVERY_ATTEMPTS and remove obsolete comment
Previously, the code would increase a in steps of 2, therefore,
_MAX_RECOVERY_ATTEMPTS was twice the number of tries. With the new
code, this is no longer the case.
* feat: implement encoding of admissions extension
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: add encoding tests
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* refactor: split encoding of inner objects into separate functions
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: simplify code comment to pass the line length checks
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: add test to check encoding of none values
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: extend none values test to also check encoding of naming authority with none values
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: use none checks when converting python data
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: raise a valueerror if the url can not be encoded to an ia5string
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: revert to truthness check for py_oids for now, will be amended in a separate pr
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: raise a valueerror if the registration_number can not be encoded to a printablestring
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: encode none for profession_oids if profession_oids is none
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
---------
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* feat(admissions): add profession info python type for the admissions extension
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* feat(admissions): add profession info rust type for the admissions extension
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* feat(admissions): add test for profession info hash implementation
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix(admissions): minor fixes
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* remove the asn1 traits from the profession info rust type
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* remove the explicit mark from the naming authority field
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: add commented out annotation for the naming authority field
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* fix: use correct type for add_profeccion_info field
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* refactor: explicitly convert profession items and oids to tuples for hash calculation
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* refactor: add asn1 trait derives to naming authority and profession info types, commented out
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
---------
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
* feat(admissions): add naming authority python type for the admissions extension
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* feat(admissions): user short names for naming authority fields
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* feat(admissions): add naming authority rust type for the admissions extension
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: use assert_eq macro for value comparison in naming authority test
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* chore: drop useless test for naming authority rust type
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* fix: correct the naming authority text type
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
---------
Signed-off-by: oleg.hoefling <oleg.hoefling@gmail.com>
* Per RFC5280 Section 5.2.5, the Issuing Distribution Point extension in a CRL can have only one of onlyContainsUserCerts, onlyContainsCACerts, onlyContainsAttributeCerts set to TRUE. However, extensions.py (lines 1991 : 2003), indirectCRL is also included, which leads to invalid CRL even if the RFC requirement is met. The proposed fix is to drop indirectCRL from the check so it conforms to the RFC.
* Made the comment shorter per line to meet the format requirement.
Removed a invalid test case for IDP
* Add CustomPolicyBuilder foundation.
* Add EKU getters to ClientVerifier and ServerVerifier.
* Document the implemented part of custom verification.
* Remove `subject` field from VerifiedClient, rename `sans` back to `subjects`.
* Remove EKU-related setters, getters and documentation from this PR.
* Use double backticks in reStructuredText.
* Remove CustomPolicyBuilder in favor of extending PolicyBuilder.
* Code style improvements.
* Resolve coverage issues.
* silencing the mmap mypy warning on windows
even though the lib doesn't exist on this platform
* better way without coverage issues
* trying with pragma no cover :(
* using type: ignore
* another test with pragma: no cover
* testing type: ignore with specific exclusions
* Relax root CA AKI field checks
Closes#11461.
Signed-off-by: William Woodruff <william@yossarian.net>
* CHANGELOG: record changes
Signed-off-by: William Woodruff <william@yossarian.net>
---------
Signed-off-by: William Woodruff <william@yossarian.net>
* Remove unnecessary test dependencies on RSA-512
test_unsupported_hash and test_prehashed_digest_mismatch work just fine
with realistic RSA key sizes. (They also, as written, silently test
nothing when the backend rejects RSA-512. As a reminder, RSA-512 was
broken since 1999.)
test_rsa_fips_small_key wants a small key, but I assume RSA-1024 is
fine.
* Keep using RSA-512 for test_rsa_fips_small_key as a RHEL-8 accommodation
* Bump RSA-512 test keys to RSA-2048
RSA-512 was broken in 1999. cryptography.io should not be requesting
its backend library support it in 2024.
* Update test-vectors.rst
The replacement keys were generated fresh, and this document seems to
just cite the external ones.
* Document custom test vectors
* extensions: EKU must contain at least one member
Signed-off-by: William Woodruff <william@trailofbits.com>
* record changes
Signed-off-by: William Woodruff <william@trailofbits.com>
* empty EKU test vector
Signed-off-by: William Woodruff <william@trailofbits.com>
* typo
Signed-off-by: William Woodruff <william@trailofbits.com>
---------
Signed-off-by: William Woodruff <william@trailofbits.com>
* Add support for encrypting S/MIME messages
* Move PKCS7 decrypt test function to Rust
* Use symmetric encryption function from PKCS12
* Remove debug file write from tests
* Remove unneeded backend parameter
* docs and changelog
* Move rust code that exists for our tests to its own module
* Update src/rust/src/test_support.rs
Co-authored-by: Paul Kehrer <paul.l.kehrer@gmail.com>
---------
Co-authored-by: Paul Kehrer <paul.l.kehrer@gmail.com>
Given the RSA public exponent (`e`), and the RSA primes (`p`, `q`), it is possible
to calculate the corresponding private exponent `d = e⁻¹ mod λ(n)` where
`λ(n) = lcm(p-1, q-1)`.
With this function added, it becomes possible to use the library to reconstruct an RSA
private key given *only* `p`, `q`, and `e`:
from cryptography.hazmat.primitives.asymmetric import rsa
n = p * q
d = rsa.rsa_recover_private_exponent(e, p, q) # newly-added piece
iqmp = rsa.rsa_crt_iqmp(p, q) # preexisting
dmp1 = rsa.rsa_crt_dmp1(d, p) # preexisting
dmq1 = rsa.rsa_crt_dmq1(d, q) # preexisting
assert rsa.rsa_recover_prime_factors(n, e, d) in ((p, q), (q, p)) # verify consistency
privk = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, rsa.RSAPublicNumbers(e, n)).private_key()
Older RSA implementations, including the original RSA paper, often used the
Euler totient function `ɸ(n) = (p-1) * (q-1)` instead of `λ(n)`. The
private exponents generated by that method work equally well, but may be
larger than strictly necessary (`λ(n)` always divides `ɸ(n)`). This commit
additionally implements `_rsa_recover_euler_private_exponent`, so that tests
of the internal structure of RSA private keys can allow for either the Euler
or the Carmichael versions of the private exponents.
It makes sense to expose only the more modern version (using the Carmichael
totient function) for public usage, given that it is slightly more
computationally efficient to use the keys in this form, and that some
standards like FIPS 186-4 require this form. (See
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#page=63)
* utils: guard against zero-length int_to_bytes
* add tests for HBKDF with llen=0
* kbkdf: guard against llen==0
* test that kbkdf rejects llen==0 at __init__
* add standalone test for zero-length int_to_bytes
* Update src/cryptography/hazmat/primitives/kdf/kbkdf.py
typo
Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>
---------
Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>