Skip to content

Commit

Permalink
WIP: remove credBlob support
Browse files Browse the repository at this point in the history
  • Loading branch information
micolous committed Oct 7, 2022
1 parent a8d3e74 commit aa3b9d0
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 77 deletions.
3 changes: 1 addition & 2 deletions webauthn-authenticator-rs/examples/authenticate/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::io::{stdin, stdout, Write};
use webauthn_authenticator_rs::prelude::Url;
use webauthn_authenticator_rs::softtoken::SoftToken;
use webauthn_authenticator_rs::AuthenticatorBackend;
use webauthn_rs_core::proto::{CredBlobGet, RequestAuthenticationExtensions};
use webauthn_rs_core::proto::RequestAuthenticationExtensions;
use webauthn_rs_core::WebauthnCore as Webauthn;

fn select_provider() -> Box<dyn AuthenticatorBackend> {
Expand Down Expand Up @@ -98,7 +98,6 @@ fn main() {
vec![cred],
Some(RequestAuthenticationExtensions {
appid: Some("example.app.id".to_string()),
get_cred_blob: Some(CredBlobGet(true)),
uvm: None,
}),
)
Expand Down
86 changes: 17 additions & 69 deletions webauthn-authenticator-rs/src/win10/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use crate::prelude::WebauthnCError;
use std::ffi::c_void;
use std::pin::Pin;
use webauthn_rs_proto::{
AuthenticationExtensionsClientOutputs, CredBlobSet, CredProtect,
RegistrationExtensionsClientOutputs, RequestAuthenticationExtensions,
AuthenticationExtensionsClientOutputs, CredProtect, RegistrationExtensionsClientOutputs,
RequestRegistrationExtensions,
};

Expand All @@ -15,28 +14,19 @@ use windows::{
Win32::{Foundation::BOOL, Networking::WindowsWebServices::*},
};

#[derive(Debug)]
pub struct WinCredBlobSet {
native: WEBAUTHN_CRED_BLOB_EXTENSION,
blob: CredBlobSet,
}

/// Represents a single extension for MakeCredential requests, analogous to a
/// single [RequestRegistrationExtensions] field.
#[derive(Debug)]
pub(crate) enum WinExtensionMakeCredentialRequest {
HmacSecret(BOOL),
CredProtect(WEBAUTHN_CRED_PROTECT_EXTENSION_IN),
CredBlob(Pin<Box<WinCredBlobSet>>),
MinPinLength(BOOL),
}

/// Represents a single extension for GetAssertion requests, analogous to a
/// single [RequestAuthenticationExtensions] field.
#[derive(Debug)]
pub(crate) enum WinExtensionGetAssertionRequest {
CredBlob(BOOL),
}
pub(crate) enum WinExtensionGetAssertionRequest {}

/// Generic request extension trait, for abstracting between
/// [WinExtensionMakeCredentialRequest] and [WinExtensionGetAssertionRequest].
Expand All @@ -60,7 +50,6 @@ impl WinExtensionRequestType for WinExtensionMakeCredentialRequest {
fn identifier(&self) -> &str {
match self {
Self::HmacSecret(_) => WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET,
Self::CredBlob(_) => WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB,
Self::CredProtect(_) => WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT,
Self::MinPinLength(_) => WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH,
}
Expand All @@ -70,7 +59,6 @@ impl WinExtensionRequestType for WinExtensionMakeCredentialRequest {
(match self {
Self::HmacSecret(_) => std::mem::size_of::<BOOL>(),
Self::CredProtect(_) => std::mem::size_of::<WEBAUTHN_CRED_PROTECT_EXTENSION_IN>(),
Self::CredBlob(_) => std::mem::size_of::<WEBAUTHN_CRED_BLOB_EXTENSION>(),
Self::MinPinLength(_) => std::mem::size_of::<BOOL>(),
}) as u32
}
Expand All @@ -79,7 +67,6 @@ impl WinExtensionRequestType for WinExtensionMakeCredentialRequest {
match self {
Self::HmacSecret(v) => v as *mut _ as *mut c_void,
Self::CredProtect(v) => v as *mut _ as *mut c_void,
Self::CredBlob(v) => (&mut v.native) as *mut _ as *mut c_void,
Self::MinPinLength(v) => v as *mut _ as *mut c_void,
}
}
Expand All @@ -94,9 +81,6 @@ impl WinExtensionRequestType for WinExtensionMakeCredentialRequest {
if let Some(h) = &e.hmac_create_secret {
o.push(Self::HmacSecret(h.into()))
}
if let Some(x) = &e.cred_blob {
o.push(Self::CredBlob(WinCredBlobSet::new(x)));
}
if let Some(x) = &e.min_pin_length {
o.push(Self::MinPinLength(x.into()));
}
Expand All @@ -105,36 +89,29 @@ impl WinExtensionRequestType for WinExtensionMakeCredentialRequest {
}
}

/*
impl WinExtensionRequestType for WinExtensionGetAssertionRequest {
fn identifier(&self) -> &str {
match self {
Self::CredBlob(_) => WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB,
}
todo!();
}
fn len(&self) -> u32 {
(match self {
Self::CredBlob(_) => std::mem::size_of::<BOOL>(),
}) as u32
todo!();
}
fn ptr(&mut self) -> *mut c_void {
match self {
Self::CredBlob(v) => v as *mut _ as *mut c_void,
}
todo!();
}
type WrappedType = RequestAuthenticationExtensions;
fn to_native(e: &Self::WrappedType) -> Vec<Self> {
let mut o: Vec<Self> = Vec::new();
if let Some(c) = &e.get_cred_blob {
o.push(Self::CredBlob(c.0.into()));
}
fn to_native(_e: &Self::WrappedType) -> Vec<Self> {
let o: Vec<Self> = Vec::new();
o
}
}
*/

impl From<&CredProtect> for WinExtensionMakeCredentialRequest {
/// Converts [CredProtect] into [WEBAUTHN_CRED_PROTECT_EXTENSION_IN].
Expand All @@ -149,28 +126,6 @@ impl From<&CredProtect> for WinExtensionMakeCredentialRequest {
}
}

impl WinCredBlobSet {
fn new(b: &CredBlobSet) -> Pin<Box<Self>> {
let res = Self {
native: Default::default(),
blob: b.clone(),
};
let mut boxed = Box::pin(res);

let native = WEBAUTHN_CRED_BLOB_EXTENSION {
cbCredBlob: boxed.blob.0 .0.len() as u32,
pbCredBlob: boxed.blob.0 .0.as_mut_ptr() as *mut _,
};

unsafe {
let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed);
Pin::get_unchecked_mut(mut_ref).native = native;
}

boxed
}
}

/// Reads a [WEBAUTHN_EXTENSION] containing a Windows-specific primitive type,
/// converting it into a Rust datatype.
fn read_extension<'a, T: 'a, U: From<&'a T>>(
Expand All @@ -197,7 +152,7 @@ fn read_extension2<'a, T: 'a + Clone>(e: &'a WEBAUTHN_EXTENSION) -> Result<T, We
enum WinExtensionMakeCredentialResponse {
HmacSecret(bool),
CredProtect(u32),
CredBlob(bool),
CredBlob,
MinPinLength(u32),
}

Expand All @@ -219,9 +174,8 @@ impl TryFrom<&WEBAUTHN_EXTENSION> for WinExtensionMakeCredentialResponse {
WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT => {
read_extension2(e).map(WinExtensionMakeCredentialResponse::CredProtect)
}
WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB => {
read_extension::<'_, BOOL, _>(e).map(WinExtensionMakeCredentialResponse::CredBlob)
}
// Value intentonally ignored
WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB => Ok(Self::CredBlob),
WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH => {
read_extension2(e).map(WinExtensionMakeCredentialResponse::MinPinLength)
}
Expand All @@ -248,9 +202,7 @@ pub fn native_to_registration_extensions(
WinExtensionMakeCredentialResponse::CredProtect(v) => {
o.cred_protect = (v as u8).try_into().ok();
}
WinExtensionMakeCredentialResponse::CredBlob(v) => {
o.cred_blob = Some(v);
}
WinExtensionMakeCredentialResponse::CredBlob => (),
WinExtensionMakeCredentialResponse::MinPinLength(v) => {
o.min_pin_length = Some(v);
}
Expand All @@ -263,7 +215,7 @@ pub fn native_to_registration_extensions(
/// Represents a single extension for GetAssertion responses, analogous to a
/// single [AuthenticationExtensionsClientOutputs] field.
enum WinExtensionGetAssertionResponse {
CredBlob(Vec<u8>),
CredBlob,
}

impl TryFrom<&WEBAUTHN_EXTENSION> for WinExtensionGetAssertionResponse {
Expand All @@ -278,9 +230,7 @@ impl TryFrom<&WEBAUTHN_EXTENSION> for WinExtensionGetAssertionResponse {
};

match id.as_str() {
WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB => {
read_extension2(e).map(WinExtensionGetAssertionResponse::CredBlob)
}
WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB => Ok(Self::CredBlob),
o => {
error!("unknown extension: {:?}", o);
Err(WebauthnCError::Internal)
Expand All @@ -294,15 +244,13 @@ impl TryFrom<&WEBAUTHN_EXTENSION> for WinExtensionGetAssertionResponse {
pub fn native_to_assertion_extensions(
native: &WEBAUTHN_EXTENSIONS,
) -> Result<AuthenticationExtensionsClientOutputs, WebauthnCError> {
let mut o = AuthenticationExtensionsClientOutputs::default();
let /* mut */ o = AuthenticationExtensionsClientOutputs::default();

for i in 0..(native.cExtensions as usize) {
let extn = unsafe { &*native.pExtensions.add(i) };
let win = WinExtensionGetAssertionResponse::try_from(extn)?;
match win {
WinExtensionGetAssertionResponse::CredBlob(b) => {
o.cred_blob = Some(b.into());
}
WinExtensionGetAssertionResponse::CredBlob => (),
}
}

Expand Down
13 changes: 7 additions & 6 deletions webauthn-authenticator-rs/src/win10/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::win10::{
credential::{native_to_transports, WinCredentialList},
extensions::{
native_to_assertion_extensions, native_to_registration_extensions,
WinExtensionGetAssertionRequest, WinExtensionMakeCredentialRequest, WinExtensionsRequest,
WinExtensionMakeCredentialRequest, WinExtensionsRequest,
},
gui::Window,
native::{WinPtr, WinWrapper},
Expand Down Expand Up @@ -241,10 +241,10 @@ impl AuthenticatorBackend for Win10 {
// [chr]: https://chromium.googlesource.com/chromium/src/+/f62b8f341c14be84c6c995133f485d76a58de090/device/fido/win/webauthn_api.cc#520
// [ffx]: https://github.com/mozilla/gecko-dev/blob/620490a051a1fc72563e1c6bbecfe7346122a6bc/dom/webauthn/WinWebAuthnManager.cpp#L714-L716
let mut app_id_used: BOOL = false.into();
let extensions = match &options.extensions {
Some(e) => WinExtensionsRequest::new(e)?,
None => Box::pin(WinExtensionsRequest::<WinExtensionGetAssertionRequest>::default()),
};
// let extensions = match &options.extensions {
// Some(e) => WinExtensionsRequest::new(e)?,
// None => Box::pin(WinExtensionsRequest::<WinExtensionGetAssertionRequest>::default()),
// };

let getassertopts = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS {
dwVersion: WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION,
Expand All @@ -254,7 +254,8 @@ impl AuthenticatorBackend for Win10 {
cCredentials: 0,
pCredentials: [].as_mut_ptr(),
},
Extensions: *extensions.native_ptr(),
// Extensions: *extensions.native_ptr(),
Extensions: Default::default(),
dwAuthenticatorAttachment: 0, // Not supported?
dwUserVerificationRequirement: user_verification_to_native(Some(
&options.user_verification,
Expand Down

0 comments on commit aa3b9d0

Please sign in to comment.