Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebAuthn key and signature support #7421

Merged
merged 12 commits into from Jun 29, 2019

Conversation

@spoonincode
Copy link
Contributor

commented May 27, 2019

Change Description

This PR adds a third key & signature type to eosio: WebAuthn. The attractive feature of WebAuthn is being able to use a hardware signing device (a WebAuthn authenticator -- like a YubiKey 5 for example) in a browser without browser extensions or other installed software. This is, of course, a consensus affecting change and it requires activation via a protocol feature.

See EOSIO/fc#97 for fc changes.

WebAuthn Public Keys

WebAuthn public keys start with a new prefix PUB_WA. They contain 3 fields:

  • The prime256v1/secp256r1 compressed public key (in the same 33-byte format as PUB_R1)
  • A single byte indicating the user presence when the WebAuthn signature was created
  • The domain origin (relying party ID) that this key is scoped to

It is important to note that a WebAuthn key is scoped to a particular domain. The browser records the current origin in the WebAuthn signature and when eosio validates an authority the origin in the signature will only match keys with the same origin.

WebAuthn signatures can indicate three levels of user presence:

  • User not present (though this is not possible to use via browsers AFAIK)
  • User present (this would map to a touch on an authenticator, for example)
  • User verified (a more strict validation of user presence, maybe a fingerprint for example)

A key only strictly matches a single type of user presence: the highest level of presence indicated in the signature. Put another way: a key that matches "user present" will not match a signature that indicates "user verified". It is important to note that it is impossible to disable the possibility of user verification in the JavaScript WebAuthn API -- you can only discourage user verification. As such, when creating an authority that only cares about user presence, two keys will have to be added: one for user presence and one for user verification. Otherwise it's possible that even though the authority only requires user presence, a web client and authenticator may still generate a signature indicating user was verified. For weighted authorities with advanced thresholds, setting up the authority such that a single WebAuthn signature is only counted once will require some nesting.

WebAuthn authenticators will require a credential ID when signing with keys that are not resident on the authenticator. Storage of the credential ID is considered out of scope of these nodeos changes. It is not part of consensus.

WebAuthn Signatures

WebAuthn signatures start with a new prefix SIG_WA. They contain 3 fields:

  • The prime256v1/secp256r1 compact signature (in the same 65-byte format as SIG_R1)
  • The authenticator data -- binary data added by the authenticator and part of the signature. This contains, for example, the user presence details
  • The client json -- JSON generated by the browser and part of the signature. This contains, for example, the origin the browser generated the signature in.

WebAuthn requires a "challenge" when creating a signature (an assertion in WebAuthn). This challenge must be the 32-byte transaction ID that would otherwise be signed had one been doing a signature with k1 or r1. Ultimately the 32-byte transaction id will be encoded in the client json and validated by eosio.

Experimental keosd wallet

An experimental keosd wallet is included in the webauthn_keosd_wallet branch. The keosd wallet talks directly to a CTAP2 authenticator (USB FIDO2 device, like a YubiKey 5). There is no plan to clean this up and merge it. It only works on macOS and can be kind of flaky. Still, it was good enough to develop and validate this feature.

Review Notes

JSON

As part of signature validation the client json needs to be parsed. All of this happens in elliptic_webauthn.cpp in fc. Since this means the json parsing is effectively consensus, it is worth a review.

Protocol Feature Guards

WebAuthn usage is gated in 4 places:

  • Creation of an authority
  • Modification of an authority
  • setprods
  • the two intrinsics to recover keys

There is no gating of webauthn signatures within transaction validation. The theory is if a WA key can't be in an authority then a transaction wouldn't be allowed either pre or post WA introduction. Certainly something to reflect on.

Subjective Length Limit

Large JSON in SIG_WAs could pose high computational overhead. Granted, even 500KB JSONs I experimented with less than a handful of milliseconds. Still, as a safety guard, there is a subjective limit configurable for the length of a SIG_WA (default is 16KB).

The subjective limit is only enforced:

  • in chain_api_plugin when a transaction_metadata is created
  • in net_plugin when a transaction_metadata is created
  • in the two intrinsic calls when controller is_producing_block()

Consensus Changes

  • Consensus Changes

API Changes

  • API Changes

Documentation Additions

  • Documentation Additions
