LCOV - differential code coverage report
Current view: top level - proxy/src/scram - signature.rs (source / functions) Coverage Total Hit UBC CBC
Current: cd44433dd675caa99df17a61b18949c8387e2242.info Lines: 94.3 % 35 33 2 33
Current Date: 2024-01-09 02:06:09 Functions: 66.7 % 6 4 2 4
Baseline: 66c52a629a0f4a503e193045e0df4c77139e344b.info
Baseline Date: 2024-01-08 15:34:46

           TLA  Line data    Source code
       1                 : //! Tools for client/server signature management.
       2                 : 
       3                 : use super::key::{ScramKey, SCRAM_KEY_LEN};
       4                 : 
       5                 : /// A collection of message parts needed to derive the client's signature.
       6 UBC           0 : #[derive(Debug)]
       7                 : pub struct SignatureBuilder<'a> {
       8                 :     pub client_first_message_bare: &'a str,
       9                 :     pub server_first_message: &'a str,
      10                 :     pub client_final_message_without_proof: &'a str,
      11                 : }
      12                 : 
      13                 : impl SignatureBuilder<'_> {
      14 CBC          86 :     pub fn build(&self, key: &ScramKey) -> Signature {
      15              86 :         let parts = [
      16              86 :             self.client_first_message_bare.as_bytes(),
      17              86 :             b",",
      18              86 :             self.server_first_message.as_bytes(),
      19              86 :             b",",
      20              86 :             self.client_final_message_without_proof.as_bytes(),
      21              86 :         ];
      22              86 : 
      23              86 :         super::hmac_sha256(key.as_ref(), parts).into()
      24              86 :     }
      25                 : }
      26                 : 
      27                 : /// A computed value which, when xored with `ClientProof`,
      28                 : /// produces `ClientKey` that we need for authentication.
      29 UBC           0 : #[derive(Debug)]
      30                 : #[repr(transparent)]
      31                 : pub struct Signature {
      32                 :     bytes: [u8; SCRAM_KEY_LEN],
      33                 : }
      34                 : 
      35                 : impl Signature {
      36                 :     /// Derive `ClientKey` from client's signature and proof.
      37 CBC          45 :     pub fn derive_client_key(&self, proof: &[u8; SCRAM_KEY_LEN]) -> ScramKey {
      38              45 :         // This is how the proof is calculated:
      39              45 :         //
      40              45 :         // 1. sha256(ClientKey) -> StoredKey
      41              45 :         // 2. hmac_sha256(StoredKey, [messages...]) -> ClientSignature
      42              45 :         // 3. ClientKey ^ ClientSignature -> ClientProof
      43              45 :         //
      44              45 :         // Step 3 implies that we can restore ClientKey from the proof
      45              45 :         // by xoring the latter with the ClientSignature. Afterwards we
      46              45 :         // can check that the presumed ClientKey meets our expectations.
      47              45 :         let mut signature = self.bytes;
      48            1440 :         for (i, x) in proof.iter().enumerate() {
      49            1440 :             signature[i] ^= x;
      50            1440 :         }
      51                 : 
      52              45 :         signature.into()
      53              45 :     }
      54                 : }
      55                 : 
      56                 : impl From<[u8; SCRAM_KEY_LEN]> for Signature {
      57              86 :     fn from(bytes: [u8; SCRAM_KEY_LEN]) -> Self {
      58              86 :         Self { bytes }
      59              86 :     }
      60                 : }
      61                 : 
      62                 : impl AsRef<[u8]> for Signature {
      63              41 :     fn as_ref(&self) -> &[u8] {
      64              41 :         &self.bytes
      65              41 :     }
      66                 : }
        

Generated by: LCOV version 2.1-beta