Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  md-d2d-join.proto   Sprache: unbekannt

 
Spracherkennung für: .proto vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// ## Device Join Protocol
//
// This protocol specifies how to add a new device to an existing device group.
//
// ### Terminology
//
// - `ED`: Existing device
// - `ND`: New device to be added
//
// ### Blobs
//
// For binary data, the usual Blob scheme is being used by ED. However, instead
// of transferring Blob data via the Blob server, the data is transmitted in
// form of a `common.BlobData` message ahead of a message referencing that Blob
// by the associated Blob ID.
//
// ND is supposed to cache received `common.BlobData` until it can associate the
// data to a Blob referencing its ID. Once the rendezvous connection has been
// closed, any remaining cached `common.BlobData` can be discarded.
//
// ### Protocol Kickoff Flow
//
// ND or ED may choose to start the protocol. If ND starts the protocol it is
// _requesting to join the device group_. If ED starts the protocol it is
// _offering to join the device group_.
//
// If ED started the protocol:
//
// - `variant` must be set to _offer to join the device group_.
// - ED takes the role of RID
// - ND takes the role of RRD
//
// If ND started the protocol:
//
// - `variant` must be set to _request to join the device group_.
// - ND takes the role of RID
// - ED takes the role of RRD
//
// #### Connection Setup
//
// RID creates a `rendezvous.RendezvousInit` by following the Connection
// Rendezvous Protocol. It wraps it in a `url.DeviceGroupJoinRequestOrOffer` and
// offers it in form of a URL or a QR code.
//
// RRD scans the QR code or decodes the URL and then parses the
// `url.DeviceGroupJoinRequestOrOffer`. It will then receive the data over a
// sufficiently secure channel (e.g. a QR code). Once decoded, the enclosed
// `rendezvous.RendezvousInit` must be handled according to the Connection
// Rendezvous Protocol.
//
// Once the Connection Rendezvous Protocol has established at least one
// connection path, ED waits another 3s or until all connection paths have been
// established. Nomination is then done by ED following the Connection
// Rendezvous Protocol.
//
// Note that all messages on the nominated connection path must be end-to-end
// encrypted as defined by the Connection Rendezvous Protocol. All transmitted
// messages are to be wrapped in:
//
// - `NdToEd` when sending from ND to ED, and
// - `EdToNd` when sending from ED to ND.
//
// #### Device Join Flow
//
// As soon as one of the connection paths has been nominated by ED, both devices
// must calculate the Rendezvous Path Hash (RPH) as defined by the Rendezvous
// Protocol and display it to the user.
//
// ED must ask the user for confirmation that RPH is equal on both devices. The
// exact comparison mechanism is an implementation detail. If the user does not
// confirm that RPH is equal on both devices, the process must be aborted.
//
// After confirmation, ED must stop displaying RPH and send a `Begin` message to
// start the device join process.
//
//     ED ------- Begin ------> ND   [1]
//
// ND can now stop displaying RPH.
//
//     ED -- common.BlobData -> ND   [0..N]
//     ED --- EssentialData --> ND   [1]
//
// Once ND successfully registered itself on the Mediator server, it sends a
// `Registered` message.
//
//     ED <---- Registered ---- ND   [1]
//
// ND may now either close the connection or leave it open to transition to the
// History Exchange Protocol. Any further messages ED receives from ND will
// transition into the History Exchange Protocol.
//
// ### Security
//
// The `url.DeviceGroupJoinRequestOrOffer` must be exchanged over a sufficiently
// secure channel. A QR code is considered sufficiently secure in a _safe
// space_. If this can be ensured by the user, ensuring that the Rendezvous Path
// Hash (RPH) is equal on both devices is not strictly necessary.
//
// If an attacker is however able to capture the
// `url.DeviceGroupJoinRequestOrOffer`, the security of the protocol relies on
// the user ensuring that RPH is equal on both devices to ensure authentication
// and mitigate the following attacks:
//
// - If ED started the protocol (offers to join the device group), comparing RPH
//   is critical as otherwise the Client Key would become compromised if an
//   attacker were able to make a connection faster than the victim's other
//   device.
// - If ND started the protocol (requests to join the device group), comparing
//   RPH is not as critical yet still vital to mitigate a more sophisticated
//   attack where the attacker makes it look as if the victim is connected to
//   its device group. Until the victim finds out that it isn't its device group
//   (because the process is stuck on ED), the victim may potentially leak
//   sensitive information by adding a contact or sending a message, etc.
// - An attacker who also controls the relay server used for connection between
//   the victim's two devices could run a full MITM attack. Comparing RPH here
//   is critical to ensure that the victim's two devices have established an
//   end-to-end encrypted communication channel between each other.
//
// Letting ND start the protocol is considered more secure because of the above
// implications.
//
// ED is always required to let the user confirm the equality of RPH on both
// devices because it is ED who is to transmit the highly sensitive information.
//
// To prevent phishing attacks of a malicious web app claiming to be a Threema
// App (typo squatting), the CORS `Access-Control-Allow-Origin` of any WebSocket
// rendezvous relay server must be set to the bare minimum required by the use
// case, so that a connection cannot be established. However, phishing
// protection against a malicious non-web app claiming to be a Threema App is
// not possible.

syntax = "proto3";

package join;

option java_package = "ch.threema.protobuf.d2d.join";

import "common.proto";
import "md-d2d-sync.proto";

// Root message envelope for messages from the new device (ND) to the existing
// device (ED).
message NdToEd {
  // The enveloped message
  oneof content {
    Registered registered = 1;
  }
}

// Root message envelope for messages from the existing device (ED) to the new
// device (ND).
message EdToNd {
  // The enveloped message
  oneof content {
    Begin begin = 1;

    // A Blob that is referenced as part of `EssentialData`.
    //
    // When receiving this variant:
    //
    // 1. If `EssentialData` has been received before, close the connection and
    //    abort these steps.
    // 2. Store the Blob data temporarily or permanently and store its
    //    associated Blob ID in the device's database.
    common.BlobData blob_data = 2;

    EssentialData essential_data = 3;
  }
}

// Initial message sent by ED after nomination and user confirmation that RPH is
// identical on both devices.
//
// When creating this message, after confirmation by the user:
//
// 1. Stop displaying RPH and notify the user that the device join process is in
//    progress.
// 2. Begin a transaction (scope `NEW_DEVICE_SYNC`, precondition: none) on the
//    D2M connection. This transaction is to be held until the connection to ND
//    drops or until a `Registered` message was received. While the transaction
//    is being held, no `Reflected` and no end-to-end encrypted message coming
//    from the chat server is allowed to be processed! If the D2M connection is
//    lost, the established connection must also be closed, aborting any running
//    steps of this protocol.
// 3. Send the `Begin` message and continue with the steps for creating
//    `EssentialData`.
//
// When receiving this message:
//
// 1. If `Begin` has been received before, close the connection and abort these
//    steps.
// 2. Stop displaying RPH and notify the user that the device join process is in
//    progress.
message Begin {}

// Essential data ND needs to be able to participate in the device group.
//
// Note: The transmitted used nonces are hashed with HMAC-SHA256 using the
// identity as _key_.
//
// When creating this message:
//
// 1. Gather all blobs referenced for the user's profile picture, contact
//    profile pictures, etc. and send them as `common.BlobData` before this
//    message.
// 2. Send the gathered `EssentialData`.
//
// When receiving this message:
//
// 1. If `EssentialData` has been received before, close the connection and
//    abort these steps.
// 2. If any Blob ID is missing from the previously received set of
//    `common.BlobData`, close the connection and abort these steps.
// 3. Store the data in the device's database.
// 4. Generate a random D2M Device ID and a random CSP Device ID and store both
//    in the device's database.
// 5. Establish a D2M connection by connecting to the provided mediator server.
// 6. Wait until the `ServerInfo` has been received on the D2M connection.
//    Validate that the provided `DeviceSlotState` is `NEW`. Otherwise, close
//    both the D2M connection (normally) and the connection to ED and abort
//    these steps.
// 7. Send a `Registered` message to ED.
// 8. Ask the user whether conversation history data should be requested from
//    ND:
//    1. If the user does not want to request conversation history data, wait
//       until all buffered data on the connection has been written. Then, close
//       the connection and abort these steps.
//    2. If the user wants to request conversation history data from ED, leave
//       the connection running and start the History Exchange Protocol.
message EssentialData {
  reserved 1; // Reserved for mediator server

  // User's identity data
  message IdentityData {
    // The user's Threema ID
    string identity = 1;

    // The permanent client key associated to the Threema ID (32 bytes)
    bytes ck = 2;

    // The device cookie used by the device group for the Threema ID (16 bytes)
    bytes csp_device_cookie = 3;

    // The CSP server group associated to the Threema ID (1 byte)
    string csp_server_group = 4;
  }
  IdentityData identity_data = 2;

  // Threema Work credentials
  //
  // Required for a Threema Work app. Must not be present in a Threema consumer
  // app.
  sync.ThreemaWorkCredentials work_credentials = 12;

  // Device group data
  message DeviceGroupData {
    // The device group key (32 bytes)
    bytes dgk = 1;
  }
  DeviceGroupData device_group_data = 3;

  // User's profile
  sync.UserProfile user_profile = 4;

  // Shared settings
  sync.Settings settings = 5;

  // MDM parameters
  //
  // Optional for a Threema Work app. Must not be present in a Threema consumer app.
  //
  // [//]: # "TODO(SE-307): Make this required for Threema Work!"
  sync.MdmParameters mdm_parameters = 6;

  // Contacts
  message AugmentedContact {
    // The contact's data.
    sync.Contact contact = 1;

    // Unix-ish timestamp in milliseconds when the conversation with this
    // contact was last updated.
    //
    // Optional if no conversation exists for this contact.
    optional uint64 last_update_at = 2;
  }
  repeated AugmentedContact contacts = 7;

  // Groups
  message AugmentedGroup {
    // The group's data.
    sync.Group group = 1;

    // Unix-ish timestamp in milliseconds when the conversation with this
    // group was last updated.
    uint64 last_update_at = 2;
  }
  repeated AugmentedGroup groups = 8;

  // Distribution lists
  message AugmentedDistributionList {
    // The distribution list's data.
    sync.DistributionList distribution_list = 1;

    // Unix-ish timestamp in milliseconds when the conversation of this
    // distribution list was last updated.
    uint64 last_update_at = 2;
  }
  repeated AugmentedDistributionList distribution_lists = 9;

  // Hashed nonces that were used for CSP messages.
  repeated bytes csp_hashed_nonces = 10;

  // Hashed nonces thate were used for D2D messages.
  repeated bytes d2d_hashed_nonces = 11;
}

// Lets ED know that ND has received all essential data and successfully
// registered itself on the mediator server.
//
// When receiving this message:
//
// 1. Commit the transaction on the D2M connection. From this point on,
//    processing `Reflected` and end-to-end encrypted message coming from the
//    chat server is allowed again.
// 2. Wait for ND to either close the connection or for ND to request
//    conversation history data. Any further messages from ND will move into
//    the History Exchange Protocol.
message Registered {}

[Dauer der Verarbeitung: 0.28 Sekunden, vorverarbeitet 2026-04-27]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge