From 0d50aaa24f16454161e92f37c9dc16da9a85dd44 Mon Sep 17 00:00:00 2001 From: swrup Date: Sat, 24 Jan 2026 06:12:52 +0100 Subject: [PATCH] --- data/secmod/kudo_1 | Bin 0 -> 1176 bytes data/secmod/kudo_2 | Bin 0 -> 1176 bytes data/secmod/sk_0 | 1 + data/secmod/sm_key | 1 + src/data_file.ml | 15 +++++---- src/secmod.ml | 74 ++++++++++++++++++++++++++------------------- 6 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 data/secmod/kudo_1 create mode 100644 data/secmod/kudo_2 create mode 100644 data/secmod/sk_0 create mode 100644 data/secmod/sm_key diff --git a/data/secmod/kudo_1 b/data/secmod/kudo_1 new file mode 100644 index 0000000000000000000000000000000000000000..86bebde0562184260cbf51e196a0621e26ae2aab GIT binary patch literal 1176 zcmZSJU}RuqU}%6t1_lNOMh3>{|KT^DZ0wUWxxeezTF=++J5rDB^q3sC<=Kwu%F8{q z4(ywE_sKD?iD$f|CGM}kI#Kz1Df3qzRTDMoKyjVS$nNtRe-?E=61Md<(vr{=`6**G z!%K}}?gsOHF(Uq)zs~=BsaSV*^L@8HyJ{3xZgSnSHR1V%+4|e0!qx@ zM?dzwVohj1X(AN4R^DB1zFNA+w!bsKb|&7qui+3UaxrYxsrr~F&5O+rb#GB@xi>>G z^3hZNP0C;Edj8L06qw_C>BX1pk!OEtu>JfW7`13Q?*Fn#)+bHQ=9a+dZ<{>P?WS|Rx8ah}_0vC1+<#RIFIpX8ey zUmJVw+|{4U=EeV-d2DgOp>Cg|`#&^`EepgR@NEC6lkmTFjoj6~&r4=4nVy?@K>y6^ z--+|BreDc-lkB~q5+5MbYCk7lg|j?W?&GC8{s+@uC`9k8nD@=Y{XnL}Jz?n!wH^7A z9FrG$f7S?<>DJF!Zx%SkHf#TX&LGa6X%A2LyGqnQ>kgbTxo&QP*PH6|S!PSLY}HS; zZI~&$Ja&o2Mj@FMugWE>7E0vg7{$2F5i&9Imd`j|wOmhr$#~bN z7JPSIo$~zmD_B&osK00ra5=NJ?f5=T{_4;@8wz5$RJPsq>VI)@-u4yxKR->(`~0MJ zb@WV=hP{d_Y=iTSl3xZX>)-xVqj7n&#zw(C7Z@Zs8S_5Q@~F*zls7r*+l`fSs)0I& zRazO>n=-jK-@h6!oYbcBZj$7w-FwtuhkWb2$g*gEq);i>I-ktq;I$bJvDF5-CwcfR pKE8E%VOhIQdv?n1p3?gTN8Ntzi~g)WaVpneF8RyWr+&rV0|56_IrRVl literal 0 HcmV?d00001 diff --git a/data/secmod/kudo_2 b/data/secmod/kudo_2 new file mode 100644 index 0000000000000000000000000000000000000000..841f82dada096ced00984b5a17c3d5036621326d GIT binary patch literal 1176 zcmZSJU}RuqU}%6t1_lNOMg~Ut_a-hmEZbOST4-0NpH7%0J6|ueU`Fxu$zeRJ`?o&Z zdAFB8r)Hb2pmo->_0{qV+itOGtj_a0|ME+Jz@LM&vu`rYe497xW!S#!^KVR#wAk|D zF=5jTc^0!}18DXWH$|h{x z?I0@A%H!v4B%v`pzu->EZMtoo z)?b!8kJ+Hl%=3}Pnbc0L6_=XiEMy!*bLJSmns4gX67}T8Mr(~7;&r_NQ|ILfu6U~| z>o4?o+I&50{{!beeh9H}a({i--}klQ+1;Kq*`*Hli~Y|T)=6rY2Bn=n5HfM?L(Y@O zqbBA_hRy0VI=+p2v*4r$+>&P^cQ5TxE7iX%-}UCGoXEz=yIoVegR8%NZtN>(cXHlr z`^w^Gi zc}?0K_j-Le@Xe?#^RuVyS7yK6$HTqt0#Bb>mh`3jPY8SX1CLWVHz%Fdt0=c@IbSC$)Tw3>OBEQ5rU7WJTtnyccqWLr^-f)SGQSDKbZGz_xhBFPekiWPB48+ zb#N8dP!$yauC_y#_pV{)w{EAExdmDuQ!l??I^nlsbY?^By%*0{=t^&M{QFZ-*7(dZ zv%Bk+X1}?9#o)~Rc^}?hnNd}+c}n2!pvOTkToy##^?p$|Z??!E2Y%M@ttM}`Y0jP) zcE`bTuj%TFKX+Q&b-X^lOcL0*puB#f*;O-@iQ?bhTCG{~>&9z4jvkf$8}IOH258r~ z)Cd_I-G2I@hG104-+3)}ldFuTs(2r7l-~F5N7B_*p{`=9mp5MKTj$QX`p?vJuL4r9 zzxfu?x_h?n*A!bu2|F=4mOI{?->QWzGP_cCz4OzPM6LaDyEzy-t8#6YT+X#w@HS{) rQN)j5J-c1l{|BwSBRZuzH{->L-Z>G!t~wsR?c~H0xFGYp6JH|$as^9a literal 0 HcmV?d00001 diff --git a/data/secmod/sk_0 b/data/secmod/sk_0 new file mode 100644 index 00000000..1d16871f --- /dev/null +++ b/data/secmod/sk_0 @@ -0,0 +1 @@ +ºÀ`øˆ@¥ò…åCnþpqÿ;%e+J" …xEK¶p \ No newline at end of file diff --git a/data/secmod/sm_key b/data/secmod/sm_key new file mode 100644 index 00000000..16d6f2e6 --- /dev/null +++ b/data/secmod/sm_key @@ -0,0 +1 @@ +ÿÛUMþƒUfz652”q¿Õ¥E¢kìØÙ†ª¨’ \ No newline at end of file diff --git a/src/data_file.ml b/src/data_file.ml index 44b98908..9fa34674 100644 --- a/src/data_file.ml +++ b/src/data_file.ml @@ -3,15 +3,18 @@ open Syntax open Crypto let read fname = - let* b = File.exists fname in + let* b = File.exists fname |> Syntax.unwrap_err_msg in match b with | false -> Ok None | true -> - let+ content = File.read fname in + let+ content = File.read fname |> Syntax.unwrap_err_msg in Some content -let write_eddsa fname priv = EddsaPrivateKey.to_octets priv |> File.write fname -let write_rsa fname priv = RsaPrivateKey.to_octets priv |> File.write fname +let write_eddsa fname priv = + EddsaPrivateKey.to_octets priv |> File.write fname |> Syntax.unwrap_err_msg + +let write_rsa fname priv = + RsaPrivateKey.to_octets priv |> File.write fname |> Syntax.unwrap_err_msg let read_eddsa fname = let* opt = read fname in @@ -19,7 +22,7 @@ let read_eddsa fname = | None -> Ok None | Some data -> ( EddsaPrivateKey.of_octets data |> function - | Error err -> Error (`Msg err) + | Error e -> Error e | Ok v -> Ok (Some v)) let read_rsa fname = @@ -28,5 +31,5 @@ let read_rsa fname = | None -> Ok None | Some data -> ( RsaPrivateKey.of_octets data |> function - | Error e -> Error (`Msg e) + | Error e -> Error e | Ok v -> Ok (Some v)) diff --git a/src/secmod.ml b/src/secmod.ml index d56a1c98..875b1592 100644 --- a/src/secmod.ml +++ b/src/secmod.ml @@ -70,14 +70,14 @@ 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 - let* opt = Pg.find_signkey conn pub in + let* opt = Pg.find_signkey conn pub |> unwrap_err_caqti in match opt with | None -> - Fmt.error_msg + Fmt.error "load_signkey error: no associated data found in database for \ signkey `%s`." (Fpath.to_string fname) @@ -86,10 +86,10 @@ module Make (Conn : Pg.CONN) = struct let db_lookup_denom_data conn ~section_name priv = let pub = RsaPrivateKey.pub_of_priv priv in let h_pub = Bin_type.DenominationHash.hash (RsaPublicKey.to_octets pub) in - let* opt = Pg.find_denom conn h_pub in + let* opt = Pg.find_denom conn h_pub |> unwrap_err_caqti in match opt with | None -> - Fmt.error_msg + Fmt.error "load_denom error no associated metadata found in database for \ denomination `%s`." section_name @@ -106,11 +106,11 @@ module Make (Conn : Pg.CONN) = struct let load conn = let error_invalid_state = - Fmt.error_msg "secmod load error: invalid store state." + Fmt.error "secmod load error: invalid store state." 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 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