Signer: only accept B58encoded-pkh as parameters

This commit is contained in:
Grégoire Henry 2018-05-26 12:51:51 +02:00
parent e8fb2bf515
commit 361b3db3e8
10 changed files with 144 additions and 131 deletions

View File

@ -7,29 +7,22 @@
(* *)
(**************************************************************************)
open Signer_messages
let log = Logging.Client.Sign.lwt_log_notice
let sign (cctxt : #Client_context.wallet) key data =
log "Request for signing %d bytes of data for key %s, magic byte = %02X"
let sign (cctxt : #Client_context.wallet) pkh data =
log "Request for signing %d bytes of data for key %a, magic byte = %02X"
(MBytes.length data)
key
Signature.Public_key_hash.pp pkh
(MBytes.get_uint8 data 0) >>= fun () ->
Client_keys.alias_keys cctxt key >>=? function
| None -> failwith "Unknown alias key (%s)" key
| Some (_, _, None) -> failwith "Unknown secret key (%s)" key
| Some (_, _, Some skloc) ->
log "Signing data for key %s" key >>= fun () ->
Client_keys.sign cctxt skloc data >>=? fun signature ->
return { Sign.Response.signature = signature }
Client_keys.get_key cctxt pkh >>=? fun (name, _pkh, sk_uri) ->
log "Signing data for key %s" name >>= fun () ->
Client_keys.sign cctxt sk_uri data >>=? fun signature ->
return signature
let public_key (cctxt : #Client_context.wallet) key =
Client_keys.alias_keys cctxt key >>=? function
| None -> failwith "Unkown alias key (%s)" key
| Some (public_key_hash, _, _) ->
log "Found public key hash %a for key %s"
Signature.Public_key_hash.pp public_key_hash key >>= fun () ->
Client_keys.get_key cctxt public_key_hash >>=? fun (_, public_key, _) ->
log "Found public key for key %s" key >>= fun () ->
return { Public_key.Response.public_key }
let public_key (cctxt : #Client_context.wallet) pkh =
log "Request for public key %a"
Signature.Public_key_hash.pp pkh >>= fun () ->
Client_keys.get_public_key cctxt pkh >>=? fun (name, pk) ->
log "Found public key for hash %a (name: %s)"
Signature.Public_key_hash.pp pkh name >>= fun () ->
return pk

View File

@ -9,18 +9,18 @@
let log = Logging.Client.Sign.lwt_log_notice
let run (cctxt : #Client_context.io_wallet) ~host ~port ~cert ~key =
let run (cctxt : #Client_context.wallet) ~host ~port ~cert ~key =
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.register0 dir Signer_services.sign begin fun () req ->
Handler.sign cctxt req.key req.data
RPC_directory.register1 dir Signer_services.sign begin fun pkh () data ->
Handler.sign cctxt pkh data
end in
let dir =
RPC_directory.register0 dir Signer_services.public_key begin fun () req ->
Handler.public_key cctxt req.key
RPC_directory.register1 dir Signer_services.public_key begin fun pkh () () ->
Handler.public_key cctxt pkh
end in
Lwt.catch
(fun () ->

View File

@ -19,13 +19,13 @@ let run (cctxt : #Client_context.wallet) path =
Lwt_utils_unix.Socket.recv fd Request.encoding >>=? function
| Sign req ->
let encoding = result_encoding Sign.Response.encoding in
Handler.sign cctxt req.key req.data >>= fun res ->
Handler.sign cctxt req.pkh req.data >>= fun res ->
Lwt_utils_unix.Socket.send fd encoding res >>= fun _ ->
Lwt_unix.close fd >>= fun () ->
return ()
| Public_key req ->
| Public_key pkh ->
let encoding = result_encoding Public_key.Response.encoding in
Handler.public_key cctxt req.key >>= fun res ->
Handler.public_key cctxt pkh >>= fun res ->
Lwt_utils_unix.Socket.send fd encoding res >>= fun _ ->
Lwt_unix.close fd >>= fun () ->
return ()

View File

@ -274,6 +274,18 @@ let get_key (cctxt : #Client_context.wallet) pkh =
Signer.public_key pk >>=? fun pk ->
return (n, pk, sk)
let get_public_key (cctxt : #Client_context.wallet) pkh =
Public_key_hash.rev_find cctxt pkh >>=? function
| None -> failwith "no keys for the source contract manager"
| Some n ->
Public_key.find cctxt n >>=? fun pk ->
let scheme = Public_key_locator.scheme pk in
find_signer_for_key cctxt ~scheme >>=? fun signer ->
let module Signer = (val signer : SIGNER) in
Signer.pk_of_locator pk >>=? fun pk ->
Signer.public_key pk >>=? fun pk ->
return (n, pk)
let get_keys (wallet : #Client_context.io_wallet) =
Secret_key.load wallet >>=? fun sks ->
Lwt_list.filter_map_s begin fun (name, sk) ->

View File

@ -150,6 +150,11 @@ val get_key:
Public_key_hash.t ->
(string * Signature.Public_key.t * sk_locator) tzresult Lwt.t
val get_public_key:
#Client_context.io_wallet ->
Public_key_hash.t ->
(string * Signature.Public_key.t) tzresult Lwt.t
val get_keys:
#Client_context.io_wallet ->
(string * Public_key_hash.t * Signature.Public_key.t * sk_locator) list tzresult Lwt.t

View File

@ -10,45 +10,44 @@
open Client_keys
open Signer_messages
let call host port service arg =
RPC_client.call_service
Media_type.all_media_types
~base: (Uri.of_string (Format.asprintf "https://%s:%d" host port))
service () () arg
type path =
| Socket of Lwt_utils_unix.Socket.addr
| Https of string * int
let socket_sign path key data =
let req = { Sign.Request.key = key ; data } in
let socket_sign path pkh data =
let req = { Sign.Request.pkh ; data } in
Lwt_utils_unix.Socket.connect path >>=? fun conn ->
Lwt_utils_unix.Socket.send conn Request.encoding (Request.Sign req) >>=? fun () ->
let encoding = result_encoding Sign.Response.encoding in
Lwt_utils_unix.Socket.recv conn encoding >>=? function
| Error err -> Lwt.return (Error err)
| Ok res -> Lwt_unix.close conn >>= fun () -> return res.signature
Lwt_utils_unix.Socket.recv conn encoding >>=? fun res ->
Lwt_unix.close conn >>= fun () ->
Lwt.return res
let socket_request_public_key path key =
let req = { Public_key.Request.key = key } in
let socket_request_public_key path pkh =
Lwt_utils_unix.Socket.connect path >>=? fun conn ->
Lwt_utils_unix.Socket.send conn Request.encoding (Request.Public_key req) >>=? fun () ->
Lwt_utils_unix.Socket.send conn Request.encoding (Request.Public_key pkh) >>=? fun () ->
let encoding = result_encoding Public_key.Response.encoding in
Lwt_utils_unix.Socket.recv conn encoding >>=? function
| Error err -> Lwt.return (Error err)
| Ok res -> Lwt_unix.close conn >>= fun () -> return res.public_key
Lwt_utils_unix.Socket.recv conn encoding >>=? fun res ->
Lwt_unix.close conn >>= fun () ->
Lwt.return res
let sign path key data = match path with
| Socket path -> socket_sign path key data
let sign path pkh data =
match path with
| Socket path -> socket_sign path pkh data
| Https (host, port) ->
call host port Signer_services.sign { key ; data } >>=? fun res ->
return res.signature
RPC_client.call_service
Media_type.all_media_types
~base: (Uri.of_string (Format.asprintf "https://%s:%d" host port))
Signer_services.sign ((), pkh) () data
let request_public_key path key = match path with
| Socket path -> socket_request_public_key path key
let request_public_key path pkh =
match path with
| Socket path -> socket_request_public_key path pkh
| Https (host, port) ->
call host port Signer_services.public_key { key } >>=? fun res ->
return res.public_key
RPC_client.call_service
Media_type.all_media_types
~base: (Uri.of_string (Format.asprintf "https://%s:%d" host port))
Signer_services.public_key ((), pkh) () ()
module Remote_signer : SIGNER = struct
let scheme = "remote"
@ -70,7 +69,7 @@ module Remote_signer : SIGNER = struct
that get evaluated to default values '$HOME/.tezos-signer-socket', \
localhost and 6732, and can be set later on."
type key_path = path * key
type key_path = path * Signature.Public_key_hash.t
(* secret key is the identifier of the location key identifier *)
type secret_key = key_path
@ -84,18 +83,22 @@ module Remote_signer : SIGNER = struct
let path_of_human_input = function
| "unix" :: key :: [] ->
return (Socket (Unix "$TEZOS_SIGNER_UNIX_PATH"), key)
return (Socket (Unix "$TEZOS_SIGNER_UNIX_PATH"),
Signature.Public_key_hash.of_b58check_exn key)
| "unix" :: file :: key :: [] ->
return (Socket (Unix file), key)
return (Socket (Unix file),
Signature.Public_key_hash.of_b58check_exn key)
| "tcp" :: host :: port :: key :: [] ->
return (Socket (Tcp (host, int_of_string port)), key)
return (Socket (Tcp (host, int_of_string port)),
Signature.Public_key_hash.of_b58check_exn key)
(* Temporary FIXME *)
(* | "tcp" :: host :: key :: [] -> *)
(* return (Socket (Tcp (host, "$TEZOS_SIGNER_TCP_PORT")), key) *)
(* | "tcp" :: key :: [] -> *)
(* return (Socket (Tcp ("$TEZOS_SIGNER_TCP_HOST", "$TEZOS_SIGNER_TCP_PORT")), key) *)
| "https" :: host :: port :: key :: [] ->
return (Https (host, int_of_string port), key)
return (Https (host, int_of_string port),
Signature.Public_key_hash.of_b58check_exn key)
(* Temporary FIXME *)
(* | "https" :: host :: key :: [] -> *)
(* return (Https (host, "$TEZOS_SIGNER_HTTPS_PORT"), key) *)
@ -108,9 +111,9 @@ module Remote_signer : SIGNER = struct
Format.pp_print_text description
let locator_of_path = function
| Socket (Unix path), key -> [ "unix" ; path ; key ]
| Socket (Tcp (host, port)), key -> [ "tcp" ; host ; string_of_int port ; key ]
| Https (host, port), key -> [ "https" ; host ; string_of_int port ; key ]
| Socket (Unix path), key -> [ "unix" ; path ; Signature.Public_key_hash.to_b58check key ]
| Socket (Tcp (host, port)), key -> [ "tcp" ; host ; string_of_int port ; Signature.Public_key_hash.to_b58check key ]
| Https (host, port), key -> [ "https" ; host ; string_of_int port ; Signature.Public_key_hash.to_b58check key ]
let pk_locator_of_human_input _cctxt path =
path_of_human_input path >>=? fun pk ->

View File

@ -7,7 +7,7 @@
(* *)
(**************************************************************************)
type error += Unkwnon_alias_key of string
type error += Unknown_alias_key of string
let () =
register_error_kind `Permanent
@ -17,84 +17,85 @@ let () =
~pp: (fun ppf s ->
Format.fprintf ppf "The key %s does not is not known on the remote signer" s)
Data_encoding.(obj1 (req "value" string))
(function Unkwnon_alias_key s -> Some s | _ -> None)
(fun s -> Unkwnon_alias_key s)
type key = string
(function Unknown_alias_key s -> Some s | _ -> None)
(fun s -> Unknown_alias_key s)
module Sign = struct
module Request = struct
type t = {
key : key ;
pkh: Signature.Public_key_hash.t ;
data: MBytes.t ;
}
let encoding =
let open Data_encoding in
conv
(fun { key ; data } ->
( key, data))
(fun (key, data) ->
{ key ; data })
(fun { pkh ; data } ->
(pkh, data))
(fun (pkh, data) ->
{ pkh ; data })
(obj2
(req "key" string)
(req "pkh" Signature.Public_key_hash.encoding)
(req "data" bytes))
end
module Response = struct
type t = {
signature : Signature.t
}
type t = Signature.t
let encoding =
let open Data_encoding in
conv
(fun { signature } -> (signature))
(fun (signature) -> { signature })
(obj1 (req "signature" Signature.encoding))
Data_encoding.(obj1 (req "signature" Signature.encoding))
end
end
module Public_key = struct
module Request = struct
type t = {
key : key ;
}
type t = Signature.Public_key_hash.t
let encoding =
let open Data_encoding in
conv
(fun { key } -> key)
(fun key -> { key })
(obj1 (req "key" string))
Data_encoding.(obj1 (req "pkh" Signature.Public_key_hash.encoding))
end
module Response = struct
type t = {
public_key : Signature.Public_key.t ;
}
type t = Signature.Public_key.t
let encoding =
let open Data_encoding in
conv
(fun { public_key } -> public_key)
(fun public_key -> { public_key })
(obj1 (req "pubkey" Signature.Public_key.encoding))
Data_encoding.(obj1 (req "pubkey" Signature.Public_key.encoding))
end
end
module Request = struct
type t =
| Sign of Sign.Request.t
| Public_key of Public_key.Request.t
let encoding =
let open Data_encoding in
union
[ case (Tag 0) (merge_objs (obj1 (req "kind" (constant "sign"))) Sign.Request.encoding)
(function Sign req -> Some ((), req) | _ -> None)
(fun ((), req) -> Sign req) ;
case (Tag 1) (merge_objs (obj1 (req "kind" (constant "public_key"))) Public_key.Request.encoding)
(function Public_key req -> Some ((), req) | _ -> None)
(fun ((), req) -> Public_key req) ]
union [
case (Tag 0)
(merge_objs
(obj1 (req "kind" (constant "sign")))
Sign.Request.encoding)
(function Sign req -> Some ((), req) | _ -> None)
(fun ((), req) -> Sign req) ;
case (Tag 1)
(merge_objs
(obj1 (req "kind" (constant "public_key")))
Public_key.Request.encoding)
(function Public_key req -> Some ((), req) | _ -> None)
(fun ((), req) -> Public_key req) ;
]
end

View File

@ -7,44 +7,44 @@
(* *)
(**************************************************************************)
type error += Unkwnon_alias_key of string
type key = string
type error += Unknown_alias_key of string
module Sign : sig
module Request : sig
type t = {
key : key ;
pkh: Signature.Public_key_hash.t ;
data: MBytes.t ;
}
val encoding : t Data_encoding.t
end
module Response : sig
type t = {
signature : Signature.t ;
}
type t = Signature.t
val encoding : t Data_encoding.t
end
end
module Public_key : sig
module Request : sig
type t = {
key : key ;
}
type t = Signature.Public_key_hash.t
val encoding : t Data_encoding.t
end
module Response : sig
type t = {
public_key : Signature.Public_key.t ;
}
type t = Signature.Public_key.t
val encoding : t Data_encoding.t
end
end
module Request : sig
type t =
| Sign of Sign.Request.t
| Public_key of Public_key.Request.t
val encoding : t Data_encoding.t
end

View File

@ -7,18 +7,17 @@
(* *)
(**************************************************************************)
open Signer_messages
let sign = RPC_service.post_service
let sign =
RPC_service.post_service
~description: "Sign a piece of data with a given remote key"
~query: RPC_query.empty
~input: Sign.Request.encoding
~output: Sign.Response.encoding
RPC_path.(root / "sign")
~input: Data_encoding.bytes
~output: Data_encoding.(obj1 (req "signature" Signature.encoding))
RPC_path.(root /: Signature.Public_key_hash.rpc_arg)
let public_key = RPC_service.post_service
let public_key =
RPC_service.get_service
~description: "Retrieve the public key of a given remote key"
~query: RPC_query.empty
~input: Public_key.Request.encoding
~output: Public_key.Response.encoding
RPC_path.(root / "public_key")
~output: Data_encoding.(obj1 (req "public_key" Signature.Public_key.encoding))
RPC_path.(root /: Signature.Public_key_hash.rpc_arg)

View File

@ -7,10 +7,10 @@
(* *)
(**************************************************************************)
open Signer_messages
val sign :
([ `POST ], unit, unit, unit, Sign.Request.t, Sign.Response.t) RPC_service.t
([ `POST ], unit, unit * Signature.Public_key_hash.t,
unit, MBytes.t, Signature.t) RPC_service.t
val public_key :
([ `POST ], unit, unit, unit, Public_key.Request.t, Public_key.Response.t) RPC_service.t
([ `GET ], unit, unit * Signature.Public_key_hash.t,
unit, unit, Signature.Public_key.t) RPC_service.t