Remove .unwrap() in SCRAM code.

Emmanuel Gil Peyrot created

Change summary

sasl/src/client/mechanisms/scram.rs |  8 ++++----
sasl/src/common/scram.rs            | 22 +++++++++++++---------
sasl/src/server/mechanisms/scram.rs |  8 ++++----
3 files changed, 21 insertions(+), 17 deletions(-)

Detailed changes

sasl/src/client/mechanisms/scram.rs 🔗

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

sasl/src/common/scram.rs 🔗

@@ -33,7 +33,7 @@ pub trait ScramProvider {
     fn hash(data: &[u8]) -> Vec<u8>;
 
     /// 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.
     fn derive(data: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String>;
@@ -43,7 +43,6 @@ pub trait ScramProvider {
 pub struct Sha1;
 
 impl ScramProvider for Sha1 {
-    // TODO: look at all these unwraps
     type Secret = secret::Pbkdf2Sha1;
 
     fn name() -> &'static str {
@@ -57,14 +56,17 @@ impl ScramProvider for Sha1 {
         vec
     }
 
-    fn hmac(data: &[u8], key: &[u8]) -> Vec<u8> {
+    fn hmac(data: &[u8], key: &[u8]) -> Result<Vec<u8>, String> {
         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);
         let result = mac.result();
         let mut vec = Vec::with_capacity(Sha1_hash::output_size());
         vec.extend_from_slice(result.code().as_slice());
-        vec
+        Ok(vec)
     }
 
     fn derive(password: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String> {
@@ -105,7 +107,6 @@ impl ScramProvider for Sha1 {
 pub struct Sha256;
 
 impl ScramProvider for Sha256 {
-    // TODO: look at all these unwraps
     type Secret = secret::Pbkdf2Sha256;
 
     fn name() -> &'static str {
@@ -119,14 +120,17 @@ impl ScramProvider for Sha256 {
         vec
     }
 
-    fn hmac(data: &[u8], key: &[u8]) -> Vec<u8> {
+    fn hmac(data: &[u8], key: &[u8]) -> Result<Vec<u8>, String> {
         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);
         let result = mac.result();
         let mut vec = Vec::with_capacity(Sha256_hash::output_size());
         vec.extend_from_slice(result.code().as_slice());
-        vec
+        Ok(vec)
     }
 
     fn derive(password: &Password, salt: &[u8], iterations: usize) -> Result<Vec<u8>, String> {

sasl/src/server/mechanisms/scram.rs 🔗

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