diff --git a/src/api.ml b/src/api.ml index 1422963f..0e77a541 100644 --- a/src/api.ml +++ b/src/api.ml @@ -69,10 +69,15 @@ module HashCode : sig type t val hash : string -> t + val to_octets : t -> string val jsont : t Jsont.t end = struct type t = B32.t + (* TODO rm + for convertion to DenominationHash *) + let to_octets s = s + let hash s = let open Digestif.SHA512 in s |> digest_string |> to_raw_string diff --git a/src/api_sig.ml b/src/api_sig.ml index b0ab5107..642369a5 100644 --- a/src/api_sig.ml +++ b/src/api_sig.ml @@ -193,7 +193,7 @@ module ExchangeSigningKeyValidityPS = struct type r = { start: TimeAbsoluteNBO.t; expire: TimeAbsoluteNBO.t; - end_: TimeAbsoluteNBO.t; (* "end" renamed to end_ *) + end_: TimeAbsoluteNBO.t; signkey_pub: ExchangePublicKeyP.t; } diff --git a/src/devices.ml b/src/devices.ml index 34538354..440d7545 100644 --- a/src/devices.ml +++ b/src/devices.ml @@ -85,6 +85,7 @@ end module Secmod_denom = struct type t = { sm_key: Signkey.t; + (* TODO rename *) keys: Denomination.t list; } diff --git a/src/management.ml b/src/management.ml index 123541dc..759d64af 100644 --- a/src/management.ml +++ b/src/management.ml @@ -124,18 +124,89 @@ let keys_get req server _env = (* - ** - *) -let store_master_signatures _ = - (* TODO *) +let verify_denom_signature ~sm_denom DenomSignature.{ h_denom_pub; master_sig } + = + let open Syntax in + let denom_hash = + Bin_type.DenominationHash.of_octets (HashCode.to_octets h_denom_pub) + in + let* denom = + let opt = + List.find_opt + (fun (denom : Denomination.t) -> denom.h_pub = denom_hash) + sm_denom.Secmod_denom.keys + in + match opt with + | None -> + Fmt.error + "404 not found, One of the keys for which a signature was provided \ + is unknown to the exchange." + | Some denom -> Ok denom + in + let open Api_sig.DenominationKeyValidityPS in + let r : r = + { + master= Config.master_public_key; + start= denom.stamp_start; + expire_withdraw= denom.stamp_expire_withdraw; + expire_spend= denom.stamp_expire_deposit; + expire_legal= denom.stamp_expire_legal; + value= denom.value; + fee_withdraw= denom.fee_withdraw; + fee_deposit= denom.fee_deposit; + fee_refresh= denom.fee_refresh; + denom_hash; + } + in + verify ~key:Config.master_public_key master_sig r + +let verify_signkey_signature ~sm_signkey SignKeySignature.{ key; master_sig } = + let open Syntax in + let* signkey = + let opt = + List.find_opt + (fun (signkey : Signkey.t) -> signkey.pub = key) + sm_signkey.Secmod_signkey.keys + in + match opt with + | None -> + Fmt.error + "404 not found, One of the keys for which a signature was provided \ + is unknown to the exchange." + | Some signkey -> Ok signkey + in + let open Api_sig.ExchangeSigningKeyValidityPS in + let r : r = + { + start= signkey.stamp_start; + expire= signkey.stamp_expire; + end_= signkey.stamp_end; + signkey_pub= signkey.pub; + } + in + verify ~key:Config.master_public_key master_sig r + +let verify_master_signatures ~sm_signkey ~sm_denom + MasterSignatures.{ denom_sigs; signkey_sigs } = + let open Syntax in + let* () = list_iter (verify_denom_signature ~sm_denom) denom_sigs in + let* () = list_iter (verify_signkey_signature ~sm_signkey) signkey_sigs in Ok () -let verify_master_signatures ~sm_signkey:_ ~sm_denom:_ _ = Ok () +let store_master_signatures _ = Ok () let keys_post req server _env = 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 open Syntax in - let* master_signatures = Ok () in + let* master_signatures = + match Vif.Request.of_json req with + | Ok (v : MasterSignatures.t) -> Ok v + | Error (`Msg msg) -> + Logs.err (fun m -> m "Invalid JSON: %s" msg); + Error msg + in let* () = verify_master_signatures ~sm_signkey ~sm_denom master_signatures in diff --git a/src/mte.ml b/src/mte.ml index 9d10ef09..51826093 100644 --- a/src/mte.ml +++ b/src/mte.ml @@ -23,13 +23,16 @@ let hello req _server _env = let routes = let open Vif.Uri in let open Vif.Route in - (*let open Vif.Type in*) + let open Vif.Type in + let open Api in + let post jsont = post (json_encoding jsont) in [ get (rel /?? nil) --> hello; get (rel / "terms" /?? nil) --> Static.terms; get (rel / "privacy" /?? nil) --> Static.privacy; get (rel / "management" / "keys" /?? nil) --> Management.keys_get; - get (rel / "management" / "keys" /?? nil) --> Management.keys_post; + post MasterSignatures.jsont (rel / "management" / "keys" /?? nil) + --> Management.keys_post; ] let () = diff --git a/tools/offline_sig.ml b/tools/offline_sig.ml index 1703c1a6..e39c7411 100644 --- a/tools/offline_sig.ml +++ b/tools/offline_sig.ml @@ -16,7 +16,6 @@ let denom_signature ~master_key fee_deposit; fee_refresh; fee_refund= _; - (* TODO check sigs *) denom_secmod_sig= _; } = let octets = DenominationKey.to_octets denom_pub in @@ -43,14 +42,7 @@ let denom_signature ~master_key let signkey_signature ~master_key FutureSignKey. - { - key; - stamp_start; - stamp_expire; - stamp_end; - (* TODO check sigs *) - signkey_secmod_sig= _; - } = + { key; stamp_start; stamp_expire; stamp_end; signkey_secmod_sig= _ } = let master_sig = let open Api_sig.ExchangeSigningKeyValidityPS in sign ~key:master_key @@ -68,7 +60,6 @@ let make_master_signatures ~master_key { future_denoms; future_signkeys; - (* TODO check sigs *) master_pub= _; denom_secmod_public_key= _; signkey_secmod_public_key= _;