Switch to libfido2 bindings

This commit is contained in:
pjht 2023-08-28 09:13:54 -05:00
parent 7f822885d8
commit f1dacd4bea
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
6 changed files with 142 additions and 281 deletions

327
Cargo.lock generated
View File

@ -2,17 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aes"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.72" version = "1.0.72"
@ -70,12 +59,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]]
name = "base64"
version = "0.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
[[package]] [[package]]
name = "base64ct" name = "base64ct"
version = "1.6.0" version = "1.6.0"
@ -91,15 +74,6 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "block-padding"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.13.0" version = "3.13.0"
@ -112,15 +86,6 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cbc"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
dependencies = [
"cipher",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.82" version = "1.0.82"
@ -136,33 +101,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "ciborium"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656"
[[package]]
name = "ciborium-ll"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b"
dependencies = [
"ciborium-io",
"half",
]
[[package]] [[package]]
name = "cipher" name = "cipher"
version = "0.4.4" version = "0.4.4"
@ -210,29 +148,6 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "ctap-hid-fido2"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3726fa3f7f978ce0a222ea73c13490115f95e7a31db3061d7c4c91bea58ea01a"
dependencies = [
"aes",
"anyhow",
"base64",
"byteorder",
"cbc",
"hex",
"hidapi",
"num",
"pad",
"ring",
"serde",
"serde_cbor",
"strum",
"strum_macros",
"x509-parser",
]
[[package]] [[package]]
name = "data-encoding" name = "data-encoding"
version = "2.4.0" version = "2.4.0"
@ -325,6 +240,12 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "ff" name = "ff"
version = "0.13.0" version = "0.13.0"
@ -369,34 +290,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "half" name = "hashbrown"
version = "1.8.2" version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hidapi"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "798154e4b6570af74899d71155fb0072d5b17e6aa12f39c8ef22c60fb8ec99e7"
dependencies = [
"cc",
"libc",
"pkg-config",
"winapi",
]
[[package]] [[package]]
name = "hmac" name = "hmac"
@ -407,13 +304,22 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]] [[package]]
name = "inout" name = "inout"
version = "0.1.3" version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [ dependencies = [
"block-padding",
"generic-array", "generic-array",
] ]
@ -447,6 +353,26 @@ version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "libfido2"
version = "0.1.0"
dependencies = [
"libfido2-sys",
"num_enum",
"paste",
"thiserror",
]
[[package]]
name = "libfido2-sys"
version = "0.2.0"
dependencies = [
"anyhow",
"cfg-if",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "libm" name = "libm"
version = "0.2.7" version = "0.2.7"
@ -481,20 +407,6 @@ dependencies = [
"minimal-lexical", "minimal-lexical",
] ]
[[package]]
name = "num"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-traits",
]
[[package]] [[package]]
name = "num-bigint" name = "num-bigint"
version = "0.4.3" version = "0.4.3"
@ -524,12 +436,14 @@ dependencies = [
] ]
[[package]] [[package]]
name = "num-complex" name = "num-derive"
version = "0.4.3" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e"
dependencies = [ dependencies = [
"num-traits", "proc-macro2",
"quote",
"syn 2.0.28",
] ]
[[package]] [[package]]
@ -553,18 +467,6 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.16" version = "0.2.16"
@ -575,6 +477,27 @@ dependencies = [
"libm", "libm",
] ]
[[package]]
name = "num_enum"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb"
dependencies = [
"num_enum_derive",
]
[[package]]
name = "num_enum_derive"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.28",
]
[[package]] [[package]]
name = "oid-registry" name = "oid-registry"
version = "0.6.1" version = "0.6.1"
@ -615,13 +538,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "pad" name = "paste"
version = "0.1.6" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
dependencies = [
"unicode-width",
]
[[package]] [[package]]
name = "pem-rfc7468" name = "pem-rfc7468"
@ -674,6 +594,16 @@ dependencies = [
"elliptic-curve", "elliptic-curve",
] ]
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
dependencies = [
"once_cell",
"toml_edit",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.66" version = "1.0.66"
@ -778,12 +708,6 @@ dependencies = [
"nom", "nom",
] ]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]] [[package]]
name = "sec1" name = "sec1"
version = "0.7.3" version = "0.7.3"
@ -803,30 +727,6 @@ name = "serde"
version = "1.0.183" version = "1.0.183"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_cbor"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [
"half",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
]
[[package]] [[package]]
name = "sha2" name = "sha2"
@ -916,33 +816,14 @@ name = "ssh_attest_verifier"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"ciborium", "libfido2",
"ctap-hid-fido2", "num-derive",
"ssh-encoding", "ssh-encoding",
"ssh-key", "ssh-key",
"thiserror", "thiserror",
"x509-parser", "x509-parser",
] ]
[[package]]
name = "strum"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
[[package]]
name = "strum_macros"
version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 1.0.109",
]
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.5.0" version = "2.5.0"
@ -985,18 +866,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.44" version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.44" version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1031,6 +912,23 @@ dependencies = [
"time-core", "time-core",
] ]
[[package]]
name = "toml_datetime"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
[[package]]
name = "toml_edit"
version = "0.19.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.16.0" version = "1.16.0"
@ -1043,12 +941,6 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.4" version = "0.2.4"
@ -1061,6 +953,12 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
@ -1159,6 +1057,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "winnow"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "x509-parser" name = "x509-parser"
version = "0.15.1" version = "0.15.1"

