diff --git a/Cargo.toml b/Cargo.toml index bbc6b5f..d392146 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,11 +13,11 @@ repository = "https://git.asonix.dog/Aardwolf/rsa-pem" [dependencies] bit-vec = "0.6" log = "0.4" -num-bigint = "0.2" +num-bigint = "0.2.6" num-bigint-dig = "0.6" num-traits = "0.2" -pem = "0.7" -rsa = "0.2.0" +pem = "0.8" +rsa = "0.3.0" thiserror = "1.0.9" yasna = { version = "0.3", features = ["num-bigint", "bit-vec"] } @@ -25,4 +25,4 @@ yasna = { version = "0.3", features = ["num-bigint", "bit-vec"] } pretty_env_logger = "0.4" anyhow = "1.0" rand = "0.7" -sha2 = "0.8" +sha2 = "0.9" diff --git a/src/lib.rs b/src/lib.rs index 899f5c0..4779f8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ pub trait KeyExt { } /// Errors produced when serializing or deserializing keys -#[derive(Clone, Debug, Error)] +#[derive(Debug, Error)] pub enum KeyError { /// The PEM wrapper has the wrong name #[error("Invalid key kind supplied")] @@ -54,7 +54,7 @@ pub enum KeyError { /// Parsing the DER bytes failed #[error("Error parsing key, {}", .0)] - Parse(#[from] yasna::ASN1Error), + Parse(rsa::errors::Error), /// The private key's fields don't make sense #[error("Constructed key is invalid")] @@ -65,10 +65,6 @@ pub enum KeyError { Serialize, } -fn to_dig(biguint: &num_bigint::BigUint) -> num_bigint_dig::BigUint { - BigUint::from_bytes_be(&biguint.to_bytes_be()) -} - fn from_dig(biguint: &BigUint) -> num_bigint::BigUint { num_bigint::BigUint::from_bytes_be(&biguint.to_bytes_be()) } diff --git a/src/private.rs b/src/private.rs index 8e9ab27..4f0391c 100644 --- a/src/private.rs +++ b/src/private.rs @@ -29,12 +29,11 @@ //! Attributes ::= SET OF Attribute //! ``` -use log::debug; +use super::*; use num_bigint_dig::{traits::ModInverse, BigUint}; use num_traits::identities::One; -use rsa::{PublicKey, RSAPrivateKey}; - -use super::*; +use rsa::{PublicKeyParts, RSAPrivateKey}; +use std::convert::TryInto; impl KeyExt for RSAPrivateKey { fn to_pem_pkcs8(&self) -> Result { @@ -67,46 +66,7 @@ impl KeyExt for RSAPrivateKey { return Err(KeyError::Kind); } - let expected_oid = yasna::models::ObjectIdentifier::from_slice(&RSA_OID); - - let pkey = yasna::parse_der(&data.contents, |reader| { - // Read the outer DER-encoded value - reader.read_sequence(|reader| { - // Read Version ::= INTEGER - debug!("Parsing algorithm ID"); - let version = reader.next().read_i64()?; - - // PKCS#8 defines version == 0 - if version != 0 { - return Err(yasna::ASN1Error::new(yasna::ASN1ErrorKind::Invalid)); - } - - // Read AlgorithmIdentifier ::= AlgorithmIdentifier - debug!("Parsing oid"); - let oid = reader.next().read_sequence(|reader| { - let oid = reader.next().read_oid()?; - reader.next().read_null()?; - Ok(oid) - })?; - - // RSA defines OID == 1.2.840.113549.1.1.1 - if oid != expected_oid { - return Err(yasna::ASN1Error::new(yasna::ASN1ErrorKind::Invalid)); - } - - // Read PrivateKey ::= OCTET STRING - debug!("Parsing bytes"); - let bytes = reader.next().read_bytes()?; - - // TODO: Read Attributes ::= SET OF Attribute - - parse_pkcs1(&bytes) - }) - })?; - - pkey.validate().map_err(|_| KeyError::Validate)?; - - Ok(pkey) + data.try_into().map_err(KeyError::Parse) } fn to_pem_pkcs1(&self) -> Result { @@ -127,11 +87,7 @@ impl KeyExt for RSAPrivateKey { return Err(KeyError::Kind); } - let pkey = parse_pkcs1(&data.contents)?; - - pkey.validate().map_err(|_| KeyError::Validate)?; - - Ok(pkey) + data.try_into().map_err(KeyError::Parse) } } @@ -156,34 +112,3 @@ fn write_pkcs1(rsa: &RSAPrivateKey) -> Option> { }) })) } - -fn parse_pkcs1(bytes: &[u8]) -> Result { - yasna::parse_der(bytes, |reader| { - reader.read_sequence(|reader| { - let version = reader.next().read_i64()?; - // version 0 (two primes) is the only supported RSAPrivateKey version, 1 (multi-prime) is unsupported - if version != 0 { - return Err(yasna::ASN1Error::new(yasna::ASN1ErrorKind::Invalid)); - } - - let modulus = reader.next().read_biguint()?; - let pubexp = reader.next().read_biguint()?; - let privexp = reader.next().read_biguint()?; - let prime1 = reader.next().read_biguint()?; - let prime2 = reader.next().read_biguint()?; - // These need to be read or else the parser will error - let _exp1 = reader.next().read_biguint()?; - let _exp2 = reader.next().read_biguint()?; - let _coeff = reader.next().read_biguint()?; - - let pkey = RSAPrivateKey::from_components( - to_dig(&modulus), - to_dig(&pubexp), - to_dig(&privexp), - vec![to_dig(&prime1), to_dig(&prime2)], - ); - - Ok(pkey) - }) - }) -} diff --git a/src/public.rs b/src/public.rs index 6e094c2..4b242dc 100644 --- a/src/public.rs +++ b/src/public.rs @@ -1,7 +1,6 @@ -use log::debug; -use rsa::{PublicKey, RSAPublicKey}; - use super::*; +use rsa::{PublicKeyParts, RSAPublicKey}; +use std::convert::TryInto; impl KeyExt for RSAPublicKey { fn to_pem_pkcs8(&self) -> Result { @@ -35,33 +34,7 @@ impl KeyExt for RSAPublicKey { return Err(KeyError::Kind); } - let expected_oid = yasna::models::ObjectIdentifier::from_slice(&RSA_OID); - - let pkey = yasna::parse_der(&data.contents, |reader| { - let o = reader.read_sequence(|reader| { - debug!("Parse OID"); - let oid = reader.next().read_sequence(|reader| { - // TODO: parse more in here - let oid = reader.next().read_oid()?; - reader.next().read_null()?; - Ok(oid) - })?; - - if oid != expected_oid { - debug!("OID was unexpected, {}", oid); - return Err(yasna::ASN1Error::new(yasna::ASN1ErrorKind::Invalid)); - } - - debug!("Parse bytes"); - let bitvec = reader.next().read_bitvec()?; - - parse_pkcs1(&bitvec.to_bytes()) - })?; - debug!("Parsed sequence"); - Ok(o) - })?; - - Ok(pkey) + data.try_into().map_err(KeyError::Parse) } fn to_pem_pkcs1(&self) -> Result { @@ -82,9 +55,7 @@ impl KeyExt for RSAPublicKey { return Err(KeyError::Kind); } - let pkey = parse_pkcs1(&data.contents)?; - - Ok(pkey) + data.try_into().map_err(KeyError::Parse) } } @@ -96,17 +67,3 @@ fn write_pkcs1(rsa: &RSAPublicKey) -> Vec { }) }) } - -fn parse_pkcs1(bytes: &[u8]) -> Result { - let (n, e) = yasna::parse_der(bytes, |reader| { - reader.read_sequence(|reader| { - let n = reader.next().read_biguint()?; - let e = reader.next().read_biguint()?; - - Ok((n, e)) - }) - })?; - - RSAPublicKey::new(to_dig(&n), to_dig(&e)) - .map_err(|_| yasna::ASN1Error::new(yasna::ASN1ErrorKind::Invalid)) -}