LCOV - differential code coverage report
Current view: top level - proxy/src/scram - signature.rs (source / functions) Coverage Total Hit UBC CBC
Current: f6946e90941b557c917ac98cd5a7e9506d180f3e.info Lines: 94.3 % 35 33 2 33
Current Date: 2023-10-19 02:04:12 Functions: 66.7 % 6 4 2 4
Baseline: c8637f37369098875162f194f92736355783b050.info
Baseline Date: 2023-10-18 20:25:20

           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          60 :     pub fn build(&self, key: &ScramKey) -> Signature {
      15              60 :         let parts = [
      16              60 :             self.client_first_message_bare.as_bytes(),
      17              60 :             b",",
      18              60 :             self.server_first_message.as_bytes(),
      19              60 :             b",",
      20              60 :             self.client_final_message_without_proof.as_bytes(),
      21              60 :         ];
      22              60 : 
      23              60 :         super::hmac_sha256(key.as_ref(), parts).into()
      24              60 :     }
      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          32 :     pub fn derive_client_key(&self, proof: &[u8; SCRAM_KEY_LEN]) -> ScramKey {
      38              32 :         // This is how the proof is calculated:
      39              32 :         //
      40              32 :         // 1. sha256(ClientKey) -> StoredKey
      41              32 :         // 2. hmac_sha256(StoredKey, [messages...]) -> ClientSignature
      42              32 :         // 3. ClientKey ^ ClientSignature -> ClientProof
      43              32 :         //
      44              32 :         // Step 3 implies that we can restore ClientKey from the proof
      45              32 :         // by xoring the latter with the ClientSignature. Afterwards we
      46              32 :         // can check that the presumed ClientKey meets our expectations.
      47              32 :         let mut signature = self.bytes;
      48            1024 :         for (i, x) in proof.iter().enumerate() {
      49            1024 :             signature[i] ^= x;
      50            1024 :         }
      51                 : 
      52              32 :         signature.into()
      53              32 :     }
      54                 : }
      55                 : 
      56                 : impl From<[u8; SCRAM_KEY_LEN]> for Signature {
      57              60 :     fn from(bytes: [u8; SCRAM_KEY_LEN]) -> Self {
      58              60 :         Self { bytes }
      59              60 :     }
      60                 : }
      61                 : 
      62                 : impl AsRef<[u8]> for Signature {
      63              28 :     fn as_ref(&self) -> &[u8] {
      64              28 :         &self.bytes
      65              28 :     }
      66                 : }
        

Generated by: LCOV version 2.1-beta