From 7e7450369baac32c57d5253d44931d7cc6fb1e56 Mon Sep 17 00:00:00 2001 From: Adam Spofford Date: Thu, 24 Oct 2024 09:12:22 -0700 Subject: [PATCH 1/3] Fix ed25519 import error --- ic-agent/src/identity/basic.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ic-agent/src/identity/basic.rs b/ic-agent/src/identity/basic.rs index 58a63c0b..9d12b45a 100644 --- a/ic-agent/src/identity/basic.rs +++ b/ic-agent/src/identity/basic.rs @@ -39,14 +39,14 @@ impl BasicIdentity { /// Create a `BasicIdentity` from reading a PEM File from a Reader. #[cfg(feature = "pem")] pub fn from_pem(pem_reader: R) -> Result { - use der::{Decode, PemReader}; + use der::{asn1::OctetString, Decode, SliceReader}; use pkcs8::PrivateKeyInfo; - let bytes: Vec = pem_reader - .bytes() - .collect::, std::io::Error>>()?; - let pki = PrivateKeyInfo::decode(&mut PemReader::new(&bytes)?)?; - let private_key = SigningKey::try_from(pki.private_key)?; + let bytes: Vec = pem_reader.bytes().collect::>()?; + let pem = pem::parse(&bytes)?; + let pki = PrivateKeyInfo::decode(&mut SliceReader::new(pem.contents())?)?; + let decoded_key = OctetString::from_der(pki.private_key)?; // ed25519 uses an octet string within another octet string + let private_key = SigningKey::try_from(decoded_key.as_bytes())?; Ok(BasicIdentity::from_signing_key(private_key)) } From c7497af25ede631fd60295e7687192ef4a29f3cb Mon Sep 17 00:00:00 2001 From: Adam Spofford Date: Thu, 24 Oct 2024 10:55:57 -0700 Subject: [PATCH 2/3] Add legacy dfx support --- ic-agent/src/identity/basic.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/ic-agent/src/identity/basic.rs b/ic-agent/src/identity/basic.rs index 9d12b45a..a7a07fba 100644 --- a/ic-agent/src/identity/basic.rs +++ b/ic-agent/src/identity/basic.rs @@ -39,12 +39,39 @@ impl BasicIdentity { /// Create a `BasicIdentity` from reading a PEM File from a Reader. #[cfg(feature = "pem")] pub fn from_pem(pem_reader: R) -> Result { - use der::{asn1::OctetString, Decode, SliceReader}; + use der::{asn1::OctetString, Decode, ErrorKind, SliceReader, Tag, TagNumber}; use pkcs8::PrivateKeyInfo; let bytes: Vec = pem_reader.bytes().collect::>()?; let pem = pem::parse(&bytes)?; - let pki = PrivateKeyInfo::decode(&mut SliceReader::new(pem.contents())?)?; + let pki_res = PrivateKeyInfo::decode(&mut SliceReader::new(pem.contents())?); + let mut truncated; + let pki = match pki_res { + Ok(pki) => pki, + Err(e) => { + if e.kind() + == (ErrorKind::Noncanonical { + tag: Tag::ContextSpecific { + constructed: true, + number: TagNumber::new(1), + }, + }) + { + // Very old versions of dfx generated nonconforming containers. They can only be imported if the extra data is removed. + truncated = pem.into_contents(); + if truncated[48..52] != *b"\xA1\x23\x03\x21" { + return Err(e.into()); + } + // hatchet surgery + truncated.truncate(48); + truncated[1] = 46; + truncated[4] = 0; + PrivateKeyInfo::decode(&mut SliceReader::new(&truncated)?).map_err(|_| e)? + } else { + return Err(e.into()); + } + } + }; let decoded_key = OctetString::from_der(pki.private_key)?; // ed25519 uses an octet string within another octet string let private_key = SigningKey::try_from(decoded_key.as_bytes())?; Ok(BasicIdentity::from_signing_key(private_key)) From 70bd9f07a5c537d1d8f0a1584d0b9c6496baaa42 Mon Sep 17 00:00:00 2001 From: Adam Spofford Date: Thu, 24 Oct 2024 11:00:23 -0700 Subject: [PATCH 3/3] clippy --- ic-agent/src/identity/basic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ic-agent/src/identity/basic.rs b/ic-agent/src/identity/basic.rs index a7a07fba..8cf2d6bd 100644 --- a/ic-agent/src/identity/basic.rs +++ b/ic-agent/src/identity/basic.rs @@ -43,7 +43,7 @@ impl BasicIdentity { use pkcs8::PrivateKeyInfo; let bytes: Vec = pem_reader.bytes().collect::>()?; - let pem = pem::parse(&bytes)?; + let pem = pem::parse(bytes)?; let pki_res = PrivateKeyInfo::decode(&mut SliceReader::new(pem.contents())?); let mut truncated; let pki = match pki_res {