Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ed25519 importing #611

Merged
merged 3 commits into from
Oct 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions ic-agent/src/identity/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,41 @@ impl BasicIdentity {
/// Create a `BasicIdentity` from reading a PEM File from a Reader.
#[cfg(feature = "pem")]
pub fn from_pem<R: std::io::Read>(pem_reader: R) -> Result<Self, PemError> {
use der::{Decode, PemReader};
use der::{asn1::OctetString, Decode, ErrorKind, SliceReader, Tag, TagNumber};
use pkcs8::PrivateKeyInfo;

let bytes: Vec<u8> = pem_reader
.bytes()
.collect::<Result<Vec<u8>, std::io::Error>>()?;
let pki = PrivateKeyInfo::decode(&mut PemReader::new(&bytes)?)?;
let private_key = SigningKey::try_from(pki.private_key)?;
let bytes: Vec<u8> = pem_reader.bytes().collect::<Result<_, _>>()?;
let pem = pem::parse(bytes)?;
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))
}

Expand Down
Loading