Services/Sync/SyncKey/J-PAKE/NewOrder: Difference between revisions

 
(10 intermediate revisions by the same user not shown)
Line 50: Line 50:
*Desktop: Client that has Fx Sync already set up  
*Desktop: Client that has Fx Sync already set up  
*Device: Client that needs to be set up, usually phone (of course this could be another desktop computer, too)  
*Device: Client that needs to be set up, usually phone (of course this could be another desktop computer, too)  
*PIN: code that is displayed on Mobile and entered on Desktop made up of the weak secret & the channel id.
*PIN: code that is displayed on Device and entered on Desktop made up of the weak secret & the channel id.
*Secret: weak secret that is used to start the J-PAKE algorithm
*Secret: weak secret that is used to start the J-PAKE algorithm
*Key: strong secret that both clients derive through J-PAKE
*Key: strong secret that both clients derive through J-PAKE


== Overview ==
== Overview ==


<ul>
*Device and Desktop complete the two roundtrips of J-PAKE messages to agree upon a strong secret K  
  <li>Device and Desktop complete the two roundtrips of J-PAKE messages to agree upon a strong secret K</li>
*A 256 bit key is derived from K using HMAC-SHA256 using a fixed extraction key.  
  <li>A 256 bit key is derived from K using HMAC-SHA256 using a fixed extraction key.</li>
*The encryption and HMAC keys are derived from that 256 bit key using HMAC-SHA256.  
  <li>The encryption and HMAC keys are derived from that 256 bit key using HMAC-SHA256.</li>
*In third round trip:  
  <li>In third round trip:
**Device encrypts the known message "0123456789ABCDEF" with the AES key and uploads it.  
<ul><li>Device encrypts the known message "0123456789ABCDEF" with the AES key and uploads it.</li>
**Between 3 and 4 is when the user may have to create an account. There may be significant delay here.
<li>Desktop verifies that against the known message encrypted with its own key, encrypts the credentials with the encryption key and uploads the encrypted credentials in turn, adding a HMAC-SHA256 hash of the ciphertext (using the HMAC key).</li>
*In the 4th round trip:
<li>Device verifies whether Desktop had the right key by checking the ciphertext against the HMAC-SHA256 hash.</li>
**Desktop verifies that against the known message encrypted with its own key, encrypts the credentials with the encryption key and uploads the encrypted credentials in turn, adding a HMAC-SHA256 hash of the ciphertext (using the HMAC key).  
<li>If that verification is successful, Device decrypts ciphertext and applies credentials (it may wait a while if the user has to create the account to create those credentials.)</li>
**Device verifies whether Desktop had the right key by checking the ciphertext against the HMAC-SHA256 hash.  
</ul></li>
**If that verification is successful, Device decrypts ciphertext and applies credentials, and triggers the first download to Device.
</ul>




<pre>
<br>
Device                        Server                        Desktop
<pre>Device                        Server                        Desktop
===================================================================
===================================================================
                                 |
                                 |
retrieve channel <---------------|
retrieve channel &lt;---------------|
generate random secret          |
generate random secret          |
show PIN = secret + channel      |                ask user for PIN
show PIN = secret + channel      |                ask user for PIN
upload Mobile's message 1 ------>|
upload Device's message 1 ------&gt;|
                                 |----> retrieve Mobile's message 1
                                 |----&gt; retrieve Device's message 1
                                 |<----- upload Desktop's message 1
                                 |&lt;----- upload Desktop's message 1
retrieve Desktop's message 1 <---|
retrieve Desktop's message 1 &lt;---|
upload Mobile's message 2 ------>|
upload Device's message 2 ------&gt;|
                                 |----> retrieve Mobile's message 2
                                 |----&gt; retrieve Device's message 2
                                 |                      compute key
                                 |                      compute key
                                 |<----- upload Desktop's message 2
                                 |&lt;----- upload Desktop's message 2
retrieve Desktop's message 2 <---|
retrieve Desktop's message 2 &lt;---|
compute key                      |
compute key                      |
encrypt known value ------------>|
encrypt known value ------------&gt;|
                                |-------> retrieve encrypted value
                                 | verify against local known value
                                 | verify against local known value
                                |
                                |      Optionally create account
                                |-------&gt; retrieve encrypted value
                                 |              encrypt credentials
                                 |              encrypt credentials
                                 |<------------- upload credentials
                                 |&lt;------------- upload credentials
