Prompt for key validation from Ledger (importing)

This commit is contained in:
Sebastien Mondet 2018-10-23 21:49:34 -04:00 committed by Grégoire Henry
parent d3cdfca8e4
commit 2cd1be9ee9
No known key found for this signature in database
GPG Key ID: 50D984F20BD445D2
8 changed files with 66 additions and 32 deletions

View File

@ -144,8 +144,12 @@ module type SIGNER = sig
val title : string val title : string
val description : string val description : string
val neuterize : sk_uri -> pk_uri tzresult Lwt.t val neuterize : sk_uri -> pk_uri tzresult Lwt.t
val public_key : pk_uri -> Signature.Public_key.t tzresult Lwt.t val public_key :
val public_key_hash : pk_uri -> (Signature.Public_key_hash.t * Signature.Public_key.t option) tzresult Lwt.t ?interactive: Client_context.io_wallet ->
pk_uri -> Signature.Public_key.t tzresult Lwt.t
val public_key_hash :
?interactive: Client_context.io_wallet ->
pk_uri -> (Signature.Public_key_hash.t * Signature.Public_key.t option) tzresult Lwt.t
val sign : val sign :
?watermark: Signature.watermark -> ?watermark: Signature.watermark ->
sk_uri -> MBytes.t -> Signature.t tzresult Lwt.t sk_uri -> MBytes.t -> Signature.t tzresult Lwt.t
@ -188,14 +192,14 @@ let neuterize sk_uri =
let module Signer = (val signer : SIGNER) in let module Signer = (val signer : SIGNER) in
Signer.neuterize sk_uri Signer.neuterize sk_uri
let public_key pk_uri = let public_key ?interactive pk_uri =
let scheme = Option.unopt ~default:"" (Uri.scheme pk_uri) in let scheme = Option.unopt ~default:"" (Uri.scheme pk_uri) in
find_signer_for_key ~scheme >>=? fun signer -> find_signer_for_key ~scheme >>=? fun signer ->
let module Signer = (val signer : SIGNER) in let module Signer = (val signer : SIGNER) in
Signer.public_key pk_uri Signer.public_key ?interactive pk_uri
let public_key_hash pk_uri = let public_key_hash ?interactive pk_uri =
public_key pk_uri >>=? fun pk -> public_key ?interactive pk_uri >>=? fun pk ->
return (Signature.Public_key.hash pk, Some pk) return (Signature.Public_key.hash pk, Some pk)
let sign cctxt ?watermark sk_uri buf = let sign cctxt ?watermark sk_uri buf =

View File

@ -67,13 +67,25 @@ module type SIGNER = sig
val neuterize : sk_uri -> pk_uri tzresult Lwt.t val neuterize : sk_uri -> pk_uri tzresult Lwt.t
(** [neuterize sk] is the corresponding [pk]. *) (** [neuterize sk] is the corresponding [pk]. *)
val public_key : pk_uri -> Signature.Public_key.t tzresult Lwt.t val public_key :
(** [public_key pk] is the Ed25519 version of [pk]. *) ?interactive: Client_context.io_wallet ->
pk_uri -> Signature.Public_key.t tzresult Lwt.t
(** [public_key pk] is the Ed25519 version of [pk].
val public_key_hash : pk_uri -> (Signature.Public_key_hash.t * Signature.Public_key.t option) tzresult Lwt.t Some signer implementations improve long-term security by
requiring human/manual validation while importing keys, the
[?interactive] argument can be used to prompt the user in such
case. *)
val public_key_hash :
?interactive: Client_context.io_wallet ->
pk_uri ->
(Signature.Public_key_hash.t * Signature.Public_key.t option) tzresult Lwt.t
(** [public_key_hash pk] is the hash of [pk]. (** [public_key_hash pk] is the hash of [pk].
As some signers will query the full public key to obtain the hash, As some signers will query the full public key to obtain the hash,
it can be optionally returned to reduce the amount of queries. *) it can be optionally returned to reduce the amount of queries.
See {!public_key} for the [?interactive] argument. *)
val sign : val sign :
?watermark: Signature.watermark -> ?watermark: Signature.watermark ->
@ -89,9 +101,13 @@ val register_signer : (module SIGNER) -> unit
val registered_signers : unit -> (string * (module SIGNER)) list val registered_signers : unit -> (string * (module SIGNER)) list
val public_key : pk_uri -> Signature.Public_key.t tzresult Lwt.t val public_key :
?interactive: Client_context.io_wallet ->
pk_uri -> Signature.Public_key.t tzresult Lwt.t
val public_key_hash : pk_uri -> (Signature.Public_key_hash.t * Signature.Public_key.t option) tzresult Lwt.t val public_key_hash :
?interactive: Client_context.io_wallet ->
pk_uri -> (Signature.Public_key_hash.t * Signature.Public_key.t option) tzresult Lwt.t
val neuterize : sk_uri -> pk_uri tzresult Lwt.t val neuterize : sk_uri -> pk_uri tzresult Lwt.t

