<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head><title>Pre-Draft: OpenID Authentication 2.0 - Pre-Draft 11</title>
<meta http-equiv="Expires" content="Sat, 25 Nov 2006 08:07:32 +0000">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="OpenID Authentication 2.0 - Pre-Draft 11">
<meta name="generator" content="xml2rfc v1.32pre2 (http://xml.resource.org/)">
<style type='text/css'><!--
body {
font-family: verdana, charcoal, helvetica, arial, sans-serif;
font-size: small; color: #000; background-color: #FFF;
margin: 2em;
}
h1, h2, h3, h4, h5, h6 {
font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif;
font-weight: bold; font-style: normal;
}
h1 { color: #900; background-color: transparent; text-align: right; }
h3 { color: #333; background-color: transparent; }
td.RFCbug {
font-size: x-small; text-decoration: none;
width: 30px; height: 30px; padding-top: 2px;
text-align: justify; vertical-align: middle;
background-color: #000;
}
td.RFCbug span.RFC {
font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
font-weight: bold; color: #666;
}
td.RFCbug span.hotText {
font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
font-weight: normal; text-align: center; color: #FFF;
}
table.TOCbug { width: 30px; height: 15px; }
td.TOCbug {
text-align: center; width: 30px; height: 15px;
color: #FFF; background-color: #900;
}
td.TOCbug a {
font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif;
font-weight: bold; font-size: x-small; text-decoration: none;
color: #FFF; background-color: transparent;
}
td.header {
font-family: arial, helvetica, sans-serif; font-size: x-small;
vertical-align: top; width: 33%;
color: #FFF; background-color: #666;
}
td.author { font-weight: bold; font-size: x-small; margin-left: 4em; }
td.author-text { font-size: x-small; }
/* info code from SantaKlauss at http://www.madaboutstyle.com/tooltip2.html */
a.info {
/* This is the key. */
position: relative;
z-index: 24;
text-decoration: none;
}
a.info:hover {
z-index: 25;
color: #FFF; background-color: #900;
}
a.info span { display: none; }
a.info:hover span.info {
/* The span will display just on :hover state. */
display: block;
position: absolute;
font-size: smaller;
top: 2em; left: -5em; width: 15em;
padding: 2px; border: 1px solid #333;
color: #900; background-color: #EEE;
text-align: left;
}
a { font-weight: bold; }
a:link { color: #900; background-color: transparent; }
a:visited { color: #633; background-color: transparent; }
a:active { color: #633; background-color: transparent; }
p { margin-left: 2em; margin-right: 2em; }
p.copyright { font-size: x-small; }
p.toc { font-size: small; font-weight: bold; margin-left: 3em; }
table.toc { margin: 0 0 0 3em; padding: 0; border: 0; vertical-align: text-top; }
td.toc { font-size: small; font-weight: bold; vertical-align: text-top; }
ol.text { margin-left: 2em; margin-right: 2em; }
ul.text { margin-left: 2em; margin-right: 2em; }
li { margin-left: 3em; }
/* RFC-2629 <spanx>s and <artwork>s. */
em { font-style: italic; }
strong { font-weight: bold; }
dfn { font-weight: bold; font-style: normal; }
cite { font-weight: normal; font-style: normal; }
tt { color: #036; }
tt, pre, pre dfn, pre em, pre cite, pre span {
font-family: "Courier New", Courier, monospace; font-size: small;
}
pre {
text-align: left; padding: 4px;
color: #000; background-color: #CCC;
}
pre dfn { color: #900; }
pre em { color: #66F; background-color: #FFC; font-weight: normal; }
pre .key { color: #33C; font-weight: bold; }
pre .id { color: #900; }
pre .str { color: #000; background-color: #CFF; }
pre .val { color: #066; }
pre .rep { color: #909; }
pre .oth { color: #000; background-color: #FCF; }
pre .err { background-color: #FCC; }
/* RFC-2629 <texttable>s. */
table.full, table.headers, table.none {
font-size: small; text-align: center; border-width: 2px;
vertical-align: top; border-collapse: collapse;
}
table.full { border-style: solid; border-color: black; }
table.headers, table.none { border-style: none; }
th {
font-weight: bold; border-color: black;
border-width: 2px 2px 3px 2px;
}
table.full th { border-style: solid; }
table.headers th { border-style: none none solid none; }
table.none th { border-style: none; }
table.full td {
border-style: solid; border-color: #333;
border-width: 1px 2px;
}
table.headers td, table.none td { border-style: none; }
hr { height: 1px; }
hr.insert {
width: 80%; border-style: none; border-width: 0;
color: #CCC; background-color: #CCC;
}
--></style>
</head>
<body>
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table>
<table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1">
<tr><td class="header">Pre-Draft</td><td class="header">D. Recordon</td></tr>
<tr><td class="header"> </td><td class="header">VeriSign</td></tr>
<tr><td class="header"> </td><td class="header">J. Hoyt</td></tr>
<tr><td class="header"> </td><td class="header">JanRain</td></tr>
<tr><td class="header"> </td><td class="header">D. Hardt</td></tr>
<tr><td class="header"> </td><td class="header">Sxip</td></tr>
<tr><td class="header"> </td><td class="header">B. Fitzpatrick</td></tr>
<tr><td class="header"> </td><td class="header">Six Apart</td></tr>
<tr><td class="header"> </td><td class="header">November 25, 2006</td></tr>
</table></td></tr></table>
<h1><br />OpenID Authentication 2.0 - Pre-Draft 11</h1>
<h3>Abstract</h3>
<p>
OpenID Authentication provides a way to prove that an end user
controls an Identifier. It does this without the Relying Party
needing access to end user credentials such as a password or
to other sensitive information such as an email address.
</p>
<p>
OpenID is decentralized. No central authority must approve or
register Relying Parties or OpenID Providers. An end user
can freely choose which OpenID Provider to use, and can
preserve their Identifier if they switch OpenID Providers.
</p>
<p>
While nothing in the protocol requires JavaScript or modern
browsers, the authentication scheme plays nicely with
"AJAX"-style setups. This means an end user can prove their
Identity to a Relying Party without having to leave their
current Web page.
</p>
<p>
OpenID Authentication uses only standard HTTP(S) requests and
responses, so it does not require any special capabilities of the
User-Agent or other software. OpenID is not tied to the use of
cookies or any other specific mechanism of Relying Party
session management. Extensions to User-Agents can simplify
the end user interaction, though are not required to utilize
the protocol.
</p>
<p>
The exchange of profile information, or the exchange of other
information not covered in this specification, can be addressed
through additional Service Types built on top of this
protocol to create a framework. OpenID Authentication is
designed to provide a base service to enable portable,
user-centric digital identity in a free and decentralized manner.
</p><a name="toc"></a><br /><hr />
<h3>Table of Contents</h3>
<p class="toc">
<a href="#anchor1">1</a>
Requirements Notation<br />
<a href="#anchor2">2</a>
Terminology<br />
<a href="#anchor3">3</a>
Protocol Overview<br />
<a href="#formats">4</a>
Data Formats<br />
<a href="#anchor4">4.1</a>
Protocol Messages<br />
<a href="#btwoc">4.2</a>
Integer Representations<br />
<a href="#communication">5</a>
Communication Types<br />
<a href="#direct_comm">5.1</a>
Direct Communication<br />
<a href="#indirect_comm">5.2</a>
Indirect Communication<br />
<a href="#generating_signatures">6</a>
Generating Signatures<br />
<a href="#anchor11">6.1</a>
Procedure<br />
<a href="#signed_list">6.2</a>
Signed List Algorithm<br />
<a href="#sign_algos">6.3</a>
Signature Algorithms<br />
<a href="#anchor12">7</a>
Initiation and Discovery<br />
<a href="#initiation">7.1</a>
Initiation<br />
<a href="#normalization">7.2</a>
Normalization<br />
<a href="#discovery">7.3</a>
Discovery<br />
<a href="#associations">8</a>
Establishing Associations<br />
<a href="#anchor20">8.1</a>
Association Session Request<br />
<a href="#anchor23">8.2</a>
Association Session Response<br />
<a href="#assoc_types">8.3</a>
Association Types<br />
<a href="#assoc_sess_types">8.4</a>
Association Session Types<br />
<a href="#requesting_authentication">9</a>
Requesting Authentication<br />
<a href="#anchor28">9.1</a>
Request Parameters<br />
<a href="#realms">9.2</a>
Realms<br />
<a href="#anchor29">9.3</a>
Immediate Requests<br />
<a href="#responding_to_authentication">10</a>
Responding to Authentication Requests<br />
<a href="#positive_assertions">10.1</a>
Positive Assertions<br />
<a href="#negative_assertions">10.2</a>
Negative Assertions<br />
<a href="#verification">11</a>
Verifying Assertions<br />
<a href="#anchor32">11.1</a>
Checking the Nonce<br />
<a href="#verifying_signatures">11.2</a>
Verifying Signatures<br />
<a href="#anchor36">11.3</a>
Verifying Discovered Information<br />
<a href="#identifying">11.4</a>
Identifying the end user<br />
<a href="#compat_mode">12</a>
OpenID Authentication 1.1 Compatibility<br />
<a href="#anchor37">12.1</a>
Relying Parties<br />
<a href="#anchor38">12.2</a>
OpenID Providers<br />
<a href="#extensions">13</a>
Extensions<br />
<a href="#anchor39">14</a>
Discovering OpenID Relying Parties<br />
<a href="#anchor40">15</a>
Security Considerations<br />
<a href="#anchor41">15.1</a>
Preventing Attacks<br />
<a href="#anchor43">15.2</a>
User-Agents<br />
<a href="#anchor44">15.3</a>
User Interface Considerations<br />
<a href="#anchor45">Appendix A</a>
Examples<br />
<a href="#anchor46">Appendix A.1</a>
OP-Specific Identifiers<br />
<a href="#XRDS Sample">Appendix A.2</a>
XRDS<br />
<a href="#anchor47">Appendix A.3</a>
HTML Identifier Markup<br />
<a href="#anchor48">Appendix A.4</a>
Login Form<br />
<a href="#anchor49">Appendix A.5</a>
XRI CanonicalID<br />
<a href="#pvalue">Appendix B</a>
Diffie-Hellman Key Exchange Default Value<br />
<a href="#anchor50">Appendix C</a>
Changes from the Previous OpenID Authentication Specification<br />
<a href="#anchor51">Appendix C.1</a>
Updated Initiation and Discovery<br />
<a href="#anchor52">Appendix C.2</a>
Security improvements<br />
<a href="#anchor53">Appendix C.3</a>
Extensions<br />
<a href="#rfc.references1">16</a>
Normative References<br />
<a href="#rfc.authors">§</a>
Authors' Addresses<br />
</p>
<br clear="all" />
<a name="rfc.section.1"></a><h4><a name="anchor1">1</a>
Requirements Notation</h4>
<p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in <a class='info' href='#RFC2119'>[RFC2119]<span> (</span><span class='info'>Bradner, B., “Key words for use in RFCs to Indicate Requirement Levels,” .</span><span>)</span></a>.
</p>
<a name="rfc.section.2"></a><h4><a name="anchor2">2</a>
Terminology</h4>
<p>
</p>
<blockquote class="text"><dl>
<dt>Identifier:</dt>
<dd>
An Identifier is either a "http" or "https" URI, (commonly
referred to as a "URL" within this document), or an <a class='info' href='#XRI Syntax 2.0'>XRI<span> (</span><span class='info'>Reed, D. and D. McAlpin, “Extensible Resource Identifier (XRI) Syntax V2.0,” .</span><span>)</span></a> [XRI Syntax 2.0]. This document defines
various kinds of Identifiers, designed for use in different
contexts.
</dd>
<dt>User-Agent:</dt>
<dd>
The end user's Web browser which implements HTTP/1.1 <a class='info' href='#RFC2616'>[RFC2616]<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1,” .</span><span>)</span></a>.
</dd>
<dt>Relying Party:</dt>
<dd>
RP. A Web application that wants proof that the end user
controls an Identifier.
</dd>
<dt>OpenID Provider:</dt>
<dd>
OP. The party operating an OpenID Authentication server on
which a Relying Party relies for an assertion that the end
user controls an Identifier.
</dd>
<dt>OP Endpoint URL:</dt>
<dd>
The URL which accepts OpenID Authentication requests,
discovered by dereferencing the end user's Identifier. This
value MUST be an absolute URL.
</dd>
<dt>User-supplied Identifier</dt>
<dd>
An Identifier that was presented by the end user to the Relying Party.
During the initiation phase of the protocol, an end user may enter
either a Public Identifier or an OP Identifier. If an OP Identifier
is used, the OP may then assist the end user in selecting either a
Public Identifier or a Private Identifier to share with the Relying
Party.
</dd>
<dt>Claimed Identifier:</dt>
<dd>
An Identifier that the end user claims to own. The overall aim
of the protocol is verifying this Identifier. The Claimed
Identifier is either:
<ul class="text">
<li>
The Identifier obtained by <a class='info' href='#normalization'>normalizing<span> (</span><span class='info'>Normalization</span><span>)</span></a> the User-supplied Identifier, if it
was an URL.
</li>
<li>
The <a class='info' href='#canonicalid'>CanonicalID<span> (</span><span class='info'>XRI and the CanonicalID Element</span><span>)</span></a>, if it
was an XRI.
</li>
</ul>
</dd>
<dt>OP-Specific Identifier:</dt>
<dd>
An alternate Identifier for an end user that is specific to a
particular OP and thus not necessarily under the end user's
control.
</dd>
<dt>OP Identifier:</dt>
<dd>
An Identifier for an OpenID Provider.
</dd>
<dt>Public Identifier:</dt>
<dd>
An Identifier that is intended to be public information and
not specific to the end user's relationship with one or more
Relying Parties, for example a blog URL or an i-name.
</dd>
<dt>Private Identifier:</dt>
<dd>
An Identifier that is intended to be private information used
only in the context of the end user's relationship with one or
more specific Relying Parties.
</dd>
<dt>Diffie-Hellman Key Exchange:</dt>
<dd>
Diffie-Hellman Key Exchange <a class='info' href='#RFC2631'>[RFC2631]<span> (</span><span class='info'>Rescorla, E., “Diffie-Hellman Key Agreement Method,” .</span><span>)</span></a> is a
protocol that allows two parties to create a shared a secret,
while preventing eavesdroppers from learning the secret.
</dd>
</dl></blockquote><p>
</p>
<a name="rfc.section.3"></a><h4><a name="anchor3">3</a>
Protocol Overview</h4>
<p>
</p>
<ol class="text">
<li>
The end user <a class='info' href='#initiation'>initiates
authentication<span> (</span><span class='info'>Initiation</span><span>)</span></a> by presenting a User-supplied Identifier
to the Relying Party via their User-Agent.
</li>
<li>
After normalizing the User-supplied Identifier, The Relying
Party <a class='info' href='#discovery'>performs discovery<span> (</span><span class='info'>Discovery</span><span>)</span></a> on
it and establishes the URL of the OP's OpenID Authentication
service endpoint that the end user uses for authentication.
</li>
<li>
(optional)
The Relying Party and the OP establish an <a class='info' href='#associations'>association<span> (</span><span class='info'>Establishing Associations</span><span>)</span></a> -- a shared
secret established using Diffie-Hellman Key Exchange. The
OP uses an association to sign subsequent messages and
the Relying Party to verify those messages; this removes
the need for subsequent direct requests to verify the
signature after each authentication request.
</li>
<li>
The Relying Party redirects the end user's User-Agent to
the OP with an OpenID <a class='info' href='#requesting_authentication'>Authentication
request<span> (</span><span class='info'>Requesting Authentication</span><span>)</span></a>.
</li>
<li>
The OP establishes whether the end user is authorized to
perform OpenID Authentication and wishes to do so. The
manner in which the end user authenticates to their OP and
any policies surrounding such authentication is out of
scope for this document.
</li>
<li>
The OP redirects the end user's User-Agent back to the
Relying Party with cyrptographic proof asserting either
that <a class='info' href='#positive_assertions'>authentication is
approved<span> (</span><span class='info'>Positive Assertions</span><span>)</span></a> or <a class='info' href='#negative_assertions'>authentication failed<span> (</span><span class='info'>Negative Assertions</span><span>)</span></a>.
</li>
<li>
The Relying Party <a class='info' href='#verification'>verifies<span> (</span><span class='info'>Verifying Assertions</span><span>)</span></a> the information
received from the OP including checking the nonce,
verifying the signature by using either the shared key
established during the association or by sending a direct
request to the OP, and verifying the discovered
information.
</li>
</ol><p>
</p>
<a name="rfc.section.4"></a><h4><a name="formats">4</a>
Data Formats</h4>
<a name="rfc.section.4.1"></a><h4><a name="anchor4">4.1</a>
Protocol Messages</h4>
<p>
The OpenID Authentication protocol messages are
mappings of plain-text keys to plain-text values. The keys and
values permit the full Unicode character set (UCS). When the
keys and values need to be converted to/from bytes, they
MUST be encoded using <a class='info' href='#RFC3629'>UTF-8<span> (</span><span class='info'>Yergeau, F., “UTF-8, a transformation format of Unicode and ISO 10646,” .</span><span>)</span></a> [RFC3629].
Messages MUST NOT contain multiple parameters with the same name.
</p>
<a name="rfc.section.4.1.1"></a><h4><a name="kvform">4.1.1</a>
Key-Value Form Encoding</h4>
<p>
A message in Key-Value form is a sequence of lines. Each
line begins with a key, followed by a colon, and the value
associated with the key. The line is terminated by a
single newline (UCS codepoint 10, "\n"). A key or value
MUST NOT contain a newline and a key also MUST NOT contain
a colon.
</p>
<p>
Additional characters, including whitespace, MUST NOT be
added before or after the colon or newline. The message
MUST be encoded in UTF-8 to produce a byte string.
</p>
<p>
Key-Value Form encoding is used for signature calculation
and for <a class='info' href='#direct_response'>direct
responses<span> (</span><span class='info'>Direct Response</span><span>)</span></a> to Relying Parties.
</p>
<a name="rfc.section.4.1.2"></a><h4><a name="queries">4.1.2</a>
HTTP Encoding</h4>
<p>
When a message is sent to an HTTP server, it MUST be encoded
using a form encoding specified in Section 17.13.4 of
<a class='info' href='#HTML401'>[HTML401]<span> (</span><span class='info'>W3C, “HTML 4.01 Specification,” .</span><span>)</span></a>. Likewise, if the "Content-Type"
header is included in the request headers, its value MUST
also be such an encoding.
</p>
<p>
All of the keys in the request message MUST be prefixed
with "openid.". This prefix prevents interference with
other parameters that are passed along with the OpenID
Authentication message. When a message is sent as a POST,
the application processing the HTTP request MUST only use
the values in the POST body and MUST ignore any GET
parameters.
</p>
<p>
This model applies to messages from the User-Agent to both
the Relying Party and the OP, as well as messages from the
Relying Party to the OP.
</p>
<a name="rfc.section.4.1.3"></a><h4><a name="anchor5">4.1.3</a>
Example</h4>
<p>
Non-normative
</p>
<p>
<p>
The following examples encode the following information:
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
Key | Value
--------+---------------------------
mode | error
error | This is an example message
</pre></div>
<p>
<p>
Key-Value Form encoded:
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>mode:error
error:This is an example message
</pre></div>
<p>
x-www-urlencoded, as in a HTTP POST body or in a URL's
query string (<a class='info' href='#RFC3986'>[RFC3986]<span> (</span><span class='info'>Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,” .</span><span>)</span></a> section 3):
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>openid.mode=error&openid.error=This%20is%20an%20example%20message</pre></div>
<a name="rfc.section.4.2"></a><h4><a name="btwoc">4.2</a>
Integer Representations</h4>
<p>
Arbitrary precision integers MUST be encoded as big-endian
signed two's complement binary strings. Henceforth,
"btwoc" is a function that takes an arbitrary precision
integer and returns its shortest big-endian two's
complement representation. All integers that are used with
Diffie-Hellman are positive. This means that the left-most
bit of the two's complement representation MUST be
zero. If it is not, implementations MUST add a zero byte
at the front of the string.
</p>
<p>Non-normative example:
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
Base 10 number | btwoc string representation
---------------+----------------------------
0 | "\x00"
127 | "\x7F"
128 | "\x00\x80"
255 | "\x00\xFF"
32768 | "\x00\x80\x00"
</pre></div>
<a name="rfc.section.5"></a><h4><a name="communication">5</a>
Communication Types</h4>
<a name="rfc.section.5.1"></a><h4><a name="direct_comm">5.1</a>
Direct Communication</h4>
<p>
Direct communication is initiated by a Relying Party to an
OP endpoint URL. It is used for <a class='info' href='#associations'>establishing associations<span> (</span><span class='info'>Establishing Associations</span><span>)</span></a> and
<a class='info' href='#check_auth'>verifying authentication
assertions<span> (</span><span class='info'>Verifying Directly with the OpenID Provider</span><span>)</span></a>.
</p>
<a name="rfc.section.5.1.1"></a><h4><a name="direct_request">5.1.1</a>
Direct Request</h4>
<p>
The message MUST be encoded as a POST body, as specified
by <a class='info' href='#queries'>Section 4.1.2<span> (</span><span class='info'>HTTP Encoding</span><span>)</span></a>.
</p>
<p>
All direct requests must contain the following field:
</p>
<p>
</p>
<ul class="text">
<li>
openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the request to
be a valid OpenID 2.0 direct request.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.5.1.2"></a><h4><a name="direct_response">5.1.2</a>
Direct Response</h4>
<p>
The body of a response to a <a class='info' href='#direct_request'>Direct Request<span> (</span><span class='info'>Direct Request</span><span>)</span></a> consists of
an HTTP Response body in <a class='info' href='#kvform'>Key-Value
Form<span> (</span><span class='info'>Key-Value Form Encoding</span><span>)</span></a>. The content-type of the response SHOULD be
"text/plain".
</p>
<p>
All direct responses must contain the following field:
</p>
<p>
</p>
<ul class="text">
<li>
ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 direct response.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.5.1.2.1"></a><h4><a name="anchor6">5.1.2.1</a>
Successful Responses</h4>
<p>
A server receiving a valid request MUST send a
response with an HTTP status code of 200.
</p>
<a name="rfc.section.5.1.2.2"></a><h4><a name="anchor7">5.1.2.2</a>
Error Responses</h4>
<p>
If a request is malformed or contains invalid arguments,
the server MUST send a response with a status code of
400. The response body MUST be a Key-Value Form <a class='info' href='#kvform'>Section 4.1.1<span> (</span><span class='info'>Key-Value Form Encoding</span><span>)</span></a> message with the following fields:
</p>
<p>
</p>
<ul class="text">
<li>
ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 direct error response.
</p>
</blockquote>
</li>
<li>
error
<blockquote class="text">
<p>
Value: Unstructured text error message.
</p>
</blockquote>
</li>
<li>
contact
<blockquote class="text">
<p>
Value: (optional) Contact address for the
administrator of the sever. The contact address
may take any form, as it is intended to be
displayed to a person.
</p>
</blockquote>
</li>
<li>
reference
<blockquote class="text">
<p>
Value: (optional) A reference identifier, such
as a support ticket number or a URL to a news
blog, etc.
</p>
</blockquote>
</li>
</ul><p>
The OP MAY add additional fields to this response.
</p>
<a name="rfc.section.5.2"></a><h4><a name="indirect_comm">5.2</a>
Indirect Communication</h4>
<p>
In indirect communication, messages are passed through the
User-Agent. This can be initiated by either the Relying
Party or the OP. Indirect communication is used for <a class='info' href='#requesting_authentication'>authentication
requests<span> (</span><span class='info'>Requesting Authentication</span><span>)</span></a> and <a class='info' href='#responding_to_authentication'>authentication
responses<span> (</span><span class='info'>Responding to Authentication Requests</span><span>)</span></a>.
</p>
<p>
There are two methods for indirect communication: HTTP
redirects and HTML form submission.
Both form submission and redirection require that the sender
know a recipient URL and that the recipient URL expect
indirect messages, as specified in <a class='info' href='#queries'>Section 4.1.2<span> (</span><span class='info'>HTTP Encoding</span><span>)</span></a>. The initiator of the communication chooses which method
of indirect communication is appropriate depending on
capabilities, message size, or other external factors.
</p>
<p>
All indirect messages must contain the following field:
</p>
<p>
</p>
<ul class="text">
<li>
openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the message to
be a valid OpenID 2.0 indirect message.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.5.2.1"></a><h4><a name="anchor8">5.2.1</a>
HTTP Redirect</h4>
<p>
Data can be transferred by issuing a 302, 303, or 307 HTTP
Redirect to the end user's User-Agent. The redirect URL is
the URL of the receiver with the OpenID Authentication
message appended to the query string, as specified in
<a class='info' href='#queries'>Section 4.1.2<span> (</span><span class='info'>HTTP Encoding</span><span>)</span></a>.
</p>
<a name="rfc.section.5.2.2"></a><h4><a name="anchor9">5.2.2</a>
HTML FORM Redirection</h4>
<p>
A mapping of keys to values can be transferred by
returning an HTML page to the User-Agent that contains an
HTML form element. Form submission MAY be automated
using JavaScript.
</p>
<p>
The <form> element's "action" attribute value MUST
be the URL of the receiving Web site. Each Key-Value pair
MUST be included in the form as an <input>
element. The key MUST be encoded as the "name" attribute
and the value as the "value" attribute, such that the
User-Agent will generate a message as specified in <a class='info' href='#queries'>Section 4.1.2<span> (</span><span class='info'>HTTP Encoding</span><span>)</span></a> when the form is submitted. The form
MUST include a submit button.
</p>
<a name="rfc.section.5.2.3"></a><h4><a name="anchor10">5.2.3</a>
Indirect Error Responses</h4>
<p>
In the case of a malformed request or one that contains
invalid arguments, the server MUST redirect the User-Agent
to the "openid.return_to" URL value if the value is a
valid URL.
</p>
<p>
</p>
<ul class="text">
<li>
openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 indirect error response.
</p>
</blockquote>
</li>
<li>
openid.mode
<blockquote class="text">
<p>
Value: "error"
</p>
</blockquote>
</li>
<li>
openid.error
<blockquote class="text">
<p>
Value: Unstructured text error message.
</p>
</blockquote>
</li>
<li>
openid.contact
<blockquote class="text">
<p>
Value: (optional) Contact address for the
administrator of the sever. The contact address
may take any form, as it is intended to be
displayed to a person.
</p>
</blockquote>
</li>
<li>
openid.reference
<blockquote class="text">
<p>
Value: (optional) A reference identifier, such
as a support ticket number or a URL to a news
blog, etc.
</p>
</blockquote>
</li>
</ul><p>
The server MAY add additional keys to this response.
</p>
<p>
If the "openid.return_to" value is not a valid URL, the
server SHOULD return a response to the end user indicating
the error and that it is unable to return the end user to
the initiating server. If the parameter is ommitted in the
request, it signifies that the initiating server does not
wish to for the end user to be returned to it as something
else useful will have been performed via an extension.
</p>
<a name="rfc.section.6"></a><h4><a name="generating_signatures">6</a>
Generating Signatures</h4>
<p>
The most common usage of an association is as a Message
Authentication Code (MAC) key used to sign OpenID
Authentication messages.
</p>
<p>
When generating MAC keys, the recommendations in <a class='info' href='#RFC1750'>[RFC1750]<span> (</span><span class='info'>Eastlake, D., Crocker, S., and J. Schiller, “Randomness Recommendations for Security,” .</span><span>)</span></a> SHOULD be followed.
</p>
<a name="rfc.section.6.1"></a><h4><a name="anchor11">6.1</a>
Procedure</h4>
<p>
To generate a message signature:
</p>
<ol class="text">
<li>
Determine the appropriate list of keys to be signed
and signature algorithm from the <a class='info' href='#associations'>association type<span> (</span><span class='info'>Establishing Associations</span><span>)</span></a>.
</li>
<li>
Generate the list of key/value pairs to be signed using
the correct <a class='info' href='#signed_list'>list algorithm<span> (</span><span class='info'>Signed List Algorithm</span><span>)</span></a>.
</li>
<li>
Convert the list of key/value pairs to be signed to an octet
string by encoding with <a class='info' href='#kvform'>Key-Value Form
Encoding<span> (</span><span class='info'>Key-Value Form Encoding</span><span>)</span></a>.
</li>
<li>
Apply the correct <a class='info' href='#sign_algos'>signature
algorithm<span> (</span><span class='info'>Signature Algorithms</span><span>)</span></a> to the octet string.
</li>
</ol><p>
</p>
<a name="rfc.section.6.2"></a><h4><a name="signed_list">6.2</a>
Signed List Algorithm</h4>
<p>
The input to the Signed List Algorithm are the message
to be signed, and the list of message keys that are to be
signed with the "openid." prefix removed.
</p>
<p>
To compute the list of key/value pairs to be signed:
</p>
<ol class="text">
<li>
Iterate through the list of keys to be signed in
the order they appear in the input to the algorithm.
For each key, find the value in the message whose key is
equal to the signed list key prefixed with "openid."
</li>
<li>
Append the signed list key and the associated value to
the list of key/value pairs to be signed.
</li>
</ol><p>
</p>
<p>
The output of this algorithm is the list of key/value pairs
to be signed, and the list of keys to be signed. A message
signed using this algorithm MUST append the list of signed
fields to the message.
</p>
<p>
As the algorithm strips the "openid." prefix from message
keys while looking for a match, it MUST only sign elements
that have keys beginning with "openid." This is to prevent
attacks where the Relying Party is malicious and tries to
have the OP sign arbitrary data.
</p>
<a name="rfc.section.6.3"></a><h4><a name="sign_algos">6.3</a>
Signature Algorithms</h4>
<p>
OpenID Authentication supports two signature algorithms:
</p>
<ul class="text">
<li>HMAC-SHA1(<a class='info' href='#RFC2104'>[RFC2104]<span> (</span><span class='info'>Krawczyk, H., Bellare, M., and R. Canetti, “HMAC: Keyed-Hashing for Message Authentication,” .</span><span>)</span></a> and <a class='info' href='#RFC3174'>[RFC3174]<span> (</span><span class='info'>Eastlake, D. and P. Jones, “US Secure Hash Algorithm 1 (SHA1),” .</span><span>)</span></a>)
</li>
<li>HMAC-SHA256 (<a class='info' href='#RFC2104'>[RFC2104]<span> (</span><span class='info'>Krawczyk, H., Bellare, M., and R. Canetti, “HMAC: Keyed-Hashing for Message Authentication,” .</span><span>)</span></a> and <a class='info' href='#FIPS180-2'>[FIPS180‑2]<span> (</span><span class='info'>U.S. Department of Commerce and National Institute of Standards and Technology, “Secure Hash Signature Standard,” .</span><span>)</span></a>
</li>
</ul><p>
HMAC-SHA1 is the default for authentication requests though
the use of HMAC-SHA256 is RECOMENDED. At the time of writing
this document, library support for SHA256 seems lacking.
</p><table class="full" align="center" border="0" cellpadding="2" cellspacing="2">
<col align="left"><col align="left">
<tr><th align="left">Algorithm</th><th align="left">Key Length</th></tr>
<tr>
<td align="left">HMAC-SHA1</td>
<td align="left">160 bits</td>
</tr>
<tr>
<td align="left">HMAC-SHA256</td>
<td align="left">256 bits</td>
</tr>
</table>
<a name="rfc.section.7"></a><h4><a name="anchor12">7</a>
Initiation and Discovery</h4>
<a name="rfc.section.7.1"></a><h4><a name="initiation">7.1</a>
Initiation</h4>
<p>
To initiate OpenID Authentication, the Relying Party SHOULD
present the end user with a form that has a field for
entering an Identifier.
</p>
<p>
It is RECOMMENDED that a Relying Party place the <a href='http://openid.net/login-bg.gif'>OpenID logo</a>
at the beginning of the form field where the end user enters
their Identifier. This aides in end user recognition that
they can use an OpenID enabled Identifier at the Relying Party.
</p>
<p>
The form field's "name" attribute SHOULD have the value
"openid_identifier" as to allow User-Agents to automatically
prefill the end user's preferred Identifier when visiting a
Relying Party. Browser extensions or other software that
support OpenID Authentication may not detect a Relying
Party's support if the value is not this value.
</p>
<a name="rfc.section.7.2"></a><h4><a name="normalization">7.2</a>
Normalization</h4>
<p>
The end user's input MUST be normalized into an
Identifier. If the end user supplies input that does not
include a scheme (http, https, or xri), then the application
needs to determine if the input is an XRI or a URL missing
the scheme.
</p>
<p>
To do so, the Relying Party SHOULD examine the first
character of the input. If it is an XRI Global Context
Symbol ("=", "@", "+", "$", or "!" see
<a class='info' href='#XRI Syntax 2.0'>Section 2.2.1.2 of<span> (</span><span class='info'>Reed, D. and D. McAlpin, “Extensible Resource Identifier (XRI) Syntax V2.0,” .</span><span>)</span></a> [XRI Syntax 2.0]),
then the input SHOULD be treated as an XRI. If it is not,
then the input SHOULD be treated as an http URL, and
prefixed with the string "http://". See <a class='info' href='#http_s_identifiers'>Section 11.4.1<span> (</span><span class='info'>HTTP and HTTPS URL Identifiers</span><span>)</span></a> for more information.
</p>
<p>
URL identifiers MUST then be further normalized by both
following redirects when retrieving their content and
finally applying the rules in Section 6 of <a class='info' href='#RFC3986'>[RFC3986]<span> (</span><span class='info'>Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,” .</span><span>)</span></a> to the final destination URL. This final
URL MUST be noted by the Relying Party as the Claimed
Identifier and be used during future requests.
</p>
<a name="rfc.section.7.3"></a><h4><a name="discovery">7.3</a>
Discovery</h4>
<p>
Discovery is the process where the Relying Party uses the
Identifier to look up ("discover") the necessary information
for initiating requests. OpenID Authentication has three
paths through which to do discovery:
</p>
<p>
</p>
<ol class="text">
<li>
If the identifier is an XRI,
<a class='info' href='#XRI Resolution 2.0'>[XRI Resolution 2.0]<span> (</span><span class='info'>Wachob, G., Reed, D., Chasen, L., Tan, W., and S. Churchill, “Extensible Resource Identifier (XRI) Resolution V2.0 - Working Draft 10,” .</span><span>)</span></a> will yield an XRDS
document that contains the necessary information.
</li>
<li>
If it is a URL, the <a class='info' href='#Yadis'>Yadis
protocol<span> (</span><span class='info'>Miller, J., “Yadis Specification 1.0,” .</span><span>)</span></a> [Yadis] SHALL be first attempted. If it
succeeds, the result is again an XRDS document.
</li>
<li>
If the Yadis protocol fails, the URL is retrieved and
<a class='info' href='#html_disco'>HTML-based discovery<span> (</span><span class='info'>HTML-Based Discovery</span><span>)</span></a>
SHALL be attempted.
</li>
</ol><p>
</p>
<a name="rfc.section.7.3.1"></a><h4><a name="anchor13">7.3.1</a>
Discovered Information</h4>
<p>
Upon successful completion of discovery, the Relying
Party will have the following information (see the
Terminology section for definitions):
</p>
<blockquote class="text"><dl>
<dt>OP Endpoint URL:</dt>
<dd>
The absolute URL on the OP that accepts authentication requests.
</dd>
<dt>Claimed Identifier:</dt>
<dd>
(optional) The identifier that is the subject of this
authentication request. This is:
</dd>
<dt></dt>
<dd>
The Identifier obtained by <a class='info' href='#normalization'>normalizing<span> (</span><span class='info'>Normalization</span><span>)</span></a> the User-supplied Identifier,
if it was an URL.
</dd>
<dt></dt>
<dd>
The <a class='info' href='#canonicalid'>CanonicalID<span> (</span><span class='info'>XRI and the CanonicalID Element</span><span>)</span></a>,
if the User-supplied Identifier was an XRI.
</dd>
<dt>OP-Specific Identifier:</dt>
<dd>
(optional) An identifier that allows an OP to
identify the end user of a Claimed Identifier. If no
OP-specific identifier is present in the discovered
information, the Claimed Identifier is also the
OP-Specific Identifier.
</dd>
<dt>Protocol Version:</dt>
<dd>
The OpenID protocol version of the discovered
OpenID Provider(s). This is determined by the
<xrd:Type> tag of the OP Identifier Element.
</dd>
</dl></blockquote><p>
</p>
<a name="rfc.section.7.3.2"></a><h4><a name="anchor14">7.3.2</a>
XRDS-Based Discovery</h4>
<p>
If XRI or Yadis discovery was used, the result will be an
XRDS Document. This is a XML document with entries for
services that are related to the Identifier. It is
defined in <a class='info' href='#XRI Resolution 2.0'>Section 3
of<span> (</span><span class='info'>Wachob, G., Reed, D., Chasen, L., Tan, W., and S. Churchill, “Extensible Resource Identifier (XRI) Resolution V2.0 - Working Draft 10,” .</span><span>)</span></a> [XRI Resolution 2.0]. See <a class='info' href='#XRDS Sample'>Appendix A.2<span> (</span><span class='info'>XRDS</span><span>)</span></a> for an
example XRDS document.
</p>
<a name="rfc.section.7.3.2.1"></a><h4><a name="anchor15">7.3.2.1</a>
Service Elements</h4>
<a name="rfc.section.7.3.2.1.1"></a><h4><a name="anchor16">7.3.2.1.1</a>
OP Identifier Element</h4>
<p>
An OP Identifier Element is a <xrd:Service>
element with the following information:
</p>
<blockquote class="text"><dl>
<dt></dt>
<dd>
An <xrd:Type> tag whose text content is
"http://openid.net/server/2.0".
</dd>
<dt></dt>
<dd>
An <xrd:URI> tag whose text content is the
OP Endpoint URL
</dd>
</dl></blockquote><p>
</p>
<a name="rfc.section.7.3.2.1.2"></a><h4><a name="anchor17">7.3.2.1.2</a>
Claimed Identifier Element</h4>
<p>
A Claimed Identifier Element is an
<xrd:Service> element with the following
information:
</p>
<blockquote class="text"><dl>
<dt></dt>
<dd>
An <xrd:Type> tag whose text content is
"http://openid.net/signon/2.0".
</dd>
<dt></dt>
<dd>
An <xrd:URI> tag whose text content is the
OP Endpoint URL.
</dd>
<dt></dt>
<dd>
An <openid:Delegate> tag (optional) whose text
content is the OP-Specific Identifier.
</dd>
</dl></blockquote><p>
</p>
<a name="rfc.section.7.3.2.2"></a><h4><a name="anchor18">7.3.2.2</a>
Extracting Authentication Data</h4>
<p>
Once the Relying Party has obtained an XRDS document, it
MUST first search the document (following the rules
described in <a class='info' href='#XRI Resolution 2.0'>[XRI Resolution 2.0]<span> (</span><span class='info'>Wachob, G., Reed, D., Chasen, L., Tan, W., and S. Churchill, “Extensible Resource Identifier (XRI) Resolution V2.0 - Working Draft 10,” .</span><span>)</span></a>) for
an OP Identifier Element. If none is found, the RP will search
for a Claimed Identifier Element.
</p>
<a name="rfc.section.7.3.2.3"></a><h4><a name="canonicalid">7.3.2.3</a>
XRI and the CanonicalID Element</h4>
<p>
When the identifier is an XRI, the <xrd:XRD>
element that contains the OpenID Authentication
<xrd:Service> element MUST also contain a
<CanonicalID> element. The content of this element
MUST be used as the Claimed Identifier (see <a class='info' href='#identifying'>Section 11.4<span> (</span><span class='info'>Identifying the end user</span><span>)</span></a>). This is a vital security
consideration because a primary purpose of the
<CanonicalID> element is to assert a persistent
identifier that will never be reassigned, thus
preventing the possibility of an XRI being "taken over"
by a new registrant.
</p>
<p>
The Relying Party MUST confirm that the provider of the
XRD that contains the <CanonicalID> element is
authoritative for that Canonical ID. The provider is
identified by the contents of the <xrd:ProviderID>
element that is a child of the <xrd:XRD>
element. If the provider is not authoritative for the
Canonical ID, the Relying Party MUST resolve the
Canonical ID to confirm the OP Endpoint URL information
that was discovered. The information discovered when
resolving the canonical ID MUST match the information
discovered when resolving the User-supplied Identifier.
</p>
<p>
When using XRI resolution, the canonical ID MUST be
used as the Claimed Identifier. For an XRI to be a
valid identifier, both the <ProviderID> and
<CanonicalID> MUST be present in the discovered
XRDS document.
</p>
<p>
When using URL-based identifiers, the CanonicalID
element SHOULD be ignored if present.
</p>
<a name="rfc.section.7.3.2.4"></a><h4><a name="anchor19">7.3.2.4</a>
Additional Information</h4>
<p>
The "openid" namespace is
"http://openid.net/signon/2.0". The "xrd" namespace is
"xri://$xrd*($v*2.0)".
</p>
<p>
For compatibility with deployed code, it is RECOMMENDED
that a Relying Party also accept
"http://openid.net/signon/1.0" or
"http://openid.net/signon/1.1" for the value of
<xrd:Type>. When one of these values is used, the
Relying Party MUST use <a class='info' href='#compat_mode'>OpenID
Authentication 1.1 Compatibility<span> (</span><span class='info'>OpenID Authentication 1.1 Compatibility</span><span>)</span></a>.
</p>
<p>
If an OpenID OP supports extensions (<a class='info' href='#extensions'>Section 13<span> (</span><span class='info'>Extensions</span><span>)</span></a>), the extensions SHOULD be listed
as additional <xrd:Type> child elements of the
<xrd:Service> element.
</p>
<a name="rfc.section.7.3.3"></a><h4><a name="html_disco">7.3.3</a>
HTML-Based Discovery</h4>
<p>
OpenID Authentication 1.1 HTML-based discovery MUST be
supported by Relying Parties. If a Relying Party locates
an OP using HTML-based discovery, it MUST use <a class='info' href='#compat_mode'>OpenID Authentication 1.1
Compatibility<span> (</span><span class='info'>OpenID Authentication 1.1 Compatibility</span><span>)</span></a> when communicating with that OP.
</p>
<p>
To use HTML-based discovery, an HTML document MUST be
available at the URL of the Claimed Identifier. In the
HEAD section of the document:
</p>
<blockquote class="text">
<p>
A <LINK> tag MUST be included with attributes
"rel" set to "openid.server", and "href" set to an OP
Endpoint URL
</p>
<p>
A <LINK> tag MAY be included with attributes
"rel" set to "openid.delegate" and "href" set to the
end user's OP-Specific Identifier
</p>
</blockquote><p>
</p>
<p> The host of the HTML document MAY be different from the
end user's OP's host.
</p>
<p>
The "openid.server" and "openid.delegate" URLs MUST NOT
include entities other than "&amp;", "&lt;",
"&gt;", and "&quot;". Other characters that would
not be valid in the HTML document or that cannot be
represented in the document's character encoding MUST be
escaped using the percent-encoding (%xx) mechanism
described in <a class='info' href='#RFC3986'>[RFC3986]<span> (</span><span class='info'>Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,” .</span><span>)</span></a>.
</p>
<a name="rfc.section.8"></a><h4><a name="associations">8</a>
Establishing Associations</h4>
<p>
An "association" is a shared secret between the OP and
Relying Party. Once established, it is used to verify
subsequent protocol messages and reduces round trips.
</p>
<p>
It is RECOMMENDED that a Relying Party form associations if it
is possible for it to do so. If a Relying Party is incapable
of creating or storing associations, <a class='info' href='#verifying_signatures'>Section 11.2<span> (</span><span class='info'>Verifying Signatures</span><span>)</span></a> provides an alternate
verification mechanism referred to as Stateless Mode (note
that this was referred to as "dumb mode" in previous versions
of this specification).
</p>
<a name="rfc.section.8.1"></a><h4><a name="anchor20">8.1</a>
Association Session Request</h4>
<p>
An association session is initiated by a <a class='info' href='#direct_comm'>direct request<span> (</span><span class='info'>Direct Communication</span><span>)</span></a> from a Relying
Party to an OP Endpoint URL with the "openid.mode" key
having the value of "associate".
</p>
<a name="rfc.section.8.1.1"></a><h4><a name="anchor21">8.1.1</a>
Common Request Parameters</h4>
<p>
These parameters are common to all association requests:
</p>
<p>
</p>
<ul class="text">
<li>openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the request to
be a valid OpenID 2.0 association request.
</p>
</blockquote>
</li>
<li>openid.mode
<blockquote class="text">
<p> Value: "associate"
</p>
</blockquote>
</li>
<li>openid.assoc_type
<blockquote class="text">
<p> The preferred association type. The association
type defines the algorithm to be used to sign
subsequent messages.
</p>
<p> Value: A valid association type from <a class='info' href='#assoc_types'>Section 8.3<span> (</span><span class='info'>Association Types</span><span>)</span></a>
</p>
<p> Default: "HMAC-SHA1".
</p>
</blockquote>
</li>
<li>openid.session_type
<blockquote class="text">
<p>
The preferred association session type. This
defines the method used to encrypt the association's
MAC key in transit.
</p>
<p>
Value: A valid association session type from
<a class='info' href='#assoc_sess_types'>Section 8.4<span> (</span><span class='info'>Association Session Types</span><span>)</span></a>.
</p>
<p>
Note: Unless using transport layer encryption, it
is NOT RECOMMENDED to use "no-encryption" on a
public network, see <a class='info' href='#preventing_eavesdropping'>Section 15.1.1<span> (</span><span class='info'>Eavesdropping Attacks</span><span>)</span></a>.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.8.1.2"></a><h4><a name="anchor22">8.1.2</a>
Diffie-Hellman Request Parameters</h4>
<p>
The following parameters are common to requests whose
requested association session type is "DH-SHA1" or
"DH-SHA256":
</p>
<p>
</p>
<ul class="text">
<li>
openid.dh_modulus
<blockquote class="text">
<p>Value: base64(btwoc(p))
</p>
<p>Default: See <a class='info' href='#pvalue'>Appendix B<span> (</span><span class='info'>Diffie-Hellman Key Exchange Default Value</span><span>)</span></a>
</p>
</blockquote>
</li>
<li>
openid.dh_gen
<blockquote class="text">
<p>Value: base64(btwoc(g))
</p>
<p>Default: g = 2
</p>
</blockquote>
</li>
<li>
openid.dh_consumer_public
<blockquote class="text">
<p>Value: base64(btwoc(g ^ xa mod p))
</p>
</blockquote>
</li>
</ul><p>
</p>
<p>
See <a class='info' href='#dh_sessions'>Section 8.4.2<span> (</span><span class='info'>Diffie-Hellman Association Sessions</span><span>)</span></a> for more information on
these parameters.
</p>
<p>
NOTE: the 'btwoc' function is defined in <a class='info' href='#btwoc'>Section 4.2<span> (</span><span class='info'>Integer Representations</span><span>)</span></a>.
</p>
<a name="rfc.section.8.2"></a><h4><a name="anchor23">8.2</a>
Association Session Response</h4>
<p>
An association session response is a direct response from the
OP to the Relying Party in <a class='info' href='#kvform'>Key-Value
Form<span> (</span><span class='info'>Key-Value Form Encoding</span><span>)</span></a>.
</p>
<a name="rfc.section.8.2.1"></a><h4><a name="anchor24">8.2.1</a>
Common Response Parameters</h4>
<p>
</p>
<ul class="text">
<li>
ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 association response.
</p>
</blockquote>
</li>
<li>
session_type
<blockquote class="text">
<p>
The session type for this association. If the OP
is unwilling or unable to support this session
type, it MUST return an unsuccessful response.
</p>
</blockquote>
</li>
<li>
assoc_handle
<blockquote class="text">
<p>
The association handle is used as a key to refer
to this association in subsequent messages.
</p>
<p>
Value: A string 255 characters or less in length.
It MUST consist only of ASCII characters in the
range 33-126 inclusive (printable non-whitespace
characters).
</p>
</blockquote>
</li>
<li>
assoc_type
<blockquote class="text">
<p>
The value of the "openid.assoc_type" parameter
from the request. If the OP is unwilling or
unable to support this association type, it MUST
return an unsuccessful response.
</p>
</blockquote>
</li>
<li>
expires_in
<blockquote class="text">
<p>
The lifetime, in seconds, of this association.
The Relying Party MUST NOT use the association
after this time has expired.
</p>
<p>
Value: An integer, represented in base 10 ASCII.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.8.2.2"></a><h4><a name="anchor25">8.2.2</a>
Unencrypted Response Parameters</h4>
<p>
</p>
<ul class="text">
<li>
mac_key
<blockquote class="text">
<p>
The MAC key (shared secret) for this
association, <a class='info' href='#RFC3548'>Base 64<span> (</span><span class='info'>Josefsson, S., “The Base16, Base32, and Base64 Data Encodings,” .</span><span>)</span></a> [RFC3548]
encoded.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.8.2.3"></a><h4><a name="anchor26">8.2.3</a>
Diffie-Hellman Response Parameters</h4>
<p>
</p>
<ul class="text">
<li>
dh_server_public
<blockquote class="text">
<p>
Value: base64(btwoc(g ^ xb mod p))
</p>
<p>
Description: The OP's Diffie-Hellman public key.
</p>
</blockquote>
</li>
<li>
enc_mac_key
<blockquote class="text">
<p>
Value: base64(H(btwoc(g ^ (xa * xb) mod p)) XOR MAC key)
</p>
<p>
Description: The MAC key (shared secret),
encrypted with the secret Diffie-Hellman value. H
is either "SHA1" or "SHA256" depending on the
session type.
</p>
</blockquote>
</li>
</ul><p>
</p>
<p>
NOTE: The 'btwoc' function is defined in <a class='info' href='#btwoc'>Section 4.2<span> (</span><span class='info'>Integer Representations</span><span>)</span></a>
</p>
<a name="rfc.section.8.2.4"></a><h4><a name="refuse_assoc">8.2.4</a>
Unsuccessful Response Parameters</h4>
<p>
If the OP does not support an association session type or
association type, it MUST respond with a message
indicating that the association request failed. If there
is another association session type or association type
that is supported, the OP MAY include that information in
the response.
</p>
<p>
</p>
<ul class="text">
<li>
ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 association failure response.
</p>
</blockquote>
</li>
<li>
error
<blockquote class="text">
<p>
Value: (optional) A human-readable message
indicating why the association request failed.
</p>
</blockquote>
</li>
<li>
error_code
<blockquote class="text">
<p>
Value: "unsupported-type"
</p>
</blockquote>
</li>
<li>
session_type
<blockquote class="text">
<p>
Value: A valid association session type from <a class='info' href='#assoc_sess_types'>Section 8.4<span> (</span><span class='info'>Association Session Types</span><span>)</span></a>.
</p>
</blockquote>
</li>
<li>
assoc_type
<blockquote class="text">
<p>
Value: (optional) An association type supported by
the OP from <a class='info' href='#assoc_types'>Section 8.3<span> (</span><span class='info'>Association Types</span><span>)</span></a>.
</p>
</blockquote>
</li>
</ul><p>
</p>
<p>
Upon receipt of an "unsupported-type" response, the
Relying Party MAY make another request with the specified
association session type and association type. If no
association is established, the Relying Party MAY continue
the authentication process in stateless mode.
</p>
<a name="rfc.section.8.3"></a><h4><a name="assoc_types">8.3</a>
Association Types</h4>
<a name="rfc.section.8.3.1"></a><h4><a name="hmacsha1">8.3.1</a>
HMAC-SHA1</h4>
<p>
An association of type "HMAC-SHA1" uses the <a class='info' href='#sign_algos'>HMAC-SHA1<span> (</span><span class='info'>Signature Algorithms</span><span>)</span></a> signature algorithm
in combination with the <a class='info' href='#signed_list'>Signed
List<span> (</span><span class='info'>Signed List Algorithm</span><span>)</span></a> algorithm.
</p>
<a name="rfc.section.8.3.2"></a><h4><a name="hmacsha256">8.3.2</a>
HMAC-SHA256</h4>
<p>
An association of type "HMAC-256" uses the <a class='info' href='#sign_algos'>HMAC-SHA256<span> (</span><span class='info'>Signature Algorithms</span><span>)</span></a> signature
algorithm in combination with the <a class='info' href='#signed_list'>Signed List<span> (</span><span class='info'>Signed List Algorithm</span><span>)</span></a> algorithm.
</p>
<a name="rfc.section.8.4"></a><h4><a name="assoc_sess_types">8.4</a>
Association Session Types</h4>
<p>
OpenID Authentication defines three valid association
session types: "no-encryption", "DH-SHA1", and "DH-SHA256".
</p>
<a name="rfc.section.8.4.1"></a><h4><a name="anchor27">8.4.1</a>
No-Encryption Association Sessions</h4>
<p>
In a "no-encryption" association session, the OP sends
the association MAC key in plain-text to the Relying Party.
This makes it possible for an eavesdropper to intercept
the key, and forge messages to this Relying Party.
Therefore, no-encryption association sessions SHOULD NOT
be used unless the messages are using transport-level
encryption. See <a class='info' href='#preventing_eavesdropping'>Section 15.1.1<span> (</span><span class='info'>Eavesdropping Attacks</span><span>)</span></a>
for more information.
</p>
<p>
The MAC key sent by the OP MUST be the length specified
for this association in <a class='info' href='#sign_algos'>Section 6.3<span> (</span><span class='info'>Signature Algorithms</span><span>)</span></a>.
</p>
<a name="rfc.section.8.4.2"></a><h4><a name="dh_sessions">8.4.2</a>
Diffie-Hellman Association Sessions</h4>
<p>
The "DH-SHA1" and DH-SHA256" association types use
Diffie-Hellman Key Exchange to securely transmit the
shared secret.
</p>
<p>
The MAC key MUST be the same length as the output of H,
the hash function - 160 bits (20 bytes) for DH-SHA1 or 256
bits (32 bytes) for DH-SHA256, as well as the output of
the signature algorithm of this association.
</p>
<p>
The Relying Party specifies a modulus, p, and a generator,
g. The Relying Party chooses a random private key xa and
OpenID Provider chooses a random private key xb, both in
the range [1 .. p-1]. The shared secret used to encrypt
the MAC key is thus g ^ (xa * xb) mod p = (g ^ xa) ^ xb
mod p = (g ^ xb) ^ xa mod p. For more information, see
<a class='info' href='#RFC2631'>[RFC2631]<span> (</span><span class='info'>Rescorla, E., “Diffie-Hellman Key Agreement Method,” .</span><span>)</span></a>. For information on the
selection of random values, see <a class='info' href='#RFC1750'>[RFC1750]<span> (</span><span class='info'>Eastlake, D., Crocker, S., and J. Schiller, “Randomness Recommendations for Security,” .</span><span>)</span></a>.
</p>
<a name="rfc.section.9"></a><h4><a name="requesting_authentication">9</a>
Requesting Authentication</h4>
<p>
Once the Relying Party has successfully performed discovery
and (optionally) created an association with the discovered
OP Endpoint URL, it can send an authentication request to the
OP to obtain an assertion. An authentication request is an
<a class='info' href='#indirect_comm'>indirect request<span> (</span><span class='info'>Indirect Communication</span><span>)</span></a>.
</p>
<a name="rfc.section.9.1"></a><h4><a name="anchor28">9.1</a>
Request Parameters</h4>
<p>
</p>
<ul class="text">
<li>
openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the request to be a
valid OpenID Authentication 2.0 request.
</p>
<p>
Note: If an OP receives an authentication request
with this parameter missing or with a lower version
number, it SHOULD still respond to the request. If
it does respond it MUST use <a class='info' href='#compat_mode'>OpenID Authentication 1.1
Compatibility<span> (</span><span class='info'>OpenID Authentication 1.1 Compatibility</span><span>)</span></a> when communicating with that
Relying Party.
</p>
</blockquote>
</li>
<li>
openid.mode
<blockquote class="text">
<p>
Value: "checkid_immediate" or "checkid_setup"
</p>
<p>
Note: If the Relying Party wishes the end user to be
able to interact with the OP, "checkid_setup"
should be used. An example of a situation where
interaction between the end user and the OP is not
desired is when the authentication request is
happening asynchronously in JavaScript.
</p>
</blockquote>
</li>
<li>
openid.claimed_id
<blockquote class="text">
<p>
Value: (optional) The Claimed Identifier. MUST be present
if, and only if, openid.identity is present.
</p>
<p>
Note: The Claimed Identifier is the same as the
OP-Specific Identifier if a different OP-Specific
Identifier is not supplied. If neither value is
present, the assertion is not about an identifier,
and will contain other information in its payload,
using <a class='info' href='#extensions'>extensions<span> (</span><span class='info'>Extensions</span><span>)</span></a>.
</p>
</blockquote>
</li>
<li>
openid.identity
<blockquote class="text">
<p>
Value: (optional) The OP-Specific Identifier.
</p>
<p>
Note: If this is set to the special value
"http://openid.net/identifier_select/2.0" then the
OP MAY choose an Identifier that belongs to the end
user. This parameter MAY be omitted if the request is
not about an identifier (for instance if an extension
is in use that makes the request meaningful without
it; see openid.claimed_id above).
</p>
</blockquote>
</li>
<li>
openid.assoc_handle
<blockquote class="text">
<p>
Value: (optional) A handle for an association
between the Relying Party and the OP that SHOULD be
used to sign the response.
</p>
<p>
Note: If no association handle is sent, the
transaction will take place in stateless mode.
</p>
</blockquote>
</li>
<li>
openid.return_to
<blockquote class="text">
<p>
Value: (optional) URL to which the OP SHOULD return
the User-Agent with the response indicating the
status of the request.
</p>
<p>
Note: If this value is not sent in the request it
signifies that the Relying Party does not wish to
for the end user to be returned to it as something
else useful will have been performed via an
extension.
</p>
</blockquote>
</li>
<li>
openid.realm
<blockquote class="text">
<p>
Value: (optional) URL pattern the OP SHOULD ask the
end user to trust. See <a class='info' href='#realms'>Section 9.2<span> (</span><span class='info'>Realms</span><span>)</span></a>.
This value MUST be sent if openid.return_to is
ommitted.
</p>
<p>
Default: return_to URL
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.9.2"></a><h4><a name="realms">9.2</a>
Realms</h4>
<p>
A "realm" is a pattern that represents the part of URL-space
for which an OpenID Authentication request is valid. A realm
is designed to give the end user an indication of the scope
of the authentication request. OPs SHOULD present the realm
when requesting the end user's approval for an
authentication request. OPs MAY use the realm to allow the
end user to automate approval of authentication
requests. The realm SHOULD be used by OPs to uniquely
identify Relying Parties.
</p>
<p>
A realm pattern is a URL, with the following changes:
</p>
<ul class="text">
<li>
A realm MUST NOT contain a URI fragment
</li>
<li>
A realm MAY contain a wild-card at the beginning of the
URL authority section. A wild-card consists of the
characters "*." prepended to the DNS name in the
authority section of the URL.
</li>
</ul><p>
</p>
<p>
A URL matches a realm if:
</p>
<ul class="text">
<li>
The URL scheme and port of the URL are identical to those
in the realm. See <a class='info' href='#RFC3986'>RFC
3986<span> (</span><span class='info'>Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,” .</span><span>)</span></a> [RFC3986], section 3.1 for rules about URI matching.
</li>
<li>
The URL's path is equal to or a sub-directory of the
realm's path.
</li>
<li>
Either:
<ol class="text">
<li>
The realm's domain contains the wild-card characters
"*.", and the trailing part of the URL's domain is
identical to the part of the realm following the
"*." wildcard, or
</li>
<li>
The URL's domain is identical to the realm's domain
</li>
</ol>
</li>
</ul><p>
When present, the "openid.return_to" URL MUST match the
"openid.realm", or the OP MUST return an error.
</p>
<p>
It is RECOMMENDED that OP's protect their end users from
requests with overly-general realms, like http://*.com/ or
http://*.co.uk/. Determining if a realm is overly-general is
at the discretion of the OP.
</p>
<a name="rfc.section.9.3"></a><h4><a name="anchor29">9.3</a>
Immediate Requests</h4>
<p>
When requesting authentication, the Relying Party MAY
request that the OP not interact with the end user. In
this case the OP MUST respond immediately with either an
assertion that authentication is successful, or a response
indicating that the request cannot be completed without
further user interaction. This is accomplished by an
authentication request with "openid.mode" set to
"checkid_immediate".
</p>
<a name="rfc.section.10"></a><h4><a name="responding_to_authentication">10</a>
Responding to Authentication Requests</h4>
<p>
When an authentication request comes from the User-Agent via
<a class='info' href='#indirect_comm'>indirect communication<span> (</span><span class='info'>Indirect Communication</span><span>)</span></a>,
the OP SHOULD identify the User-Agent, and determine whether
the end user wishes to complete the authentication. If the
end user can be identified and wishes to complete the
authentication, the OP should send a <a class='info' href='#positive_assertions'>positive assertion<span> (</span><span class='info'>Positive Assertions</span><span>)</span></a> to the
Relying Party.
</p>
<p>
Methods of identifying and authenticating the end user and
obtaining approval to return an OpenID Authentication
assertion are beyond the scope of this specification.
</p>
<p>
If no Identifier was specified in the request and there are
Identifiers in the control of the end user, the OP SHOULD
allow the end user to choose which Identifier to use. If an
Identifier was specified, the OP SHOULD only issue assertions
about the specified Identifier.
</p>
<p>
If the Relying Party supplied an association handle with the
authentication request, the OP SHOULD attempt to look up an
association based on that handle. If the association is
missing or expired, the OP SHOULD send the
"openid.invalidate_handle" parameter as part of the response
with the value of the request's "openid.assoc_handle"
parameter, and SHOULD proceed as if no association handle was
specified.
</p>
<p>
If no association handle is specified, the OP SHOULD create a
private association for signing the response. The OP MUST
store this association and MUST respond to later requests to
check the signature of the response in <a class='info' href='#verifying_signatures'>stateless mode<span> (</span><span class='info'>Verifying Signatures</span><span>)</span></a>.
</p>
<p>
If the "openid.return_to" value is ommitted in the request, it
signifies that the initiating server does not wish to for the
end user to be returned to it as something else useful will
have been performed via an extension.
</p>
<a name="rfc.section.10.1"></a><h4><a name="positive_assertions">10.1</a>
Positive Assertions</h4>
<p>
Positive assertions are <a class='info' href='#indirect_comm'>indirect responses<span> (</span><span class='info'>Indirect Communication</span><span>)</span></a> with the following fields:
</p>
<p>
</p>
<ul class="text">
<li>
openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
Note: This defines the interpretation of the OpenID
Authentication arguments without a namespace. To be
an OpenID Authentication 2.0 response, the given
value MUST be present.
</p>
</blockquote>
</li>
<li>
openid.mode
<blockquote class="text">
<p>Value: "id_res"
</p>
</blockquote>
</li>
<li>
openid.claimed_id
<blockquote class="text">
<p>
Value: (optional) The Claimed Identifier. Verbatim copy
of the openid.claimed_id received in the authentication
request (if present). MUST be present if, and only if,
openid.identity is present.
</p>
<p>
Note: The Claimed Identifier is the same as the
OP-Specific Identifier if a different OP-Specific
Identifier is not supplied. If neither value is
present, the assertion is not about an identifier,
and will contain other information in its payload,
using <a class='info' href='#extensions'>extensions<span> (</span><span class='info'>Extensions</span><span>)</span></a>.
</p>
</blockquote>
</li>
<li>
openid.identity
<blockquote class="text">
<p>
Value: (optional) The OP-Specific Identifier
</p>
<p>
Note: The openid.identity field MAY be omitted if an
extension is in use that makes the response
meaningful without it (see openid.claimed_id above).
</p>
</blockquote>
</li>
<li>
openid.return_to
<blockquote class="text">
<p>
Value: Verbatim copy of the return_to URL parameter
sent in the request.
</p>
<p>
Note: Because the "openid.return_to" URL is signed
by the OP, a Relying Party can make sure outside
parties haven't sent responses with query parameters
that were not included in the "openid.return_to"
URL.
</p>
</blockquote>
</li>
<li>
openid.response_nonce
<blockquote class="text">
<p>
Value: A string that MUST be unique to this
particular successful authentication response. The
nonce MUST start with the current time on the
server, and MAY have additional characters appended
to the end as necessary to make each response
unique. The date and time MUST be formatted as
specified in section 5.6 of <a class='info' href='#RFC3339'>[RFC3339]<span> (</span><span class='info'>Newman, C. and G. Klyne, “Date and Time on the Internet: Timestamps,” .</span><span>)</span></a>, with the following restrictions:
</p>
<ul class="text">
<li>
All times must be in the UTC
timezone, indicated with a "Z".
</li>
<li>
No fractional seconds are allowed
</li>
</ul>
For example: 2005-05-15T17:11:51ZUNIQUE
</blockquote>
</li>
<li>
openid.invalidate_handle
<blockquote class="text">
<p>
Value: (optional) If the Relying Party sent an
invalid association handle with the request, it
SHOULD be included here.
</p>
</blockquote>
</li>
<li>
openid.assoc_handle
<blockquote class="text">
<p>
Value: The handle for the association that was used
to sign this assertion.
</p>
</blockquote>
</li>
<li>
openid.signed
<blockquote class="text">
<p>
Value: Comma-separated list of signed fields.
</p>
<p>
Note: This entry consists of the fields without the
"openid." prefix that the signature covers. This
list MUST contain at least "return_to" and
"response_nonce", and if present in the response,
"claimed_id" and "identity". For example,
"identity,claimed_id,return_to,response_nonce".
</p>
</blockquote>
</li>
<li>
openid.sig
<blockquote class="text">
<p>
Value: Base 64 encoded signature calculated as
specified in <a class='info' href='#generating_signatures'>Section 6<span> (</span><span class='info'>Generating Signatures</span><span>)</span></a>.
</p>
<p>
Note: Successful authentication messages from the
OP to the Relying Party MUST be signed.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.10.2"></a><h4><a name="negative_assertions">10.2</a>
Negative Assertions</h4>
<p>
If the OP is unable to identify the end user or the end
user does not or cannot approve the authentication request,
the OP SHOULD send a negative assertion to the Relying
Party as an <a class='info' href='#indirect_comm'>indirect
response<span> (</span><span class='info'>Indirect Communication</span><span>)</span></a>.
</p>
<p>
When receiving a negative assertion in response to an
immediate mode request, Relying Parties SHOULD
construct a new authentication request using the
"checkid_setup" mode to complete the transaction. This is a
change from OpenID Authentication 1.1 and more details can
be found in <a class='info' href='#compat_mode'>Section 12<span> (</span><span class='info'>OpenID Authentication 1.1 Compatibility</span><span>)</span></a>.
</p>
<a name="rfc.section.10.2.1"></a><h4><a name="anchor30">10.2.1</a>
In Response to Immediate Requests</h4>
<p>
If the request was an immediate request, there is no chance
for the end user to interact with pages on the OP to provide
identifying credentials or approval of a request.
A negative assertion of an immediate request takes the
following form:
</p>
<ul class="text">
<li>
openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 immediate negative assertion.
</p>
</blockquote>
</li>
<li>
openid.mode
<blockquote class="text">
<p>Value: "id_res"
</p>
</blockquote>
</li>
<li>
openid.user_setup_url
<blockquote class="text">
<p>
Value: A URL that the end user may visit to
complete the request. The Relying Party may
redirect the end user to this URL, or provide the
end user with a link that points to this URL. The
request is no longer immediate.
</p>
</blockquote>
</li>
</ul><p>
</p>
<a name="rfc.section.10.2.2"></a><h4><a name="anchor31">10.2.2</a>
In Response to Non-Immediate Requests</h4>
<p>
Since the OP may display pages to the end user and
request credentials from the end user, a negative response
to a request that is not immediate is definitive. It
takes the following form:
</p>
<ul class="text">
<li>
openid.ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 non-immediate negative assertion.
</p>
</blockquote>
</li>
<li>
openid.mode
<blockquote class="text">
<p>
Value: "cancel"
</p>
</blockquote>
</li>
</ul><p>
</p>
<p>
In a lot of cases, the Relying Party won't get a cancel
mode response; the end user will just quit or press back
within their User-Agent. But if it is returned, the
Relying Party SHOULD return to what it was doing.
</p>
<a name="rfc.section.11"></a><h4><a name="verification">11</a>
Verifying Assertions</h4>
<p>
When the Relying Party receives a positive assertion, it MUST
verify the following before accepting the assertion:
</p>
<ul class="text">
<li>
An assertion has not yet been accepted from this
OP with the same value for "openid.response_nonce"
</li>
<li>
The signature on the assertion is valid
</li>
<li>
Discovered information from the Identifier matches the
information in the assertion.
</li>
</ul><p>
If all three of these conditions are met, the Claimed
Identifier in the response is now verified.
</p>
<a name="rfc.section.11.1"></a><h4><a name="anchor32">11.1</a>
Checking the Nonce</h4>
<p>
To prevent replay attacks, the agent checking the signature
SHOULD keep track of the nonce values included in positive
assertions and never accept the same value more than once
for the same OP Endpoint URL. When using
"check_authentication", the OP is responsible for
preventing replay attacks. When the Relying Party checks the
signature on an assertion, it is responsible for preventing
replay attacks.
</p>
<p>
The time-stamp may be used to reject responses that are too
far away from the current time, limiting the amount of time
that nonces must be stored to prevent attacks. The
acceptable range is implementation dependent. A larger range
requires storing more nonces for a longer time. A shorter
range increases the chance that clock-skew and transaction
time will cause a spurious rejection.
</p>
<a name="rfc.section.11.2"></a><h4><a name="verifying_signatures">11.2</a>
Verifying Signatures</h4>
<p>
If the Relying Party has stored an association with the
association handle specified in the assertion, it MUST check
the signature on the assertion itself. If it does not have
an association stored, it MUST <a class='info' href='#check_auth'>request that the OP verify the
signature<span> (</span><span class='info'>Verifying Directly with the OpenID Provider</span><span>)</span></a> via Stateless mode.
</p>
<a name="rfc.section.11.2.1"></a><h4><a name="anchor33">11.2.1</a>
Verifying with an Association</h4>
<p>
The Relying Party follows the same procedure that the
OP followed in <a class='info' href='#generating_signatures'>generating the signature<span> (</span><span class='info'>Generating Signatures</span><span>)</span></a>, and then compares the
signature in the response to the signature it
generated. If the signatures do not match, the assertion
is invalid.
</p>
<p>
If an authentication request included an association
handle for an association between the OP and the Relying
party, and the OP no longer wishes to use that handle
(because it has expired or the secret has been
compromised, for instance), the OP will send a response
that must be verified directly with the OP, as specified
in <a class='info' href='#check_auth'>Section 11.2.2<span> (</span><span class='info'>Verifying Directly with the OpenID Provider</span><span>)</span></a>. In that instance, the OP
will include the field "openid.invalidate_handle" set to
the association handle that the Relying Party included
with the original request.
</p>
<a name="rfc.section.11.2.2"></a><h4><a name="check_auth">11.2.2</a>
Verifying Directly with the OpenID Provider</h4>
<p>
To verify a signature directly with the OP, the Relying
Party sends a <a class='info' href='#direct_request'>direct
request<span> (</span><span class='info'>Direct Request</span><span>)</span></a> to the OP. This is known as Stateless
mode.
</p>
<a name="rfc.section.11.2.2.1"></a><h4><a name="anchor34">11.2.2.1</a>
Request Parameters</h4>
<p>
</p>
<ul class="text">
<li>
openid.mode
<blockquote class="text">
<p>Value: "check_authentication"
</p>
</blockquote>
</li>
<li>
Exact copies of all fields from the authentication
response, except for "openid.mode".
</li>
</ul><p>
</p>
<a name="rfc.section.11.2.2.2"></a><h4><a name="anchor35">11.2.2.2</a>
Response Parameters</h4>
<p>
</p>
<ul class="text">
<li>
ns
<blockquote class="text">
<p>
Value: "http://openid.net/signon/2.0"
</p>
<p>
This value MUST be present for the response to
be a valid OpenID 2.0 verification response.
</p>
</blockquote>
</li>
<li>
mode
<blockquote class="text">
<p>Value: "id_res"
</p>
</blockquote>
</li>
<li>
is_valid
<blockquote class="text">
<p>Value: "true" or "false"
</p>
<p>Description: Boolean; whether the signature is
valid.
</p>
</blockquote>
</li>
<li>
invalidate_handle
<blockquote class="text">
<p>
Value: (optional) An association handle
</p>
<p>
Description: The association handle sent in
the request, if the server confirms that it is
invalid.
</p>
</blockquote>
</li>
</ul><p>
</p>
<p>
An OP MUST NOT verify signatures for associations that
have shared MAC keys. If an OP did verify signatures
for associations with shared MAC keys, it would be
possible for parties other than the OP to create valid
assertions that seemed to come from the OP.
</p>
<p>
The OP SHOULD only return "is_valid" once for each
authentication response. An authentication response may
be identified by its "openid.response_nonce" value.
</p>
<p>
If the OP responds with "is_valid" set to
"true", and "invalidate_handle" is present, the Relying
Party SHOULD NOT send further authentication requests
with that handle. "invalidate_handle" will only be
present when the original authentication request to the
OP included an association that the OP deemed
invalid. This implies that it will only be present in
this response if it was also present in the <a class='info' href='#positive_assertions'>"id_res"
response<span> (</span><span class='info'>Positive Assertions</span><span>)</span></a>. Including "invalidate_handle" in the
direct verification is necessary to prevent an attacker
from invalidating an association at will by adding it to
an authentication response.
</p>
<a name="rfc.section.11.3"></a><h4><a name="anchor36">11.3</a>
Verifying Discovered Information</h4>
<p>
The Claimed Identifier MUST have been <a class='info' href='#discovery'>discovered<span> (</span><span class='info'>Discovery</span><span>)</span></a> by the Relying Party
and the information in the assertion MUST exactly match the
discovered information.
</p>
<p>
If the Claimed Identifier was not present in the request
("openid.identity" was
"http://openid.net/identifier_select/2.0"), the Relying
Party MUST perform discovery on the Identifier in the
response to make sure that the OP is authorized to make
assertions about the Claimed Identifier.
</p>
<a name="rfc.section.11.4"></a><h4><a name="identifying">11.4</a>
Identifying the end user</h4>
<p>
The Claimed Identifier in a successful authentication
response MAY be used as a user-visible Identifier. The
Relying Party SHOULD use it as a key for local storage of
information about the end user.
</p>
<p>
If an assertion is made for a Claimed Identifier which
has not been discovered, the Relying Party MUST
perform discovery on that Identifier and verify that the
discovered information matches that in the assertion,
including that the OP is authoritative for the Identifier.
</p>
<a name="rfc.section.11.4.1"></a><h4><a name="http_s_identifiers">11.4.1</a>
HTTP and HTTPS URL Identifiers</h4>
<p>
Relying Parties MUST differentiate between URL Identifiers
that have different schemes. When user input is processed
into a URL, it is processed into a HTTP URL. If the same
end user controls the same URL, differing only by scheme,
and it is desired that the Identifier be the HTTPS URL, it
is RECOMMENDED that a redirect be issued from the HTTP URL
to the HTTPS URL. Because the HTTP and HTTPS URLs are not
equivalent and the Identifier that is used is the URL
after following redirects, there is no reduction in
security when using this scheme. If an attacker could gain
control of the HTTP URL, it would have no effect on the
HTTPS URL, since the HTTP URL is not ever used as an
Identifier.
</p>
<a name="rfc.section.12"></a><h4><a name="compat_mode">12</a>
OpenID Authentication 1.1 Compatibility</h4>
<p>
OpenID Authentication 2.0 attempts to retain maximum
compatibility with earlier versions of the OpenID
Authentication specification, but this is not universally
possible. This section lists the behavioral changes required
of an OpenID Authentication 2.0 OP or Relying Party when
communicating with another party using OpenID Authentication
1.1.
</p>
<p>
OpenID Authentication 2.0 implementations SHOULD support
OpenID Authentication 1.1 compatibility, unlesss security
considerations make it undesirable.
</p>
<p>
All messages in OpenID Authentication 1.1 omit the "openid.ns"
parameter, which is an easy way for an RP to determine if the
message is from an OpenID Authentication 1.1 endpoint. OpenID
Authentication 1.1 in practice only supports HMAC-SHA1
associations.
</p>
<a name="rfc.section.12.1"></a><h4><a name="anchor37">12.1</a>
Relying Parties</h4>
<p>
</p>
<ul class="text">
<li>
Relying Parties MUST implement <a class='info' href='#html_disco'>HTML-Based Discovery<span> (</span><span class='info'>HTML-Based Discovery</span><span>)</span></a>.
</li>
<li>
Relying Parties MUST send a blank session_type parameter
in "no-encryption" association requests.
</li>
<li>
Relying Parties MUST accept a "no-encryption" association
response with a blank or missing session_type parameter,
if they choose to accept "no-encryption" sessions.
</li>
<li>
In <a class='info' href='#requesting_authentication'>authentication
requests<span> (</span><span class='info'>Requesting Authentication</span><span>)</span></a>, the "openid.identity" parameter MUST NOT
be the special value
"http://openid.net/identifier_select/2.0", because OpenID
Authentication 1.1 does not support the use of OP
Identifiers.
</li>
<li>
The "openid.realm" parameter in authentication requests
was known as "openid.trust_root". The syntax and meaning
are identical.
</li>
<li>
When responding with a negative assertion to a
"checkid_immediate" mode authentication request, the
"user_setup_url" paramater MUST be returned. This is a
URL that the end user may visit to complete the
request. The OP may redirect the end user to
this URL, or provide the end user with a link that
points to this URL.
</li>
<li>
The Relying Party MUST accept an <a class='info' href='#positive_assertions'>authentication
response<span> (</span><span class='info'>Positive Assertions</span><span>)</span></a> that is missing the
"openid.response_nonce" parameter. It SHOULD however
implement an out-of-band method for preventing replay
attacks.
</li>
</ul><p>
</p>
<a name="rfc.section.12.2"></a><h4><a name="anchor38">12.2</a>
OpenID Providers</h4>
<p>
</p>
<ul class="text">
<li>
"openid.identity" MUST be sent in a <a class='info' href='#positive_assertions'>positive authentication
assertion<span> (</span><span class='info'>Positive Assertions</span><span>)</span></a>.
</li>
<li>
OPs MUST accept a "no-encryption" association request
with a blank session_type parameter, if they choose to
accept "no-encryption" sessions.
</li>
<li>
OPs MUST accept association requests with no assoc_type
parameter, and assume them to be of type HMAC-SHA1.
</li>
<li>
<a class='info' href='#refuse_assoc'>Unsuccessful association
responses<span> (</span><span class='info'>Unsuccessful Response Parameters</span><span>)</span></a> MUST NOT be sent, since they are not
part of the OpenID Authentication 1.1 protocol.
</li>
<li>
OPs MAY choose to return a successful "no-encryption"
response to any association request.
</li>
<li>
Omit or set to blank the "session_type" parameter when
making "no-encryption" responses to association requests.
</li>
<li>
The "openid.realm" parameter in authentication requests
was known as "openid.trust_root". The syntax and meaning
are identical.
</li>
<li>
When responding with a negative assertion to a
"checkid_immediate" mode authentication request, the
"user_setup_url" paramater MUST be returned. This is a URL
that the end user may visit to complete the request. The
Relying Party may redirect the end user to this URL, or
provide the end user with a link that points to this
URL.
</li>
</ul><p>
</p>
<a name="rfc.section.13"></a><h4><a name="extensions">13</a>
Extensions</h4>
<p>
An Extension to OpenID Authentication is a protocol that
"piggybacks" on the authentication request and response. Extensions
are useful for providing extra information about an
authentication request or response as well as providing extra
information about the subject of the authentication response.
</p>
<p>
OpenID extensions are identified by a Type URI. The Type URI
MAY be used as the value of an <xrd:Type> element of an
OpenID <xrd:Service> element in an XRDS document
associated with a Claimed Identifier. The Type URI is also
used to associate key-value pairs in messages with the extension.
</p>
<p>
To associate keys and values in a message with an extension,
the key MUST be associated with the Type URI. To associate
keys with a Type URI, establish an alias by adding a key
prefixed with "openid.ns." and ending with the alias text
whose value is the Type URI. Once an alias has been
established, all pairs in the message whose keys start with
"openid." followed by the alias text, followed by a period or
the end of the key are associated with that extension.
</p>
<p>
A namespace alias MUST NOT contain a period, MUST NOT be the
name of a field in a message defined in this specification,
and MUST NOT be the same as another namespace alias in the
same message. A namespace MUST NOT be assigned more than one
alias in the same message. If a message is a response to
another message, the response MAY use a different alias to
refer to the same namespace.
</p>
<p>Non-normative example:
</p>
<p>An extension's type URI is
"<http://example.com/ext/1.0>".
</p>
<blockquote class="text">
<p>openid.ns.x=http://example.com/ext/1.0
</p>
<p>openid.x=example
</p>
<p>openid.x.foo=bar
</p>
<p>openid.xx=notx
</p>
</blockquote><p>
In this example, the keys openid.x and openid.x.foo are
associated with the extension; the openid.xx key is not.
</p>
<p>
Extensions MUST NOT define parameters with the same name. It
is RECOMMENDED that commas are used as value delimiters,
though other characters may be better suited in
certain situations. Another approach is to append a
numeric value to each key to differentiate between each value.
</p>
<a name="rfc.section.14"></a><h4><a name="anchor39">14</a>
Discovering OpenID Relying Parties</h4>
<p>
Relying Parties are RECOMMENDED to use the Yadis protocol to
publish their return_to URL. This allows for automated
discovery of OpenID Relying Parties.
</p>
<p>
In this case, the XRDS document published by the Relying
Party, SHOULD have an <xrd:Service> element where the
content of the <xrd:URI> tag is the return_to URL and
the content of the <xrd:Type> tag is
"http://openid.net/return_to/2.0".
</p>
<p>For example:
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
<Service xmlns="xri://$xrd*($v*2.0)">
<Type>http://openid.net/return_to/2.0</Type>
<URI>http://consumer.example.com/return</URI>
</Service>
</pre></div>
<a name="rfc.section.15"></a><h4><a name="anchor40">15</a>
Security Considerations</h4>
<a name="rfc.section.15.1"></a><h4><a name="anchor41">15.1</a>
Preventing Attacks</h4>
<a name="rfc.section.15.1.1"></a><h4><a name="preventing_eavesdropping">15.1.1</a>
Eavesdropping Attacks</h4>
<p>
There are two places in this protocol that are vulnerable
to eavesdropping attacks. An eavesdropper could intercept
an unencrypted association session and recover the shared
secret, allowing an attacker to masquerade as the OP to
that relying party. An eavesdropper could also intercept a
successful authentication assertion and re-use it, if the
nonce is not checked.
</p>
<p>
Both of these attacks can be prevented by using SSL for
these connections. The association session can also use
Diffie-Hellman Key Exchange instead of "no-encryption" to
protect from eavesdropping. If the nonce is checked in
message verification, the positive authentication
assertion cannot be re-used.
</p>
<a name="rfc.section.15.1.2"></a><h4><a name="anchor42">15.1.2</a>
Man-in-the-Middle Attcks</h4>
<p>
Associations prevent tampering of signed fields by a man
in the middle, except during discovery, association
sessions and stateless mode. Altering signed fields
without the shared secret requires breaking the
MAC. Currently, no tractable attack is known on the MACs
used in this protocol. The quality of the protection
provided by the MAC depends on the randomness of the
shared MAC key, so it is important that an unguessable
value be used.
</p>
<p>
If DNS resolution or the transport layer is compromised,
signatures on messages are not adequate, since the
attacker can impersonate the OP and issue its own
associations, or its own decisions in stateless mode. If
an attacker can tamper with the discovery process, he can
specify any OP, and so does not have to impersonate the
OP.
</p>
<p>
Using SSL with certificates signed by a trusted authority
prevents these kinds of attacks by verifying the results
of the DNS look-up against the certificate. Once the
validity of the certificate has been established,
tampering is not possible. Impersonating an SSL server
requires forging or stealing a certificate, which is
significantly harder than the network attacks.
</p>
<p>
In order to get protection from SSL, SSL must be used for
all parts of the interaction, including interaction with
the end user through the User-Agent. While the protocol
does not require SSL be used, its use is strongly
RECOMMENDED. Current best practicies dictate that an OP
SHOULD use SSL, with a certificate signed by a trusted
authority, to secure its service endpoint. In addition,
SSL, with a certificate signed by a trusted authority,
SHOULD be used so that a Relying Party can fetch the
end user's URL in a secure manner. Following its own
security policies, a Relying Party MAY choose to not
complete, or even begin, a transaction if SSL is not being
correctly used at these various endpoints.
</p>
<a name="rfc.section.15.2"></a><h4><a name="anchor43">15.2</a>
User-Agents</h4>
<p>
Since this protocol is intended to be used interactively,
User-Agents will primarily be common Web browsers. Web
browsers or their hosts may be infected with spyware or
other malware, which limits the strength of the
authentication assertion, since untrusted software makes it
impossible to know whether the authentication decision has
been made with the end user's approval. With that said, many
web applications and protocols today rely on the security of
the Web browser and their hosts.
</p>
<p>
Cross-site-scripting attacks against OPs may be used to the
same effect. For the best security, OPs should not depend
on scripting. This enables User-Agents that do not support
scripting, or have scripting disabled, to still employ the
protocol.
</p>
<a name="rfc.section.15.3"></a><h4><a name="anchor44">15.3</a>
User Interface Considerations</h4>
<p>
The Relying Party SHOULD redirect the end user to the OP
Endpoint URL in a top-level browser window with all controls
visible. This allows better protection for the end user
against OP look-alike sites (phishing).
</p>
<p>
OPs SHOULD educate their end users about the potential for
OpenID phishing attacks and SHOULD equip their end users
with the tools to defeat such attacks, for example browser
plugins that verify the authenticity of the OP's
Authentication Service Endpoint URL.
</p>
<a name="rfc.section.A"></a><h4><a name="anchor45">Appendix A</a>
Examples</h4>
<p>Non-normative
</p>
<a name="rfc.section.A.1"></a><h4><a name="anchor46">Appendix A.1</a>
OP-Specific Identifiers</h4>
<p>
An end user wants to use "http://www.example.com/" as their
Claimed Identifier. The end user has an account with
Example Provider, which functions as an OpenID Provider. The
end user's OP-Specific Identifier is
"https://exampleuser.exampleprovider.com/".
</p>
<p>
In this scenerio, with the proper configuration of Yadis or
HTML-based Discovery (see <a class='info' href='#discovery'>Section 7.3<span> (</span><span class='info'>Discovery</span><span>)</span></a> and
<a class='info' href='#XRDS Sample'>Appendix A.2<span> (</span><span class='info'>XRDS</span><span>)</span></a> below), a Relying Party will
discover the following information about the end user:
</p>
<blockquote class="text"><dl>
<dt>Claimed Identifier</dt>
<dd>
http://www.example.com/
</dd>
<dt>OP-Specific Identifier</dt>
<dd>
https://exampleuser.exampleprovider.com/
</dd>
</dl></blockquote><p>
</p>
<a name="rfc.section.A.2"></a><h4><a name="XRDS Sample">Appendix A.2</a>
XRDS</h4>
<p>
<p>
For an end user to use "http://www.example.com/" as
their Identifier, but have Relying Parties actually
verify https://exampleuser.exampleprovider.com/ with the OP
Endpoint URL
https://www.exampleprovider.com/endpoint/, the
following XML snippet should be present in the final XRD
element in the XRDS file when discovery is preformed on
"http://www.example.com":
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
<Service xmlns="xri://$xrd*($v*2.0)">
<Type>http://openid.net/signon/2.0</Type>
<URI>https://www.exampleprovider.com/endpoint/</URI>
<LocalID>https://exampleuser.exampleprovider.com/</LocalID>
</Service>
</pre></div>
<a name="rfc.section.A.3"></a><h4><a name="anchor47">Appendix A.3</a>
HTML Identifier Markup</h4>
<p>
To use www.example.com as their Identifier, but have
Relying Parties actually verify
http://exampleuser.livejournal.com/ with the OpenID
Provider located at
http://www.livejournal.com/openid/server.bml, the
following markup should be present in the <head>
of the HTML document located by the identifier URL:
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
<link rel="openid.server"
href="http://www.livejournal.com/openid/server.bml"/>
<link rel="openid.delegate"
href="http://exampleuser.livejournal.com/"/>
</pre></div>
<a name="rfc.section.A.4"></a><h4><a name="anchor48">Appendix A.4</a>
Login Form</h4>
<p>
The end user visits a Relying Party site which supports
OpenID Authentication. The Relying Party presents the end
user with a form field for them to enter their Claimed
Identifier or their OP Identifier.
</p>
<p>
<p>For example:
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
----------------------------------
|[logo]example.com | [Login Button]
----------------------------------
</pre></div>
<a name="rfc.section.A.5"></a><h4><a name="anchor49">Appendix A.5</a>
XRI CanonicalID</h4>
<p>
For example, if the XRI i-names =example and =exmpl both
yield an XRDS document with the CanonicalID
xri://(example)!1234 then those Identifiers should be
treated as equivalent. For applications with user accounts,
the persistant Canonical ID xri://(example)!1234 should be
used the the primary key for the account. Although the
i-names =example and =exmpl may also be stored for reference
as display names, they are reassignable identifier and
should not be used as persistent keys.
</p>
<a name="rfc.section.B"></a><h4><a name="pvalue">Appendix B</a>
Diffie-Hellman Key Exchange Default Value</h4>
<p>
This is a confirmed-prime number, used as the default
modulus for Diffie-Hellman Key Exchange. In hexadecimal:
</p><div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
DCF93A0B883972EC0E19989AC5A2CE310E1D37717E8D9571BB7623731866E61E
F75A2E27898B057F9891C2E27A639C3F29B60814581CD3B2CA3986D268370557
7D45C2E7E52DC81C7A171876E5CEA74B1448BFDFAF18828EFD2519F14E45E382
6634AF1949E5B535CC829A483B8A76223E5D490A257F05BDFF16F2FB22C583AB
</pre></div>
<a name="rfc.section.C"></a><h4><a name="anchor50">Appendix C</a>
Changes from the Previous OpenID Authentication Specification</h4>
<p>
This specification is based on the original specification for
OpenID Authentication as written by Brad Fitzpatrick. That
specification did not have a version number, but was called
OpenID 1.0, and then OpenID 1.1 when it was revised. The
protocol outlined in this specification is intended to be
backwards-compatible with the revised OpenID protocol. The
most significant changes to the specification are outlined in
this section.
</p>
<a name="rfc.section.C.1"></a><h4><a name="anchor51">Appendix C.1</a>
Updated Initiation and Discovery</h4>
<p>
</p>
<ul class="text">
<li>
Supports OP Identifiers. This new variation of the
protocol flow is initiated by an end user entering an OP
Identifier instead of a Public Identifier. This allows
the OP to assist the end user in selecting an
Identifier, which may be either a Public Identifier (one
of multiple "personas"), or a Private Identifier (which
may be generated by the OP to be used only in the
context of a single RP).
</li>
<li>
Supports the use of XRIs as Identifiers. XRIs may be
used as Identifiers for both end users and OPs, and
provide automatic mapping from one or more reassignable
i-names to a synonymous persistent Canonical ID that
will never be reassigned.
</li>
<li>
When URLs are used as Identifiers, they are normalized
according to the guidelines in <a class='info' href='#RFC3986'>[RFC3986]<span> (</span><span class='info'>Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,” .</span><span>)</span></a>, for better compatibility with existing Web infrastructure.
</li>
<li>
Uses the Yadis protocol for discovery. This allows for
using multiple OPs for a single Identifier, for
load-balancing and fallback in the case of OP
failure. Additionally, it allows for discovery of
supported extensions and other associated services.
</li>
</ul><p>
</p>
<a name="rfc.section.C.2"></a><h4><a name="anchor52">Appendix C.2</a>
Security improvements</h4>
<p>
A nonce is now part of the protocol for built-in protection
against replay attacks, which was previously implemented out of
band by each library or application.
</p>
<p>
A new association type, HMAC-SHA256, and a new association
session type, DH-SHA256, allow for stronger signatures on
authentication assertions.
</p>
<a name="rfc.section.C.3"></a><h4><a name="anchor53">Appendix C.3</a>
Extensions</h4>
<p>
Extensions are now an officially supported mechanism to
support data exchange and other Relying Party-OP
communication along with the authentication
exchange. Extensions allow for the exchange of arbitrary
attributes, as well as for protocol extensions,
such as the inclusion of additional information about the
Relying Party in the authentication request.
</p>
<p>
Because extensions can transfer arbitrary data, the
Identifier is now optional in the response.
</p>
<a name="rfc.references1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table>
<h3>16. Normative References</h3>
<table width="99%" border="0">
<tr><td class="author-text" valign="top"><a name="FIPS180-2">[FIPS180-2]</a></td>
<td class="author-text">U.S. Department of Commerce and National Institute of Standards
and Technology, “<a href="http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf">Secure Hash Signature Standard</a>,” FIPS 180-2.<p>
Defines Secure Hash Algorithm 256 (SHA256)
</p>
</td></tr>
<tr><td class="author-text" valign="top"><a name="HTML401">[HTML401]</a></td>
<td class="author-text">W3C, “<a href="http://www.w3.org/TR/html401">HTML 4.01 Specification</a>.”</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC1750">[RFC1750]</a></td>
<td class="author-text">Eastlake, D., Crocker, S., and J. Schiller, “<a href="ftp://ftp.isi.edu/in-notes/rfc1750.txt">Randomness Recommendations for Security</a>,” RFC 1750.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2104">[RFC2104]</a></td>
<td class="author-text">Krawczyk, H., Bellare, M., and R. Canetti, “<a href="ftp://ftp.isi.edu/in-notes/rfc2104.txt">HMAC: Keyed-Hashing for Message Authentication</a>,” RFC 2104.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2119">[RFC2119]</a></td>
<td class="author-text">Bradner, B., “<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">Key words for use in RFCs to Indicate Requirement Levels</a>,” RFC 2119.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2616">[RFC2616]</a></td>
<td class="author-text">Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “<a href="ftp://ftp.isi.edu/in-notes/rfc2616.txt">Hypertext Transfer Protocol -- HTTP/1.1</a>,” RFC 2616.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2631">[RFC2631]</a></td>
<td class="author-text">Rescorla, E., “<a href="ftp://ftp.isi.edu/in-notes/rfc2631.txt">Diffie-Hellman Key Agreement Method</a>,” RFC 2631.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3174">[RFC3174]</a></td>
<td class="author-text">Eastlake, D. and P. Jones, “<a href="ftp://ftp.isi.edu/in-notes/rfc3174.txt">US Secure Hash Algorithm 1 (SHA1)</a>,” RFC 3174.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3339">[RFC3339]</a></td>
<td class="author-text">Newman, C. and G. Klyne, “<a href="ftp://ftp.isi.edu/in-notes/rfc3174.txt">Date and Time on the Internet: Timestamps</a>,” RFC 3174.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3548">[RFC3548]</a></td>
<td class="author-text">Josefsson, S., “<a href="ftp://ftp.isi.edu/in-notes/rfc3548.txt">The Base16, Base32, and Base64 Data Encodings</a>,” RFC 3548.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3629">[RFC3629]</a></td>
<td class="author-text">Yergeau, F., “<a href="ftp://ftp.isi.edu/in-notes/rfc3629.txt">UTF-8, a transformation format of Unicode and ISO 10646</a>,” RFC 3629.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3986">[RFC3986]</a></td>
<td class="author-text">Berners-Lee, T., “<a href="ftp://ftp.isi.edu/in-notes/rfc3986.txt">Uniform Resource Identifiers (URI): Generic Syntax</a>,” RFC 3986.</td></tr>
<tr><td class="author-text" valign="top"><a name="XRI Resolution 2.0">[XRI Resolution 2.0]</a></td>
<td class="author-text">Wachob, G., Reed, D., Chasen, L., Tan, W., and S. Churchill, “<a href="http://www.oasis-open.org/committees/download.php/17293">Extensible Resource Identifier (XRI) Resolution V2.0
- Working Draft 10</a>” (<a href="http://www.oasis-open.org/committees/download.php/17293">PDF</a>).</td></tr>
<tr><td class="author-text" valign="top"><a name="XRI Syntax 2.0">[XRI Syntax 2.0]</a></td>
<td class="author-text">Reed, D. and D. McAlpin, “<a href="http://www.oasis-open.org/committees/download.php/15376">Extensible Resource Identifier (XRI) Syntax V2.0</a>” (<a href="http://www.oasis-open.org/committees/download.php/15376">HTML</a>, <a href="http://www.oasis-open.org/committees/download.php/15377">PDF</a>).</td></tr>
<tr><td class="author-text" valign="top"><a name="Yadis">[Yadis]</a></td>
<td class="author-text">Miller, J., “Yadis Specification 1.0” (<a href="http://yadis.org/papers/yadis-v1.0.pdf">PDF</a>, <a href="http://yadis.org/papers/yadis-v1.0.odt">ODT</a>).</td></tr>
</table>
<a name="rfc.authors"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table>
<h3>Authors' Addresses</h3>
<table width="99%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="author-text"> </td>
<td class="author-text">David Recordon</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">VeriSign, Inc.</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">487 E Middlefield Road</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Mountain View, CA 94109</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">USA</td></tr>
<tr><td class="author" align="right">Email: </td>
<td class="author-text"><a href="mailto:drecordon@verisign.com">drecordon@verisign.com</a></td></tr>
<tr cellpadding="3"><td> </td><td> </td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Josh Hoyt</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">JanRain, Inc.</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">5331 SW Macadam Avenue</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Suite #375</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Portland, OR 97239</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">USA</td></tr>
<tr><td class="author" align="right">Email: </td>
<td class="author-text"><a href="mailto:josh@janrain.com">josh@janrain.com</a></td></tr>
<tr cellpadding="3"><td> </td><td> </td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Dick Hardt</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Sxip Identity Corporation</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">798 Beatty Street</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Vancouver, BC V6B 2M1</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Canada</td></tr>
<tr><td class="author" align="right">Email: </td>
<td class="author-text"><a href="mailto:dick@sxip.com">dick@sxip.com</a></td></tr>
<tr cellpadding="3"><td> </td><td> </td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Brad Fitzpatrick</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">Six Apart, Ltd.</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">548 4th Street</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">San Francisco, CA 94107</td></tr>
<tr><td class="author-text"> </td>
<td class="author-text">USA</td></tr>
<tr><td class="author" align="right">Email: </td>
<td class="author-text"><a href="mailto:brad@danga.com">brad@danga.com</a></td></tr>
</table>
</body></html>