util  nimtas.ct at [f7c93df9f4]

File spec/nimtas.ct artifact 22aa494f33 part of check-in f7c93df9f4


# nimtas protocol
the nimtas protocol is a very simple authentication/identification protocol suitable for embedding in other protocols. 

## definitions
an italicized form indicates a formally specified sequence of bytes. parameters (e.g. the length of an integer form) are placed in angle brackets after the identifier. if the form is bound to a name in context, it is followed by a [`:] and a name in variable notation.
* [*byte], [*byte<1>] ==> one octet
* [*byte<[$N]>] ==> [!byte] [!byte<[=N-1]>]
* [*int<[$N]>] ==>  [!byte<[=N / 8]>] interpreted as a little-endian unsigned integer (e.g. [!int<32>] represents an unsigned little-endian 32-bit integer)
* [*byte-sequence<[$L]>] ==> [!int<[$L]>:[$N]] [!byte<[$N]>], with no specific semantics. that is, a variable-length byte sequence whose size prefix is [$L] bits long

##overview
nimtas is composed of two procedures, the [>proc-id] and the authentication procedure. the identity procedure is a [*strict subset] of the authentication procedure and for some clients may be sufficient. formally, the [>proc-auth] is the protocol entry point.

the initial connection handshake is the responsibility of the containing protocol.

###proc-auth authentication procedure
: to authenticate by identity alone, client immediately follows the [>proc-id]
: to authenticate by challenge:
:: client transmits:
::: [`0x10] indicating challenge auth
::: a [!byte] naming a supported type of challenge
:::: [`0x00] = passphrase/prompt
:::: [`0x01] = SHA3 nonce hash
:::: [`0x02] = libsodium asymmetric signature
:::: [`0x03] = SCRAM
:::: [`0x04] = U2F
:::: [`0xFF] [!int<32>:[$method-number]] = private challenge method
::: client follows the [>proc-id]
:: if the server does not support the selected challenge type, it sends {m.n status-fail} and closes the connection.
:: otherwise, the following steps are repeated until authentication is complete:
::: if authentication is complete, exit loop and jump to ["[report]]
::: otherwise, server sends {m.n status-data} followed by [!byte-sequence<16>:[$challenge-blob]], the meaning of which depends on the selected challenge method
::: client sends [!byte-sequence<16>:[$challenge-response]]
: ["[report]] server reports authentication status
:: if the authentication failed, xmit {m.n status-fail} and close the connection
:: if the authentication succeeded, xmit {m.n status-ok}

! other authentication methods may be defined later. a server that encounters an unknown authentication method must transmit {m.n status-fail} and close the connection, as it cannot know how to interpret any further communications from the client

###proc-id identity procedure
! the identity procedure is a [*strict subset] of the [>proc-auth]

: to identify anonymously, client transmits byte [`0x00].
: to identify externally, client transmits byte [`0x01]. this method indicates that identity is already coded by the connection or challenge context, similar to the SASL EXTERNAL method. possible uses cases include connection over UNIX domain socket, over TLS, or when authenticating via a type of challenge that also supplies identification data.
: to identify by shortname, client transmits byte [`0x02] followed by a [!byte-sequence<8>]. this may be a PSK, a URI, a literal text name, an OID, or anything else depending on what the server is configured to recognize.
: to identify by longname, client transmits byte [`0x03] followed by a [!byte-sequence<16>]. this is identical to the above but allows longer values. technically these are different forms of the "name" authentication method; the difference is relevant only at the byte-level
: to identify by private method, client transmits byte [`0x0f] followed by
:: [!int<32>:[$method-number]]
:: [!byte-sequence<16>:[$auth-blob]]

! note that bytes [`0x04]~[`0x0e] are reserved for potential future identification methods. a server that encounters a method it doesn't understand must immediately send {m.n stats-fail} and close the connection.

##m magic numbers
	n: ‹[*[#1]]›

+ ID + value +
| status-ok | [`0xFF] |
| status-data | [`0xF0] |
| status-fail | [`0x00] |