Browse Source

use CredentialsV3 from webauthn-rs instead of own webauthn_0_3 module

pull/5934/head
zUnixorn 1 week ago
parent
commit
a5b5d5be2f
No known key found for this signature in database GPG Key ID: BE3A9CAE3E8D0DA
  1. 1
      Cargo.lock
  2. 1
      Cargo.toml
  3. 146
      src/db/models/two_factor.rs

1
Cargo.lock

@ -5181,6 +5181,7 @@ dependencies = [
"url",
"uuid",
"webauthn-rs",
"webauthn-rs-core",
"webauthn-rs-proto",
"which",
"yubico_ng",

1
Cargo.toml

@ -125,6 +125,7 @@ yubico = { package = "yubico_ng", version = "0.13.0", features = ["online-tokio"
# danger-user-presence-only-security-keys is needed to disable UV
webauthn-rs = { version = "0.5.2", features = ["danger-allow-state-serialisation", "danger-credential-internals", "danger-user-presence-only-security-keys"] }
webauthn-rs-proto = "0.5.2"
webauthn-rs-core = "0.5.2"
# Handling of URL's for WebAuthn and favicons
url = "2.5.4"

146
src/db/models/two_factor.rs

@ -3,6 +3,7 @@ use crate::api::core::two_factor::webauthn::WebauthnRegistration;
use crate::{api::EmptyResult, db::DbConn, error::MapResult};
use serde_json::Value;
use webauthn_rs::prelude::{Credential, ParsedAttestation};
use webauthn_rs_core::proto::CredentialV3;
use webauthn_rs_proto::{AttestationFormat, RegisteredExtensions};
db_object! {
@ -42,130 +43,6 @@ pub enum TwoFactorType {
ProtectedActions = 2000,
}
mod webauthn_0_3 {
use webauthn_rs::prelude::ParsedAttestation;
use webauthn_rs_proto::{AttestationFormat, RegisteredExtensions};
#[derive(Deserialize)]
pub struct WebauthnRegistration {
pub id: i32,
pub name: String,
pub migrated: bool,
pub credential: Credential,
}
impl From<WebauthnRegistration> for crate::api::core::two_factor::webauthn::WebauthnRegistration {
fn from(value: WebauthnRegistration) -> Self {
Self {
id: value.id,
name: value.name,
migrated: value.migrated,
credential: webauthn_rs::prelude::Credential::from(value.credential).into(),
}
}
}
// Copied from https://docs.rs/webauthn-rs/0.3.2/src/webauthn_rs/proto.rs.html#316-339
#[derive(Deserialize)]
pub struct Credential {
pub cred_id: Vec<u8>,
pub cred: COSEKey,
pub counter: u32,
pub verified: bool,
pub registration_policy: webauthn_rs_proto::UserVerificationPolicy,
}
impl From<Credential> for webauthn_rs::prelude::Credential {
fn from(value: Credential) -> Self {
Self {
cred_id: value.cred_id.into(),
cred: value.cred.into(),
counter: value.counter,
transports: None,
user_verified: value.verified,
backup_eligible: false,
backup_state: false,
registration_policy: value.registration_policy,
extensions: RegisteredExtensions::none(),
attestation: ParsedAttestation::default(),
attestation_format: AttestationFormat::None,
}
}
}
// Copied from https://docs.rs/webauthn-rs/0.3.2/src/webauthn_rs/proto.rs.html#300-305
#[derive(Deserialize)]
pub struct COSEKey {
pub type_: webauthn_rs::prelude::COSEAlgorithm,
pub key: COSEKeyType,
}
impl From<COSEKey> for webauthn_rs::prelude::COSEKey {
fn from(value: COSEKey) -> Self {
Self {
type_: value.type_,
key: value.key.into(),
}
}
}
// Copied from https://docs.rs/webauthn-rs/0.3.2/src/webauthn_rs/proto.rs.html#260-278
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
#[derive(Deserialize)]
pub enum COSEKeyType {
EC_OKP,
EC_EC2(COSEEC2Key),
RSA(COSERSAKey),
}
impl From<COSEKeyType> for webauthn_rs::prelude::COSEKeyType {
fn from(value: COSEKeyType) -> Self {
match value {
COSEKeyType::EC_EC2(a) => Self::EC_EC2(a.into()),
COSEKeyType::RSA(a) => Self::RSA(a.into()),
// This should've never been able to be constructed when webauthn 0.3 was used
// Refer: https://docs.rs/webauthn-rs/0.3.2/src/webauthn_rs/crypto.rs.html#414
COSEKeyType::EC_OKP => unreachable!(),
}
}
}
// Copied from https://docs.rs/webauthn-rs/0.3.2/src/webauthn_rs/proto.rs.html#249-254
#[derive(Deserialize)]
pub struct COSERSAKey {
pub n: Vec<u8>,
pub e: [u8; 3],
}
impl From<COSERSAKey> for webauthn_rs::prelude::COSERSAKey {
fn from(value: COSERSAKey) -> Self {
Self {
n: value.n.into(),
e: value.e,
}
}
}
// Copied from https://docs.rs/webauthn-rs/0.3.2/src/webauthn_rs/proto.rs.html#235-242
#[derive(Deserialize)]
pub struct COSEEC2Key {
pub curve: webauthn_rs::prelude::ECDSACurve,
pub x: [u8; 32],
pub y: [u8; 32],
}
impl From<COSEEC2Key> for webauthn_rs::prelude::COSEEC2Key {
fn from(value: COSEEC2Key) -> Self {
Self {
curve: value.curve,
x: value.x.into(),
y: value.y.into(),
}
}
}
}
/// Local methods
impl TwoFactor {
pub fn new(user_uuid: UserId, atype: TwoFactorType, data: String) -> Self {
@ -365,7 +242,7 @@ impl TwoFactor {
for webauthn_factor in webauthn_factors {
// assume that a failure to parse into the old struct, means that it was already converted
// alternatively this could also be checked via an extra field in the db
let Ok(regs) = serde_json::from_str::<Vec<webauthn_0_3::WebauthnRegistration>>(&webauthn_factor.data)
let Ok(regs) = serde_json::from_str::<Vec<WebauthnRegistrationV3>>(&webauthn_factor.data)
else {
continue;
};
@ -383,3 +260,22 @@ impl TwoFactor {
#[derive(Clone, Debug, DieselNewType, FromForm, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct TwoFactorId(String);
#[derive(Deserialize)]
pub struct WebauthnRegistrationV3 {
pub id: i32,
pub name: String,
pub migrated: bool,
pub credential: CredentialV3,
}
impl From<WebauthnRegistrationV3> for WebauthnRegistration {
fn from(value: WebauthnRegistrationV3) -> Self {
Self {
id: value.id,
name: value.name,
migrated: value.migrated,
credential: Credential::from(value.credential).into(),
}
}
}

Loading…
Cancel
Save