An implementation of webauthn components for Rustlang servers

Overview

Webauthn-rs

Webauthn is a modern approach to hardware based authentication, consisting of a user with an authenticator device, a browser or client that interacts with the device, and a server that is able to generate challenges and verify the authenticators validity.

Users are able to enroll their own tokens through a registration process to be associated to their accounts, and then are able to login using the token which performas a cryptographic authentication.

This library aims to provide useful functions and frameworks allowing you to integrate webauthn into rust web servers. This means the library implements the Relying Party component of the FIDO2 workflow. We provide template and example javascript to demonstrate the browser interactions required.

Examples

As this library aims to be usable in a variety of contexts, we have provided examples in the examples folder. These examples should demonstrate secure and valid use, so please report any issues found, and we'd love to see more examples contributed!

Known Supported Keys/Harwdare

  • Yubico 5c + MacOS 10.14 + Firefox/Edge
  • Yubico 5ci + iPadOS 14 + Safari/Brave
  • TouchID + iPadOS + Safari
  • Windows Hello + Windows 10 + Chrome

If your key/browser combination don't work (generally due to missing crypto routines) please open an issue so that I can help you generate vectors and add support!

FIDO Compliance

This library has been carefully implemented to follow the w3c standard for webauthn processing to ensure correct behaviour. However, not all elements of the standard are implemented (yet). This means the library is not yet FIDO compliant. It is a goal to improve this library to meet that standard over time as more test vectors and hardware becomes available, but the current focus has been on supporting the most popular key types.

Feedback

The current design of the traits and configuration is open to feedback on how it can be improved - please use this library and contact the project on what can be improved!

Why OpenSSL?

A question I expect is why OpenSSL rather than some other pure-Rust cryptographic providers. There are two major justfications.

The first is that if this library will be used in corporate or major deployments, then cryptographic audits may have to be performed. It is much easier to point toward OpenSSL which has already undergone much more review and auditing than using a series of Rust crates which (while still great!) have not seen the same level of scrutiny.

The second is that OpenSSL is the only library I have found that allows us to reconstruct an EC public key from it's X/Y points or an RSA public key from it's n/e for use with signature verification. Without this, we are not able to parse authenticator credentials to perform authentication.

Resources

Comments
  • TouchID Attestation [WIP]

    TouchID Attestation [WIP]

    • wip
    • feat(touchid-attest): initial implementation of touch id attestation

    Implements #33.

    Currently missing steps 4 and 5, and the validation of the certificate chain against Apple's root certificates.

    • [x] cargo fmt has been run
    • [x] cargo test has been run and passes
    • [x] documentation has been updated with relevant examples (if relevant)
    opened by ericmarkmartin 26
  • Firefox 98 + Windows 11 + Windows Hello truncates aaguid

    Firefox 98 + Windows 11 + Windows Hello truncates aaguid

    As we discussed, I updated to windows 11 and ran the compat test to try to collect a tpm vector. I still need to analyze the vectors to see what format we're using but was surprised by the number of failures

    Please add any extra details here:

    • Browser version: Firefox 98.0
    • Type of authenticator hardware: Windows hello. My processor is a Ryzen 9 which I believe has a TPM module. I authenticated using my pin.
    • Any other details that may help
    {
      "direct_attest_1": {
        "Passed": {
          "rs": {
            "cred_id": "EzjDD8m1NnXx7CPfRjQJrh_lFX4fIKTTCPX-2X6ZSYc",
            "uv": true,
            "alg": "RS256"
          },
          "ccr": {
            "publicKey": {
              "rp": {
                "name": "webauthn.firstyear.id.au",
                "id": "webauthn.firstyear.id.au"
              },
              "user": {
                "id": "Y29tcGF0dXNlcg",
                "name": "compatuser",
                "displayName": "compatuser"
              },
              "challenge": "BjAqz29Ec_vJtUolavnSAGAgJcaUwTIVrKH16LXcYAU",
              "pubKeyCredParams": [
                {
                  "type": "public-key",
                  "alg": -7
                },
                {
                  "type": "public-key",
                  "alg": -35
                },
                {
                  "type": "public-key",
                  "alg": -36
                },
                {
                  "type": "public-key",
                  "alg": -257
                },
                {
                  "type": "public-key",
                  "alg": -258
                },
                {
                  "type": "public-key",
                  "alg": -259
                },
                {
                  "type": "public-key",
                  "alg": -37
                },
                {
                  "type": "public-key",
                  "alg": -38
                },
                {
                  "type": "public-key",
                  "alg": -39
                },
                {
                  "type": "public-key",
                  "alg": -8
                },
                {
                  "type": "public-key",
                  "alg": -65535
                }
              ],
              "timeout": 60000,
              "attestation": "direct",
              "authenticatorSelection": {
                "requireResidentKey": false,
                "userVerification": "discouraged"
              }
            }
          },
          "rpkc": {
            "id": "EzjDD8m1NnXx7CPfRjQJrh_lFX4fIKTTCPX-2X6ZSYc",
            "rawId": "EzjDD8m1NnXx7CPfRjQJrh_lFX4fIKTTCPX-2X6ZSYc",
            "response": {
              "attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZzkBAGNzaWdZAQCjBbdY-Q0qXTabiieICTaU0765ide6hPvIxPZV3xjuegHJku-bUy_J8nZRGWwXOI3dSbv-LUp2Ft9joRwk8lFxHYSiQ0GLonmJbb2cOxxp5URWsOX6qIlbFS2tFGPx8XZI0xuBd2LBXzQn34mELIgeF6Qsjh-j2lbGsFxOR7SImklUbyfTiJtoeAG1s9U8SDEXipsN-AGZUa7tietzs-VJl1q1Foee2zVUchA42NsguK57eoDvdic6ckTl9HQ8aKxdVjA2zq4J-ugX9LTD6vbDFEGu-3B4-SXJx916VSnTeFIkPWHlK2ZbyciZ0z2K_jX4EboYmBKFCJ54YbeQmVwDaGF1dGhEYXRhWQFnarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpFAAAAAAiYcFjK3EuBtuEw3lDcvpYAIBM4ww_JtTZ18ewj30Y0Ca4f5RV-HyCk0wj1_tl-mUmHpAEDAzkBACBZAQCo9GhWUyex7JKeFuTHnPVMWwDbMDS9AwO07NeBvgrt-k1M1DXmsPFqbIdUKEdASOLKjeLP5dzjFqVd5aOz9ZixlfomMlYeJr_JYknNPAJ0qWvboQwMnbPktgqYRPMjNvS-FkBuN9LMyV5I8W195O14XyFQ5KuNz09T8P4hvZBR5UGVc6z_O48HHG6P8M1qTUVM21iHOzRkVNj_QHd6Jv51-lDWzzjKCdhmWWfYdoN6lvq3HyKQIFn13P4DjXhhz0qIyrB-9DkASWXu308KERGiqZsxerkpnRGzTzs4Cq8XevShCa3s5_1xtxtvxP2kvFvBuLnf1dEGxv48RpHn6SIBIUMBAAE",
              "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJCakFxejI5RWNfdkp0VW9sYXZuU0FHQWdKY2FVd1RJVnJLSDE2TFhjWUFVIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5maXJzdHllYXIuaWQuYXUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"
            },
            "type": "public-key"
          }
        }
      },
      "indirect_attest_1": {
        "Passed": {
          "rs": {
            "cred_id": "olVLUBLIsDmwCvQf3v5s53TqOS7teRGtbqt9Uoq3xzI",
            "uv": true,
            "alg": "RS256"
          },
          "ccr": {
            "publicKey": {
              "rp": {
                "name": "webauthn.firstyear.id.au",
                "id": "webauthn.firstyear.id.au"
              },
              "user": {
                "id": "Y29tcGF0dXNlcg",
                "name": "compatuser",
                "displayName": "compatuser"
              },
              "challenge": "XYK1QETOh_FCKxUhKYr0cLzSKQfHa1o2dqlI0BtQlqM",
              "pubKeyCredParams": [
                {
                  "type": "public-key",
                  "alg": -7
                },
                {
                  "type": "public-key",
                  "alg": -35
                },
                {
                  "type": "public-key",
                  "alg": -36
                },
                {
                  "type": "public-key",
                  "alg": -257
                },
                {
                  "type": "public-key",
                  "alg": -258
                },
                {
                  "type": "public-key",
                  "alg": -259
                },
                {
                  "type": "public-key",
                  "alg": -37
                },
                {
                  "type": "public-key",
                  "alg": -38
                },
                {
                  "type": "public-key",
                  "alg": -39
                },
                {
                  "type": "public-key",
                  "alg": -8
                },
                {
                  "type": "public-key",
                  "alg": -65535
                }
              ],
              "timeout": 60000,
              "attestation": "indirect",
              "authenticatorSelection": {
                "requireResidentKey": false,
                "userVerification": "discouraged"
              }
            }
          },
          "rpkc": {
            "id": "olVLUBLIsDmwCvQf3v5s53TqOS7teRGtbqt9Uoq3xzI",
            "rawId": "olVLUBLIsDmwCvQf3v5s53TqOS7teRGtbqt9Uoq3xzI",
            "response": {
              "attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZzkBAGNzaWdZAQBTrKkKEnB7KHhNRoUxEpb5s1fy6ygb3agozdWiBCNYcf1O6uCbp0rh6eScNgZ5ol3rYhp9KNllDkU50pfRUGiemlxnL0kaUfkMkm-P5DQzA4RtZCkISIHnWsOGdzWSQQNQ8-nsjr7po02gJtL0fLrPd9Gyi-5v7Ks73D5n38akU9-1Cv8l6zgMptm0tfvRM6_GF1uBGkkXDCmedye7CITteo7odwltQD_8HLjtno8n9MxOmKb3s6g7oT5c8YrkJVP7siR11CLt08UywZQN75VcvCn_Kj8q51T4o6M9KPVAm13BfxxamPy26wTQErn3NjnTAFTb2Axd-42iHp60xYWEaGF1dGhEYXRhWQFnarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpFAAAAAAiYcFjK3EuBtuEw3lDcvpYAIKJVS1ASyLA5sAr0H97-bOd06jku7XkRrW6rfVKKt8cypAEDAzkBACBZAQCjejzCxfZmoACsb-cdF98bO791UAB4l6hlB3PH82-HVi0yA1UfsGYcOgT2m-tlvZ2drpA319w6roxM-ud5PZcFVKrYWhpBf02Q4kVe4AEF5oxWZlLOYffv1HMr0JK_Qb38LdYPUn1ceFyj8jNnq9C0Y38u-brySirHGEAbOmkaWZjtY9DhCwp2PC0SYl5ZkEP-cFtEVxbEjuiw9kA68ZyOmef_EITkTU4KMQ1WNE0q4TxSUTOVXYE9pw3fBWXyfR7mwuXlRlJfPNCeZySuwX4T41mjtvnXBjAvfuuIQ4sDnA_WeEtEXoWKgpxCDZrLe3w8sjci0wPGIY6Qai6a-YEJIUMBAAE",
              "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJYWUsxUUVUT2hfRkNLeFVoS1lyMGNMelNLUWZIYTFvMmRxbEkwQnRRbHFNIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5maXJzdHllYXIuaWQuYXUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"
            },
            "type": "public-key"
          }
        }
      },
      "none_attest_1": {
        "Failed": {
          "err": "ParseNOMFailure",
          "ccr": {
            "publicKey": {
              "rp": {
                "name": "webauthn.firstyear.id.au",
                "id": "webauthn.firstyear.id.au"
              },
              "user": {
                "id": "Y29tcGF0dXNlcg",
                "name": "compatuser",
                "displayName": "compatuser"
              },
              "challenge": "FKVseWmr5DxQ_H9iTyoTgRPIClLspXO0XbOKQfMuaFc",
              "pubKeyCredParams": [
                {
                  "type": "public-key",
                  "alg": -7
                },
                {
                  "type": "public-key",
                  "alg": -35
                },
                {
                  "type": "public-key",
                  "alg": -36
                },
                {
                  "type": "public-key",
                  "alg": -257
                },
                {
                  "type": "public-key",
                  "alg": -258
                },
                {
                  "type": "public-key",
                  "alg": -259
                },
                {
                  "type": "public-key",
                  "alg": -37
                },
                {
                  "type": "public-key",
                  "alg": -38
                },
                {
                  "type": "public-key",
                  "alg": -39
                },
                {
                  "type": "public-key",
                  "alg": -8
                },
                {
                  "type": "public-key",
                  "alg": -65535
                }
              ],
              "timeout": 60000,
              "attestation": "none",
              "authenticatorSelection": {
                "requireResidentKey": false,
                "userVerification": "discouraged"
              }
            }
          },
          "rpkc": {
            "id": "6h7wVk2n4Buulhd5fiShGb0BBViIgvDoVO3xhn0A0Mg",
            "rawId": "6h7wVk2n4Buulhd5fiShGb0BBViIgvDoVO3xhn0A0Mg",
            "response": {
              "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVkBWGq5u_Dfmhb5Hbszu7Ey-vnRfHgsSCbG7HDs7ljZfvUqRQAAAAAAACDqHvBWTafgG66WF3l-JKEZvQEFWIiC8OhU7fGGfQDQyKQBAwM5AQAgWQEAt86lR2w_hmnhDr6tvJD5hmIuWt0QkG1sphC8aqeOHuIWnbcBWnxNUrKQibJxEGJilM20s-_w-aUjDoV5MYu4NBgguFHju-qA-qe1sjhqY7UkMkx4Z1KGMeiZNNGgk5Gtmu0xjaq-1RohB3TKADeWTularHWzG6q6sJHgC-qKKa67Rmwr0T4a4S3VjLvjvSPILx88nLJvwqO1rDb5cLOgL5CEjtRijR6SNeN05uBhz2ePn5mMo2lN73pHsMGPo68pGWIWWsb2sC_aBF2eA02Me2jldIgSzMy3y8xsTIg6r_xF105pC8jOPsQVN2TJDxN9zVEuxpY_mUsqGOAFGR-SiyFDAQAB",
              "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJGS1ZzZVdtcjVEeFFfSDlpVHlvVGdSUElDbExzcFhPMFhiT0tRZk11YUZjIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5maXJzdHllYXIuaWQuYXUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"
            },
            "type": "public-key"
          }
        }
      },
      "authdiscouraged": "FailedPrerequisite",
      "authdiscouraged_consistent": "FailedPrerequisite",
      "none_attest_2": {
        "Failed": {
          "err": "ParseNOMFailure",
          "ccr": {
            "publicKey": {
              "rp": {
                "name": "webauthn.firstyear.id.au",
                "id": "webauthn.firstyear.id.au"
              },
              "user": {
                "id": "Y29tcGF0dXNlcg",
                "name": "compatuser",
                "displayName": "compatuser"
              },
              "challenge": "Ykr70oCHYaW3heAsQHfeUQ5ittysUSb6aQL35ah90zA",
              "pubKeyCredParams": [
                {
                  "type": "public-key",
                  "alg": -7
                },
                {
                  "type": "public-key",
                  "alg": -35
                },
                {
                  "type": "public-key",
                  "alg": -36
                },
                {
                  "type": "public-key",
                  "alg": -257
                },
                {
                  "type": "public-key",
                  "alg": -258
                },
                {
                  "type": "public-key",
                  "alg": -259
                },
                {
                  "type": "public-key",
                  "alg": -37
                },
                {
                  "type": "public-key",
                  "alg": -38
                },
                {
                  "type": "public-key",
                  "alg": -39
                },
                {
                  "type": "public-key",
                  "alg": -8
                },
                {
                  "type": "public-key",
                  "alg": -65535
                }
              ],
              "timeout": 60000,
              "attestation": "none",
              "authenticatorSelection": {
                "requireResidentKey": false,
                "userVerification": "discouraged"
              }
            }
          },
          "rpkc": {
            "id": "ERVIVbSJuZcS_ewnP1K5rsHuOzJlc8_WJfVijJp8ayw",
            "rawId": "ERVIVbSJuZcS_ewnP1K5rsHuOzJlc8_WJfVijJp8ayw",
            "response": {
              "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVkBWGq5u_Dfmhb5Hbszu7Ey-vnRfHgsSCbG7HDs7ljZfvUqRQAAAAAAACARFUhVtIm5lxL97Cc_Urmuwe47MmVzz9Yl9WKMmnxrLKQBAwM5AQAgWQEA48xXOWz0nxYFasxR2F2b8eOJpS0fRS9F9jDCEZ1NiK8VPUZbqaPDm6mryK9X-3XpNpRkZhNs6rmsZhLAqH9PQneZCuLt9CiNyjD8C1xO9tzFn0iIpuSlzDdRclFAK61pAgnXw_gjYNYpdof71O3bdLuU7X8fGNd42iVjv2hNcB83BXJ2Qe01Vi43_PTtDhg2V2pN7gsLQulJKGc10NgusuPXjdnrTqJOSy9O4tvLqu6XT2AndZJ9xN3ks0YXmcfoA3RLOeYZCWzLd3ayX6Bbk_Ok7V9vMvOuU43tB_fYKaLB8hv1z_-bhlrFpwH4H2gF66KA3WAwysCoLiInVMhucSFDAQAB",
              "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJZa3I3MG9DSFlhVzNoZUFzUUhmZVVRNWl0dHlzVVNiNmFRTDM1YWg5MHpBIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5maXJzdHllYXIuaWQuYXUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"
            },
            "type": "public-key"
          }
        }
      },
      "authmultiple": "FailedPrerequisite",
      "fallback_alg": "NotTested",
      "uvpreferred": {
        "Failed": {
          "err": "ParseNOMFailure",
          "ccr": {
            "publicKey": {
              "rp": {
                "name": "webauthn.firstyear.id.au",
                "id": "webauthn.firstyear.id.au"
              },
              "user": {
                "id": "Y29tcGF0dXNlcg",
                "name": "compatuser",
                "displayName": "compatuser"
              },
              "challenge": "BZdJ3kGUVbZCiSmYBZXfxWqSrH241ZKnysN_jG-ZSw0",
              "pubKeyCredParams": [
                {
                  "type": "public-key",
                  "alg": -7
                },
                {
                  "type": "public-key",
                  "alg": -35
                },
                {
                  "type": "public-key",
                  "alg": -36
                },
                {
                  "type": "public-key",
                  "alg": -257
                },
                {
                  "type": "public-key",
                  "alg": -258
                },
                {
                  "type": "public-key",
                  "alg": -259
                },
                {
                  "type": "public-key",
                  "alg": -37
                },
                {
                  "type": "public-key",
                  "alg": -38
                },
                {
                  "type": "public-key",
                  "alg": -39
                },
                {
                  "type": "public-key",
                  "alg": -8
                },
                {
                  "type": "public-key",
                  "alg": -65535
                }
              ],
              "timeout": 60000,
              "attestation": "none",
              "authenticatorSelection": {
                "requireResidentKey": false,
                "userVerification": "preferred"
              }
            }
          },
          "rpkc": {
            "id": "S8YjipouhTSMTeD5R0DgSssj_KS3tQ0vg-PrKZe0SUU",
            "rawId": "S8YjipouhTSMTeD5R0DgSssj_KS3tQ0vg-PrKZe0SUU",
            "response": {
              "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVkBWGq5u_Dfmhb5Hbszu7Ey-vnRfHgsSCbG7HDs7ljZfvUqRQAAAAAAACBLxiOKmi6FNIxN4PlHQOBKyyP8pLe1DS-D4-spl7RJRaQBAwM5AQAgWQEAt7LzACPAeQa5-UU2oitnIXh3NVUDpmVPQlCgDt9T-roXH6oQK1dHDrB_kcJp6I77BQcRd5Lx-Qhb9g0osrdF--zemBIPScbvjwmiYTyEmycvvhO9NZ8lUB3DFaVd3N3HaEvYXceimFyNVxbt8vwDyYiAU6ZyPF-YfvUGv6Nxe0q0BPSEJLnKvMtX8nyWGEPwEVukimZzAApmhhDvIUm2EvxLXGSbA_8owU4W5iDegErkRd8twI4AaqCxtVKNszPkmHpMZDjMkFyYXQmiIcmYU6EUW60yGr_BbEkPXIgLL19jTWWYcgrLVcdYvoTqeKeLdIixPFM1Ck3zJ24als2_iyFDAQAB",
              "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJCWmRKM2tHVVZiWkNpU21ZQlpYZnhXcVNySDI0MVpLbnlzTl9qRy1aU3cwIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5maXJzdHllYXIuaWQuYXUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"
            },
            "type": "public-key"
          }
        }
      },
      "authpreferred": "FailedPrerequisite",
      "authpreferred_consistent": "FailedPrerequisite",
      "uvrequired": {
        "Failed": {
          "err": "ParseNOMFailure",
          "ccr": {
            "publicKey": {
              "rp": {
                "name": "webauthn.firstyear.id.au",
                "id": "webauthn.firstyear.id.au"
              },
              "user": {
                "id": "Y29tcGF0dXNlcg",
                "name": "compatuser",
                "displayName": "compatuser"
              },
              "challenge": "gAu9I4xf3y_c1tKasOlDlBKX8gzpHLhoy5FesHl7mv0",
              "pubKeyCredParams": [
                {
                  "type": "public-key",
                  "alg": -7
                },
                {
                  "type": "public-key",
                  "alg": -35
                },
                {
                  "type": "public-key",
                  "alg": -36
                },
                {
                  "type": "public-key",
                  "alg": -257
                },
                {
                  "type": "public-key",
                  "alg": -258
                },
                {
                  "type": "public-key",
                  "alg": -259
                },
                {
                  "type": "public-key",
                  "alg": -37
                },
                {
                  "type": "public-key",
                  "alg": -38
                },
                {
                  "type": "public-key",
                  "alg": -39
                },
                {
                  "type": "public-key",
                  "alg": -8
                },
                {
                  "type": "public-key",
                  "alg": -65535
                }
              ],
              "timeout": 60000,
              "attestation": "none",
              "authenticatorSelection": {
                "requireResidentKey": false,
                "userVerification": "required"
              }
            }
          },
          "rpkc": {
            "id": "wBQcWbgrp0xhzOwbTSrxqP3BW3DmZX3mAyUBSxm-xgA",
            "rawId": "wBQcWbgrp0xhzOwbTSrxqP3BW3DmZX3mAyUBSxm-xgA",
            "response": {
              "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVkBWGq5u_Dfmhb5Hbszu7Ey-vnRfHgsSCbG7HDs7ljZfvUqRQAAAAAAACDAFBxZuCunTGHM7BtNKvGo_cFbcOZlfeYDJQFLGb7GAKQBAwM5AQAgWQEAvdQhpHWoxeJ6uQu5WhxgGC6PzZ2AOsO3eMjDOwvlHQ1sidxYyN0WV-Ck9JPyUx9DXyv5b4tEVxVo9dlMYfmmUC2s58ZAc-6UXzHGOsT3EqpiPxJxun5qfV_8fOtAFoLHp67NS_xc1tfwZW1kXPqkZNG0d-l-M_E1kAohajZwQdZflAqgVXBLrJPJ5D7TPiFdibVaFQJMpGIciWRmzCjM-NEG7kvKjQUDd3Z6Evm9lUDlUVUzDvdbQ1I2VfkY_3ufbCemBkbsL3tt_OMahNUI-9FCwpx_f29CcAsK2m2TYm8oYT69tPPpTMyVMTEppDaVC54hIn6OsVr5FIK4FBWXeSFDAQAB",
              "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJnQXU5STR4ZjN5X2MxdEthc09sRGxCS1g4Z3pwSExob3k1RmVzSGw3bXYwIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5maXJzdHllYXIuaWQuYXUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"
            },
            "type": "public-key"
          }
        }
      },
      "authrequired": "FailedPrerequisite"
    }
    
    opened by ericmarkmartin 23
  • Use owned strings instead of references.

    Use owned strings instead of references.

    Implements #70.

    • [x] cargo fmt has been run
    • [x] cargo test has been run and passes
    • [x] documentation has been updated with relevant examples (if relevant)
    opened by jalcine 19
  • WebauthnBuilder and prelude don't exist

    WebauthnBuilder and prelude don't exist

    I'm reading through the docs and the examples, and attempting to replicate my own simple version, but most of the examples and tutorials seem to use WebauthnBuilder and prelude in webauthn_rs, but I can't find any mention of them existing or ever having existed in the docs. Am I missing something?

    opened by benwis 16
  • Add x5c extension validation

    Add x5c extension validation

    Uses x509_parser to validate x5c extensions.

    Implements #22.

    • [x] cargo fmt has been run
    • [x] cargo test has been run and passes
    • [x] documentation has been updated with relevant examples (if relevant)
    opened by ericmarkmartin 12
  • dependency serde_cbor is unmaintained

    dependency serde_cbor is unmaintained

    The dependency serde_cbor is unmaintained and is flagged on a "cargo audit". The serde_cbor maintainer recommends moving over to ciborium or minicbor. In my experience, the former is an easy replacement (though ymmv).

    opened by mtnking 11
  • Last call for changes!

    Last call for changes!

    Last call for ideas! I want to do the next release soon and stop changing the api so much, so now is your time to give constructive feedback! From my side I will commit a fido metadata service library and parser first before I do the release, currently I'm thinking to do the next release on 16th of August.

    @agrinman @benwis @devsnek @yaleman @ericmarkmartin

    opened by Firstyear 11
  • Support U2F appid extension

    Support U2F appid extension

    Implements support for the appid extension for U2F backwards compatibility.

    I've noticed that some types have been recently changed to return &str instead of a String, and I've considered doing the same here, but didn't want to complicate the code adding lifetimes, let me know if you'd prefer it that way and I can change it.

    Might also want to change the parameter type from String to something like Into, which would make it easier to use both &str and String types directly.

    • [x] cargo fmt has been run
    • [x] cargo test has been run and passes
    • [x] documentation has been updated with relevant examples (if relevant)
    opened by dani-garcia 11
  • Review public API

    Review public API

    An open question is the ergonomics of the public API and how we expose datastorage traits and other methods of application integration. As this library hasn't been used in "production" yet, it's still an open question if the decisions I made were really correct or ergonomic to use for deployments.

    If you have comments or feedback on the current API design, I'd love to know!

    opened by Firstyear 11
  • User verification logic

    User verification logic

    Re: the discussion here: https://github.com/kanidm/webauthn-rs/commit/9e3fd65de11594955790cc1ebb60e567398f0cfd

    What do you think of this approach for dealing with the UV problem?

    opened by agrinman 10
  • Register doesn't work on Firefox because I need to enter a PIN!?

    Register doesn't work on Firefox because I need to enter a PIN!?

    I tested the axtix example on Fedora 32. Tested key: HyperFIDO Pro Mini, which is a Feitian K8 rebrand/OEM device with a LED and button.

    But it is not working on Firefox 82. I can click register, Firefox asks about to make the keydata more anonymous. But after that, my key LED doesn't blink.

    But when I try Chromium: Username "Test" and click Register Chomium asks for a PIN. After entering the PIN to Unlock The LED of the key blinks and after pressing the button, registeration is compleed.

    Then when I go back to firefox. Only login works.

    So I wonder why Firefox doesn't support a PIN. Second why does your example needs that PIN? Maybe can we turn that off? Why does https://demo.yubico.com/webauthn-technical/registration need a pin to register on Firefox?

    opened by vDorst 10
  • Common API changes needed to (later) add caBLE support.

    Common API changes needed to (later) add caBLE support.

    This adds functionality, changes APIs and refactors webauthn-authenticator-rs in ways that's necessary (or useful) for caBLE support (#232), without actually adding support for caBLE itself.

    • AuthenticatorBackendHashedClientData: new trait for AuthenticatorBackends which accepts client_data_hash directly. This de-duplicates the client_data_json handling, and allows the library to proxy requests from a caBLE initiator.
    • perform_register_with_request, perform_auth_with_request: Accepts MakeCredentialRequest and GetAssertionResponse commands directly, mapping them onto AuthenticatorBackendHashedClientData. This allows it to act as a caBLE authenticator, while also handling PIN/UV auth internally when proxying to physical authenticators (as browsers don't attempt it!)
    • crypto: new module for common cryptographic operations, shared between caBLE and CTAP2 implementation.
    • CTAP2:
      • implement AuthenticatorBackendHashedClientData instead of AuthenticatorBackend
      • adds serialisation for Map<u32, String> to GetAssertionResponse and MakeCredentialResponse and from GetAssertionRequest and MakeCredentialRequest for perform_*_with_request.
      • allow for both Map<String, String> and Map<u32, String> representations of CBORRequest and CBORResponse for perform_*_with_request.
      • add GetInfoResponse serialisation
      • make to_short_apdus and to_long_apdu stand-alone methods
      • Token is now mutable, and Token::close is now async
      • use short APDUs for selecting FIDO2 applet over NFC, because Feitian tokens don't support extended APDUs (in violation of the FIDO specification!)
    • SoftPasskey:
      • implement AuthenticatorBackendHashedClientData instead of AuthenticatorBackend
    • SoftToken:
      • implement AuthenticatorBackendHashedClientData instead of AuthenticatorBackend
      • add support for persisting the SoftToken (as SoftTokenFile)
      • add examples/softtoken for creating a persisted SoftToken
    • ui: Add methods for caBLE (displaying QR codes and reporting status)
    • examples/authenticate:
      • refactor to use command line arguments, rather than interactive text UI
      • re-open the connection to the key after every operation (needed for Feitian NFC keys, and also caBLE)
    • clean up some dead/commented code that was from testing earlier features
    • fix some documentation formatting errors

    Fixes #

    • [ ] cargo test has been run and passes
    • [x] documentation has been updated with relevant examples (if relevant)
    opened by micolous 0
  • Compatibility Test Failure

    Compatibility Test Failure

    • Browser version: Safari Version 16.1 (17614.2.9.1.13, 17614) on macOS 12.6.1 (21G217)
    • Type of authenticator hardware MacBook Air (M1, 2020) with TouchID
    • Any other details that may help: I simply followed the steps, used TouchID every time it asked me
    {"direct_attest_1":{"Failed":{"err":{"NavigatorError":"JsValue(NotAllowedError: This request has been cancelled by the user.\n)"},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"cT2ctcz-QS6MXTWdxsallw","name":"compatuser","displayName":"compatuser"},"challenge":"MaUNExX79dh_kyv4aXsbCWazLnVrcNs8cKiViXvCqjU","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"direct","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":null}},"indirect_attest_1":{"Passed":{"rs":{"cred_id":"SMZ3C9_LE-4RSL468u8AvzsHOZI","uv":true,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":{"Unsigned":{"rk":true}}}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"evr0fmuZQcSkqVYCCDc1UQ","name":"compatuser","displayName":"compatuser"},"challenge":"rZKjEitRPy7TCBC8qmH1mujDVXn_4FqCKyEAP2QGMVs","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"indirect","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"SMZ3C9_LE-4RSL468u8AvzsHOZI","rawId":"SMZ3C9_LE-4RSL468u8AvzsHOZI","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpdAAAAAAAAAAAAAAAAAAAAAAAAAAAAFEjGdwvfyxPuEUi-OvLvAL87BzmSpQECAyYgASFYIJ91QTMT5VQ9tlCT8zUqZwXbkuxXd5IDRX-T-NlepPKKIlggMDXRP-GtNJ0xMkhrMPHrBYU2GdzQ0AlclwV6oeWeBXA","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiclpLakVpdFJQeTdUQ0JDOHFtSDFtdWpEVlhuXzRGcUNLeUVBUDJRR01WcyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1In0","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":{"rk":true}}}}},"none_attest_1":{"Failed":{"err":{"NavigatorError":"JsValue(NotAllowedError: This request has been cancelled by the user.\n)"},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"IMW-vKUbRwGSrKFl0hCEHA","name":"compatuser","displayName":"compatuser"},"challenge":"nx4hmC7rZK263pCydiZ1mftre7oDYjB4fGJ7g5xXQWA","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":null}},"authdiscouraged":"FailedPrerequisite","authdiscouraged_consistent":"FailedPrerequisite","none_attest_2":{"Passed":{"rs":{"cred_id":"dv1TRgQG6osqTEOC3oxfgY7qru0","uv":true,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":{"Unsigned":{"rk":true}}}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"tqIDa7LIT8O1710hB7mXQQ","name":"another_user","displayName":"another_user"},"challenge":"6ZcfBEpyVUfuZi6k17wHzE0Fki-oWa-9FH85mOFfAbo","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"dv1TRgQG6osqTEOC3oxfgY7qru0","rawId":"dv1TRgQG6osqTEOC3oxfgY7qru0","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpdAAAAAAAAAAAAAAAAAAAAAAAAAAAAFHb9U0YEBuqLKkxDgt6MX4GO6q7tpQECAyYgASFYIBl1QPWiui_C90g3tYHmwfEX-0G1OeoggBV2R9mKu16wIlgglXbPhkZT1BQ0wuLyNYgTCbKOFMJWS-RnnsCinaaKbqI","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiNlpjZkJFcHlWVWZ1Wmk2azE3d0h6RTBGa2ktb1dhLTlGSDg1bU9GZkFibyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1In0","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":{"rk":true}}}}},"authmultiple":"FailedPrerequisite","fallback_alg":"NotTested","uvpreferred":{"Passed":{"rs":{"cred_id":"Xw4txbvIL4fTC2OIJdx-Rfk22bw","uv":true,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":{"Unsigned":{"rk":true}}}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"aEmf2XglTj-J7ZGCKw_psg","name":"compatuser","displayName":"compatuser"},"challenge":"tzFuoA-_gcNiGTlG90vza0KRSXG5Tvdze0JnA9Vfkko","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"Xw4txbvIL4fTC2OIJdx-Rfk22bw","rawId":"Xw4txbvIL4fTC2OIJdx-Rfk22bw","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpdAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF8OLcW7yC-H0wtjiCXcfkX5Ntm8pQECAyYgASFYIMDJGMm_sTDCJfXat6U0xhDocT7r6ulJzyKbx51ekoJaIlggd-jq94cRZyiqxKOIeShkWn_Eq3MvfFwjUmXv2Ezoj_E","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoidHpGdW9BLV9nY05pR1RsRzkwdnphMEtSU1hHNVR2ZHplMEpuQTlWZmtrbyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1In0","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":{"rk":true}}}}},"authpreferred":{"Passed":{"aus":{"cred_id":"Xw4txbvIL4fTC2OIJdx-Rfk22bw","uv":true,"extensions":{}},"rcr":{"publicKey":{"challenge":"ZmUb37ACiLTHZbjEwNq8rJWqr9JWft_MlcE4Ez09Ns4","timeout":60000,"rpId":"webauthn.firstyear.id.au","allowCredentials":[{"type":"public-key","id":"Xw4txbvIL4fTC2OIJdx-Rfk22bw"}],"userVerification":"preferred","extensions":{"uvm":true}}},"pkc":{"id":"Xw4txbvIL4fTC2OIJdx-Rfk22bw","rawId":"Xw4txbvIL4fTC2OIJdx-Rfk22bw","response":{"authenticatorData":"arm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SodAAAAAA","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiWm1VYjM3QUNpTFRIWmJqRXdOcThySldxcjlKV2Z0X01sY0U0RXowOU5zNCIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1In0","signature":"MEUCIHUymdH23H3e9y5O8PUij1dt8auVBZN49Kj8arPkg5_NAiEAknozj_NKuwntE4uN2ln8l4dCFBF3ILdJ3-sB6W_AVJY","userHandle":"aEmf2XglTj-J7ZGCKw_psg"},"extensions":{"appid":null,"cred_blob":null},"type":"public-key"}}},"authpreferred_consistent":"Passed","uvrequired":{"Passed":{"rs":{"cred_id":"ztiwDL5FFNu6wb3hLuZ01OPSOfA","uv":true,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":{"Unsigned":{"rk":true}}}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"yeO-vvyVRJiRUtNldk-twA","name":"compatuser","displayName":"compatuser"},"challenge":"KlF7-ibbcLFC_Rwm04JhCnc4jt-aFwgu0tmHgOKKDJs","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"required"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"ztiwDL5FFNu6wb3hLuZ01OPSOfA","rawId":"ztiwDL5FFNu6wb3hLuZ01OPSOfA","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpdAAAAAAAAAAAAAAAAAAAAAAAAAAAAFM7YsAy-RRTbusG94S7mdNTj0jnwpQECAyYgASFYIHHsNy5I06KO5vIqSATgL9lSKqT25G4n1Lepe2EWjrP7IlggUNJOkxA0TJLL2TDfqwB5QREmfhwjAERZZPkF_VSSb7o","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiS2xGNy1pYmJjTEZDX1J3bTA0SmhDbmM0anQtYUZ3Z3UwdG1IZ09LS0RKcyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1In0","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":{"rk":true}}}}},"authrequired":{"Passed":{"aus":{"cred_id":"ztiwDL5FFNu6wb3hLuZ01OPSOfA","uv":true,"extensions":{}},"rcr":{"publicKey":{"challenge":"R62shtkA2YwpNliDZVDi6Fq5QIwbXBsxFb5i2Y2QwyA","timeout":60000,"rpId":"webauthn.firstyear.id.au","allowCredentials":[{"type":"public-key","id":"ztiwDL5FFNu6wb3hLuZ01OPSOfA"}],"userVerification":"required","extensions":{"uvm":true}}},"pkc":{"id":"ztiwDL5FFNu6wb3hLuZ01OPSOfA","rawId":"ztiwDL5FFNu6wb3hLuZ01OPSOfA","response":{"authenticatorData":"arm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SodAAAAAA","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiUjYyc2h0a0EyWXdwTmxpRFpWRGk2RnE1UUl3YlhCc3hGYjVpMlkyUXd5QSIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1In0","signature":"MEYCIQC0iBE7udTEXA06AKp-_wWQa3l5wJg8dxytBF2EVY50kAIhAJh8FjlzhaGYFasIey79aMp5Ja_ZfZgMndRHRNEQiGgY","userHandle":"yeO-vvyVRJiRUtNldk-twA"},"extensions":{"appid":null,"cred_blob":null},"type":"public-key"}}},"extn_uvm_supported":"FailedPrerequisite","extn_credprotect_supported":"FailedPrerequisite","extn_hmacsecret_supported":"FailedPrerequisite"}
    
    opened by x4m3 1
  • Fido MDS tool query

    Fido MDS tool query

    We need a way to be able to query the FIDO MDS data, but more specifically, users who use the tool need a way to query it as well.

    How should we do this? What should the queries look like?

    What kind of requirements would users realistically have?

    Finally, when we have the query complete, what format should we output the data as? Something we can import directly into Webauthn-RS Attestation CA Lists?

    Currently some ideas in my head for use cases are:

    • A user wants to allow device AAGUID X and Y and export these to an attestation CA List
    • A user wants to know what devices have been certified with "FIPS-CMVP-2"> X.
    • A user may want to know what devices support a specific extension such as hmac-secret.
    • A user wants to know what devices support a specific userverification method - or do not support a verification method (exclude bio metrics for example)

    My thinking is that users will often query to find devices, shortlist them, then can just feed the aaguid list to extract the set of attestation's CA's in use (and the aaguids they govern).

    Thoughts?

    opened by Firstyear 0
  • WIP: caBLE

    WIP: caBLE

    ~~This is still some way off, and needs #215.~~ This needs #251.

    This will be slow to implement because there's no publicly published spec, so I need to reverse engineer what Chromium does.

    What's done:

    • generates a QR code
    • scans for BLE advertisement
    • decrypts BLE advertisement
    • connects to correct websocket
    • works on Android and current iOS
    • establishes a Cable-Noise channel (it's almost like Noise, but is different in enough ways to prevent using a standard Noise implementation, eg: it uses a non-standard DH function (P256))
    • decrypt the initial GetInfo response
    • Cable-Noise crypter channel (it again differs from Noise, by constructing nonces differently)
    • connected to CtapAuthenticator
    • added QR functionality to UiCallback
    • websocket tunnel works bidirectionally
    • encryption over websockets works
    • makecredential, getassertion works on current Android and iOS
    • encrypting discovery messages for BLE transmission works to other devices
    • establishing new tunnel on Google's tunnel server
    • implemented authenticator for Token (examples/cable_tunnel.rs): this allows you to tunnel a physical NFC or USB token over caBLE; this also works if you then re-use that authenticator on another transport (USB / NFC)
    • added AuthenticatorBackendHashedClientData API, which allows passing in client_data_json directly
      • wired up caBLE to that...
      • PIN/UV auth works 🎉
      • SoftToken partly works, it just needs a properly persisted private key
    • put caBLE implementation behind a feature flag
    • untangle the protocol

    TODO:

    • error propagation, rather than unwrap()
    • tests
    • documentation
    • using bluer (bluez rust bindings) for advertisements?

    Deferred work:

    • Pairing / Linking / "Remember Device": Android always sends a linking information message, but the data is all null bytes if the user didn't consent... so this PR just ignores it.
    • DevicePubKey extension (Android only)
    • Using Apple's tunnel server

    Fixes #

    • [ ] cargo fmt has been run
    • [ ] cargo test has been run and passes
    • [ ] documentation has been updated with relevant examples (if relevant)

    in-development screenshots

    MakeCredential flow on iOS 16:

    MakeCredential QR scanning on iOS

    MakeCredential TouchID prompt

    GetAssertion flow on iOS 16:

    GetAssertion QR scanning on iOS

    GetAssertion TouchID prompt

    opened by micolous 2
  • Review dashlane results

    Review dashlane results

    {"direct_attest_1":{"Passed":{"rs":{"cred_id":"YWNkZTE2ZTctMDAzNi00MTg4LWIxYzYtODdmMWQxOTU3MWI0","uv":false,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":"Ignored"}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"lv6yyrPBRgySDDm1Oirh0w","name":"compatuser","displayName":"compatuser"},"challenge":"RzoutgCF8Z4Uj9hMV4tw8d7Cj2vOfZjTfLf0XQTChG4","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"direct","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"YWNkZTE2ZTctMDAzNi00MTg4LWIxYzYtODdmMWQxOTU3MWI0","rawId":"YWNkZTE2ZTctMDAzNi00MTg4LWIxYzYtODdmMWQxOTU3MWI0","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVioarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpJAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGFjZGUxNmU3LTAwMzYtNDE4OC1iMWM2LTg3ZjFkMTk1NzFiNKUBAgMmIAEhWCDwleYhPbzB4ZegeVtO6wOnpT3ojmj-htVy3RAFVdM15yJYIHUkd-j-rf-0nRHRtm7-BvNtnK_VdDv9kwwlkreDMBUw","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiUnpvdXRnQ0Y4WjRVajloTVY0dHc4ZDdDajJ2T2ZaalRmTGYwWFFUQ2hHNCIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":null}}}},"indirect_attest_1":{"Passed":{"rs":{"cred_id":"NTJkMTdhY2UtN2M4Ny00NDQwLTgwNTYtNTVlNjIzZWY3MTJi","uv":false,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":"Ignored"}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"d3Nr8mxwS-qtgBU42xY7Yg","name":"compatuser","displayName":"compatuser"},"challenge":"oUoQqBNUI3umSaU8zz2Blwp4dcQFP1hwWogLoMsUYQg","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"indirect","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"NTJkMTdhY2UtN2M4Ny00NDQwLTgwNTYtNTVlNjIzZWY3MTJi","rawId":"NTJkMTdhY2UtN2M4Ny00NDQwLTgwNTYtNTVlNjIzZWY3MTJi","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVioarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpJAAAAAAAAAAAAAAAAAAAAAAAAAAAAJDUyZDE3YWNlLTdjODctNDQ0MC04MDU2LTU1ZTYyM2VmNzEyYqUBAgMmIAEhWCCIW8aF7wl9Zc39G3-r_ISt5oB_DK9VLGU5TyHg2iRe4SJYIMH9pcc3Qx7hBtV33mRsPp-Y7-iyJs1MPIC1q6B21G1S","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoib1VvUXFCTlVJM3VtU2FVOHp6MkJsd3A0ZGNRRlAxaHdXb2dMb01zVVlRZyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":null}}}},"none_attest_1":{"Passed":{"rs":{"cred_id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","uv":false,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":"Ignored"}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"BmSX78CwQbKqBYCcoUd4xA","name":"compatuser","displayName":"compatuser"},"challenge":"Eopg6A-fls_EHr8MQ4nahtBHxP8jyvzAz0IJU6FJmGQ","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","rawId":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVioarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpJAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGIyNmZlMDI2LTRkYWMtNGJmZi1iN2NlLTQ0ZGE5MWI2M2I2NaUBAgMmIAEhWCCMh3toRqma2onnzGC7CZCh4WaWDTGMxZ3cCQl7oUHn4iJYIK5LDRpp7zVeh3S_ihGNmGdVs4DPeb02hO3M8aE0EF6A","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiRW9wZzZBLWZsc19FSHI4TVE0bmFodEJIeFA4anl2ekF6MElKVTZGSm1HUSIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":null}}}},"authdiscouraged":{"Passed":{"aus":{"cred_id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","uv":false,"extensions":{}},"rcr":{"publicKey":{"challenge":"whC3rqoAZcKaLAElj-85c2AuWDNfVv0LhA_7pK98TlI","timeout":60000,"rpId":"webauthn.firstyear.id.au","allowCredentials":[{"type":"public-key","id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1"}],"userVerification":"discouraged","extensions":{"uvm":true}}},"pkc":{"id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","rawId":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","response":{"authenticatorData":"arm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SoJAAAAAQ","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoid2hDM3Jxb0FaY0thTEFFbGotODVjMkF1V0ROZlZ2MExoQV83cEs5OFRsSSIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","signature":"MEUCIQCEeT0mPAic-eW1tnE1sfaSUZotX0TjjHesm_slxn-qzgIgIWalKLLF5u5v6NYEeTFP5nUIuA1XzZF2c0yKLwVE-qo","userHandle":"BmSX78CwQbKqBYCcoUd4xA"},"extensions":{"appid":null,"cred_blob":null},"type":"public-key"}}},"authdiscouraged_consistent":"Passed","none_attest_2":{"Passed":{"rs":{"cred_id":"MTRlOTE5MmUtNTRkZS00MjA0LWEwMjEtYTRkMWIyZWIyODEy","uv":false,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":"Ignored"}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"HlazJeVMR2iBQVS0X-GaBA","name":"another_user","displayName":"another_user"},"challenge":"gEedv2b3jbyqDlhrzt0GwC-DBl0JOOTSYfG75y8BCyo","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"MTRlOTE5MmUtNTRkZS00MjA0LWEwMjEtYTRkMWIyZWIyODEy","rawId":"MTRlOTE5MmUtNTRkZS00MjA0LWEwMjEtYTRkMWIyZWIyODEy","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVioarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpJAAAAAAAAAAAAAAAAAAAAAAAAAAAAJDE0ZTkxOTJlLTU0ZGUtNDIwNC1hMDIxLWE0ZDFiMmViMjgxMqUBAgMmIAEhWCBw9Ia-fnnsjPU-icDmUH8_nhUh6buErr_5lBgvtfXNnyJYIHHXymSXw-Cs2VN6SqWzPL42Eiatcn-2Xq4UNDBVoDnv","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiZ0VlZHYyYjNqYnlxRGxocnp0MEd3Qy1EQmwwSk9PVFNZZkc3NXk4QkN5byIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":null}}}},"authmultiple":{"Passed":{"aus":{"cred_id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","uv":false,"extensions":{}},"rcr":{"publicKey":{"challenge":"HZ3ioDis0e_MmalvoZD-xD5chjTR_xTUWgx-DUH3VDs","timeout":60000,"rpId":"webauthn.firstyear.id.au","allowCredentials":[{"type":"public-key","id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1"}],"userVerification":"discouraged","extensions":{"uvm":true}}},"pkc":{"id":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","rawId":"YjI2ZmUwMjYtNGRhYy00YmZmLWI3Y2UtNDRkYTkxYjYzYjY1","response":{"authenticatorData":"arm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SoJAAAAAg","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiSFozaW9EaXMwZV9NbWFsdm9aRC14RDVjaGpUUl94VFVXZ3gtRFVIM1ZEcyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","signature":"MEQCIBPE20D6VS0KnyicuI31BZTnp8CRgREg_qiHEG7VgUf-AiAFsyEn09Oa-v7DuzYFPi-oDA6WsmGghpUYo7q4SiohPw","userHandle":"BmSX78CwQbKqBYCcoUd4xA"},"extensions":{"appid":null,"cred_blob":null},"type":"public-key"}}},"fallback_alg":{"Warning":{"err":{"NavigatorError":"JsValue(NotAllowedError: The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.\nundefined)"},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"_v9a5YP6Ss61Z_mYN8270A","name":"compatuser","displayName":"compatuser"},"challenge":"yZngYXCxN9DQsf_XqaM3SzS-Jlgm922LFqra5ekn-I0","pubKeyCredParams":[{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"discouraged"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":null}},"uvpreferred":{"Passed":{"rs":{"cred_id":"MGVjYzM1MjQtZDBlZi00YmQ4LWJjODAtMmE1NjIyMmUyOThl","uv":false,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":"Ignored"}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"ErYJ5lcOSIaL7biaaMwL_A","name":"compatuser","displayName":"compatuser"},"challenge":"Xj5_R6NWtfk4B3AY6Rmvt_kaVAmbnLkdewKO4ttKCE8","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"MGVjYzM1MjQtZDBlZi00YmQ4LWJjODAtMmE1NjIyMmUyOThl","rawId":"MGVjYzM1MjQtZDBlZi00YmQ4LWJjODAtMmE1NjIyMmUyOThl","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVioarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpJAAAAAAAAAAAAAAAAAAAAAAAAAAAAJDBlY2MzNTI0LWQwZWYtNGJkOC1iYzgwLTJhNTYyMjJlMjk4ZaUBAgMmIAEhWCCMcDGXeESr6mM3qXKeJJqGfvAwD0EXRsoDXdckCWnCfSJYIOaBCVB2snnnloJAsswQC6-uPLGWD0wFIWTvwOi3YKM5","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiWGo1X1I2Tld0Zms0QjNBWTZSbXZ0X2thVkFtYm5Ma2Rld0tPNHR0S0NFOCIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":null}}}},"authpreferred":{"Passed":{"aus":{"cred_id":"MGVjYzM1MjQtZDBlZi00YmQ4LWJjODAtMmE1NjIyMmUyOThl","uv":false,"extensions":{}},"rcr":{"publicKey":{"challenge":"YHhqX__gDStLr-ENQ50Sn7Wtr7FqbYiXSZr7R624tr0","timeout":60000,"rpId":"webauthn.firstyear.id.au","allowCredentials":[{"type":"public-key","id":"MGVjYzM1MjQtZDBlZi00YmQ4LWJjODAtMmE1NjIyMmUyOThl"}],"userVerification":"preferred","extensions":{"uvm":true}}},"pkc":{"id":"MGVjYzM1MjQtZDBlZi00YmQ4LWJjODAtMmE1NjIyMmUyOThl","rawId":"MGVjYzM1MjQtZDBlZi00YmQ4LWJjODAtMmE1NjIyMmUyOThl","response":{"authenticatorData":"arm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SoJAAAAAQ","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiWUhocVhfX2dEU3RMci1FTlE1MFNuN1d0cjdGcWJZaVhTWnI3UjYyNHRyMCIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","signature":"MEUCIQDsotnyYhdORMBV9BoPWmHOb8jo9zEJjURy_JeFWP5NVAIga82SDZiZteayGTxPLuGjntqm_LkfznK5dk3R1TZ9NAk","userHandle":"ErYJ5lcOSIaL7biaaMwL_A"},"extensions":{"appid":null,"cred_blob":null},"type":"public-key"}}},"authpreferred_consistent":"Passed","uvrequired":{"Passed":{"rs":{"cred_id":"ZTI1YTgyZTItYzc2MC00M2Y1LWI5Y2QtN2NjYzgzOGIxZDQ5","uv":true,"alg":"ES256","extensions":{"cred_protect":"Ignored","hmac_create_secret":"Ignored","appid":"NotRequested","cred_props":"Ignored"}},"ccr":{"publicKey":{"rp":{"name":"webauthn.firstyear.id.au","id":"webauthn.firstyear.id.au"},"user":{"id":"LoU2k0FpTVioNGTlAulFsQ","name":"compatuser","displayName":"compatuser"},"challenge":"0KDR6g7fvRgq50shrD0CGleLX5MaQiJhHv0nUMOgnSk","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-8},{"type":"public-key","alg":-65535}],"timeout":60000,"attestation":"none","authenticatorSelection":{"requireResidentKey":false,"userVerification":"required"},"extensions":{"credentialProtectionPolicy":"userVerificationOptionalWithCredentialIDList","enforceCredentialProtectionPolicy":false,"uvm":true,"credProps":true,"minPinLength":true,"hmacCreateSecret":true}}},"rpkc":{"id":"ZTI1YTgyZTItYzc2MC00M2Y1LWI5Y2QtN2NjYzgzOGIxZDQ5","rawId":"ZTI1YTgyZTItYzc2MC00M2Y1LWI5Y2QtN2NjYzgzOGIxZDQ5","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVioarm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SpNAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGUyNWE4MmUyLWM3NjAtNDNmNS1iOWNkLTdjY2M4MzhiMWQ0OaUBAgMmIAEhWCAnOlwSdiFQBeSSi-TJ4kwouI84AGc1CF3E7mFiS6P9jCJYIHz3k-WmaTfJy8wEwDML-KUe7e1UlLJvAWUVvag3HZIv","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiMEtEUjZnN2Z2UmdxNTBzaHJEMENHbGVMWDVNYVFpSmhIdjBuVU1PZ25TayIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","transports":null},"type":"public-key","extensions":{"appid":null,"cred_blob":null,"cred_props":null}}}},"authrequired":{"Passed":{"aus":{"cred_id":"ZTI1YTgyZTItYzc2MC00M2Y1LWI5Y2QtN2NjYzgzOGIxZDQ5","uv":true,"extensions":{}},"rcr":{"publicKey":{"challenge":"jdmL6Nd7Bvmsa-TUAfsWL0x2Gk2wF7fRbkGc00_B_ps","timeout":60000,"rpId":"webauthn.firstyear.id.au","allowCredentials":[{"type":"public-key","id":"ZTI1YTgyZTItYzc2MC00M2Y1LWI5Y2QtN2NjYzgzOGIxZDQ5"}],"userVerification":"required","extensions":{"uvm":true}}},"pkc":{"id":"ZTI1YTgyZTItYzc2MC00M2Y1LWI5Y2QtN2NjYzgzOGIxZDQ5","rawId":"ZTI1YTgyZTItYzc2MC00M2Y1LWI5Y2QtN2NjYzgzOGIxZDQ5","response":{"authenticatorData":"arm78N-aFvkduzO7sTL6-dF8eCxIJsbscOzuWNl-9SoNAAAAAQ","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiamRtTDZOZDdCdm1zYS1UVUFmc1dMMHgyR2syd0Y3ZlJia0djMDBfQl9wcyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","signature":"MEQCIF5ABMnaPC29aRqlYJcwcTi2UEuNk5l0OpYMQE9FThq6AiBlDVkCoAbTtxAQtoQqXCabFrPQ1B9gb30otiG4go_t6w","userHandle":"LoU2k0FpTVioNGTlAulFsQ"},"extensions":{"appid":null,"cred_blob":null},"type":"public-key"}}},"extn_uvm_supported":"FailedPrerequisite","extn_credprotect_supported":"Failed","extn_hmacsecret_supported":"Failed"}
    
    opened by Firstyear 0
