mirror of
https://github.com/Yubico/yubikey-val.git
synced 2024-11-29 00:24:13 +01:00
213 lines
5.7 KiB
Plaintext
213 lines
5.7 KiB
Plaintext
== Validation Protocol Version 2.0
|
|
|
|
=== Introduction
|
|
|
|
All requests are HTTP GET requests. As such, all parameters must be
|
|
properly URL encoded. In particular, some base64 characters (such as
|
|
"+") in the value fields needs to be escaped.
|
|
|
|
Each response sent by the server is signed. To verify that the
|
|
response has not been tampered with, clients either verify the HMAC
|
|
signature or use HTTPS connections (and verify the server
|
|
certificate).
|
|
|
|
=== Generating signatures
|
|
|
|
The protocol uses HMAC-SHA-1 signatures. The HMAC key to use is the
|
|
client API key.
|
|
|
|
Generate the signature over the parameters in the message. Each
|
|
message contains a set of key/value pairs, and the signature is always
|
|
over the entire set (excluding the signature itself), and sorted in
|
|
alphabetical order of the keys. More precisely, to generate a message
|
|
signature do:
|
|
|
|
* Alphabetically sort the set of key/value pairs by key order.
|
|
* Construct a single line with each ordered key/value pair concatenated using '&', and each key and value contatenated with '='. Do not add any linebreaks. Do not add whitespace. For example: `a=2&b=1&c=3`.
|
|
* Apply the HMAC-SHA-1 algorithm on the line as an octet string using the API key as key (remember to base64decode the API key obtained from Yubico).
|
|
* Base 64 encode the resulting value according to RFC 4648, for example, `t2ZMtKeValdA+H0jVpj3LIichn4=`.
|
|
* Append the value under key 'h' to the message.
|
|
|
|
=== Verifying signatures
|
|
|
|
To verify a signature on a response message, follow the same procedure
|
|
that was used to sign the response message and compare the signature
|
|
in the response to the signature you generated. If the signature
|
|
values are equal, the signature is correct. Make sure you remove the
|
|
signature itself from the values you generate the signature over for
|
|
verification. If the incoming message is
|
|
|
|
b=1&a=2&c=3&h=V5FkMYr9GCG9tQA9ihuuybWl99U=
|
|
|
|
|
|
make sure to remove h before verifying:
|
|
|
|
b=1&a=2&c=3
|
|
|
|
Don't forget to sort the key/value pairs.
|
|
|
|
=== Verification
|
|
|
|
There is one call to verify YubiKey OTPs: verify.
|
|
|
|
The verify call lets you check whether an OTP is valid. Since the OTP
|
|
itself contains identification information, all you have to do is to
|
|
send the OTP.
|
|
|
|
To avoid cut'n'paste attacks, the client MUST verify that the "otp" in
|
|
the response is the same as the "otp" supplied in the request.
|
|
|
|
=== Request
|
|
|
|
Construct an HTTP GET call to
|
|
|
|
http://api.yubico.com/wsapi/2.0/verify
|
|
|
|
with the following parameters (note that this request need not be signed):
|
|
|
|
[options="header"]
|
|
|===
|
|
| parameter | type | required | purpose
|
|
|
|
| id
|
|
| string
|
|
| Yes
|
|
| Specifies the requestor so that the end-point can retrieve correct shared secret for signing the response.
|
|
|
|
|otp
|
|
| string
|
|
| Yes
|
|
| The OTP from the YubiKey.
|
|
|
|
| h
|
|
| string
|
|
| No
|
|
| The optional HMAC-SHA1 signature for the request.
|
|
|
|
| timestamp
|
|
| string
|
|
| No
|
|
| Timestamp=1 requests timestamp and session counter information in the response
|
|
|
|
| nonce
|
|
| string
|
|
| Yes
|
|
| A 16 to 40 character long string with random unique data
|
|
|
|
| sl
|
|
| string
|
|
| No
|
|
| A value 0 to 100 indicating percentage of syncing required by client, or strings "fast" or "secure" to use server-configured values; if absent, let the server decide
|
|
|
|
| timeout
|
|
| integer
|
|
| No
|
|
| Number of seconds to wait for sync responses; if absent, let the server decide
|
|
|===
|
|
|
|
An example request:
|
|
|
|
http://api.yubico.com/wsapi/2.0/verify?otp=vvvvvvcucrlcietctckflvnncdgckubflugerlnr&id=87&timeout=8&sl=50&nonce=askjdnkajsndjkasndkjsnad
|
|
|
|
And if you require additional information on timestamp and session
|
|
counters:
|
|
|
|
http://api.yubico.com/wsapi/2.0/verify?id=87&otp=vvvvvvcucrlcietctckflvnncdgckubflugerlnr&timeout=8&sl=50&nonce=askjdnkajsndjkasndkjsnad×tamp=1
|
|
|
|
|
|
=== Response
|
|
|
|
The verification response tells you whether the OTP is valid. The
|
|
response has the following values:
|
|
|
|
[options="header"]
|
|
|===
|
|
|parameter | type | purpose
|
|
|
|
|otp
|
|
|string
|
|
|The OTP from the YubiKey, from request
|
|
|
|
|nonce
|
|
|string
|
|
|Random unique data, from request
|
|
|
|
|h
|
|
|string (base64)
|
|
|Signature as described above.
|
|
|
|
|t
|
|
|time stamp
|
|
|Timestamp in UTC
|
|
|
|
|status
|
|
|string
|
|
|The status of the operation, see below
|
|
|
|
|timestamp
|
|
|string
|
|
|YubiKey internal timestamp value when key was pressed
|
|
|
|
|sessioncounter
|
|
|string
|
|
|YubiKey internal usage counter when key was pressed
|
|
|
|
|sessionuse
|
|
|string
|
|
|YubiKey internal session usage counter when key was pressed
|
|
|
|
|sl
|
|
|integer
|
|
|percentage of external validation server that replied successfully (0 to 100)
|
|
|===
|
|
|
|
These are the possible "status" values in a verify response:
|
|
|
|
[options="header"]
|
|
|===
|
|
| name | meaning
|
|
|
|
| OK
|
|
| The OTP is valid.
|
|
|
|
| BAD_OTP
|
|
| The OTP is invalid format.
|
|
|
|
| REPLAYED_OTP
|
|
| The OTP has already been seen by the service.
|
|
|
|
| BAD_SIGNATURE
|
|
| The HMAC signature verification failed.
|
|
|
|
| MISSING_PARAMETER
|
|
| The request lacks a parameter.
|
|
|
|
| NO_SUCH_CLIENT
|
|
| The request id does not exist.
|
|
|
|
| OPERATION_NOT_ALLOWED
|
|
| The request id is not allowed to verify OTPs.
|
|
|
|
| BACKEND_ERROR
|
|
| Unexpected error in our server. Please contact us if you see this error.
|
|
|
|
| NOT_ENOUGH_ANSWERS
|
|
| Server could not get requested number of syncs during before timeout
|
|
|
|
| REPLAYED_REQUEST
|
|
| Server has seen the OTP/Nonce combination before
|
|
|===
|
|
|
|
=== Changes since version 1.1
|
|
|
|
The verify URL has changed. In the request, the new required field
|
|
"nonce" were added, and the new optional fields "sl" and "timeout" are
|
|
added. In the response, the new fields "otp", "nonce", and "sl" are
|
|
added. The status codes NOT_ENOUGH_ANSWERS and REPLAYED_REQUEST were
|
|
added.
|
|
|
|
Since both the URL and required fields has changed, version 2.0 is not
|
|
backwards compatible with version 1.1 or version 1.0. However,
|
|
because version 2.0 use a different URL than version 1.x, the server
|
|
may support both version 1.x and version 2.0 clients at the same time.
|