From 828e61a574f484aea575f3cd98322407d3f9aea5 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 17 Apr 2021 14:24:59 -0400 Subject: stop using ring --- Cargo.lock | 148 +++++++++++++++++++++++++++++++++++++++------------- Cargo.toml | 5 +- src/cipherstring.rs | 29 ++++------ src/error.rs | 5 ++ src/identity.rs | 27 ++++------ 5 files changed, 142 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71a5168..0d14e5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,6 +142,12 @@ version = "0.13.0" 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" @@ -159,6 +165,15 @@ dependencies = [ "constant_time_eq", ] +[[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" @@ -269,6 +284,12 @@ version = "0.8.2" 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" @@ -290,6 +311,16 @@ dependencies = [ "generic-array 0.7.3", ] +[[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" @@ -369,6 +400,15 @@ dependencies = [ "generic-array 0.7.3", ] +[[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" @@ -619,17 +659,37 @@ dependencies = [ "libc", ] +[[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" @@ -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]] @@ -997,6 +1057,16 @@ dependencies = [ "winapi", ] +[[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" @@ -1024,6 +1094,19 @@ version = "1.0.0" 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" @@ -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", @@ -1297,21 +1383,6 @@ dependencies = [ "winreg", ] -[[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" @@ -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,12 +1535,25 @@ 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" @@ -1507,12 +1591,6 @@ dependencies = [ "winapi", ] -[[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" @@ -1550,6 +1628,12 @@ dependencies = [ "syn", ] +[[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" @@ -1790,12 +1874,6 @@ version = "0.2.1" 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" diff --git a/Cargo.toml b/Cargo.toml index 45f2015..8eba338 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 { 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::::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 { 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> { 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::::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::>( 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::>( 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::::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); -- cgit v1.2.3-54-g00ecf