mte/test/validate_response.ml

159 lines
4.4 KiB
OCaml
Raw Normal View History

2026-02-27 17:49:54 +01:00
open Syntax
let keys content =
2026-02-27 18:15:09 +01:00
let open Api in
let open ExchangeKeysResponse in
2026-02-27 17:49:54 +01:00
let* v = Api.decode jsont content in
let* () =
if
Libtool_version.is_compatible
~implementation:Libtool_version.mte_protocol_version v.version
then Ok ()
else Fmt.error "version incompatible"
in
2026-02-27 18:15:09 +01:00
(* TODO need hash over json..
validate ExchangeWireAccount *)
let* () =
let open AggregateTransferFee in
v.wire_fees
|> String_map.bindings
|> List.concat_map (fun (wire_method, l) ->
List.map (fun item -> (wire_method, item)) l)
|> list_iter
(fun
(wire_method, { wire_fee; closing_fee; start_date; end_date; sig_ })
->
let open Signatures.MasterWireFee in
verify v.master_public_key sig_
{
h_wire_method= Hash.Cstring.H64.hash wire_method;
start_date;
end_date;
wire_fee;
closing_fee;
})
in
2026-02-27 18:30:01 +01:00
let* () =
let open SignKey in
v.signkeys
|> list_iter
(fun { key; stamp_start; stamp_expire; stamp_end; master_sig } ->
let open Signatures.ExchangeSigningKeyValidity in
verify v.master_public_key master_sig
{
R.start= stamp_start;
expire= stamp_expire;
end_= stamp_end;
signkey_pub= key;
})
in
2026-02-27 18:37:37 +01:00
let* () =
let opt =
List.find_opt (fun sk -> sk.SignKey.key = v.exchange_pub) v.signkeys
in
match opt with
| None -> Fmt.error "exchange_pub is not in signkeys list"
| Some sk ->
let sk = SignKey.to_signkey sk in
(* todo will need to fake time to validate expired data *)
let now = Timestamp.of_ptime (Ptime_clock.now ()) in
if Signkey.is_valid_at ~timestamp:now sk then Ok ()
else Fmt.error "exchange_pub is not valid at the current time"
in
2026-02-27 18:40:20 +01:00
let* () =
let open Signatures.ExchangeKeySet in
verify v.exchange_pub v.exchange_sig
R.
{
list_issue_date= v.list_issue_date;
hc= Denomination.hash_over_master_sigs v.denominations;
}
in
2026-02-27 18:30:01 +01:00
2026-02-27 18:55:31 +01:00
let* () =
(* TODO parse CS *)
v.denominations
|> list_iter
(fun
(DenomGroup.Rsa
RsaDenomGroup.
{
denoms;
value;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
})
->
let open RsaDenom in
denoms
|> list_iter
(fun
{
rsa_pub;
master_sig;
stamp_start;
stamp_expire_withdraw;
stamp_expire_deposit;
stamp_expire_legal;
lost= _;
}
->
let denom_hash =
DenominationHash.hash
(Crypto.RsaPublicKey.to_octets rsa_pub)
in
let open Signatures.DenominationKeyValidity in
verify v.master_public_key master_sig
{
R.master= v.master_public_key;
start= stamp_start;
expire_withdraw= stamp_expire_withdraw;
expire_spend= stamp_expire_deposit;
expire_legal= stamp_expire_legal;
value;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
denom_hash;
}))
in
2026-02-27 17:49:54 +01:00
(* validate global-fees *)
(* validate list_issue_date *)
(* validate auditors *)
Ok ()
(* --- *)
open Cmdliner
open Cmdliner.Term.Syntax
let keys_cmd =
let input =
let doc = "input file" in
Arg.(required & opt (some filepath) None & info [ "i"; "input" ] ~doc)
in
let doc = "validate a /keys JSON response" in
Cmd.make (Cmd.info "keys" ~doc)
@@
let+ input = input in
let* content =
Result.bind (Fpath.of_string input) Bos.OS.File.read |> unwrap_err_msg
in
keys content
let cli =
let info =
let doc = "Testing tool to validate exchange responses" in
Cmd.info "validate" ~doc
in
Cmd.group info [ keys_cmd ]
let main () = Cmd.eval_result cli
let () = if !Sys.interactive then () else exit (main ())