summaryrefslogtreecommitdiff
path: root/src/key
diff options
context:
space:
mode:
authorStuart Stock <stuart@int08h.com>2018-10-11 21:27:10 -0500
committerStuart Stock <stuart@int08h.com>2018-10-11 21:27:10 -0500
commitdda76cfc88d6673358c6dd21007c227c45ccb13f (patch)
treef0b62cb5a1db2c098d368831c2d8847ea1dffa77 /src/key
parentc66513b606f6aacf61bab1434c1f512c24981b2b (diff)
downloadroughenough-dda76cfc88d6673358c6dd21007c227c45ccb13f.zip
another wip checkpoint; server integration
Diffstat (limited to 'src/key')
-rw-r--r--src/key/awskms.rs5
-rw-r--r--src/key/envelope.rs6
-rw-r--r--src/key/longterm.rs9
-rw-r--r--src/key/mod.rs49
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)))
+ }
+}