Changes

Jump to: navigation, search

Identity/AttachedServices/KeyServerProtocol

540 bytes added, 00:15, 1 August 2013
Login: /session/auth: updating with new protocol, still not complete
After the client submits /account/create, it performs the "/session/auth" login sequence below to obtain a sessionToken. It then polls the "GET /account/recovery_methods" (which requires a sessionToken but not account verification) until the user clicks the email link and the API reports verification is complete. Then the client uses "GET /account/keys" and "POST /certificate/sign", described below, to obtain kA, kB, and a signed certificate to talk to the storage server.
= Login: /session/auth Obtaining the authToken =
To connect a browser to an existing account, we use the following login protocol to transform an email+password pair into (keyFetchToken, sessionToken)a single-use authToken. These tokens We will be used use this in the next section to create a session, from which we can obtain encryption keys and signed certificates.
This protocol starts by using key-stretching to transform the email+password into a "stretchedPW", then feeds this into an SRP protocol to get a session key. It uses this session key to decrypt a bundle of encrypted data from the keyserver, resulting in three values: kA, wrap(kB), and the sessionToken. The stretchedPW is also used to derive the key that will decrypt wrap(kB) into the actual kB valueauthToken.
[[Filesession key. It uses this session key to decrypt a bundle of encrypted data from the keyserver, resulting in three values:PICL-IdPAuth-bigpixkA, wrap(kB), and the sessionToken. The stretchedPW is also used to derive the key that will decrypt wrap(kB) into the actual kB value.png|IdP Auth Big Picture]]
This same protocol is used, with slightly different methods and constants, to obtain the "accountResetToken". This token allows a client to safely reset the account password[[File:PICL-IdPAuth-auth-start.png|IdP Auth Protocol]]
This same authToken is used to obtain the "accountResetToken", which allows a client to safely reset the account password. The protocol is optimized designed to minimize roundenable parallelism between key-trips stretching and to enable parallelismthe initial network messages, to reduce the time it takes to connect a browser to the account to just a few seconds. As a result, the two messages it sends (/session/auth/start and /session/auth/finish) each perform multiple jobs. In total, the browser requires four five messages in three four roundtrips (1: /session/auth/start, 2: /session/auth/finish, 3: /session/create, 4: /account/keys and /certificate/sign in parallel) before it is ready to talk to the storage server.
== auth/start ==
As soon as the user finishes typing in the email address, the client should send it in the "/session/auth/start" message to the keyserver. The response will include a set of parameters that are needed for key-stretching (described below), and the common parameters used by both sides of the SRP protocol to follow. These are simply looked up in a database entry for the client, along with an account-id. It must also include an allocated loginSRPToken that is used to associate this request with the subsequent /session/auth/finish request. Finally, the response also includes the server's contribution to the SRP protocol ("srpB"), which is calculated on the server based upon a random value that it remembers in the session.
To mitigate DoS abuse, /session/auth/start may also require a proof-of-work string, described below.
== Client-Side Key Stretching ==
=== SRP Server-side Sign-In Flow ===
When the user connects a new device to their account, they use the /session/auth/start API to start the SRP protocol. This sends the account email address to the server. The server looks up the stored srpVerifier for this account, creates a random 'b' integer, performs some math to compute the "B" number, then converts B into a string known as "srpB". "srpB" is returned to the client, along with srpSalt and the key-stretching parameters. "b" and "srpB" are retained for the subsequent /session/auth/finish call. '''Note that it is critical that the "b" integer remain secret on the server.''' The server also allocates a random loginSRPToken to connect the two calls.
[[File:PICL-IdPAuth-SRP-Server.png|server--side SRP]]
Later, /session/auth/start will be called with the client's srpA string and its M1 key-confirmation string. srpA is combined with srpB to calculate the "u" integer. srpA is also turned into an integer and used to compute the shared-secret "S" integer. S is then used to compute the shared key "srpK", which is the output of the SRP process.
=== SRP Client Calculation ===
While the client is waiting for the response to /session/auth/start, it begins its key-stretching calculations. Everything else must wait until the response to /session/auth/start arrives, which includes the key-stretching parameters (which are retroactively confirmed), srpSalt, and the server's generated srpB value.
[[File:PICL-IdPAuth-SRP-Client.png|client-side SRP]]
There are several places in SRP where integers (usually in the range 1..N-1) are converted into bytestrings, either for transmission over a wire, or to be passed into a hash function. The SRP spec is somewhat ambiguous about padding here: if the integer happens to be less than 2^2040, the simplest toString() approach will yield a '''255''' byte string, not a 256 byte string. PiCL consistently uses padding, so compatible implementations must prepend one or more NUL bytes to these short strings before transmission or hashing. The examples above were brute-forced to ensure that "srpVerifier", "srpA", "srpB", and "S" all wind up with leading zeros, to exercise the padding code in compatible implementations. If you are having problems getting your code to match these results, add some assertions to test that the stringified integers being put into hashes are exactly 256 bytes long.
The client does its entire SRP calculation in a single step, after receiving the server's "B" value. It creates its "A" value, computes the shared secret S, and the proof-of-knowledge M1. It sends both "A" and "M1" in the same message (/session/auth/finish).
The server receives "A" in /session/auth/finish, computes the shared secret "S", computes M1, checks that the client's M1 is correct, then derives the shared session key K. It then allocates a token (of the requested type) and encrypts keyFetchToken+sessionToken as described below, returning the encrypted/MACed bundle in the response to /session/auth/finish.
Outstanding crypto questions:
* The original SRP papers defined M1=H(A+B+S) as we use here, but other implementation (in particular RFC2945) uses a curious construct that includes the username, the salt, and an odd XOR combination of N and g. We need to decide what to use for M1.
== /session/auth/finish ==
The client-side SRP calculation results in two values that are sent to the server in the /session/auth/finish message: "srpA" and "srpM1". "A" is the client's contribution to the SRP protocol. "M1" is an output of this protocol, and proves (to the server) that this client knew the right password.
The server feeds "A" into its own SRP calculation and derives (hopefully) the same "S" value as the client did. It can then compute its own copy of M1 and see if it matches. If not, the client (or a man-in-the-middle) did not get the right password, and the server will return an error and increment it's "somebody is trying to guess passwords" counter (which will be used to trigger defenses against online guessing attacks). If it does match, then both sides can derive the same "K" session key.
The server then allocates two tokens for this device: keyFetchToken and sessionTokena single-use token named "authToken". It encrypts the tokens token with the session key. The server , and returns a success message with the encrypted bundle.
Both All tokens have an associated tokenID, described below. The server needs to maintain a table that maps the tokenID to the token itself, so it can derive other values from the token later. The tokens are also associated with a specific account, so later API requests do not specify an email address or account ID.
== Decrypting the /session/auth/finish Response ==
The SRP session key ("srpK") is used to derive two other keys: respHMACkey and respXORkey.
[[File:PICL-IdPAuth-encrypt-authToken.png|Decrypting the authToken]] The respXORkey is used to encrypt the authToken string, by simply XORing the two. This ciphertext is then protected by a MAC, using HMAC-SHA256, keyed by respHMACkey. The MAC is appended to the ciphertext, and the whole bundle is returned to the client. The client recomputes the MAC, compares it (throwing an error if it doesn't match), extracts the ciphertext, XORs it with the derived respXORkey, then returns the authToken value. = Creating a Session = For login, the single-use authToken is spent on a call to /session/create .This allocates two new tokens: a long-lived "sessionToken", and a single-use "keyFetchToken". The /session/create call returns an encrypted bundle containing the two tokens. [[File:PICL-IdPAuth-encrypt-sessionToken.png|Decrypting the sessionToken and keyFetchToken]]
The As before, the respXORkey is used to encrypt the concatenated keyFetchToken/sessionToken string, by simply XORing the two. This ciphertext is then protected by a MAC, using HMAC-SHA256, keyed by respHMACkey. The MAC is appended to the ciphertext, and the whole bundle is returned to the client.
The client recomputes the MAC, compares it (throwing an error if it doesn't match), extracts the ciphertext, XORs it with the derived respXORkey, then splits it into the separate keyFetchToken and sessionToken values.
Confirm
471
edits

Navigation menu