def test_generates_options_with_defaults(
            self, token_bytes_mock: MagicMock) -> None:
        token_bytes_mock.return_value = b"12345"

        options = generate_registration_options(
            rp_id="example.com",
            rp_name="Example Co",
            user_id="ABAV6QWPBEY9WOTOA1A4",
            user_name="lee",
        )

        assert options.rp == PublicKeyCredentialRpEntity(
            id="example.com",
            name="Example Co",
        )
        assert options.challenge == b"12345"
        assert options.user == PublicKeyCredentialUserEntity(
            id=b"ABAV6QWPBEY9WOTOA1A4",
            name="lee",
            display_name="lee",
        )
        assert options.pub_key_cred_params[0] == PublicKeyCredentialParameters(
            type="public-key",
            alg=COSEAlgorithmIdentifier.ECDSA_SHA_256,
        )
        assert options.timeout == 60000
        assert options.exclude_credentials == []
        assert options.authenticator_selection is None
        assert options.attestation == AttestationConveyancePreference.NONE
示例#2
0
    def get_challenge(self, *args, **kwargs) -> Challenge:
        # clear session variables prior to starting a new registration
        self.request.session.pop("challenge", None)
        stage: AuthenticateWebAuthnStage = self.executor.current_stage
        user = self.get_pending_user()

        # library accepts none so we store null in the database, but if there is a value
        # set, cast it to string to ensure it's not a django class
        authenticator_attachment = stage.authenticator_attachment
        if authenticator_attachment:
            authenticator_attachment = str(authenticator_attachment)

        registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
            rp_id=get_rp_id(self.request),
            rp_name=self.request.tenant.branding_title,
            user_id=user.uid,
            user_name=user.username,
            user_display_name=user.name,
            authenticator_selection=AuthenticatorSelectionCriteria(
                resident_key=str(stage.resident_key_requirement),
                user_verification=str(stage.user_verification),
                authenticator_attachment=authenticator_attachment,
            ),
        )

        self.request.session["challenge"] = registration_options.challenge
        return AuthenticatorWebAuthnChallenge(
            data={
                "type": ChallengeTypes.NATIVE.value,
                "registration": loads(options_to_json(registration_options)),
            })
示例#3
0
    def test_converts_options_to_JSON(self) -> None:
        options = generate_registration_options(
            rp_id="example.com",
            rp_name="Example Co",
            user_id="ABAV6QWPBEY9WOTOA1A4",
            user_name="lee",
            user_display_name="Lee",
            attestation=AttestationConveyancePreference.DIRECT,
            authenticator_selection=AuthenticatorSelectionCriteria(
                authenticator_attachment=AuthenticatorAttachment.PLATFORM,
                resident_key=ResidentKeyRequirement.REQUIRED,
            ),
            challenge=b"1234567890",
            exclude_credentials=[
                PublicKeyCredentialDescriptor(id=b"1234567890"),
            ],
            supported_pub_key_algs=[COSEAlgorithmIdentifier.ECDSA_SHA_512],
            timeout=120000,
        )

        output = options_to_json(options)

        assert json.loads(output) == {
            "rp": {
                "name": "Example Co",
                "id": "example.com"
            },
            "user": {
                "id": "QUJBVjZRV1BCRVk5V09UT0ExQTQ",
                "name": "lee",
                "displayName": "Lee",
            },
            "challenge": "MTIzNDU2Nzg5MA",
            "pubKeyCredParams": [{
                "type": "public-key",
                "alg": -36
            }],
            "timeout": 120000,
            "excludeCredentials": [{
                "type": "public-key",
                "id": "MTIzNDU2Nzg5MA"
            }],
            "authenticatorSelection": {
                "authenticatorAttachment": "platform",
                "residentKey": "required",
                "requireResidentKey": True,
                "userVerification": "preferred",
            },
            "attestation": "direct",
        }
示例#4
0
文件: user.py 项目: janheise/zentral
 def get(self, request, *args, **kwargs):
     credentials = []
     for user_device in request.user.userwebauthn_set.all():
         credentials.append(PublicKeyCredentialDescriptor(id=user_device.get_key_handle_bytes()))
     registration_options = json.loads(
         options_to_json(
             generate_registration_options(
                 rp_id=zentral_settings["api"]["fqdn"],
                 rp_name="Zentral",
                 exclude_credentials=credentials,
                 user_id=str(request.user.pk),
                 user_name=request.user.username,
             )
         )
     )
     request.session["webauthn_challenge"] = registration_options
     return super().get(request, *args, **kwargs)
示例#5
0
def get_credential_options(user, *, challenge, rp_name, rp_id):
    """
    Returns a dictionary of options for credential creation
    on the client side.
    """
    _authenticator_selection = AuthenticatorSelectionCriteria()
    _authenticator_selection.user_verification = UserVerificationRequirement.DISCOURAGED
    options = pywebauthn.generate_registration_options(
        rp_id=rp_id,
        rp_name=rp_name,
        user_id=str(user.id),
        user_name=user.username,
        user_display_name=user.name or user.username,
        challenge=challenge,
        attestation=AttestationConveyancePreference.NONE,
        authenticator_selection=_authenticator_selection,
    )
    return json.loads(options_to_json(options))
    def test_generates_options_with_custom_values(self) -> None:
        options = generate_registration_options(
            rp_id="example.com",
            rp_name="Example Co",
            user_id="ABAV6QWPBEY9WOTOA1A4",
            user_name="lee",
            user_display_name="Lee",
            attestation=AttestationConveyancePreference.DIRECT,
            authenticator_selection=AuthenticatorSelectionCriteria(
                authenticator_attachment=AuthenticatorAttachment.PLATFORM,
                resident_key=ResidentKeyRequirement.REQUIRED,
            ),
            challenge=b"1234567890",
            exclude_credentials=[
                PublicKeyCredentialDescriptor(id=b"1234567890"),
            ],
            supported_pub_key_algs=[COSEAlgorithmIdentifier.ECDSA_SHA_512],
            timeout=120000,
        )

        assert options.rp == PublicKeyCredentialRpEntity(id="example.com",
                                                         name="Example Co")
        assert options.challenge == b"1234567890"
        assert options.user == PublicKeyCredentialUserEntity(
            id=b"ABAV6QWPBEY9WOTOA1A4",
            name="lee",
            display_name="Lee",
        )
        assert options.pub_key_cred_params[0] == PublicKeyCredentialParameters(
            type="public-key",
            alg=COSEAlgorithmIdentifier.ECDSA_SHA_512,
        )
        assert options.timeout == 120000
        assert options.exclude_credentials == [
            PublicKeyCredentialDescriptor(id=b"1234567890")
        ]
        assert options.authenticator_selection == AuthenticatorSelectionCriteria(
            authenticator_attachment=AuthenticatorAttachment.PLATFORM,
            resident_key=ResidentKeyRequirement.REQUIRED,
            require_resident_key=True,
        )
        assert options.attestation == AttestationConveyancePreference.DIRECT
示例#7
0
    def test_includes_optional_value_when_set(self) -> None:
        options = generate_registration_options(
            rp_id="example.com",
            rp_name="Example Co",
            user_id="ABAV6QWPBEY9WOTOA1A4",
            user_name="lee",
            exclude_credentials=[
                PublicKeyCredentialDescriptor(
                    id=b"1234567890",
                    transports=[AuthenticatorTransport.USB],
                )
            ],
        )

        output = options_to_json(options)

        assert json.loads(output)["excludeCredentials"] == [{
            "id":
            "MTIzNDU2Nzg5MA",
            "transports": ["usb"],
            "type":
            "public-key",
        }]
示例#8
0
    AuthenticatorSelectionCriteria,
    PublicKeyCredentialDescriptor,
    ResidentKeyRequirement,
    RegistrationCredential,
)

################
#
# Examples of using webauthn for registration ceremonies
#
################

# Simple Options
simple_registration_options = generate_registration_options(
    rp_id="example.com",
    rp_name="Example Co",
    user_id="12345",
    user_name="bob",
)

print("\n[Registration Options - Simple]")
print(options_to_json(simple_registration_options))

# Complex Options
complex_registration_options = generate_registration_options(
    rp_id="example.com",
    rp_name="Example Co",
    user_id="ABAV6QWPBEY9WOTOA1A4",
    user_name="lee",
    user_display_name="Lee",
    attestation=AttestationConveyancePreference.DIRECT,
    authenticator_selection=AuthenticatorSelectionCriteria(