Contact pairing

Contact pairing is a two-phase process due to Awala’s E2E encryption and pre-authorisation requirements, and this server plays the role of a broker as follows:

  1. The two parties exchange pairing requests. The order in which requests are received is irrelevant, as the server will wait until both have been received before exchanging them.
  2. The two parties exchange pairing authorisations. The order in which authorisations are received is irrelevant, as the server will forward them as they are received.

The diagram below illustrates the process above:

Contact pairing diagram

The two parties will then be able to communicate with each other using the Awala protocol, without further intervention from this server.

Messages

Contact pairing request

This message signifies a Letro user’s intention to pair with another user.

  • Recipient: Both server and user agent.
  • Content type: application/vnd.relaycorp.letro.contact-pairing.request.
  • Content: A DER-serialised VeraId SignatureBundle encapsulating a ContactPairingRequest structure (see below).

The ASN.1 ContactPairingRequest structure is defined as follows:

ContactPairingRequest ::= SEQUENCE {
  requesterAwalaEndpointPublicKey [0] SubjectPublicKeyInfo -- From the X.509 spec
  prospectiveContactVeraid        [1] UTF8String           -- E.g., "maria@example.com"
}

The following MUST also be true, or else the pairing request will be rejected and a ContactPairingFailure message will be sent to the requester:

  • requesterAwalaEndpointPublicKey corresponds to the Awala endpoint that sent the service message.
  • prospectiveContactVeraid is a well-formed VeraId identifier for a user (e.g., maria@example.com), not a bot (e.g., example.com).

Contact pairing authorisation

This message encapsulates the Awala connection parameters whereby a Letro user (the granter) authorises another user (the grantee) to message them.

  • Recipient: Both server and user agent.
  • Content type: application/vnd.relaycorp.letro.contact-pairing.authorisation.
  • Content: An Awala endpoint’s connection parameters binary. For example, the output from FirstPartyEndpoint.authorizeIndefinitely() in the Awala Android SDK.

Contact pairing failure

This message signifies that a pairing request has failed.

  • Recipient: User agent.
  • Content type: application/vnd.relaycorp.letro.contact-pairing.failure.
  • Content: A DER-serialised ContactPairingFailure structure (see below).

The ASN.1 ContactPairingFailure structure is defined as follows:

ContactPairingFailureReason :: INTEGER {
  INVALID_REQUESTER_VERAID(0),
  INVALID_TARGET_VERAID(1),
  INVALID_REQUESTER_AWALA_KEY(2)
}

ContactPairingFailure ::= SEQUENCE {
  prospectiveContactVeraid [0] UTF8String,  -- E.g., "maria@example.com"
  reason                   [1] ContactPairingFailureReason
}

Where the ContactPairingFailure can be one of the following:

  • INVALID_REQUESTER_VERAID: The requester’s VeraId id is invalid (i.e., it’s a domain name).
  • INVALID_TARGET_VERAID: The target’s VeraId id is malformed or a domain name.
  • INVALID_REQUESTER_AWALA_KEY: The requester’s Awala endpoint public key does not correspond to the one that sent the service message.

Security considerations

Since pairing requests are signed with VeraId, it’s not possible for the server to forge or tamper with them. Worst case scenario, if the server were compromised, it could only prevent pairing requests from being forwarded.

Data persistence

Contact pairing requests are stored for up to 90 days or until they are matched, whichever comes first.