This commit is contained in:
swrup 2026-02-17 14:04:34 +01:00
parent 3e75660824
commit 62dddfe81f
2 changed files with 36 additions and 115 deletions

View file

@ -3,93 +3,12 @@ open Api
open Hash open Hash
module Keys_get = struct module Keys_get = struct
let mk_future_denom (module Sm : Secmod.S) ~section_name
({
pub;
value;
stamp_start;
stamp_expire_withdraw;
stamp_expire_deposit;
stamp_expire_legal;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
age_mask;
h_pub;
master_sig= _;
revoked_sig= _;
} :
Denomination.t) =
let denom_pub =
DenominationKey.of_rsa RsaDenominationKey.{ age_mask; rsa_pub= pub }
in
let denom_secmod_sig =
let open Signatures.DenominationKeyAnnouncement in
let h_denom_pub = h_pub in
let h_section_name = Hash.Cstring.H64.hash section_name in
let anchor_time = stamp_start in
let duration_withdraw =
Timestamp.diff stamp_start stamp_expire_withdraw
in
sign_f ~f:Sm.sign_with_sm_key
{ h_denom_pub; h_section_name; anchor_time; duration_withdraw }
in
FutureDenom.
{
section_name;
value;
stamp_start;
stamp_expire_withdraw;
stamp_expire_deposit;
stamp_expire_legal;
denom_pub;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
denom_secmod_sig;
}
let mk_future_signkey (module Sm : Secmod.S)
({
pub;
stamp_start;
stamp_expire;
stamp_end;
master_sig= _;
revoked_sig= _;
} :
Signkey.t) =
let signkey_secmod_sig =
let open Signatures.SigningKeyAnnouncement in
let exchange_pub = pub in
let anchor_time = stamp_start in
let duration = Timestamp.diff stamp_start stamp_expire in
sign_f ~f:Sm.sign_with_sm_key { exchange_pub; anchor_time; duration }
in
FutureSignKey.
{ key= pub; stamp_start; stamp_expire; stamp_end; signkey_secmod_sig }
let mk_future_keys_response (module Sm : Secmod.S) = let mk_future_keys_response (module Sm : Secmod.S) =
let future_signkeys = let future_signkeys = Sm.get_future_signkeys () in
Sm.get_signkeys_data () let future_denoms = Sm.get_future_denominations () in
|> List.filter (fun k -> Option.is_none k.Signkey.master_sig)
|> List.map (fun signkey -> mk_future_signkey (module Sm) signkey)
in
let future_denoms =
Sm.get_denoms_data ()
|> List.filter (fun k -> Option.is_none k.Denomination.master_sig)
|> List.map (fun dn_data ->
let opt = Sm.find_denom_section_name dn_data.Denomination.h_pub in
match opt with
| None -> Fmt.failwith "section_name not found."
| Some section_name ->
mk_future_denom (module Sm) ~section_name dn_data)
in
let master_pub = Config.Exchange.master_public_key in let master_pub = Config.Exchange.master_public_key in
let denom_secmod_public_key = Sm.get_sm_key_pub () in let denom_secmod_public_key = Sm.sm_pubkey in
let signkey_secmod_public_key = Sm.get_sm_key_pub () in let signkey_secmod_public_key = Sm.sm_pubkey in
FutureKeysResponse. FutureKeysResponse.
{ {
future_denoms; future_denoms;
@ -144,7 +63,7 @@ module Keys_post = struct
let verify_signkey_signature (module Sm : Secmod.S) let verify_signkey_signature (module Sm : Secmod.S)
SignKeySignature.{ key; master_sig } = SignKeySignature.{ key; master_sig } =
let* signkey = let* signkey =
match Sm.find_signkey_data key with match Sm.find_signkey key with
| None -> | None ->
Fmt.error Fmt.error
"404 not found, One of the keys for which a signature was provided \ "404 not found, One of the keys for which a signature was provided \
@ -170,18 +89,18 @@ module Keys_post = struct
let do_ ~db_conn:_ (module Sm : Secmod.S) let do_ ~db_conn:_ (module Sm : Secmod.S)
MasterSignatures.{ denom_sigs; signkey_sigs } = MasterSignatures.{ denom_sigs; signkey_sigs } =
let* () = let* () =
list_iter
(fun SignKeySignature.{ key; master_sig } ->
Sm.certify_future_signkey key master_sig)
signkey_sigs signkey_sigs
|> List.map (fun SignKeySignature.{ key; master_sig } ->
(key, master_sig))
|> Sm.add_signkey_master_signatures
in in
let* () = let* () =
list_iter
(fun DenomSignature.{ h_denom_pub; master_sig } ->
Sm.certify_future_denomination h_denom_pub master_sig)
denom_sigs denom_sigs
|> List.map (fun DenomSignature.{ h_denom_pub; master_sig } ->
(h_denom_pub, master_sig))
|> Sm.add_denom_master_signatures
in in
let* () = Sm.store () in let* () = Sm.save () in
Ok () Ok ()
let jsont = MasterSignatures.jsont let jsont = MasterSignatures.jsont

View file

@ -48,7 +48,8 @@ module Make (Conn : Pg.CONN) = struct
type dn = Denomination.t type dn = Denomination.t
type future_dn = Api.FutureDenom.t type future_dn = Api.FutureDenom.t
(* TODO use lock! *) (* TODO ! use lock *)
(* not sure what to do with coin section_name, rm if possible *)
type t = { type t = {
sm_key: eddsa_priv; sm_key: eddsa_priv;
sm_pubkey: eddsa_pub; sm_pubkey: eddsa_pub;
@ -63,6 +64,12 @@ module Make (Conn : Pg.CONN) = struct
dn_section_name_ht: (denom_hash, string) Hashtbl.t; dn_section_name_ht: (denom_hash, string) Hashtbl.t;
} }
let sm_key_fname = Fpath.(Config.secrets_dir / "sm_key")
let sk_key_fname i = Fpath.(Config.secrets_dir / Fmt.str "sk_%d" i)
let dn_key_fname section_name =
Fpath.(Config.secrets_dir / Fmt.str "dn_%s" section_name)
let database_find_sk conn fname pub = let database_find_sk conn fname pub =
let* opt = Pg.find_signkey conn pub |> unwrap_err_caqti in let* opt = Pg.find_signkey conn pub |> unwrap_err_caqti in
match opt with match opt with
@ -88,11 +95,9 @@ module Make (Conn : Pg.CONN) = struct
let error_invalid_state = let error_invalid_state =
Fmt.error "secmod load error: invalid store state." Fmt.error "secmod load error: invalid store state."
in in
let* sm_key = Data_file.read_eddsa Fpath.(Config.secrets_dir / "sk_sm") in let* sm_key = Data_file.read_eddsa sm_key_fname in
let* sk_keys = let* sk_keys =
let l = let l = List.init 1 sk_key_fname in
List.init 1 (fun i -> Fpath.(Config.secrets_dir / Fmt.str "sk_%d" i))
in
let* l = let* l =
list_map list_map
(fun fname -> (fun fname ->
@ -108,8 +113,7 @@ module Make (Conn : Pg.CONN) = struct
list_map list_map
(fun coin -> (fun coin ->
let section_name = coin.section_name in let section_name = coin.section_name in
let fname = Fpath.(Config.secrets_dir / section_name) in let+ opt = Data_file.read_rsa (dn_key_fname section_name) in
let+ opt = Data_file.read_rsa fname in
Option.map (fun priv -> (section_name, priv)) opt) Option.map (fun priv -> (section_name, priv)) opt)
all_coins all_coins
in in
@ -136,6 +140,7 @@ module Make (Conn : Pg.CONN) = struct
(list_to_ht sk_l, list_to_ht priv_l) (list_to_ht sk_l, list_to_ht priv_l)
in in
(* dn *) (* dn *)
let dn_section_name_ht = Hashtbl.create 0xff in
let* l = let* l =
list_map list_map
(fun (section_name, priv) -> (fun (section_name, priv) ->
@ -145,15 +150,18 @@ module Make (Conn : Pg.CONN) = struct
|> RsaPublicKey.to_octets |> RsaPublicKey.to_octets
|> DenominationHash.hash |> DenominationHash.hash
in in
(* fill dn_section_name_ht *)
Hashtbl.replace dn_section_name_ht h_pub section_name;
let+ dn = database_find_dn conn ~section_name h_pub in let+ dn = database_find_dn conn ~section_name h_pub in
((h_pub, dn), (h_pub, priv))) ((h_pub, dn), (h_pub, priv)))
dn_keys dn_keys
in in
let dn_ht, dn_key_ht = let dn_ht, dn_key_ht =
let dn_l, priv_l = List.split l in match List.split l with l1, l2 -> (list_to_ht l1, list_to_ht l2)
(list_to_ht dn_l, list_to_ht priv_l)
in in
(* future keys are not stored (until they are signed) (* future keys are not stored anywhere until they are certified with a master_sig
so we don't have any future key to load *) so we don't have any future key to load *)
let t = let t =
{ {
@ -167,7 +175,7 @@ module Make (Conn : Pg.CONN) = struct
future_dn_ht= Hashtbl.create 0xff; future_dn_ht= Hashtbl.create 0xff;
future_sk_key_ht= Hashtbl.create 0xff; future_sk_key_ht= Hashtbl.create 0xff;
future_dn_key_ht= Hashtbl.create 0xff; future_dn_key_ht= Hashtbl.create 0xff;
dn_section_name_ht= Hashtbl.create 0xff; dn_section_name_ht;
} }
in in
Ok (Some t) Ok (Some t)
@ -453,16 +461,11 @@ module Make (Conn : Pg.CONN) = struct
Ok () Ok ()
let save () = let save () =
let* () = let* () = Data_file.write_eddsa sm_key_fname t.sm_key in
let fname = Fpath.(Config.secrets_dir / "sk_sm") in
Data_file.write_eddsa fname t.sm_key
in
let* () = let* () =
Hashtbl.to_seq_values t.sk_key_ht Hashtbl.to_seq_values t.sk_key_ht
|> List.of_seq |> List.of_seq
|> List.mapi (fun i priv -> |> List.mapi (fun i priv -> Data_file.write_eddsa (sk_key_fname i) priv)
let fname = Fpath.(Config.secrets_dir / Fmt.str "sk_%d" i) in
Data_file.write_eddsa fname priv)
|> list_iter Fun.id |> list_iter Fun.id
in in
let* () = let* () =
@ -474,8 +477,7 @@ module Make (Conn : Pg.CONN) = struct
| None -> Error "invalid state, section_name not found" | None -> Error "invalid state, section_name not found"
| Some s -> Ok s | Some s -> Ok s
in in
let fname = Fpath.(Config.secrets_dir / section_name) in Data_file.write_rsa (dn_key_fname section_name) priv)
Data_file.write_rsa fname priv)
in in
Logs.info (fun m -> m "saved secmod private keys data"); Logs.info (fun m -> m "saved secmod private keys data");
Ok () Ok ()