mirror of
https://github.com/Yubico/yubikey-val.git
synced 2024-11-29 09:24:12 +01:00
168 lines
5.7 KiB
Plaintext
168 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.
|
|
# 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):
|
|
|
|
{|
|
|
! 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:
|
|
|
|
{|
|
|
! 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:
|
|
|
|
{|
|
|
! 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. |