diff options
-rw-r--r-- | Cargo.lock | 148 | ||||
-rw-r--r-- | Cargo.toml | 5 | ||||
-rw-r--r-- | src/cipherstring.rs | 29 | ||||
-rw-r--r-- | src/error.rs | 5 | ||||
-rw-r--r-- | src/identity.rs | 27 |
5 files changed, 142 insertions, 72 deletions
@@ -143,6 +143,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] +name = "base64ct" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" + +[[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -160,6 +166,15 @@ dependencies = [ ] [[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] name = "block-modes" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -270,6 +285,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + +[[package]] name = "crossbeam-utils" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -291,6 +312,16 @@ dependencies = [ ] [[package]] +name = "crypto-mac" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" +dependencies = [ + "generic-array 0.14.4", + "subtle", +] + +[[package]] name = "daemonize" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -370,6 +401,15 @@ dependencies = [ ] [[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] name = "digest-buffer" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -620,17 +660,37 @@ dependencies = [ ] [[package]] +name = "hkdf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" +dependencies = [ + "digest 0.9.0", + "hmac 0.10.1", +] + +[[package]] name = "hmac" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdb5aa9647ba4711e9d6968dc1c810cd23989ed435443ca962e1bf6d8b8b83ff" dependencies = [ - "crypto-mac", - "digest", + "crypto-mac 0.3.0", + "digest 0.5.2", "generic-array 0.7.3", ] [[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.0", + "digest 0.9.0", +] + +[[package]] name = "http" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -914,11 +974,11 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec6405dc6afe8219020d535f9ad888a12b191bbc8ce1c55f7ee663bde5be80ca" dependencies = [ - "digest", - "hmac", + "digest 0.5.2", + "hmac 0.1.1", "rustc-hex", "sha-1", - "sha2", + "sha2 0.5.3", ] [[package]] @@ -998,6 +1058,16 @@ dependencies = [ ] [[package]] +name = "password-hash" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85d8faea6c018131952a192ee55bd9394c51fc6f63294b668d97636e6f842d40" +dependencies = [ + "base64ct", + "rand_core", +] + +[[package]] name = "paw" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1025,6 +1095,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f0b59668fe80c5afe998f0c0bf93322bf2cd66cafeeb80581f291716f3467f2" [[package]] +name = "pbkdf2" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf916dd32dd26297907890d99dc2740e33f6bd9073965af4ccff2967962f5508" +dependencies = [ + "base64ct", + "crypto-mac 0.10.0", + "hmac 0.10.1", + "password-hash", + "sha2 0.9.3", +] + +[[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1171,6 +1254,8 @@ dependencies = [ "daemonize", "directories", "env_logger", + "hkdf", + "hmac 0.10.1", "humantime", "libc", "log", @@ -1178,15 +1263,16 @@ dependencies = [ "oath", "openssl", "paw", + "pbkdf2", "percent-encoding", "rand", "region", "reqwest", - "ring", "serde", "serde_json", "serde_path_to_error", "serde_repr", + "sha2 0.9.3", "structopt", "tempfile", "term_size", @@ -1298,21 +1384,6 @@ dependencies = [ ] [[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] name = "rust-argon2" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1451,7 +1522,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8347606816471548cd60f0abd5ef0d513a81f5202dbdab9c09f17a15b5248484" dependencies = [ "byte-tools", - "digest", + "digest 0.5.2", "digest-buffer", "fake-simd", "generic-array 0.7.3", @@ -1464,13 +1535,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84920f9ac881e94e33ec89e1b3dcd36040523a308a92548e01217ce35d8cf6a8" dependencies = [ "byte-tools", - "digest", + "digest 0.5.2", "digest-buffer", "fake-simd", "generic-array 0.7.3", ] [[package]] +name = "sha2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" +dependencies = [ + "block-buffer", + "cfg-if", + "cpuid-bool", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] name = "signal-hook-registry" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1508,12 +1592,6 @@ dependencies = [ ] [[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1551,6 +1629,12 @@ dependencies = [ ] [[package]] +name = "subtle" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" + +[[package]] name = "syn" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1791,12 +1875,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] name = "url" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -23,6 +23,8 @@ chbs = "0.1" daemonize = "0.4" directories = "3.0" env_logger = "0.8" +hkdf = "0.10" +hmac = { version = "0.10", features = ["std"] } humantime = "2.1" libc = "0.2" log = "0.4" @@ -30,15 +32,16 @@ nix = "0.20" oath = "0.10" openssl = "0.10" paw = "1.0" +pbkdf2 = "0.7" percent-encoding = "2.1" rand = "0.8" region = "2.2" reqwest = { version = "0.11", features = ["blocking", "json"] } -ring = "0.16" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_path_to_error = "0.1" serde_repr = "0.1" +sha2 = "0.9" structopt = { version = "0.3", features = ["paw", "wrap_help"] } tempfile = "3.2" term_size = "0.3" diff --git a/src/cipherstring.rs b/src/cipherstring.rs index f213cf7..cd1d25b 100644 --- a/src/cipherstring.rs +++ b/src/cipherstring.rs @@ -1,6 +1,7 @@ use crate::prelude::*; use block_modes::BlockMode as _; +use hmac::{Mac as _, NewMac as _}; use rand::RngCore as _; pub enum CipherString { @@ -94,8 +95,6 @@ impl CipherString { ) -> Result<Self> { let iv = random_iv(); - // ring doesn't currently support CBC ciphers, so we have to do it - // manually. see https://github.com/briansmith/ring/issues/588 let cipher = block_modes::Cbc::< aes::Aes256, block_modes::block_padding::Pkcs7, @@ -103,12 +102,12 @@ impl CipherString { .map_err(|source| Error::CreateBlockMode { source })?; let ciphertext = cipher.encrypt_vec(plaintext); - let mut digest = ring::hmac::Context::with_key( - &ring::hmac::Key::new(ring::hmac::HMAC_SHA256, keys.mac_key()), - ); + let mut digest = + hmac::Hmac::<sha2::Sha256>::new_varkey(keys.mac_key()) + .map_err(|source| Error::CreateHmac { source })?; digest.update(&iv); digest.update(&ciphertext); - let mac = digest.sign().as_ref().to_vec(); + let mac = digest.finalize().into_bytes().as_slice().to_vec(); Ok(Self::Symmetric { iv, @@ -182,9 +181,6 @@ impl CipherString { ) -> Result<crate::locked::Vec> { match self { Self::Asymmetric { ciphertext } => { - // ring doesn't currently support asymmetric encryption (only - // signatures). see - // https://github.com/briansmith/ring/issues/691 let pkey = openssl::pkey::PKey::private_key_from_pkcs8( private_key.private_key(), ) @@ -223,21 +219,16 @@ fn decrypt_common_symmetric( ) -> Result<block_modes::Cbc<aes::Aes256, block_modes::block_padding::Pkcs7>> { if let Some(mac) = mac { - let key = - ring::hmac::Key::new(ring::hmac::HMAC_SHA256, keys.mac_key()); - // it'd be nice to not have to pull this into a vec, but ring - // doesn't currently support non-contiguous verification. see - // https://github.com/briansmith/ring/issues/615 - let data: Vec<_> = - iv.iter().chain(ciphertext.iter()).copied().collect(); + let mut key = hmac::Hmac::<sha2::Sha256>::new_varkey(keys.mac_key()) + .map_err(|source| Error::CreateHmac { source })?; + key.update(&iv); + key.update(&ciphertext); - if ring::hmac::verify(&key, &data, mac).is_err() { + if key.verify(mac).is_err() { return Err(Error::InvalidMac); } } - // ring doesn't currently support CBC ciphers, so we have to do it - // manually. see https://github.com/briansmith/ring/issues/588 Ok(block_modes::Cbc::< aes::Aes256, block_modes::block_padding::Pkcs7, diff --git a/src/error.rs b/src/error.rs index 3576aa1..28f8504 100644 --- a/src/error.rs +++ b/src/error.rs @@ -8,6 +8,11 @@ pub enum Error { source: block_modes::InvalidKeyIvLength, }, + #[error("failed to create block mode decryptor")] + CreateHmac { + source: hmac::crypto_mac::InvalidKeyLength, + }, + #[error("failed to create directory at {}", .file.display())] CreateDirectory { source: std::io::Error, diff --git a/src/identity.rs b/src/identity.rs index 602940f..90d4fad 100644 --- a/src/identity.rs +++ b/src/identity.rs @@ -19,35 +19,28 @@ impl Identity { keys.extend(std::iter::repeat(0).take(64)); let enc_key = &mut keys.data_mut()[0..32]; - ring::pbkdf2::derive( - ring::pbkdf2::PBKDF2_HMAC_SHA256, - iterations, - email.as_bytes(), + pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>( password.password(), + email.as_bytes(), + iterations.get(), enc_key, ); let mut hash = crate::locked::Vec::new(); hash.extend(std::iter::repeat(0).take(32)); - ring::pbkdf2::derive( - ring::pbkdf2::PBKDF2_HMAC_SHA256, - std::num::NonZeroU32::new(1).unwrap(), - password.password(), + pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>( enc_key, + password.password(), + 1, hash.data_mut(), ); - let hkdf = - ring::hkdf::Prk::new_less_safe(ring::hkdf::HKDF_SHA256, enc_key); - hkdf.expand(&[b"enc"], ring::hkdf::HKDF_SHA256) - .map_err(|_| Error::HkdfExpand)? - .fill(enc_key) + let hkdf = hkdf::Hkdf::<sha2::Sha256>::from_prk(enc_key) + .map_err(|_| Error::HkdfExpand)?; + hkdf.expand(b"enc", enc_key) .map_err(|_| Error::HkdfExpand)?; - let mac_key = &mut keys.data_mut()[32..64]; - hkdf.expand(&[b"mac"], ring::hkdf::HKDF_SHA256) - .map_err(|_| Error::HkdfExpand)? - .fill(mac_key) + hkdf.expand(b"mac", mac_key) .map_err(|_| Error::HkdfExpand)?; let keys = crate::locked::Keys::new(keys); |