Confirmed users
358
edits
No edit summary |
No edit summary |
||
| Line 30: | Line 30: | ||
In initial discussions we've been calling this a "key escrow service", but to me (rfkelly) that conjures up too many big-brother clipper-chip-style associations. Since the idea is that Mozilla won't be able to obtain your sync key even if you enable this service, I think "key recovery service" has more accurate connotations. Thoughts? | In initial discussions we've been calling this a "key escrow service", but to me (rfkelly) that conjures up too many big-brother clipper-chip-style associations. Since the idea is that Mozilla won't be able to obtain your sync key even if you enable this service, I think "key recovery service" has more accurate connotations. Thoughts? | ||
== Server API == | |||
Since the server component is intended to run from a high-security restricted-access environment, it should be as simple and light-weight as possible. Hence, we provide the smallest and simplest API the could possibly work: you get a single blob of plain text data, keyed by your username, limited to 1 KB. | |||
GET https://recov-server/username | |||
=> 404 Not Found | |||
PUT https://recov-server/username | |||
Content-Length: 11 | |||
hello world | |||
=> 201 No Content | |||
GET https://recov-server/username | |||
=> 200 OK | |||
Content-Length: 11 | |||
Content-Type: text/plain | |||
hello world | |||
PUT https://recov-server/username | |||
Content-Length: 2048 | |||
<mwuahahaha I store my warez on you> | |||
=> 413 Request Entity Too Large | |||
DELETE https://recov-server/username | |||
=> 201 No Content | |||
GET https://recov-server/username | |||
=> 404 Not Found | |||
It's tempting to expand this API into something more generic, e.g. to provide multiple different recovery keys for each username. But the less this service has to do, the less chance there is for something to go wrong. | |||
If we can successfully bootstrap from the user's password into a strong crypto key, then anything else they might need to keep safe can be stored in standard sync storage with strong encryption. | |||
== Sync Key Encryption == | == Sync Key Encryption == | ||
| Line 57: | Line 91: | ||
"hmac": "hex-encoded hmac", | "hmac": "hex-encoded hmac", | ||
} | } | ||
HTTP.PUT(recovery_url, JSON.stringify(recov)) | |||
To recover the sync key, the client retrieves the above JSON from the recovery service and does: | To recover the sync key, the client retrieves the above JSON from the recovery service and does: | ||
recov = JSON.parse(HTTP.GET(recovery_url)) | |||
enc_key = PBKDF2(username + password, recov["salt"], 4096, 32) | enc_key = PBKDF2(username + password, recov["salt"], 4096, 32) | ||
| Line 83: | Line 121: | ||
The recovery service shares a private key with a separate "authentication service" which generates signed auth tokens for the user. The user provides their account credentials to the authentication services and obtains a signed auth token in return: | The recovery service shares a private key with a separate "authentication service" which generates signed auth tokens for the user. The user provides their account credentials to the authentication services and obtains a signed auth token in return: | ||
GET https://server | GET https://auth-server/token | ||
Authorization: Basic XXXYYYZZZ | Authorization: Basic XXXYYYZZZ | ||
| Line 95: | Line 133: | ||
The user then presents this token to the recovery service and can retrieve, update or delete the stored recovery data: | The user then presents this token to the recovery service and can retrieve, update or delete the stored recovery data: | ||
GET https://server | GET https://recov-server/username | ||
=> 401 Unauthorized | => 401 Unauthorized | ||
GET https://server | GET https://recov-server/username | ||
X-Auth-Token: <username>:<timestamp>:<hmac> | X-Auth-Token: <username>:<timestamp>:<hmac> | ||
=> 200 OK | => 200 OK | ||
Content-Type: text/ | Content-Type: text/plain | ||
{ ...recovery data here... } | { ...recovery data here... } | ||