formats icon indicating copy to clipboard operation
formats copied to clipboard

cms: ECC KeyAgreementRecipientInfo initial support

Open nemynm opened this issue 1 year ago • 5 comments

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 KeyAgreementRecipientInfoBuilder for ECC. For now only EnvelopedData using (ephemeral-static) ECDH is supported.
  • It does not include reader/decryption logic (it could be part of another PR if there is interest).
  • It does not support SHA1 and 3DES schemes (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)
  1. Utils functions:

    • KDF and key-wrapping operation are hosted in their own submodules.
    • Key-derivation uses an internal HashDigest enum to select the hash function to use during key-derivation
    • KeyWrapper is a struct that aims at abstracting the key-wrapping logic for different AES algorithm and different incoming key size.
  2. Key Agreement Recipient Info:

    • KeyAgreementRecipientInfoBuilder is 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). While EcKeyEncryptionInfo is essentially the ECC equivalent of the existing KeyEncryptionInfo, 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 simplicity From<ContentEncryptionAlgorithm> for KeyWrapAlgorithm trait has been implemented.
  3. Testing: Unit tests have been written in the relevant files. One integration test showcasing KeyAgreeRecipientInfoBuilder is 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 avatar Oct 20 '24 15:10 nemynm

@nemynm can you rebase?

tarcieri avatar Jan 21 '25 18:01 tarcieri

@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.

nemynm avatar Jan 22 '25 02:01 nemynm

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.

baloo avatar Feb 25 '25 04:02 baloo

No worries, in the meantime I'll rebase the PR regularly.

nemynm avatar Feb 25 '25 13:02 nemynm

I don't know if rebase is something you can do until we re-unite the workspace (or worth it)

baloo avatar Feb 25 '25 19:02 baloo

Could you either merge master or rebase? Thanks a lot!

baloo avatar Apr 20 '25 14:04 baloo

yes working on a rebase right now

nemynm avatar Apr 20 '25 14:04 nemynm

@baloo rebased it is. I had a few issues solving the dependency tree:

  • I had to patch async-signature from git to bring it in sync with signature
  • patching ansi-x963-kdf from its specific master branch 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.

nemynm avatar Apr 20 '25 22:04 nemynm

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",

baloo avatar Apr 21 '25 16:04 baloo

Thanks a lot!

baloo avatar Apr 21 '25 18:04 baloo