Latssiam

LATSSIAM is to be a minimalist end-to-end encrypted messaging protocol using X.509 certificates. It shall sit somewhere between SMTP, IRC, Signal and Misfin. It is appropriate for communication between parties that have already been introduced to each other.

LATSSIAM stands for "Lightweight Alternative To SMTP, Signal, IRC And Misfin"

Sketch

LATSSIAM requires all connections be made TLS-encrypted to port 1977. During the TLS handshake, certificates should be trusted on a Trust On First Use basis.

A LATSSIAM implementation should hang up the connection if the other side violates the protocol.

Verbs

LATSSIAM has five verbs:

Mapping

LATSSIAM uses the same mapping from certificate to address as Misfin, using the subjectAltName field from the certificate.

LATSSIAM maps from the address in the domain to IP addresses via DNS records: firstly the MX record should be checked, as per SMTP, and then the A/AAAA record.

Wire format

LATSSIAM is an aggressively line-oriented protocol and all lines must be terminated with CRLF. No line transmitted by server or client shall be longer than 73 characters, including the trailing CRLF.

Where data is being transmitted in a base64-encoded block, the maximum number of lines in any such block shall be 400.

Message transmission

C: SEND <recipient-fingerprint>
S: 30 Recipient recognised; proceed
C: -----BEGIN ENCRYPTED MESSAGE-----
   X2ogZwcsUEwWPPuDxzgSYW7AbQTrxkd/mbEiut3h3Q1DXLttfP6lkczXkBnm0XX0
   zmrhQiUFWjOsK5Pg4Wtt7kBkb8httNReZkL9om2qMaoaMNnndxDpQ8PxlTCd3nxM
   FTpMrAz/Ljd9/a8jkfwvGZIkstmZduUP9J84jrQgwEErOz3oPt6wg4z2TkRvOM3M
   +1jAIEBaRCVtNb4z+Hu0Qe4hvi9FGvR3Qcxk8QkS5k9LQ9ZOnAcWyMO2lqAB5EDp
   L3c61A/f7+N6ZARfh82MTtp/ObayFt0bq7E57I1lyHRyrpyYadA9xSRMauVCkPj+
   pUAw2xyW62jo7c6+8PqgjA==
   -----END ENCRYPTED MESSAGE-----
S: 31 Message accepted

C can hang up at this point.

S may insist on a signature, in which case a client must transmit a signature block immediately *before* sending the message:

C: SEND <recipient-fingerprint>
S: 30 Recipient recognised; proceed
C: -----BEGIN ENCRYPTED MESSAGE-----
   X2ogZwcsUEwWPPuDxzgSYW7AbQTrxkd/mbEiut3h3Q1DXLttfP6lkczXkBnm0XX0
   zmrhQiUFWjOsK5Pg4Wtt7kBkb8httNReZkL9om2qMaoaMNnndxDpQ8PxlTCd3nxM
   FTpMrAz/Ljd9/a8jkfwvGZIkstmZduUP9J84jrQgwEErOz3oPt6wg4z2TkRvOM3M
   +1jAIEBaRCVtNb4z+Hu0Qe4hvi9FGvR3Qcxk8QkS5k9LQ9ZOnAcWyMO2lqAB5EDp
   L3c61A/f7+N6ZARfh82MTtp/ObayFt0bq7E57I1lyHRyrpyYadA9xSRMauVCkPj+
   pUAw2xyW62jo7c6+8PqgjA==
   -----END ENCRYPTED MESSAGE-----
