macula_key_bindings (macula v11.4.0)
View SourceBindings 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
-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
-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.
-spec status_statement(macula_node_keys:node_key(), envelope(), non_neg_integer(), non_neg_integer()) -> envelope().
A status statement that keeps a binding in force from IssuedAt to ExpiresAt, at most one hour.
-spec tls_binding(macula_node_keys:node_key(), binary(), non_neg_integer(), non_neg_integer()) -> envelope().
Bind the TLS key of the leaf certificate a listener presents, by the SHA-384 of that leaf's DER.
-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.
-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.
-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.