retrieve credentials <-----------|
retrieve credentials &lt;-----------|
verify HMAC                      |
verify HMAC                      |
decrypt credentials              |
decrypt credentials               
Device begins download          |
</pre>
</pre>


Line 213: Line 215:


<ol>
<ol>
<li>Mobile asks server for new channel ID (3 characters a-z0-9)
<li>Device asks server for new channel ID (3 characters a-z0-9)
<pre>C: GET /new_channel HTTP/1.1
<pre>C: GET /new_channel HTTP/1.1
S: "a7id"</pre></li>
S: "a7id"</pre></li>
<li>Mobile generates PIN from random weak secret (4 characters a-z0-9) and the channel ID, computes and uploads J-PAKE msg 1.
<li>Device generates PIN from random weak secret (4 characters a-z0-9) and the channel ID, computes and uploads J-PAKE msg 1.To prevent double uploads in case of retries, the If-None-Match: * header is specified. This makes sure that the message is only uploaded if the channel is empty. If it is not then the request will fail with a 412 Precondition Failed which should be considered the same as 200 OK. The 412 will also contain the Etag of the data was the client just uploaded.
 
<b>New in version 3:</b> Timeouts will need to be increased to accommodate the case where users have to create an account on the Desktop before proceeding.  
<b>New for v2:</b> To prevent double uploads in case of retries, the If-None-Match: * header is specified. This makes sure that the message is only uploaded if the channel is empty. If it is not then the request will fail with a 412 Precondition Failed which should be considered the same as 200 OK. The 412 will also contain the Etag of the data was the client just uploaded.
<pre>
<pre>
C: PUT /a7id HTTP/1.1
C: PUT /a7id HTTP/1.1
Line 255: Line 256:
S: ETag: "etag-of-receiver1-message"
S: ETag: "etag-of-receiver1-message"
</pre></li>
</pre></li>
<li>Desktop asks user for the PIN, extracts channel ID and weak secret, fetches Mobile's msg 1
<li>Desktop asks user for the PIN, extracts channel ID and weak secret, fetches Devce's msg 1
<pre>
<pre>
C: GET /a7id HTTP/1.1
C: GET /a7id HTTP/1.1
Line 267: Line 268:
</pre></li>
</pre></li>


<li>Desktop computes and uploads msg 1.
<li>Desktop computes and uploads msg 1. The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
 
<b>New in version 2:</b> The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
<pre>
<pre>
C: PUT /a7id HTTP/1.1
C: PUT /a7id HTTP/1.1
Line 304: Line 303:
S: Etag: "etag-of-sender1-message"
S: Etag: "etag-of-sender1-message"
</pre></li>
</pre></li>
<li>Mobile polls for Desktop's msg 1
<li>Device polls for Desktop's msg 1
<pre>
<pre>
C: GET /a7id HTTP/1.1
C: GET /a7id HTTP/1.1
Line 311: Line 310:
S: HTTP/1.1 304 Not Modified
S: HTTP/1.1 304 Not Modified
</pre>
</pre>
<p>Mobile tries again after 1s</p>
<p>Device tries again after 1s</p>
<pre>
<pre>
C: GET /a7id HTTP/1.1
C: GET /a7id HTTP/1.1
Line 319: Line 318:
...
...
</pre>
</pre>
  <p>Mobile computes and uploads msg 2.
  <p>Device computes and uploads msg 2. The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
 
<b>New in version 2:</b> The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
</p>
</p>
  <pre>C: PUT /a7id HTTP/1.1
  <pre>C: PUT /a7id HTTP/1.1
Line 344: Line 341:
S: ETag: "etag-of-receiver2-message"
S: ETag: "etag-of-receiver2-message"
</pre></li>
</pre></li>
<li>Desktop polls for and eventually retrieves Mobile's msg 2
<li>Desktop polls for and eventually retrieves Device's msg 2
<pre>
<pre>
C: GET /a7id HTTP/1.1
C: GET /a7id HTTP/1.1
Line 357: Line 354:
...
...
</pre>
</pre>
<p>Desktop computes key, computes and uploads msg 2.
<p>Desktop computes key, computes and uploads msg 2. The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
 
<b>New in version 2:</b> The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
</p>
</p>
<pre>
<pre>
Line 384: Line 379:
</pre></li>
</pre></li>


