diff --git a/tools/offline.ml b/tools/offline.ml index ba191e35..833f1e37 100644 --- a/tools/offline.ml +++ b/tools/offline.ml @@ -12,6 +12,7 @@ let to_term_ret = Fun.id let setup_cmd = let doc = "Generate offline master keys" in let output = + let doc = "output file" in Arg.( value & opt filepath default_master_offline_key_file @@ -28,6 +29,7 @@ let download_cmd = [ `S Manpage.s_description; `P "$(cmd) download /management/keys." ] in let output = + let doc = "output file" in Arg.( value & opt filepath default_response_file & info [ "o"; "output" ] ~doc) in @@ -37,42 +39,75 @@ let download_cmd = download ~output |> to_term_ret let upload_cmd = - let doc = "POST /management/keys/" in - let man = - [ `S Manpage.s_description; `P "$(cmd) upload /management/keys." ] - in + let doc = "POST input.json data to url (default /management/keys)" in let input = + let doc = "input file" in Arg.(value & opt file default_request_file & info [ "i"; "input" ] ~doc) in - Cmd.make (Cmd.info "upload" ~doc ~man) + let url = + let doc = "url" in + Arg.(value & opt string "/management/keys" & info [ "url" ] ~doc) + in + Cmd.make (Cmd.info "upload" ~doc) @@ - let+ input = input in - upload ~input |> to_term_ret + let+ input = input and+ url = url in + upload ~input ~url |> to_term_ret + +let master_key = + let doc = "Master offline Eddsa private key file." in + Arg.(value & opt file default_master_offline_key_file & info [ "key" ] ~doc) + +let input = + let doc = "input file" in + Arg.(value & opt file default_response_file & info [ "i"; "input" ] ~doc) + +let output = + let doc = "output file" in + Arg.(value & opt filepath default_request_file & info [ "o"; "output" ] ~doc) let sign_cmd = let doc = "Sign FutureKeysResponse." in - let master_key = - let doc = "Master offline Eddsa private key file." in - Arg.(value & opt file default_master_offline_key_file & info [ "key" ] ~doc) - in - let input = - Arg.(value & opt file default_response_file & info [ "i"; "input" ] ~doc) - in - let output = - Arg.( - value & opt filepath default_request_file & info [ "o"; "output" ] ~doc) - in Cmd.make (Cmd.info "sign" ~doc) @@ let+ input = input and+ output = output and+ master_key = master_key in sign ~input ~output ~master_key |> to_term_ret +let revoke_denom_cmd = + let doc = "Revoke denomination." in + let h_denom = + let doc = "hash of denomination public key" in + Arg.(required & pos 0 (some string) None & info [] ~doc) + in + Cmd.make (Cmd.info "revoke-denom" ~doc) + @@ + let+ output = output and+ master_key = master_key and+ h_denom = h_denom in + revoke_denom ~output ~master_key ~h_denom |> to_term_ret + +let revoke_signkey_cmd = + let doc = "Revoke signkey." in + let signkey = + let doc = "public signing key" in + Arg.(required & pos 0 (some string) None & info [] ~doc) + in + Cmd.make (Cmd.info "revoke-signkey" ~doc) + @@ + let+ output = output and+ master_key = master_key and+ signkey = signkey in + revoke_signkey ~output ~master_key ~signkey |> to_term_ret + let cli = let info = let doc = "MTE Offline CLI tool" in Cmd.info "mte-offline" ~doc in - Cmd.group info [ setup_cmd; download_cmd; sign_cmd; upload_cmd ] + Cmd.group info + [ + setup_cmd; + download_cmd; + sign_cmd; + upload_cmd; + revoke_denom_cmd; + revoke_signkey_cmd; + ] let main () = Cmd.eval_result cli let () = if !Sys.interactive then () else exit (main ()) diff --git a/tools/offline_impl.ml b/tools/offline_impl.ml index 14047080..7e105f84 100644 --- a/tools/offline_impl.ml +++ b/tools/offline_impl.ml @@ -6,19 +6,17 @@ let write_file fname content = Bos.OS.File.write (Fpath.v fname) content |> unwrap_err_msg let base_url = Uri.of_string "http://localhost:3434/" - -let management_keys_url = - Uri.with_path base_url "/management/keys/" |> Uri.to_string +let full_url path = Uri.with_path base_url path |> Uri.to_string let download ~output = let open Bos in - let uri = management_keys_url in + let uri = full_url "/management/keys/" in OS.Cmd.run Cmd.(v "curl" % "-s" % "-o" % output % "-X" % "GET" % uri) |> unwrap_err_msg -let upload ~input = +let upload ~input ~url = let open Bos in - let uri = management_keys_url in + let uri = full_url url in OS.Cmd.run Cmd.( v "curl" @@ -56,3 +54,24 @@ let sign ~master_key ~input ~output = let* s = Api.encode Api.MasterSignatures.jsont master_signatures in let* () = write_file output s in Ok () + +let revoke_denom ~output ~master_key ~h_denom = + let open Crypto in + let* key = read_file master_key in + let key = EddsaPrivateKey.of_octets key in + let* h_denom = B32.decode h_denom in + let h_denom = Bin_type.DenominationHash.of_octets h_denom in + let denom_revoke = Offline_sig.mk_denom_revoke ~key h_denom in + let* s = Api.encode Api.DenomRevocationSignature.jsont denom_revoke in + let* () = write_file output s in + Ok () + +let revoke_signkey ~output ~master_key ~signkey = + let open Crypto in + let* key = read_file master_key in + let key = EddsaPrivateKey.of_octets key in + let* signkey = EddsaPublicKey.of_b32 signkey in + let v = Offline_sig.mk_signkey_revoke ~key signkey in + let* s = Api.encode Api.SignkeyRevocationSignature.jsont v in + let* () = write_file output s in + Ok () diff --git a/tools/offline_sig.ml b/tools/offline_sig.ml index c1e6a16f..580cb809 100644 --- a/tools/offline_sig.ml +++ b/tools/offline_sig.ml @@ -134,3 +134,17 @@ let verify_future_keys_response our_master_public_key future_signkeys in Ok () + +let mk_denom_revoke ~key h_denom_pub = + let master_sig = + let open Bin_sig.MasterDenominationKeyRevocation in + sign ~key { h_denom_pub } + in + DenomRevocationSignature.{ master_sig } + +let mk_signkey_revoke ~key exchange_pub = + let master_sig = + let open Bin_sig.MasterSigningKeyRevocation in + sign ~key { exchange_pub } + in + SignkeyRevocationSignature.{ master_sig }