diff --git a/src/crypto.ml b/src/crypto.ml index 388cb839..b806d590 100644 --- a/src/crypto.ml +++ b/src/crypto.ml @@ -22,13 +22,13 @@ module EddsaPublicKey = struct in Bin.map (Bin.bytes 32) of_octets to_octets + let of_b32 s = + let open Syntax in + let* octets = B32.decode s in + let* pub = of_octets octets in + Ok pub + let jsont = - let of_b32 s = - let open Syntax in - let* octets = B32.decode s in - let* pub = of_octets octets in - Ok pub - in let to_b32 t = B32.encode (to_octets t) in Jsont.of_of_string ~kind:"EddsaPublicKey" of_b32 ~enc:to_b32 diff --git a/src/handler.ml b/src/handler.ml index a9fb82d8..17cc203f 100644 --- a/src/handler.ml +++ b/src/handler.ml @@ -62,7 +62,6 @@ let management_denom_revoke req h_denom_pub server _env = let open Syntax in let open Management in let db_conn = Vif.Server.device Devices.db_connection server in - let _sm_signkey = Vif.Server.device Devices.secmod_signkey server in let sm_denom = Vif.Server.device Devices.secmod_denom server in let res = let* h_denom_pub = HashCode.of_b32 h_denom_pub in @@ -73,3 +72,19 @@ let management_denom_revoke req h_denom_pub server _env = Ok "" in respond_with_res res req + +let management_signkey_revoke_jsont = SignkeyRevocationSignature.jsont + +let management_signkey_revoke req exchange_pub server _env = + let open Syntax in + let open Management in + let db_conn = Vif.Server.device Devices.db_connection server in + let sm_signkey = Vif.Server.device Devices.secmod_signkey server in + let res = + let* exchange_pub = Crypto.EddsaPublicKey.of_b32 exchange_pub in + let* v = Vif.Request.of_json req |> unwrap_err_msg in + let* () = verify_signkey_revocation_sig exchange_pub v in + let* () = update_signkey_revocation ~db_conn ~sm_signkey exchange_pub v in + Ok "" + in + respond_with_res res req diff --git a/src/management.ml b/src/management.ml index 5a22bd8e..de55ae39 100644 --- a/src/management.ml +++ b/src/management.ml @@ -228,3 +228,18 @@ let update_denom_revocation ~db_conn ~sm_denom h_denom_pub |> unwrap_err_caqti in Ok () + +let verify_signkey_revocation_sig exchange_pub + SignkeyRevocationSignature.{ master_sig } = + let open Bin_sig.MasterSigningKeyRevocation in + verify ~key:Config.Exchange.master_public_key master_sig { exchange_pub } + +let update_signkey_revocation ~db_conn ~sm_signkey exchange_pub + SignkeyRevocationSignature.{ master_sig } = + let open Syntax in + let* () = Secmod_signkey.revoke_signkey sm_signkey exchange_pub master_sig in + let* () = + Pg.insert_signkey_revocation db_conn exchange_pub master_sig + |> unwrap_err_caqti + in + Ok () diff --git a/src/mte.ml b/src/mte.ml index 3e82c256..f6265ca4 100644 --- a/src/mte.ml +++ b/src/mte.ml @@ -39,6 +39,10 @@ let routes = (v "management" / "denominations" /% string `Path / "revoke") management_denom_revoke_jsont --> management_denom_revoke; + post + (v "management" / "signkeys" /% string `Path / "revoke") + management_signkey_revoke_jsont + --> management_signkey_revoke; ] let () = diff --git a/src/pg.ml b/src/pg.ml index f6146e74..af06fc11 100644 --- a/src/pg.ml +++ b/src/pg.ml @@ -169,3 +169,13 @@ let insert_denomination_revocation = in fun (module Conn : CONN) h_denom_pub master_sig -> Conn.exec denomination_revocation_insert (h_denom_pub, master_sig) + +let insert_signkey_revocation = + let signkey_revocation_insert = + let master_sig = Bin_sig.MasterSigningKeyRevocation.caqti in + Caqti_type.(t2 eddsa_public master_sig ->. unit) + "INSERT INTO signkey_revocations (esk_serial, master_sig) SELECT \ + esk_serial, $2 FROM exchange_sign_keys WHERE exchange_pub=$1" + in + fun (module Conn : CONN) exchange_pub master_sig -> + Conn.exec signkey_revocation_insert (exchange_pub, master_sig) diff --git a/src/secmod_signkey.ml b/src/secmod_signkey.ml index 356212f0..823b0321 100644 --- a/src/secmod_signkey.ml +++ b/src/secmod_signkey.ml @@ -4,10 +4,14 @@ we just use 1 for now *) open Syntax +type exchange_pub = Crypto.EddsaPublicKey.t + type t = { lock: Miou.Mutex.t; sm_key: Signkey.t; - signkey_ht: (Crypto.EddsaPublicKey.t, Signkey.t) Hashtbl.t; + signkey_ht: (exchange_pub, Signkey.t) Hashtbl.t; + revoked_ht: + (exchange_pub, Signkey.t * Bin_sig.MasterSigningKeyRevocation.t) Hashtbl.t; } let get_sm_key t = t.sm_key @@ -31,6 +35,15 @@ let add_master_signatures conn t l = Ok ()) l +let revoke_signkey t exchange_pub master_sig = + Miou.Mutex.protect t.lock @@ fun () -> + match Hashtbl.find_opt t.signkey_ht exchange_pub with + | None -> Error "secmod_denom failure: denomination hash not found." + | Some signkey -> + Hashtbl.remove t.signkey_ht exchange_pub; + Hashtbl.replace t.revoked_ht exchange_pub (signkey, master_sig); + Ok () + let dir = Fpath.(v "data" / "secmod_signkey") let _store_secmod_data t = @@ -65,7 +78,8 @@ let load conn = |> List.to_seq |> Hashtbl.of_seq in - Ok (Some { lock; sm_key; signkey_ht }) + let revoked_ht = Hashtbl.create 0xff in + Ok (Some { lock; sm_key; signkey_ht; revoked_ht }) | _, _ -> error_invalid_state let make_new () = @@ -78,7 +92,8 @@ let make_new () = |> List.to_seq |> Hashtbl.of_seq in - { lock; sm_key; signkey_ht } + let revoked_ht = Hashtbl.create 0xff in + { lock; sm_key; signkey_ht; revoked_ht } let init conn = match load conn with diff --git a/src/secmod_signkey.mli b/src/secmod_signkey.mli index d0a73b3f..6d97f2f5 100644 --- a/src/secmod_signkey.mli +++ b/src/secmod_signkey.mli @@ -1,4 +1,5 @@ type t +type exchange_pub = Crypto.EddsaPublicKey.t val get_sm_key : t -> Signkey.t val get_signkeys : t -> Signkey.t list @@ -6,7 +7,13 @@ val get_signkeys : t -> Signkey.t list val add_master_signatures : (module Pg.CONN) -> t -> - (Crypto.EddsaPublicKey.t * Bin_sig.ExchangeSigningKeyValidity.t) list -> + (exchange_pub * Bin_sig.ExchangeSigningKeyValidity.t) list -> + (unit, string) result + +val revoke_signkey : + t -> + exchange_pub -> + Bin_sig.MasterSigningKeyRevocation.t -> (unit, string) result val init : (module Pg.CONN) -> t