util  Check-in [e15188634a]

Overview
Comment:iterate on rasuir
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e15188634a12da9f3f882af3158914c56fde051036863d9efb48f33c9db1e849
User & Date: lexi on 2023-01-29 21:16:50
Other Links: manifest | tags
Context
2023-01-29
21:47
fixes check-in: 46da53de26 user: lexi tags: trunk
21:16
iterate on rasuir check-in: e15188634a user: lexi tags: trunk
19:21
add rasuir spec, other updates check-in: 6bda93a905 user: lexi tags: trunk
Changes

Added spec/nimtas.ct version [22aa494f33].























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 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] |

Modified spec/rasuir.ct from [13ce85cdbb] to [d1e6e704c3].

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
63
64
65
66
* [*sigint<[$N]>] ==> like the above, but interpreted as a two's-complement signed 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
* [*string] ==> [!byte-sequence<8>] interpreted as a UTF-8 string
* [*text] ==> [!byte-sequence<16>] interpreted as a UTF-8 string
* [*bitmap] ==> [!int<16>:[$pxl-width]] [!byte-sequence<8>:[$map]]
* [*state] ==>
*: if on the root menu: [`0x00]
*: if on a menu with an ID between [`1]-[`127] and the opaque [$ref] value is [`0] ("null"): the menu number cast to [!int<8>] (e.g. [`0x00 4A] --> [`0x4A])
*: if on a menu between [`128]-[`383] with a null [$ref] value: [`0x80] [!int<8>:[=mode - 128]]
*: if on a menu greater than [`383] with a null [$ref]: [`0x81] [!int<16>:[$mode]]. this form is also valid if the number is lower than [`383], and can be used where logical simplicity is more important than compact signalling
*: otherwise:
*:: let [$ref-len] be the length in bytes of the [$ref] value, maximum 8 (0 is valid, in which case no [$ref] sequence is sent)
*:: let [$mode-range] be [`0] if [$mode] is between [`0] and [`255], [`1] otherwise
*:: let [$signal-byte] be [`([$ref-len] << 1) | [$mode]-[$range]]
*:: send [!int<8>:[$signal-byte]] [!int<[=8 + 8*mode-range]>:[$mode]] [!int<[$ref-len*8]>:[$ref]]
* [*link] ==> [!int<8>:[$role]] [!state:[$target]]

## outline

: client connects to server
: client transmits {m.n con-ack}

: client authenticates by one of the following
:: to authenticate anonymously, client transmits byte [`0x00].
:: to authenticate by shortname, client transmits byte [`0x01] 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 authenticate by longname, client transmits byte [`0x01] followed by a [!byte-sequence<16>]. this is identical to the above but allows to longer values. technically these are different forms of the "name" authentication method; the difference is relevant only at the byte-level
:: other authentication methods may be defined later. a server that encounters an unknown authentication method must transmit an error and close the connection, as it cannot know how to interpret any further communications from the client
: 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}
: client transmits a command
:: {m.n cmd-get} retrieves a menu. it takes the form [!state] [!action]
:: {m.n cmd-hint} transmits a hint to the server. it takes the form [!int<8>:[$hint]] [!byte-sequence<16>]
:: {m.n cmd-meta} requests metadata from the server. it takes the form [!int<16>]
:: {m.n cmd-end} closes the connection. it takes no arguments
: server issues [>rep reply]
: while command was not {m.n cmd-end}, previous two steps repeat
: peers disconnect



##rep server replies
all replies begin with a one-byte status code.

### cmd-get reply
the hint reply code may be:
* {m.n status-ok}: the request was valid but the current display should not be changed
* {m.n status-fail}: the request was not valid
* {m.n status-ignore}: the action did nothing
* {m.n status-data}: the request was valid and a form is being returned to display.

if the reply is {m.n status-data}, it is followed by the header [!byte:[$flags]] [!int<16>:[$widget-count]]
* [$flags] is a bitmask







|
|




|
|



<


>
|
<
<
<
<
<
<
<








>
>





|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
* [*sigint<[$N]>] ==> like the above, but interpreted as a two's-complement signed 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
* [*string] ==> [!byte-sequence<8>] interpreted as a UTF-8 string
* [*text] ==> [!byte-sequence<16>] interpreted as a UTF-8 string
* [*bitmap] ==> [!int<16>:[$pxl-width]] [!byte-sequence<8>:[$map]]
* [*state] ==>
*: if on the root menu: [`0x00]
*: if on a menu with an ID between [`1]~[`127] and the opaque [$ref] value is [`0] ("null"): the menu number cast to [!int<8>] (e.g. [`0x00 4A] --> [`0x4A])
*: if on a menu between [`128]~[`383] with a null [$ref] value: [`0x80] [!int<8>:[=mode - 128]]
*: if on a menu greater than [`383] with a null [$ref]: [`0x81] [!int<16>:[$mode]]. this form is also valid if the number is lower than [`383], and can be used where logical simplicity is more important than compact signalling
*: otherwise:
*:: let [$ref-len] be the length in bytes of the [$ref] value, maximum 8 (0 is valid, in which case no [$ref] sequence is sent)
*:: let [$mode-range] be [`0] if [$mode] is between [`0] and [`255], [`1] otherwise
*:: let [$signal-byte] be [`([$ref-len] << 1) | [$mode-range]]
*:: send [!int<8>:[$signal-byte]] [!int<[`8 + 8*[$mode-range]]>:[$mode]] [!int<[`[$ref-len]*8]>:[$ref]]
* [*link] ==> [!int<8>:[$role]] [!state:[$target]]

## outline

: client connects to server
: client transmits {m.n con-ack}
: server responds {m.n status-ok}
: client and server authenticate using the [>nimtas authentication protocol]. for an anonymous connection, this is as simple as the dialogue “C: [`0x00] / S: {m.n status-ok}”







: client transmits a command
:: {m.n cmd-get} retrieves a menu. it takes the form [!state] [!action]
:: {m.n cmd-hint} transmits a hint to the server. it takes the form [!int<8>:[$hint]] [!byte-sequence<16>]
:: {m.n cmd-meta} requests metadata from the server. it takes the form [!int<16>]
:: {m.n cmd-end} closes the connection. it takes no arguments
: server issues [>rep reply]
: while command was not {m.n cmd-end}, previous two steps repeat
: peers disconnect
	nimtas: file:nimtas.ct


##rep server replies
all replies begin with a one-byte status code.

### cmd-get reply
the get reply code may be:
* {m.n status-ok}: the request was valid but the current display should not be changed
* {m.n status-fail}: the request was not valid
* {m.n status-ignore}: the action did nothing
* {m.n status-data}: the request was valid and a form is being returned to display.

if the reply is {m.n status-data}, it is followed by the header [!byte:[$flags]] [!int<16>:[$widget-count]]
* [$flags] is a bitmask