mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-08-26 12:43:20 +00:00
use CredentialsV3 from webauthn-rs instead of own webauthn_0_3 module
This commit is contained in:
parent
c90df9e040
commit
a5b5d5be2f
3 changed files with 23 additions and 125 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -5181,6 +5181,7 @@ dependencies = [
|
|||
"url",
|
||||
"uuid",
|
||||
"webauthn-rs",
|
||||
"webauthn-rs-core",
|
||||
"webauthn-rs-proto",
|
||||
"which",
|
||||
"yubico_ng",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue