|
| 1 | +# MSC2630: Checking public keys in SAS verification |
| 2 | + |
| 3 | +The current SAS protocol does not ensure that the two users correctly received |
| 4 | +each other's public keys. An attacker could send Alice and Bob public keys |
| 5 | +that he has created and, if the attacker is lucky, could obtain the same shared |
| 6 | +secret with both Alice and Bob, so that when they verify the SAS string, will |
| 7 | +believe that the exchange was secure. |
| 8 | + |
| 9 | +To mitigate against this, Alice and Bob can use the two public keys in the |
| 10 | +generation of the SAS string by including it in the info parameter of the HKDF. |
| 11 | +Thus if an attacker sends them different public keys, the info parameters will |
| 12 | +be different, and so the key generated by the HKDF will be different. |
| 13 | + |
| 14 | +Thanks to [David Wong](https://twitter.com/cryptodavidw) for identifying the |
| 15 | +issue, disclosing responsibly, and for helping to design the fix. |
| 16 | + |
| 17 | +## Proposal |
| 18 | + |
| 19 | +A new `key_agreement_protocol`, `curve25519-hkdf-sha256` is introduced, and |
| 20 | +will be mandatory for clients to support when performing SAS verification. It |
| 21 | +is the same as `curve25519` except that the info parameter for the HKDF is the |
| 22 | +concatenation of: |
| 23 | + |
| 24 | + * The string `MATRIX_KEY_VERIFICATION_SAS|`. |
| 25 | + * The Matrix ID of the user who sent the `m.key.verification.start` message, |
| 26 | + followed by `|`. |
| 27 | + * The Device ID of the device which sent the `m.key.verification.start` |
| 28 | + message, followed by `|`. |
| 29 | + * The public key from the `m.key.verification.key` message sent by the device |
| 30 | + which sent the `m.key.verification.start` message, followed by `|`. |
| 31 | + * The Matrix ID of the user who sent the `m.key.verification.accept` message, |
| 32 | + followed by `|`. |
| 33 | + * The Device ID of the device which sent the `m.key.verification.accept` |
| 34 | + message, followed by `|`. |
| 35 | + * The public key from the `m.key.verification.key` message sent by the device |
| 36 | + which sent the `m.key.verification.accept` message, followed by `|`. |
| 37 | + * The `transaction_id` being used. |
| 38 | + |
| 39 | +The differences from `curve25519` are the addition of the public keys, and the |
| 40 | +addition of `|` as delimiter between the fields. |
| 41 | + |
| 42 | +The `key_agreement_protocol` `curve25519` is deprecated and may be removed in |
| 43 | +the future. It will no longer be mandatory for clients to support, and new |
| 44 | +implementations are discouraged from implementing it. |
| 45 | + |
| 46 | +## Implementation |
| 47 | + |
| 48 | +This has been implemented in: |
| 49 | + |
| 50 | +- Riot Web 1.6.3 (matrix-js-sdk 6.2.0) |
| 51 | +- Riot Android 0.9.12 (matrix-android-sdk 0.9.35) |
| 52 | +- RiotX 0.21 |
| 53 | +- Riot iOS 0.11.5 (matrix-ios-sdk 0.16.5) |
| 54 | +- matrix-weechat and pantalaimon (matrix-nio 0.12.0) |
| 55 | +- famedlysdk |
0 commit comments