macula_key_bindings (macula v11.4.0)

View Source

Bindings of a node's TLS and CONNECT keys to its identity key, and the status statements that keep a binding in force, as plans/DESIGN_PQ_HANDSHAKE_FRAMES.md lays them out (decisions D16 and D22).

A binding or a statement travels as #{tbs => Bytes, signature => Signature}. The identity key signs Label || 0x00 || tbs. A verifier checks that signature over the tbs bytes it received, and only then decodes them with macula_record_cbor:decode_strict/1: a duplicate key, bytes after the map, an unknown key, or a field of the wrong type or length is refused as malformed_frame. Validity is checked with 5 minutes of clock tolerance.

A binding for one use never verifies as the other use, because its signature covers the other use's label.

Summary

Functions

Bind a CONNECT key, by the SHA-384 of the key as carried.

A status statement that keeps a binding in force from IssuedAt to ExpiresAt, at most one hour.

Bind the TLS key of the leaf certificate a listener presents, by the SHA-384 of that leaf's DER.

Verify a CONNECT-key binding against the carried identity key and the carried CONNECT key.

Verify a status statement for the binding it came with, against the carried identity key, and return when the statement expires.

Verify a TLS-key binding against the carried identity key and the leaf this connection presented.

Types

envelope/0

-type envelope() :: #{tbs := binary(), signature := binary()}.

refusal/0

-type refusal() ::
          malformed_frame | binding_signature_invalid | binding_wrong_use | binding_key_mismatch |
          binding_expired | binding_not_yet_valid | node_id_mismatch | status_signature_invalid |
          status_binding_mismatch | status_expired | status_future_dated.

Functions

connect_binding(IdentityKey, ConnectKey, NotBefore, NotAfter)

-spec connect_binding(macula_node_keys:node_key(), binary(), non_neg_integer(), non_neg_integer()) ->
                         envelope().

Bind a CONNECT key, by the SHA-384 of the key as carried.

status_statement(IdentityKey, _, IssuedAt, ExpiresAt)

A status statement that keeps a binding in force from IssuedAt to ExpiresAt, at most one hour.

tls_binding(IdentityKey, LeafDer, NotBefore, NotAfter)

Bind the TLS key of the leaf certificate a listener presents, by the SHA-384 of that leaf's DER.

verify_connect_binding(Envelope, IdentityPublic, Profile, ConnectKey, NowMs)

-spec verify_connect_binding(term(), binary(), macula_crypto_profile:profile(), binary(), integer()) ->
                                {ok,
                                 #{use := tls | connect,
                                   node_id := <<_:256>>,
                                   not_after := non_neg_integer()}} |
                                {error, refusal()}.

Verify a CONNECT-key binding against the carried identity key and the carried CONNECT key.

verify_status(Envelope, Binding, IdentityPublic, Profile, NowMs)

-spec verify_status(term(), envelope(), binary(), macula_crypto_profile:profile(), integer()) ->
                       {ok, #{expires_at := non_neg_integer()}} | {error, refusal()}.

Verify a status statement for the binding it came with, against the carried identity key, and return when the statement expires.

verify_tls_binding(Envelope, IdentityPublic, Profile, LeafDer, NowMs)

-spec verify_tls_binding(term(), binary(), macula_crypto_profile:profile(), binary(), integer()) ->
                            {ok,
                             #{use := tls | connect,
                               node_id := <<_:256>>,
                               not_after := non_neg_integer()}} |
                            {error, refusal()}.

Verify a TLS-key binding against the carried identity key and the leaf this connection presented.