diff --git a/common/defs/webauthn/apps/binance.png b/common/defs/webauthn/apps/binance.png index e9b00051f..3b87e3d6d 100644 Binary files a/common/defs/webauthn/apps/binance.png and b/common/defs/webauthn/apps/binance.png differ diff --git a/common/defs/webauthn/apps/bitbucket.png b/common/defs/webauthn/apps/bitbucket.png index d8307c4df..698eaed00 100644 Binary files a/common/defs/webauthn/apps/bitbucket.png and b/common/defs/webauthn/apps/bitbucket.png differ diff --git a/common/defs/webauthn/apps/bitfinex.png b/common/defs/webauthn/apps/bitfinex.png index 80b352983..fd3d6f537 100644 Binary files a/common/defs/webauthn/apps/bitfinex.png and b/common/defs/webauthn/apps/bitfinex.png differ diff --git a/common/defs/webauthn/apps/dashlane.png b/common/defs/webauthn/apps/dashlane.png index cfb5c115d..7341306df 100644 Binary files a/common/defs/webauthn/apps/dashlane.png and b/common/defs/webauthn/apps/dashlane.png differ diff --git a/common/defs/webauthn/apps/dropbox.png b/common/defs/webauthn/apps/dropbox.png index c2ef266d5..5e5ece1e3 100644 Binary files a/common/defs/webauthn/apps/dropbox.png and b/common/defs/webauthn/apps/dropbox.png differ diff --git a/common/defs/webauthn/apps/duo.png b/common/defs/webauthn/apps/duo.png index ec31b1a6e..4a3da92a8 100644 Binary files a/common/defs/webauthn/apps/duo.png and b/common/defs/webauthn/apps/duo.png differ diff --git a/common/defs/webauthn/apps/fastmail.png b/common/defs/webauthn/apps/fastmail.png index 1ef1233be..98fc87cf5 100644 Binary files a/common/defs/webauthn/apps/fastmail.png and b/common/defs/webauthn/apps/fastmail.png differ diff --git a/common/defs/webauthn/apps/fedora.png b/common/defs/webauthn/apps/fedora.png index d01c272d6..cbf3a2a96 100644 Binary files a/common/defs/webauthn/apps/fedora.png and b/common/defs/webauthn/apps/fedora.png differ diff --git a/common/defs/webauthn/apps/gandi.png b/common/defs/webauthn/apps/gandi.png index 724e558f0..4493c7fba 100644 Binary files a/common/defs/webauthn/apps/gandi.png and b/common/defs/webauthn/apps/gandi.png differ diff --git a/common/defs/webauthn/apps/github.png b/common/defs/webauthn/apps/github.png index 773f69530..9182e3bb2 100644 Binary files a/common/defs/webauthn/apps/github.png and b/common/defs/webauthn/apps/github.png differ diff --git a/common/defs/webauthn/apps/gitlab.png b/common/defs/webauthn/apps/gitlab.png index 5c32dddaa..d21e6b462 100644 Binary files a/common/defs/webauthn/apps/gitlab.png and b/common/defs/webauthn/apps/gitlab.png differ diff --git a/common/defs/webauthn/apps/google.png b/common/defs/webauthn/apps/google.png index de5a29a17..9e32553b3 100644 Binary files a/common/defs/webauthn/apps/google.png and b/common/defs/webauthn/apps/google.png differ diff --git a/common/defs/webauthn/apps/keeper.png b/common/defs/webauthn/apps/keeper.png index ab934e235..476205bdb 100644 Binary files a/common/defs/webauthn/apps/keeper.png and b/common/defs/webauthn/apps/keeper.png differ diff --git a/common/defs/webauthn/apps/lastpass.png b/common/defs/webauthn/apps/lastpass.png index 2eb382d5d..6dc3d7793 100644 Binary files a/common/defs/webauthn/apps/lastpass.png and b/common/defs/webauthn/apps/lastpass.png differ diff --git a/common/defs/webauthn/apps/login.gov.png b/common/defs/webauthn/apps/login.gov.png index a33cb5ace..517daf919 100644 Binary files a/common/defs/webauthn/apps/login.gov.png and b/common/defs/webauthn/apps/login.gov.png differ diff --git a/common/defs/webauthn/apps/microsoft.png b/common/defs/webauthn/apps/microsoft.png index 44e0e3a93..b0cc39265 100644 Binary files a/common/defs/webauthn/apps/microsoft.png and b/common/defs/webauthn/apps/microsoft.png differ diff --git a/common/defs/webauthn/apps/mojeid.png b/common/defs/webauthn/apps/mojeid.png index d41338cc8..e9506894a 100644 Binary files a/common/defs/webauthn/apps/mojeid.png and b/common/defs/webauthn/apps/mojeid.png differ diff --git a/common/defs/webauthn/apps/slushpool.png b/common/defs/webauthn/apps/slushpool.png index 2cbd58791..e51c2e940 100644 Binary files a/common/defs/webauthn/apps/slushpool.png and b/common/defs/webauthn/apps/slushpool.png differ diff --git a/common/defs/webauthn/apps/stripe.png b/common/defs/webauthn/apps/stripe.png index 351d67723..31def860f 100644 Binary files a/common/defs/webauthn/apps/stripe.png and b/common/defs/webauthn/apps/stripe.png differ diff --git a/common/defs/webauthn/apps/u2f.bin.coffee.json b/common/defs/webauthn/apps/u2f.bin.coffee.json index 4be50c62d..933fd7f1b 100644 --- a/common/defs/webauthn/apps/u2f.bin.coffee.json +++ b/common/defs/webauthn/apps/u2f.bin.coffee.json @@ -1,4 +1,5 @@ { "label": "u2f.bin.coffee", - "u2f": ["1b3c16dd2f7c46e2b4c289dc16746bcc60dfcf0fb818e13215526e1408e7f468"] + "u2f": ["1b3c16dd2f7c46e2b4c289dc16746bcc60dfcf0fb818e13215526e1408e7f468"], + "demo": true } diff --git a/common/defs/webauthn/apps/webauthn.bin.coffee.json b/common/defs/webauthn/apps/webauthn.bin.coffee.json index 6542db923..ac1d7c54e 100644 --- a/common/defs/webauthn/apps/webauthn.bin.coffee.json +++ b/common/defs/webauthn/apps/webauthn.bin.coffee.json @@ -1,4 +1,5 @@ { "label": "webauthn.bin.coffee", - "webauthn": ["webauthn.bin.coffee"] + "webauthn": ["webauthn.bin.coffee"], + "demo": true } diff --git a/common/defs/webauthn/apps/webauthn.io.json b/common/defs/webauthn/apps/webauthn.io.json index 70ec5929c..477bc03fd 100644 --- a/common/defs/webauthn/apps/webauthn.io.json +++ b/common/defs/webauthn/apps/webauthn.io.json @@ -1,4 +1,5 @@ { "label": "WebAuthn.io", - "webauthn": ["webauthn.io"] + "webauthn": ["webauthn.io"], + "demo": true } diff --git a/common/defs/webauthn/apps/webauthn.me.json b/common/defs/webauthn/apps/webauthn.me.json index 212f0e288..e552264db 100644 --- a/common/defs/webauthn/apps/webauthn.me.json +++ b/common/defs/webauthn/apps/webauthn.me.json @@ -1,4 +1,5 @@ { "label": "WebAuthn.me", - "webauthn": ["webauthn.me"] + "webauthn": ["webauthn.me"], + "demo": true } diff --git a/common/defs/webauthn/apps/yubico-demo.json b/common/defs/webauthn/apps/yubico-demo.json index 34f3a25f1..032a01586 100644 --- a/common/defs/webauthn/apps/yubico-demo.json +++ b/common/defs/webauthn/apps/yubico-demo.json @@ -1,4 +1,5 @@ { "label": "demo.yubico.com", - "webauthn": ["demo.yubico.com"] + "webauthn": ["demo.yubico.com"], + "demo": true } diff --git a/common/tools/coin_info.py b/common/tools/coin_info.py index 13fea7954..7af79198c 100755 --- a/common/tools/coin_info.py +++ b/common/tools/coin_info.py @@ -197,9 +197,9 @@ def validate_btc(coin): def _load_btc_coins(): - """Load btc-like coins from `coins/*.json`""" + """Load btc-like coins from `bitcoin/*.json`""" coins = [] - for filename in glob.glob(os.path.join(DEFS_DIR, "coins", "*.json")): + for filename in glob.glob(os.path.join(DEFS_DIR, "bitcoin", "*.json")): coin = load_json(filename) coin.update( name=coin["coin_label"], @@ -259,6 +259,20 @@ def _load_misc(): return others +def _load_fido_apps(): + """Load btc-like coins from `coins/*.json`""" + apps = [] + for filename in glob.glob(os.path.join(DEFS_DIR, "webauthn", "apps", "*.json")): + app_name = os.path.basename(filename)[:-5] + app = load_json(filename) + app.update( + key=app_name, + ) + apps.append(app) + + return apps + + # ====== support info ====== RELEASES_URL = "https://beta-wallet.trezor.io/data/firmware/{}/releases.json" @@ -559,6 +573,11 @@ def coin_info(): return all_coins +def fido_info(): + """Returns info about known FIDO/U2F apps.""" + return _load_fido_apps() + + def search(coins, keyword): kwl = keyword.lower() if isinstance(coins, CoinsInfo): diff --git a/common/tools/cointool.py b/common/tools/cointool.py index 804819559..15408ef60 100755 --- a/common/tools/cointool.py +++ b/common/tools/cointool.py @@ -168,8 +168,11 @@ def find_collisions(coins, field): """Detects collisions in a given field. Returns buckets of colliding coins.""" collisions = defaultdict(list) for coin in coins: - value = coin[field] - collisions[value].append(coin) + values = coin[field] + if not isinstance(values, list): + values = [values] + for value in values: + collisions[value].append(coin) return {k: v for k, v in collisions.items() if len(v) > 1} @@ -473,6 +476,64 @@ def check_segwit(coins): return True +FIDO_KNOWN_KEYS = frozenset( + ("key", "u2f", "webauthn", "label", "use_sign_count", "demo") +) + + +def check_fido(apps): + check_passed = True + + uf2_hashes = find_collisions((a for a in apps if "u2f" in a), "u2f") + for key, bucket in uf2_hashes.items(): + bucket_str = ", ".join(app["key"] for app in bucket) + u2f_hash_str = "colliding U2F hash " + crayon(None, key, bold=True) + ":" + print_log(logging.ERROR, u2f_hash_str, bucket_str) + check_passed = False + + webauthn_domains = find_collisions((a for a in apps if "webauthn" in a), "webauthn") + for key, bucket in webauthn_domains.items(): + bucket_str = ", ".join(app["key"] for app in bucket) + webauthn_str = "colliding WebAuthn domain " + crayon(None, key, bold=True) + ":" + print_log(logging.ERROR, webauthn_str, bucket_str) + check_passed = False + + for app in apps: + if "label" not in app: + print_log(logging.ERROR, app["key"], ": missing label") + check_passed = False + + if not app.get("u2f") and not app.get("webauthn"): + print_log(logging.ERROR, app["key"], ": no U2F nor WebAuthn addresses") + check_passed = False + + unknown_keys = set(app.keys()) - FIDO_KNOWN_KEYS + if unknown_keys: + print_log(logging.ERROR, app["key"], ": unrecognized keys:", unknown_keys) + + # check icons + icon_file = app["key"].lower() + ".png" + try: + icon = Image.open( + os.path.join(coin_info.DEFS_DIR, "webauthn", "apps", icon_file) + ) + except Exception: + if app.get("demo"): + log_level = logging.WARNING + else: + log_level = logging.ERROR + check_passed = False + print_log(log_level, app["key"], ": failed to open icon file", icon_file) + continue + + if icon.size != (128, 128) or icon.mode != "RGBA": + print_log( + logging.ERROR, app["key"], ": bad icon format (must be RGBA 128x128)" + ) + check_passed = False + return check_passed + + # ====== coindefs generators ====== @@ -638,6 +699,10 @@ def check(backend, icons, show_duplicates): if not check_key_uniformity(coinlist): all_checks_passed = False + print("Checking FIDO app definitions...") + if not check_fido(coin_info.fido_info()): + all_checks_passed = False + if not all_checks_passed: print("Some checks failed.") sys.exit(1) @@ -674,7 +739,7 @@ def dump( exclude_tokens, device, ): - """Dump coin data in JSON format + """Dump coin data in JSON format. This file is structured the same as the internal data. That is, top-level object is a dict with keys: 'bitcoin', 'eth', 'erc20', 'nem' and 'misc'. Value for each