aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-05-03 00:21:07 -0400
committerJesse Luehrs <doy@tozt.net>2020-05-03 00:56:21 -0400
commit047550f2368d134c9d5dca60aeb0b56fe151a323 (patch)
tree2ad014146d2214db42f550646379bb2dbd571ff1
parentea6398d5951ef6a5811cf605bfa223b5b1ce08c4 (diff)
downloadrbw-047550f2368d134c9d5dca60aeb0b56fe151a323.tar.gz
rbw-047550f2368d134c9d5dca60aeb0b56fe151a323.zip
move to ring for things that it supports
it doesn't support AES_256_CBC_HMAC_SHA256, so we can't move that over yet (see https://github.com/briansmith/ring/issues/588)
-rw-r--r--Cargo.lock211
-rw-r--r--Cargo.toml5
-rw-r--r--src/cipherstring.rs52
-rw-r--r--src/error.rs18
-rw-r--r--src/identity.rs29
5 files changed, 92 insertions, 223 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a9e9943..a2d218b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -115,16 +115,6 @@ dependencies = [
[[package]]
name = "base64"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
-dependencies = [
- "byteorder",
- "safemem",
-]
-
-[[package]]
-name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
@@ -147,18 +137,6 @@ dependencies = [
]
[[package]]
-name = "block-buffer"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
-dependencies = [
- "block-padding",
- "byte-tools",
- "byteorder",
- "generic-array",
-]
-
-[[package]]
name = "block-cipher-trait"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -218,9 +196,9 @@ checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
[[package]]
name = "cc"
-version = "1.0.50"
+version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
+checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
[[package]]
name = "cfg-if"
@@ -236,7 +214,7 @@ checksum = "9b8579452901e185b65f91bc5571f9543ede86f3238389105a0f44dd4b9a82ab"
dependencies = [
"derive_builder",
"failure",
- "rand 0.7.3",
+ "rand",
]
[[package]]
@@ -256,15 +234,6 @@ dependencies = [
]
[[package]]
-name = "cloudabi"
-version = "0.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -298,16 +267,6 @@ dependencies = [
]
[[package]]
-name = "crypto-mac"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
-dependencies = [
- "generic-array",
- "subtle",
-]
-
-[[package]]
name = "daemonize"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -378,15 +337,6 @@ dependencies = [
]
[[package]]
-name = "digest"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
name = "directories"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -465,12 +415,6 @@ dependencies = [
]
[[package]]
-name = "fake-simd"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
-
-[[package]]
name = "fnv"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -492,12 +436,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
-name = "fuchsia-cprng"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
-
-[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -609,26 +547,6 @@ dependencies = [
]
[[package]]
-name = "hkdf"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3"
-dependencies = [
- "digest",
- "hmac",
-]
-
-[[package]]
-name = "hmac"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
-dependencies = [
- "crypto-mac",
- "digest",
-]
-
-[[package]]
name = "http"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -936,6 +854,12 @@ dependencies = [
]
[[package]]
+name = "once_cell"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b"
+
+[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -975,21 +899,6 @@ dependencies = [
]
[[package]]
-name = "pbkdf2"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9"
-dependencies = [
- "base64 0.9.3",
- "byteorder",
- "crypto-mac",
- "hmac",
- "rand 0.5.6",
- "sha2",
- "subtle",
-]
-
-[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1065,19 +974,6 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
-dependencies = [
- "cloudabi",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.3.1",
- "winapi 0.3.8",
-]
-
-[[package]]
-name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
@@ -1085,7 +981,7 @@ dependencies = [
"getrandom",
"libc",
"rand_chacha",
- "rand_core 0.5.1",
+ "rand_core",
"rand_hc",
]
@@ -1096,26 +992,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
-dependencies = [
- "rand_core 0.4.2",
+ "rand_core",
]
[[package]]
name = "rand_core"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
-
-[[package]]
-name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
@@ -1129,7 +1010,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
- "rand_core 0.5.1",
+ "rand_core",
]
[[package]]
@@ -1139,25 +1020,22 @@ dependencies = [
"aes",
"anyhow",
"arrayvec",
- "base64 0.11.0",
+ "base64",
"block-modes",
"chbs",
"clap",
"daemonize",
"directories",
"env_logger",
- "hkdf",
- "hmac",
"humantime",
"log",
"nix",
- "pbkdf2",
- "rand 0.7.3",
+ "rand",
"region",
"reqwest",
+ "ring",
"serde",
"serde_json",
- "sha2",
"snafu",
"tempfile",
"tokio",
@@ -1227,7 +1105,7 @@ version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b81e49ddec5109a9dcfc5f2a317ff53377c915e9ae9d4f2fb50914b85614e2"
dependencies = [
- "base64 0.11.0",
+ "base64",
"bytes",
"encoding_rs",
"futures-core",
@@ -1258,12 +1136,27 @@ dependencies = [
]
[[package]]
+name = "ring"
+version = "0.16.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "703516ae74571f24b465b4a1431e81e2ad51336cb0ded733a55a1aa3eccac196"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
+ "winapi 0.3.8",
+]
+
+[[package]]
name = "rust-argon2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
dependencies = [
- "base64 0.11.0",
+ "base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
@@ -1282,12 +1175,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
[[package]]
-name = "safemem"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
-
-[[package]]
name = "schannel"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1364,18 +1251,6 @@ dependencies = [
]
[[package]]
-name = "sha2"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
-dependencies = [
- "block-buffer",
- "digest",
- "fake-simd",
- "opaque-debug",
-]
-
-[[package]]
name = "signal-hook-registry"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1431,6 +1306,12 @@ 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"
@@ -1443,12 +1324,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
-name = "subtle"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
-
-[[package]]
name = "syn"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1479,7 +1354,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"libc",
- "rand 0.7.3",
+ "rand",
"redox_syscall",
"remove_dir_all",
"winapi 0.3.8",
@@ -1652,6 +1527,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
name = "url"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1668,7 +1549,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
dependencies = [
- "rand 0.7.3",
+ "rand",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 025d76c..52dcb75 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,18 +22,15 @@ clap = { version = "2.33", features = ["wrap_help"] }
daemonize = "0.4"
directories = "2.0"
env_logger = "0.7"
-hkdf = "0.8"
-hmac = "0.7"
humantime = "1.3"
log = "0.4"
nix = "0.17"
-pbkdf2 = "0.3"
rand = "0.7"
region = "2.1"
reqwest = { version = "0.10", features = ["blocking", "json"] }
+ring = "0.16"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
-sha2 = "0.8"
snafu = "0.6"
tempfile = "3.1"
tokio = { version = "0.2", features = ["full"] }
diff --git a/src/cipherstring.rs b/src/cipherstring.rs
index 2398b07..09d5c88 100644
--- a/src/cipherstring.rs
+++ b/src/cipherstring.rs
@@ -1,7 +1,6 @@
use crate::prelude::*;
use block_modes::BlockMode as _;
-use hmac::Mac as _;
use rand::RngCore as _;
pub struct CipherString {
@@ -58,6 +57,8 @@ 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,
@@ -65,12 +66,12 @@ impl CipherString {
.context(crate::error::CreateBlockMode)?;
let ciphertext = cipher.encrypt_vec(plaintext);
- let mut digest =
- hmac::Hmac::<sha2::Sha256>::new_varkey(keys.mac_key())
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(&iv);
- digest.input(&ciphertext);
- let mac = digest.result().code().to_vec();
+ let mut digest = ring::hmac::Context::with_key(
+ &ring::hmac::Key::new(ring::hmac::HMAC_SHA256, keys.mac_key()),
+ );
+ digest.update(&iv);
+ digest.update(&ciphertext);
+ let mac = digest.sign().as_ref().to_vec();
Ok(Self {
ty: 2,
@@ -111,18 +112,25 @@ impl CipherString {
}
if let Some(mac) = &self.mac {
- let mut digest =
- hmac::Hmac::<sha2::Sha256>::new_varkey(keys.mac_key())
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(&self.iv);
- digest.input(&self.ciphertext);
- let calculated_mac = digest.result().code();
-
- if !macs_equal(mac, &calculated_mac, keys.mac_key())? {
+ 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<_> = self
+ .iv
+ .iter()
+ .chain(self.ciphertext.iter())
+ .copied()
+ .collect();
+
+ if ring::hmac::verify(&key, &data, 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,
@@ -144,20 +152,6 @@ impl std::fmt::Display for CipherString {
}
}
-fn macs_equal(mac1: &[u8], mac2: &[u8], mac_key: &[u8]) -> Result<bool> {
- let mut digest = hmac::Hmac::<sha2::Sha256>::new_varkey(mac_key)
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(mac1);
- let hmac1 = digest.result().code();
-
- let mut digest = hmac::Hmac::<sha2::Sha256>::new_varkey(mac_key)
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(mac2);
- let hmac2 = digest.result().code();
-
- Ok(hmac1 == hmac2)
-}
-
fn random_iv() -> Vec<u8> {
let mut iv = vec![0_u8; 16];
let mut rng = rand::thread_rng();
diff --git a/src/error.rs b/src/error.rs
index b1ce2b6..2222f66 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -22,18 +22,9 @@ pub enum Error {
res: std::process::ExitStatus,
},
- // no Error impl
- // #[snafu(display("failed to expand with hkdf: {}", source))]
- // HkdfExpand { source: hkdf::InvalidLength },
#[snafu(display("failed to expand with hkdf"))]
HkdfExpand,
- // no Error impl
- // #[snafu(display("failed to create hkdf: {}", source))]
- // HkdfFromPrk { source: hkdf::InvalidPrkLength },
- #[snafu(display("failed to create hkdf"))]
- HkdfFromPrk,
-
#[snafu(display("username or password incorrect"))]
IncorrectPassword,
@@ -49,12 +40,6 @@ pub enum Error {
#[snafu(display("invalid mac"))]
InvalidMac,
- // no Error impl
- // #[snafu(display("invalid mac key: {}", source))]
- // InvalidMacKey { source: hmac::crypto_mac::InvalidKeyLength },
- #[snafu(display("invalid mac key"))]
- InvalidMacKey,
-
#[snafu(display("failed to load config: {}", source))]
LoadConfig { source: std::io::Error },
@@ -73,6 +58,9 @@ pub enum Error {
#[snafu(display("failed to load db: {}", source))]
LoadDbJson { source: serde_json::Error },
+ #[snafu(display("pbkdf2 requires at least 1 iteration (got 0)"))]
+ Pbkdf2ZeroIterations,
+
#[snafu(display("pinentry cancelled"))]
PinentryCancelled,
diff --git a/src/identity.rs b/src/identity.rs
index 1baac0f..8415765 100644
--- a/src/identity.rs
+++ b/src/identity.rs
@@ -12,33 +12,42 @@ impl Identity {
password: &crate::locked::Password,
iterations: u32,
) -> Result<Self> {
+ let iterations = std::num::NonZeroU32::new(iterations)
+ .context(crate::error::Pbkdf2ZeroIterations)?;
+
let mut keys = crate::locked::Vec::new();
keys.extend(std::iter::repeat(0).take(64));
let enc_key = &mut keys.data_mut()[0..32];
- pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>(
- password.password(),
+ ring::pbkdf2::derive(
+ ring::pbkdf2::PBKDF2_HMAC_SHA256,
+ iterations,
email.as_bytes(),
- iterations as usize,
+ password.password(),
enc_key,
);
let mut hash = crate::locked::Vec::new();
hash.extend(std::iter::repeat(0).take(32));
- pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>(
- enc_key,
+ ring::pbkdf2::derive(
+ ring::pbkdf2::PBKDF2_HMAC_SHA256,
+ std::num::NonZeroU32::new(1).unwrap(),
password.password(),
- 1,
+ enc_key,
hash.data_mut(),
);
- let hkdf = hkdf::Hkdf::<sha2::Sha256>::from_prk(enc_key)
- .map_err(|_| Error::HkdfFromPrk)?;
- hkdf.expand(b"enc", enc_key)
+ 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)
.map_err(|_| Error::HkdfExpand)?;
let mac_key = &mut keys.data_mut()[32..64];
- hkdf.expand(b"mac", mac_key)
+ hkdf.expand(&[b"mac"], ring::hkdf::HKDF_SHA256)
+ .map_err(|_| Error::HkdfExpand)?
+ .fill(mac_key)
.map_err(|_| Error::HkdfExpand)?;
let keys = crate::locked::Keys::new(keys);