💾 Archived View for gemini.ucant.org › heterodox-tech › latssiam.gmi captured on 2024-05-26 at 14:40:31. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-03-21)
-=-=-=-=-=-=-
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"
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.
LATSSIAM has five verbs:
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.
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.
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.
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).
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.
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]
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.
Where certificate fingerprints are references, this is the SHA256 fingerprint of the DER-encoded certificate, with no colons and with everything in lower-case.
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.
All status codes sent by server or client must start with two digits followed by a single space.
The server then sends its certificate signing request to the client
The client then sends the server's attestation certificate back to the server
Where a client has established a TLS connection without proffering a client certificate, the server should respond to most requests with this code.
The mailbox is configured not to accept more messages from this client, possibly because the client has sent too many (unread) messages already.
The client is sending messages more quickly than the server chooses to accept them.
State machine: READY ----> EXPECT_SIG ----> EXPECT_MSG ^ ^ ^ | | | | | v | | | +----------------------------+ | | | +-------> EXPECT_RCT | +---------> EXPECT_ATTEST
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.
Misfin has shown that it is useful to have functions for deriving:
LATSSIAM has:
https://stackoverflow.com/questions/5355046/where-is-the-pem-file-format-specified
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")