Skip to content
This repository was archived by the owner on Sep 4, 2024. It is now read-only.

Commit 9f05ebc

Browse files
committed
Utilize a pin code for Windows Hello
This utilizes changes in hsm-crypto which allow us to set a pin code on the TPM key. This permits pin code authentication. Signed-off-by: David Mulder <dmulder@samba.org>
1 parent 718783f commit 9f05ebc

File tree

3 files changed

+51
-22
lines changed

3 files changed

+51
-22
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Cargo.lock
1313
# MSVC Windows builds of rustc generate these, which store debugging information
1414
*.pdb
1515

16+
tags
1617

1718
# Added by cargo
1819

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ uuid = { version = "^1.4.1", features = [ "v4", "serde" ] }
3030
os-release = "^0.1.0"
3131
hostname = "^0.3.1"
3232
openssl = "^0.10.55"
33-
compact_jwt = { version = "0.3.5", optional = true }
33+
compact_jwt = { version = "0.4.0-dev", git = "https://github.com/dmulder/compact-jwt.git", branch = "dmulder/msextensions_build_fix", optional = true }
3434
kanidm-hsm-crypto = { version = "^0.2.0", optional = true }
3535
regex = "^1.10.3"
3636
zeroize = { version = "^1.7.0", features = ["zeroize_derive"] }

src/auth.rs

