diff --git a/src/bin_signer/handler.ml b/src/bin_signer/handler.ml index b302bf68c..1f0849591 100644 --- a/src/bin_signer/handler.ml +++ b/src/bin_signer/handler.ml @@ -17,13 +17,26 @@ module Authorized_key = let of_source t = Lwt.return (of_b58check t) end) +let check_magic_byte magic_bytes data = + match magic_bytes with + | None -> return () + | Some magic_bytes -> + let byte = MBytes.get_uint8 data 0 in + if MBytes.length data > 1 + && (List.mem byte magic_bytes) then + return () + else + failwith "magic byte 0x%02X not allowed" byte + let sign (cctxt : #Client_context.wallet) - Signer_messages.Sign.Request.{ pkh ; data ; signature } ~require_auth = + Signer_messages.Sign.Request.{ pkh ; data ; signature } + ?magic_bytes ~require_auth = log "Request for signing %d bytes of data for key %a, magic byte = %02X" (MBytes.length data) Signature.Public_key_hash.pp pkh (MBytes.get_uint8 data 0) >>= fun () -> + check_magic_byte magic_bytes data >>=? fun () -> begin match require_auth, signature with | false, _ -> return () | true, None -> failwith "missing authentication signature field" diff --git a/src/bin_signer/https_daemon.ml b/src/bin_signer/https_daemon.ml index 4ac868139..6e40562eb 100644 --- a/src/bin_signer/https_daemon.ml +++ b/src/bin_signer/https_daemon.ml @@ -9,14 +9,14 @@ let log = Signer_logging.lwt_log_notice -let run (cctxt : #Client_context.wallet) ~host ~port ~cert ~key ~require_auth = +let run (cctxt : #Client_context.wallet) ~host ~port ~cert ~key ?magic_bytes ~require_auth = log "Accepting HTTPS requests on port %d" port >>= fun () -> let mode : Conduit_lwt_unix.server = `TLS (`Crt_file_path cert, `Key_file_path key, `No_password, `Port port) in let dir = RPC_directory.empty in let dir = RPC_directory.register1 dir Signer_services.sign begin fun pkh signature data -> - Handler.sign cctxt { pkh ; data ; signature } ~require_auth + Handler.sign cctxt { pkh ; data ; signature } ?magic_bytes ~require_auth end in let dir = RPC_directory.register1 dir Signer_services.public_key begin fun pkh () () -> diff --git a/src/bin_signer/https_daemon.mli b/src/bin_signer/https_daemon.mli index 22d6eebad..436ae30c0 100644 --- a/src/bin_signer/https_daemon.mli +++ b/src/bin_signer/https_daemon.mli @@ -10,5 +10,6 @@ val run: #Client_context.io_wallet -> host:string -> port:int -> cert:string -> key:string -> + ?magic_bytes: int list -> require_auth: bool -> 'a tzresult Lwt.t diff --git a/src/bin_signer/main_signer.ml b/src/bin_signer/main_signer.ml index 2c8d1a7a1..6fc1ca829 100644 --- a/src/bin_signer/main_signer.ml +++ b/src/bin_signer/main_signer.ml @@ -38,11 +38,30 @@ let group = { Clic.name = "signer" ; title = "Commands specific to the signing daemon" } +let magic_bytes_arg = + Clic.arg + ~doc: "values allowed for the magic bytes, defaults to any" + ~short: 'M' + ~long: "magic-bytes" + ~placeholder: "0xHH,0xHH,..." + (Clic.parameter (fun _ s -> + try + return + (List.map + (fun s -> + let b = int_of_string s in + if b < 0 || b > 255 then raise Exit else b) + (String.split ',' s)) + with _ -> + failwith "Bad format for magic bytes, a series of numbers \ + is expected, separated by commas.")) + let commands base_dir require_auth = Client_keys_commands.commands () @ [ command ~group ~desc: "Launch a signer daemon over a TCP socket." - (args2 + (args3 + magic_bytes_arg (default_arg ~doc: "listening address or host name" ~short: 'a' @@ -61,12 +80,13 @@ let commands base_dir require_auth = try return (int_of_string x) with Failure _ -> failwith "Invalid port %s" x)))) (prefixes [ "launch" ; "socket" ; "signer" ] @@ stop) - (fun (host, port) cctxt -> + (fun (magic_bytes, host, port) cctxt -> Tezos_signer_backends.Encrypted.decrypt_all cctxt >>=? fun () -> - Socket_daemon.run cctxt (Tcp (host, port)) ~require_auth) ; + Socket_daemon.run cctxt (Tcp (host, port)) ?magic_bytes ~require_auth) ; command ~group ~desc: "Launch a signer daemon over a local Unix socket." - (args1 + (args2 + magic_bytes_arg (default_arg ~doc: "path to the local socket file" ~short: 's' @@ -75,12 +95,13 @@ let commands base_dir require_auth = ~default: (Filename.concat base_dir "socket") (parameter (fun _ s -> return s)))) (prefixes [ "launch" ; "local" ; "signer" ] @@ stop) - (fun path cctxt -> + (fun (magic_bytes, path) cctxt -> Tezos_signer_backends.Encrypted.decrypt_all cctxt >>=? fun () -> - Socket_daemon.run cctxt (Unix path) ~require_auth) ; + Socket_daemon.run cctxt (Unix path) ?magic_bytes ~require_auth) ; command ~group ~desc: "Launch a signer daemon over HTTPS." - (args2 + (args3 + magic_bytes_arg (default_arg ~doc: "listening address or host name" ~short: 'a' @@ -107,9 +128,9 @@ let commands base_dir require_auth = ~name:"key" ~desc: "path to th TLS key" (parameter (fun _ s -> return s)) @@ stop) - (fun (host, port) cert key cctxt -> + (fun (magic_bytes, host, port) cert key cctxt -> Tezos_signer_backends.Encrypted.decrypt_all cctxt >>=? fun () -> - Https_daemon.run cctxt ~host ~port ~cert ~key ~require_auth) ; + Https_daemon.run cctxt ~host ~port ~cert ~key ?magic_bytes ~require_auth) ; command ~group ~desc: "Authorize a given public key to perform signing requests." (args1 diff --git a/src/bin_signer/socket_daemon.ml b/src/bin_signer/socket_daemon.ml index cb91cf20a..f5d77e632 100644 --- a/src/bin_signer/socket_daemon.ml +++ b/src/bin_signer/socket_daemon.ml @@ -11,7 +11,7 @@ open Signer_messages let log = Signer_logging.lwt_log_notice -let run (cctxt : #Client_context.wallet) path ~require_auth = +let run (cctxt : #Client_context.wallet) path ?magic_bytes ~require_auth = Lwt_utils_unix.Socket.bind path >>=? fun fd -> let rec loop () = Lwt_unix.accept fd >>= fun (fd, _) -> @@ -19,7 +19,7 @@ let run (cctxt : #Client_context.wallet) path ~require_auth = Lwt_utils_unix.Socket.recv fd Request.encoding >>=? function | Sign req -> let encoding = result_encoding Sign.Response.encoding in - Handler.sign cctxt req ~require_auth >>= fun res -> + Handler.sign cctxt req ?magic_bytes ~require_auth >>= fun res -> Lwt_utils_unix.Socket.send fd encoding res >>= fun _ -> Lwt_unix.close fd >>= fun () -> return () diff --git a/src/bin_signer/socket_daemon.mli b/src/bin_signer/socket_daemon.mli index a7e330fcb..46ceafea0 100644 --- a/src/bin_signer/socket_daemon.mli +++ b/src/bin_signer/socket_daemon.mli @@ -10,5 +10,6 @@ val run: #Client_context.io_wallet -> Lwt_utils_unix.Socket.addr -> + ?magic_bytes: int list -> require_auth: bool -> 'a tzresult Lwt.t