S: 32 Signaure required
C: SEND <recipient-fingerprint>
S: 30 Recipient recognised; proceed
C: -----BEGIN SIGNATURE-----
   MIX2ZwcsUEwWPPuDxzgSYW7AbQTrxkd/mbEiut3h3Q1DXLttfP6lkczXkBnm0XX0
   pUAw2xyW62jo7c6+8PqgjA==
   -----END SIGNATURE-----
   -----BEGIN ENCRYPTED MESSAGE-----
   X2ogZwcsUEwWPPuDxzgSYW7AbQTrxkd/mbEiut3h3Q1DXLttfP6lkczXkBnm0XX0
   zmrhQiUFWjOsK5Pg4Wtt7kBkb8httNReZkL9om2qMaoaMNnndxDpQ8PxlTCd3nxM
   FTpMrAz/Ljd9/a8jkfwvGZIkstmZduUP9J84jrQgwEErOz3oPt6wg4z2TkRvOM3M
   +1jAIEBaRCVtNb4z+Hu0Qe4hvi9FGvR3Qcxk8QkS5k9LQ9ZOnAcWyMO2lqAB5EDp
   L3c61A/f7+N6ZARfh82MTtp/ObayFt0bq7E57I1lyHRyrpyYadA9xSRMauVCkPj+
   pUAw2xyW62jo7c6+8PqgjA==
   -----END ENCRYPTED MESSAGE-----
S: 31 Message accepted

The client may opportunistically send the signature even when not demanded by the server.

Stored message retrieval

C can also request a switch of roles, and pull down one message from the server, POP3-style. It can keep doing this until the server indicates that there are no more messages to be had. Note that in this context, the client is likely to be the recipient of messages which have already been delivered to the server, rather than representing someone sending new messages.

The ACCEPT verb is in the tradition of STMP's ETRN/ATRN/TURN verbs.

C: ACCEPT 0
S: 40 Message follows
   -----BEGIN ENCRYPTED MESSAGE-----
   X2ogZwcsUEwWPPuDxzgSYW7AbQTrxkd/mbEiut3h3Q1DXLttfP6lkczXkBnm0XX0
   zmrhQiUFWjOsK5Pg4Wtt7kBkb8httNReZkL9om2qMaoaMNnndxDpQ8PxlTCd3nxM
   FTpMrAz/Ljd9/a8jkfwvGZIkstmZduUP9J84jrQgwEErOz3oPt6wg4z2TkRvOM3M
   +1jAIEBaRCVtNb4z+Hu0Qe4hvi9FGvR3Qcxk8QkS5k9LQ9ZOnAcWyMO2lqAB5EDp
   L3c61A/f7+N6ZARfh82MTtp/ObayFt0bq7E57I1lyHRyrpyYadA9xSRMauVCkPj+
   pUAw2xyW62jo7c6+8PqgjA==
   -----END ENCRYPTED MESSAGE-----
C: 31 Message accepted
C: ACCEPT 0
S: 40 Message follows
   -----BEGIN ENCRYPTED MESSAGE-----
   X2ogZwcsUEwWPPuDxzgSYW7AbQTrxkd/mbEiut3h3Q1DXLttfP6lkczXkBnm0XX0
   FTpMrAz/Ljd9/a8jkfwvGZIkstmZduUP9J84jrQgwEErOz3oPt6wg4z2TkRvOM3M
   [some different encrypted message block]
   +1jAIEBaRCVtNb4z+Hu0Qe4hvi9FGvR3Qcxk8QkS5k9LQ9ZOnAcWyMO2lqAB5EDp
   L3c61A/f7+N6ZARfh82MTtp/ObayFt0bq7E57I1lyHRyrpyYadA9xSRMauVCkPj+
   pUAw2xyW62jo7c6+8PqgjA==
   -----END ENCRYPTED MESSAGE-----
C: 31 Message accepted
C: ACCEPT 0
S: 33 No more messages available

The server may send a code 37 to slow down obnoxiously eager clients misusing this facility.

The only argument to ACCEPT is the deadline, in seconds, for the server's response. A server may hang up the connection for any deadline greater than zero seconds which it deems inappropriate. Otherwise, the server must wait until the earlier of the deadline and the arrival of a relevant message before responding (with, e.g., code 40 or 33 as the case may be). The argument is to be separated by a single space. Where a non-zero deadline has been specified, both sides should use appropriate TCP and TLS keepalive mechanisms.

The server must prepend the signature if it has one, and the client may otherwise reject the message with the appropriate code (32).

Mailbox registration

C may also send "MAILBOX REGISTER" or "MAILBOX DEREGISTER".

The server must create a new mailbox on successful registration, for the public key and certificate proffered by the client during TLS session handshake.

After successful deregistration, the server should respond to future message sending attempts to that mailbox with code 34 or 38.

C: MAILBOX REGISTER <wrong-password>
S: 11 Registration refused
C: MAILBOX REGISTER <password>
S: 13 Attestion requested
   -----BEGIN CERTIFICATE REQUEST-----
   MIIByjCCATMCAQAwgYkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
   MRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMR8w
   HQYDVQQLExZJbmZvcm1hdGlvbiBUZWNobm9sb2d5MRcwFQYDVQQDEw53d3cuZ29v
   Z2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApZtYJCHJ4VpVXHfV
   IlstQTlO4qC03hjX+ZkPyvdYd1Q4+qbAeTwXmCUKYHThVRd5aXSqlPzyIBwieMZr
   WFlRQddZ1IzXAlVRDWwAo60KecqeAXnnUK+5fXoTI/UgWshre8tJ+x/TMHaQKR/J
   cIWPhqaQhsJuzZbvAdGA80BLxdMCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAIhl
   4PvFq+e7ipARgI5ZM+GZx6mpCz44DTo0JkwfRDf+BtrsaC0q68eTf2XhYOsq4fkH
   Q0uA0aVog3f5iJxCa3Hp5gxbJQ6zV6kJ0TEsuaaOhEko9sdpCoPOnRBm2i/XRD2D
   6iNh8f8z0ShGsFqjDgFHyF3o+lUyj+UC6H1QW7bn
   -----END CERTIFICATE REQUEST-----
C: 14 Attestation follows
C: -----BEGIN CERTIFICATE-----
   MIIDHzCCAgegAwIBAgIUEs0q/FWrMLL+8JUD3P15yIcYahEwDQYJKoZIhvcNAQEL
   BQAwLTEVMBMGCgmSJomT8ixkAQEMBW1rMjcwMRQwEgYDVQQDDAtUZW1wIE1pc2Zp
   bjAgFw0yNDAxMDgxNzM1MjZaGA8yMTEzMDkyNjE3MzUyNlowLTEVMBMGCgmSJomT
   8ixkAQEMBW1rMjcwMRQwEgYDVQQDDAtUZW1wIE1pc2ZpbjCCASIwDQYJKoZIhvcN
   AQEBBQADggEPADCCAQoCggEBALTLZ7gFoXfFbo+v+Pe+9G2xsEtwk7qNcCTL89fl
   8Mw89fkJrEwsfaCMEqLj7U7cDkA8EwyDiYXk3N79hvamdru/5CiWfzJqfA3Areeq
   AKpzG2isYfa/XB9LglVtWRP0KsfG0iXFgw04WvtlQfMJRkVU0au3y6lVl8m2oOUu
   [etc, etc]
   tja/SvSNIfxK6/N8jTzE0yyWBO2PJK9QuvnIrhF7pxmp13s=
   -----END CERTIFICATE-----
S: 10 Registration complete

To register, a client must provide a password that the server operator has pre-shared. The server should then transmit a CSR and the client should sign it and transmit it back.

The password must not contain bytes other than those between 32 and 127 inclusive.

Address verification

C may wish to check that S actually is authorised to receive encrypted messages to a mailbox. Clients may routinely request this before sending a message, and servers must not terminate the connection solely for this reason. In LATSSIAM, a server certificate signed by a recipient whose mailbox it hosts is called an "attestion", for which see below.

C: VERIFY <recipient-fingerprint>
S: 14 Attestation follows
S: -----BEGIN CERTIFICATE-----
   MIIDHzCCAgegAwIBAgIUEs0q/FWrMLL+8JUD3P15yIcYahEwDQYJKoZIhvcNAQEL
   BQAwLTEVMBMGCgmSJomT8ixkAQEMBW1rMjcwMRQwEgYDVQQDDAtUZW1wIE1pc2Zp
   bjAgFw0yNDAxMDgxNzM1MjZaGA8yMTEzMDkyNjE3MzUyNlowLTEVMBMGCgmSJomT
   8ixkAQEMBW1rMjcwMRQwEgYDVQQDDAtUZW1wIE1pc2ZpbjCCASIwDQYJKoZIhvcN
   AQEBBQADggEPADCCAQoCggEBALTLZ7gFoXfFbo+v+Pe+9G2xsEtwk7qNcCTL89fl
   8Mw89fkJrEwsfaCMEqLj7U7cDkA8EwyDiYXk3N79hvamdru/5CiWfzJqfA3Areeq
   AKpzG2isYfa/XB9LglVtWRP0KsfG0iXFgw04WvtlQfMJRkVU0au3y6lVl8m2oOUu
   [etc, etc]
   tja/SvSNIfxK6/N8jTzE0yyWBO2PJK9QuvnIrhF7pxmp13s=
   -----END CERTIFICATE-----
