This commit is contained in:
parent
05cfa7a5b1
commit
122d91b79d
8 changed files with 89 additions and 73 deletions
19
src/auditor.ml
Normal file
19
src/auditor.ml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
type t = {
|
||||||
|
auditor_pub: Crypto.EddsaPublicKey.t;
|
||||||
|
auditor_url: string;
|
||||||
|
auditor_name: string;
|
||||||
|
last_change: Timestamp.t;
|
||||||
|
is_active: bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
let of_setup_message
|
||||||
|
Api.AuditorSetupMessage.
|
||||||
|
{ auditor_url; auditor_name; auditor_pub; master_sig= _; validity_start }
|
||||||
|
=
|
||||||
|
{
|
||||||
|
auditor_url;
|
||||||
|
auditor_name;
|
||||||
|
auditor_pub;
|
||||||
|
last_change= validity_start;
|
||||||
|
is_active= true;
|
||||||
|
}
|
||||||
|
|
@ -153,24 +153,22 @@ module Auditors = struct
|
||||||
h_auditor_url= Hash.Cstring.H64.hash auditor_url;
|
h_auditor_url= Hash.Cstring.H64.hash auditor_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
(* TODO monotonic time *)
|
|
||||||
let do_ ~db_conn v =
|
let do_ ~db_conn v =
|
||||||
let auditor_pub = v.AuditorSetupMessage.auditor_pub in
|
let auditor_pub = v.AuditorSetupMessage.auditor_pub in
|
||||||
let validity_start = v.AuditorSetupMessage.validity_start in
|
let validity_start = v.AuditorSetupMessage.validity_start in
|
||||||
let* last_date_opt =
|
let* opt = Pg.find_auditor db_conn auditor_pub |> unwrap_err_caqti in
|
||||||
Pg.get_auditor_timestamp db_conn auditor_pub |> unwrap_err_caqti
|
match opt with
|
||||||
in
|
|
||||||
match last_date_opt with
|
|
||||||
| None ->
|
| None ->
|
||||||
let+ () = Pg.insert_auditor db_conn v |> unwrap_err_caqti in
|
let auditor = Auditor.of_setup_message v in
|
||||||
|
let+ () = Pg.update_auditor db_conn auditor |> unwrap_err_caqti in
|
||||||
Logs.info (fun m -> m "enabled auditor");
|
Logs.info (fun m -> m "enabled auditor");
|
||||||
()
|
()
|
||||||
| Some last_date ->
|
| Some auditor ->
|
||||||
if Timestamp.compare last_date validity_start > 0 then
|
if Timestamp.compare auditor.last_change validity_start > 0 then
|
||||||
Error
|
Error
|
||||||
"database has more recent auditor data for this auditor public key"
|
"database has more recent auditor data for this auditor public key"
|
||||||
else
|
else
|
||||||
let+ () = Pg.update_auditor db_conn v |> unwrap_err_caqti in
|
let+ () = Pg.update_auditor db_conn auditor |> unwrap_err_caqti in
|
||||||
Logs.info (fun m -> m "updated auditor");
|
Logs.info (fun m -> m "updated auditor");
|
||||||
()
|
()
|
||||||
|
|
||||||
|
|
@ -198,26 +196,36 @@ module Auditors_disable = struct
|
||||||
|
|
||||||
let do_ ~db_conn auditor_pub
|
let do_ ~db_conn auditor_pub
|
||||||
AuditorTeardownMessage.{ master_sig= _; validity_end } =
|
AuditorTeardownMessage.{ master_sig= _; validity_end } =
|
||||||
let* last_date_opt =
|
let* opt = Pg.find_auditor db_conn auditor_pub |> unwrap_err_caqti in
|
||||||
Pg.get_auditor_timestamp db_conn auditor_pub |> unwrap_err_caqti
|
match opt with
|
||||||
in
|
|
||||||
match last_date_opt with
|
|
||||||
| None -> Error "auditor not found"
|
| None -> Error "auditor not found"
|
||||||
| Some last_date ->
|
| Some auditor -> (
|
||||||
if Timestamp.compare last_date validity_end > 0 then
|
match Timestamp.compare auditor.last_change validity_end > 0 with
|
||||||
Error
|
| true ->
|
||||||
"database has more recent auditor data for this auditor public key"
|
Error
|
||||||
else
|
"database has more recent auditor data for this auditor public \
|
||||||
let+ () =
|
key"
|
||||||
Pg.disable_auditor db_conn ~auditor_pub ~change_date:validity_end
|
| false -> (
|
||||||
|> unwrap_err_caqti
|
match auditor.is_active with
|
||||||
in
|
| false ->
|
||||||
()
|
Logs.info (fun m -> m "auditor was already revoked");
|
||||||
|
Ok ()
|
||||||
|
| true ->
|
||||||
|
let auditor =
|
||||||
|
{ auditor with last_change= validity_end; is_active= false }
|
||||||
|
in
|
||||||
|
let+ () =
|
||||||
|
Pg.update_auditor db_conn auditor |> unwrap_err_caqti
|
||||||
|
in
|
||||||
|
Logs.info (fun m ->
|
||||||
|
m "revoked auditor `%s`"
|
||||||
|
(Crypto.EddsaPublicKey.to_b32 auditor_pub));
|
||||||
|
()))
|
||||||
|
|
||||||
let jsont = AuditorTeardownMessage.jsont
|
let jsont = AuditorTeardownMessage.jsont
|
||||||
|
|
||||||
let f req auditor_pub server _env =
|
let f req auditor_pub server _env =
|
||||||
Logs.info (fun m -> m "POST /management/auditors/$AUDITOR_PUB/revoke/");
|
Logs.info (fun m -> m "POST /management/auditors/$AUDITOR_PUB/disable/");
|
||||||
let keys = Vif.Server.device Devices.keys server in
|
let keys = Vif.Server.device Devices.keys server in
|
||||||
let db_conn = Vif.Server.device Devices.db_connection server in
|
let db_conn = Vif.Server.device Devices.db_connection server in
|
||||||
let res =
|
let res =
|
||||||
|
|
|
||||||
40
src/pg.ml
40
src/pg.ml
|
|
@ -115,43 +115,23 @@ let insert_signkey_revocation =
|
||||||
fun (module Conn : CONN) exchange_pub master_sig ->
|
fun (module Conn : CONN) exchange_pub master_sig ->
|
||||||
Conn.exec req (exchange_pub, master_sig)
|
Conn.exec req (exchange_pub, master_sig)
|
||||||
|
|
||||||
let get_auditor_timestamp =
|
let find_auditor =
|
||||||
let req =
|
let req =
|
||||||
Caqti_type.(eddsa_pub ->? time)
|
Caqti_type.(eddsa_pub ->? auditor)
|
||||||
"SELECT last_change FROM auditors WHERE auditor_pub=$1"
|
"SELECT auditor_pub, auditor_name, auditor_url, last_change, is_active \
|
||||||
|
FROM auditors WHERE auditor_pub=$1"
|
||||||
in
|
in
|
||||||
fun (module Conn : CONN) auditor_pub -> Conn.find_opt req auditor_pub
|
fun (module Conn : CONN) auditor_pub -> Conn.find_opt req auditor_pub
|
||||||
|
|
||||||
let insert_auditor =
|
|
||||||
let req =
|
|
||||||
Caqti_type.(t4 eddsa_pub string string time ->. unit)
|
|
||||||
"INSERT INTO auditors (auditor_pub, auditor_name, auditor_url, \
|
|
||||||
is_active, last_change) VALUES ($1, $2, $3, true, $4)"
|
|
||||||
in
|
|
||||||
fun (module Conn : CONN)
|
|
||||||
AuditorSetupMessage.
|
|
||||||
{ auditor_url; auditor_name; auditor_pub; master_sig= _; validity_start }
|
|
||||||
-> Conn.exec req (auditor_pub, auditor_name, auditor_url, validity_start)
|
|
||||||
|
|
||||||
let update_auditor =
|
let update_auditor =
|
||||||
let req =
|
let req =
|
||||||
Caqti_type.(t5 eddsa_pub string string bool time ->. unit)
|
Caqti_type.(auditor ->. unit)
|
||||||
"UPDATE auditors SET auditor_url=$2, auditor_name=$3, is_active=$4, \
|
"INSERT INTO auditors (auditor_pub, auditor_name, auditor_url, \
|
||||||
last_change=$5 WHERE auditor_pub=$1"
|
last_change, is_active) VALUES ($1, $2, $3, $4, $5) ON CONFLICT \
|
||||||
|
(auditor_pub) DO UPDATE SET auditor_name=$2, auditor_url=$3, \
|
||||||
|
last_change=$4, is_active=$5"
|
||||||
in
|
in
|
||||||
fun (module Conn : CONN)
|
fun (module Conn : CONN) auditor -> Conn.exec req auditor
|
||||||
AuditorSetupMessage.
|
|
||||||
{ auditor_url; auditor_name; auditor_pub; master_sig= _; validity_start }
|
|
||||||
-> Conn.exec req (auditor_pub, auditor_url, auditor_name, true, validity_start)
|
|
||||||
|
|
||||||
let disable_auditor =
|
|
||||||
let req =
|
|
||||||
Caqti_type.(t5 eddsa_pub string string bool time ->. unit)
|
|
||||||
"UPDATE auditors SET auditor_url=$2, auditor_name=$3, is_active=$4, \
|
|
||||||
last_change=$5 WHERE auditor_pub=$1"
|
|
||||||
in
|
|
||||||
fun (module Conn : CONN) ~auditor_pub ~change_date ->
|
|
||||||
Conn.exec req (auditor_pub, "", "", false, change_date)
|
|
||||||
|
|
||||||
let insert_auditor_denom_sig =
|
let insert_auditor_denom_sig =
|
||||||
let req =
|
let req =
|
||||||
|
|
|
||||||
|
|
@ -351,3 +351,14 @@ let exchange_partner_setup =
|
||||||
wad_fee;
|
wad_fee;
|
||||||
})
|
})
|
||||||
Caqti_type.(t7 eddsa_pub time time time_span amount master_sig string)
|
Caqti_type.(t7 eddsa_pub time time time_span amount master_sig string)
|
||||||
|
|
||||||
|
let auditor =
|
||||||
|
let open Auditor in
|
||||||
|
Caqti_type.custom
|
||||||
|
~encode:(fun
|
||||||
|
{ auditor_pub; auditor_url; auditor_name; last_change; is_active } ->
|
||||||
|
Ok (auditor_pub, auditor_url, auditor_name, last_change, is_active))
|
||||||
|
~decode:(fun
|
||||||
|
(auditor_pub, auditor_url, auditor_name, last_change, is_active) ->
|
||||||
|
Ok { auditor_pub; auditor_url; auditor_name; last_change; is_active })
|
||||||
|
Caqti_type.(t5 eddsa_pub string string time bool)
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,16 @@ offline_tool enable-auditor \
|
||||||
--output $b \
|
--output $b \
|
||||||
--auditor_url "auditor.example.com" \
|
--auditor_url "auditor.example.com" \
|
||||||
--auditor_name "auditor example" \
|
--auditor_name "auditor example" \
|
||||||
--auditor_pub $auditor_pub \
|
--auditor_pub $auditor_pub
|
||||||
--validity_start 0
|
|
||||||
offline_tool upload --input $b --url $url"/management/auditors"
|
offline_tool upload --input $b --url $url"/management/auditors"
|
||||||
echo "[OK] /management/auditors"
|
echo "[OK] /management/auditors"
|
||||||
|
|
||||||
# todo test disable auditor
|
offline_tool disable-auditor \
|
||||||
|
--master_key $master_key \
|
||||||
|
--output $b \
|
||||||
|
--auditor_pub $auditor_pub
|
||||||
|
offline_tool upload --input $b --url $url"/management/auditors/"$auditor_pub"/disable"
|
||||||
|
echo "[OK] /management/auditors/\$AUDITOR_PUB/disable"
|
||||||
|
|
||||||
offline_tool wire-fee \
|
offline_tool wire-fee \
|
||||||
--master_key $master_key \
|
--master_key $master_key \
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
(public_name offline)
|
(public_name offline)
|
||||||
(name offline)
|
(name offline)
|
||||||
(modules offline offline_impl)
|
(modules offline offline_impl)
|
||||||
(libraries cmdliner bos fmt mirage-crypto ptime mte vif))
|
(libraries cmdliner bos fmt mirage-crypto mtime ptime mte vif))
|
||||||
|
|
||||||
(executable
|
(executable
|
||||||
(public_name gen_registry_files)
|
(public_name gen_registry_files)
|
||||||
|
|
|
||||||
|
|
@ -199,35 +199,26 @@ let enable_auditor_cmd =
|
||||||
let auditor_pub =
|
let auditor_pub =
|
||||||
Arg.(required & opt (some eddsa_pub) None & info [ "auditor_pub" ])
|
Arg.(required & opt (some eddsa_pub) None & info [ "auditor_pub" ])
|
||||||
in
|
in
|
||||||
let validity_start =
|
|
||||||
Arg.(required & opt (some timestamp) None & info [ "validity_start" ])
|
|
||||||
in
|
|
||||||
Cmd.make (Cmd.info "enable-auditor" ~doc)
|
Cmd.make (Cmd.info "enable-auditor" ~doc)
|
||||||
@@
|
@@
|
||||||
let+ output = output
|
let+ output = output
|
||||||
and+ master_key = master_key
|
and+ master_key = master_key
|
||||||
and+ auditor_url = auditor_url
|
and+ auditor_url = auditor_url
|
||||||
and+ auditor_name = auditor_name
|
and+ auditor_name = auditor_name
|
||||||
and+ auditor_pub = auditor_pub
|
and+ auditor_pub = auditor_pub in
|
||||||
and+ validity_start = validity_start in
|
|
||||||
enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub
|
enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub
|
||||||
~validity_start
|
|
||||||
|
|
||||||
let disable_auditor_cmd =
|
let disable_auditor_cmd =
|
||||||
let doc = "Disable auditor." in
|
let doc = "Disable auditor." in
|
||||||
let auditor_pub =
|
let auditor_pub =
|
||||||
Arg.(required & opt (some eddsa_pub) None & info [ "auditor_pub" ])
|
Arg.(required & opt (some eddsa_pub) None & info [ "auditor_pub" ])
|
||||||
in
|
in
|
||||||
let validity_end =
|
|
||||||
Arg.(required & opt (some timestamp) None & info [ "validity_end" ])
|
|
||||||
in
|
|
||||||
Cmd.make (Cmd.info "disable-auditor" ~doc)
|
Cmd.make (Cmd.info "disable-auditor" ~doc)
|
||||||
@@
|
@@
|
||||||
let+ output = output
|
let+ output = output
|
||||||
and+ master_key = master_key
|
and+ master_key = master_key
|
||||||
and+ auditor_pub = auditor_pub
|
and+ auditor_pub = auditor_pub in
|
||||||
and+ validity_end = validity_end in
|
disable_auditor ~output ~master_key ~auditor_pub
|
||||||
disable_auditor ~output ~master_key ~auditor_pub ~validity_end
|
|
||||||
|
|
||||||
let wire_fee_cmd =
|
let wire_fee_cmd =
|
||||||
let doc = "Provides wire fee configuration." in
|
let doc = "Provides wire fee configuration." in
|
||||||
|
|
|
||||||
|
|
@ -275,9 +275,10 @@ let global_fees ~output ~master_key ~start_date ~end_date ~history_fee
|
||||||
let* () = write_file output s in
|
let* () = write_file output s in
|
||||||
Ok ()
|
Ok ()
|
||||||
|
|
||||||
let enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub
|
let enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub =
|
||||||
~validity_start =
|
|
||||||
let* key = read_master_key_file master_key in
|
let* key = read_master_key_file master_key in
|
||||||
|
let ns = Mtime_clock.now_ns () in
|
||||||
|
let validity_start = Timestamp.of_s @@ Int64.unsigned_div ns 1_000_000_000L in
|
||||||
let master_sig =
|
let master_sig =
|
||||||
let open Signatures.MasterAddAuditor in
|
let open Signatures.MasterAddAuditor in
|
||||||
signf (EddsaSignature.sign ~key)
|
signf (EddsaSignature.sign ~key)
|
||||||
|
|
@ -295,8 +296,10 @@ let enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub
|
||||||
let* () = write_file output s in
|
let* () = write_file output s in
|
||||||
Ok ()
|
Ok ()
|
||||||
|
|
||||||
let disable_auditor ~output ~master_key ~auditor_pub ~validity_end =
|
let disable_auditor ~output ~master_key ~auditor_pub =
|
||||||
let* key = read_master_key_file master_key in
|
let* key = read_master_key_file master_key in
|
||||||
|
let ns = Mtime_clock.now_ns () in
|
||||||
|
let validity_end = Timestamp.of_s @@ Int64.unsigned_div ns 1_000_000_000L in
|
||||||
let master_sig =
|
let master_sig =
|
||||||
let open Signatures.MasterDelAuditor in
|
let open Signatures.MasterDelAuditor in
|
||||||
signf (EddsaSignature.sign ~key) { end_date= validity_end; auditor_pub }
|
signf (EddsaSignature.sign ~key) { end_date= validity_end; auditor_pub }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue