From 5692200c2d58859f5a1a4f7b8cdfd5fd91ea6535 Mon Sep 17 00:00:00 2001 From: swrup Date: Tue, 3 Mar 2026 01:36:12 +0100 Subject: [PATCH] add last_change timestamp to secmod_rsa --- src/http_info.ml | 6 +----- src/keys.ml | 5 +++++ src/secmod_rsa.ml | 17 +++++++++++++---- src/time.ml | 6 ++++++ src/time.mli | 3 +++ test/validate_response.ml | 23 ++--------------------- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/http_info.ml b/src/http_info.ml index ad4fc4e7..a57d7682 100644 --- a/src/http_info.ml +++ b/src/http_info.ml @@ -60,11 +60,7 @@ let mk_keys ~db_conn (module Keys : Keys.S) ~last_issue_date = let zero_limits = [] in let* denom_l = Keys.denominations () in - let list_issue_date = - List.fold_left - (fun acc dn -> Timestamp.max acc dn.Denomination.stamp_start) - Timestamp.zero denom_l - in + let list_issue_date = Keys.denominations_last_change () in let denom_l = (* if `?last_issue_date` query param does not exactly match the `stamp_start` of one of the denomination keys, all keys are returned *) diff --git a/src/keys.ml b/src/keys.ml index 45433c32..6ad2a4f6 100644 --- a/src/keys.ml +++ b/src/keys.ml @@ -11,6 +11,9 @@ module type S = sig val find_denomination : denom_hash -> Denomination.t option result val signkeys : unit -> Signkey.t list result val denominations : unit -> Denomination.t list result + val denominations_last_change : unit -> Timestamp.t + + (* future keys *) val make_future_keys_response : unit -> Api.FutureKeysResponse.t result val verify_future_signkey : Api.SignKeySignature.t -> unit result val verify_future_denomination : Api.DenomSignature.t -> unit result @@ -90,6 +93,8 @@ module Make (Conn : Pg.CONN) : S = struct m "found %d active denomination(s)" (List.length l)); l + let denominations_last_change () = Sm_rsa.last_change () + let make_future_sk (pub, (start, expire)) = Logs.debug (fun m -> m "make_future_sk: `%s`" (EddsaPublicKey.to_b32 pub)); let open Time in diff --git a/src/secmod_rsa.ml b/src/secmod_rsa.ml index ef149b3e..698c8de4 100644 --- a/src/secmod_rsa.ml +++ b/src/secmod_rsa.ml @@ -52,6 +52,7 @@ type t = { sm_key_priv: EddsaPrivateKey.t; sm_pub: EddsaPublicKey.t; ht: (DenominationHash.t, key) Hashtbl.t; + mutable last_change: Timestamp.t; } let parse_filename = @@ -198,10 +199,15 @@ let load () = let sm_pub = EddsaPrivateKey.pub_of_priv sm_key_priv in let ht = Hashtbl.create 0xff in let () = List.iter (fun k -> Hashtbl.replace ht k.h_pub k) keys in - Ok (Some { sm_key_priv; sm_pub; ht }) + (* TODO list_issue_date + not ideal, not sure what to put here + it would be best to save keys creation time *) + let last_change = Timestamp.never in + Ok (Some { sm_key_priv; sm_pub; ht; last_change }) let init () = let* opt = load () in + let now = TimeAbsolute.of_ptime (Ptime_clock.now ()) in let* t = match opt with | Some t -> Ok t @@ -211,9 +217,9 @@ let init () = m "generated secmod key: `%s`" (EddsaPublicKey.to_b32 sm_pub)); let* () = write_eddsa sm_key_fpath sm_key_priv in let ht = Hashtbl.create 0xff in - Ok { sm_key_priv; sm_pub; ht } + let last_change = Timestamp.of_absolute now in + Ok { sm_key_priv; sm_pub; ht; last_change } in - let now = TimeAbsolute.of_ptime (Ptime_clock.now ()) in let all_keys = List.of_seq @@ Hashtbl.to_seq_values t.ht in let new_keys_l = List.map @@ -251,11 +257,14 @@ module Make () = struct |> list_iter delete let add section_name t1 t2 = + let last_change = Timestamp.of_ptime (Ptime_clock.now ()) in let k = gen_key ~section_name t1 t2 in - Hashtbl.replace t.ht k.h_pub k; let+ () = write_key k in + Hashtbl.replace t.ht k.h_pub k; + t.last_change <- last_change; () + let last_change () = t.last_change let sm_pub = t.sm_pub let sign_secmod s = EddsaSignature.sign ~key:t.sm_key_priv s diff --git a/src/time.ml b/src/time.ml index 634a9dff..6c3b634e 100644 --- a/src/time.ml +++ b/src/time.ml @@ -54,6 +54,9 @@ module TimeRelative = struct Jsont.Object.map ~kind:"RelativeTime" Fun.id |> Jsont.Object.mem "d_us" jsont ~enc:Fun.id |> Jsont.Object.finish + + let pp ppf t = + if t = forever then Fmt.pf ppf "forever" else Fmt.pf ppf "%Lu" t end module TimeAbsolute = struct @@ -89,6 +92,7 @@ module TimeAbsolute = struct if Int64.unsigned_div v 1_000_000L <> s then never else v let of_ptime v = v |> Ptime.to_float_s |> Int64.of_float |> of_s + let pp ppf t = if t = never then Fmt.pf ppf "never" else Fmt.pf ppf "%Lu" t end module Timestamp = struct @@ -148,4 +152,6 @@ module Timestamp = struct Jsont.Object.map ~kind:"Timestamp" Fun.id |> Jsont.Object.mem "t_s" jsont ~enc:Fun.id |> Jsont.Object.finish + + let pp ppf t = if t = never then Fmt.pf ppf "never" else Fmt.pf ppf "%Lu" t end diff --git a/src/time.mli b/src/time.mli index a7c038b3..ca3322c4 100644 --- a/src/time.mli +++ b/src/time.mli @@ -14,6 +14,7 @@ module TimeRelative : sig val bin : t Bin.t val caqti : t Caqti_type.t val jsont : t Jsont.t + val pp : Format.formatter -> t -> unit end module TimeAbsolute : sig @@ -29,6 +30,7 @@ module TimeAbsolute : sig val sub : t -> TimeRelative.t -> t val of_s : int64 -> t val of_ptime : Ptime.t -> t + val pp : Format.formatter -> t -> unit end module Timestamp : sig @@ -53,4 +55,5 @@ module Timestamp : sig val bin : t Bin.t val caqti : t Caqti_type.t val jsont : t Jsont.t + val pp : Format.formatter -> t -> unit end diff --git a/test/validate_response.ml b/test/validate_response.ml index 970a803f..95d02531 100644 --- a/test/validate_response.ml +++ b/test/validate_response.ml @@ -74,27 +74,8 @@ let keys content = let denom_l = v.denominations |> Denomination.denoms_of_denomgroups in let* () = denom_l - |> list_iter (fun dn -> - let open Denomination in - (*let to_int64 ts = ts |> Timestamp.to_s |> Option.get in*) - Fmt.pr "rsa_pub: %s@." (Crypto.RsaPublicKey.to_b32 dn.pub); - Fmt.pr "master_sig: %s@." (B32.encode @@ Obj.magic dn.master_sig); - (* amount bin fraction bad? *) - let* () = - Denomination.verify_denomination_key_validity ~key:v.master_public_key - dn - in - Fmt.pr "validated a denom@."; - Ok ()) - in - let* () = - let last_issue_date = - denom_l - |> List.map (fun dn -> dn.Denomination.stamp_start) - |> List.fold_left Timestamp.max Timestamp.zero - in - if last_issue_date = v.list_issue_date then Ok () - else Fmt.error "list_issue_date is wrong" + |> list_iter + (Denomination.verify_denomination_key_validity ~key:v.master_public_key) in Fmt.pr "OK denominations@.";