Skip to content

Commit

Permalink
Add support for internal verification and key fingerprinting (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
Firstyear authored Nov 22, 2023
1 parent cecc21f commit 9d78726
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "kanidm-hsm-crypto"
description = "A library for easily interacting with a HSM or TPM"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
homepage = "https://github.com/kanidm/hsm-crypto/"
Expand Down
29 changes: 28 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum AuthValue {
Key256Bit { auth_key: Zeroizing<[u8; 32]> },
}

#[derive(Debug, Copy, Clone)]
pub enum KeyAlgorithm {
Rsa2048,
Ecdsa256,
Expand Down Expand Up @@ -109,10 +110,13 @@ pub enum TpmError {
EcKeyPrivateToDer,
EcKeyFromDer,
EcKeyToPrivateKey,
IdentityKeyDigest,
IdentityKeyPublicToDer,
IdentityKeyPublicToPem,
IdentityKeyInvalidForSigning,
IdentityKeyInvalidForVerification,
IdentityKeySignature,
IdentityKeyVerification,
IdentityKeyX509ToPem,
IdentityKeyX509ToDer,
IdentityKeyX509Missing,
Expand Down Expand Up @@ -247,6 +251,15 @@ pub enum IdentityKey {
},
}

impl IdentityKey {
pub fn alg(&self) -> KeyAlgorithm {
match self {
IdentityKey::SoftEcdsa256 { .. } => KeyAlgorithm::Ecdsa256,
IdentityKey::SoftRsa2048 { .. } => KeyAlgorithm::Rsa2048,
}
}
}

pub trait Tpm {
fn machine_key_create(
&mut self,
Expand Down Expand Up @@ -281,8 +294,17 @@ pub trait Tpm {
loadable_key: &LoadableIdentityKey,
) -> Result<IdentityKey, TpmError>;

fn identity_key_id(&mut self, key: &IdentityKey) -> Result<Vec<u8>, TpmError>;

fn identity_key_sign(&mut self, key: &IdentityKey, input: &[u8]) -> Result<Vec<u8>, TpmError>;

fn identity_key_verify(
&mut self,
key: &IdentityKey,
input: &[u8],
signature: &[u8],
) -> Result<bool, TpmError>;

fn identity_key_certificate_request(
&mut self,
mk: &MachineKey,
Expand Down Expand Up @@ -433,14 +455,19 @@ mod tests {
.expect("Unable to get id key public pem");

// Rehydrate the der to a public key.

let public_key = PKey::public_key_from_der(&id_key_public_der).expect("Invalid DER");

let input = "test string";
let signature = $tpm
.identity_key_sign(&id_key, input.as_bytes())
.expect("Unable to sign input");

// Internal verification
assert!($tpm
.identity_key_verify(&id_key, input.as_bytes(), signature.as_slice())
.expect("Unable to sign input"));

// External verification.
let mut verifier = Verifier::new(MessageDigest::sha256(), &public_key)
.expect("Unable to setup verifier.");

Expand Down
41 changes: 39 additions & 2 deletions src/soft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use crate::{
use zeroize::Zeroizing;

use openssl::ec::{EcGroup, EcKey};
use openssl::hash::MessageDigest;
use openssl::hash::{hash, MessageDigest};
use openssl::nid::Nid;
use openssl::pkey::PKey;
use openssl::rand::rand_bytes;
use openssl::rsa::Rsa;
use openssl::sign::Signer;
use openssl::sign::{Signer, Verifier};
use openssl::symm::{Cipher, Crypter, Mode};
use openssl::x509::{X509NameBuilder, X509ReqBuilder, X509};

Expand Down Expand Up @@ -305,6 +305,19 @@ impl Tpm for SoftTpm {
}
}

/// Aka key fingerprint
fn identity_key_id(&mut self, key: &IdentityKey) -> Result<Vec<u8>, TpmError> {
let der = self.identity_key_public_as_der(key)?;

let digest = MessageDigest::sha256();
hash(digest, &der)
.map(|bytes| bytes.to_vec())
.map_err(|ossl_err| {
error!(?ossl_err);
TpmError::IdentityKeyDigest
})
}

fn identity_key_public_as_der(&mut self, key: &IdentityKey) -> Result<Vec<u8>, TpmError> {
match key {
IdentityKey::SoftEcdsa256 { pkey, x509: _ }
Expand Down Expand Up @@ -380,6 +393,30 @@ impl Tpm for SoftTpm {
})
}

fn identity_key_verify(
&mut self,
key: &IdentityKey,
input: &[u8],
signature: &[u8],
) -> Result<bool, TpmError> {
let mut verifier = match key {
IdentityKey::SoftEcdsa256 { pkey, x509: _ }
| IdentityKey::SoftRsa2048 { pkey, x509: _ } => {
Verifier::new(MessageDigest::sha256(), pkey).map_err(|ossl_err| {
error!(?ossl_err);
TpmError::IdentityKeyInvalidForVerification
})?
}
};

verifier
.verify_oneshot(signature, input)
.map_err(|ossl_err| {
error!(?ossl_err);
TpmError::IdentityKeyVerification
})
}

fn identity_key_certificate_request(
&mut self,
mk: &MachineKey,
Expand Down
4 changes: 4 additions & 0 deletions src/tpm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ impl Tpm for TpmTss {
Err(TpmError::TpmOperationUnsupported)
}

fn identity_key_id(&mut self, _key: &IdentityKey) -> Result<Vec<u8>, TpmError> {
Err(TpmError::TpmOperationUnsupported)
}

fn identity_key_sign(
&mut self,
_key: &IdentityKey,
Expand Down

0 comments on commit 9d78726

Please sign in to comment.