diff --git a/CHANGES.rst b/CHANGES.rst index 5f68cbbb266031d2c4a5dc4e5db9fe613e448337..d12e9ae64550763d8b76bbc3f084ee87cf869906 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -97,9 +97,14 @@ Signer ------ - Add a ``--allow-list-known-keys`` argument at signer launch to allow client to - ask for the signer list of known public key hashes. The signer return ``List + ask for the signer list of known public key hashes. The signer returns ``List known keys request not allowed.`` otherwise. (MR :gl:`!17403`) +- Add a ``--allow-to-prove-possession`` argument at signer launch to allow + client to request proof of possession of known public key hashes. The signer + returns ``Request to prove possession is not allowed`` otherwise. + (MR :gl:`!18137`) + Baker ----- diff --git a/src/bin_signer/http_daemon.ml b/src/bin_signer/http_daemon.ml index ad59087063ceea0e3abaad6f6abfd65b791292c3..9cbc73d0f0e87a5e9ae9a136dbc227566d108b48 100644 --- a/src/bin_signer/http_daemon.ml +++ b/src/bin_signer/http_daemon.ml @@ -26,7 +26,8 @@ module Events = Signer_events.Http_daemon let run (cctxt : #Client_context.wallet) ~hosts ?signing_version ?magic_bytes - ?(allow_list_known_keys = false) ~check_high_watermark ~require_auth mode = + ?(allow_list_known_keys = false) ?(allow_to_prove_possession = false) + ~check_high_watermark ~require_auth mode = let open Lwt_result_syntax in let dir = Tezos_rpc.Directory.empty in let dir = @@ -54,11 +55,18 @@ let run (cctxt : #Client_context.wallet) ~hosts ?signing_version ?magic_bytes (fun pkh () () -> Handler.public_key cctxt pkh) in let dir = - Tezos_rpc.Directory.register1 - dir - Signer_services.bls_prove_possession - (fun pkh override_pk () -> - Handler.bls_prove_possession cctxt ?override_pk pkh) + if allow_to_prove_possession then + Tezos_rpc.Directory.register1 + dir + Signer_services.bls_prove_possession + (fun pkh override_pk () -> + Handler.bls_prove_possession cctxt ?override_pk pkh) + else + Tezos_rpc.Directory.register1 + dir + Signer_services.bls_prove_possession + (fun _pkh _override_pk () -> + failwith "Request to prove possession is not allowed.") in let dir = Tezos_rpc.Directory.register0 @@ -107,8 +115,8 @@ let run (cctxt : #Client_context.wallet) ~hosts ?signing_version ?magic_bytes | exn -> fail_with_exn exn) let run_https ~host ~port ~cert ~key ?signing_version ?magic_bytes - ?allow_list_known_keys ~check_high_watermark ~require_auth - (cctxt : #Client_context.wallet) = + ?allow_list_known_keys ?allow_to_prove_possession ~check_high_watermark + ~require_auth (cctxt : #Client_context.wallet) = let open Lwt_syntax in let* points = Lwt_utils_unix.getaddrinfo @@ -130,12 +138,14 @@ let run_https ~host ~port ~cert ~key ?signing_version ?magic_bytes ?signing_version ?magic_bytes ?allow_list_known_keys + ?allow_to_prove_possession ~check_high_watermark ~require_auth mode let run_http ~host ~port ?signing_version ?magic_bytes ?allow_list_known_keys - ~check_high_watermark ~require_auth (cctxt : #Client_context.wallet) = + ?allow_to_prove_possession ~check_high_watermark ~require_auth + (cctxt : #Client_context.wallet) = let open Lwt_syntax in let* points = Lwt_utils_unix.getaddrinfo @@ -155,6 +165,7 @@ let run_http ~host ~port ?signing_version ?magic_bytes ?allow_list_known_keys ?signing_version ?magic_bytes ?allow_list_known_keys + ?allow_to_prove_possession ~check_high_watermark ~require_auth mode diff --git a/src/bin_signer/http_daemon.mli b/src/bin_signer/http_daemon.mli index e765e825cb42c378a7da4fc87efd8e110e75baef..b473a26b05d94edced4535086cbf8dd9ae8faa52 100644 --- a/src/bin_signer/http_daemon.mli +++ b/src/bin_signer/http_daemon.mli @@ -31,6 +31,7 @@ val run_https : ?signing_version:Signature.version -> ?magic_bytes:int list -> ?allow_list_known_keys:bool -> + ?allow_to_prove_possession:bool -> check_high_watermark:bool -> require_auth:bool -> #Client_context.io_wallet -> @@ -42,6 +43,7 @@ val run_http : ?signing_version:Signature.version -> ?magic_bytes:int list -> ?allow_list_known_keys:bool -> + ?allow_to_prove_possession:bool -> check_high_watermark:bool -> require_auth:bool -> #Client_context.io_wallet -> diff --git a/src/bin_signer/main_signer.ml b/src/bin_signer/main_signer.ml index 201a5e84c933db7d362fea20e9600818dd5e01ea..19f6b4b87b761d064ae6a555f5b9cd6794d86276 100644 --- a/src/bin_signer/main_signer.ml +++ b/src/bin_signer/main_signer.ml @@ -105,6 +105,14 @@ let allow_list_known_keys_switch = ~long:"allow-list-known-keys" () +let allow_to_prove_possession_switch = + Tezos_clic.switch + ~doc: + "allow remote request for the proof of possession of a known public key \ + hash" + ~long:"allow-to-prove-possession" + () + let pidfile_arg = Tezos_clic.arg ~doc:"write process id in file" @@ -133,11 +141,12 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list command ~group ~desc:"Launch a signer daemon over a TCP socket." - (args7 + (args8 pidfile_arg magic_bytes_arg high_watermark_switch allow_list_known_keys_switch + allow_to_prove_possession_switch (default_arg ~doc:"listening address or host name" ~short:'a' @@ -170,6 +179,7 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list magic_bytes, check_high_watermark, allow_list_known_keys, + allow_to_prove_possession, host, port, timeout ) @@ -183,6 +193,7 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list ?magic_bytes ?signing_version:signing_version_for_test ~allow_list_known_keys + ~allow_to_prove_possession ~check_high_watermark ~require_auth ~timeout @@ -191,11 +202,12 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list command ~group ~desc:"Launch a signer daemon over a local Unix socket." - (args5 + (args6 pidfile_arg magic_bytes_arg high_watermark_switch allow_list_known_keys_switch + allow_to_prove_possession_switch (default_arg ~doc:"path to the local socket file" ~short:'s' @@ -208,6 +220,7 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list magic_bytes, check_high_watermark, allow_list_known_keys, + allow_to_prove_possession, path ) cctxt -> may_setup_pidfile pidfile @@ fun () -> @@ -219,6 +232,7 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list ?magic_bytes ?signing_version:signing_version_for_test ~allow_list_known_keys + ~allow_to_prove_possession ~check_high_watermark ~require_auth in @@ -226,11 +240,12 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list command ~group ~desc:"Launch a signer daemon over HTTP." - (args6 + (args7 pidfile_arg magic_bytes_arg high_watermark_switch allow_list_known_keys_switch + allow_to_prove_possession_switch (default_arg ~doc:"listening address or host name" ~short:'a' @@ -252,6 +267,7 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list magic_bytes, check_high_watermark, allow_list_known_keys, + allow_to_prove_possession, host, port ) cctxt -> @@ -265,15 +281,17 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list ?signing_version:signing_version_for_test ~check_high_watermark ~allow_list_known_keys + ~allow_to_prove_possession ~require_auth); command ~group ~desc:"Launch a signer daemon over HTTPS." - (args6 + (args7 pidfile_arg magic_bytes_arg high_watermark_switch allow_list_known_keys_switch + allow_to_prove_possession_switch (default_arg ~doc:"listening address or host name" ~short:'a' @@ -310,6 +328,7 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list magic_bytes, check_high_watermark, allow_list_known_keys, + allow_to_prove_possession, host, port ) cert @@ -327,6 +346,7 @@ let commands base_dir require_auth : Client_context.full Tezos_clic.command list ?signing_version:signing_version_for_test ~check_high_watermark ~allow_list_known_keys + ~allow_to_prove_possession ~require_auth); command ~group diff --git a/src/bin_signer/socket_daemon.ml b/src/bin_signer/socket_daemon.ml index 4a5424b309cbb0c44ec29f19364bf2af2b2b8265..4edcb61939f13d92c70cbe1c56a9d0ec0dac16ec 100644 --- a/src/bin_signer/socket_daemon.ml +++ b/src/bin_signer/socket_daemon.ml @@ -27,8 +27,8 @@ open Signer_messages module Events = Signer_events.Socket_daemon let handle_client_step ?signing_version ?magic_bytes ?timeout - ?(allow_list_known_keys = false) ~check_high_watermark ~require_auth cctxt - fd = + ?(allow_list_known_keys = false) ?(allow_to_prove_possession = false) + ~check_high_watermark ~require_auth cctxt fd = let open Lwt_result_syntax in let* recved = Tezos_base_unix.Socket.recv ?timeout fd Request.encoding in match recved with @@ -87,11 +87,16 @@ let handle_client_step ?signing_version ?magic_bytes ?timeout Tezos_base_unix.Socket.send fd encoding res | Bls_prove_possession (pkh, override_pk) -> let encoding = result_encoding Bls_prove_possession.Response.encoding in - let*! res = Handler.bls_prove_possession cctxt ?override_pk pkh in + let*! res = + if allow_to_prove_possession then + Handler.bls_prove_possession cctxt ?override_pk pkh + else failwith "Request to prove possession is not allowed" + in Tezos_base_unix.Socket.send fd encoding res let handle_client_loop ?signing_version ?magic_bytes ?timeout - ?allow_list_known_keys ~check_high_watermark ~require_auth cctxt fd = + ?allow_list_known_keys ?allow_to_prove_possession ~check_high_watermark + ~require_auth cctxt fd = let rec loop () = let open Lwt_result_syntax in let* () = @@ -100,6 +105,7 @@ let handle_client_loop ?signing_version ?magic_bytes ?timeout ?magic_bytes ?timeout ?allow_list_known_keys + ?allow_to_prove_possession ~check_high_watermark ~require_auth cctxt @@ -110,7 +116,8 @@ let handle_client_loop ?signing_version ?magic_bytes ?timeout loop () let run ?signing_version ?magic_bytes ?timeout ?allow_list_known_keys - ~check_high_watermark ~require_auth (cctxt : #Client_context.wallet) path = + ?allow_to_prove_possession ~check_high_watermark ~require_auth + (cctxt : #Client_context.wallet) path = let open Lwt_result_syntax in let open Tezos_base_unix.Socket in let*! () = @@ -144,6 +151,7 @@ let run ?signing_version ?magic_bytes ?timeout ?allow_list_known_keys ?magic_bytes ?timeout ?allow_list_known_keys + ?allow_to_prove_possession ~check_high_watermark ~require_auth cctxt diff --git a/src/bin_signer/socket_daemon.mli b/src/bin_signer/socket_daemon.mli index fa0d94d616045b97fbb5fcb67de4fad0bcdf79a7..9d7866184ed139de397ab91bb6052620088752cb 100644 --- a/src/bin_signer/socket_daemon.mli +++ b/src/bin_signer/socket_daemon.mli @@ -28,6 +28,7 @@ val run : ?magic_bytes:int list -> ?timeout:Time.System.Span.t -> ?allow_list_known_keys:bool -> + ?allow_to_prove_possession:bool -> check_high_watermark:bool -> require_auth:bool -> #Client_context.io_wallet -> diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index 77717b3e628e059028657314369f2eacc3353a27..78664d051428f146814d1f57ace4c3e390257cf5 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -1103,6 +1103,11 @@ let list_known_remote_keys client uri = in return addresses +let spawn_set_consensus_key ?(wait = "none") client ~account ~key = + spawn_command + client + ["--wait"; wait; "set"; "consensus"; "key"; "for"; account; "to"; key] + let gen_and_show_keys ?alias ?sig_alg client = let* alias = gen_keys ?alias ?sig_alg client in show_address ~alias client diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli index 66840e29df652696d1d67d32d4eaca058e7d5811..f669dbd7d96d3da16ed2e1d4b083a412ef997675 100644 --- a/tezt/lib_tezos/client.mli +++ b/tezt/lib_tezos/client.mli @@ -811,6 +811,10 @@ val list_known_remote_keys : t -> Uri.t -> string list Lwt.t exit. *) val spawn_list_known_remote_keys : t -> Uri.t -> Process.t +(** Run [octez-client --wait wait set consensus key for account to key] *) +val spawn_set_consensus_key : + ?wait:string -> t -> account:string -> key:string -> Process.t + (** Run [octez-client gen keys] and return the key alias. The default value for [alias] is a fresh alias of the form [tezt_]. *) diff --git a/tezt/lib_tezos/signer.ml b/tezt/lib_tezos/signer.ml index aa06fe935c8a3736f0f02baf2ef957d40b48e876..057f4f2a45764ccc5c266011fe66c919587d6df2 100644 --- a/tezt/lib_tezos/signer.ml +++ b/tezt/lib_tezos/signer.ml @@ -31,6 +31,7 @@ module Parameters = struct keys : Account.key list; magic_byte : string option; allow_list_known_keys : bool; + allow_to_prove_possession : bool; mutable pending_ready : unit option Lwt.u list; } @@ -94,7 +95,8 @@ let import_secret_key signer (key : Account.key) = spawn_import_secret_key signer key |> Process.check let create ?name ?color ?event_pipe ?base_dir ?uri ?runner ?magic_byte - ?(allow_list_known_keys = false) ?(keys = [Constant.bootstrap1]) () = + ?(allow_list_known_keys = false) ?(allow_to_prove_possession = false) + ?(keys = [Constant.bootstrap1]) () = let name = match name with None -> fresh_name () | Some name -> name in let base_dir = match base_dir with None -> Temp.dir name | Some dir -> dir @@ -117,6 +119,7 @@ let create ?name ?color ?event_pipe ?base_dir ?uri ?runner ?magic_byte pending_ready = []; magic_byte; allow_list_known_keys; + allow_to_prove_possession; } in on_event signer (handle_readiness signer) ; @@ -148,6 +151,11 @@ let run signer = ["--allow-list-known-keys"] else [] in + let allow_to_prove_possession_args = + if signer.persistent_state.allow_to_prove_possession then + ["--allow-to-prove-possession"] + else [] + in let arguments = [ "--base-dir"; @@ -159,6 +167,7 @@ let run signer = host; ] @ port_args @ magic_bytes_args @ allow_list_known_keys_args + @ allow_to_prove_possession_args in let arguments = if !passfile = "" then arguments @@ -189,7 +198,7 @@ let wait_for_ready signer = check_event signer "Signer started." promise let init ?name ?color ?event_pipe ?base_dir ?uri ?runner ?keys ?magic_byte - ?allow_list_known_keys () = + ?allow_list_known_keys ?allow_to_prove_possession () = let* signer = create ?name @@ -201,6 +210,7 @@ let init ?name ?color ?event_pipe ?base_dir ?uri ?runner ?keys ?magic_byte ?keys ?magic_byte ?allow_list_known_keys + ?allow_to_prove_possession () in let* () = run signer in diff --git a/tezt/lib_tezos/signer.mli b/tezt/lib_tezos/signer.mli index 36b7f5258e1f7291c0fbb5a54f2624ba36c0f2ce..fac13272a7b125bbc96809c537bf89800b0734d8 100644 --- a/tezt/lib_tezos/signer.mli +++ b/tezt/lib_tezos/signer.mli @@ -60,6 +60,7 @@ val init : ?keys:Account.key list -> ?magic_byte:string -> ?allow_list_known_keys:bool -> + ?allow_to_prove_possession:bool -> unit -> t Lwt.t diff --git a/tezt/tests/signer_test.ml b/tezt/tests/signer_test.ml index 7a36dff174edb8aa8e0e0ea2e383f44d29b6914c..68b9ac1dfb0602be307b3502fc503d84e50827af 100644 --- a/tezt/tests/signer_test.ml +++ b/tezt/tests/signer_test.ml @@ -123,7 +123,9 @@ let signer_bls_test = ~uses:(fun _ -> [Constant.octez_signer]) @@ fun protocol -> let* _node, client = Client.init_with_protocol `Client ~protocol () in - let* signer = Signer.init ~keys:[Constant.tz4_account] () in + let* signer = + Signer.init ~keys:[Constant.tz4_account] ~allow_to_prove_possession:true () + in let* () = let Account.{alias; public_key_hash; _} = Constant.tz4_account in Client.import_signer_key @@ -190,8 +192,57 @@ let signer_known_remote_keys_test = let pp = Format.(pp_print_list pp_print_string) in Test.fail "@[expected:@,%a@]@,@[found:@,%a@]" pp expected pp found +let signer_prove_possession_test = + Protocol.register_test + ~__FILE__ + ~title:"Prove possession of tz4 test" + ~tags:[team; "signer"; "prove"; "possession"; "keys"] + ~uses:(fun _ -> [Constant.octez_signer]) + @@ fun protocol -> + let* _node, client = Client.init_with_protocol `Client ~protocol () in + let keys = [Constant.tz4_account] in + let alias = "alias_ko" in + let* signer = Signer.init ~keys () in + let* () = + Client.import_signer_key + ~alias + client + ~signer:(Signer.uri signer) + ~public_key_hash:Constant.tz4_account.public_key_hash + in + let process = + Client.spawn_set_consensus_key + client + ~account:Constant.bootstrap1.alias + ~key:alias + in + let* () = + Process.check_error + ~msg:(rex "Request to prove possession is not allowed") + process + in + let alias = "alias_ok" in + let* signer = Signer.init ~keys ~allow_to_prove_possession:true () in + let* () = + Client.import_signer_key + ~force:true + ~alias + client + ~signer:(Signer.uri signer) + ~public_key_hash:Constant.tz4_account.public_key_hash + in + let process = + Client.spawn_set_consensus_key + client + ~account:Constant.bootstrap2.alias + ~key:alias + in + Process.check process + let register ~protocols = signer_simple_test protocols ; signer_magic_bytes_test protocols ; signer_bls_test protocols ; - signer_known_remote_keys_test protocols + signer_known_remote_keys_test protocols ; + signer_prove_possession_test + (List.filter (fun p -> Protocol.number p > 022) protocols)