spoonincode added 2 commits May 26, 2019
…py of all the structures or rely on custom comparators. It will now store the needed sorting information (where tiebreaking is explicit when constructing the map) and a lambda that evaluates the rest of the needs of `::satisfies(...)`. This required making some changes to allow for any "key weight" type in the `weight_tally_visitor`. The order of evaluation exactly matches the previous implementation.
spoonincode and others added 4 commits May 28, 2019
…void implicit casting to uint. Also fix drift in tester that was passing compression_type as the subjective limit for signatures
@b1bart b1bart referenced this pull request May 29, 2019
4 of 5 tasks complete
spoonincode added 2 commits May 31, 2019
…c_key_type to shared_key_weight & shared_public_key within shared_authority
@b1bart
b1bart approved these changes Jun 12, 2019
@@ -11,6 +11,78 @@

namespace eosio { namespace chain {

using shared_public_key_data = fc::static_variant<fc::ecc::public_key_shim, fc::crypto::r1::public_key_shim, shared_string>;

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };

This comment has been minimized.

Copy link
@b1bart

b1bart Jun 12, 2019

Contributor

I think we should consider moving struct overloaded to at least types.hpp or, more ideally, fc/static_variant.hpp it seems broadly useful and generalized

b1bart and others added 4 commits Jun 12, 2019
@spoonincode spoonincode merged commit ce5cf0d into develop Jun 29, 2019
90 checks passed
90 checks passed
buildkite/eosio Build #13580 passed (39 minutes, 33 seconds)
Details
buildkite/eosio/aws-amazon-2-block-log-util-test Passed (4 minutes, 32 seconds)
Details
buildkite/eosio/aws-amazon-2-build Passed (9 minutes, 7 seconds)
Details
buildkite/eosio/aws-amazon-2-db-modes-test Passed (3 minutes, 24 seconds)
Details
buildkite/eosio/aws-amazon-2-distributed-transactions-test Passed (2 minutes, 10 seconds)
Details
buildkite/eosio/aws-amazon-2-launcher-test Passed (2 minutes, 55 seconds)
Details
buildkite/eosio/aws-amazon-2-nodeos-protocol-feature-test Passed (51 seconds)
Details
buildkite/eosio/aws-amazon-2-nodeos-run-test Passed (3 minutes, 5 seconds)
Details
buildkite/eosio/aws-amazon-2-nodeos-run-test-mongodb Passed (3 minutes, 31 seconds)
Details
buildkite/eosio/aws-amazon-2-nodeos-sanity-test Passed (2 minutes, 36 seconds)
Details
buildkite/eosio/aws-amazon-2-p2p-dawn515-test Passed (58 seconds)
Details
buildkite/eosio/aws-amazon-2-producer-preactivate-feature-test Passed (3 minutes, 48 seconds)
Details
buildkite/eosio/aws-amazon-2-restart-scenarios-test-hard-replay Passed (3 minutes, 34 seconds)
Details
buildkite/eosio/aws-amazon-2-restart-scenarios-test-none Passed (3 minutes, 15 seconds)
Details
buildkite/eosio/aws-amazon-2-restart-scenarios-test-resync Passed (3 minutes, 21 seconds)
Details
buildkite/eosio/aws-amazon-2-tests Passed (3 minutes, 46 seconds)
Details
buildkite/eosio/aws-amazon-2-validate-dirty-db-test Passed (2 minutes, 27 seconds)
Details
buildkite/eosio/bar-chart-test-metrics Passed (29 seconds)
Details
buildkite/eosio/beer-brew-updater Passed (19 seconds)
Details
buildkite/eosio/centos-centos-7-block-log-util-test Passed (4 minutes, 57 seconds)
Details
buildkite/eosio/centos-centos-7-build Passed (10 minutes, 51 seconds)
Details
buildkite/eosio/centos-centos-7-db-modes-test Passed (3 minutes, 28 seconds)
Details
buildkite/eosio/centos-centos-7-distributed-transactions-test Passed (3 minutes, 29 seconds)
Details
buildkite/eosio/centos-centos-7-launcher-test Passed (3 minutes)
Details
buildkite/eosio/centos-centos-7-nodeos-protocol-feature-test Passed (2 minutes, 15 seconds)
Details
buildkite/eosio/centos-centos-7-nodeos-run-test Passed (3 minutes, 24 seconds)
Details
buildkite/eosio/centos-centos-7-nodeos-run-test-mongodb Passed (4 minutes, 6 seconds)
Details
buildkite/eosio/centos-centos-7-nodeos-sanity-test Passed (2 minutes, 44 seconds)
Details
buildkite/eosio/centos-centos-7-p2p-dawn515-test Passed (2 minutes, 32 seconds)
Details
buildkite/eosio/centos-centos-7-package-builder Passed (2 minutes, 42 seconds)
Details
buildkite/eosio/centos-centos-7-producer-preactivate-feature-tes Passed (3 minutes, 23 seconds)
Details
buildkite/eosio/centos-centos-7-restart-scenarios-test-hard-repl Passed (3 minutes, 53 seconds)
Details
buildkite/eosio/centos-centos-7-restart-scenarios-test-none Passed (3 minutes, 48 seconds)
Details
buildkite/eosio/centos-centos-7-restart-scenarios-test-resync Passed (2 minutes, 13 seconds)
Details
buildkite/eosio/centos-centos-7-tests Passed (3 minutes, 36 seconds)
Details
buildkite/eosio/centos-centos-7-validate-dirty-db-test Passed (2 minutes, 28 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-block-log-util-test Passed (3 minutes, 26 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-build Passed (10 minutes, 37 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-db-modes-test Passed (2 minutes, 33 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-distributed-transactions-tes Passed (3 minutes, 29 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-launcher-test Passed (2 minutes, 15 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-nodeos-protocol-feature-test Passed (3 minutes, 6 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-nodeos-run-test Passed (5 minutes, 11 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-nodeos-run-test-mongodb Passed (8 minutes, 41 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-nodeos-sanity-test Passed (1 minute, 26 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-p2p-dawn515-test Passed (1 minute, 7 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-producer-preactivate-feature Passed (2 minutes, 10 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-restart-scenarios-test-hard Passed (5 minutes, 2 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-restart-scenarios-test-none Passed (3 minutes, 48 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-restart-scenarios-test-resyn Passed (4 minutes, 56 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-tests Passed (2 minutes, 58 seconds)
Details
buildkite/eosio/darwin-darwin-10-dot-14-validate-dirty-db-test Passed (1 minute, 38 seconds)
Details
buildkite/eosio/darwin-ensure-mojave-anka-template-dependency-tag-slash Passed (13 seconds)
Details
buildkite/eosio/darwin-mojave-package-builder Passed (50 seconds)
Details
buildkite/eosio/git-git-submodule-regression-check Passed (25 seconds)
Details
buildkite/eosio/pipeline-upload-pipeline-upload Passed (2 minutes, 49 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-block-log-util-test Passed (4 minutes, 54 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-build Passed (10 minutes, 7 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-db-modes-test Passed (3 minutes, 19 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-distributed-transactions-tes Passed (3 minutes, 16 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-launcher-test Passed (2 minutes, 52 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-nodeos-protocol-feature-test Passed (53 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-nodeos-run-test Passed (3 minutes, 40 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-nodeos-run-test-mongodb Passed (3 minutes, 35 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-nodeos-sanity-test Passed (2 minutes, 42 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-p2p-dawn515-test Passed (7 minutes, 31 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-package-builder Passed (1 minute, 15 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-producer-preactivate-feature Passed (3 minutes, 3 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-restart-scenarios-test-hard Passed (3 minutes, 34 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-restart-scenarios-test-none Passed (3 minutes, 25 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-restart-scenarios-test-resyn Passed (3 minutes, 34 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-tests Passed (3 minutes, 31 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-16-dot-04-validate-dirty-db-test Passed (2 minutes, 35 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-block-log-util-test Passed (4 minutes, 49 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-build Passed (9 minutes, 50 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-db-modes-test Passed (3 minutes, 29 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-distributed-transactions-tes Passed (3 minutes, 18 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-launcher-test Passed (1 minute, 30 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-nodeos-protocol-feature-test Passed (2 minutes, 13 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-nodeos-run-test Passed (3 minutes, 5 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-nodeos-run-test-mongodb Passed (3 minutes, 43 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-nodeos-sanity-test Passed (2 minutes, 29 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-p2p-dawn515-test Passed (2 minutes, 25 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-package-builder Passed (56 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-producer-preactivate-feature Passed (1 minute, 42 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-restart-scenarios-test-hard Passed (3 minutes, 39 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-restart-scenarios-test-none Passed (3 minutes, 30 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-restart-scenarios-test-resyn Passed (3 minutes, 26 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-tests Passed (3 minutes, 40 seconds)
Details
buildkite/eosio/ubuntu-ubuntu-18-dot-04-validate-dirty-db-test Passed (54 seconds)
Details
@spoonincode spoonincode deleted the webauthn branch Jun 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.