Proposed Specification for New Consumer-Server Commnunications
Nathan D. Bowen
nbowen+yadis at andtonic.com
Wed Jun 8 14:37:40 PDT 2005
The old communication between the server and consumer could be described as:
Request: The Consumer requests a DSA public key from the Server by
adding the GET parameter openid.mode of value getpubkey
Response: The Server returns the DSA public key in PEM format.
The new communication, could be described more as "establishing an
association" than as "getting a key", and the communication is
necessarily more complex.
It should be easier to discuss these things if we all share a vocabulary
for them.
I'll take a stab here:
Establishing Consumer-Server Associations
=========================================
Before a Consumer can redirect UserAgents to retrieve identification
tokens from a remote Server, the Consumer must have already established
an association with that Server.
The Consumer-to-Server association:
1) provides the Server with a configuration to use when generating
identification tokens for the Consumer over a specific timespan.
2) provides the Consumer with a handle by which to reference the
association in future requests.
Request:
--------
A Consumer requests an association with a Server by initiating an HTTP
request to the Server, with the details of the requested association
specified the GET parameters.
The Consumer indicates that it is requesting an association with the
Server by providing:
Parameter: openid.mode
Value: 'associate'
The Consumer specifies the method by which the Server should produce
identification tokens intended for the Consumer. Currently, the only
supported identification token format is "HMAC-SHA1", so including this
parameter is optional.
Parameter: openid.id_token_format
Value: 'HMAC-SHA1'
The other parameters of an association request are dependent on the
chosen format.
* For HMAC-SHA1:
HMAC-SHA1 will require a secret to be shared between the Consumer and
Server for the duration of the association. A Diffie-Hellman key
exchange protects this secret in transit. The consumer provides the
shared Diffie-Hellman parameters along with its own Diffie-Hellman
public integer.
Parameter: openid.dh_modulus
Value: BASE64(BTWOC(modulus))
Parameter: openid.dh_generator
Value: BASE64(BTWOC(generator))
Parameter: openid.dh_consumer_public
Value: BASE64(BTWOC(consumer's public value))
Response
--------
The Server configures an association with the Consumer using the
requested configuration parameters, communicates any parameters the
Consumer will need for the chosen identification token format, and
supplies a handle by which the association can be identified in the
future. The parameters are supplied in the response one-per-line, in the
format:
name: value
Regardless of the specifics of the association, the Consumer needs to
know the handle by which to refer to this association in the future, as
well as the timespan for which the association will be effective.
Parameter: openid.association_handle
Value: handle
Parameter: openid.association_issuetime
Value: UTC date and time of issue
Parameter: openid.association_expires
Value: UTC date and time this association will expire
Parameter: openid.association_replacetime
Value: UTC date and time on which the server
recommends initiating a new association
Since the consumer may not have specified a preference for the
identification token format, the server states which format this
association will use. Again, only HMAC-SHA1 is currently supported.
Parameter: openid.id_token_format
Value: 'HMAC-SHA1'
The other parameters of an association response are dependent on the
chosen format.
* For HMAC-SHA1:
The Server needs to communicate its Diffie-Hellman public integer
(generated with the Consumer-provided parameters).
Parameter: openid.dh_server_public
Value: BASE64(BTWOC(server's public value))
The Consumer needs to know what shared secret will be used for identity
tokens created under this association.
Parameter: openid.encrypted_hmac_secret
Value: base64(SHA1(BTWOC(DH_secret_integer)) XOR hmac_secret)
Generaton of the hmac_secret is left up to the server implementation.
Some methods that are in use include:
1) Use the DH private integer directly -- use
SHA1(BTWOC(DH_secret_integer)) as the hmac_secret (producing an
encrypted_hmac_secret of 0)
2) Use a "get_secret" method that can calculate secrets from
handles, e.g., LiveJournal's LJ::get_secret, which allows a secret to be
retrieved by a handle without requiring all known secrets to be
explicitly stored.
More information about the yadis
mailing list