The Misfin mail protocol (prototype B)

(updated 11 May 2023)

(for comments, suggestions, well-wishes, insults, etc. - send a Misfin letter to rfc@misfin.org)

1 Overview

Misfin is a client-server mail transport protocol, broadly similar to SMTP and heavily influenced by Gemini. All connections follow the pattern request-response, and are closed at the end of this transaction.

Misfin servers on TCP/IP should be bound to port 1958, which is unprivledged and should be accessible without administrator permissions on most systems.

1.1 Misfin transactions

The sole type of Misfin transaction delivers a message from a client to a server. This transaction proceeds as so:

C: Opens connection

S: Accepts connection

C/S: Complete TLS handshake

C/S: Validate peer's certificate[s]

C: Sends one CRLF terminated line - the request

S: Sends one CRLF terminated line - the response

C/S: Closes connection, handling response if not OK

Both clients and servers should gracefully handle connections that close before they are expected to.

1.2 Misfin request scheme

A single request line is sent by the Misfin client to a Misfin server, following this structure:

misfin://<MAILBOX>@<HOSTNAME><SPACE><MESSAGE><CR><LF>

MAILBOX is the user receiving the message.

HOSTNAME is the domain name that points to the Misfin server.

SPACE is a single space character, i.e. the byte 0x20.

The remainder of the request following the SPACE, and up until the terminating CRLF, makes up the MESSAGE, which is assumed to be Gemtext (text/gemini). All strings are UTF-8 encoded, and the entire request should not exceed 2048 bytes.

By including the hostname of the server in the request, advanced Misfin servers can host mailboxes for multiple domains on the same host. Servers are not required to implement this feature, and are only expected to service mail for a single domain.

1.3 Misfin response scheme

The Misfin server will send a single response line to the requesting client, following this structure:

<STATUS><SPACE><META><CR><LF>

STATUS is a two-digit numeric status code.

META is a string whose meaning is defined by the status code.

Like requests, response strings are UTF-8 encoded and should not exceed 2048 bytes in length. After the response is sent, the transaction is finished, and the connection should be closed.

2 Status codes

Misfin servers send a two-digit status code in their response to the client, which either confirms the message was delivered, or explains why it wasn't. The status code's category is indicated by the first digit, so simple clients only need to read the first character of the response to know, broadly, what it should do.

These status codes are designed to be compatible with Gemini's, so developers comfortable with Gemini status codes should intuitively know the meaning of Misfin status codes.

2.1 1x (INPUT)

These codes are reserved, and must not be sent by a Misfin server.

2.2 2x (SUCCESS)

Status codes beginning with 2 are SUCCESS status codes, which mean that the client's message has been delivered.

20 <fingerprint> - MESSAGE DELIVERED

The message was delivered successfully. The META tag is the fingerprint of the recipient's certificate - see section 3.1.

2.3 3x (REDIRECT)

Status codes beginning with 3 are REDIRECT status codes, which tell the client to resend their request to a different Misfin server.

30 <address> - SEND HERE INSTEAD

The mailbox has moved to a different address, and this message should be resent to that address.

31 <address> - SEND HERE FOREVER

The mailbox has moved to a different address, and all future messages should be sent to that address.

2.4 4x (TEMPORARY FAILURE)

Status codes beginning with 4 are TEMPORARY FAILURE status codes, which mean the request did not succeed, but might succeed if retried in the future.

40 - TEMPORARY ERROR

The mailserver experienced a transient issue, and the message should be resent.

41 - SERVER IS UNAVAILABLE

The mailserver can't accept mail right now.

42 - CGI ERROR

A mailserver script ran for your message, but experienced an error.

43 - PROXYING ERROR

There was a problem accepting mail for that domain, but it might resolve itself.

44 - SLOW DOWN

You are being rate limited - wait before trying to send more mail.

45 - MAILBOX FULL

The mailbox isn't accepting mail right now, but it might in the future.

2.5 5x (PERMANENT FAILURE)

Status codes beginning with 5 are PERMANENT FAILURE status codes, which mean the request did not succeed, and should not be retried.

50 - PERMANENT ERROR

Something is wrong with the mailserver, and you should not try to resend your message.

51 - MAILBOX DOESN'T EXIST

The mailbox you are trying to send to doesn't exist, and the mailserver won't accept your message.

52 - MAILBOX GONE

The mailbox you are trying to send to existed once, but doesn't anymore.

53 - DOMAIN NOT SERVICED

This mailserver doesn't serve mail for the hostname you provided.

59 - BAD REQUEST

Your request is malformed, and won't be accepted by the mailserver.

2.6 6x (AUTHENTICATION FAILURE)

Status codes beginning with 6 are AUTHENTICATION FAILURE status codes, which mean that there was an issue with the client's certificate.

60 - CERTIFICATE REQUIRED

This mailserver doesn't accept anonymous mail, and you need to repeat your request with a certificate.

61 - UNAUTHORIZED SENDER

Your certificate was validated, but you are not allowed to send mail to that mailbox.

62 - CERTIFICATE INVALID

Your certificate might be legitimate, but it has a problem - it is expired, or it doesn't point to a valid Misfin identity, etc.

63 - YOU'RE A LIAR

Your certificate matches an identity that the mailserver recognizes, but the fingerprint has changed, so it is rejecting your message.

64 - PROVE IT

The mailserver needs you to complete a task to confirm that you are a legitimate sender. (This is reserved for a Hashcash style anti-spam measure).

3 TLS

The use of TLS is mandatory for Misfin transactions. The minimum permissible version of TLS allowed for transactions is TLS 1.2, but clients and servers may choose a more recent version of TLS to support and disallow connections from earlier versions.

