diff options
author | Stuart Stock <stuart@int08h.com> | 2018-10-11 21:27:10 -0500 |
---|---|---|
committer | Stuart Stock <stuart@int08h.com> | 2018-10-11 21:27:10 -0500 |
commit | dda76cfc88d6673358c6dd21007c227c45ccb13f (patch) | |
tree | f0b62cb5a1db2c098d368831c2d8847ea1dffa77 /src/key | |
parent | c66513b606f6aacf61bab1434c1f512c24981b2b (diff) | |
download | roughenough-dda76cfc88d6673358c6dd21007c227c45ccb13f.zip |
another wip checkpoint; server integration
Diffstat (limited to 'src/key')
-rw-r--r-- | src/key/awskms.rs | 5 | ||||
-rw-r--r-- | src/key/envelope.rs | 6 | ||||
-rw-r--r-- | src/key/longterm.rs | 9 | ||||
-rw-r--r-- | src/key/mod.rs | 49 |
4 files changed, 55 insertions, 14 deletions
diff --git a/src/key/awskms.rs b/src/key/awskms.rs index 234864b..878eff9 100644 --- a/src/key/awskms.rs +++ b/src/key/awskms.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +extern crate hex; extern crate log; #[cfg(feature = "kms")] @@ -22,9 +23,7 @@ extern crate rusoto_kms; #[cfg(feature = "kms")] use self::rusoto_core::Region; #[cfg(feature = "kms")] -use self::rusoto_kms::{ - DecryptError, DecryptRequest, EncryptError, EncryptRequest, Kms, KmsClient, -}; +use self::rusoto_kms::{DecryptRequest, EncryptRequest, Kms, KmsClient}; use std::default::Default; use std::error::Error; diff --git a/src/key/envelope.rs b/src/key/envelope.rs index 5128b76..ed774ae 100644 --- a/src/key/envelope.rs +++ b/src/key/envelope.rs @@ -42,7 +42,7 @@ const MIN_PAYLOAD_SIZE: usize = DEK_LEN_FIELD // No input prefix to skip, consume entire buffer const IN_PREFIX_LEN: usize = 0; -// Trivial domain separation to guard KMS key reuse +// Trivial domain separation to guard against KMS key reuse static AD: &[u8; 11] = b"roughenough"; // Convenience function to create zero-filled Vec of given size @@ -91,7 +91,7 @@ impl EnvelopeEncryption { let dek_open_key = OpeningKey::new(&AES_256_GCM, &dek)?; match open_in_place(&dek_open_key, &nonce, AD, IN_PREFIX_LEN, &mut encrypted_seed) { Ok(plaintext_seed) => Ok(plaintext_seed.to_vec()), - Err(e) => Err(KmsError::OperationFailed( + Err(_) => Err(KmsError::OperationFailed( "failed to decrypt plaintext seed".to_string(), )), } @@ -124,7 +124,7 @@ impl EnvelopeEncryption { TAG_SIZE_BYTES, ) { Ok(enc_len) => plaintext_buf[..enc_len].to_vec(), - Err(e) => { + Err(_) => { return Err(KmsError::OperationFailed( "failed to encrypt plaintext seed".to_string(), )) diff --git a/src/key/longterm.rs b/src/key/longterm.rs index f06a318..ddac6ea 100644 --- a/src/key/longterm.rs +++ b/src/key/longterm.rs @@ -16,10 +16,6 @@ //! Represents the server's long-term identity. //! -use time::Timespec; - -use byteorder::{LittleEndian, WriteBytesExt}; - use std::fmt; use std::fmt::Formatter; @@ -59,6 +55,11 @@ impl LongTermKey { cert_msg } + + /// Return the public key for the provided seed + pub fn public_key(&self) -> &[u8] { + self.signer.public_key_bytes() + } } impl fmt::Display for LongTermKey { diff --git a/src/key/mod.rs b/src/key/mod.rs index 7ae2198..3fe365f 100644 --- a/src/key/mod.rs +++ b/src/key/mod.rs @@ -32,10 +32,10 @@ pub use self::envelope::EnvelopeEncryption; pub use self::longterm::LongTermKey; pub use self::online::OnlineKey; -#[cfg(feature = "kms")] -pub mod awskms; +use super::error; +use super::config::ServerConfig; -#[derive(Debug, PartialEq, Eq, PartialOrd, Hash, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Hash, Clone)] pub enum KeyProtection { /// No protection, seed is in plaintext Plaintext, @@ -47,6 +47,16 @@ pub enum KeyProtection { GoogleKmsEnvelope(String), } +impl Display for KeyProtection { + fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { + match self { + KeyProtection::Plaintext => write!(f, "Plaintext"), + KeyProtection::AwsKmsEnvelope(key_id) => write!(f, "AwsKms({})", key_id), + KeyProtection::GoogleKmsEnvelope(key_id) => write!(f, "GoogleKms({})", key_id), + } + } +} + impl FromStr for KeyProtection { type Err = (); @@ -75,7 +85,7 @@ impl From<std::io::Error> for KmsError { } impl From<ring::error::Unspecified> for KmsError { - fn from(error: ring::error::Unspecified) -> Self { + fn from(_: ring::error::Unspecified) -> Self { KmsError::OperationFailed("unspecified ring cryptographic failure".to_string()) } } @@ -101,3 +111,34 @@ pub trait KmsProvider { fn encrypt_dek(&self, plaintext_dek: &PlaintextDEK) -> Result<EncryptedDEK, KmsError>; fn decrypt_dek(&self, encrypted_dek: &EncryptedDEK) -> Result<PlaintextDEK, KmsError>; } + +#[cfg(feature = "kms")] +pub mod awskms; + +#[cfg(feature = "kms")] +use key::awskms::AwsKms; +use std::fmt::Display; +use std::fmt::Formatter; + +#[cfg(feature = "kms")] +pub fn load_seed(config: &Box<ServerConfig>) -> Result<Vec<u8>, error::Error> { + match config.key_protection() { + KeyProtection::Plaintext => Ok(config.seed()), + KeyProtection::AwsKmsEnvelope(key_id) => { + info!("Unwrapping seed via AWS KMS key '{}'", key_id); + let kms = AwsKms::from_arn(key_id)?; + let seed = EnvelopeEncryption::decrypt_seed(&kms, &config.seed())?; + Ok(seed) + } + _ => Err(error::Error::InvalidConfiguration("Google KMS not supported".to_string())) + } +} + +#[cfg(not(feature = "kms"))] +pub fn load_seed(config: &Box<ServerConfig>) -> Result<Vec<u8>, error::Error> { + match config.key_protection() { + KeyProtection::Plaintext => Ok(config.seed()), + v => Err(error::Error::InvalidConfiguration( + format!("key_protection '{}' implies KMS but server was not compiled with KMS support", v))) + } +} |