Repository navigation
feat(cms)!: encrypt content to an EC public key with ECDH key agreement - #291
Merged
Merged
Conversation
encrypt_data reads a P-256 or P-384 key as `recipient:`. The container carries a KeyAgreeRecipientInfo: an ephemeral key on the recipient's curve, the X9.63 KDF over SHA-256 for P-256 and SHA-384 for P-384 (RFC 5753), and the content-encryption key under AES-256 key wrap. The recipient is named by its fingerprint, as a ktri's is. The ephemeral private key is drawn from the step's backend, as the content key is, since whoever knows it derives the key-encryption key. Opening is split where a card splits it. A new KeyAgreementBackend trait runs the Diffie-Hellman agreement with the key the backend holds and returns an AgreedSecret, and the host derives the wrap key and unwraps, so the trait stays the same whatever container format runs its KDF over the secret. Its doc is the contract a PIV, PKCS#11 or TPM backend implements against. The OpenSSL backend implements it. An EC key opens by key agreement, which PKCS#11 permits under CKA_DERIVE, so agree and unwrap_key under an EC key require the derive usage. KeyUsages::to_open names the usage per algorithm, and a refused usage says which one the step needs. cms::Envelope carries a RecipientInfo enum, one variant per recipient form with that form's fields, in place of a protection, an identifier and a protected key that had to agree. A provider-defined protection cannot be put in a container, and decrypt_data matches on the form to know what opening takes. PublicKeyDer refuses an EC key whose point is compressed: the same key under another encoding would have another fingerprint, and converting it takes curve arithmetic rite-sdk does not carry. A container whose ephemeral point is compressed is refused when opened, by name. Both directions are checked against openssl cms with ecdh_kdf_md, and the CLI's default SHA-1 derivation is refused by name. A kari naming several recipient keys is described by its first and refused when opened. BREAKING CHANGE: an EC key that opens what wrap_key or encrypt_data sealed to it needs `usages: [derive]`; `unwrap` does not permit it. PublicKeyDer refuses compressed EC points, so a key, certificate or CSR carrying one is refused wherever it is read. Closes #202
encrypt_and_decrypt seals the runbook a second time, to the public key of a P-256 custodian key granted the derive usage, opens it under that key, and compares the digests. rite verify checks the container against the recorded recipient. The wrap_and_unwrap comment on EC transport keys names the usages such a key needs.
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.
encrypt_dataseals content to a P-256 or P-384 public key through a CMSKeyAgreeRecipientInfo: ECDH with an ephemeral key drawn from the step's backend, the X9.63 KDF over SHA-256 or SHA-384 (RFC 5753), and AES-256 key wrap.decrypt_dataopens it, and opens one sealed byopenssl cmswithecdh_kdf_md. Both directions are checked against the OpenSSL CLI.Opening goes through a new
KeyAgreementBackendtrait: the backend agrees the secret with the key it holds and returns it as anAgreedSecret, and the host runs the KDF and the unwrap. The OpenSSL backend implements it; the PIV backend is a follow-up.Breaking:
usages: [derive]rather thanunwrap, indecrypt_dataandunwrap_key;Closes #202