How to use webauthn - 10 common examples

To help you get started, we’ve selected a few webauthn examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github pypa / warehouse / tests / unit / utils / test_webauthn.py View on Github external
def test_verify_registration_response_failure(monkeypatch):
    response_obj = pretend.stub(
        verify=pretend.raiser(pywebauthn.webauthn.RegistrationRejectedException)
    )
    response_cls = pretend.call_recorder(lambda *a, **kw: response_obj)
    monkeypatch.setattr(pywebauthn, "WebAuthnRegistrationResponse", response_cls)

    with pytest.raises(webauthn.RegistrationRejectedException):
        webauthn.verify_registration_response(
            {}, "not_a_real_challenge", rp_id="fake_rp_id", origin="fake_origin"
        )
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
if not subject.get_attributes_for_oid(COMMON_NAME):
                    raise RegistrationRejectedException(
                        'Attestation certificate must have subject-CN.')

                extensions = x509_att_cert.extensions

                #   * If the related attestation root certificate is used
                #     for multiple authenticator models, the Extension OID
                #     1.3.6.1.4.1.45724.1.1.4 (id-fido-gen-ce-aaguid) MUST
                #     be present, containing the AAGUID as a 16-byte OCTET
                #     STRING. The extension MUST NOT be marked as critical.
                try:
                    oid = x509.ObjectIdentifier('1.3.6.1.4.1.45724.1.1.4')
                    aaguid_ext = extensions.get_extension_for_oid(oid)
                    if aaguid_ext.value.value[2:] != aaguid:
                        raise RegistrationRejectedException(
                            'Attestation certificate AAGUID must match '
                            'authenticator data.')
                    if aaguid_ext.critical:
                        raise RegistrationRejectedException(
                            "Attestation certificate's "
                            "'id-fido-gen-ce-aaguid' extension must not be "
                            "marked critical.")
                except x509.ExtensionNotFound:
                    pass  # Optional extension

                #   * The Basic Constraints extension MUST have the CA
                #     component set to false.
                bc_extension = extensions.get_extension_for_class(
                    x509.BasicConstraints)
                if not bc_extension or bc_extension.value.ca:
                    raise RegistrationRejectedException(
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
if 'x5c' not in att_stmt or 'sig' not in att_stmt:
                raise RegistrationRejectedException(
                    'Attestation statement must be a valid CBOR object.')

            # Step 2.
            #
            # Let attCert be the value of the first element of x5c. Let certificate
            # public key be the public key conveyed by attCert. If certificate public
            # key is not an Elliptic Curve (EC) public key over the P-256 curve,
            # terminate this algorithm and return an appropriate error.
            att_cert = att_stmt.get('x5c')[0]
            x509_att_cert = load_der_x509_certificate(att_cert,
                                                      default_backend())
            certificate_public_key = x509_att_cert.public_key()
            if not isinstance(certificate_public_key.curve, SECP256R1):
                raise RegistrationRejectedException(
                    'Bad certificate public key.')

            # Step 3.
            #
            # Extract the claimed rpIdHash from authenticatorData, and the
            # claimed credentialId and credentialPublicKey from
            # authenticatorData.attestedCredentialData.

            # The credential public key encoded in COSE_Key format, as defined in Section 7
            # of [RFC8152], using the CTAP2 canonical CBOR encoding form. The COSE_Key-encoded
            # credential public key MUST contain the optional "alg" parameter and MUST NOT
            # contain any other optional parameters. The "alg" parameter MUST contain a
            # COSEAlgorithmIdentifier value. The encoded credential public key MUST also
            # contain any additional required parameters stipulated by the relevant key type
            # specification, i.e., required for the key type "kty" and algorithm "alg" (see
            # Section 8 of [RFC8152]).
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
#
            # Assess the attestation trustworthiness using the outputs of the
            # verification procedure in step 14, as follows:
            #
            #     * If self attestation was used, check if self attestation is
            #       acceptable under Relying Party policy.
            #     * If ECDAA was used, verify that the identifier of the
            #       ECDAA-Issuer public key used is included in the set of
            #       acceptable trust anchors obtained in step 15.
            #     * Otherwise, use the X.509 certificates returned by the
            #       verification procedure to verify that the attestation
            #       public key correctly chains up to an acceptable root
            #       certificate.
            if attestation_type == AT_SELF_ATTESTATION:
                if not self.self_attestation_permitted:
                    raise RegistrationRejectedException(
                        'Self attestation is not permitted.')
            elif attestation_type == AT_ATTESTATION_CA:
                raise NotImplementedError(
                    'Attestation CA attestation type is not currently supported.'
                )
            elif attestation_type == AT_ECDAA:
                raise NotImplementedError(
                    'ECDAA attestation type is not currently supported.')
            elif attestation_type == AT_BASIC:
                if self.trusted_attestation_cert_required:
                    if not _is_trusted_attestation_cert(
                            trust_path, trust_anchors):
                        raise RegistrationRejectedException(
                            'Untrusted attestation certificate.')
            elif attestation_type == AT_NONE:
                pass
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
# identifier values in the clientExtensionResults and the extensions
            # in authData MUST be also be present as extension identifier values
            # in the extensions member of options, i.e., no extensions are
            # present that were not requested. In the general case, the meaning
            # of "are as expected" is specific to the Relying Party and which
            # extensions are in use.
            registration_client_extensions = self.registration_response.get(
                'registrationClientExtensions')
            if registration_client_extensions:
                rce = json.loads(registration_client_extensions)
                if not _verify_client_extensions(rce, self.expected_registration_client_extensions):
                    raise RegistrationRejectedException(
                        'Unable to verify client extensions.')
                if not _verify_authenticator_extensions(
                        c, self.expected_registration_authenticator_extensions):
                    raise RegistrationRejectedException(
                        'Unable to verify authenticator extensions.')

            # Step 13.
            #
            # Determine the attestation statement format by performing
            # a USASCII case-sensitive match on fmt against the set of
            # supported WebAuthn Attestation Statement Format Identifier
            # values. The up-to-date list of registered WebAuthn
            # Attestation Statement Format Identifier values is maintained
            # in the in the IANA registry of the same name
            # [WebAuthn-Registries].
            if not _verify_attestation_statement_format(fmt):
                raise RegistrationRejectedException(
                    'Unable to verify attestation statement format.')

            # Step 14.
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
extensions = x509_att_cert.extensions

                #   * If the related attestation root certificate is used
                #     for multiple authenticator models, the Extension OID
                #     1.3.6.1.4.1.45724.1.1.4 (id-fido-gen-ce-aaguid) MUST
                #     be present, containing the AAGUID as a 16-byte OCTET
                #     STRING. The extension MUST NOT be marked as critical.
                try:
                    oid = x509.ObjectIdentifier('1.3.6.1.4.1.45724.1.1.4')
                    aaguid_ext = extensions.get_extension_for_oid(oid)
                    if aaguid_ext.value.value[2:] != aaguid:
                        raise RegistrationRejectedException(
                            'Attestation certificate AAGUID must match '
                            'authenticator data.')
                    if aaguid_ext.critical:
                        raise RegistrationRejectedException(
                            "Attestation certificate's "
                            "'id-fido-gen-ce-aaguid' extension must not be "
                            "marked critical.")
                except x509.ExtensionNotFound:
                    pass  # Optional extension

                #   * The Basic Constraints extension MUST have the CA
                #     component set to false.
                bc_extension = extensions.get_extension_for_class(
                    x509.BasicConstraints)
                if not bc_extension or bc_extension.value.ca:
                    raise RegistrationRejectedException(
                        'Attestation certificate must have Basic Constraints '
                        'extension with CA=false.')

                #   * If successful, return attestation type Basic and
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
raise RegistrationRejectedException(
                        'Invalid signature received.')
                except NotImplementedError:
                    raise RegistrationRejectedException(
                        'Unsupported algorithm.')

                #   * Verify that attestnCert meets the requirements in
                #     §8.2.1 Packed attestation statement certificate
                #     requirements.

                # The attestation certificate MUST have the following
                # fields/extensions:
                #   * Version MUST be set to 3 (which is indicated by an
                #     ASN.1 INTEGER with value 2).
                if x509_att_cert.version != x509.Version.v3:
                    raise RegistrationRejectedException(
                        'Invalid attestation certificate version.')

                #   * Subject field MUST be set to:
                subject = x509_att_cert.subject
                COUNTRY_NAME = x509.NameOID.COUNTRY_NAME
                ORGANIZATION_NAME = x509.NameOID.ORGANIZATION_NAME
                ORG_UNIT_NAME = x509.NameOID.ORGANIZATIONAL_UNIT_NAME
                COMMON_NAME = x509.NameOID.COMMON_NAME

                #     * Subject-C: ISO 3166 code specifying the country
                #                  where the Authenticator vendor is
                #                  incorporated
                if not subject.get_attributes_for_oid(COUNTRY_NAME):
                    raise RegistrationRejectedException(
                        'Attestation certificate must have subject-C.')
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
#   * If successful, return attestation type Basic and
                #     attestation trust path x5c.
                attestation_type = AT_BASIC
                trust_path = [x509_att_cert]
            elif 'ecdaaKeyId' in att_stmt:
                # Step 3.
                #
                # If ecdaaKeyId is present, then the attestation type is
                # ECDAA. In this case:
                #   * Verify that sig is a valid signature over the
                #     concatenation of authenticatorData and clientDataHash
                #     using ECDAA-Verify with ECDAA-Issuer public key
                #     identified by ecdaaKeyId (see  [FIDOEcdaaAlgorithm]).
                #   * If successful, return attestation type ECDAA and
                #     attestation trust path ecdaaKeyId.
                raise RegistrationRejectedException(
                    'ECDAA attestation type is not currently supported.')
            else:
                # Step 4.
                #
                # If neither x5c nor ecdaaKeyId is present, self
                # attestation is in use.
                #   * Validate that alg matches the algorithm of the
                #     credentialPublicKey in authenticatorData.
                try:
                    public_key_alg, credential_public_key = _load_cose_public_key(
                        credential_pub_key)
                except COSEKeyException as e:
                    raise RegistrationRejectedException(str(e))

                if public_key_alg != alg:
                    raise RegistrationRejectedException(
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
subject = x509_att_cert.subject
                COUNTRY_NAME = x509.NameOID.COUNTRY_NAME
                ORGANIZATION_NAME = x509.NameOID.ORGANIZATION_NAME
                ORG_UNIT_NAME = x509.NameOID.ORGANIZATIONAL_UNIT_NAME
                COMMON_NAME = x509.NameOID.COMMON_NAME

                #     * Subject-C: ISO 3166 code specifying the country
                #                  where the Authenticator vendor is
                #                  incorporated
                if not subject.get_attributes_for_oid(COUNTRY_NAME):
                    raise RegistrationRejectedException(
                        'Attestation certificate must have subject-C.')

                #     * Subject-O: Legal name of the Authenticator vendor
                if not subject.get_attributes_for_oid(ORGANIZATION_NAME):
                    raise RegistrationRejectedException(
                        'Attestation certificate must have subject-O.')

                #     * Subject-OU: Literal string
                #                   “Authenticator Attestation”
                ou = subject.get_attributes_for_oid(ORG_UNIT_NAME)
                if not ou or ou[0].value != 'Authenticator Attestation':
                    raise RegistrationRejectedException(
                        "Attestation certificate must have subject-OU set to "
                        "'Authenticator Attestation'.")

                #     * Subject-CN: A UTF8String of the vendor’s choosing
                if not subject.get_attributes_for_oid(COMMON_NAME):
                    raise RegistrationRejectedException(
                        'Attestation certificate must have subject-CN.')

                extensions = x509_att_cert.extensions
github duo-labs / py_webauthn / webauthn / webauthn.py View on Github external
'Invalid signature received.')
                except NotImplementedError:
                    raise RegistrationRejectedException(
                        'Unsupported algorithm.')

                #   * If successful, return attestation type Self and empty
                #     attestation trust path.
                attestation_type = AT_SELF_ATTESTATION
                trust_path = []

            return (attestation_type, trust_path, credential_pub_key, cred_id)
        elif fmt == AT_FMT_NONE:
            # `none` - indicates that the Relying Party is not interested in
            # authenticator attestation.
            if not self.none_attestation_permitted:
                raise RegistrationRejectedException(
                    'Authenticator attestation is required.')

            # Step 1.
            #
            # Return attestation type None with an empty trust path.
            attestation_type = AT_NONE
            trust_path = []
            return (attestation_type, trust_path, credential_pub_key, cred_id)
        else:
            raise RegistrationRejectedException('Invalid format.')