Skip to main content

CTAP (client-to-authenticator-protocol) device backed by python's keyring library

Project description

PyPi version Python version Code style: Black Read the docs CI workflow

This library provides an implementation of a virtual CTAP2 (client-to-authenticator-protocol) device, which uses the keyring library as its backend.

One may use this implementation as a reference for CTAP2-compatible devices, or to use ones host machine as an authenticator, rather than using an external one.

A common use-case would be to use this library as an authenticator for a webauthn flow, storing keys and retrieving assertions on a machine’s configured keyring.

Supported features are:
  • The make-credential, get-assertion, get-next-assertion and get-info CTAP2 flows

  • The management of keys using the following COSE algorithms: RS1, RS256, PS256, EC256, EdDSA

  • The use of any available keyring as a backend for the created key-pairs (e.g. WinCred, Keychain, …)

  • User presence & verification on OSX and Windows, via Touch-ID and Windows-Hello

  • Storing keys in a secure manner, with no PII (personal-identifying-information) attached to them


Installation

Run the following (on a darwin machine):

$ pip install ctap-keyring-device

Using This Library

Make Credential Flow

from fido2.webauthn import PublicKeyCredentialCreationOptions, PublicKeyCredentialType, PublicKeyCredentialParameters
from ctap_keyring_device.ctap_keyring_device import CtapKeyringDevice
from fido2.client import Fido2Client
from fido2 import cose
import base64

device = CtapKeyringDevice.list_devices()[0]
origin = 'https://rp.pasten.com'
client = Fido2Client(device, origin)

rp = {'id': 'pasten.com', 'name': origin[8:], 'icon': '...'}
user = {'id': 'danny@pasten.io', 'name': 'Danny Shemesh', 'icon': '...', 'displayName': 'Danny Pastanny'}
challenge = base64.b64encode(b'my-challenge')
timeout_ms = 30_000

pub_key_cred_params = [PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, cose.ES256.ALGORITHM)]
options = PublicKeyCredentialCreationOptions(rp, user, challenge, pub_key_cred_params, timeout=timeout_ms)

attestation, client_data = client.make_credential(options)

Get Assertion Flow

from fido2.webauthn import PublicKeyCredentialRequestOptions, PublicKeyCredentialType, \
    PublicKeyCredentialParameters, PublicKeyCredentialDescriptor, UserVerificationRequirement
from ctap_keyring_device.ctap_keyring_device import CtapKeyringDevice
from fido2.client import Fido2Client
from fido2 import cose
import base64

device = CtapKeyringDevice.list_devices()[0]
origin = 'https://rp.pasten.com'
client = Fido2Client(device, origin)

challenge = base64.b64encode(b'my-challenge')
rp = {'id': 'pasten.com', 'name': origin[8:], 'icon': '...'}
credential_id = b'.......'
allow_list = [
    PublicKeyCredentialDescriptor(PublicKeyCredentialType.PUBLIC_KEY, credential_id)
]
timeout_ms = 30_000

pub_key_cred_params = [PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, cose.ES256.ALGORITHM)]
options = PublicKeyCredentialRequestOptions(challenge=challenge, rp_id=rp['id'],
                                            allow_credentials=allow_list, timeout=timeout_ms,
                                            user_verification=UserVerificationRequirement.PREFERRED)
assertions, client_data = client.get_assertion(options)

See examples in ctap-keyring-device/tests.


CTAP Flow Diagrams

Make Credential Flow

Make Credential Flow

Get Assertion Flow

Get Assertion Flow

Security Considerations

Using this library will help one utilize their machine’s keyring as a CTAP2-compliant FIDO authenticator.

Credentials are stores on the configured keyring, which defaults to a sensible implementation, per the platform the code is running on (e.g. keychain on OSX, WinCred on Windows, …)

The make-credentials flow will create a key-pair for signing, using the requested COSE algorithm.

Private keys are encrypted with a random UUID4 as the passphrase, using hazmat’s BestAvailableEncryption.

Credential IDs comprise of <UUID5-of-user-id>_<key-passphrase>, and are sent back to the requesting client; it is assumed that the credential ID is kept in a remote machine, and is always provided in the allow-list of a ctap get-assertion request.

The above allows us to generate and store our keys in a manner that renders key exposure as less risky, due to the key being encrypted; and not storing the user-id directly, making it harder to use the key, even if decrypted.

On top of the mentioned safeguards, one may request the UV (user-verification) option, in order to trigger a 2nd factor before returning an assertion; Touch-ID / Password prompt is used on OSX, and Windows-Hello on Windows.


Making Releases

A CI/CD pipeline is setup on github - once a PR is merged to master, a pre-release will be automatically deployed to github; When a release is tagged, it will be automatically deployed to pypi.


Running Tests

To run the tests locally, install and invoke tox.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ctap-keyring-device-1.0.6.tar.gz (266.8 kB view details)

Uploaded Source

Built Distribution

ctap_keyring_device-1.0.6-py2.py3-none-any.whl (16.7 kB view details)

Uploaded Python 2Python 3

File details

Details for the file ctap-keyring-device-1.0.6.tar.gz.

File metadata

  • Download URL: ctap-keyring-device-1.0.6.tar.gz
  • Upload date:
  • Size: 266.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for ctap-keyring-device-1.0.6.tar.gz
Algorithm Hash digest
SHA256 a44264bb3d30c4ab763e4a3098b136602f873d86b666210d2bb1405b5e0473f6
MD5 5738caf5184542eb9368fc302f9ded54
BLAKE2b-256 c4c55c4ce510d457679c8886229ddbdc2a84969d63e50fe9fb09d6975d8e500e

See more details on using hashes here.

File details

Details for the file ctap_keyring_device-1.0.6-py2.py3-none-any.whl.

File metadata

  • Download URL: ctap_keyring_device-1.0.6-py2.py3-none-any.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for ctap_keyring_device-1.0.6-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 12c08aabd60318bd4223eebd12463e979b8ebfec36c5943059b2eca226ed1427
MD5 48267688de8afa643ecd86f5cd7762fa
BLAKE2b-256 e5e3af7b4655eb93c9458e3aa92a25b2358b4b08e36b05188f4f5bb377508be9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page