add role definition key id / threshold requirements
diff --git a/src/crypto.rs b/src/crypto.rs
index 484d5ed..987f4e3 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -4,7 +4,9 @@
use ring;
use ring::digest::{self, SHA256};
use ring::rand::SystemRandom;
-use ring::signature::{RSAKeyPair, RSASigningState, Ed25519KeyPair, ED25519, RSA_PSS_2048_8192_SHA256, RSA_PSS_2048_8192_SHA512, RSA_PSS_SHA256, RSA_PSS_SHA512};
+use ring::signature::{RSAKeyPair, RSASigningState, Ed25519KeyPair, ED25519,
+ RSA_PSS_2048_8192_SHA256, RSA_PSS_2048_8192_SHA512, RSA_PSS_SHA256,
+ RSA_PSS_SHA512};
use serde::de::{Deserialize, Deserializer, Error as DeserializeError};
use serde::ser::{Serialize, Serializer, SerializeTupleStruct, Error as SerializeError};
use std::collections::HashMap;
@@ -219,7 +221,7 @@
enum PrivateKeyType {
Ed25519(Ed25519KeyPair),
- Rsa(Arc<RSAKeyPair>)
+ Rsa(Arc<RSAKeyPair>),
}
impl Debug for PrivateKeyType {
@@ -240,47 +242,53 @@
impl PrivateKey {
/// Create an Ed25519 private key from PKCS#8v2 DER bytes.
pub fn ed25519_from_pkcs8(der_key: &[u8]) -> Result<Self> {
- let key = Ed25519KeyPair::from_pkcs8(Input::from(der_key))
- .map_err(|_| Error::Encoding("Could not parse key as PKCS#8v2".into()))?;
- Ok(PrivateKey {
- private: PrivateKeyType::Ed25519(key),
- })
+ let key = Ed25519KeyPair::from_pkcs8(Input::from(der_key)).map_err(
+ |_| {
+ Error::Encoding("Could not parse key as PKCS#8v2".into())
+ },
+ )?;
+ Ok(PrivateKey { private: PrivateKeyType::Ed25519(key) })
}
/// Create an RSA private key from PKCS#8v2 DER bytes.
pub fn rsa_from_pkcs8(der_key: &[u8]) -> Result<Self> {
- let key = RSAKeyPair::from_pkcs8(Input::from(der_key))
- .map_err(|_| Error::Encoding("Could not parse key as PKCS#8v2".into()))?;
- Ok(PrivateKey {
- private: PrivateKeyType::Rsa(Arc::new(key)),
- })
+ let key = RSAKeyPair::from_pkcs8(Input::from(der_key)).map_err(|_| {
+ Error::Encoding("Could not parse key as PKCS#8v2".into())
+ })?;
+ Ok(PrivateKey { private: PrivateKeyType::Rsa(Arc::new(key)) })
}
/// Sign a message with the given scheme.
pub fn sign(&self, msg: &[u8], scheme: &SignatureScheme) -> Result<SignatureValue> {
match (&self.private, scheme) {
(&PrivateKeyType::Rsa(ref rsa), &SignatureScheme::RsaSsaPssSha256) => {
- let mut signing_state = RSASigningState::new(rsa.clone())
- .map_err(|_| Error::Opaque("Could not initialize RSA signing state.".into()))?;
+ let mut signing_state = RSASigningState::new(rsa.clone()).map_err(|_| {
+ Error::Opaque("Could not initialize RSA signing state.".into())
+ })?;
let rng = SystemRandom::new();
let mut buf = vec![0; signing_state.key_pair().public_modulus_len()];
- signing_state.sign(&RSA_PSS_SHA256, &rng, msg, &mut buf)
+ signing_state
+ .sign(&RSA_PSS_SHA256, &rng, msg, &mut buf)
.map_err(|_| Error::Opaque("Failed to sign message.".into()))?;
Ok(SignatureValue(buf))
}
(&PrivateKeyType::Rsa(ref rsa), &SignatureScheme::RsaSsaPssSha512) => {
- let mut signing_state = RSASigningState::new(rsa.clone())
- .map_err(|_| Error::Opaque("Could not initialize RSA signing state.".into()))?;
+ let mut signing_state = RSASigningState::new(rsa.clone()).map_err(|_| {
+ Error::Opaque("Could not initialize RSA signing state.".into())
+ })?;
let rng = SystemRandom::new();
let mut buf = vec![0; signing_state.key_pair().public_modulus_len()];
- signing_state.sign(&RSA_PSS_SHA512, &rng, msg, &mut buf)
+ signing_state
+ .sign(&RSA_PSS_SHA512, &rng, msg, &mut buf)
.map_err(|_| Error::Opaque("Failed to sign message.".into()))?;
Ok(SignatureValue(buf))
}
(&PrivateKeyType::Ed25519(ref ed), &SignatureScheme::Ed25519) => {
Ok(SignatureValue(ed.sign(msg).as_ref().into()))
}
- (k, s) => Err(Error::IllegalArgument(format!("Key {:?} can't be used with scheme {:?}", k, s)))
+ (k, s) => Err(Error::IllegalArgument(
+ format!("Key {:?} can't be used with scheme {:?}", k, s),
+ )),
}
}
}
diff --git a/src/interchange/mod.rs b/src/interchange/mod.rs
index eb90f5d..bfe1fc5 100644
--- a/src/interchange/mod.rs
+++ b/src/interchange/mod.rs
@@ -76,7 +76,7 @@
/// ```
/// use tuf::interchange::{DataInterchange, JsonDataInterchange};
/// use std::collections::HashMap;
- ///
+ ///
/// let jsn: &[u8] = br#"{"foo": "bar", "baz": "quux"}"#;
/// let raw = JsonDataInterchange::from_reader(jsn).unwrap();
/// let mut map = HashMap::new();
@@ -95,7 +95,7 @@
/// ```
/// use tuf::interchange::{DataInterchange, JsonDataInterchange};
/// use std::collections::HashMap;
- ///
+ ///
/// let arr = vec![1, 2, 3];
/// let raw = JsonDataInterchange::serialize(&arr).unwrap();
/// assert!(raw.is_array());
diff --git a/src/metadata.rs b/src/metadata.rs
index c97b74b..75f1f6b 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -335,7 +335,17 @@
}
if key_ids.is_empty() {
- return Err(Error::IllegalArgument("Cannot define a role with no associated key IDs".into()));
+ return Err(Error::IllegalArgument(
+ "Cannot define a role with no associated key IDs".into(),
+ ));
+ }
+
+ if key_ids.len() < threshold {
+ return Err(Error::IllegalArgument(format!(
+ "Cannot have a threshold greater than the number of associated key IDs",
+ threshold,
+ key_ids.len()
+ )));
}
Ok(RoleDefinition {
diff --git a/src/shims.rs b/src/shims.rs
index c334e8d..543921a 100644
--- a/src/shims.rs
+++ b/src/shims.rs
@@ -152,11 +152,7 @@
crypto::KeyFormat::Spki,
)
}
- x => {
- return Err(Error::Encoding(
- format!("PEM with bad tag: {}", x),
- ))
- }
+ x => return Err(Error::Encoding(format!("PEM with bad tag: {}", x))),
}
}
}
@@ -200,7 +196,9 @@
let dupes = vec_len - key_ids.len();
if dupes != 0 {
- return Err(Error::Encoding(format!("Found {} duplicate key IDs.", dupes)));
+ return Err(Error::Encoding(
+ format!("Found {} duplicate key IDs.", dupes),
+ ));
}
Ok(metadata::RoleDefinition::new(self.threshold, key_ids)?)