moved pub key checks into crypto module
diff --git a/Cargo.toml b/Cargo.toml
index 8fee87d..125765c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,7 +28,7 @@
itoa = "0.3"
log = "0.3"
pem = "0.4"
-ring = "0.9.4"
+ring = { version = "0.9.4", features = [ "rsa_signing" ] }
serde = "1"
serde_derive = "1"
serde_json = "1"
diff --git a/src/crypto.rs b/src/crypto.rs
index ad10c91..8ada683 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -10,6 +10,7 @@
use Result;
use error::Error;
+use rsa;
use shims;
pub fn calculate_key_id(public_key: &PublicKeyValue) -> KeyId {
@@ -25,11 +26,7 @@
pub struct KeyId(Vec<u8>);
impl KeyId {
- pub fn new(bytes: Vec<u8>) -> Self {
- KeyId(bytes)
- }
-
- pub fn from_string(string: &str) -> Result<Self> {
+ fn from_string(string: &str) -> Result<Self> {
Ok(KeyId(HEXLOWER.decode(string.as_bytes())?))
}
}
@@ -65,8 +62,6 @@
RsaSsaPssSha512,
}
-impl SignatureScheme {}
-
impl ToString for SignatureScheme {
fn to_string(&self) -> String {
match self {
@@ -140,7 +135,7 @@
fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
let string: String = Deserialize::deserialize(de)?;
SignatureValue::from_string(&string).map_err(|e| {
- DeserializeError::custom("Signature value was not valid hex lower".to_string())
+ DeserializeError::custom(format!("Signature value was not valid hex lower: {:?}", e))
})
}
}
@@ -200,13 +195,56 @@
}
impl PublicKey {
- pub fn new(typ: KeyType, format: KeyFormat, value: PublicKeyValue) -> Self {
- PublicKey {
- typ: typ,
- format: format,
+ pub fn from_ed25519(value: PublicKeyValue) -> Result<Self> {
+ if value.value().len() != 32 {
+ return Err(Error::Decode(
+ "Ed25519 public key was not 32 bytes long".into(),
+ ));
+ }
+
+ Ok(PublicKey {
+ typ: KeyType::Ed25519,
+ format: KeyFormat::HexLower,
key_id: calculate_key_id(&value),
value: value,
- }
+ })
+ }
+
+ pub fn from_rsa(value: PublicKeyValue, format: KeyFormat) -> Result<Self> {
+ // TODO check n > 2048 bits
+
+ let key_id = calculate_key_id(&value);
+
+ let pkcs1_value = match format {
+ KeyFormat::Pkcs1 => {
+ let bytes = rsa::from_pkcs1(value.value()).ok_or(
+ Error::IllegalArgument(
+ "Key claimed to be PKCS1 but could not be parsed."
+ .into(),
+ ),
+ )?;
+ PublicKeyValue(bytes)
+ }
+ KeyFormat::Spki => {
+ let bytes = rsa::from_spki(value.value()).ok_or(Error::IllegalArgument(
+ "Key claimed to be SPKI but could not be parsed."
+ .into(),
+ ))?;
+ PublicKeyValue(bytes)
+ }
+ x => {
+ return Err(Error::IllegalArgument(
+ format!("RSA keys in format {:?} not supported.", x),
+ ))
+ }
+ };
+
+ Ok(PublicKey {
+ typ: KeyType::Rsa,
+ format: format,
+ key_id: key_id,
+ value: pkcs1_value,
+ })
}
pub fn typ(&self) -> &KeyType {
@@ -281,3 +319,23 @@
Spki,
}
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Signature {
+ key_id: KeyId,
+ scheme: SignatureScheme,
+ signature: SignatureValue,
+}
+
+impl Signature {
+ pub fn key_id(&self) -> &KeyId {
+ &self.key_id
+ }
+
+ pub fn scheme(&self) -> &SignatureScheme {
+ &self.scheme
+ }
+
+ pub fn signature(&self) -> &SignatureValue {
+ &self.signature
+ }
+}
diff --git a/src/metadata.rs b/src/metadata.rs
index 0d13826..874ddbc 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -7,7 +7,7 @@
use std::marker::PhantomData;
use Result;
-use crypto::{KeyId, PublicKey, SignatureScheme, SignatureValue};
+use crypto::{KeyId, PublicKey, Signature};
use error::Error;
use interchange::DataInterchange;
use shims;
@@ -266,26 +266,6 @@
}
}
-#[derive(Debug, Serialize, Deserialize)]
-pub struct Signature {
- key_id: KeyId,
- scheme: SignatureScheme,
- signature: SignatureValue,
-}
-
-impl Signature {
- pub fn key_id(&self) -> &KeyId {
- &self.key_id
- }
-
- pub fn scheme(&self) -> &SignatureScheme {
- &self.scheme
- }
-
- pub fn signature(&self) -> &SignatureValue {
- &self.signature
- }
-}
#[derive(Clone, Debug, PartialEq)]
pub struct RoleDefinition {
threshold: u32,
@@ -335,12 +315,13 @@
#[cfg(test)]
mod test {
- use super::*;
use json;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
+ use crypto::{KeyType, PublicKey, KeyFormat};
+
#[test]
fn parse_spki_json() {
let mut jsn = json!({"type": "rsa", "value": {}});
@@ -402,7 +383,7 @@
#[test]
fn parse_hex_json() {
let mut jsn = json!({"type": "ed25519", "value": {}});
- let buf = "2bedead4feed".to_string();
+ let buf = "cf07711807f5176a4814613f3f348091dfc2b91f36b46a6abf6385f4ad14435b".to_string();
let _ = jsn.as_object_mut()
.unwrap()
diff --git a/src/repository.rs b/src/repository.rs
index 62c447c..d65dc13 100644
--- a/src/repository.rs
+++ b/src/repository.rs
@@ -20,7 +20,7 @@
fn store_root(
&mut self,
root: &SignedMetadata<D, RootMetadata, Verified>,
- version: &MetadataVersion
+ version: &MetadataVersion,
) -> Result<()>;
fn fetch_root(
&mut self,
@@ -81,7 +81,7 @@
fn store_root(
&mut self,
root: &SignedMetadata<D, RootMetadata, Verified>,
- version: &MetadataVersion
+ version: &MetadataVersion,
) -> Result<()> {
let root_version = format!("{}root{}", version.prefix(), D::suffix());
let path = self.local_path.join("metadata").join(&root_version);
@@ -158,7 +158,7 @@
fn store_root(
&mut self,
_: &SignedMetadata<D, RootMetadata, Verified>,
- _: &MetadataVersion
+ _: &MetadataVersion,
) -> Result<()> {
Err(Error::Generic(
"Http repo store root not implemented".to_string(),
@@ -208,7 +208,7 @@
fn store_root(
&mut self,
root: &SignedMetadata<D, RootMetadata, Verified>,
- version: &MetadataVersion
+ version: &MetadataVersion,
) -> Result<()> {
let root_version = format!("{}root{}", version.prefix(), D::suffix());
let mut buf = Vec::new();
@@ -224,9 +224,7 @@
) -> Result<SignedMetadata<D, RootMetadata, Unverified>> {
let root_version = format!("{}root{}", version.prefix(), D::suffix());
match self.metadata.get(&root_version) {
- Some(bytes) => {
- D::from_reader(&**bytes)
- },
+ Some(bytes) => D::from_reader(&**bytes),
None => Err(Error::NotFound),
}
}
diff --git a/src/shims.rs b/src/shims.rs
index 765574c..ea1cdfd 100644
--- a/src/shims.rs
+++ b/src/shims.rs
@@ -140,31 +140,25 @@
}
pub fn try_into(self) -> Result<crypto::PublicKey> {
- let (key_bytes, format) = match self.typ {
+ match self.typ {
crypto::KeyType::Ed25519 => {
let bytes = HEXLOWER.decode(self.value.public.as_bytes())?;
- (bytes, crypto::KeyFormat::HexLower)
+ crypto::PublicKey::from_ed25519(crypto::PublicKeyValue::new(bytes))
}
crypto::KeyType::Rsa => {
let _pem = pem::parse(self.value.public.as_bytes())?;
match _pem.tag.as_str() {
"RSA PUBLIC KEY" => {
- let bytes = rsa::from_pkcs1(&_pem.contents).ok_or(
- Error::UnsupportedKeyFormat(
- "PEM claimed to PKCS1 but could not be parsed"
- .into(),
- ),
- )?;
- (bytes, crypto::KeyFormat::Pkcs1)
+ crypto::PublicKey::from_rsa(
+ crypto::PublicKeyValue::new(_pem.contents),
+ crypto::KeyFormat::Pkcs1,
+ )
}
"PUBLIC KEY" => {
- let bytes = rsa::from_spki(&_pem.contents).ok_or(
- Error::UnsupportedKeyFormat(
- "PEM claimed to SPKI but could not be parsed"
- .into(),
- ),
- )?;
- (bytes, crypto::KeyFormat::Spki)
+ crypto::PublicKey::from_rsa(
+ crypto::PublicKeyValue::new(_pem.contents),
+ crypto::KeyFormat::Spki,
+ )
}
x => {
return Err(Error::UnsupportedKeyFormat(
@@ -173,11 +167,7 @@
}
}
}
- };
-
- let key = crypto::PublicKeyValue::new(key_bytes);
-
- Ok(crypto::PublicKey::new(self.typ, format, key))
+ }
}
}
@@ -214,9 +204,7 @@
));
}
- let key_ids = self.key_ids
- .drain(0..)
- .collect::<HashSet<crypto::KeyId>>();
+ let key_ids = self.key_ids.drain(0..).collect::<HashSet<crypto::KeyId>>();
let dupes = vec_len - key_ids.len();
if dupes != 0 {
diff --git a/src/tuf.rs b/src/tuf.rs
index 9f325ae..049f201 100644
--- a/src/tuf.rs
+++ b/src/tuf.rs
@@ -1,4 +1,3 @@
-//! Structs and functions for interacting with TUF repositories.
use std::marker::PhantomData;
use Result;