From ded3830ec67fdacafaf30f70a04265cbdcb63c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= Date: Wed, 2 Oct 2024 11:42:20 +0200 Subject: [PATCH] Pretty printing of certificate exts (#6) This exposes some X.509 extension details so we can pretty print certificates with Universal 2nd Factor (U2F) certificate transports extensions Co-authored-by: Hannes Mehnert --- bin/webauthn_demo.ml | 17 ++++++++++++++++- src/webauthn.ml | 6 +++--- src/webauthn.mli | 8 ++++++++ webauthn.opam | 4 ++-- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/bin/webauthn_demo.ml b/bin/webauthn_demo.ml index 0b613de..21d5469 100644 --- a/bin/webauthn_demo.ml +++ b/bin/webauthn_demo.ml @@ -1,5 +1,20 @@ open Lwt.Infix +let pp_cert = + let pp_extensions ppf (oid, data) = + let fido_u2f_transport_oid_name = "id-fido-u2f-ce-transports" in + if Asn.OID.equal oid Webauthn.fido_u2f_transport_oid then + match Webauthn.decode_transport data with + | Error `Msg _ -> + Fmt.pf ppf "%s invalid-data %a" fido_u2f_transport_oid_name (Ohex.pp_hexdump ()) data + | Ok transports -> + Fmt.pf ppf "%s %a" fido_u2f_transport_oid_name + Fmt.(list ~sep:(any ",") Webauthn.pp_transport) transports + else + Fmt.pf ppf "unsupported %a: %a" Asn.OID.pp oid (Ohex.pp_hexdump ()) data + in + X509.Certificate.pp' pp_extensions + let users : (string, string * (Mirage_crypto_ec.P256.Dsa.pub * string * X509.Certificate.t option) list) Hashtbl.t = Hashtbl.create 7 let find_username username = @@ -140,7 +155,7 @@ let add_routes t = Option.fold ~none:("No certificate", "No certificate", Ok []) ~some:(fun c -> X509.Certificate.encode_pem c, - Fmt.to_to_string X509.Certificate.pp c, + Fmt.to_to_string pp_cert c, Webauthn.transports_of_cert c) certificate in diff --git a/src/webauthn.ml b/src/webauthn.ml index 870b2da..9984cb3 100644 --- a/src/webauthn.ml +++ b/src/webauthn.ml @@ -448,11 +448,11 @@ type transport = [ ] let pp_transport ppf = function - | `Bluetooth_classic -> Fmt.string ppf "Bluetooth classic" - | `Bluetooth_low_energy -> Fmt.string ppf "Bluetooth low energy" + | `Bluetooth_classic -> Fmt.string ppf "BluetoothClassic" + | `Bluetooth_low_energy -> Fmt.string ppf "BluetoothLowEnergy" | `Usb -> Fmt.string ppf "USB" | `Nfc -> Fmt.string ppf "NFC" - | `Usb_internal -> Fmt.string ppf "USB internal" + | `Usb_internal -> Fmt.string ppf "USBInternal" let transports = let opts = [ diff --git a/src/webauthn.mli b/src/webauthn.mli index 0a36b20..8dac3d4 100644 --- a/src/webauthn.mli +++ b/src/webauthn.mli @@ -168,6 +168,14 @@ type transport = [ (** [pp_transport ppf tranport] pretty-prints the [transport] on [ppf]. *) val pp_transport : Format.formatter -> transport -> unit +(** [fido_u2f_transport_oid] is the OID 1.3.6.1.4.1.45724.2.1.1 for + certificate authenticator transports extensions. *) +val fido_u2f_transport_oid : Asn.oid + +(** [decode_transport data] decodes the [fido_u2f_transport_oid] certificate + extension data. *) +val decode_transport : string -> (transport list, [> `Msg of string ]) result + (** [transports_of_cert certficate] attempts to extract the FIDO U2F authenticator transports extension (OID 1.3.6.1.4.1.45724.2.1.1) from the [certificate]. *) diff --git a/webauthn.opam b/webauthn.opam index 8d5a1ad..ba7bbc6 100644 --- a/webauthn.opam +++ b/webauthn.opam @@ -17,7 +17,7 @@ depends: [ "ocaml" {>= "4.08.0"} "dune" {>= "2.7"} "dream" {dev & >= "1.0.0~alpha7"} - "ppx_blob" {dev} + "ppx_blob" {dev & >= "0.9.0"} "cmdliner" {dev & >= "1.1.0"} "logs" {dev} "lwt" {dev} @@ -27,7 +27,7 @@ depends: [ "mirage-crypto-ec" {>= "1.1.0"} "mirage-crypto-rng" {>= "1.1.0"} "ocplib-endian" - "x509" {>= "1.0.2"} + "x509" {>= "1.0.4"} "base64" {>= "3.1.0"} "cbor" {>= "0.5"} "ohex" {>= "0.2.0"}