From 99b8d0ac7f69f0007dd10307e79b35e68cbb854b Mon Sep 17 00:00:00 2001 From: readygo67 Date: Sun, 8 Sep 2024 18:41:47 +0800 Subject: [PATCH 1/2] from_pem_wo_parameter() for pem exported by dfx identity export xxx --- ic-agent/src/identity/secp256k1.rs | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ic-agent/src/identity/secp256k1.rs b/ic-agent/src/identity/secp256k1.rs index 73670987..fe4c2887 100644 --- a/ic-agent/src/identity/secp256k1.rs +++ b/ic-agent/src/identity/secp256k1.rs @@ -58,6 +58,23 @@ impl Secp256k1Identity { Err(pem::PemError::MissingData.into()) } + #[cfg(feature = "pem")] + pub fn from_pem_wo_parameter(pem_reader: R) -> Result { + use sec1::{pem::PemLabel, EcPrivateKey}; + + let contents = pem_reader.bytes().collect::, io::Error>>()?; + + for pem in pem::parse_many(contents)? { + if pem.tag() != EcPrivateKey::PEM_LABEL { + continue; + } + let private_key = + SecretKey::from_sec1_der(pem.contents()).map_err(|_| pkcs8::Error::KeyMalformed)?; + return Ok(Self::from_private_key(private_key)); + } + Err(pem::PemError::MissingData.into()) + } + /// Creates an identity from a private key. pub fn from_private_key(private_key: SecretKey) -> Self { let public_key = private_key.public_key(); @@ -159,6 +176,15 @@ MHQCAQEEIAgy7nZEcVHkQ4Z1Kdqby8SwyAiyKDQmtbEHTIM+WNeBoAcGBSuBBAAK oUQDQgAEgO87rJ1ozzdMvJyZQ+GABDqUxGLvgnAnTlcInV3NuhuPv4O3VGzMGzeB N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== -----END EC PRIVATE KEY----- +"; + + // IDENTITY_FILE_WITHOUT_PARAMS is exported from the following command: + // > dfx identity export identity + const IDENTITY_FILE_WITHOUT_PARAMS: &str = "-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIAgy7nZEcVHkQ4Z1Kdqby8SwyAiyKDQmtbEHTIM+WNeBoAcGBSuBBAAK +oUQDQgAEgO87rJ1ozzdMvJyZQ+GABDqUxGLvgnAnTlcInV3NuhuPv4O3VGzMGzeB +N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== +-----END EC PRIVATE KEY----- "; // DER_ENCODED_PUBLIC_KEY was generated from the the following commands: @@ -188,6 +214,16 @@ N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== assert!(DER_ENCODED_PUBLIC_KEY == hex::encode(identity.der_encoded_public_key)); } + #[test] + fn test_secp256k1_public_key_wo_params() { + // Create a secp256k1 identity from a PEM file. + let identity = Secp256k1Identity::from_pem_wo_parameter(IDENTITY_FILE_WITHOUT_PARAMS.as_bytes()) + .expect("Cannot create secp256k1 identity from PEM file."); + + // Assert the DER-encoded secp256k1 public key matches what we would expect. + assert!(DER_ENCODED_PUBLIC_KEY == hex::encode(identity.der_encoded_public_key)); + } + #[test] fn test_secp256k1_signature() { // Create a secp256k1 identity from a PEM file. From 0fbda5f036fca2e93d5c54583d3829830771a651 Mon Sep 17 00:00:00 2001 From: keep Date: Sun, 8 Sep 2024 19:02:52 +0800 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf64bc12..b344a768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `Url` now implements `RouteProvider`. * Add canister snapshot methods to `ManagementCanister`. * Add `AllowedViewers` to `LogVisibility` enum. +* Add `from_pem_wo_parameter` for `Secp256k1Identity`. ## [0.37.1] - 2024-07-25