View File

@ -7,8 +7,8 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.72" anyhow = "1.0.72"
ciborium = "0.2.1" libfido2 = { version = "0.1.0", path = "../libfido2" }
ctap-hid-fido2 = "3.5.0" num-derive = "0.4.0"
ssh-encoding = "0.2.0" ssh-encoding = "0.2.0"
ssh-key = { version = "0.6.0" } ssh-key = { version = "0.6.0" }
thiserror = "1.0.44" thiserror = "1.0.44"

View File

@ -1,4 +1,3 @@
use ssh_key::Algorithm;
use thiserror::Error; use thiserror::Error;
use x509_parser::prelude::X509Error; use x509_parser::prelude::X509Error;
@ -20,8 +19,6 @@ pub enum Error {
InvalidRootCa(String), InvalidRootCa(String),
#[error("FIDO public key type unsupported")] #[error("FIDO public key type unsupported")]
UnsupportedFidoKeyType, UnsupportedFidoKeyType,
#[error("SSH public key type {} does not match FIDO public key type {}", .ssh.as_str(), .fido.as_str())]
SshFidoTypeMismatch { ssh: Algorithm, fido: Algorithm },
#[error("SSH public key des not match FIDO public key")] #[error("SSH public key des not match FIDO public key")]
SshFidoKeyMismatch, SshFidoKeyMismatch,
} }

View File