View File

@ -290,7 +290,8 @@ let commands version : Client_context.io_wallet Clic.command list =
"public and secret keys '%s' don't correspond, \ "public and secret keys '%s' don't correspond, \
please don't use --force" name) please don't use --force" name)
end >>=? fun () -> end >>=? fun () ->
Client_keys.public_key_hash pk_uri >>=? fun (pkh, public_key) -> Client_keys.public_key_hash ~interactive:cctxt pk_uri
>>=? fun (pkh, public_key) ->
cctxt#message cctxt#message
"Tezos address added: %a" "Tezos address added: %a"
Signature.Public_key_hash.pp pkh >>= fun () -> Signature.Public_key_hash.pp pkh >>= fun () ->

View File

@ -85,7 +85,7 @@ module Make(N : sig val scheme : string end) = struct
Lwt.return (Signature.Public_key_hash.of_b58check pkh) >>=? fun pkh -> Lwt.return (Signature.Public_key_hash.of_b58check pkh) >>=? fun pkh ->
return (base, pkh) return (base, pkh)
let public_key uri = let public_key ?interactive:_ uri =
parse (uri : pk_uri :> Uri.t) >>=? fun (base, pkh) -> parse (uri : pk_uri :> Uri.t) >>=? fun (base, pkh) ->
RPC_client.call_service RPC_client.call_service
~logger: P.logger ~logger: P.logger
@ -96,8 +96,8 @@ module Make(N : sig val scheme : string end) = struct
let neuterize uri = let neuterize uri =
return (Client_keys.make_pk_uri (uri : sk_uri :> Uri.t)) return (Client_keys.make_pk_uri (uri : sk_uri :> Uri.t))
let public_key_hash uri = let public_key_hash ?interactive uri =
public_key uri >>=? fun pk -> public_key ?interactive uri >>=? fun pk ->
return (Signature.Public_key.hash pk, Some pk) return (Signature.Public_key.hash pk, Some pk)
let sign ?watermark uri msg = let sign ?watermark uri msg =

View File

@ -362,7 +362,8 @@ let path_of_pk_uri (uri : pk_uri) =
List.map int32_of_path_element_exn path List.map int32_of_path_element_exn path
| path -> List.map int32_of_path_element_exn path | path -> List.map int32_of_path_element_exn path
let public_key (pk_uri : pk_uri) = let public_key
?(interactive : Client_context.io_wallet option) (pk_uri : pk_uri) =
let find_ledger of_pkh = function let find_ledger of_pkh = function
| Pkh pkh -> snd (List.assoc pkh of_pkh) | Pkh pkh -> snd (List.assoc pkh of_pkh)
| Animals (_, curve) -> curve | Animals (_, curve) -> curve
@ -374,7 +375,19 @@ let public_key (pk_uri : pk_uri) =
with_ledger id begin fun ledger _version _of_curve of_pkh -> with_ledger id begin fun ledger _version _of_curve of_pkh ->
let curve = find_ledger of_pkh id in let curve = find_ledger of_pkh id in
let path = path_of_pk_uri pk_uri in let path = path_of_pk_uri pk_uri in
get_public_key ledger curve path >>=? fun pk -> begin
match interactive with
| Some cctxt ->
get_public_key ~prompt:false ledger curve path >>=? fun pk ->
let pkh = Signature.Public_key.hash pk in
cctxt#message
"Please validate@ (and write down)@ the public key hash\
@ displayed@ on the Ledger,@ it should be equal@ to `%a`:"
Signature.Public_key_hash.pp pkh >>= fun () ->
get_public_key ~prompt:true ledger curve path
| None ->
get_public_key ~prompt:false ledger curve path
end >>=? fun pk ->
let pkh = Signature.Public_key.hash pk in let pkh = Signature.Public_key.hash pk in
Hashtbl.replace pks pk_uri pk ; Hashtbl.replace pks pk_uri pk ;
Hashtbl.replace pkhs pk_uri pkh ; Hashtbl.replace pkhs pk_uri pkh ;
@ -383,11 +396,11 @@ let public_key (pk_uri : pk_uri) =
| Error err -> failwith "%a" pp_print_error err | Error err -> failwith "%a" pp_print_error err
| Ok v -> return v | Ok v -> return v
let public_key_hash pk_uri = let public_key_hash ?interactive pk_uri =
match Hashtbl.find_opt pkhs pk_uri with match Hashtbl.find_opt pkhs pk_uri with
| Some pkh -> return (pkh, None) | Some pkh -> return (pkh, None)
| None -> | None ->
public_key pk_uri >>=? fun pk -> public_key ?interactive pk_uri >>=? fun pk ->
return (Hashtbl.find pkhs pk_uri, Some pk) return (Hashtbl.find pkhs pk_uri, Some pk)
let curve_of_id = function let curve_of_id = function

