.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Authen::WebAuthn 3pm" .TH Authen::WebAuthn 3pm "2022-02-17" "perl v5.32.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Authen::WebAuthn \- A library to add Web Authentication support to server applications .SH "VERSION" .IX Header "VERSION" version 0.001 .SH "SYNOPSIS" .IX Header "SYNOPSIS" This module lets you validate WebAuthn registration and authentication responses. .PP Currently, it does not handle the generation of registration and authentication requests. .PP The transmission of requests and responses from the application server to the user's browser, and interaction with the WebAuthn browser \s-1API\s0 is also out of scope and could be handled by a dedicated \s-1JS\s0 library. .PP To register a new device: .PP .Vb 6 \& # Obtain registration response from web browser \& # Then, \& my $webauthn_rp = Authen::WebAuthn\->new( \& rp_id => "app.example.com", \& origin => "https://app.example.com" \& ); \& \& my $registration_result = eval { \& $webauthn_rp\->validate_registration( \& challenge_b64 => ... , \& requested_uv => ... , \& client_data_json_b64 => ... , \& attestation_object_b64 => ... , \& token_binding_id_b64 => ... , \& ) \& }; \& if ($@) { \& die "Error validating registration: $@"; \& } .Ve .PP To authenticate a user: .PP .Vb 6 \& # Obtain authentication response from web browser \& # Then, \& my $webauthn_rp = Authen::WebAuthn\->new( \& rp_id => "app.example.com", \& origin => "https://app.example.com" \& ); \& \& my $validation_result = eval { \& $webauthn_rp\->validate_assertion( \& challenge_b64 => ..., \& credential_pubkey_b64 => ..., \& stored_sign_count => ..., \& requested_uv => ..., \& client_data_json_b64 => ..., \& authenticator_data_b64 => ..., \& signature_b64 => ..., \& extension_results => ..., \& token_binding_id_b64 => ..., \& ) \& }; \& if ($@) { \& die "Error validating authentication: $@"; \& } .Ve .SH "ATTRIBUTES" .IX Header "ATTRIBUTES" .SS "rp_id" .IX Subsection "rp_id" The identifier of your Relying Party. Usually, this is set to the domain name over which your application is accessed (app.example.com). .SS "origin" .IX Subsection "origin" The origin, as defined by the \s-1HTML\s0 standard, that your Relying Party is expecting to find in registration or authentication responses. This must contain the scheme and port of your application, but no path (http://app.example.com:8080 or https://app.example.com) .SH "METHODS" .IX Header "METHODS" .SS "validate_registration" .IX Subsection "validate_registration" This method validates the registration response emitted by the authenticator. .PP It takes the following named arguments .IP "challenge_b64" 4 .IX Item "challenge_b64" The base64url\-encoded challenge that was submitted to the authenticator .IP "requested_uv" 4 .IX Item "requested_uv" Whether or not the Relying Party required user verification for this operation. Possible values are \f(CW\*(C`required\*(C'\fR, \f(CW\*(C`preferred\*(C'\fR, \f(CW\*(C`discouraged\*(C'\fR. .IP "client_data_json_b64" 4 .IX Item "client_data_json_b64" The base64url\-encoded client data received from the authenticator .IP "attestation_object_b64" 4 .IX Item "attestation_object_b64" The base64url\-encoded attestation object received from the authenticator .IP "token_binding_id_b64" 4 .IX Item "token_binding_id_b64" The base64url\-encoded Token Binding \s-1ID\s0 for the current connection. Usually this comes from a \f(CW\*(C`Sec\-Provided\-Token\-Binding\-ID\*(C'\fR \s-1HTTP\s0 header. If you are not using Token Binding, you can omit this parameter. .PP This method croaks on errors. If the registration was successful, it returns a hashref with the following subkeys: .IP "credential_id" 4 .IX Item "credential_id" The base64url\-encoded credential \s-1ID\s0 for this authenticator .IP "credential_pubkey" 4 .IX Item "credential_pubkey" The base64url\-encoded public key for this authenticator, in \s-1COSE\s0 format .IP "signature_count" 4 .IX Item "signature_count" The initial signature count of this authenticator .PP This information is supposed to be persisted in the Relying Party, usually in some sort of database .SS "validate_assertion" .IX Subsection "validate_assertion" This method validates the registration response emitted by the authenticator. .PP It takes the following named arguments .IP "challenge_b64" 4 .IX Item "challenge_b64" The base64url\-encoded challenge that was submitted to the authenticator .IP "credential_pubkey_b64" 4 .IX Item "credential_pubkey_b64" The base64url\-encoded credential public key corresponding to the received Credential \s-1ID\s0 .IP "stored_sign_count" 4 .IX Item "stored_sign_count" The current signature count in the Relying Party's database. Set it to 0 to disable verification of the signature count .IP "requested_uv" 4 .IX Item "requested_uv" Whether or not the Relying Party required user verification for this operation. Possible values are \f(CW\*(C`required\*(C'\fR, \f(CW\*(C`preferred\*(C'\fR, \f(CW\*(C`discouraged\*(C'\fR. .IP "client_data_json_b64" 4 .IX Item "client_data_json_b64" The base64url\-encoded client data received from the authenticator .IP "authenticator_data_b64" 4 .IX Item "authenticator_data_b64" The base64url\-encoded authenticator data received from the authenticator .IP "signature_b64" 4 .IX Item "signature_b64" The base64url\-encoded signature received from the authenticator .IP "extension_results" 4 .IX Item "extension_results" A hashref containing extension results received from the authenticator .IP "token_binding_id_b64" 4 .IX Item "token_binding_id_b64" The base64url\-encoded Token Binding \s-1ID\s0 for the current connection. Usually this comes from a \f(CW\*(C`Sec\-Provided\-Token\-Binding\-ID\*(C'\fR \s-1HTTP\s0 header. If you are not using Token Binding, you can omit this parameter. .PP This method croaks on errors. If the registration was successful, it returns a hashref with the following subkeys: .IP "signature_count" 4 .IX Item "signature_count" The new signature count, to be updated in the Relying Party's database .SS "convert_raw_ecc_to_cose" .IX Subsection "convert_raw_ecc_to_cose" .Vb 1 \& my $cose_b64 = Authen::WebAuthn::convert_raw_ecc_to_cose($u2f_b64); .Ve .PP This method takes the base64url\-encoded raw \s-1ECC\s0 key (U2F format) and converts it to a base64url\-encoded \s-1COSE\s0 representation. It can be useful for converting existing U2F device registration to WebAuthen device registrations in your Relying Party. .SH "CAVEAT" .IX Header "CAVEAT" This module only supports the \*(L"None\*(R" attestation type at the moment, which means Relying Parties cannot have a strong guarantee of the authenticator's security properties. This makes it possible for users to register weak authenticators. .PP Because of that, is it not recommended to use this module in passwordless authentication scenarios. However, it should be good enough for using security keys as a second factor. .PP This limitation may be addressed in a future version. .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "FIDO::Raw" 4 .IX Item "FIDO::Raw" A library with a similar purpose, based on Yubico's libfido2 .IP "Authen::U2F" 4 .IX Item "Authen::U2F" A library for adding U2F support to server applications .IP "Crypt::U2F::Server" 4 .IX Item "Crypt::U2F::Server" A library for adding U2F support to server applications, based on Yubico's libu2f\-server .SH "AUTHOR" .IX Header "AUTHOR" Maxime Besson .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2022 by Maxime Besson. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.