Skip to content

Commit

Permalink
Add verification and add keyhashes
Browse files Browse the repository at this point in the history
  • Loading branch information
quexten committed Jan 10, 2025
1 parent a3c131e commit 1a51803
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 10 deletions.
2 changes: 2 additions & 0 deletions crates/bitwarden-crypto/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub enum CryptoError {
InvalidHashAlgorithm,
#[error("Hash Parse Error")]
HashParseError,
#[error("Invalid signature")]
InvalidSignature,
}

#[derive(Debug, Error)]
Expand Down
16 changes: 14 additions & 2 deletions crates/bitwarden-crypto/src/keys/signing_key.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::pin::Pin;

use super::key_encryptable::CryptoKey;
use super::{key_encryptable::CryptoKey, key_hash::KeyHashData};
use crate::{
error::Result,
signing::{SignatureAlgorithm, Signer, Verifier},
Expand All @@ -11,7 +11,7 @@ pub trait Verifiable {
}

pub struct VerifyingCryptoKey {
verifier: Verifier,
pub(crate) verifier: Verifier,
}

impl VerifyingCryptoKey {
Expand All @@ -31,6 +31,18 @@ pub struct SigningCryptoKey {
pub(crate) signing_key: Pin<Box<Signer>>,
}

impl KeyHashData for SigningCryptoKey {
fn hash_data(&self) -> Vec<u8> {
self.verifier().to_spki_der()
}
}

impl KeyHashData for VerifyingCryptoKey {
fn hash_data(&self) -> Vec<u8> {
self.to_spki_der()
}
}

const _: () = {
fn assert_zeroize_on_drop<T: zeroize::ZeroizeOnDrop>() {}
fn assert_all() {
Expand Down
8 changes: 7 additions & 1 deletion crates/bitwarden-crypto/src/keys/symmetric_crypto_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use generic_array::GenericArray;
use rand::Rng;
use zeroize::Zeroize;

use super::key_encryptable::CryptoKey;
use super::{key_encryptable::CryptoKey, key_hash::KeyHashData};
use crate::CryptoError;

/// A symmetric encryption key. Used to encrypt and decrypt [`EncString`](crate::EncString)
Expand Down Expand Up @@ -135,6 +135,12 @@ impl std::fmt::Debug for SymmetricCryptoKey {
}
}

impl KeyHashData for SymmetricCryptoKey {
fn hash_data(&self) -> Vec<u8> {
self.to_vec()
}
}

#[cfg(test)]
pub fn derive_symmetric_key(name: &str) -> SymmetricCryptoKey {
use zeroize::Zeroizing;
Expand Down
56 changes: 49 additions & 7 deletions crates/bitwarden-crypto/src/sign.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use serde::{Deserialize, Serialize};

use self::key_hash::KeyHashable;
use crate::{
key_hash::{self, KeyHash},
signing,
signing_key::{SigningCryptoKey, VerifyingCryptoKey},
signing_key::{SigningCryptoKey, Verifiable, VerifyingCryptoKey},
CryptoError,
};

Expand Down Expand Up @@ -43,7 +44,7 @@ pub fn trust_identity_key(
) -> Result<Signature, CryptoError> {
let message = IdentityTrustMessage {
identity: peer_identity.clone(),
verifying_key_fingerprint: key_hash::KeyHash::default(),
verifying_key_fingerprint: peer_verifying_key.hash(),
};

let message_bytes = serde_json::to_vec(&message).map_err(|_| CryptoError::InvalidKey)?;
Expand All @@ -52,14 +53,45 @@ pub fn trust_identity_key(
context: SignatureContext::IdentityTrust(peer_identity),
data: message_bytes.clone(),
signature_data: own_signing_key.signing_key.sign(&message_bytes),
signing_key_hash: key_hash::KeyHash::default(),
signing_key_hash: own_signing_key.hash(),
})
}

pub fn verify_identity_trust(
own_signing_key: &mut SigningCryptoKey,
peer_verifying_key: &VerifyingCryptoKey,
peer_identity: TrustIdentity,
signature: &Signature,
) -> Result<(), CryptoError> {
if let SignatureContext::IdentityTrust(message_peer_identity) = &signature.context {
if !message_peer_identity.eq(&peer_identity) {
return Err(CryptoError::InvalidSignature);
}
} else {
return Err(CryptoError::InvalidSignature);
}

let message = IdentityTrustMessage {
identity: peer_identity.clone(),
verifying_key_fingerprint: peer_verifying_key.hash(),
};

let message_bytes = serde_json::to_vec(&message).map_err(|_| CryptoError::InvalidKey)?;
if !own_signing_key
.verifier()
.verifier
.verify(&message_bytes, &signature.signature_data)
{
return Err(CryptoError::InvalidSignature);
}

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{signing::Signer, signing_key::Verifiable};
use crate::signing_key::Verifiable;

#[test]
fn test_trust_identity_key() {
Expand All @@ -68,8 +100,18 @@ mod tests {
let peer_verifying_key = peer_signing_key.verifier();
let peer_identity = TrustIdentity::User("test_user_id".to_string());

let signature =
trust_identity_key(&mut own_signing_key, &peer_verifying_key, peer_identity)
.expect("Failed to generate trust signature");
let signature = trust_identity_key(
&mut own_signing_key,
&peer_verifying_key,
peer_identity.clone(),
)
.expect("Failed to generate trust signature");
let verified = verify_identity_trust(
&mut own_signing_key,
&peer_verifying_key,
peer_identity,
&signature,
);
assert!(verified.is_ok());
}
}

0 comments on commit 1a51803

Please sign in to comment.