Misfin clients and servers must send a TLS "close-notify" prior to closing the connection, so that a complete transaction can be distinguished from one that has ended prematurely.

3.1 Misfin identity certificates

Senders and recipients are identified via self-signed x509 certificates, sent as part of a Misfin transaction's TLS handshake. Senders are not required to send a certificate, but are strongly urged to do so, and mailservers should require sender certificates (unless you really know what you are doing).

A Misfin identity consists of a mailbox name, the hostname of the user's mailserver, and a human-readable description of the mailbox or user (the blurb). The mailbox and blurb are stored in the USER_ID and COMMON_NAME fields, respectively, of the certificate's Distinguished Name (as per RFC 4514). The hostname is stored as a DNS record in the certificate's SUBJECT_ALT_NAME extension, to be compatible with Server Name Indication (SNI). Other fields in the subject and issuer names can be present, but are not required to be present, and should not be relied on by Misfin utilities.

A Misfin address is written as "mailbox@hostname", or "blurb (mailbox@hostname)" in longform.

Multiple mailboxes can be serviced by a single mailserver; in this case, the mailserver's certificate should be self-signed, and each mailbox certificate should be signed by the mailserver certificate, so other clients and servers can confirm that those mailboxes actually exist on the mailserver. Mailserver certificates used this way should have the CA constraint set to True, so the mailserver certificate can cryptographically verify its mailbox certificates.

The fingerprint of a Misfin certificate should be a SHA256 hash, and sent as a hexadecimal number without octet separators. Clients and servers should make an effort to normalize received fingerprints that don't match this specification, by lowering the case of the fingerprint or stripping out non-alphanumeric characters.

3.2 Certificate validation

Misfin clients and servers send certificates during a transaction, but have no obligation to verify these certificates; however, this is highly, highly discouraged.

Like Gemini, the default validation method for certificates is TOFU, or Trust on First Use. Misfin clients and servers should store the fingerprint of a received certificate the first time it is received, and subsequent certificates from that client or server should be matched against the stored fingerprint.

Advanced Misfin servers may perform CA validation in addition to TOFU. In this scheme, upon receiving a message from a sender with an unrecognized host, the Misfin server may perform a single blank request to the sender's host, and store its certificate. That stored certificate can then be used to verify the certificates of senders purporting to be from that host.

Certificates may be signed by other CAs; Misfin servers may choose to verify these signatures, but are not required to.

3.3 Security implications

TOFU is a better-than-nothing strategy that should be suitable for most Misfin users; as long as you've successfully interacted with a legitimate sender once, future attempts to intercept or forge interactions with them will fail.

CA validation is even better; you only need to have an uncompromised connection to a server once, and you can then verify the legitimacy of anyone reporting to have a mailbox with them. This method also has the effect of disallowing messages from senders that are not associated with a Misfin server, which might be desireable in some cases.

Since the sender of a message is identified solely by their certificate, it is not possible to spoof the sender's address in a way that is not visible to the recipient. For instance, you could generate a new, self-signed certificate claiming to be bob@example.com, and send mail pretending to be Bob; however, any replies to those messages will be delivered to the Misfin server at example.com, and not to you.

4 Mail file format (gemmail)

The default encoding of Misfin messages is text/gemini; however, Misfin extends this by adding three new line types. Misfin utilites must only parse the first occurance of these lines in a file.

4.1 Sender line

The sender line records the Misfin address of the user that sent the message. Sender lines begin with a single "<" character, and have this syntax:

< mailbox@hostname.com blurb

The whitespace separating the < and the address is optional. The blurb is also optional, but if it is included, it must be separated from the address by whitespace.

Sender lines should be added by the server when saving or retransmitting a message. If a message is forwarded, the original sender line should be preserved and sent alongside, so the final recipient will see both senders:

< development@mailing-lists.com Development mailing list
< source@example.com Source user
...

4.2 Recipients line

The recipients line begins with a single ":" character, and denotes all receivers of a message, separated by whitespace:

: one@example.com two@example.com three@example.com ...

When replying to a Misfin message, it should be delivered to the address in the sender line (if present), followed by the addresses in the recipients line. Misfin clients are required to check for duplicate addresses, and not send multiple copies of the message to the same recipient. Misfin clients must also check to make sure they are not sending mail back to their sending address.

A recipient line can added for messages going to only one person, but since replies go to the sending address anyway, this shouldn't be done - it's overkill.

4.3 Timestamp line

This line type is a work in progress, but the intention is to record when the message was received - useful if your mailbox is implemented as a single text file (like UNIX back in the day) or when forwarding a message.

Timestamp lines begin with a single "@" character, and are followed by the time in ISO-8601 format:

@ 2023-05-09T19:39:15Z

Like sender lines, timestamp lines should be added by the receiving mailserver, and only sent if forwarding a message, in which case they should be left as-is.

4.4 Message subject

The first heading line in a file, if provided, should be considered as the message's subject, and advanced Misfin utilities may elect to show it to the user in place of the full message contents.

4.5 Example messages

The simplest messages may just consist of a sender line:

< friend@example.com Your Friend

What's up?

A group message can be sent with a recipients line:

< one@example.com Person One
: two@example.com three@example.com

A funny joke

...and the replies will have the addresses shuffled around to make sense:

< two@example.com Person Two
: one@example.com three@example.com

Rolling on the floor laughing

A message from a mailing list might read:

< workers@hive.com Worker bees list
< 33@hive.com Bee #33

# A note on flowers

The green snappy looking ones are venus flytraps and you SHOULD NOT interact