C: SEND <recipient-fingerprint>
[etc]

Attestation

The server may need to attest to the client that it *is* indeed authorised by a recipient to handle that recipient's messages. As the messsages are encrypted, there is no risk of the server operator actually reading them. Attestation protects, in particular, against the accidental transmission to a misconfigured server of messages that it shouldn't have been sent.

Attestation is achieved by recipients' signing of the server's certificate with their own. A client may request that the server provide this attestation in the form of an additional certificate. It is not required that the server present such a certificate during the TLS handshake, as that might require hundreds of certificates, one for each mailbox.

Fingerprints

Where certificate fingerprints are references, this is the SHA256 fingerprint of the DER-encoded certificate, with no colons and with everything in lower-case.

Key distribution

via QR code

a LATSSIAM URL should comprise the SHA256 fingerprint of the public key and the gemini URL of the key, with the "gemini:" schema omitted. This supports the Y-Property (q.v.)

latssiam://ddcda7087a6bca80abe469ec57df8abee345f16d3a34123ee81b2775ac67bc91@gemini.ucant.org/pubkey.pem

the QR code, when decoded, must all be converted to lower case.

The implicit schema for downloading the key from the URL is hardwired to "gemini", to avoid executing Javascript or similar if HTTP were available.

Return codes

All status codes sent by server or client must start with two digits followed by a single space.

10 Registration / deregistration complete

11 Registration / deregistration refused

12 Registration pending

13 Attestation requested

The server then sends its certificate signing request to the client

14 Attestation follows

The client then sends the server's attestation certificate back to the server

15 Registration not available for that domain

20 Certificate required

Where a client has established a TLS connection without proffering a client certificate, the server should respond to most requests with this code.

21 Certificate unauthorised

30 Recipient recognised; proceed

31 Message accepted

32 Signature required

33 No more messages available

34 Mailbox does not exist

35 Mailbox moved

36 Mailbox full

The mailbox is configured not to accept more messages from this client, possibly because the client has sent too many (unread) messages already.

37 Slow down

The client is sending messages more quickly than the server chooses to accept them.

38 Mailbox gone

39 Message too long

40 Message follows

50 Syntax error

51 Sequencing error

52 Message refused

53 Internal server error

54 Timeout

State machine

State machine:

    READY ----> EXPECT_SIG ----> EXPECT_MSG
    ^ ^ ^            |               |     
    | | |            v               |     
    | | +----------------------------+
    | |
    | +-------> EXPECT_RCT
    |                     
    +---------> EXPECT_ATTEST   

Notes

Questions

The server has to present the signature of the recipient after receiving messages. If this doesn't happen, then the client should assume that the recipient won't get it.

Functions

Misfin has shown that it is useful to have functions for deriving:

LATSSIAM has:

RFCs re ascii-armour / PEM format

https://stackoverflow.com/questions/5355046/where-is-the-pem-file-format-specified

Openssl CLI crib

Extract pubkey from cert

openssl x509 -pubkey -noout -in cert.pem  > pubkey.pem

Encrypt data, with binary output:

openssl rsautl -encrypt -pubin -inkey pubkey.pem  -in plantext.txt

Base64 the binary output, suitable for ascii armouring / PEM format:

openssl rsautl -encrypt -pubin -inkey pubkey.pem  -in plantext.txt  | \
openssl base64

Decode base64 (note this is not an openssl command):

base64 -d

Make a CSR for user01@my-domain.xyz:

openssl req -new -key private_key.pem -out csr.pem -subj "UID=user123/CN=blurba blurbb" -reqexts SAN -config <(echo "[SAN]\nsubjectAltName=DNS:my-domain.xyz")

IRC-based background notes