2009-10-08 08:38:52 +02:00
|
|
|
|
<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>
|
2009-10-12 13:39:46 +02:00
|
|
|
|
<tr>
|
|
|
|
|
<td><code>timestamp</td>
|
|
|
|
|
<td>string</td>
|
|
|
|
|
<td>No</td>
|
|
|
|
|
<td>Timestamp=1 requests timestamp and session counter information the response</td>
|
2009-10-08 08:38:52 +02:00
|
|
|
|
|
|
|
|
|
<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>
|
2009-10-12 13:39:46 +02:00
|
|
|
|
<br />
|
|
|
|
|
And if you require additional information on timestamp and session counters:
|
|
|
|
|
<pre>
|
|
|
|
|
http://api.yubico.com/wsapi/verify?otp=vvvvvvcucrlcietctc\
|
|
|
|
|
kflvnncdgckubflugerlnr&id=87×tamp=1 </pre>
|
|
|
|
|
<br />
|
|
|
|
|
|
2009-10-08 08:38:52 +02:00
|
|
|
|
<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>
|
2009-10-14 09:43:45 +02:00
|
|
|
|
|
2009-10-08 08:38:52 +02:00
|
|
|
|
<tr>
|
|
|
|
|
<td><code>h</code></td>
|
|
|
|
|
<td>string (base64)</td>
|
|
|
|
|
|
|
|
|
|
<td>Signature as <a href="#signatures">described above</a>.</td>
|
|
|
|
|
</tr>
|
2009-10-14 09:43:45 +02:00
|
|
|
|
|
2009-10-08 08:38:52 +02:00
|
|
|
|
<tr>
|
|
|
|
|
<td><code>t</code></td>
|
|
|
|
|
<td>time stamp</td>
|
|
|
|
|
<td>Timestamp in UTC.</td>
|
|
|
|
|
</tr>
|
2009-10-14 09:43:45 +02:00
|
|
|
|
|
2009-10-08 08:38:52 +02:00
|
|
|
|
<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>
|
|
|
|
|
|
2009-10-12 13:39:46 +02:00
|
|
|
|
<tr>
|
|
|
|
|
<td><code>timestamp</code></td>
|
|
|
|
|
<td>string</td>
|
|
|
|
|
<td>YubiKey internal timestamp value when key was pressed</td>
|
|
|
|
|
</tr>
|
2009-10-14 09:43:45 +02:00
|
|
|
|
|
2009-10-12 13:39:46 +02:00
|
|
|
|
<tr>
|
|
|
|
|
<td><code>sessioncounter</code></td>
|
|
|
|
|
<td>string</td>
|
|
|
|
|
<td>YubiKey internal usage counter when key was pressed</td>
|
|
|
|
|
</tr>
|
2009-10-14 09:43:45 +02:00
|
|
|
|
|
2009-10-12 13:39:46 +02:00
|
|
|
|
<tr>
|
|
|
|
|
<td><code>sessionuse</code></td>
|
|
|
|
|
<td>string</td>
|
|
|
|
|
<td>YubiKey internal session usage counter when key was pressed</td>
|
|
|
|
|
</tr>
|
2009-10-08 08:38:52 +02:00
|
|
|
|
</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>
|
2009-10-14 09:43:45 +02:00
|
|
|
|
<td>The request lacks a parameter.</td>
|
2009-10-08 08:38:52 +02:00
|
|
|
|
|
|
|
|
|
</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>
|