# # # patch "cmd_key_cert.cc" # from [476b852acef7bc44f67c66f1cadd2b1ca406c599] # to [ab8b6ad9f555050cab7987ff173b989ea43ff422] # # patch "ssh_agent.cc" # from [b64b1e3c6e2d2aa33b742dfe1ce4c11027742315] # to [1d08ec27ca6d868527c9d58170102f02818ba3f5] # # patch "ssh_agent.hh" # from [abc8bf1f64cd81be6cec4748cd7c8613801ae6d6] # to [90e9eb5957fc913e896ecee54f6fc7a3da04b281] # ============================================================ --- cmd_key_cert.cc 476b852acef7bc44f67c66f1cadd2b1ca406c599 +++ cmd_key_cert.cc ab8b6ad9f555050cab7987ff173b989ea43ff422 @@ -8,6 +8,7 @@ // PURPOSE. #include +#include #include "cert.hh" #include "charset.hh" @@ -16,12 +17,16 @@ #include "packet.hh" #include "transforms.hh" #include "ssh_agent.hh" +#include "botan/pipe.h" using std::cout; using std::ostream_iterator; using std::ostringstream; using std::set; using std::string; +using std::ofstream; +using Botan::Pipe; +using Botan::RSA_PrivateKey; CMD(genkey, N_("key and cert"), N_("KEYID"), N_("generate an RSA key-pair"), options::opts::none) @@ -118,9 +123,54 @@ CMD(ssh_agent_export, N_("key and cert") if (args.size() > 1) throw usage(name); - app.agent.export_key(name, app, args); + rsa_keypair_id id; + keypair key; + get_user_key(id, app); + N(priv_key_exists(app, id), F("the key you specified cannot be found")); + app.keys.get_key_pair(id, key); + shared_ptr priv = get_private_key(app.lua, id, key.priv); + utf8 new_phrase; + get_passphrase(app.lua, id, new_phrase, true, true, "enter new passphrase"); + Pipe p; + p.start_msg(); + if (new_phrase().length()) + { + Botan::PKCS8::encrypt_key(*priv, + p, + new_phrase(), + "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"); + } + else + { + Botan::PKCS8::encode(*priv, p); + } + string decoded_key = p.read_all_as_string(); + if (args.size() == 0) + cout << decoded_key; + else + { + ofstream fout(idx(args,0)().c_str(), ofstream::out); + fout << decoded_key; + } } +CMD(ssh_agent_add, N_("key and cert"), + N_(""), + N_("Add your momotone key to ssh-agent"), + options::opts::none) +{ + if (args.size() > 1) + throw usage(name); + + rsa_keypair_id id; + keypair key; + get_user_key(id, app); + N(priv_key_exists(app, id), F("the key you specified cannot be found")); + app.keys.get_key_pair(id, key); + shared_ptr priv = get_private_key(app.lua, id, key.priv); + app.agent.add_identity(*priv, id()); +} + CMD(cert, N_("key and cert"), N_("REVISION CERTNAME [CERTVAL]"), N_("create a cert for a revision"), options::opts::none) { ============================================================ --- ssh_agent.cc b64b1e3c6e2d2aa33b742dfe1ce4c11027742315 +++ ssh_agent.cc 1d08ec27ca6d868527c9d58170102f02818ba3f5 @@ -1,28 +1,22 @@ #include #include #include #include -#include -#include -#include "cmd.hh" #include "ssh_agent.hh" #include "sanity.hh" #include "netio.hh" #include "keys.hh" -#include "botan/pipe.h" +#include "botan/numthry.h" using Botan::RSA_PublicKey; using Botan::RSA_PrivateKey; using Botan::BigInt; -using Botan::Pipe; using Netxx::Stream; using boost::shared_ptr; using std::string; using std::vector; using std::min; -using std::cout; -using std::ofstream; /* * The ssh-agent network format is essentially based on a u32 which @@ -148,43 +142,6 @@ ssh_agent::connected() return stream != NULL; } -void -ssh_agent::export_key(string const & name, app_state & app, vector const & args) -{ - if (args.size() > 1) - throw usage(name); - - rsa_keypair_id id; - keypair key; - get_user_key(id, app); - N(priv_key_exists(app, id), F("the key you specified cannot be found")); - app.keys.get_key_pair(id, key); - shared_ptr priv = get_private_key(app.lua, id, key.priv); - utf8 new_phrase; - get_passphrase(app.lua, id, new_phrase, true, true, "enter new passphrase"); - Pipe p; - p.start_msg(); - if (new_phrase().length()) - { - Botan::PKCS8::encrypt_key(*priv, - p, - new_phrase(), - "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"); - } - else - { - Botan::PKCS8::encode(*priv, p); - } - string decoded_key = p.read_all_as_string(); - if (args.size() == 0) - cout << decoded_key; - else - { - ofstream fout(idx(args,0)().c_str(), ofstream::out); - fout << decoded_key; - } -} - u32 ssh_agent::get_long(char const * buf) { @@ -275,18 +232,35 @@ void } void -ssh_agent::put_key_into_buf(RSA_PublicKey const & key, string & buf) +ssh_agent::put_public_key_into_buf(RSA_PublicKey const & key, string & buf) { - L(FL("ssh_agent: put_key_into_buf: key e: %s, n: %s") + L(FL("ssh_agent: put_public_key_into_buf: key e: %s, n: %s") % key.get_e() % key.get_n()); put_string_into_buf("ssh-rsa", buf); put_bigint_into_buf(key.get_e(), buf); put_bigint_into_buf(key.get_n(), buf); - L(FL("ssh_agent: put_key_into_buf: buf len now %i") % buf.length()); + L(FL("ssh_agent: put_public_key_into_buf: buf len now %i") % buf.length()); } void +ssh_agent::put_private_key_into_buf(RSA_PrivateKey const & key, string & buf) +{ + L(FL("ssh_agent: put_private_key_into_buf: key e: %s, n: %s") + % key.get_e() + % key.get_n()); + put_string_into_buf("ssh-rsa", buf); + put_bigint_into_buf(key.get_n(), buf); + put_bigint_into_buf(key.get_e(), buf); + put_bigint_into_buf(key.get_d(), buf); + BigInt iqmp = inverse_mod(key.get_q(), key.get_p()); + put_bigint_into_buf(iqmp, buf); + put_bigint_into_buf(key.get_p(), buf); + put_bigint_into_buf(key.get_q(), buf); + L(FL("ssh_agent: put_private_key_into_buf: buf len now %i") % buf.length()); +} + +void ssh_agent::put_string_into_buf(string const & str, string & buf) { L(FL("ssh_agent: put_string_into_buf: str len %i, buf len %i") @@ -466,7 +440,7 @@ ssh_agent::sign_data(RSA_PublicKey const unsigned char cmd[1]; cmd[0] = 13; data_out.append((char *)cmd, 1); - put_key_into_buf(key, key_buf); + put_public_key_into_buf(key, key_buf); put_string_into_buf(key_buf, data_out); put_string_into_buf(data, data_out); @@ -514,6 +488,40 @@ ssh_agent::sign_data(RSA_PublicKey const % packet_in.length())); } +void +ssh_agent::add_identity(RSA_PrivateKey const & key, string const & comment) +{ + E(connected(), + F("ssh_agent: add_identity: attempted to add a key when not connected")); + + L(FL("ssh_agent: add_identity: key e: %s, n: %s, comment len: %i") + % key.get_e() + % key.get_n() + % comment.length()); + string data_out; + string key_buf; + unsigned char cmd[1]; + cmd[0] = 17; + //data_out.append((char *)cmd, 1); + key_buf.append((char *)cmd, 1); + put_private_key_into_buf(key, key_buf); + put_string_into_buf(comment, key_buf); + //put_string_into_buf(key_buf, data_out); + + string packet_out; + put_string_into_buf(key_buf, packet_out); + + stream->write(packet_out.c_str(), packet_out.length()); + + string packet_in; + fetch_packet(packet_in); + u32 packet_in_loc = 0; + E(packet_in.at(0) == 6, F("ssh_agent: packet type (%u) != 6") + % (u32)packet_in.at(0)); + packet_in_loc += 1; + +} + // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- ssh_agent.hh abc8bf1f64cd81be6cec4748cd7c8613801ae6d6 +++ ssh_agent.hh 90e9eb5957fc913e896ecee54f6fc7a3da04b281 @@ -5,7 +5,6 @@ #include "netxx/stream.h" #include "botan/rsa.h" #include "botan/bigint.h" -#include "app_state.hh" #include #include @@ -15,11 +14,11 @@ public: ssh_agent(); ~ssh_agent(); bool connected(); - void export_key(std::string const & name, app_state & app, std::vector const & args); std::vector const get_keys(); void sign_data(Botan::RSA_PublicKey const & key, std::string const & data, std::string & out); + void add_identity(Botan::RSA_PrivateKey const & key, std::string const & comment); private: boost::shared_ptr stream; @@ -40,7 +39,8 @@ private: void put_long_into_buf(u32 l, std::string & buf); void put_string_into_buf(std::string const & str, std::string & buf); void put_bigint_into_buf(Botan::BigInt const & bi, std::string & buf); - void put_key_into_buf(Botan::RSA_PublicKey const & key, std::string & buf); + void put_public_key_into_buf(Botan::RSA_PublicKey const & key, std::string & buf); + void put_private_key_into_buf(Botan::RSA_PrivateKey const & key, std::string & buf); }; // Local Variables: