Remove .unwrap() in SCRAM code.

This commit is contained in:
Emmanuel Gil Peyrot 2019-01-18 00:26:41 +01:00
parent 5337a0a149
commit 0c426b4d17
3 changed files with 21 additions and 17 deletions

View file

@ -137,8 +137,8 @@ impl<S: ScramProvider> Mechanism for Scram<S> {
client_final_message_bare.extend(b",r="); client_final_message_bare.extend(b",r=");
client_final_message_bare.extend(server_nonce.bytes()); client_final_message_bare.extend(server_nonce.bytes());
let salted_password = S::derive(&self.password, &salt, iterations)?; let salted_password = S::derive(&self.password, &salt, iterations)?;
let client_key = S::hmac(b"Client Key", &salted_password); let client_key = S::hmac(b"Client Key", &salted_password)?;
let server_key = S::hmac(b"Server Key", &salted_password); let server_key = S::hmac(b"Server Key", &salted_password)?;
let mut auth_message = Vec::new(); let mut auth_message = Vec::new();
auth_message.extend(initial_message); auth_message.extend(initial_message);
auth_message.push(b','); auth_message.push(b',');
@ -146,9 +146,9 @@ impl<S: ScramProvider> Mechanism for Scram<S> {
auth_message.push(b','); auth_message.push(b',');
auth_message.extend(&client_final_message_bare); auth_message.extend(&client_final_message_bare);
let stored_key = S::hash(&client_key); let stored_key = S::hash(&client_key);
let client_signature = S::hmac(&auth_message, &stored_key); let client_signature = S::hmac(&auth_message, &stored_key)?;
let client_proof = xor(&client_key, &client_signature); let client_proof = xor(&client_key, &client_signature);
let server_signature = S::hmac(&auth_message, &server_key); let server_signature = S::hmac(&auth_message, &server_key)?;
let mut client_final_message = Vec::new(); let mut client_final_message = Vec::new();
client_final_message.extend(&client_final_message_bare); client_final_message.extend(&client_final_message_bare);
client_final_message.extend(b",p="); client_final_message.extend(b",p=");

View file

@ -33,7 +33,7 @@ pub trait ScramProvider {
fn hash(data: &[u8]) -> Vec<u8>; fn hash(data: &[u8]) -> Vec<u8>;
/// A function which performs an HMAC using the hash function. /// A function which performs an HMAC using the hash function.
fn hmac(data: &[u8], key: &[u8]) -> Vec<u8>; fn hmac(data: &[u8], key: &[u8]) -> Result<Vec<u8>, String>;
/// A function which does PBKDF2 key derivation using the hash function. /// A function which does PBKDF2 key derivation using the hash function.
fn derive(data: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String>; fn derive(data: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String>;
@ -43,7 +43,6 @@ pub trait ScramProvider {
pub struct Sha1; pub struct Sha1;
impl ScramProvider for Sha1 { impl ScramProvider for Sha1 {
// TODO: look at all these unwraps
type Secret = secret::Pbkdf2Sha1; type Secret = secret::Pbkdf2Sha1;
fn name() -> &'static str { fn name() -> &'static str {
@ -57,14 +56,17 @@ impl ScramProvider for Sha1 {
vec vec
} }
fn hmac(data: &[u8], key: &[u8]) -> Vec<u8> { fn hmac(data: &[u8], key: &[u8]) -> Result<Vec<u8>, String> {
type HmacSha1 = Hmac<Sha1_hash>; type HmacSha1 = Hmac<Sha1_hash>;
let mut mac = HmacSha1::new_varkey(key).unwrap(); let mut mac = match HmacSha1::new_varkey(key) {
Ok(mac) => mac,
Err(err) => return Err(format!("{}", err)),
};
mac.input(data); mac.input(data);
let result = mac.result(); let result = mac.result();
let mut vec = Vec::with_capacity(Sha1_hash::output_size()); let mut vec = Vec::with_capacity(Sha1_hash::output_size());
vec.extend_from_slice(result.code().as_slice()); vec.extend_from_slice(result.code().as_slice());
vec Ok(vec)
} }
fn derive(password: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String> { fn derive(password: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String> {
@ -105,7 +107,6 @@ impl ScramProvider for Sha1 {
pub struct Sha256; pub struct Sha256;
impl ScramProvider for Sha256 { impl ScramProvider for Sha256 {
// TODO: look at all these unwraps
type Secret = secret::Pbkdf2Sha256; type Secret = secret::Pbkdf2Sha256;
fn name() -> &'static str { fn name() -> &'static str {
@ -119,14 +120,17 @@ impl ScramProvider for Sha256 {
vec vec
} }
fn hmac(data: &[u8], key: &[u8]) -> Vec<u8> { fn hmac(data: &[u8], key: &[u8]) -> Result<Vec<u8>, String> {
type HmacSha256 = Hmac<Sha256_hash>; type HmacSha256 = Hmac<Sha256_hash>;
let mut mac = HmacSha256::new_varkey(key).unwrap(); let mut mac = match HmacSha256::new_varkey(key) {
Ok(mac) => mac,
Err(err) => return Err(format!("{}", err)),
};
mac.input(data); mac.input(data);
let result = mac.result(); let result = mac.result();
let mut vec = Vec::with_capacity(Sha256_hash::output_size()); let mut vec = Vec::with_capacity(Sha256_hash::output_size());
vec.extend_from_slice(result.code().as_slice()); vec.extend_from_slice(result.code().as_slice());
vec Ok(vec)
} }
fn derive(password: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String> { fn derive(password: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String> {

View file

@ -150,8 +150,8 @@ where
client_final_message_bare.extend(base64::encode(&cb_data).bytes()); client_final_message_bare.extend(base64::encode(&cb_data).bytes());
client_final_message_bare.extend(b",r="); client_final_message_bare.extend(b",r=");
client_final_message_bare.extend(server_nonce.bytes()); client_final_message_bare.extend(server_nonce.bytes());
let client_key = S::hmac(b"Client Key", &salted_password); let client_key = S::hmac(b"Client Key", &salted_password)?;
let server_key = S::hmac(b"Server Key", &salted_password); let server_key = S::hmac(b"Server Key", &salted_password)?;
let mut auth_message = Vec::new(); let mut auth_message = Vec::new();
auth_message.extend(initial_client_message); auth_message.extend(initial_client_message);
auth_message.extend(b","); auth_message.extend(b",");
@ -159,7 +159,7 @@ where
auth_message.extend(b","); auth_message.extend(b",");
auth_message.extend(client_final_message_bare.clone()); auth_message.extend(client_final_message_bare.clone());
let stored_key = S::hash(&client_key); let stored_key = S::hash(&client_key);
let client_signature = S::hmac(&auth_message, &stored_key); let client_signature = S::hmac(&auth_message, &stored_key)?;
let client_proof = xor(&client_key, &client_signature); let client_proof = xor(&client_key, &client_signature);
let sent_proof = frame.get("p").ok_or_else(|| "no proof".to_owned())?; let sent_proof = frame.get("p").ok_or_else(|| "no proof".to_owned())?;
let sent_proof = let sent_proof =
@ -167,7 +167,7 @@ where
if client_proof != sent_proof { if client_proof != sent_proof {
return Err("authentication failed".to_owned()); return Err("authentication failed".to_owned());
} }
let server_signature = S::hmac(&auth_message, &server_key); let server_signature = S::hmac(&auth_message, &server_key)?;
let mut buf = Vec::new(); let mut buf = Vec::new();
buf.extend(b"v="); buf.extend(b"v=");
buf.extend(base64::encode(&server_signature).bytes()); buf.extend(base64::encode(&server_signature).bytes());