Refactoring + more idiomatic enum names
This commit is contained in:
parent
06bebeaae3
commit
caef740ad4
|
@ -1,5 +1,6 @@
|
||||||
/// The supported RSA key formats, see the documentation for ring::signature::RsaKeyPair
|
/// The supported RSA key formats, see the documentation for ring::signature::RsaKeyPair
|
||||||
/// for more information
|
/// for more information
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Key<'a> {
|
pub enum Key<'a> {
|
||||||
/// An unencrypted PKCS#8-encoded key. Can be used with both ECDSA and RSA
|
/// An unencrypted PKCS#8-encoded key. Can be used with both ECDSA and RSA
|
||||||
/// algorithms when signing. See ring for information.
|
/// algorithms when signing. See ring for information.
|
||||||
|
|
|
@ -9,22 +9,22 @@ use simple_asn1::{BigUint, OID};
|
||||||
/// Supported PEM files for EC and RSA Public and Private Keys
|
/// Supported PEM files for EC and RSA Public and Private Keys
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum PemType {
|
enum PemType {
|
||||||
ECPublicKey,
|
EcPublicKey,
|
||||||
ECPrivateKey,
|
EcPrivateKey,
|
||||||
RSAPublicKey,
|
RsaPublicKey,
|
||||||
RSAPrivateKey,
|
RsaPrivateKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum PemEncodedWith {
|
enum Standard {
|
||||||
PKCS1,
|
Pkcs1,
|
||||||
PKCS8,
|
Pkcs8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum Classification {
|
enum Classification {
|
||||||
EC,
|
Ec,
|
||||||
RSA,
|
Rsa,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The return type of a successful PEM encoded key with `decode_pem`
|
/// The return type of a successful PEM encoded key with `decode_pem`
|
||||||
|
@ -46,7 +46,7 @@ pub struct PemEncodedKey {
|
||||||
content: Vec<u8>,
|
content: Vec<u8>,
|
||||||
asn1: Vec<simple_asn1::ASN1Block>,
|
asn1: Vec<simple_asn1::ASN1Block>,
|
||||||
pem_type: PemType,
|
pem_type: PemType,
|
||||||
encoded_with: PemEncodedWith,
|
standard: Standard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PemEncodedKey {
|
impl PemEncodedKey {
|
||||||
|
@ -65,55 +65,51 @@ impl PemEncodedKey {
|
||||||
"RSA PRIVATE KEY" => Ok(PemEncodedKey {
|
"RSA PRIVATE KEY" => Ok(PemEncodedKey {
|
||||||
content: pem_contents,
|
content: pem_contents,
|
||||||
asn1: asn1_content,
|
asn1: asn1_content,
|
||||||
pem_type: PemType::RSAPrivateKey,
|
pem_type: PemType::RsaPrivateKey,
|
||||||
encoded_with: PemEncodedWith::PKCS1,
|
standard: Standard::Pkcs1,
|
||||||
}),
|
}),
|
||||||
"RSA PUBLIC KEY" => Ok(PemEncodedKey {
|
"RSA PUBLIC KEY" => Ok(PemEncodedKey {
|
||||||
content: pem_contents,
|
content: pem_contents,
|
||||||
asn1: asn1_content,
|
asn1: asn1_content,
|
||||||
pem_type: PemType::RSAPublicKey,
|
pem_type: PemType::RsaPublicKey,
|
||||||
encoded_with: PemEncodedWith::PKCS1,
|
standard: Standard::Pkcs1,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// No "EC PRIVATE KEY"
|
// No "EC PRIVATE KEY"
|
||||||
// https://security.stackexchange.com/questions/84327/converting-ecc-private-key-to-pkcs1-format
|
// https://security.stackexchange.com/questions/84327/converting-ecc-private-key-to-pkcs1-format
|
||||||
// "there is no such thing as a "PKCS#1 format" for elliptic curve (EC) keys"
|
// "there is no such thing as a "PKCS#1 format" for elliptic curve (EC) keys"
|
||||||
|
|
||||||
// This handles PKCS#8 private keys
|
// This handles PKCS#8 public & private keys
|
||||||
"PRIVATE KEY" => match classify_pem(&asn1_content) {
|
tag @ "PRIVATE KEY" | tag @ "PUBLIC KEY" => match classify_pem(&asn1_content) {
|
||||||
Some(Classification::EC) => Ok(PemEncodedKey {
|
Some(c) => {
|
||||||
content: pem_contents,
|
let is_private = tag == "PRIVATE KEY";
|
||||||
asn1: asn1_content,
|
let pem_type = match c {
|
||||||
pem_type: PemType::ECPrivateKey,
|
Classification::Ec => {
|
||||||
encoded_with: PemEncodedWith::PKCS8,
|
if is_private {
|
||||||
}),
|
PemType::EcPrivateKey
|
||||||
Some(Classification::RSA) => Ok(PemEncodedKey {
|
} else {
|
||||||
content: pem_contents,
|
PemType::EcPublicKey
|
||||||
asn1: asn1_content,
|
}
|
||||||
pem_type: PemType::RSAPrivateKey,
|
}
|
||||||
encoded_with: PemEncodedWith::PKCS8,
|
Classification::Rsa => {
|
||||||
}),
|
if is_private {
|
||||||
_ => return Err(ErrorKind::InvalidKeyFormat)?,
|
PemType::RsaPrivateKey
|
||||||
|
} else {
|
||||||
|
PemType::RsaPublicKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(PemEncodedKey {
|
||||||
|
content: pem_contents,
|
||||||
|
asn1: asn1_content,
|
||||||
|
pem_type,
|
||||||
|
standard: Standard::Pkcs8,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
None => return Err(ErrorKind::InvalidKeyFormat)?,
|
||||||
},
|
},
|
||||||
|
|
||||||
// This handles PKCS#8 public keys
|
// Unknown/unsupported type
|
||||||
"PUBLIC KEY" => match classify_pem(&asn1_content) {
|
|
||||||
Some(Classification::EC) => Ok(PemEncodedKey {
|
|
||||||
content: pem_contents,
|
|
||||||
asn1: asn1_content,
|
|
||||||
pem_type: PemType::ECPublicKey,
|
|
||||||
encoded_with: PemEncodedWith::PKCS8,
|
|
||||||
}),
|
|
||||||
Some(Classification::RSA) => Ok(PemEncodedKey {
|
|
||||||
content: pem_contents,
|
|
||||||
asn1: asn1_content,
|
|
||||||
pem_type: PemType::RSAPublicKey,
|
|
||||||
encoded_with: PemEncodedWith::PKCS8,
|
|
||||||
}),
|
|
||||||
_ => return Err(ErrorKind::InvalidKeyFormat)?,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Unknown type
|
|
||||||
_ => return Err(ErrorKind::InvalidKeyFormat)?,
|
_ => return Err(ErrorKind::InvalidKeyFormat)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,13 +122,13 @@ impl PemEncodedKey {
|
||||||
/// "PRIVATE KEY", "PUBLIC KEY"
|
/// "PRIVATE KEY", "PUBLIC KEY"
|
||||||
/// PEMs with multiple tagged portions are not supported
|
/// PEMs with multiple tagged portions are not supported
|
||||||
pub fn as_key(&self) -> Result<Key<'_>> {
|
pub fn as_key(&self) -> Result<Key<'_>> {
|
||||||
match self.encoded_with {
|
match self.standard {
|
||||||
PemEncodedWith::PKCS1 => Ok(Key::Der(self.content.as_slice())),
|
Standard::Pkcs1 => Ok(Key::Der(self.content.as_slice())),
|
||||||
PemEncodedWith::PKCS8 => match self.pem_type {
|
Standard::Pkcs8 => match self.pem_type {
|
||||||
PemType::RSAPrivateKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
|
PemType::RsaPrivateKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
|
||||||
PemType::RSAPublicKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
|
PemType::RsaPublicKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
|
||||||
PemType::ECPrivateKey => Ok(Key::Pkcs8(self.content.as_slice())),
|
PemType::EcPrivateKey => Ok(Key::Pkcs8(self.content.as_slice())),
|
||||||
PemType::ECPublicKey => Ok(Key::Pkcs8(extract_first_bitstring(&self.asn1)?)),
|
PemType::EcPublicKey => Ok(Key::Pkcs8(extract_first_bitstring(&self.asn1)?)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,9 +156,10 @@ fn extract_first_bitstring(asn1: &Vec<simple_asn1::ASN1Block>) -> Result<&[u8]>
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(ErrorKind::InvalidEcdsaKey)?;
|
Err(ErrorKind::InvalidEcdsaKey)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find whether this is EC or RSA
|
||||||
fn classify_pem(asn1: &Vec<simple_asn1::ASN1Block>) -> Option<Classification> {
|
fn classify_pem(asn1: &Vec<simple_asn1::ASN1Block>) -> Option<Classification> {
|
||||||
// These should be constant but the macro requires
|
// These should be constant but the macro requires
|
||||||
// #![feature(const_vec_new)]
|
// #![feature(const_vec_new)]
|
||||||
|
@ -178,9 +175,10 @@ fn classify_pem(asn1: &Vec<simple_asn1::ASN1Block>) -> Option<Classification> {
|
||||||
}
|
}
|
||||||
simple_asn1::ASN1Block::ObjectIdentifier(_, oid) => {
|
simple_asn1::ASN1Block::ObjectIdentifier(_, oid) => {
|
||||||
if oid == ec_public_key_oid {
|
if oid == ec_public_key_oid {
|
||||||
return Some(Classification::EC);
|
return Some(Classification::Ec);
|
||||||
} else if oid == rsa_public_key_oid {
|
}
|
||||||
return Some(Classification::RSA);
|
if oid == rsa_public_key_oid {
|
||||||
|
return Some(Classification::Rsa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
Loading…
Reference in New Issue