<li>Mobile retrieves Desktop's msg 2
<li>Device retrieves Desktop's msg 2
<pre>
<pre>
C: GET /a7id HTTP/1.1
C: GET /a7id HTTP/1.1
Line 396: Line 391:
S: Etag: "etag-of-sender2-message"
S: Etag: "etag-of-sender2-message"
</pre>
</pre>
<p>Mobile computes key, uploads encrypted known message "0123456789ABCDEF" to prove its knowledge (msg 3).
<p>Device uploads encrypted known message "0123456789ABCDEF" to prove its knowledge (msg 3).
 
<b>New in version 3:</b>No longer includes the key, just the known message.
<b>New in version 2:</b> The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
</p>
</p>
<pre>
<pre>
Line 407: Line 402:
C:    'type': 'receiver3',
C:    'type': 'receiver3',
C:    'payload': {
C:    'payload': {
C:      'ciphertext': "base64encoded=",
C:      'IV': "base64encoded=",
C:      'IV': "base64encoded=",
C:    }
C:    }
Line 420: Line 414:
</li>
</li>


<li>Desktop retrieves Mobile's msg 3 to confirm key
<li>Desktop retrieves Device's msg 3 to confirm connection. <b>new in version 3</b> No longer includes encrypted key. That will come in the 4th exchange once account creation has happened if needed and first sync upload has occurred.
<pre>
<pre>
C: GET /a7id HTTP/1.1
C: GET /a7id HTTP/1.1
Line 429: Line 423:
...
...
</pre>
</pre>
Desktop verifies it against its own version. If the hash matches, it encrypts and uploads Sync credentials.
Desktop verifies it against its own version. If the hash matches, it acquires (either the existing account or by creating a new one), then encrypts and uploads Sync credentials.


<b>New in version 2:</b> The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.
The If-Match header is set so that we only upload this message if the other side's previous message is still in the channel. This is to prevent double PUTs during retries. If a 412 is received then it means that our first PUT was actually correctly received by the server and that the other side has already uploaded it's next message. So just consider the 412 to be a 200.


<pre>
<pre>
Line 440: Line 434:
C:    'type': 'sender3',
C:    'type': 'sender3',
C:    'payload': {
C:    'payload': {
C:      'ciphertext': "base64encoded=",
C:      'IV': "base64encoded=",
C:      'IV': "base64encoded=",
C:      'hmac': "base64encoded=",
C:      'hmac': "base64encoded=",
C:    }
C:    }
C: }
C: }


S: HTTP/1.1 200 OK
S: HTTP/1.1 200 OK
Line 460: Line 452:
...  
...  
</pre>
</pre>
This means that Mobile will receive a 404 when it tries to retrieve the encrypted credentials.
This means that Device will receive a 404 when it tries to retrieve the encrypted credentials.
</li></li>
</li></li>


<li>Mobile retrieves encrypted credentials
</li>
<li><b>New in version 3:</b> Desktop signals that uploading sync has finished by encrypting and sending over the key. This is the 4th and last exchange.
<pre>
C: PUT /a7id HTTP/1.1
C: If-Match: "etag-of-receiver4-message"
C:
C: {
C:    'type': 'sender4',
C:    'payload': {
C:      'ciphertext': "base64encoded=",
C:    }
C: }
Success response:
 
S: HTTP/1.1 200 OK
S: ETag: "etag-of-receiver4-message"
</pre>
</li>
<li><b>New in version 3:</b> Device retrieves encrypted key, decrypts it, starts downloading. Device kills session if HMAC does not match.
<pre>
C: GET /a7id HTTP/1.1
C: If-None-Match: "etag-of-receiver4-message"
</pre>
<li>Device retrieves encrypted credentials
<pre>
<pre>
C: GET /a7id HTTP/1.1
C: GET /a7id HTTP/1.1
C: If-None-Match: "etag-of-receiver3-message"
C: If-None-Match: "etag-of-receiver4-message"


S: HTTP/1.1 200 OK
S: HTTP/1.1 200 OK
Line 472: Line 487:
</pre>
</pre>
<p>decrypts Sync credentials and verifies HMAC.</p></li>
<p>decrypts Sync credentials and verifies HMAC.</p></li>
<li>Mobile deletes the session [OPTIONAL]
<pre>
<pre>
C: DELETE /a7id HTTP/1.1
C: DELETE /a7id HTTP/1.1
Confirmed users
385

edits