1
0
mirror of https://github.com/Yubico/yubikey-val.git synced 2024-11-29 09:24:12 +01:00
yubikey-val/ykval-api.html
2009-10-14 07:43:45 +00:00

227 lines
6.3 KiB
HTML

<h6>Protocol Specification</h6>
<p>All requests are HTTP GETs. As such, all parameters must be
properly URL encoded. In particular, some base64 characters (such as
"+") in the value fields needs to be escaped.</p>
<p>Each response sent by Yubico is signed. To make sure the response
has not been tampered with, you should verify the signature.</p>
<p>To verify a <a name="signatures">signature</a> on a response message, follow
the same procedure that was used to <a href="#generate_sig">sign the
response message</a> and compare the signature in the response to the signature
you generated. If the signature values are equal, the
signature is correct.</p>
Make sure you remove the signature itself from the values you generate
the signature over for verification. If the incoming message is
<pre>
b=1&a=2&c=3&h=V5FkMYr9GCG9tQA9ihuuybWl99U=
</pre>
make sure to remove <code>h</code> before verifying:
<pre>b=1&a=2&c=3 </pre>
<br />
<hr size="1" noshade color="#cccccc">
<br />
<h6 id="generate_sig">Generating signatures</h6>
The Yubico API uses HMAC-SHA1 signatures with 160 bit key lengths
(as defined by <a href="http://www.ietf.org/rfc/rfc3174.txt">RFC
3174</a>). The HMAC key to use is the <a href="#api_key">API key</a>.
<br /><br />
<p>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), sorted in
alphabetical order of the keys.
To generate a message signature:
<ol>
<li>Alphabetically sort the set of key/value pairs by key order.</li>
<li>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: <code>a=2&b=1&c=3</code>.</li>
<li>Apply the signature algorithm to the line's octet string (UTF-8 byte
values according to
<a href="http://www.ietf.org/rfc/rfc3629.txt">RFC 3629</a>) using
the
<a href="#api_key">API key</a> as key.</li>
<li>Base 64 encode the resulting value according to
<a href="http://www.ietf.org/rfc/rfc4648.html">RFC 4648</a>, for
example, <code>t2ZMtKeValdA+H0jVpj3LIichn4=</code>.</li>
<li>Append the value under key <code>h</code> to the message.
</ol>
<br /><br />
<hr size="1" noshade color="#cccccc">
<br />
<h6>Verification</h6>
There is one call to verify YubiKey OTPs: <code>verify</code>.
<br /><br />
<b>verify</b>
The <code>verify</code> 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.
<br /><br />
<hr size="1" noshade color="#cccccc">
<br />
<h6>Request</h6>
Construct an HTTP GET call to
<pre>http://api.yubico.com/wsapi/verify</pre>
with the following parameters (note that this request need not be signed):
<br></br>
<table border="1">
<th>parameter</th><th>type</th><th>required</th><th>purpose</th>
<tr>
<td><code>id</code></td>
<td>string</td>
<td>Yes</td>
<td>Specifies the requestor so that the end-point can retrieve
correct shared secret for signing the response.</td>
</tr>
<tr>
<td><code>otp</code></td>
<td>string</td>
<td>Yes</td>
<td>The OTP from the YubiKey.</td>
</tr>
<tr>
<td><code>timestamp</td>
<td>string</td>
<td>No</td>
<td>Timestamp=1 requests timestamp and session counter information the response</td>
<tr>
<td><code>h</code></td>
<td>string</td>
<td>No</td>
<td>The optional HMAC-SHA1 signature for the request.</td>
</tr>
</table>
<br></br>
An example request (broken into two lines for legibility):
<pre>
http://api.yubico.com/wsapi/verify?otp=vvvvvvcucrlcietctc\
kflvnncdgckubflugerlnr&id=87 </pre>
<br />
And if you require additional information on timestamp and session counters:
<pre>
http://api.yubico.com/wsapi/verify?otp=vvvvvvcucrlcietctc\
kflvnncdgckubflugerlnr&id=87&timestamp=1 </pre>
<br />
<hr size="1" noshade color="#cccccc">
<br />
<h6>Response</h6>
The verification response tells you whether the OTP is valid.
<br></br>
The response has the following values:
<br></br>
<table border=1 width="100%">
<th>parameter</th><th>type</th><th>purpose</th>
<tr>
<td><code>h</code></td>
<td>string (base64)</td>
<td>Signature as <a href="#signatures">described above</a>.</td>
</tr>
<tr>
<td><code>t</code></td>
<td>time stamp</td>
<td>Timestamp in UTC.</td>
</tr>
<tr>
<td><code>status</code></td>
<td>string</td>
<td>The status of the operation. The status are described
in <a href="#verify_return_codes">return codes</a>.</td>
</tr>
<tr>
<td><code>timestamp</code></td>
<td>string</td>
<td>YubiKey internal timestamp value when key was pressed</td>
</tr>
<tr>
<td><code>sessioncounter</code></td>
<td>string</td>
<td>YubiKey internal usage counter when key was pressed</td>
</tr>
<tr>
<td><code>sessionuse</code></td>
<td>string</td>
<td>YubiKey internal session usage counter when key was pressed</td>
</tr>
</table>
<br /><br />
<hr size="1" noshade color="#cccccc">
<br />
<h6 id="verify_return_codes">Return codes</h6>
These are possible <code>status</code> values in a <code>verify</code>
response:
<table border=1 width="100%">
<th>name</th><th>meaning</th>
<tr>
<td><code>OK</code></td>
<td>The OTP is valid.</td>
</tr>
<tr>
<td><code>BAD_OTP</code></td>
<td>The OTP is invalid format.</td>
</tr>
<tr>
<td><code>REPLAYED_OTP</code></td>
<td>The OTP has already been seen by the service.</td>
</tr>
<tr>
<td><code>BAD_SIGNATURE</code></td>
<td>The HMAC signature verification failed.</td>
</tr>
<tr>
<td><code>MISSING_PARAMETER</code></td>
<td>The request lacks a parameter.</td>
</tr>
<tr>
<td><code>NO_SUCH_CLIENT</code></td>
<td>The request <code>id</code> does not exist.</td>
</tr>
<tr>
<td><code>OPERATION_NOT_ALLOWED</code></td>
<td>The request <code>id</code> is not allowed to verify OTPs.</td>
</tr>
<tr>
<td><code>BACKEND_ERROR</code></td>
<td>Unexpected error in our server. Please contact us if you see this
error.</td>
</tr>
</table>