specs/spec/5.html

50 lines
54 KiB
HTML
Raw Normal View History

2021-11-22 18:48:50 +00:00
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>5/SECURE-TRANSPORT - Status Specification</title> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"> <link rel="stylesheet" href="/assets/css/just-the-docs-default.css"> <script type="text/javascript" src="/assets/js/vendor/lunr.min.js"></script> <script type="text/javascript" src="/assets/js/just-the-docs.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Begin Jekyll SEO tag v2.7.1 --> <title>5/SECURE-TRANSPORT | Status Specification</title> <meta name="generator" content="Jekyll v4.2.1" /> <meta property="og:title" content="5/SECURE-TRANSPORT" /> <meta property="og:locale" content="en_US" /> <link rel="canonical" href="https://specs.status.im/spec/5" /> <meta property="og:url" content="https://specs.status.im/spec/5" /> <meta property="og:site_name" content="Status Specification" /> <meta name="twitter:card" content="summary" /> <meta property="twitter:title" content="5/SECURE-TRANSPORT" /> <script type="application/ld+json"> {"@type":"WebPage","url":"https://specs.status.im/spec/5","headline":"5/SECURE-TRANSPORT","@context":"https://schema.org"}</script> <!-- End Jekyll SEO tag --> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-link" viewBox="0 0 24 24"> <title>Link</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"> <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> </svg> </symbol> <symbol id="svg-search" viewBox="0 0 24 24"> <title>Search</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"> <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"> <title>Menu</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"> <title>Expand</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <symbol id="svg-doc" viewBox="0 0 24 24"> <title>Document</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline> </svg> </symbol> </svg> <div class="side-bar"> <div class="site-header"> <a href="https://specs.status.im/" class="site-title lh-tight"> Status Specification </a> <a href="#" id="menu-button" class="site-button"> <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg> </a> </div> <nav role="navigation" aria-label="Main" id="site-nav" class="site-nav"> <ul class="nav-list"><li class="nav-list-item active"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="https://specs.status.im/spec/" class="nav-list-link">Stable specs</a><ul class="nav-list "><li class="nav-list-item "><a href="https://specs.status.im/spec/1" class="na
2021-11-16 14:54:10 +00:00
<span class="kd">message</span> <span class="nc">Bundle</span> <span class="p">{</span>
<span class="kt">bytes</span> <span class="na">identity</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">map</span><span class="o">&lt;</span><span class="kt">string</span><span class="p">,</span><span class="n">SignedPreKey</span><span class="err">&gt;</span> <span class="na">signed_pre_keys</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="kt">bytes</span> <span class="na">signature</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="kt">int64</span> <span class="na">timestamp</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <ul> <li><code class="language-plaintext highlighter-rouge">identity</code>: Identity key <code class="language-plaintext highlighter-rouge">IK_B</code></li> <li><code class="language-plaintext highlighter-rouge">signed_pre_keys</code>: Signed prekey <code class="language-plaintext highlighter-rouge">SPK_B</code> for each device, indexed by <code class="language-plaintext highlighter-rouge">installation-id</code></li> <li><code class="language-plaintext highlighter-rouge">signature</code>: Prekey signature <i>Sig(<code class="language-plaintext highlighter-rouge">IK_B</code>, Encode(<code class="language-plaintext highlighter-rouge">SPK_B</code>))</i></li> <li><code class="language-plaintext highlighter-rouge">timestamp</code>: When the bundle was created locally</li> </ul> <p>(<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L5">protobuf</a>)</p> <div class="language-protobuf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">message</span> <span class="nc">SignedPreKey</span> <span class="p">{</span>
<span class="kt">bytes</span> <span class="na">signed_pre_key</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="kt">uint32</span> <span class="na">version</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">signature</code> is generated by sorting <code class="language-plaintext highlighter-rouge">installation-id</code> in lexicographical order, and concatenating the <code class="language-plaintext highlighter-rouge">signed-pre-key</code> and <code class="language-plaintext highlighter-rouge">version</code>:</p> <p><code class="language-plaintext highlighter-rouge">installation-id-1signed-pre-key1version1installation-id2signed-pre-key2-version-2</code></p> <h4 id="double-ratchet"> <a href="#double-ratchet" class="anchor-heading" aria-labelledby="double-ratchet"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Double Ratchet </h4> <p>Having established the initial shared secret <code class="language-plaintext highlighter-rouge">SK</code> through X3DH, it can be used to seed a Double Ratchet exchange between Alice and Bob.</p> <p>Please refer to the <a href="https://signal.org/docs/specifications/doubleratchet/">Double Ratchet spec</a> for more details.</p> <p>The initial message sent by Alice to Bob is sent as a top-level <code class="language-plaintext highlighter-rouge">ProtocolMessage</code> (<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L65">protobuf</a>) containing a map of <code class="language-plaintext highlighter-rouge">DirectMessageProtocol</code> indexed by <code class="language-plaintext highlighter-rouge">installation-id</code> (<a href="https://github.com/status-im/status-go/blob/1ac9dd974415c3f6dee95145b6644aeadf02f02c/services/shhext/chat/encryption.proto#L56">protobuf</a>):</p> <div class="language-protobuf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">message</span> <span class="nc">ProtocolMessage</span> <span class="p">{</span>
<span class="kt">string</span> <span class="na">installation_id</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="k">repeated</span> <span class="n">Bundle</span> <span class="na">bundles</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="c1">// One to one message, encrypted, indexed by installation_id</span>
<span class="n">map</span><span class="o">&lt;</span><span class="kt">string</span><span class="p">,</span><span class="n">DirectMessageProtocol</span><span class="err">&gt;</span> <span class="na">direct_message</span> <span class="o">=</span> <span class="mi">101</span><span class="p">;</span>
<span class="c1">// Public chats, not encrypted</span>
<span class="kt">bytes</span> <span class="na">public_message</span> <span class="o">=</span> <span class="mi">102</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <ul> <li><code class="language-plaintext highlighter-rouge">bundles</code>: a sequence of bundles</li> <li><code class="language-plaintext highlighter-rouge">installation_id</code>: the installation id of the sender</li> <li><code class="language-plaintext highlighter-rouge">direct_message</code> is a map of <code class="language-plaintext highlighter-rouge">DirectMessageProtocol</code> indexed by <code class="language-plaintext highlighter-rouge">installation-id</code></li> <li><code class="language-plaintext highlighter-rouge">public_message</code>: unencrypted public chat message.</li> </ul> <div class="language-protobuf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">message</span> <span class="nc">DirectMessageProtocol</span> <span class="p">{</span>
<span class="n">X3DHHeader</span> <span class="na">X3DH_header</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">DRHeader</span> <span class="na">DR_header</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="n">DHHeader</span> <span class="na">DH_header</span> <span class="o">=</span> <span class="mi">101</span><span class="p">;</span>
<span class="c1">// Encrypted payload</span>
<span class="kt">bytes</span> <span class="na">payload</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <ul> <li> <p><code class="language-plaintext highlighter-rouge">X3DH_header</code>: the <code class="language-plaintext highlighter-rouge">X3DHHeader</code> field in <code class="language-plaintext highlighter-rouge">DirectMessageProtocol</code> contains:</p> <p>(<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L47">protobuf</a>)</p> <div class="language-protobuf highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">message</span> <span class="nc">X3DHHeader</span> <span class="p">{</span>
<span class="kt">bytes</span> <span class="na">key</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="kt">bytes</span> <span class="na">id</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div> </div> <ul> <li><code class="language-plaintext highlighter-rouge">key</code>: Alices ephemeral key <code class="language-plaintext highlighter-rouge">EK_A</code>;</li> <li><code class="language-plaintext highlighter-rouge">id</code>: Identifier stating which of Bobs prekeys Alice used, in this case Bobs bundle signed prekey.</li> </ul> <p>Alices identity key <code class="language-plaintext highlighter-rouge">IK_A</code> is sent at the transport layer level (Whisper/Waku);</p> </li> <li><code class="language-plaintext highlighter-rouge">DR_header</code>: Double ratchet header (<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L31">protobuf</a>). Used when Bobs public bundle is available: <div class="language-protobuf highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">message</span> <span class="nc">DRHeader</span> <span class="p">{</span>
<span class="kt">bytes</span> <span class="na">key</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="kt">uint32</span> <span class="na">n</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="kt">uint32</span> <span class="na">pn</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="kt">bytes</span> <span class="na">id</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div> </div> <ul> <li><code class="language-plaintext highlighter-rouge">key</code>: Alices current ratchet public key (as mentioned in <a href="https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet">DR spec section 2.2</a>);</li> <li><code class="language-plaintext highlighter-rouge">n</code>: number of the message in the sending chain;</li> <li><code class="language-plaintext highlighter-rouge">pn</code>: length of the previous sending chain;</li> <li><code class="language-plaintext highlighter-rouge">id</code>: Bobs bundle ID.</li> </ul> </li> <li><code class="language-plaintext highlighter-rouge">DH_header</code>: Diffie-Helman header (used when Bobs bundle is not available): (<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L42">protobuf</a>) <div class="language-protobuf highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">message</span> <span class="nc">DHHeader</span> <span class="p">{</span>
<span class="kt">bytes</span> <span class="na">key</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
2021-11-16 15:16:16 +00:00
</code></pre></div> </div> <ul> <li><code class="language-plaintext highlighter-rouge">key</code>: Alices compressed ephemeral public key.</li> </ul> </li> <li><code class="language-plaintext highlighter-rouge">payload</code>: <ul> <li>if a bundle is available, contains payload encrypted with the Double Ratchet algorithm;</li> <li>otherwise, payload encrypted with output key of DH exchange (no Perfect Forward Secrecy).</li> </ul> </li> </ul> <!-- TODO: A lot of links to status-go, seems likely these should be updated to status-protocol-go --> <h2 id="security-considerations"> <a href="#security-considerations" class="anchor-heading" aria-labelledby="security-considerations"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Security Considerations </h2> <p>The same considerations apply as in <a href="https://signal.org/docs/specifications/x3dh/#security-considerations">section 4 of the X3DH spec</a> and <a href="https://signal.org/docs/specifications/doubleratchet/#security-considerations">section 6 of the Double Ratchet spec</a>, with some additions detailed below.</p> <!-- TODO: Add any additional context here not covered in the X3DH and DR specs --> <!-- TODO: description here ### --- Security and Privacy Features #### Confidentiality (YES) > Only the intended recipients are able to read a message. Specifically, the message must not be readable by a server operator that is not a conversation participant - Yes. - There's a layer of encryption at Whisper as well as above with Double Ratchet - Relay nodes and Mailservers can only read a topic of a Whisper message, and nothing within the payload. #### Integrity (YES) > No honest party will accept a message that has been modified in transit. - Yes. - Assuming a user validates (TODO: Check this assumption) every message they are able to decrypt and validate its signature from the sender, then it is not able to be altered in transit. * [igorm] i'm really not sure about it, Whisper provides a signature, but I'm not sure we check it anywhere (simple grepping didn't give anything) * [andrea] Whisper checks the signature and a public key is derived from it, we check the public key is a meaningful public key. The pk itself is not in the content of the message for public chats/1-to-1 so potentially you could send a message from a random account without having access to the private key, but that would not be much of a deal, as you might just as easily create a random account) #### Authentication (YES) > Each participant in the conversation receives proof of possession of a known long-term secret from all other participants that they believe to be participating in the conversation. In addition, each participant is able to verify that a message was sent from the claimed source - 1:1 --- one-to-one messages are encrypted with the recipient's public key, and digitally signed by the sender's. In order to provide Perfect Forward Secrecy, we build on the X3DH and Double Ratchet specifications from Open Whisper Systems, with some adaptations to operate in a decentralized environment. - group --- group chat is pairwise - public --- A user subscribes to a public channel topic and the decryption key is derived from the topic name **TODO:** Need to verify that this is actually the case **TODO:** Fill in explicit details here #### Participant Consistency (YES?) > At any point when a message is accepted by an honest party, all honest parties are guaranteed to have the same view of the participant list - **TODO:** Need details here #### Destination Validation (YES?) > When a message is accepted by an honest party, they can verify that they were included in the set of intended recipients for the message. - Users are aware of the topic that a message was sent to, and that they have the ability to decrypt it. - #### Forward Secrecy (PARTIAL) > Compromising all key material does not enable decryption of previously encrypted data - After first back and forth between two contacts with PFS enabled, yes. #### Backward Secrecy (YES) > Compromising all key material