Owner
Kanidm
Kanidm Identity Management Project
Kanidm
An oauth2 client implementation providing the Device, Installed and Service Account flows.

yup-oauth2 is a utility library which implements several OAuth 2.0 flows. It's mainly used by google-apis-rs, to authenticate against Google services.

Lewin Bormann 174 Dec 30, 2022
An implementation for an authentication API for Rocket applications.

rocket_auth rocket_auth provides a ready-to-use backend agnostic API for authentication management. For more information visit the documentation at ht

null 62 Dec 19, 2022
A paseto implementation in rust.

Paseto Rust Paseto is everything you love about JOSE (JWT, JWE, JWS) without any of the many design deficits that plague the JOSE standards. This is d

Instructure, Inc. 145 Nov 7, 2022
OpenSK is an open-source implementation for security keys written in Rust that supports both FIDO U2F and FIDO2 standards.

OpenSK This repository contains a Rust implementation of a FIDO2 authenticator. We developed this as a Tock OS application and it has been successfull

Google 2.4k Jan 2, 2023
A minimal jwt implementation for OIDC

Compact JWT Json Web Tokens (JWT) are a popular method for creating signed transparent tokens that can be verified by clients and servers. They are en

Kanidm 4 Dec 29, 2021
ROCCA cipher implementation for Rust.

