This commit is contained in:
swrup 2025-11-28 07:47:51 +01:00
parent 481a0644cb
commit 473557c2df
9 changed files with 127 additions and 26 deletions

View file

View file

View file

@ -0,0 +1 @@
<EFBFBD><EFBFBD>џ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>$<24><01><><EFBFBD>8<16><><EFBFBD> <0B><><EFBFBD><EFBFBD>BֿJ<D6BF><4A>T{

View file

@ -0,0 +1 @@
.癩+Жームヤゲフヘq<16>゙N識エ[゚ヤメヘYL

View file

@ -1,22 +1,127 @@
(* TODO KV store *)
type env = { type env = {
caqti_switch: Caqti_miou.Switch.t; caqti_switch: Caqti_miou.Switch.t;
db_uri: Uri.t; db_uri: Uri.t;
} }
let db_connection : (env, Caqti_miou.connection) Vif.Device.device =
let finally (module Conn : Caqti_miou.CONNECTION) = Conn.disconnect () in
Vif.Device.v ~name:"db_connection" ~finally []
@@ fun { caqti_switch; db_uri } ->
match Caqti_miou_unix.connect ~sw:caqti_switch db_uri with
| Error err ->
Fmt.failwith "Database connection failure: %a." Caqti_error.pp err
| Ok conn -> (
match Pg.preflight conn with
| Error err ->
Fmt.failwith "Database preflight failure: %a." Caqti_error.pp err
| Ok () -> conn)
(* TODO KV store *)
module Secmod_signkey = struct module Secmod_signkey = struct
type t = { type t = {
sm_key: Signkey.t; sm_key: Signkey.t;
keys: Signkey.t list; keys: Signkey.t list;
} }
let v = let dir = Fpath.(v "data" / "secmod_signkey")
let finally _key = () in
Vif.Device.v ~name:"secmod_signkey" ~finally [] @@ fun (_env : env) -> let read_eddsa_key_files fname =
let open Syntax in
let open Bos.OS in
let open Crypto in
let pub = Fpath.(dir / fname) |> Fpath.set_ext "pub" in
let priv = Fpath.(dir / fname) in
let* b0 = File.exists pub in
let* b1 = File.exists priv in
match (b0, b1) with
| true, true ->
let* pub = File.read pub in
let* priv = File.read priv in
let pub = EddsaPublicKey.of_octets pub in
let priv = EddsaPrivateKey.of_octets priv in
Ok (Some (pub, priv))
| false, false -> Ok None
| _, _ -> Error (`Msg "secmod_signkey: invalid local file state.")
let write_eddsa_key_files fname signkey =
let open Syntax in
let open Bos.OS in
let open Crypto in
let pub_file = Fpath.(dir / fname) |> Fpath.set_ext "pub" in
let priv_file = Fpath.(dir / fname) in
let pub = EddsaPublicKey.to_octets signkey.Signkey.pub in
let priv = EddsaPrivateKey.to_octets signkey.priv in
let* () = File.write pub_file pub in
let* () = File.write priv_file priv in
Ok ()
let write_local_keys t =
let open Syntax in
let* () = write_eddsa_key_files "sm_key" t.sm_key in
let keys = List.mapi (fun i key -> (string_of_int i, key)) t.keys in
let* () = list_iter (fun (s, key) -> write_eddsa_key_files s key) keys in
Ok ()
let load_local_keys conn =
let open Syntax in
let load s =
let* opt = read_eddsa_key_files s in
match opt with
| None -> Ok None
| Some (pub, priv) -> (
let* opt = Pg.lookup_signing_key conn pub in
match opt with
| None ->
Fmt.error_msg
"secmod_signkey error: no associtaed metadata found in \
database for key `%s`."
s
| Some (stamp_start, stamp_expire, stamp_end) ->
let master_sig = None in
Ok
(Some
Signkey.
{
pub;
priv;
stamp_start;
stamp_expire;
stamp_end;
master_sig;
}))
in
let* sm_key = load "sm_key" in
let* key_0 = load "0" in
match (sm_key, key_0) with
| None, None -> Ok None
| Some sm_key, Some key_0 ->
let keys = [ key_0 ] in
Ok (Some { sm_key; keys })
| _, _ -> Error (`Msg "secmod_signkey: invalid local file state.")
let generate_fresh_keys () =
let sm_key = Signkey.generate () in let sm_key = Signkey.generate () in
let keys = [ Signkey.generate () ] in let keys = [ Signkey.generate () ] in
{ sm_key; keys } { sm_key; keys }
let v =
let finally _key = () in
Vif.Device.v ~name:"secmod_signkey" ~finally
[ Vif.Device.value db_connection ]
@@ fun conn (_env : env) ->
match load_local_keys conn with
| Ok None ->
Fmt.pr "secmod_signkey: generate_fresh_keys@.";
let t = generate_fresh_keys () in
write_local_keys t |> Result.get_ok;
t
| Ok (Some v) ->
Fmt.pr "secmod_signkey: loaded local keys@.";
v
| Error _ ->
(* TODO pp error *)
Fmt.failwith "secmod_signkey init failure."
end end
module Secmod_denom = struct module Secmod_denom = struct
@ -35,16 +140,3 @@ end
let secmod_signkey = Secmod_signkey.v let secmod_signkey = Secmod_signkey.v
let secmod_denom = Secmod_denom.v let secmod_denom = Secmod_denom.v
let db_connection : (env, Caqti_miou.connection) Vif.Device.device =
let finally (module Conn : Caqti_miou.CONNECTION) = Conn.disconnect () in
Vif.Device.v ~name:"db_connection" ~finally []
@@ fun { caqti_switch; db_uri } ->
match Caqti_miou_unix.connect ~sw:caqti_switch db_uri with
| Error err ->
Fmt.failwith "Database connection failure: %a." Caqti_error.pp err
| Ok conn -> (
match Pg.preflight conn with
| Error err ->
Fmt.failwith "Database preflight failure: %a." Caqti_error.pp err
| Ok () -> conn)

View file

@ -54,7 +54,7 @@ let mk_future_denom denom_key_signf
} }
let mk_future_signkey signkey_signf let mk_future_signkey signkey_signf
({ pub; stamp_start; stamp_expire; stamp_end; sign= _; master_sig= _ } : ({ pub; priv= _; stamp_start; stamp_expire; stamp_end; master_sig= _ } :
Signkey.t) = Signkey.t) =
let signkey_secmod_sig = let signkey_secmod_sig =
let open Bin_type in let open Bin_type in
@ -83,12 +83,20 @@ let mk_future_keys_response (secmod_signkey : Secmod_signkey.t)
let future_denoms = let future_denoms =
secmod_denom.keys secmod_denom.keys
|> List.filter (fun k -> Option.is_none k.Denomination.master_sig) |> List.filter (fun k -> Option.is_none k.Denomination.master_sig)
|> List.map (mk_future_denom secmod_denom.sm_key.Signkey.sign) |> List.map (fun denom ->
let signf s =
Crypto.EddsaSignature.sign ~key:secmod_denom.sm_key.Signkey.priv s
in
mk_future_denom signf denom)
in in
let future_signkeys = let future_signkeys =
secmod_signkey.keys secmod_signkey.keys
|> List.filter (fun k -> Option.is_none k.Signkey.master_sig) |> List.filter (fun k -> Option.is_none k.Signkey.master_sig)
|> List.map (mk_future_signkey secmod_signkey.sm_key.sign) |> List.map (fun signkey ->
let signf s =
Crypto.EddsaSignature.sign ~key:secmod_denom.sm_key.Signkey.priv s
in
mk_future_signkey signf signkey)
in in
let master_pub = Config.Exchange.master_public_key in let master_pub = Config.Exchange.master_public_key in
let denom_secmod_public_key = secmod_denom.sm_key.pub in let denom_secmod_public_key = secmod_denom.sm_key.pub in

