Skip to content

Commit 2cab0c7

Browse files
committed
Replace hard-coded attachment modality
1 parent ebda2e8 commit 2cab0c7

5 files changed

Lines changed: 69 additions & 17 deletions

File tree

webext/add-on/content.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ async function cloneCredentialResponse(credential) {
3535
const obj = {}
3636
obj.id = credential.id;
3737
obj.rawId = cloneInto(Uint8Array.fromBase64(credential.rawId, options), obj)
38-
// TODO: get authenticator attachment
39-
obj.authenticatorAttachment = undefined
38+
obj.authenticatorAttachment = credential.authenticatorAttachment;
4039
const response = {}
4140
// credential registration response
4241
if (credential.response.attestationObject) {

xyz-iinuwa-credential-manager-portal-gtk/src/credential_service/mod.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ use tokio::runtime::Runtime;
2222
use tracing::{debug, warn};
2323

2424
use crate::{
25-
dbus::{CredentialRequest, CredentialResponse, MakeCredentialResponseInternal},
25+
dbus::{
26+
CredentialRequest, CredentialResponse, GetAssertionResponseInternal,
27+
MakeCredentialResponseInternal,
28+
},
2629
view_model::{Device, InternalPinState, Transport},
2730
};
2831

@@ -203,7 +206,8 @@ impl CredentialService {
203206
CredentialResponse::CreatePublicKeyCredentialResponse(
204207
MakeCredentialResponseInternal::new(
205208
r,
206-
vec![String::from("usb"), String::from("usb")],
209+
vec![String::from("usb")],
210+
String::from("cross-platform"),
207211
),
208212
),
209213
);
@@ -216,7 +220,10 @@ impl CredentialService {
216220
let mut cred_response = self.cred_response.lock().unwrap();
217221
cred_response.replace(
218222
CredentialResponse::GetPublicKeyCredentialResponse(
219-
r.assertions[0].clone(),
223+
GetAssertionResponseInternal::new(
224+
r.assertions[0].clone(),
225+
String::from("cross-platform"),
226+
),
220227
),
221228
);
222229
Ok(UsbState::Completed)
@@ -257,6 +264,7 @@ impl CredentialService {
257264
MakeCredentialResponseInternal::new(
258265
r,
259266
vec![String::from("usb")],
267+
String::from("cross-platform"),
260268
),
261269
),
262270
);
@@ -269,7 +277,10 @@ impl CredentialService {
269277
let mut cred_response = self.cred_response.lock().unwrap();
270278
cred_response.replace(
271279
CredentialResponse::GetPublicKeyCredentialResponse(
272-
r.assertions[0].clone(),
280+
GetAssertionResponseInternal::new(
281+
r.assertions[0].clone(),
282+
String::from("cross-platform"),
283+
),
273284
),
274285
);
275286
Ok(UsbState::Completed)

xyz-iinuwa-credential-manager-portal-gtk/src/dbus.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,20 +291,41 @@ pub(crate) enum CredentialRequest {
291291
#[derive(Clone, Debug)]
292292
pub(crate) enum CredentialResponse {
293293
CreatePublicKeyCredentialResponse(MakeCredentialResponseInternal),
294-
GetPublicKeyCredentialResponse(Assertion),
294+
GetPublicKeyCredentialResponse(GetAssertionResponseInternal),
295295
}
296296

297297
#[derive(Clone, Debug)]
298298
pub(crate) struct MakeCredentialResponseInternal {
299299
ctap: MakeCredentialResponse,
300300
transport: Vec<String>,
301+
attachment_modality: String,
301302
}
302303

303304
impl MakeCredentialResponseInternal {
304-
pub(crate) fn new(response: MakeCredentialResponse, transport: Vec<String>) -> Self {
305+
pub(crate) fn new(
306+
response: MakeCredentialResponse,
307+
transport: Vec<String>,
308+
attachment_modality: String,
309+
) -> Self {
305310
Self {
306311
ctap: response,
307312
transport,
313+
attachment_modality,
314+
}
315+
}
316+
}
317+
318+
#[derive(Clone, Debug)]
319+
pub(crate) struct GetAssertionResponseInternal {
320+
ctap: Assertion,
321+
attachment_modality: String,
322+
}
323+
324+
impl GetAssertionResponseInternal {
325+
pub(crate) fn new(ctap: Assertion, attachment_modality: String) -> Self {
326+
Self {
327+
ctap,
328+
attachment_modality,
308329
}
309330
}
310331
}
@@ -516,6 +537,7 @@ impl CreatePublicKeyCredentialResponse {
516537
client_data_json,
517538
Some(response.transport.clone()),
518539
None,
540+
response.attachment_modality.clone(),
519541
)
520542
.to_json();
521543
let response = CreatePublicKeyCredentialResponse {
@@ -678,10 +700,10 @@ pub struct GetPublicKeyCredentialRequest {
678700

679701
impl GetPublicKeyCredentialResponse {
680702
fn try_from_ctap2_response(
681-
response: &Assertion,
703+
response: &GetAssertionResponseInternal,
682704
client_data_json: String,
683705
) -> std::result::Result<Self, fdo::Error> {
684-
let auth_data = &response.authenticator_data;
706+
let auth_data = &response.ctap.authenticator_data;
685707
let attested_credential_data = match &auth_data.attested_credential {
686708
None => None,
687709
Some(att) => {
@@ -719,12 +741,14 @@ impl GetPublicKeyCredentialResponse {
719741
let authentication_response_json = webauthn::GetPublicKeyCredentialResponse::new(
720742
client_data_json,
721743
response
744+
.ctap
722745
.credential_id
723746
.as_ref()
724747
.map(|c| c.id.clone().into_vec()),
725748
authenticator_data_blob,
726-
response.signature.clone(),
727-
response.user.as_ref().map(|u| u.id.clone().into_vec()),
749+
response.ctap.signature.clone(),
750+
response.ctap.user.as_ref().map(|u| u.id.clone().into_vec()),
751+
response.attachment_modality.clone(),
728752
)
729753
.to_json();
730754
let response = GetPublicKeyCredentialResponse {

xyz-iinuwa-credential-manager-portal-gtk/src/platform_authenticator/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ pub(crate) fn make_credential(
378378
client_data_json,
379379
None,
380380
None,
381+
String::from("platform"),
381382
);
382383
Ok((response, credential_source))
383384
}
@@ -548,6 +549,7 @@ fn get_credential(
548549
// selectedCredential.userHandle
549550
// Note: In cases where allowCredentialDescriptorList was supplied the returned userHandle value may be null, see: userHandleResult.
550551
user_handle: selected_credential.user_handle.clone(),
552+
attachment_modality: String::from("platform"),
551553
};
552554
Ok(response)
553555
// If the authenticator cannot find any credential corresponding to the specified Relying Party that matches the specified criteria, it terminates the operation and returns an error.

xyz-iinuwa-credential-manager-portal-gtk/src/webauthn.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@ pub struct CreatePublicKeyCredentialResponse {
438438

439439
/// JSON string of extension output
440440
extensions: Option<String>,
441+
442+
/// If the device used is builtin ("platform") or removable ("cross-platform", aka "roaming")
443+
attachment_modality: String,
441444
}
442445

443446
/// Returned from a creation of a new public key credential.
@@ -473,6 +476,7 @@ impl CreatePublicKeyCredentialResponse {
473476
client_data_json: String,
474477
transports: Option<Vec<String>>,
475478
extension_output_json: Option<String>,
479+
attachment_modality: String,
476480
) -> Self {
477481
Self {
478482
cred_type: "public-key".to_string(),
@@ -484,6 +488,7 @@ impl CreatePublicKeyCredentialResponse {
484488
authenticator_data,
485489
},
486490
extensions: extension_output_json,
491+
attachment_modality,
487492
}
488493
}
489494

@@ -500,7 +505,8 @@ impl CreatePublicKeyCredentialResponse {
500505
let mut output = json!({
501506
"id": self.get_id(),
502507
"rawId": self.get_id(),
503-
"response": response
508+
"response": response,
509+
"authenticatorAttachment": self.attachment_modality,
504510
});
505511
if let Some(extensions) = &self.extensions {
506512
let extension_value =
@@ -534,17 +540,29 @@ pub struct GetPublicKeyCredentialResponse {
534540
/// created. This item is nullable, however user handle MUST always be
535541
/// populated for discoverable credentials.
536542
pub(crate) user_handle: Option<Vec<u8>>,
543+
544+
/// Whether the used device is "cross-platform" (aka "roaming", i.e.: can be
545+
/// removed from the platform) or is built-in ("platform").
546+
pub(crate) attachment_modality: String,
537547
}
538548

539549
impl GetPublicKeyCredentialResponse {
540-
pub(crate) fn new(client_data_json: String, id: Option<Vec<u8>>, authenticator_data: Vec<u8>, signature: Vec<u8>, user_handle: Option<Vec<u8>>) -> Self {
550+
pub(crate) fn new(
551+
client_data_json: String,
552+
id: Option<Vec<u8>>,
553+
authenticator_data: Vec<u8>,
554+
signature: Vec<u8>,
555+
user_handle: Option<Vec<u8>>,
556+
attachment_modality: String,
557+
) -> Self {
541558
Self {
542559
cred_type: "public-key".to_string(),
543560
client_data_json,
544561
raw_id: id,
545562
authenticator_data,
546563
signature,
547564
user_handle,
565+
attachment_modality,
548566
}
549567
}
550568
pub fn to_json(&self) -> String {
@@ -560,12 +578,10 @@ impl GetPublicKeyCredentialResponse {
560578
// This means we'll have to remember the ID on the request if the allow-list has exactly one
561579
// credential descriptor, then we'll need. This should probably be done in libwebauthn.
562580
let id = self.raw_id.as_ref().map(|id| URL_SAFE_NO_PAD.encode(id));
563-
// TODO: Fix for platorm authenticator
564-
let attachment = "cross-platform";
565581
let output = json!({
566582
"id": id,
567583
"rawId": id,
568-
"authenticatorAttachment": attachment,
584+
"authenticatorAttachment": self.attachment_modality,
569585
"response": response
570586
});
571587
// TODO: support client extensions

0 commit comments

Comments
 (0)