ROCCA for Rust This is a Rust implementation of the ROCCA authenticated cipher, ported from the Zig implementation. ROCCA is key committing, has a 256

Frank Denis 6 Sep 30, 2022
RSA implementation in pure Rust

RSA A portable RSA implementation in pure Rust. ⚠️ WARNING: This crate has been audited by a 3rd party, but a full blog post with the results and the

Rust Crypto 346 Jan 4, 2023
WebCipher - JWT encryption/decryption algorithms + a JWK Store implementation

webcipher provides JWT authentication utilities and storage mechanism for caching keys and optimizing decryption/encryption processes.

Wavy 1 May 1, 2022
SD-JWT Rust Reference Implementation

SD-JWT Rust Reference Implementation This is the reference implementation of the IETF SD-JWT specification written in Rust. Supported version: 6. Note

OpenWallet Foundation Labs 4 Dec 19, 2023
An implementation of webauthn components for Rustlang servers

Webauthn-rs Webauthn is a modern approach to hardware based authentication, consisting of a user with an authenticator device, a browser or client tha

Kanidm 226 Dec 28, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
A simple tcp server that written in rustlang

rust_tcp A simple tcp server that written in rustlang How to build In the root dir cargo run Then you can do a test by using telnet as a client telne

null 1 Oct 25, 2021
⚡🚀 Content Delivery Network written in Rustlang, optimized for speed and latency.

Supported Formats HTML Javscript Css Image PNG JPG JPEG GIF SVG Video MP4 WEBM FLV Audio OGG ACC MP3 Archives ZIP RAR Feeds & Data JSON YAML XML Docum

Noname 3 Apr 9, 2024
Pure Rust implementation of components of the Secure Shell (SSH) protocol

RustCrypto: SSH Pure Rust implementation of components of the Secure Shell (SSH) protocol. Crates Name crates.io Docs Description ssh—encoding Decoder

Rust Crypto 27 Dec 27, 2022
Reusable components for the Arduino Uno.

Ruduino This library provides a set of reusable components for the Arduino Uno. Overview Register and bit definitions use ruduino::cores::current::POR

The AVR-Rust project 610 Dec 28, 2022
Rewind is a snapshot-based coverage-guided fuzzer targeting Windows kernel components.

Rewind is a snapshot-based coverage-guided fuzzer targeting Windows kernel components.

Quarkslab 259 Dec 26, 2022
NPM package distributing biscuit in WebAssembly for web components

Biscuit playground This is an example application for Biscuit tokens, where you can manipulate tokens and their verification in your browser. build wi

null 0 Dec 30, 2021
🕺 Run React code snippets/components from your command-line without config

Run React code snippets/components from your command-line without config.

Eliaz Bobadilla 11 Dec 30, 2022
A collection of components and widgets that are built for bevy_ui and the ECS pattern

Widgets for Bevy UI A collection of components and widgets that are built for bevy_ui and the ECS pattern. Current State This was started recently and

Gabriel Bourgeois 3 Sep 2, 2022
WASM bindings for React - enables you to write and use React components in Rust

This library enables you to write and use React components in Rust, which then can be exported to JS to be reused or rendered.

Yichuan Shen 55 Dec 24, 2022