Proposal for an XRI (i-name) profile for OpenID

Victor Grey victor at 2idi.com
Sun Apr 2 18:45:59 UTC 2006


The following is my proposal for an XRI (i-name) profile for OpenID 
SSO. It modifies the identity server discovery steps to use XRI 
Resolution, and otherwise is the same as the basic OpenID protocol. The 
rest of what appears here is my understanding of the OpenID protocol. 
Feedback is very welcome, and most especially from anyone who can 
verify (or dispute) that my analysis of OpenID is actually correct.

=vg

---------------------------------------
Proposal for an XRI (i-name) profile for the OpenID SSO protocol

Actors:
Principal - the entity being authenticated (or interchangeably, her 
user agent).
SP - the service provider that wishes to authenticate the Principal.
IDA - the provider of an authentication service for the Principal.

The OpenID protocol (as I see it) has six distinct phases:
1. Principal presents the SP with an identity signifier.
2. SP uses the presented identity to discover the URL for the IDA.
3. SP acquires a secret key from the IDA (or a local cache).
4. SP redirects the Principal to the IDA with an authentication request.
5. IDA authenticates the Principal and redirects her to the SP with an 
authentication assertion.
6. SP verifies the authentication assertion via the secret key.

Step 3 can alternatively be folded into step 6. (OpenID calls this 
"dumb mode.")

The only difference between standard OpenID and the XRI profile is in 
steps 1 and 2. In standard OpenID the Principle presents a URL as an 
identifier, and the IDA URL is obtained by reading information in the 
HTTP header that is returned by the identity URL. In the XRI profile, 
the Principal presents an XRI (an i-name or an i-number), and the IDA 
URL is obtained by means of XRI resolution.

XRI profile in detail:

1. Principal presents the SP with an i-name or i-number
   a. Principal enters i-name in a form field and submits, or
   b. i-name or i-number is url-encoded into the GET request query 
string (e.g. "http://example.com/login.php?iname=%40example%2Ainame") 
or
   c. SP retrieves a cookie set on a previous authentication by this 
Principal, and determines i-name or i-number from it.

2. SP uses XRI Resolution to discover the Principal's authentication 
service URL. If more than one authentication service URL is sent in the 
resolution response, the first one in priority order (as defined by XRI 
Resolution 2.0) should be tried first, and if that fails, the SP MAY 
try the others, in order.

Optionally, resolution data may be cached by the SP for a period of 
time specified in the resolution response, and the authentication 
service URL retrieved from cache if available on subsequent visits by 
the Principal.

3. This is the optional "smart mode". We should consider requiring 
smart mode for the XRI profile.

   a. SP sends a POST request to the IDA, with the following required 
value:

     openid.mode=associate

     and the following optional values:

     openid.assoc_type=HMAC-SHA1
     ## This is the default if not sent, and the only value presently 
available.

     openid.session_type=DH-SHA1
     ## If this is not sent, the IDA will respond in cleartext.
     ## The IDA may respond in cleartext anyway, at which point the SP 
has to decide
     ##  whether to accept it. I propose that for the XRI profile, if 
the IDA is
     ##  using an https URL, cleartext over SSL be the recommended 
method, to save
     ##  the additional overhead of the Diffie-Hellman processing.

     ## If openid.session_type=DH-SHA1 is specified, then the following 
values apply.
     openid.dh_modulus
     openid.dh_gen
     openid.dh_consumer_public
     ## OpenID provides libraries in several languages to calculate 
these values.

   b. IDA responds with a plaintext file (UTF-8 encoded, but only ASCII 
is used),
     that contains key-value pairs in the format "somekey:somevalue\n".

     assoc_type:HMAC-SHA1
     ## the only type available presently

     assoc_handle:xxx
     ## an opaque handle for this association, must be <= 255 chars,
     ## in ASCII range 33..126 (printable non-whitespace characters)

     expires_in:nnn
     ## the number of seconds from now within which this association may 
be used

     session_type:DH-SHA1
     ## if absent, secret is being sent in cleartext.

     ## If using Diffie-Hellman:
     dh_server_public:base64value
     enc_mac_key:base64value  ## the encrypted shared secret
     ## OpenID provides libraries in several languages to calculate 
