Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for importing ECDSA identities from either SEC1 (EC PRIVATE KEY) or PKCS#8 (PRIVATE KEY) PEM encodings, with curve validation to reject keys for the wrong curve.
Changes:
- Extend
Secp256k1Identity::from_pemandPrime256v1Identity::from_pemto accept PKCS#8 keys in addition to SEC1 keys. - Introduce a shared
parse_ec_pkcs8_key_byteshelper to validate EC algorithm + curve OID and extract inner SEC1 bytes (including a legacy dfx “hatchet surgery” fallback). - Add unit tests covering PKCS#8 import success and wrong-curve rejection for both identities.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
ic-agent/src/identity/secp256k1.rs |
Adds PKCS#8 handling branch in from_pem and new PKCS#8-focused tests. |
ic-agent/src/identity/prime256v1.rs |
Adds PKCS#8 handling branch in from_pem and new PKCS#8-focused tests. |
ic-agent/src/identity/mod.rs |
Adds shared PKCS#8 EC parsing/validation helper used by both identities. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if curve_oid != expected_curve { | ||
| return Err(error::PemError::UnsupportedKeyCurve( | ||
| curve_name.to_string(), | ||
| curve_oid.as_bytes().to_vec(), | ||
| )); |
There was a problem hiding this comment.
curve_oid.as_bytes().to_vec() returns the OID content bytes (no ASN.1 tag/len). Existing SEC1 parsing reports the DER-encoded OID bytes from the EC PARAMETERS block (includes the 0x06 tag/length). This makes PemError::UnsupportedKeyCurve(_, Vec<u8>) inconsistent depending on input format (SEC1 vs PKCS#8), which can break consumers relying on those bytes. Consider storing a consistently encoded representation (e.g., DER-encode curve_oid the same way EC PARAMETERS does, or store a string form instead).
| if pem.tag() == PrivateKeyInfo::PEM_LABEL { | ||
| // PKCS#8 "PRIVATE KEY" format |
There was a problem hiding this comment.
PrivateKeyInfo::PEM_LABEL is typically only available when the pkcs8 crate is built with its pem feature (it implements the PemLabel trait). In this repo, pkcs8 appears to be built without that feature (Cargo.lock shows pkcs8 depends only on der and spki, not pem-rfc7468), so this comparison is likely to fail to compile. Consider comparing against the literal tag ("PRIVATE KEY") instead, and drop the PrivateKeyInfo import if it’s only used for PEM_LABEL.
| if pem.tag() == PrivateKeyInfo::PEM_LABEL { | ||
| // PKCS#8 "PRIVATE KEY" format |
There was a problem hiding this comment.
PrivateKeyInfo::PEM_LABEL is usually gated behind the pkcs8 crate’s pem feature (it needs to implement the PemLabel trait). Here pkcs8 seems to be built without that feature (Cargo.lock shows pkcs8 depends only on der and spki), so this will likely be a compile error. Suggest comparing pem.tag() to the literal "PRIVATE KEY" and removing the PrivateKeyInfo import if it’s only used for PEM_LABEL.
| @@ -31,8 +31,11 @@ impl Secp256k1Identity { | |||
| } | |||
|
|
|||
| /// Creates an identity from a PEM certificate. | |||
There was a problem hiding this comment.
The doc comment says “Creates an identity from a PEM certificate”, but from_pem actually expects a PEM-encoded private key (SEC1 EC PRIVATE KEY or PKCS#8 PRIVATE KEY). Consider updating the wording to avoid implying an X.509 certificate is accepted here.
| /// Creates an identity from a PEM certificate. | |
| /// Creates an identity from a PEM-encoded private key. |
| @@ -31,8 +31,11 @@ impl Prime256v1Identity { | |||
| } | |||
|
|
|||
| /// Creates an identity from a PEM certificate. | |||
There was a problem hiding this comment.
The doc comment says “Creates an identity from a PEM certificate”, but from_pem is parsing a PEM-encoded private key (SEC1 EC PRIVATE KEY or PKCS#8 PRIVATE KEY). Suggest rewording to avoid suggesting that X.509 certificates are supported here.
| /// Creates an identity from a PEM certificate. | |
| /// Creates an identity from a PEM-encoded private key. |
Checks whether keys are pkcs8 or sec1 before importing them.