This commit is contained in:
swrup 2026-02-17 11:11:46 +01:00
parent a937595d6f
commit 8580a107ab
3 changed files with 80 additions and 67 deletions

View file

@ -13,6 +13,6 @@ type t = {
fee_refund: Amount.t;
age_mask: int;
h_pub: denomination_hash;
master_sig: Signatures.DenominationKeyValidity.t option;
master_sig: Signatures.DenominationKeyValidity.t;
revoked_sig: Signatures.MasterDenominationKeyRevocation.t option;
}

View file

@ -171,8 +171,7 @@ module Make (Conn : Pg.CONN) = struct
Ok (Some t)
| _, _, _ -> error_invalid_state
(* TODO *)
let sign_with_sm_key _ = assert false
let sign_with_sm_key t s = EddsaSignature.sign ~key:t.sm_key s
let make_future_sk t =
let start = Time.Absolute.of_ptime (Ptime_clock.now ()) in
@ -188,7 +187,7 @@ module Make (Conn : Pg.CONN) = struct
let exchange_pub = pub in
let anchor_time = stamp_start in
let duration = Timestamp.diff stamp_start stamp_expire in
sign_f ~f:sign_with_sm_key { exchange_pub; anchor_time; duration }
sign_f ~f:(sign_with_sm_key t) { exchange_pub; anchor_time; duration }
in
let future_sk =
Api.FutureSignKey.
@ -243,7 +242,7 @@ module Make (Conn : Pg.CONN) = struct
let duration_withdraw =
Timestamp.diff stamp_start stamp_expire_withdraw
in
sign_f ~f:sign_with_sm_key
sign_f ~f:(sign_with_sm_key t)
{ h_denom_pub; h_section_name; anchor_time; duration_withdraw }
in
let future_dn =
@ -268,26 +267,24 @@ module Make (Conn : Pg.CONN) = struct
()
let make_new () =
let lock = Miou.Mutex.create () in
let sm_key_priv, sm_key_pub = Mirage_crypto_ec.Ed25519.generate () in
let sk_ht =
[ make_new_signkey () ]
|> List.map (fun v -> (v.sk_data.pub, v))
|> List.to_seq
|> Hashtbl.of_seq
let sm_key, sm_pubkey = Mirage_crypto_ec.Ed25519.generate () in
let t =
{
sm_key;
sm_pubkey;
sk_ht= Hashtbl.create 0xff;
dn_ht= Hashtbl.create 0xff;
sk_key_ht= Hashtbl.create 0xff;
dn_key_ht= Hashtbl.create 0xff;
future_sk_ht= Hashtbl.create 0xff;
future_dn_ht= Hashtbl.create 0xff;
future_sk_key_ht= Hashtbl.create 0xff;
future_dn_key_ht= Hashtbl.create 0xff;
}
in
let dn_section_name_ht = Hashtbl.create 0xff in
let dn_ht =
Config.Coin.all_coins
|> List.map (fun coin ->
let denom = make_new_denom coin in
Hashtbl.replace dn_section_name_ht denom.dn_data.h_pub
coin.section_name;
(denom.dn_data.h_pub, denom))
|> List.to_seq
|> Hashtbl.of_seq
in
{ lock; sm_key_priv; sm_key_pub; sk_ht; dn_ht; dn_section_name_ht }
make_future_sk t;
List.iter (make_future_dn t) Config.Coin.all_coins;
t
let t =
match load (module Conn) with
@ -300,59 +297,75 @@ module Make (Conn : Pg.CONN) = struct
t
| Error e -> Fmt.failwith "secmod init failure: %s." e
(* note: don't expose a signing function if we want a real "security module" one day *)
let sign_with_sm_key s = EddsaSignature.sign ~key:t.sm_key_priv s
let verify_with_sm_key s ~msg = EddsaSignature.verify ~key:t.sm_key_pub s ~msg
let sign_with_sm_key s = sign_with_sm_key t s
let verify_with_sm_key s ~msg = EddsaSignature.verify ~key:t.sm_pubkey s ~msg
let verify_with_master_key s ~msg =
EddsaSignature.verify ~key:Config.master_public_key s ~msg
(* TODO
- do something to force `pub` to be one of the valid signkey
how to handle revocation?
raise exn for now *)
let sign_with_signkey ~pub s =
Miou.Mutex.protect t.lock @@ fun () ->
match Hashtbl.find_opt t.sk_ht pub with
| None -> Fmt.failwith "secmod failure: public key not found."
| Some signkey ->
let v = EddsaSignature.sign ~key:signkey.priv s in
v
match Hashtbl.find_opt t.sk_key_ht pub with
| None -> Fmt.failwith "secmod failure: signkey not found."
| Some priv -> EddsaSignature.sign ~key:priv s
let verify_with_master_key =
EddsaSignature.verify ~key:Config.master_public_key
let verify_with_signkey ~pub s ~msg =
Miou.Mutex.protect t.lock @@ fun () ->
(* check that the key we are verifying with is one of our own *)
match Hashtbl.find_opt t.sk_ht pub with
| None -> Error "secmod failure: public key not found."
| Some signkey -> EddsaSignature.verify ~key:signkey.sk_data.pub s ~msg
| None -> Fmt.failwith "secmod failure: signkey not found."
| Some _priv -> EddsaSignature.verify ~key:pub s ~msg
let get_sm_key_pub () = t.sm_key_pub
let sm_pubkey = t.sm_pubkey
let get_signkeys () = t.sk_ht |> Hashtbl.to_seq_values |> List.of_seq
let get_denominations () = t.dn_ht |> Hashtbl.to_seq_values |> List.of_seq
let get_signkeys () =
Miou.Mutex.protect t.lock @@ fun () ->
Hashtbl.to_seq_values t.sk_ht |> List.of_seq
let get_future_signkeys () =
t.future_sk_ht |> Hashtbl.to_seq_values |> List.of_seq
let get_denoms () =
Miou.Mutex.protect t.lock @@ fun () ->
Hashtbl.to_seq_values t.dn_ht |> List.of_seq
let get_future_denominations () =
t.future_dn_ht |> Hashtbl.to_seq_values |> List.of_seq
let find_signkey pub =
Miou.Mutex.protect t.lock @@ fun () -> Hashtbl.find_opt t.sk_ht pub
let find_signkey pub = Hashtbl.find_opt t.sk_ht pub
let find_denomination pub = Hashtbl.find_opt t.dn_ht pub
let find_denom h_denom =
Miou.Mutex.protect t.lock @@ fun () -> Hashtbl.find_opt t.dn_ht h_denom
let certify_future_signkey pub master_sig =
match
( Hashtbl.find_opt t.future_sk_ht pub,
Hashtbl.find_opt t.future_sk_key_ht pub )
with
| None, _ | _, None -> Error "secmod failure: future signkey not found."
| Some future_sk, Some priv -> (
match Hashtbl.find_opt t.sk_ht pub with
| Some _sk ->
Error "secmod failure: this signkey already has a master signature"
| None ->
let Api.FutureSignKey.
{
key;
stamp_start;
stamp_expire;
stamp_end;
signkey_secmod_sig= _;
} =
future_sk
in
let sk =
Signkey.
{
pub= key;
stamp_start;
stamp_expire;
stamp_end;
master_sig;
revoked_sig= None;
}
in
Hashtbl.replace t.sk_ht pub sk;
Hashtbl.replace t.sk_key_ht pub priv;
Hashtbl.remove t.future_sk_ht pub;
Hashtbl.remove t.future_sk_key_ht pub;
let get_signkeys_data () = get_signkeys () |> List.map (fun v -> v.sk_data)
let get_denoms_data () = get_denoms () |> List.map (fun v -> v.dn_data)
let find_signkey_data pub =
find_signkey pub |> Option.map (fun v -> v.sk_data)
let find_denomination h_denom =
find_denom h_denom |> Option.map (fun v -> v.dn_data)
let find_denom_section_name h_denom =
Miou.Mutex.protect t.lock @@ fun () ->
Hashtbl.find_opt t.dn_section_name_ht h_denom
let* () = Pg.insert_signkey (module Conn) sk |> unwrap_err_caqti in
Ok ())
let add_signkey_master_signatures l =
Miou.Mutex.protect t.lock @@ fun () ->

View file

@ -5,6 +5,6 @@ type t = {
stamp_start: Timestamp.t;
stamp_expire: Timestamp.t;
stamp_end: Timestamp.t;
master_sig: Signatures.ExchangeSigningKeyValidity.t option;
master_sig: Signatures.ExchangeSigningKeyValidity.t;
revoked_sig: Signatures.MasterSigningKeyRevocation.t option;
}