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; fee_refund: Amount.t;
age_mask: int; age_mask: int;
h_pub: denomination_hash; h_pub: denomination_hash;
master_sig: Signatures.DenominationKeyValidity.t option; master_sig: Signatures.DenominationKeyValidity.t;
revoked_sig: Signatures.MasterDenominationKeyRevocation.t option; revoked_sig: Signatures.MasterDenominationKeyRevocation.t option;
} }

View file

@ -171,8 +171,7 @@ module Make (Conn : Pg.CONN) = struct
Ok (Some t) Ok (Some t)
| _, _, _ -> error_invalid_state | _, _, _ -> error_invalid_state
(* TODO *) let sign_with_sm_key t s = EddsaSignature.sign ~key:t.sm_key s
let sign_with_sm_key _ = assert false
let make_future_sk t = let make_future_sk t =
let start = Time.Absolute.of_ptime (Ptime_clock.now ()) in 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 exchange_pub = pub in
let anchor_time = stamp_start in let anchor_time = stamp_start in
let duration = Timestamp.diff stamp_start stamp_expire 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 in
let future_sk = let future_sk =
Api.FutureSignKey. Api.FutureSignKey.
@ -243,7 +242,7 @@ module Make (Conn : Pg.CONN) = struct
let duration_withdraw = let duration_withdraw =
Timestamp.diff stamp_start stamp_expire_withdraw Timestamp.diff stamp_start stamp_expire_withdraw
in 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 } { h_denom_pub; h_section_name; anchor_time; duration_withdraw }
in in
let future_dn = let future_dn =
@ -268,26 +267,24 @@ module Make (Conn : Pg.CONN) = struct
() ()
let make_new () = let make_new () =
let lock = Miou.Mutex.create () in let sm_key, sm_pubkey = Mirage_crypto_ec.Ed25519.generate () in
let sm_key_priv, sm_key_pub = Mirage_crypto_ec.Ed25519.generate () in let t =
let sk_ht = {
[ make_new_signkey () ] sm_key;
|> List.map (fun v -> (v.sk_data.pub, v)) sm_pubkey;
|> List.to_seq sk_ht= Hashtbl.create 0xff;
|> Hashtbl.of_seq 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 in
let dn_section_name_ht = Hashtbl.create 0xff in make_future_sk t;
let dn_ht = List.iter (make_future_dn t) Config.Coin.all_coins;
Config.Coin.all_coins t
|> 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 }
let t = let t =
match load (module Conn) with match load (module Conn) with
@ -300,59 +297,75 @@ module Make (Conn : Pg.CONN) = struct
t t
| Error e -> Fmt.failwith "secmod init failure: %s." e | 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 = sign_with_sm_key t s
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_pubkey s ~msg
let verify_with_sm_key s ~msg = EddsaSignature.verify ~key:t.sm_key_pub 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 = let sign_with_signkey ~pub s =
Miou.Mutex.protect t.lock @@ fun () -> match Hashtbl.find_opt t.sk_key_ht pub with
match Hashtbl.find_opt t.sk_ht pub with | None -> Fmt.failwith "secmod failure: signkey not found."
| None -> Fmt.failwith "secmod failure: public key not found." | Some priv -> EddsaSignature.sign ~key:priv s
| Some signkey ->
let v = EddsaSignature.sign ~key:signkey.priv s in let verify_with_master_key =
v EddsaSignature.verify ~key:Config.master_public_key
let verify_with_signkey ~pub s ~msg = 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 match Hashtbl.find_opt t.sk_ht pub with
| None -> Error "secmod failure: public key not found." | None -> Fmt.failwith "secmod failure: signkey not found."
| Some signkey -> EddsaSignature.verify ~key:signkey.sk_data.pub s ~msg | 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 () = let get_future_signkeys () =
Miou.Mutex.protect t.lock @@ fun () -> t.future_sk_ht |> Hashtbl.to_seq_values |> List.of_seq
Hashtbl.to_seq_values t.sk_ht |> List.of_seq
let get_denoms () = let get_future_denominations () =
Miou.Mutex.protect t.lock @@ fun () -> t.future_dn_ht |> Hashtbl.to_seq_values |> List.of_seq
Hashtbl.to_seq_values t.dn_ht |> List.of_seq
let find_signkey pub = let find_signkey pub = Hashtbl.find_opt t.sk_ht pub
Miou.Mutex.protect t.lock @@ fun () -> Hashtbl.find_opt t.sk_ht pub let find_denomination pub = Hashtbl.find_opt t.dn_ht pub
let find_denom h_denom = let certify_future_signkey pub master_sig =
Miou.Mutex.protect t.lock @@ fun () -> Hashtbl.find_opt t.dn_ht h_denom 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* () = Pg.insert_signkey (module Conn) sk |> unwrap_err_caqti in
let get_denoms_data () = get_denoms () |> List.map (fun v -> v.dn_data) Ok ())
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 add_signkey_master_signatures l = let add_signkey_master_signatures l =
Miou.Mutex.protect t.lock @@ fun () -> Miou.Mutex.protect t.lock @@ fun () ->

View file

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