Client, wallet: Change type of location
This commit is contained in:
parent
cfe82ab7cf
commit
8b9d02eec4
@ -8,6 +8,7 @@
|
||||
(**************************************************************************)
|
||||
|
||||
type error += Unregistered_key_scheme of string
|
||||
|
||||
let () =
|
||||
register_error_kind `Permanent
|
||||
~id: "cli.unregistered_key_scheme"
|
||||
@ -29,19 +30,21 @@ module Public_key_hash = Client_aliases.Alias (struct
|
||||
let name = "public key hash"
|
||||
end)
|
||||
|
||||
type location = string list
|
||||
|
||||
module type LOCATOR = sig
|
||||
val name : string
|
||||
type t
|
||||
|
||||
val create : scheme:string -> location:string -> t
|
||||
val create : scheme:string -> location:location -> t
|
||||
val scheme : t -> string
|
||||
val location : t -> string
|
||||
val location : t -> location
|
||||
val to_string : t -> string
|
||||
val pp : Format.formatter -> t -> unit
|
||||
end
|
||||
|
||||
type sk_locator = Sk_locator of { scheme : string ; location : string }
|
||||
type pk_locator = Pk_locator of { scheme : string ; location : string }
|
||||
type sk_locator = Sk_locator of { scheme : string ; location : location }
|
||||
type pk_locator = Pk_locator of { scheme : string ; location : location }
|
||||
|
||||
module Sk_locator = struct
|
||||
let name = "secret key"
|
||||
@ -54,10 +57,10 @@ module Sk_locator = struct
|
||||
let location (Sk_locator { location }) = location
|
||||
|
||||
let to_string (Sk_locator { scheme ; location }) =
|
||||
scheme ^ ":" ^ location
|
||||
String.concat "/" ((scheme ^ ":") :: List.map Uri.pct_encode location)
|
||||
|
||||
let pp ppf (Sk_locator { scheme ; location }) =
|
||||
Format.pp_print_string ppf (scheme ^ ":" ^ location)
|
||||
let pp ppf loc =
|
||||
Format.pp_print_string ppf (to_string loc)
|
||||
end
|
||||
|
||||
module Pk_locator = struct
|
||||
@ -71,10 +74,10 @@ module Pk_locator = struct
|
||||
let location (Pk_locator { location }) = location
|
||||
|
||||
let to_string (Pk_locator { scheme ; location }) =
|
||||
scheme ^ ":" ^ location
|
||||
String.concat "/" ((scheme ^ ":") :: List.map Uri.pct_encode location)
|
||||
|
||||
let pp ppf (Pk_locator { scheme ; location }) =
|
||||
Format.pp_print_string ppf (scheme ^ ":" ^ location)
|
||||
let pp ppf loc =
|
||||
Format.pp_print_string ppf (to_string loc)
|
||||
end
|
||||
|
||||
module type KEY = sig
|
||||
@ -88,7 +91,7 @@ module Locator (K : KEY) (L : LOCATOR) = struct
|
||||
|
||||
let of_unencrypted k =
|
||||
L.create ~scheme:"unencrypted"
|
||||
~location:(K.to_b58check k)
|
||||
~location:[K.to_b58check k]
|
||||
|
||||
let of_string s =
|
||||
match String.index s ':' with
|
||||
@ -96,9 +99,13 @@ module Locator (K : KEY) (L : LOCATOR) = struct
|
||||
of_unencrypted (K.of_b58check_exn s)
|
||||
| i ->
|
||||
let len = String.length s in
|
||||
create
|
||||
~scheme:(String.sub s 0 i)
|
||||
~location:(String.sub s (i+1) (len-i-1))
|
||||
let scheme = String.sub s 0 i in
|
||||
let location =
|
||||
String.sub s (i+1) (len-i-1) |>
|
||||
String.split '/' |>
|
||||
List.map Uri.pct_decode |>
|
||||
List.filter ((<>) "") in
|
||||
create ~scheme ~location
|
||||
|
||||
let of_source s = return (of_string s)
|
||||
let to_source t = return (to_string t)
|
||||
@ -125,8 +132,8 @@ module type SIGNER = sig
|
||||
val sk_to_locator : secret_key -> sk_locator Lwt.t
|
||||
val pk_to_locator : public_key -> pk_locator Lwt.t
|
||||
val neuterize : secret_key -> public_key Lwt.t
|
||||
val public_key : public_key -> Signature.Public_key.t Lwt.t
|
||||
val public_key_hash : public_key -> Signature.Public_key_hash.t Lwt.t
|
||||
val public_key : public_key -> Signature.Public_key.t tzresult Lwt.t
|
||||
val public_key_hash : public_key -> Signature.Public_key_hash.t tzresult Lwt.t
|
||||
val sign :
|
||||
?watermark: Signature.watermark ->
|
||||
secret_key -> MBytes.t -> Signature.t tzresult Lwt.t
|
||||
@ -140,7 +147,8 @@ let register_signer signer =
|
||||
|
||||
let find_signer_for_key cctxt ~scheme =
|
||||
match Hashtbl.find signers_table scheme with
|
||||
| exception Not_found -> fail (Unregistered_key_scheme scheme)
|
||||
| exception Not_found ->
|
||||
fail (Unregistered_key_scheme scheme)
|
||||
| signer, false ->
|
||||
let module Signer = (val signer : SIGNER) in
|
||||
Signer.init cctxt >>=? fun () ->
|
||||
@ -151,11 +159,33 @@ let find_signer_for_key cctxt ~scheme =
|
||||
let registered_signers () : (string * (module SIGNER)) list =
|
||||
Hashtbl.fold (fun k (v, _) acc -> (k, v) :: acc) signers_table []
|
||||
|
||||
type error += Signature_mismatch of Secret_key_locator.t
|
||||
|
||||
let () =
|
||||
register_error_kind `Permanent
|
||||
~id: "cli.signature_mismatch"
|
||||
~title: "Signature mismatch"
|
||||
~description: "The signer produced an invalid signature"
|
||||
~pp:
|
||||
(fun ppf sk ->
|
||||
Format.fprintf ppf
|
||||
"The signer for %a produced an invalid signature"
|
||||
Secret_key_locator.pp sk)
|
||||
Data_encoding.(obj1 (req "locator" Secret_key_locator.encoding))
|
||||
(function Signature_mismatch sk -> Some sk | _ -> None)
|
||||
(fun sk -> Signature_mismatch sk)
|
||||
|
||||
let sign ?watermark cctxt ((Sk_locator { scheme }) as skloc) buf =
|
||||
find_signer_for_key cctxt ~scheme >>=? fun signer ->
|
||||
let module Signer = (val signer : SIGNER) in
|
||||
Signer.sk_of_locator skloc >>=? fun t ->
|
||||
Signer.sign ?watermark t buf
|
||||
Signer.sign ?watermark t buf >>=? fun signature ->
|
||||
Signer.neuterize t >>= fun pk ->
|
||||
Signer.public_key pk >>=? fun pubkey ->
|
||||
fail_unless
|
||||
(Signature.check pubkey signature buf)
|
||||
(Signature_mismatch skloc) >>=? fun () ->
|
||||
return signature
|
||||
|
||||
let append ?watermark cctxt loc buf =
|
||||
sign ?watermark cctxt loc buf >>|? fun signature ->
|
||||
@ -241,7 +271,7 @@ let get_key (cctxt : #Client_context.wallet) pkh =
|
||||
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 ->
|
||||
Signer.public_key pk >>=? fun pk ->
|
||||
return (n, pk, sk)
|
||||
|
||||
let get_keys (wallet : #Client_context.io_wallet) =
|
||||
@ -254,7 +284,7 @@ let get_keys (wallet : #Client_context.io_wallet) =
|
||||
find_signer_for_key wallet ~scheme >>=? fun signer ->
|
||||
let module Signer = (val signer : SIGNER) in
|
||||
Signer.pk_of_locator pk >>=? fun pk ->
|
||||
Signer.public_key pk >>= fun pk ->
|
||||
Signer.public_key pk >>=? fun pk ->
|
||||
return (name, pkh, pk, sk)
|
||||
end >>= function
|
||||
| Ok r -> Lwt.return (Some r)
|
||||
@ -277,10 +307,11 @@ let alias_keys cctxt name =
|
||||
| [] -> return None
|
||||
| (key_name, pkh) :: tl ->
|
||||
if key_name = name
|
||||
then
|
||||
then begin
|
||||
Public_key.find_opt cctxt name >>=? fun pkm ->
|
||||
Secret_key.find_opt cctxt name >>=? fun pks ->
|
||||
return (Some (pkh, pkm, pks))
|
||||
end
|
||||
else find_key tl
|
||||
in find_key l
|
||||
|
||||
|
@ -9,16 +9,17 @@
|
||||
|
||||
(** {2 Location of keys using schemes} *)
|
||||
|
||||
type sk_locator = Sk_locator of { scheme : string ; location : string }
|
||||
type pk_locator = Pk_locator of { scheme : string ; location : string }
|
||||
type location = string list
|
||||
type sk_locator = Sk_locator of { scheme : string ; location : location }
|
||||
type pk_locator = Pk_locator of { scheme : string ; location : location }
|
||||
|
||||
module type LOCATOR = sig
|
||||
val name : string
|
||||
type t
|
||||
|
||||
val create : scheme:string -> location:string -> t
|
||||
val create : scheme:string -> location:location -> t
|
||||
val scheme : t -> string
|
||||
val location : t -> string
|
||||
val location : t -> location
|
||||
val to_string : t -> string
|
||||
val pp : Format.formatter -> t -> unit
|
||||
end
|
||||
@ -84,10 +85,10 @@ module type SIGNER = sig
|
||||
val neuterize : secret_key -> public_key Lwt.t
|
||||
(** [neuterize sk] is the corresponding [pk]. *)
|
||||
|
||||
val public_key : public_key -> Signature.Public_key.t Lwt.t
|
||||
(** [public_key pk] is the full version of [pk]. *)
|
||||
val public_key : public_key -> Signature.Public_key.t tzresult Lwt.t
|
||||
(** [public_key pk] is the Ed25519 version of [pk]. *)
|
||||
|
||||
val public_key_hash : public_key -> Signature.Public_key_hash.t Lwt.t
|
||||
val public_key_hash : public_key -> Signature.Public_key_hash.t tzresult Lwt.t
|
||||
(** [public_key_hash pk] is the hash of [pk]. *)
|
||||
|
||||
val sign :
|
||||
|
@ -76,21 +76,24 @@ module Encrypted_signer : SIGNER = struct
|
||||
if Secret_key_locator.scheme skloc <> scheme then
|
||||
Lwt.return a
|
||||
else
|
||||
let location = Secret_key_locator.location skloc in
|
||||
match Base58.safe_decode location with
|
||||
| None -> Lwt.fail Exit
|
||||
| Some payload ->
|
||||
let salt, skenc = salt_skenc_of_skloc payload in
|
||||
match decrypt_sk skenc salt a with
|
||||
| Some sk ->
|
||||
Hashtbl.replace decrypted_sks location
|
||||
(Data_encoding.Binary.of_bytes_exn Signature.Secret_key.encoding sk) ;
|
||||
Lwt.return a
|
||||
| None ->
|
||||
passwd_ask_loop
|
||||
cctxt ~name ~salt ~skenc >>= fun (passwd, decrypted_sk) ->
|
||||
Hashtbl.replace decrypted_sks location decrypted_sk ;
|
||||
Lwt.return (passwd :: a)
|
||||
match Secret_key_locator.location skloc with
|
||||
|location :: _ -> begin
|
||||
match Base58.safe_decode location with
|
||||
| None -> Lwt.fail Exit
|
||||
| Some payload ->
|
||||
let salt, skenc = salt_skenc_of_skloc payload in
|
||||
match decrypt_sk skenc salt a with
|
||||
| Some sk ->
|
||||
Hashtbl.replace decrypted_sks location
|
||||
(Data_encoding.Binary.of_bytes_exn Signature.Secret_key.encoding sk);
|
||||
Lwt.return a
|
||||
| None ->
|
||||
passwd_ask_loop
|
||||
cctxt ~name ~salt ~skenc >>= fun (passwd, decrypted_sk) ->
|
||||
Hashtbl.replace decrypted_sks location decrypted_sk ;
|
||||
Lwt.return (passwd :: a)
|
||||
end
|
||||
|_ -> Lwt.fail Exit
|
||||
end [] sks
|
||||
|
||||
let init cctxt =
|
||||
@ -117,7 +120,7 @@ module Encrypted_signer : SIGNER = struct
|
||||
let payload = MBytes.(to_string (concat "" [salt; encrypted_passwd])) in
|
||||
let location = Base58.safe_encode payload in
|
||||
Hashtbl.replace decrypted_sks location sk ;
|
||||
return (Secret_key_locator.create ~scheme ~location)
|
||||
return (Secret_key_locator.create ~scheme ~location:[location])
|
||||
|
||||
let rec get_boolean_answer (cctxt : #Client_context.io_wallet) ~default ~msg =
|
||||
let prompt = if default then "(Y/n/q)" else "(y/N/q)" in
|
||||
@ -179,29 +182,36 @@ module Encrypted_signer : SIGNER = struct
|
||||
|
||||
let pk_locator_of_human_input _cctxt = function
|
||||
| [] -> failwith "Missing public key argument."
|
||||
| pk :: _ -> return (Public_key_locator.create ~scheme ~location:pk)
|
||||
| pk :: _ -> return (Public_key_locator.create ~scheme ~location:[pk])
|
||||
|
||||
let sk_of_locator (Sk_locator { location }) =
|
||||
match Hashtbl.find decrypted_sks location with
|
||||
| exception Not_found -> failwith "Unknown secret key location."
|
||||
| sk -> return sk
|
||||
let sk_of_locator = function
|
||||
| (Sk_locator { location = [location] }) -> begin
|
||||
match Hashtbl.find decrypted_sks location with
|
||||
| exception Not_found -> failwith "Unknown secret key location."
|
||||
| sk -> return sk
|
||||
end
|
||||
| (Sk_locator { location = _ }) ->
|
||||
failwith "Wrong location type."
|
||||
|
||||
let pk_of_locator (Pk_locator { location }) =
|
||||
Lwt.return (Signature.Public_key.of_b58check location)
|
||||
let pk_of_locator = function
|
||||
|(Pk_locator { location = [location] }) ->
|
||||
Lwt.return (Signature.Public_key.of_b58check location)
|
||||
|(Pk_locator { location = _ }) ->
|
||||
failwith "Wrong location type."
|
||||
|
||||
let sk_to_locator sk =
|
||||
Secret_key_locator.create
|
||||
~scheme ~location:(Signature.Secret_key.to_b58check sk) |>
|
||||
~scheme ~location:[Signature.Secret_key.to_b58check sk] |>
|
||||
Lwt.return
|
||||
|
||||
let pk_to_locator pk =
|
||||
Public_key_locator.create
|
||||
~scheme ~location:(Signature.Public_key.to_b58check pk) |>
|
||||
~scheme ~location:[Signature.Public_key.to_b58check pk] |>
|
||||
Lwt.return
|
||||
|
||||
let neuterize x = Lwt.return (Signature.Secret_key.to_public_key x)
|
||||
let public_key x = Lwt.return x
|
||||
let public_key_hash x = Lwt.return (Signature.Public_key.hash x)
|
||||
let public_key x = return x
|
||||
let public_key_hash x = return (Signature.Public_key.hash x)
|
||||
let sign ?watermark t buf = return (Signature.sign ?watermark t buf)
|
||||
end
|
||||
|
||||
|
@ -30,35 +30,42 @@ module Unencrypted_signer : SIGNER = struct
|
||||
|
||||
let sk_locator_of_human_input _cctxt = function
|
||||
| sk :: _ ->
|
||||
return (Secret_key_locator.create ~scheme ~location:sk)
|
||||
return (Secret_key_locator.create ~scheme ~location:[sk])
|
||||
| [] ->
|
||||
let _, _, sk = Ed25519.generate_key () in
|
||||
return (Secret_key_locator.create ~scheme
|
||||
~location:(Ed25519.Secret_key.to_b58check sk))
|
||||
~location:[Ed25519.Secret_key.to_b58check sk])
|
||||
|
||||
let pk_locator_of_human_input _cctxt = function
|
||||
| [] -> failwith "Missing public key argument"
|
||||
| pk :: _ -> return (Public_key_locator.create ~scheme ~location:pk)
|
||||
| pk :: _ -> return (Public_key_locator.create ~scheme ~location:[pk])
|
||||
|
||||
let sk_of_locator (Sk_locator { location }) =
|
||||
Lwt.return (Signature.Secret_key.of_b58check location)
|
||||
let sk_of_locator = function
|
||||
|(Sk_locator { location = ( location :: _ ) }) ->
|
||||
Lwt.return (Signature.Secret_key.of_b58check location)
|
||||
|(Sk_locator { location = _ }) ->
|
||||
failwith "Wrong type of location"
|
||||
|
||||
let pk_of_locator (Pk_locator { location }) =
|
||||
Lwt.return (Signature.Public_key.of_b58check location)
|
||||
|
||||
let pk_of_locator = function
|
||||
|(Pk_locator { location = ( location :: _ ) }) ->
|
||||
Lwt.return (Signature.Public_key.of_b58check location)
|
||||
|(Pk_locator { location = _ }) ->
|
||||
failwith "Wrong type of location"
|
||||
|
||||
let sk_to_locator sk =
|
||||
Secret_key_locator.create
|
||||
~scheme ~location:(Signature.Secret_key.to_b58check sk) |>
|
||||
~scheme ~location:[Signature.Secret_key.to_b58check sk] |>
|
||||
Lwt.return
|
||||
|
||||
let pk_to_locator pk =
|
||||
Public_key_locator.create
|
||||
~scheme ~location:(Signature.Public_key.to_b58check pk) |>
|
||||
~scheme ~location:[Signature.Public_key.to_b58check pk] |>
|
||||
Lwt.return
|
||||
|
||||
let neuterize x = Lwt.return (Signature.Secret_key.to_public_key x)
|
||||
let public_key x = Lwt.return x
|
||||
let public_key_hash x = Lwt.return (Signature.Public_key.hash x)
|
||||
let public_key x = return x
|
||||
let public_key_hash x = return (Signature.Public_key.hash x)
|
||||
let sign ?watermark t buf = return (Signature.sign ?watermark t buf)
|
||||
end
|
||||
|
||||
|
@ -107,7 +107,7 @@ let commands () =
|
||||
Signer.pk_to_locator pk >>= fun pkloc ->
|
||||
Public_key.find_opt cctxt name >>=? function
|
||||
| None ->
|
||||
Signer.public_key_hash pk >>= fun pkh ->
|
||||
Signer.public_key_hash pk >>=? fun pkh ->
|
||||
Secret_key.add ~force cctxt name skloc >>=? fun () ->
|
||||
Public_key_hash.add ~force cctxt name pkh >>=? fun () ->
|
||||
Public_key.add ~force cctxt name pkloc
|
||||
@ -142,7 +142,7 @@ let commands () =
|
||||
Signer.pk_locator_of_human_input
|
||||
(cctxt :> Client_context.io_wallet) location >>=? fun pkloc ->
|
||||
Signer.pk_of_locator pkloc >>=? fun pk ->
|
||||
Signer.public_key_hash pk >>= fun pkh ->
|
||||
Signer.public_key_hash pk >>=? fun pkh ->
|
||||
Public_key_hash.add ~force cctxt name pkh >>=? fun () ->
|
||||
Public_key.add ~force cctxt name pkloc) ;
|
||||
|
||||
@ -192,7 +192,7 @@ let commands () =
|
||||
find_signer_for_key ~scheme cctxt >>=? fun signer ->
|
||||
let module Signer = (val signer : SIGNER) in
|
||||
Signer.pk_of_locator pkloc >>=? fun pk ->
|
||||
Signer.public_key pk >>= fun pk ->
|
||||
Signer.public_key pk >>=? fun pk ->
|
||||
ok_lwt @@ cctxt#message "Public Key: %a"
|
||||
Signature.Public_key.pp pk >>=? fun () ->
|
||||
if show_private then
|
||||
|
@ -116,7 +116,7 @@ let activate_alpha ?(vote = false) () =
|
||||
let fitness = Fitness_repr.from_int64 0L in
|
||||
let dictator_sk = Client_keys.Secret_key_locator.create
|
||||
~scheme:"unencrypted"
|
||||
~location:"edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6" in
|
||||
~location:["edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6"] in
|
||||
let protocol_parameters =
|
||||
if vote then vote_protocol_parameters else protocol_parameters in
|
||||
Tezos_client_genesis.Client_proto_main.bake
|
||||
@ -250,7 +250,7 @@ module Account = struct
|
||||
~amount () =
|
||||
let src_sk = Client_keys.Secret_key_locator.create
|
||||
~scheme:"unencrypted"
|
||||
~location:(Signature.Secret_key.to_b58check account.sk) in
|
||||
~location:[Signature.Secret_key.to_b58check account.sk] in
|
||||
Client_proto_context.transfer
|
||||
(new wrap_full (no_write_context !rpc_config ~block))
|
||||
block
|
||||
@ -274,7 +274,7 @@ module Account = struct
|
||||
| Some delegate -> true, Some delegate in
|
||||
let src_sk = Client_keys.Secret_key_locator.create
|
||||
~scheme:"unencrypted"
|
||||
~location:(Signature.Secret_key.to_b58check src.sk) in
|
||||
~location:[Signature.Secret_key.to_b58check src.sk] in
|
||||
Client_proto_context.originate_account
|
||||
~source:src.contract
|
||||
~src_pk:src.pk
|
||||
@ -508,7 +508,7 @@ module Baking = struct
|
||||
None in
|
||||
let src_sk = Client_keys.Secret_key_locator.create
|
||||
~scheme:"unencrypted"
|
||||
~location:(Signature.Secret_key.to_b58check contract.sk) in
|
||||
~location:[Signature.Secret_key.to_b58check contract.sk] in
|
||||
Client_baking_forge.forge_block
|
||||
ctxt
|
||||
block
|
||||
|
Loading…
Reference in New Issue
Block a user