View File

@ -80,12 +80,12 @@ module Make(S : sig
| path -> Uri.with_path S.default (path ^ "/" ^ key)) | path -> Uri.with_path S.default (path ^ "/" ^ key))
| _ -> assert false | _ -> assert false
let public_key pk_uri = let public_key ?interactive pk_uri =
Remote.public_key Remote.public_key ?interactive
(Client_keys.make_pk_uri (key (pk_uri : pk_uri :> Uri.t))) (Client_keys.make_pk_uri (key (pk_uri : pk_uri :> Uri.t)))
let public_key_hash pk_uri = let public_key_hash ?interactive pk_uri =
Remote.public_key_hash Remote.public_key_hash ?interactive
(Client_keys.make_pk_uri (key (pk_uri : pk_uri :> Uri.t))) (Client_keys.make_pk_uri (key (pk_uri : pk_uri :> Uri.t)))
let neuterize sk_uri = let neuterize sk_uri =

View File

@ -93,14 +93,14 @@ module Make(P : sig
Lwt.return (Signature.Public_key_hash.of_b58check key) >>=? fun key -> Lwt.return (Signature.Public_key_hash.of_b58check key) >>=? fun key ->
return (Lwt_utils_unix.Socket.Unix (Uri.path uri), key) return (Lwt_utils_unix.Socket.Unix (Uri.path uri), key)
let public_key uri = let public_key ?interactive:(_) uri =
parse (uri : pk_uri :> Uri.t) >>=? fun (path, pkh) -> parse (uri : pk_uri :> Uri.t) >>=? fun (path, pkh) ->
public_key path pkh public_key path pkh
let neuterize uri = let neuterize uri =
return (Client_keys.make_pk_uri (uri : sk_uri :> Uri.t)) return (Client_keys.make_pk_uri (uri : sk_uri :> Uri.t))
let public_key_hash uri = let public_key_hash ?interactive:(_) uri =
public_key uri >>=? fun pk -> public_key uri >>=? fun pk ->
return (Signature.Public_key.hash pk, Some pk) return (Signature.Public_key.hash pk, Some pk)
@ -139,15 +139,15 @@ module Make(P : sig
return (Lwt_utils_unix.Socket.Tcp (path, string_of_int port, return (Lwt_utils_unix.Socket.Tcp (path, string_of_int port,
[Lwt_unix.AI_SOCKTYPE SOCK_STREAM]), pkh) [Lwt_unix.AI_SOCKTYPE SOCK_STREAM]), pkh)
let public_key uri = let public_key ?interactive:(_) uri =
parse (uri : pk_uri :> Uri.t) >>=? fun (path, pkh) -> parse (uri : pk_uri :> Uri.t) >>=? fun (path, pkh) ->
public_key path pkh public_key path pkh
let neuterize uri = let neuterize uri =
return (Client_keys.make_pk_uri (uri : sk_uri :> Uri.t)) return (Client_keys.make_pk_uri (uri : sk_uri :> Uri.t))
let public_key_hash uri = let public_key_hash ?interactive uri =
public_key uri >>=? fun pk -> public_key ?interactive uri >>=? fun pk ->
return (Signature.Public_key.hash pk, Some pk) return (Signature.Public_key.hash pk, Some pk)
let sign ?watermark uri msg = let sign ?watermark uri msg =

View File

@ -47,7 +47,7 @@ let make_sk sk =
Client_keys.make_sk_uri Client_keys.make_sk_uri
(Uri.make ~scheme ~path:(Signature.Secret_key.to_b58check sk) ()) (Uri.make ~scheme ~path:(Signature.Secret_key.to_b58check sk) ())
let public_key pk_uri = let public_key ?interactive:(_) pk_uri =
Lwt.return Lwt.return
(Signature.Public_key.of_b58check (Uri.path (pk_uri : pk_uri :> Uri.t))) (Signature.Public_key.of_b58check (Uri.path (pk_uri : pk_uri :> Uri.t)))
@ -59,8 +59,8 @@ let neuterize sk_uri =
secret_key sk_uri >>=? fun sk -> secret_key sk_uri >>=? fun sk ->
return (make_pk (Signature.Secret_key.to_public_key sk)) return (make_pk (Signature.Secret_key.to_public_key sk))
let public_key_hash pk_uri = let public_key_hash ?interactive pk_uri =
public_key pk_uri >>=? fun pk -> public_key ?interactive pk_uri >>=? fun pk ->
return (Signature.Public_key.hash pk, Some pk) return (Signature.Public_key.hash pk, Some pk)
let sign ?watermark sk_uri buf = let sign ?watermark sk_uri buf =