@ -1,14 +1,11 @@
mod error; mod error;
mod ssh_attest; mod ssh_attest;
use ctap_hid_fido2::{
public_key::PublicKeyType,
verifier,
};
pub use error::Error; pub use error::Error;
use libfido2::{cred::{Credential, CredType}, fido_init};
use ssh_attest::SshAttestationInfo; use ssh_attest::SshAttestationInfo;
use ssh_encoding::Decode; use ssh_encoding::Decode;
use ssh_key::{public::KeyData, Algorithm, PublicKey}; use ssh_key::{public::KeyData, PublicKey, Algorithm};
pub use x509_parser; pub use x509_parser;
use x509_parser::{prelude::*, x509::X509Name}; use x509_parser::{prelude::*, x509::X509Name};
@ -25,13 +22,26 @@ pub fn verify_attestation(
challenge: Vec<u8>, challenge: Vec<u8>,
ssh_pubkey: PublicKey, ssh_pubkey: PublicKey,
) -> Result<(), Error> { ) -> Result<(), Error> {
fido_init(true);
// Decode the SSH attestation file // Decode the SSH attestation file
let attestation = SshAttestationInfo::decode(&mut ssh_attest.as_slice()) let attestation = SshAttestationInfo::decode(&mut ssh_attest.as_slice())
.map_err(|e| Error::AttestationDecodeError(e))?; .map_err(|e| Error::AttestationDecodeError(e))?;
let attestation_cert = attestation let attestation_cert = attestation
.decode_cert() .decode_cert()
.map_err(|e| Error::AttestationCertDecodeError(e))?; .map_err(|e| Error::AttestationCertDecodeError(e))?;
let attestation = attestation.to_fido_attestation().map_err(|_e| Error::AttestationInvalidAuthData)?;
// Reconstruct the credential from the attestation
let mut credential = Credential::new().unwrap();
match ssh_pubkey.algorithm() {
Algorithm::SkEcdsaSha2NistP256 => credential.set_type(CredType::Ecdsa256).unwrap(),
Algorithm::SkEd25519 => credential.set_type(CredType::Ed25519).unwrap(),
_ => return Err(Error::NonFidoSshKey.into()),
};
credential.set_authdata_raw(attestation.auth_data.as_ref().unwrap().as_slice()).unwrap();
credential.set_sig(attestation.enroll_sig.as_slice()).unwrap();
credential.set_clientdata(challenge.as_slice()).unwrap();
credential.set_x509(attestation.attestation_cert.as_slice()).unwrap();
credential.set_fmt("packed").unwrap();
// Extract the RPID from the SSH public key // Extract the RPID from the SSH public key
let application = match ssh_pubkey.key_data() { let application = match ssh_pubkey.key_data() {
@ -40,9 +50,10 @@ pub fn verify_attestation(
_ => return Err(Error::NonFidoSshKey.into()), _ => return Err(Error::NonFidoSshKey.into()),
}; };
credential.set_rp(application, "").unwrap();
// Verify the attestation RPID & signature // Verify the attestation RPID & signature
let verify_result = verifier::verify_attestation(&application, &challenge, &attestation); if credential.verify().is_err() {
if !verify_result.is_success {
return Err(Error::AttestationVerificationFailed); return Err(Error::AttestationVerificationFailed);
} }
@ -61,21 +72,6 @@ pub fn verify_attestation(
return Err(Error::InvalidAttestationCertSignature.into()); return Err(Error::InvalidAttestationCertSignature.into());
} }
let fido_pubkey = &verify_result.credential_public_key;
// Verify the FIDO public key is the same type as the SSH public key
let fido_pubkey_alg = match fido_pubkey.key_type {
PublicKeyType::Ecdsa256 => Algorithm::SkEcdsaSha2NistP256,
PublicKeyType::Ed25519 => Algorithm::SkEd25519,
PublicKeyType::Unknown => return Err(Error::UnsupportedFidoKeyType),
};
if fido_pubkey_alg != ssh_pubkey.algorithm() {
return Err(Error::SshFidoTypeMismatch {
ssh: ssh_pubkey.algorithm(),
fido: fido_pubkey_alg,
});
}
// Verify that the SSH public key data matches the FIDO public key data // Verify that the SSH public key data matches the FIDO public key data
let key_data = match ssh_pubkey.key_data() { let key_data = match ssh_pubkey.key_data() {
@ -83,7 +79,7 @@ pub fn verify_attestation(
KeyData::SkEd25519(key) => key.public_key().0.as_slice(), KeyData::SkEd25519(key) => key.public_key().0.as_slice(),
_ => unreachable!(), _ => unreachable!(),
}; };
if key_data != fido_pubkey.der { if key_data != credential.pubkey() {
return Err(Error::SshFidoKeyMismatch.into()); return Err(Error::SshFidoKeyMismatch.into());
} }
Ok(()) Ok(())

View File

@ -27,9 +27,9 @@ fn main() -> anyhow::Result<()> {
}) })
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
let ssh_attest = std::fs::read("id_ecdsa_rustgen_sk_attest.bin")?; let ssh_attest = std::fs::read("id_ed25519-sk_attest.bin")?;
let challenge = std::fs::read("id_ecdsa_rustgen_sk_attest_chall.bin")?; let challenge = std::fs::read("id_ed25519-sk_attest_chall.bin")?;
let ssh_pubkey = ssh_key::PublicKey::read_openssh_file(Path::new("id_ecdsa_rustgen_sk.pub"))?; let ssh_pubkey = ssh_key::PublicKey::read_openssh_file(Path::new("id_ed25519-sk.pub"))?;
verify_attestation(root_cas, ssh_attest, challenge, ssh_pubkey)?; verify_attestation(root_cas, ssh_attest, challenge, ssh_pubkey)?;
println!("Attestation verified successfully"); println!("Attestation verified successfully");

View File

@ -1,7 +1,5 @@
use std::str::FromStr; use std::str::FromStr;
use ciborium::Value;
use ctap_hid_fido2::fidokey::make_credential::{Attestation, make_credential_response};
use ssh_encoding::{Decode, Label, LabelError}; use ssh_encoding::{Decode, Label, LabelError};
use x509_parser::{nom::Finish, prelude::*}; use x509_parser::{nom::Finish, prelude::*};
@ -49,43 +47,6 @@ impl SshAttestationInfo {
.finish() .finish()
.map(|(_, cert)| cert) .map(|(_, cert)| cert)
} }
pub fn to_fido_attestation(&self) -> Result<Attestation, anyhow::Error> {
let mut attestation_map_bytes = Vec::new();
ciborium::into_writer(
&Value::from(
[
(0x01.into(), "packed".into()),
(
0x02.into(),
self.auth_data.as_deref().unwrap().into(),
),
(
0x03.into(),
[
// TODO: Don't hardcode algorithm
// -7: ECDSA P256
("alg".into(), (-7).into()),
("sig".into(), self.enroll_sig.as_slice().into()),
(
"x5c".into(),
[Value::from(self.attestation_cert.as_slice())]
.as_slice()
.into(),
),
]
.as_slice()
.into(),
),
]
.as_slice(),
),
&mut attestation_map_bytes,
)
.expect("Failed to serialize CBOR attestation info");
make_credential_response::parse_cbor(&attestation_map_bytes)
}
} }
impl Decode for SshAttestationInfo { impl Decode for SshAttestationInfo {