+49-21
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ use compact_jwt::traits::JwsSignable;
3232
use compact_jwt::Jws;
3333
#[cfg(feature = "broker")]
3434
use kanidm_hsm_crypto::{
35-
BoxedDynTpm, IdentityKey, KeyAlgorithm, LoadableIdentityKey, MachineKey, SealedData, Tpm,
35+
BoxedDynTpm, IdentityKey, KeyAlgorithm, LoadableIdentityKey, MachineKey, PinValue, SealedData,
36+
Tpm,
3637
};
3738
#[cfg(feature = "broker")]
3839
use kanidm_hsm_crypto::{LoadableMsOapxbcRsaKey, MsOapxbcRsaKey};
@@ -1904,7 +1905,7 @@ impl BrokerClientApplication {
19041905
) -> Result<IdentityKey, MsalError> {
19051906
match &self.cert_key {
19061907
Some(cert_key) => {
1907-
let cert_key = tpm.identity_key_load(machine_key, cert_key)
1908+
let cert_key = tpm.identity_key_load(machine_key, None, cert_key)
19081909
.map_err(|e| {
19091910
MsalError::TPMFail(format!("Failed to load IdentityKey: {:?}", e))
19101911
})?;
@@ -1956,7 +1957,7 @@ impl BrokerClientApplication {
19561957
.await?;
19571958
// Create the transport and cert keys
19581959
let loadable_cert_key = tpm
1959-
.identity_key_create(machine_key, KeyAlgorithm::Rsa2048)
1960+
.identity_key_create(machine_key, None, KeyAlgorithm::Rsa2048)
19601961
.map_err(|e| MsalError::TPMFail(format!("Failed creating certificate key: {:?}", e)))?;
19611962
let loadable_transport_key = tpm
19621963
.msoapxbc_rsa_key_create(machine_key)
@@ -1966,6 +1967,7 @@ impl BrokerClientApplication {
19661967
// Create the CSR
19671968
let csr_der = match tpm.identity_key_certificate_request(
19681969
machine_key,
1970+
None,
19691971
&loadable_cert_key,
19701972
"7E980AD9-B86D-4306-9425-9AC066FB014A",
19711973
) {
@@ -2009,6 +2011,7 @@ impl BrokerClientApplication {
20092011

20102012
let new_loadable_cert_key = match tpm.identity_key_associate_certificate(
20112013
machine_key,
2014+
None,
20122015
&loadable_cert_key,
20132016
&cert
20142017
.to_der()
@@ -2801,24 +2804,26 @@ impl BrokerClientApplication {
28012804
/// acquire_token_by_username_password_for_device_enrollment
28022805
/// or acquire_token_by_device_flow.
28032806
///
2804-
/// * `key` - An optional existing LoadableIdentityKey, if not provided
2805-
/// one will be created.
2806-
///
28072807
/// * `tpm` - The tpm object.
28082808
///
28092809
/// * `machine_key` - The TPM MachineKey associated with this application.
28102810
///
2811+
/// * `pin` - The PIN code which will be used to unlock the key.
2812+
///
28112813
/// # Returns
28122814
/// * Success: Either the existing LoadableIdentityKey, or a new created
28132815
/// key if none was provided.
28142816
/// * Failure: An MsalError, indicating the failure.
28152817
pub async fn provision_hello_for_business_key(
28162818
&self,
28172819
token: &UserToken,
2818-
key: Option<LoadableIdentityKey>,
28192820
tpm: &mut BoxedDynTpm,
28202821
machine_key: &MachineKey,
2822+
pin: &str,
28212823
) -> Result<LoadableIdentityKey, MsalError> {
2824+
let pin = PinValue::new(pin)
2825+
.map_err(|e| MsalError::TPMFail(format!("Failed setting pin value: {:?}", e)))?;
2826+
28222827
// Discover the KeyProvisioningService
28232828
let access_token = match &token.access_token {
28242829
Some(access_token) => access_token.clone(),
@@ -2864,17 +2869,14 @@ impl BrokerClientApplication {
28642869
)
28652870
.await?;
28662871

2867-
// Use an existing key, or create a new hello key (using the TPM)
2868-
let loadable_win_hello_key = match key {
2869-
Some(loadable_win_hello_key) => loadable_win_hello_key,
2870-
None => tpm
2871-
.identity_key_create(machine_key, KeyAlgorithm::Rsa2048)
2872-
.map_err(|e| {
2873-
MsalError::TPMFail(format!("Failed creating Windows Hello Key: {:?}", e))
2874-
})?,
2875-
};
2872+
// Create a new hello key (using the TPM)
2873+
let loadable_win_hello_key = tpm
2874+
.identity_key_create(machine_key, Some(&pin), KeyAlgorithm::Rsa2048)
2875+
.map_err(|e| {
2876+
MsalError::TPMFail(format!("Failed creating Windows Hello Key: {:?}", e))
2877+
})?;
28762878
let win_hello_key = tpm
2877-
.identity_key_load(machine_key, &loadable_win_hello_key)
2879+
.identity_key_load(machine_key, Some(&pin), &loadable_win_hello_key)
28782880
.map_err(|e| {
28792881
MsalError::TPMFail(format!("Failed loading Windows Hello Key: {:?}", e))
28802882
})?;
@@ -2946,6 +2948,8 @@ impl BrokerClientApplication {
29462948
///
29472949
/// * `machine_key` - The TPM MachineKey associated with this application.
29482950
///
2951+
/// * `pin` - The PIN code required to unlock the key.
2952+
///
29492953
/// # Returns
29502954
/// * Success: A UserToken containing an access_token.
29512955
/// * Failure: An MsalError, indicating the failure.
@@ -2956,9 +2960,19 @@ impl BrokerClientApplication {
29562960
scopes: Vec<&str>,
29572961
tpm: &mut BoxedDynTpm,
29582962
machine_key: &MachineKey,
2963+
pin: &str,
29592964
) -> Result<UserToken, MsalError> {
2965+
let pin = PinValue::new(pin)
2966+
.map_err(|e| MsalError::TPMFail(format!("Failed setting pin value: {:?}", e)))?;
2967+
29602968
let prt = self
2961-
.acquire_user_prt_by_hello_for_business_key_internal(username, key, tpm, machine_key)
2969+
.acquire_user_prt_by_hello_for_business_key_internal(
2970+
username,
2971+
key,
2972+
tpm,
2973+
machine_key,
2974+
&pin,
2975+
)
29622976
.await?;
29632977
let transport_key = self.transport_key(tpm, machine_key)?;
29642978
let session_key = prt.session_key()?;
@@ -2984,10 +2998,11 @@ impl BrokerClientApplication {
29842998
loadable_key: &LoadableIdentityKey,
29852999
tpm: &mut BoxedDynTpm,
29863000
machine_key: &MachineKey,
3001+
pin: &PinValue,
29873002
) -> Result<Jws, MsalError> {
29883003
let nonce = self.request_nonce().await?;
29893004
let key = tpm
2990-
.identity_key_load(machine_key, loadable_key)
3005+
.identity_key_load(machine_key, Some(pin), loadable_key)
29913006
.map_err(|e| MsalError::TPMFail(format!("{:?}", e)))?;
29923007
let win_hello_pub_der = tpm.identity_key_public_as_der(&key).map_err(|e| {
29933008
MsalError::TPMFail(format!("Failed getting Windows Hello Key as der: {:?}", e))
@@ -3056,9 +3071,10 @@ impl BrokerClientApplication {
30563071
key: &LoadableIdentityKey,
30573072
tpm: &mut BoxedDynTpm,
30583073
machine_key: &MachineKey,
3074+
pin: &PinValue,
30593075
) -> Result<PrimaryRefreshToken, MsalError> {
30603076
let jwt = self
3061-
.build_jwt_by_hello_for_business_key(username, key, tpm, machine_key)
3077+
.build_jwt_by_hello_for_business_key(username, key, tpm, machine_key, pin)
30623078
.await?;
30633079
let signed_jwt = self.sign_jwt(&jwt, tpm, machine_key).await?;
30643080

@@ -3078,6 +3094,8 @@ impl BrokerClientApplication {
30783094
///
30793095
/// * `machine_key` - The TPM MachineKey associated with this application.
30803096
///
3097+
/// * `pin` - The PIN code required to unlock the key.
3098+
///
30813099
/// # Returns
30823100
/// * Success: An encrypted PrimaryRefreshToken, containing a refresh_token and tgt.
30833101
/// * Failure: An MsalError, indicating the failure.
@@ -3087,9 +3105,19 @@ impl BrokerClientApplication {
30873105
key: &LoadableIdentityKey,
30883106
tpm: &mut BoxedDynTpm,
30893107
machine_key: &MachineKey,
3108+
pin: &str,
30903109
) -> Result<SealedData, MsalError> {
3110+
let pin = PinValue::new(pin)
3111+
.map_err(|e| MsalError::TPMFail(format!("Failed setting pin value: {:?}", e)))?;
3112+
30913113
let prt = self
3092-
.acquire_user_prt_by_hello_for_business_key_internal(username, key, tpm, machine_key)
3114+
.acquire_user_prt_by_hello_for_business_key_internal(
3115+
username,
3116+
key,
3117+
tpm,
3118+
machine_key,
3119+
&pin,
3120+
)
30933121
.await?;
30943122
let transport_key = self.transport_key(tpm, machine_key)?;
30953123
self.seal_user_prt(&prt, tpm, &transport_key)

0 commit comments

Comments
 (0)