these values.
     ## SP uses DH library to decrypt the shared secret

     ## If using plaintext:
     mac_key:base64(shared secret value for the association keyed to the 
assoc_handle)


4. SP redirects the Principal to the IDA with an authentication 
request. This is
   necessarily a GET request, and includes the following query string 
parameters:

     openid.mode
     ## Value can be checkid_setup or checkid_immediate
     ## "checkid_immediate" assumes that the IDA can authenticate the 
Principal
     ##  without interaction. If this is not the case, see how this is
     ##  handled in step 5 below.

     openid.identity
     ## The XRI from step 1

     openid.assoc_handle
     ## From step 3b

     openid.return_to
     ## URL to which the SP wishes the Principal to be returned. IDA 
must preserve
     ##  any query string parameters in the return URL. It is suggested 
that
     ##  the SP include a self-signed nonce with local timestamp to 
resist
     ##  replay attacks.

     openid.trust_root
     ## Optional. The SP URL that the IDA may show to the Principal for 
approval.
     ##  The return_to URL must be descendant from the trust root, by a 
set
     ##  of rules described in the OpenID docs.

5. IDA authenticates the Principal and redirects her to the SP with an 
authentication assertion in the query string. The redirect URL must 
have appended to it the following parameters:

     openid.mode
     ## If the request was made with mode "checkid_immediate", but the 
IDA requires
     ##  interaction with the Principal, the mode is set to "cancel" and 
a
     ##  user_setup_url is returned. In any case, "cancel" indicates an
     ##  authentication failure, and "id_res" indicates success.

     openid.user_setup_url
     ## See above. SP may choose to redirect the Principal to this URL 
with
     ##  a "checkid_setup" request if an original checkid_immediate 
request failed.

     ## If authn is successful, the following params are also sent:

     openid.identity
     ## The XRI being authenticated

     openid.assoc_handle
     ## The assoc_handle to be used by the SP to find the HMAC key to 
verify the
     ##  signature. If it doesn't match the one sent in step 4, or the 
SP didn't
     ##  send one in step 4 (dumb mode), then see step 6.

     openid.return_to
     ## Must match the value transmitted in step 4.

     openid.signed
     ## Comma-separated list of params which the signature covers, 
without
     ##  the "openid" prefix, e.g "mode,identity,return_to"

     openid.sig
     ## base64(HMAC(secret + token_contents)), where token_contents is a 
string
     ##  in "key:value\n" format, with the keys as in the above 
"openid.signed" (in
     ##  that order), and the values from step 4, and the secret is the 
one
     ##  keyed by the "assoc_handle".

     ## The IDA may also send:
     openid.invalidate_handle
     ## If the server didn't accept the assoc_handle provided in step 4, 
it sends
     ##  it back as a value to this key, to tell you to stop using it. 
You must then
     ##  do the check_authentication in step 6.


6. SP verifies the authentication assertion via the secret key. If you 
can verify the openid.sig you are done. Otherwise,

   a. the SP sends a POST request to the IDA, with
the following fields:

     openid.mode=check_authentication

     openid.*
     ## All the openid.* response params the SP got back from step 5, 
with their
     ##  values, exactly as received.

     openid.invalidate_handle
     ## SP can optionally send this to check that the invalidate_handle 
command
     ##  actually came from the IDA

   b. The IDA returns, in "key:value\n" format:

     is_valid
     ## "true" or "false"

     invalidate_handle
     ## If present, the SP should delete this handle from its cache.

#########################
Error handling:
This section pertains to protocol/run-time errors, not authentication 
errors.

If it's a GET request with bad arguments but a valid return_to URL, 
redirect with openid.mode=error and openid.error=Error+Text.

If it's a GET request with bad arguments, and no valid return_to, 
return a "400 Bad Request" with any content-type and error message you 
want.

If it's a GET request with no arguments, show a 200 text/html saying 
"This is an OpenID server endpoint. For more information, see 
http://openid.net/"

If it's a POST request with bad/no arguments, return a 400 Bad request 
with the key-value response format ("key:value\n"), with a single key 
"error" with the natural language text.

Limits:
XRI: 255 bytes
IDA URL: 2047 bytes, including the query string
SP return_to URL: 2047 bytes, including the query string
assoc_handle: 255 chars in ASCII range 33..126











More information about the yadis mailing list