On 9/01/2014 11:44 AM, Toby Elliott wrote:
> 2) The account identifier (we call it the uid) is simply a mapping from the 
> username to an externally-chosen integer, and isn't derived as a function. 
> That enables services to index users by an integer rather than a string, and 
> it may be a constant across multiple services. Changing that will cause the 
> user to start a completely new sync account, leaving us with all their old 
> data sitting there.
> 
> Tokens expire after a specifically configured period, which addresses the 
> second bullet point (and the third, to an extent) in terms . Perhaps an HMAC 
> error should trigger a fresh round of auth before proceeding to worry about 
> other possibilities?
> 
> If a client does a complete account reset, it would probably be best if they 
> kicked off their new interactions with the Sync server by deleting everything.

I'm not thrilled about making the tokenserver responsible for sync-key
management.  It'd work, sure, but it seems like a layering violation.

Restating an implicit intermediate goal:  resetting your account should
blow away your sync data, causing all clients to update their encryption
keys and re-sync from scratch.

Is that accurate or have I lost some nuance?

Would the following work without having to special-case things in the
tokenserver?

  When a client switches to using a new encryption key
  (e.g. after successful password reset):

     * re-auth with the tokenserver, to update the
       generation number

     * delete all data on the sync node (we have an atomic API
       operation for this already)

     * re-sync from scratch

  When a client encounters an HMAC error:

     * re-auth with the tokenserver, which may in turn
       force re-auth with FxA due to generation change

     * if the encryption key was changed, try syncing again
       and it will probably work this time

     * if the encryption key was not changed, someone has
       left junk on the sync node; delete all data
       and try syncing again

By always doing a tokenserver re-auth before deleting data from the
node, this should prevent clients getting into a slap-fight over which
encryption key is currently active.  They're gated by the generation
number stored in the tokenserver.

The junk-cleaning-up behaviour in the HMAC-error case would heal from
situations like a client crashing after it changes the password, but
before it has a chance to delete things form the storage node.

Sticking point: clients that write old-key-encrypted data into the store
*after* it has been cleared.  Consistent use of X-If-Unmodified-Since
could avoid this, but I don't think we use it consistently.

So the downside here would be more client code churn.  The
tokenserver-based approach is probably simpler to implement before our
impending deadline, and almost certainly simpler to implement *reliably*.


  Cheers,

    Ryan

> On Jan 8, 2014, at 3:36 PM, Brian Warner <[email protected]> wrote:
> 
>>
>> ["To:" folks, please review]
>>
>> ckarlof, nalexander, and myself had a meeting today to figure out what
>> should happen in Sync+FxAland when you change or reset your FxA account
>> password. We specifically cared about:
>>
>> * resetting your account (new password, new encryption key) should *not*
>>  result in clients seeing HMAC errors, when they try to decrypt new
>>  records with the old key or vice-versa
>>
>> * changing the password (new password, unchanged encryption key) should
>>  sooner-or-later cause all other clients to lose access, and their
>>  users should be prompted to re-login
>>
>> * resetting the account (new password, new encryption key) should also
>>  cause other clients to lose access and be prompted to re-login
>>
>>
>> To support this, we're proposing the following changes:
>>
>> * the fxa-auth-server will remember a "generation number" for each
>>  account. Each account-reset and change-password event increments the
>>  generation number. The generation will be included in signed
>>  certificates returned by the /certificate/sign API.
>>
>> * when the client submits a signed assertion to the tokenserver's
>>  "please give me a token" API, it will include the hash of the
>>  encryption key it is currently using (derived from kB). nalexander:
>>  I'd recommend this value be a sibling of the key you're already
>>  deriving from kB, either by using a different ctxInfo string, or by
>>  extracting an extra 32 bytes from the existing HKDF operation. Neither
>>  is derivable from the other.
>>
>> * the Sync tokenserver will maintain a table with three columns:
>>  - FxA Account Identifier
>>  - FxA generation number
>>  - Sync account identifier (endpoint? collection-id? I don't know the
>>    right lingo)
>>
>> * The Sync account identifier must be a consistent function of (FxA
>>  account-id, hash-of-encryption-key). Previously it was merely a
>>  consistent function of the FxA account-id.
>>
>> * If the tokenserver gets a please-give-me-a-token request with a
>>  generation number that's lower than the one currently stored, it
>>  should reject the request. If it gets a cert with a higher generation
>>  number, it should update the table.
>>
>> * the FxA/Sync client code should respond to most errors (specifically
>>  token-expired and old-generation errors) by asking the user to
>>  re-login
>>
>>
>> The idea is:
>>
>> * when client#1 changes the FxA account password, they get the same kB
>>  but a new generation number. As soon as their Sync client code talks
>>  to the tokenserver, all other clients will be locked out (the
>>  tokenserver will no longer accept their older-generation
>>  certificates), and will be prompted to re-login (with the new
>>  password). The window of revocation will be as short as the token
>>  expiration time. If client#1 crashes and never manages to talk to the
>>  Sync server, other clients will continue to work until their tokens
>>  and certificates expire.
>>
>> * if client#1 resets the account (forgot-password), they get a new kB
>>  and a new generation number. When they sync, they'll get a new Sync
>>  account-id and a new place for server-side data, independent of the
>>  old place. Client#2 (who is still using the old key) will keep using
>>  the old place. No matter how long the clients keep using their old
>>  keys, they won't interfere with each other's ciphertext, and no client
>>  will observe a wrong-key-provoked HMAC failure. Eventually all certs
>>  and tokens will expire, and they'll stop using the old place.
>>
>> * the tokenserver can run a query to find stale Sync-account-identifiers
>>  (lowest generation number for the same FxA account identifier) to mark
>>  for garbage-collection. We might want to store a last-used timestamp
>>  here too, to defer GC for a day or two after the last client stops
>>  touching it.
>>
>> The overall goal is to avoid requiring a back-channel between the FxA
>> auth-server and the Sync tokenserver. The generation numbers should be
>> useful for other RPs that want slightly faster revocation properties
>> too.
>>
>>
>> thoughts?
>> -Brian
> 

_______________________________________________
Sync-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/sync-dev

Reply via email to