# # # patch "cmd_agent.cc" # from [a20008044cf80c5657e7689c468feee72efb3cef] # to [de62f2edf48cdfebe02eb35539c7ad0a4de17bc8] # # patch "keys.cc" # from [4a058060b5a56df134ca3c1d418b810c644712bd] # to [2046adb65a4749a85adc58c8d2577a30425d7289] # # patch "keys.hh" # from [9533f5981f0e090d3a4378607b14d5082050098b] # to [d0e0528c82f6d621c14e3dfb2e140a34bdf98464] # ============================================================ --- cmd_agent.cc a20008044cf80c5657e7689c468feee72efb3cef +++ cmd_agent.cc de62f2edf48cdfebe02eb35539c7ad0a4de17bc8 @@ -1,11 +1,25 @@ #include +#include +#include +#include #include "cmd.hh" +#include "keys.hh" #include "ssh_agent.hh" +#include "botan/rsa.h" +#include "botan/base64.h" +#include "botan/pipe.h" +using std::cout; using std::string; using std::vector; +using std::fstream; using boost::scoped_ptr; +using boost::shared_ptr; +using Botan::RSA_PublicKey; +using Botan::RSA_PrivateKey; +using Botan::Base64_Encoder; +using Botan::Pipe; static void agent_list(string const & name, app_state & app, vector const & args) @@ -18,8 +32,41 @@ agent_list(string const & name, app_stat a->get_keys(); } +static void +agent_export(string const & name, app_state & app, vector const & args) +{ + if (args.size() != 0 && args.size() != 1) + throw usage(name); + + vector keys; + keypair key; + if (args.size() == 0) + app.keys.get_keys(keys); + else + app.keys.get_key_ids(idx(args,0)(), keys); + for (vector::const_iterator + i = keys.begin(); i != keys.end(); ++i) { + app.keys.get_key_pair(*i, key); + //cout << key.priv << "\n"; + shared_ptr priv = get_private_key(app.lua, *i, key.priv); + + utf8 new_phrase; + get_passphrase(app.lua, *i, new_phrase, true, true, "enter new passphrase"); + Pipe p; + p.start_msg(); + Botan::PKCS8::encrypt_key(*priv, p, new_phrase(), + "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"); + string decoded_key = p.read_all_as_string(); + fstream fout; + fout.open("id_monotone", fstream::out | fstream::trunc); + fout << decoded_key; + fout.close(); + } +} + CMD(agent, N_("informative"), - N_("list"), + N_("list\n" + "export"), N_("interact with the agent"), options::opts::depth | options::opts::exclude) { @@ -31,6 +78,8 @@ CMD(agent, N_("informative"), vector removed (i, args.end()); if (idx(args, 0)() == "list") agent_list(name, app, removed); + else if (idx(args, 0)() == "export") + agent_export(name, app, removed); else throw usage(name); } ============================================================ --- keys.cc 4a058060b5a56df134ca3c1d418b810c644712bd +++ keys.cc 2046adb65a4749a85adc58c8d2577a30425d7289 @@ -72,13 +72,13 @@ do_arc4(SecureVector & sym_ // 'force_from_user' means that we don't use the passphrase cache, and we // don't use the get_passphrase hook. -static void +void get_passphrase(lua_hooks & lua, rsa_keypair_id const & keyid, utf8 & phrase, - bool confirm_phrase = false, - bool force_from_user = false, - string prompt_beginning = "enter passphrase") + bool confirm_phrase, + bool force_from_user, + string prompt_beginning) { // we permit the user to relax security here, by caching a passphrase (if @@ -216,7 +216,7 @@ get_private_key(lua_hooks & lua, get_private_key(lua_hooks & lua, rsa_keypair_id const & id, base64< rsa_priv_key > const & priv, - bool force_from_user = false) + bool force_from_user) { rsa_priv_key decoded_key; utf8 phrase; ============================================================ --- keys.hh 9533f5981f0e090d3a4378607b14d5082050098b +++ keys.hh d0e0528c82f6d621c14e3dfb2e140a34bdf98464 @@ -11,8 +11,13 @@ // PURPOSE. #include "vocab.hh" +#include "botan/rsa.h" +#include #include +using Botan::RSA_PrivateKey; +using boost::shared_ptr; + class lua_hooks; class app_state; @@ -66,6 +71,20 @@ void decrypt_rsa(lua_hooks & lua, rsa_oaep_sha_data const & ciphertext, std::string & plaintext); +void +get_passphrase(lua_hooks & lua, + rsa_keypair_id const & keyid, + utf8 & phrase, + bool confirm_phrase = false, + bool force_from_user = false, + std::string prompt_beginning = "enter passphrase"); + +shared_ptr +get_private_key(lua_hooks & lua, + rsa_keypair_id const & id, + base64< rsa_priv_key > const & priv, + bool force_from_user = false); + // netsync stuff void read_pubkey(std::string const & in,