cms: ECC KeyAgreementRecipientInfo initial support
This PR intends to bring initial support for Elliptic Curve Cryptography (ECC) for CMS - addressing https://github.com/RustCrypto/formats/issues/1544.
- Following rfc5753, it implements
KeyAgreementRecipientInfoBuilderfor ECC. For now onlyEnvelopedDatausing(ephemeral-static) ECDHis supported. - It does not include reader/decryption logic (it could be part of another PR if there is interest).
- It does not support
SHA1and3DESschemes (For SHA1, it could maybe be introduced and gated behind a feature to parse/read/decrypt older/legacy incoming CMS message that use them. However RustCrypto does not seem to support 3DES key wrap)
-
Utils functions:
- KDF and key-wrapping operation are hosted in their own submodules.
- Key-derivation uses an internal
HashDigestenum to select the hash function to use during key-derivation -
KeyWrapperis a struct that aims at abstracting the key-wrapping logic for different AES algorithm and different incoming key size.
-
Key Agreement Recipient Info:
-
KeyAgreementRecipientInfoBuilderis hosted in its own submodule. - Supported schemes and algorithm are represented using enums. At least three are needed for the builder:
-
EcKeyEncryptionInfo- recipient public key (generic over RustCrypto elliptic-curve). WhileEcKeyEncryptionInfois essentially the ECC equivalent of the existingKeyEncryptionInfo, it has been introduced to limit API breakage - as it introduces a generic over the chosen elliptic-curve. -
KeyAgreementAlgorithm- key agreement as per RFC (SHA1 schemes are not supported on purpose, can be amended if needed). -
KeyWrapAlgorithm- key-wrap algorithm to use. For the sake of simplicityFrom<ContentEncryptionAlgorithm> for KeyWrapAlgorithmtrait has been implemented.
-
-
-
Testing: Unit tests have been written in the relevant files. One integration test showcasing
KeyAgreeRecipientInfoBuilderis available, leveraging the existing test P256 key material. Obtained message can be decrypted using:openssl cms -decrypt -inkey cms/tests/examples/p256-priv.der -inform PEM
Fixes #1544
@nemynm can you rebase?
@nemynm can you rebase?
Sure will do, I'll also mark it as draft untill changes done during initial review by @baloo have been included.
I can't merge this before we re-integrate x509 and cms in the workspace. I'll need to revisit once that's done. Sorry for the delay.
No worries, in the meantime I'll rebase the PR regularly.
I don't know if rebase is something you can do until we re-unite the workspace (or worth it)
Could you either merge master or rebase? Thanks a lot!
yes working on a rebase right now
@baloo rebased it is. I had a few issues solving the dependency tree:
- I had to patch
async-signaturefrom git to bring it in sync withsignature - patching
ansi-x963-kdffrom its specificmasterbranch does not seem necessary after the fact, but somehow helped cargo figuring it out, so I left it for now.
Also some adjustments with latest CryptoRng changes.
Let me know any other needed adjustments.
async-signature should be deprecated now (it moved to signature)
Could you try this patch:
diff --git a/Cargo.lock b/Cargo.lock
index c0bbcbbe35..2029b3663e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -77,7 +77,7 @@
[[package]]
name = "ansi-x963-kdf"
version = "0.0.1"
-source = "git+https://github.com/RustCrypto/KDFs.git?branch=master#b1d7fe67b3053deef498563adcf415ec631d1cd8"
+source = "git+https://github.com/RustCrypto/KDFs.git#b1d7fe67b3053deef498563adcf415ec631d1cd8"
dependencies = [
"digest",
]
@@ -98,14 +98,6 @@
]
[[package]]
-name = "async-signature"
-version = "0.6.0-pre.4"
-source = "git+https://github.com/RustCrypto/traits.git#2dc47f8d1461a2a7a22b68e2afafeb4b59e13420"
-dependencies = [
- "signature",
-]
-
-[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -309,7 +301,6 @@
"aes",
"aes-kw",
"ansi-x963-kdf",
- "async-signature",
"cbc",
"cipher",
"const-oid",
diff --git a/Cargo.toml b/Cargo.toml
index 87074a1173..490f768d86 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -72,17 +72,14 @@
# https://github.com/RustCrypto/key-wraps/pull/39
aes-kw = { git = "https://github.com/RustCrypto/key-wraps.git" }
-
# https://github.com/RustCrypto/KDFs/pull/102
-ansi-x963-kdf = { git = "https://github.com/RustCrypto/KDFs.git", branch = "master" }
-
+ansi-x963-kdf = { git = "https://github.com/RustCrypto/KDFs.git" }
# https://github.com/RustCrypto/traits/pull/1777
crypto-common = { git = "https://github.com/RustCrypto/traits.git" }
elliptic-curve = { git = "https://github.com/RustCrypto/traits.git" }
signature = { git = "https://github.com/RustCrypto/traits.git" }
aead = { git = "https://github.com/RustCrypto/traits.git" }
-async-signature = { git = "https://github.com/RustCrypto/traits.git" }
# https://github.com/RustCrypto/RSA/pull/478
# https://github.com/RustCrypto/RSA/pull/504
diff --git a/cms/Cargo.toml b/cms/Cargo.toml
index 57d54a337f..257ebb6791 100644
--- a/cms/Cargo.toml
+++ b/cms/Cargo.toml
@@ -24,7 +24,6 @@
aes = { version = "=0.9.0-pre.3", optional = true }
aes-kw = { version ="=0.3.0-pre", optional = true }
ansi-x963-kdf = { version = "0.0.1", optional = true }
-async-signature = { version = "=0.6.0-pre.4", features = ["digest", "rand_core"], optional = true }
cbc = { version = "=0.2.0-pre.2", optional = true }
cipher = { version = "=0.5.0-pre.8", features = ["alloc", "block-padding", "rand_core"], optional = true }
digest = { version = "0.11.0-pre.10", optional = true }
@@ -56,7 +55,6 @@
"dep:aes",
"dep:aes-kw",
"dep:ansi-x963-kdf",
- "dep:async-signature",
"dep:cbc",
"dep:cipher",
"dep:digest",
Thanks a lot!