View file

@ -129,7 +129,7 @@ let () =
in in
let devices = let devices =
Vif.Devices. Vif.Devices.
[ Devices.secmod_signkey; Devices.secmod_denom; Devices.db_connection ] [ Devices.db_connection; Devices.secmod_signkey; Devices.secmod_denom ]
in in
let middlewares = Vif.Middlewares.[] in let middlewares = Vif.Middlewares.[] in
Vif.run ~cfg ~devices ~middlewares routes env Vif.run ~cfg ~devices ~middlewares routes env

View file

@ -96,7 +96,7 @@ let activate_signing_key =
expire_legal, master_sig) VALUES ($1, $2, $3, $4, $5)" expire_legal, master_sig) VALUES ($1, $2, $3, $4, $5)"
in in
fun (module Conn : CONN) fun (module Conn : CONN)
Signkey.{ pub; stamp_start; stamp_expire; stamp_end; master_sig; sign= _ } Signkey.{ pub; priv= _; stamp_start; stamp_expire; stamp_end; master_sig }
-> ->
(* TODO master_sig *) (* TODO master_sig *)
let master_sig = master_sig |> Option.get in let master_sig = master_sig |> Option.get in

View file

@ -4,10 +4,10 @@ open Crypto
not sur how to handle master_sig initialization *) not sur how to handle master_sig initialization *)
type t = { type t = {
pub: EddsaPublicKey.t; pub: EddsaPublicKey.t;
priv: EddsaPrivateKey.t;
stamp_start: Ptime.t; stamp_start: Ptime.t;
stamp_expire: Ptime.t; stamp_expire: Ptime.t;
stamp_end: Ptime.t; stamp_end: Ptime.t;
sign: string -> EddsaSignature.t;
(* signature of this key by offline master key *) (* signature of this key by offline master key *)
master_sig: EddsaSignature.t option; master_sig: EddsaSignature.t option;
} }
@ -25,6 +25,5 @@ let generate () =
in in
let stamp_end = stamp_expire in let stamp_end = stamp_expire in
let priv, pub = Mirage_crypto_ec.Ed25519.generate () in let priv, pub = Mirage_crypto_ec.Ed25519.generate () in
let sign s = EddsaSignature.sign ~key:priv s in
let master_sig = None in let master_sig = None in
{ pub; stamp_start; stamp_expire; stamp_end; master_sig; sign } { pub; priv; stamp_start; stamp_expire; stamp_end; master_sig }