bin_node: sanity check on node identity file

This commit is contained in:
Julien Tesson 2018-10-16 15:39:12 +02:00 committed by Grégoire Henry
parent 0c9812f881
commit 532a934438
No known key found for this signature in database
GPG Key ID: 50D984F20BD445D2

View File

@ -25,13 +25,21 @@
type error += No_identity_file of string type error += No_identity_file of string
type error += Insufficient_proof_of_work of { expected: float } type error += Insufficient_proof_of_work of { expected: float }
type error += Identity_mismatch of {
filename: string ;
peer_id: Crypto_box.Public_key_hash.t ;
}
type error += Identity_keys_mismatch of {
filename: string ;
expected_key:Crypto_box.public_key ;
}
let () = let () =
register_error_kind register_error_kind
`Permanent `Permanent
~id:"main.identity.no_file" ~id:"main.identity.no_file"
~title:"TODO" ~title:"No identity file"
~description:"TODO" ~description:"The node identity file cannot be found"
~pp:(fun ppf file -> ~pp:(fun ppf file ->
Format.fprintf ppf Format.fprintf ppf
"Cannot read the identity file: `%s`. \ "Cannot read the identity file: `%s`. \
@ -45,8 +53,8 @@ let () =
register_error_kind register_error_kind
`Permanent `Permanent
~id:"main.identity.insufficient_proof_of_work" ~id:"main.identity.insufficient_proof_of_work"
~title:"TODO" ~title:"Insufficient proof of work"
~description:"TODO" ~description:"The proof of work embeded by the current identity is not sufficient"
~pp:(fun ppf expected -> ~pp:(fun ppf expected ->
Format.fprintf ppf Format.fprintf ppf
"The current identity does not embed a sufficient stamp of proof-of-work. \ "The current identity does not embed a sufficient stamp of proof-of-work. \
@ -57,22 +65,72 @@ let () =
(function Insufficient_proof_of_work { expected } -> Some expected | _ -> None) (function Insufficient_proof_of_work { expected } -> Some expected | _ -> None)
(fun expected -> Insufficient_proof_of_work { expected }) (fun expected -> Insufficient_proof_of_work { expected })
let read ?expected_pow file =
Lwt_unix.file_exists file >>= function let () =
register_error_kind
`Permanent
~id:"main.identity.identity_mismatch"
~title:"Identity mismatch"
~description:"The identity (public key hash) does not match the keys provided with it"
~pp:(fun ppf (file, public_key_hash) ->
Format.fprintf ppf
"The current identity (public key hash) does not match the keys in %s.
Expected identity %a."
file
Crypto_box.Public_key_hash.pp
public_key_hash)
Data_encoding.(obj2 (req "file" string) (req "public_key_hash" Crypto_box.Public_key_hash.encoding))
(function Identity_mismatch { filename ; peer_id } ->
Some (filename, peer_id) | _ -> None)
(fun (filename,peer_id) -> Identity_mismatch { filename ; peer_id })
let () =
register_error_kind
`Permanent
~id:"main.identity.identity_keys_mismatch"
~title:"Identity keys mismatch"
~description:"The current identity file has non-matching keys (secret key/ public key pair is not valid)"
~pp:(fun ppf (file, public_key) ->
Format.fprintf ppf
"The current identity file %s has non-matching keys (secret key/ public key pair is not valid).
Expected public key %a."
file
Crypto_box.pp_pk
public_key)
Data_encoding.(obj2 (req "file" string) (req "public_key" Crypto_box.public_key_encoding))
(function
| Identity_keys_mismatch { filename ; expected_key } ->
Some (filename, expected_key)
| _ -> None)
(fun (filename, expected_key) ->
Identity_keys_mismatch { filename ; expected_key })
let read ?expected_pow filename =
Lwt_unix.file_exists filename >>= function
| false -> | false ->
fail (No_identity_file file) fail (No_identity_file filename)
| true -> | true ->
Lwt_utils_unix.Json.read_file file >>=? fun json -> Lwt_utils_unix.Json.read_file filename >>=? fun json ->
let id = Data_encoding.Json.destruct P2p_identity.encoding json in let id = Data_encoding.Json.destruct P2p_identity.encoding json in
match expected_pow with let pkh = Crypto_box.hash id.public_key in
| None -> return id (* check public_key hash *)
| Some expected -> if not (Crypto_box.Public_key_hash.equal pkh id.peer_id) then
let target = Crypto_box.make_target expected in fail (Identity_mismatch { filename ; peer_id = pkh })
if (Crypto_box.check_proof_of_work (* check public/private keys correspondance *)
id.public_key id.proof_of_work_stamp target) then else if not Crypto_box.(equal (neuterize id.secret_key) id.public_key) then
return id fail (Identity_keys_mismatch { filename ; expected_key = id.public_key })
else else (* check PoW level *)
fail (Insufficient_proof_of_work { expected }) match expected_pow with
| None -> return id
| Some expected ->
let target = Crypto_box.make_target expected in
if
not (Crypto_box.check_proof_of_work
id.public_key id.proof_of_work_stamp target)
then
fail (Insufficient_proof_of_work { expected })
else
return id
type error += Existent_identity_file of string type error += Existent_identity_file of string
@ -80,8 +138,8 @@ let () =
register_error_kind register_error_kind
`Permanent `Permanent
~id:"main.identity.existent_file" ~id:"main.identity.existent_file"
~title:"TODO" ~title:"Cannot overwrite identity file"
~description:"TODO" ~description:"Cannot implicitely overwrite the current identity file"
~pp:(fun ppf file -> ~pp:(fun ppf file ->
Format.fprintf ppf Format.fprintf ppf
"Cannot implicitely overwrite the current identity file: '%s'. \ "Cannot implicitely overwrite the current identity file: '%s'. \