fix check for replay attack + revoke 1sec in the future
This commit is contained in:
parent
a3880e5377
commit
b1602a5020
5 changed files with 67 additions and 48 deletions
|
|
@ -6,8 +6,7 @@
|
||||||
properly combine jsont for "interface DenomGroupRsa extends DenomGroupCommon"
|
properly combine jsont for "interface DenomGroupRsa extends DenomGroupCommon"
|
||||||
better types:
|
better types:
|
||||||
- payto_uri
|
- payto_uri
|
||||||
- uri
|
- uri *)
|
||||||
use of monotonic time for some validity_start/_end fields *)
|
|
||||||
|
|
||||||
let protocol_version = "31:0:0"
|
let protocol_version = "31:0:0"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,8 +165,7 @@ module Auditors = struct
|
||||||
()
|
()
|
||||||
| Some auditor ->
|
| Some auditor ->
|
||||||
if Timestamp.geq auditor.last_change validity_start then
|
if Timestamp.geq auditor.last_change validity_start then
|
||||||
Error
|
Error "replay detected on enable-auditor"
|
||||||
"database has more recent auditor data for this auditor public key"
|
|
||||||
else
|
else
|
||||||
let+ () = Pg.update_auditor db_conn auditor |> 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");
|
||||||
|
|
@ -200,27 +199,22 @@ module Auditors_disable = struct
|
||||||
match opt with
|
match opt with
|
||||||
| None -> Error "auditor not found"
|
| None -> Error "auditor not found"
|
||||||
| Some auditor -> (
|
| Some auditor -> (
|
||||||
match Timestamp.geq auditor.last_change validity_end with
|
if Timestamp.geq auditor.last_change validity_end then
|
||||||
| true ->
|
Error "replay detected on disable-auditor"
|
||||||
Error
|
else
|
||||||
"database has more recent auditor data for this auditor public \
|
match auditor.is_active with
|
||||||
key"
|
| false ->
|
||||||
| false -> (
|
Logs.info (fun m -> m "auditor was already revoked");
|
||||||
match auditor.is_active with
|
Ok ()
|
||||||
| false ->
|
| true ->
|
||||||
Logs.info (fun m -> m "auditor was already revoked");
|
let auditor =
|
||||||
Ok ()
|
{ auditor with last_change= validity_end; is_active= false }
|
||||||
| true ->
|
in
|
||||||
let auditor =
|
let+ () = Pg.update_auditor db_conn auditor |> unwrap_err_caqti in
|
||||||
{ auditor with last_change= validity_end; is_active= false }
|
Logs.info (fun m ->
|
||||||
in
|
m "revoked auditor `%s`"
|
||||||
let+ () =
|
(Crypto.EddsaPublicKey.to_b32 auditor_pub));
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -436,14 +430,6 @@ module Wire = struct
|
||||||
} =
|
} =
|
||||||
let* opt = Pg.find_wire db_conn ~payto_uri |> unwrap_err_caqti in
|
let* opt = Pg.find_wire db_conn ~payto_uri |> unwrap_err_caqti in
|
||||||
match opt with
|
match opt with
|
||||||
| Some wire ->
|
|
||||||
let+ () =
|
|
||||||
Pg.update_wire db_conn ~is_active:true ~last_change:validity_start
|
|
||||||
wire
|
|
||||||
|> unwrap_err_caqti
|
|
||||||
in
|
|
||||||
Logs.info (fun m -> m "updated wire method");
|
|
||||||
()
|
|
||||||
| None ->
|
| None ->
|
||||||
let wire =
|
let wire =
|
||||||
ExchangeWireAccount.
|
ExchangeWireAccount.
|
||||||
|
|
@ -464,6 +450,17 @@ module Wire = struct
|
||||||
in
|
in
|
||||||
Logs.info (fun m -> m "added wire method");
|
Logs.info (fun m -> m "added wire method");
|
||||||
()
|
()
|
||||||
|
| Some (wire, _is_active, last_change) ->
|
||||||
|
if Timestamp.geq last_change validity_start then
|
||||||
|
Error "replay detected on enable-wire"
|
||||||
|
else
|
||||||
|
let+ () =
|
||||||
|
Pg.update_wire db_conn ~is_active:true ~last_change:validity_start
|
||||||
|
wire
|
||||||
|
|> unwrap_err_caqti
|
||||||
|
in
|
||||||
|
Logs.info (fun m -> m "updated wire method");
|
||||||
|
()
|
||||||
|
|
||||||
let jsont = WireSetupMessage.jsont
|
let jsont = WireSetupMessage.jsont
|
||||||
|
|
||||||
|
|
@ -492,13 +489,17 @@ module Wire_disable = struct
|
||||||
let* opt = Pg.find_wire db_conn ~payto_uri |> unwrap_err_caqti in
|
let* opt = Pg.find_wire db_conn ~payto_uri |> unwrap_err_caqti in
|
||||||
match opt with
|
match opt with
|
||||||
| None -> Error "wire not found"
|
| None -> Error "wire not found"
|
||||||
| Some wire ->
|
| Some (wire, _is_active, last_change) ->
|
||||||
let+ () =
|
if Timestamp.geq last_change validity_end then
|
||||||
Pg.update_wire db_conn ~is_active:false ~last_change:validity_end wire
|
Error "replay detected on disable-wire"
|
||||||
|> unwrap_err_caqti
|
else
|
||||||
in
|
let+ () =
|
||||||
Logs.info (fun m -> m "disabled wire method");
|
Pg.update_wire db_conn ~is_active:false ~last_change:validity_end
|
||||||
()
|
wire
|
||||||
|
|> unwrap_err_caqti
|
||||||
|
in
|
||||||
|
Logs.info (fun m -> m "disabled wire method");
|
||||||
|
()
|
||||||
|
|
||||||
let jsont = WireTeardownMessage.jsont
|
let jsont = WireTeardownMessage.jsont
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,10 +257,10 @@ let insert_global_fees =
|
||||||
|
|
||||||
let find_wire =
|
let find_wire =
|
||||||
let req =
|
let req =
|
||||||
Caqti_type.(payto_uri ->? exchange_wire_account)
|
Caqti_type.(payto_uri ->? t3 exchange_wire_account bool time)
|
||||||
"SELECT payto_uri, conversion_url, debit_restrictions::TEXT, \
|
"SELECT payto_uri, conversion_url, debit_restrictions::TEXT, \
|
||||||
credit_restrictions::TEXT, master_sig, bank_label, priority FROM \
|
credit_restrictions::TEXT, master_sig, bank_label, priority, is_active, \
|
||||||
wire_accounts WHERE payto_uri=$1"
|
last_change FROM wire_accounts WHERE payto_uri=$1"
|
||||||
in
|
in
|
||||||
fun (module Conn : CONN) ~payto_uri -> Conn.find_opt req payto_uri
|
fun (module Conn : CONN) ~payto_uri -> Conn.find_opt req payto_uri
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
(* not done:
|
(* TODO
|
||||||
/management/aml-officers (for /aml)
|
don't trust any public keys
|
||||||
/management/partners (for /wads) *)
|
keep trusted exchange/secmod keys
|
||||||
|
either from config or TOFU (Trust On First Use)
|
||||||
|
|
||||||
|
not done:
|
||||||
|
/management/aml-officers (for /aml)
|
||||||
|
/management/partners (for /wads) *)
|
||||||
open Cmdliner
|
open Cmdliner
|
||||||
open Cmdliner.Term.Syntax
|
open Cmdliner.Term.Syntax
|
||||||
open Offline_impl
|
open Offline_impl
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,14 @@ let enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub =
|
||||||
let disable_auditor ~output ~master_key ~auditor_pub =
|
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 ns = Mtime_clock.now_ns () in
|
||||||
let validity_end = Timestamp.of_s @@ Int64.unsigned_div ns 1_000_000_000L in
|
let open Time in
|
||||||
|
let validity_end =
|
||||||
|
TimeAbsolute.of_s @@ Int64.unsigned_div ns 1_000_000_000L
|
||||||
|
in
|
||||||
|
(* hack for tests: +1sec to be sure it overwrite previous timestamp *)
|
||||||
|
let validity_end =
|
||||||
|
Timestamp.of_absolute (TimeAbsolute.add validity_end TimeRelative.(of_s 1L))
|
||||||
|
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 }
|
||||||
|
|
@ -397,7 +404,14 @@ let enable_wire ~output ~master_key ~payto_uri ~bank_label ~priority =
|
||||||
let disable_wire ~output ~master_key ~payto_uri =
|
let disable_wire ~output ~master_key ~payto_uri =
|
||||||
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 ns = Mtime_clock.now_ns () in
|
||||||
let validity_end = Timestamp.of_s @@ Int64.unsigned_div ns 1_000_000_000L in
|
let open Time in
|
||||||
|
let validity_end =
|
||||||
|
TimeAbsolute.of_s @@ Int64.unsigned_div ns 1_000_000_000L
|
||||||
|
in
|
||||||
|
(* hack for tests: +1sec to be sure it overwrite previous timestamp *)
|
||||||
|
let validity_end =
|
||||||
|
Timestamp.of_absolute (TimeAbsolute.add validity_end TimeRelative.(of_s 1L))
|
||||||
|
in
|
||||||
let h_wire = Hash.FullPaytoHash.hash payto_uri in
|
let h_wire = Hash.FullPaytoHash.hash payto_uri in
|
||||||
let master_sig_del =
|
let master_sig_del =
|
||||||
let open Signatures.MasterDelWire in
|
let open Signatures.MasterDelWire in
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue