tanguilp / wax_demo

WebAuthn demo in Elixir, using the Phoenix framework and the wax library
Apache License 2.0
17 stars 6 forks source link

demo not starting #4

Closed jschoch closed 5 years ago

jschoch commented 5 years ago

the mix.exs has a relative path for the wax library, I replaced it with the github directive. When I try to start the demo it seems wax shuts down. I also tried to add wax to extra_applications but it still shuts down.

elix@xeon:~/dev/wax_demo$ iex -S mix phx.server
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Compiling 19 files (.ex)
Generated wax_demo app
[info] Application wax exited: shutdown
** (Mix) Could not start application wax_demo: {:not_running, :wax}
tanguilp commented 5 years ago

I just changed the dependency, now using the Github repository.

Clone this repository again, run mix deps.compile then iex -S mix phx.server and please confirm it works as expected.

jschoch commented 5 years ago

recloned after rm -rf

added dev.secret.exs

is it my OTP version? I was able to get it to run on a different machine running 1.9 and OTP 22. this machine had issues with the packed format and could not register a key.

elix@xeon:~/dev/wax_demo$ iex -S mix phx.server
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

===> Compiling parse_trans
==> asn1ex
Compiling 1 file (.ex)
Generated asn1ex app
===> Compiling mimerl
==> file_system
Compiling 7 files (.ex)
Generated file_system app
===> Compiling metrics
===> Compiling unicode_util_compat
===> Compiling idna
==> gettext
Compiling 1 file (.yrl)
Compiling 1 file (.erl)
Compiling 20 files (.ex)
Generated gettext app
===> Compiling ranch
==> jason
Compiling 8 files (.ex)
Generated jason app
==> ssl_verify_fun
Compiling 7 files (.erl)
Generated ssl_verify_fun app
===> Compiling cbor
===> Compiling certifi
===> Compiling hackney
==> httpoison
Compiling 3 files (.ex)
Generated httpoison app
==> phoenix_pubsub
Compiling 13 files (.ex)
Generated phoenix_pubsub app
===> Compiling cowlib
===> Compiling cowboy
==> mime
Compiling 2 files (.ex)
Generated mime app
==> x509
Compiling 22 files (.ex)
Generated x509 app
==> wax
Compiled AndroidKeyAttestationV1
Compiled AndroidKeyAttestationV2
Compiled AndroidKeyAttestationV3
Compiling 3 files (.erl)
Compiling 23 files (.ex)
Generated wax app
==> plug_crypto
Compiling 4 files (.ex)
Generated plug_crypto app
==> plug
Compiling 1 file (.erl)
Compiling 38 files (.ex)
warning: System.stacktrace/0 outside of rescue/catch clauses is deprecated. If you want to support only Elixir v1.7+, you must access __STACKTRACE__ inside a rescue/catch. If you want to support earlier Elixir versions, move System.stacktrace/0 inside a rescue/catch
  lib/plug/conn/wrapper_error.ex:23

Generated plug app
==> phoenix_html
Compiling 8 files (.ex)
Generated phoenix_html app
==> plug_cowboy
Compiling 5 files (.ex)
Generated plug_cowboy app
==> phoenix
Compiling 67 files (.ex)
warning: redefining @doc attribute previously set at line 216
  lib/phoenix/presence.ex:223: Phoenix.Presence (module)

Generated phoenix app
==> phoenix_live_reload
Compiling 4 files (.ex)
Generated phoenix_live_reload app
==> wax_demo
Compiling 19 files (.ex)
Generated wax_demo app
[info] Application wax exited: shutdown
** (Mix) Could not start application wax_demo: {:not_running, :wax}
tanguilp commented 5 years ago

Wax is indeed support from OTP21 (https://github.com/tanguilp/wax#compatibility) because it uses handle_continue somewhere.

Regarding the

issues with the packed format

could you open an issue if it is an issue with Wax? Thank you in advance.

jschoch commented 5 years ago

I have it working now. I also wonder if the metadata was causing the issue on the other box with the packed format error?

I noticed you require a password on key register. Is this intended to limit key registration for only existing users that have a password? What are your thoughts on passwordless signup flows? I'd like to design something that has no usernames or passwords, only webauthn authentication. Let me know if this additional question should be in a new issue.

jschoch commented 5 years ago

here is the error if I try to use the metadata.

[info] POST /register_key
[debug] Processing with WaxDemoWeb.RegisterKeyController.validate/2
  Parameters: %{"_csrf_token" => "PRskBiocfgsBJkoVKDYGXi0QAiAUAAAAtJjdIhL97RelrFSinYQCVQ==", "_utf8" => "✓", "key" => %{"attestationObject" => "o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEgwRgIhAMQETqb3+T2GBZn3dNYcTOhd/NCc88gqLWKofCc8SbXlAiEAo0CQ7Uk1dk/Ox02hjMWub6IkD+Sk8UwieRWyBz6zMURjeDVjgVkCwDCCArwwggGkoAMCAQICBATF/vwwDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEwIBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG0xCzAJBgNVBAYTAlNFMRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0ZXN0YXRpb24xJjAkBgNVBAMMHVl1YmljbyBVMkYgRUUgU2VyaWFsIDgwMDg0NzMyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHNjadhGj9e8fiF6VC6ZdgOM0hVORWEvUf1txnFMjXCQh5OOZvbVzZ4JBkJNXZmFJPJFMLmck35OU/Pp96osYBKNsMGowIgYJKwYBBAGCxAoCBBUxLjMuNi4xLjQuMS40MTQ4Mi4xLjEwEwYLKwYBBAGC5RwCAQEEBAMCBSAwIQYLKwYBBAGC5RwBAQQEEgQQ+KAR84wKTRWABhcRH57cfTAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQB3GEzvdS0aBfMKU4XcLYb4+sBjcXCwImKlGVz1/tA2/gBlTg0pFbxFUpo/iV5qwczUHpdxVuALqToG4KyZpnFlhAWcl0qUULWHJdi0zVNPiM/Vm8hzTdcECfcmxcI+tPMQbqDUQtKxvMIGGzAuLrMkWnbd3WDlXUItHH2pLFQdlTSp8PrbUFFiqGbDx7bsxcfDZWsy0AXqdVtk9BQjjRRBu8f5fmXHzYU9d2swG2rqydidP33+h9D1yT+ofjm53uMX89PvLo37Vg1EofaGolUWH/rYGpv7czishFN/FdpYlddczMhylq14itAH8g4G+fJMth0q5/wIBOTFv6F4Pwl3aGF1dGhEYXRhWMRJlg3liA6MaHQ0Fw9kdmBbj+SuuaKGMseZXPO6gx2XY0UAAAA2+KAR84wKTRWABhcRH57cfQBAPcQazrcH7k8ceuXlIehoQ971w7hZhzAU6oVLCUhTzkf9IWVz09rmMiqajY6J6kA8ApslAyRMGxWEK0Tb6MvuVqUBAgMmIAEhWCCGVQcZvBPm0RC6Zbeim5s+bsLYAz+A1BD9tGJlY05vYyJYILmTG9em3zi+e+JyDxzDtpwYhJg7W5S0SlicIDXG7RFJ", "clientDataJSON" => "{\"challenge\":\"udU8dlLx4SCMO-hzxbkrFXYm_siWqezZNOuSX-y1Q28\",\"origin\":\"http://localhost:4000\",\"type\":\"webauthn.create\"}", "rawID" => "PcQazrcH7k8ceuXlIehoQ971w7hZhzAU6oVLCUhTzkf9IWVz09rmMiqajY6J6kA8ApslAyRMGxWEK0Tb6MvuVg==", "type" => "public-key"}}
  Pipelines: [:browser]
[debug] Elixir.Wax: decoded attestation object: %{
  "attStmt" => %{
    "alg" => -7,
    "sig" => <<48, 70, 2, 33, 0, 196, 4, 78, 166, 247, 249, 61, 134, 5, 153,
      247, 116, 214, 28, 76, 232, 93, 252, 208, 156, 243, 200, 42, 45, 98, 168,
      124, 39, 60, 73, 181, 229, 2, 33, 0, 163, 64, 144, 237, 73, 53, 118,
      ...>>,
    "x5c" => [
      <<48, 130, 2, 188, 48, 130, 1, 164, 160, 3, 2, 1, 2, 2, 4, 4, 197, 254,
        252, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 46,
        49, 44, 48, 42, 6, 3, 85, 4, 3, ...>>
    ]
  },
  "authData" => <<73, 150, 13, 229, 136, 14, 140, 104, 116, 52, 23, 15, 100,
    118, 96, 91, 143, 228, 174, 185, 162, 134, 50, 199, 153, 92, 243, 186, 131,
    29, 151, 99, 69, 0, 0, 0, 54, 248, 160, 17, 243, 140, 10, 77, 21, 128, 6,
    23, ...>>,
  "fmt" => "packed"
}
[debug] Elixir.Wax.AttestationStatementFormat.Packed: verifying signature with public key {{:ECPoint, <<4, 28, 216, 218, 118, 17, 163, 245, 239, 31, 136, 94, 149, 11, 166, 93, 128, 227, 52, 133, 83, 145, 88, 75, 212, 127, 91, 113, 156, 83, 35, 92, 36, 33, 228, 227, 153, 189, 181, 115, 103, 130, 65, 144, 147, 87, 102, ...>>}, {:namedCurve, {1, 2, 840, 10045, 3, 1, 7}}} (digest: :sha256)
[debug] Elixir.Wax.AttestationStatementFormat.Packed: verifying certificate info of {:OTPCertificate, {:OTPTBSCertificate, :v3, 80084732, {:SignatureAlgorithm, {1, 2, 840, 113549, 1, 1, 11}, :NULL}, {:rdnSequence, [[{:AttributeTypeAndValue, {2, 5, 4, 3}, {:printableString, 'Yubico U2F Root CA Serial 457200631'}}]]}, {:Validity, {:utcTime, '140801000000Z'}, {:generalTime, '20500904000000Z'}}, {:rdnSequence, [[{:AttributeTypeAndValue, {2, 5, 4, 6}, 'SE'}], [{:AttributeTypeAndValue, {2, 5, 4, 10}, {:utf8String, "Yubico AB"}}], [{:AttributeTypeAndValue, {2, 5, 4, 11}, {:utf8String, "Authenticator Attestation"}}], [{:AttributeTypeAndValue, {2, 5, 4, 3}, {:utf8String, "Yubico U2F EE Serial 80084732"}}]]}, {:OTPSubjectPublicKeyInfo, {:PublicKeyAlgorithm, {1, 2, 840, 10045, 2, 1}, {:namedCurve, {1, 2, 840, 10045, 3, 1, 7}}}, {:ECPoint, <<4, 28, 216, 218, 118, 17, 163, 245, 239, 31, 136, 94, 149, 11, 166, 93, 128, 227, 52, 133, 83, 145, 88, 75, 212, 127, 91, 113, 156, 83, 35, 92, 36, 33, 228, ...>>}}, :asn1_NOVALUE, :asn1_NOVALUE, [{:Extension, {1, 3, 6, 1, 4, 1, 41482, 2}, false, "1.3.6.1.4.1.41482.1.1"}, {:Extension, {1, 3, 6, 1, 4, 1, 45724, 2, 1, 1}, false, <<3, 2, 5, 32>>}, {:Extension, {1, 3, 6, 1, 4, 1, 45724, 1, 1, 4}, false, <<4, 16, 248, 160, 17, 243, 140, 10, 77, 21, 128, 6, 23, 17, 31, 158, 220, 125>>}, {:Extension, {2, 5, 29, 19}, true, {:BasicConstraints, false, :asn1_NOVALUE}}]}, {:SignatureAlgorithm, {1, 2, 840, 113549, 1, 1, 11}, :NULL}, <<119, 24, 76, 239, 117, 45, 26, 5, 243, 10, 83, 133, 220, 45, 134, 248, 250, 192, 99, 113, 112, 176, 34, 98, 165, 25, 92, 245, 254, 208, 54, 254, 0, 101, 78, 13, 41, 21, 188, 69, 82, 154, 63, 137, 94, 106, ...>>}
[debug] Wax: attestation object validation failed with error {:error, :attestation_packed_no_attestation_metadata_statement_found}
[debug] Wax: generated attestation challenge %Wax.Challenge{allow_credentials: [], bytes: <<24, 10, 48, 250, 183, 32, 156, 124, 28, 197, 143, 255, 44, 151, 239, 241, 17, 16, 188, 96, 48, 191, 113, 240, 177, 171, 175, 235, 111, 226, 66, 10>>, exp: nil, origin: "http://localhost:4000", rp_id: "localhost", token_binding_status: nil, trusted_attestation_types: [:none, :basic, :uncertain, :attca, :self], user_verified_required: false, verify_trust_root: true}
tanguilp commented 5 years ago

It seems that in this case Wax is called with the :verify_trust_root set to true. If there's no matching metadatam then it cannot, indeed, validate the certificate chain (to a root certificate). Therefore:

And yeah, the API is provided by the FIDO Alliance and you have to request access to it - this is not legally possible to share this API's credentials. The FIDO alliance will provide with an open API in the future though.

As for your question on the flow, password is not mandatory. But you have to ask yourself: what if the user loses his authenticator (usb key, smartphone...)? Then you'll either ask him to create a new account (terrible, as he'll lose its previous data on the site) or need a reinitalization process,. Typically this is done by email, so you'll ask him his email at some point (and that's not a problem). However:

jschoch commented 5 years ago

I don't see any yubico key identifiers in the log. perhaps they can be added per this: https://developers.yubico.com/yubico-piv-tool/Attestation.html

my main concern is not wanting to store passwords. I also plan to recommend multiple keys get setup.

tanguilp commented 5 years ago

If it's just about no password, you don't need certification. Certification is needed when you want, in general for legal reasons, restrict authentication to some certified authenticators.

Indeed Yubico keys are not FIDO2-certified. They are present in the metadatav1 service but Wax doesn't user it and I don;t plan adding them (because the FIDO Alliance will provide, in the future, with a webservice with both FIDO1 and FIDO2 certified authenticators).

However, Wax should allow adding manually some metadata - that's definitely in my mind!