diff --git a/data/secmod/kudo_1 b/data/secmod/kudo_1 new file mode 100644 index 00000000..93bc8f85 Binary files /dev/null and b/data/secmod/kudo_1 differ diff --git a/data/secmod/kudo_2 b/data/secmod/kudo_2 new file mode 100644 index 00000000..103a504b Binary files /dev/null and b/data/secmod/kudo_2 differ diff --git a/data/secmod/sk_0 b/data/secmod/sk_0 new file mode 100644 index 00000000..127d374e --- /dev/null +++ b/data/secmod/sk_0 @@ -0,0 +1 @@ +pxR Br캾> \ No newline at end of file diff --git a/data/secmod/sm_key b/data/secmod/sm_key new file mode 100644 index 00000000..f717f36c --- /dev/null +++ b/data/secmod/sm_key @@ -0,0 +1 @@ +OqпoA}]Y.? \ No newline at end of file diff --git a/src/secmod.ml b/src/secmod.ml index d56a1c98..4e8373a6 100644 --- a/src/secmod.ml +++ b/src/secmod.ml @@ -70,7 +70,7 @@ module Make (Conn : Pg.CONN) = struct dn_section_name_ht: (denomination_hash, string) Hashtbl.t; } - let dir = Fpath.(v "data" / "secmod ") + let dir = Fpath.(v "data" / "secmod") let db_lookup_signkey_data conn fname priv = let pub = EddsaPrivateKey.pub_of_priv priv in @@ -110,7 +110,7 @@ module Make (Conn : Pg.CONN) = struct in let* sm_key_priv = Data_file.read_eddsa Fpath.(dir / "sm_key") in let* signkeys = - let l = List.init 1 (fun i -> Fpath.(dir / string_of_int i)) in + let l = List.init 1 (fun i -> Fpath.(dir / Fmt.str "sk_%d" i)) in let* l = list_map (fun fname -> load_signkey conn fname) l in match opt_list l with Error () -> error_invalid_state | Ok opt -> Ok opt in @@ -249,18 +249,49 @@ module Make (Conn : Pg.CONN) = struct in { lock; sm_key_priv; sm_key_pub; sk_ht; dn_ht; dn_section_name_ht } + let store t = + Miou.Mutex.protect t.lock @@ fun () -> + let* () = Data_file.write_eddsa Fpath.(dir / "sm_key") t.sm_key_priv in + let* () = + Hashtbl.to_seq_values t.sk_ht + |> List.of_seq + |> List.mapi (fun i (key : signkey) -> + let fname = Fpath.(dir / Fmt.str "sk_%d" i) in + (fname, key.priv)) + |> list_iter (fun (fname, key) -> Data_file.write_eddsa fname key) + in + let* () = + Hashtbl.to_seq_values t.dn_ht + |> List.of_seq + |> List.map (fun (key : denom) -> + let section_name = + match Hashtbl.find_opt t.dn_section_name_ht key.dn_data.h_pub with + | None -> + Fmt.failwith + "secmod failure: invalid state, section_name not found" + | Some s -> s + in + let fname = Fpath.(dir / section_name) in + (fname, key.priv)) + |> list_iter (fun (fname, key) -> Data_file.write_rsa fname key) + in + Ok () + let t = match load (module Conn) with | Ok None -> let t = make_new () in + let () = + match store t with + | Error (`Msg e) -> Fmt.failwith "secmod storage failure: %s." e + | Ok () -> () + in Logs.info (fun m -> m "secmod initialized with fresh keys"); t - | Ok (Some v) -> + | Ok (Some t) -> Logs.info (fun m -> m "secmod initialized from storage"); - v - | Error _ -> - (* TODO error: pretty print *) - Fmt.failwith "secmod init failure." + t + | Error _ -> Fmt.failwith "secmod init failure." (* 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 @@ -369,23 +400,4 @@ module Make (Conn : Pg.CONN) = struct let denom = { denom with dn_data } in Hashtbl.replace t.dn_ht h_denom_pub denom; Ok () - - (* TODO *) - let _store t = - let* () = Data_file.write_eddsa Fpath.(dir / "sm_key") t.sm_key_priv in - let* () = - get_signkeys () - |> List.mapi (fun i (key : signkey) -> - let fname = Fpath.(dir / string_of_int i) in - (fname, key.priv)) - |> list_iter (fun (fname, key) -> Data_file.write_eddsa fname key) - in - let* () = - get_denoms () - |> List.mapi (fun i (key : denom) -> - let fname = Fpath.(dir / string_of_int i) in - (fname, key.priv)) - |> list_iter (fun (fname, key) -> Data_file.write_rsa fname key) - in - Ok () end