# # # add_file "tests/t_read_privkey.at" # # patch "ChangeLog" # from [f17e3a4cd4bfbcbb8a7e720e43446cb0449e81ca] # to [49f5bb0004ee0720ad25f20a08585e5f9b342051] # # patch "commands.cc" # from [0a5d9cd019e6de8366160979548bd62167777ee2] # to [389e32c8fb504abe7f3e3a16f025a07396f7d0a2] # # patch "key_store.cc" # from [92f4fc2b3b1ac16c869de4aae95e9ca9fb2774d0] # to [75549872a8c7373ded03d254298fc75fa975a6c2] # # patch "packet.cc" # from [00bd3aba6a226fbf464b1dcb503ddb585697f0de] # to [eb432f35e940516009c223c4659461200fdb1e79] # # patch "packet.hh" # from [39fc6a33b1554136d2cf8ed85a69ca0de408807f] # to [0745d303425673413b765c61d664242953466171] # # patch "tests/t_dropkey_2.at" # from [52a101950139d3799bf23b1f789de3503d37741f] # to [1a15229900da781d07f0f6776f942dc0ff2d0b38] # # patch "tests/t_read_privkey.at" # from [] # to [d03aae665c6a20fb4434dc2004a7ca37171027d5] # # patch "testsuite.at" # from [80576368fe0f091078e2cff77c2a8c56253a4e0c] # to [bdc90ade96c294f4b14b061e1e6d0adbf002f60c] # ============================================================ --- ChangeLog f17e3a4cd4bfbcbb8a7e720e43446cb0449e81ca +++ ChangeLog 49f5bb0004ee0720ad25f20a08585e5f9b342051 @@ -1,3 +1,18 @@ +2005-12-06 Timothy Brownawell + + * packet.cc (packet stream reading): Fix handling of privkey packets. + It would convert pubkey+privkey to keypair, but not change the private + key to the new encryption type. Now uses migrate_private_key to + convert privkey->keypair. Reading privkey packets from stdin only works + if the get_passphrase hook is defined for that key. + Fix packet_roundabout_test; the send+receive part was using an empty + stream, rather than the packet sequence generated in the first part. + * packet.hh, commands.cc, key_store.cc: read_packets now takes an + app_state argument. + * tests/t_dropkey_2.at: use genkey instead of reading packets + * tests/t_read_privkey.at: check that reading a privkey packet works + * testsuite.at: add read_privkey test + 2005-12-06 Matthew Gregan * contrib/usher.cc (fork_server): Avoid getting stuck in an ============================================================ --- commands.cc 0a5d9cd019e6de8366160979548bd62167777ee2 +++ commands.cc 389e32c8fb504abe7f3e3a16f025a07396f7d0a2 @@ -1943,7 +1943,7 @@ size_t count = 0; if (args.empty()) { - count += read_packets(cin, dbw); + count += read_packets(cin, dbw, app); N(count != 0, F("no packets found on stdin")); } else @@ -1953,7 +1953,7 @@ data dat; read_data(system_path(*i), dat); istringstream ss(dat()); - count += read_packets(ss, dbw); + count += read_packets(ss, dbw, app); } N(count != 0, FP("no packets found in given file", "no packets found in given files", ============================================================ --- key_store.cc 92f4fc2b3b1ac16c869de4aae95e9ca9fb2774d0 +++ key_store.cc 75549872a8c7373ded03d254298fc75fa975a6c2 @@ -90,7 +90,7 @@ data dat; read_data(key_dir / (*i)(), dat); std::istringstream is(dat()); - read_packets(is, kr); + read_packets(is, kr, *app); } } ============================================================ --- packet.cc 00bd3aba6a226fbf464b1dcb503ddb585697f0de +++ packet.cc eb432f35e940516009c223c4659461200fdb1e79 @@ -1341,6 +1341,7 @@ struct feed_packet_consumer { + app_state & app; size_t & count; packet_consumer & cons; std::string ident; @@ -1348,8 +1349,8 @@ std::string certname; std::string base; std::string sp; - feed_packet_consumer(size_t & count, packet_consumer & c) - : count(count), cons(c), + feed_packet_consumer(size_t & count, packet_consumer & c, app_state & app_) + : app(app_), count(count), cons(c), ident(constants::regex_legal_id_bytes), key(constants::regex_legal_key_name_bytes), certname(constants::regex_legal_cert_name_bytes), @@ -1428,7 +1429,7 @@ L(F("read cert packet")); match_results matches; require(regex_match(args, matches, regex(ident + sp + certname - + key + sp + base))); + + sp + key + sp + base))); string certid(matches[1].first, matches[1].second); string name(matches[2].first, matches[2].second); string keyid(matches[3].first, matches[3].second); @@ -1462,6 +1463,19 @@ string priv_dat(trim_ws(string(matches[2].first, matches[2].second))); cons.consume_key_pair(rsa_keypair_id(args), keypair(pub_dat, priv_dat)); } + else if (type == "privkey") + { + L(F("read pubkey data packet")); + require(regex_match(args, regex(key))); + require(regex_match(body, regex(base))); + string contents(trim_ws(body)); + keypair kp; + migrate_private_key(app, + rsa_keypair_id(args), + base64 >(contents), + kp); + cons.consume_key_pair(rsa_keypair_id(args), kp); + } else { W(F("unknown packet type: '%s'") % type); @@ -1473,40 +1487,21 @@ }; static size_t -extract_packets(string const & s, packet_consumer & cons, bool last) +extract_packets(string const & s, packet_consumer & cons, app_state & app) { - std::string r(s); - { - // since we don't have privkey packets anymore, translate a - // pubkey packet immediately followed by a matching privkey - // packet into a keypair packet (which is what privkey packets - // have been replaced by) - string const pubkey("\\[pubkey[[:space:]]+" + constants::regex_legal_key_name_bytes - + "\\]" + constants::regex_legal_packet_bytes + "\\[end\\]"); - string const privkey("\\[privkey \\1\\]" + constants::regex_legal_packet_bytes - + "\\[end\\]"); - string const pubkey_privkey = pubkey + "[[:space:]]*" + privkey; - string const keypair_fmt("[keypair $1]$2#$3[end]"); - r = regex_replace(s, regex(pubkey_privkey), keypair_fmt); - bool pub = regex_match(s, regex(pubkey + ".*")); - bool two = regex_match(s, regex(".+\\[end\\].+\\[end\\]")); - if (!last && pub && !two) - return 0; - } - string const head("\\[([a-z]+)[[:space:]]+([^\\[\\]]+)\\]"); string const body("([^\\[\\]]+)"); string const tail("\\[end\\]"); string const whole = head + body + tail; regex expr(whole); size_t count = 0; - regex_grep(feed_packet_consumer(count, cons), r, expr, match_default); + regex_grep(feed_packet_consumer(count, cons, app), s, expr, match_default); return count; } size_t -read_packets(istream & in, packet_consumer & cons) +read_packets(istream & in, packet_consumer & cons, app_state & app) { string accum, tmp; size_t count = 0; @@ -1523,16 +1518,13 @@ { endpos += end.size(); string tmp = accum.substr(0, endpos); - size_t num = extract_packets(tmp, cons, false); - count += num; - if (num) - if (endpos < accum.size() - 1) - accum = accum.substr(endpos+1); - else - accum.clear(); + count += extract_packets(tmp, cons, app); + if (endpos < accum.size() - 1) + accum = accum.substr(endpos+1); + else + accum.clear(); } } - count += extract_packets(accum, cons, true); return count; } @@ -1560,7 +1552,7 @@ // an fdelta packet file_data fdata2(data("this is some file data which is not the same as the first one")); file_id fid2; - calculate_ident(fdata2, fid); + calculate_ident(fdata2, fid2); delta del; diff(fdata.inner(), fdata2.inner(), del); pw.consume_file_delta(fid, fid2, file_delta(del)); @@ -1611,15 +1603,21 @@ pw.consume_key_pair(rsa_keypair_id("address@hidden"), kp); + tmp = oss.str(); } - + + // read_packets needs this to convert privkeys to keypairs. + // This doesn't test privkey packets (theres a tests/ test for that), + // so we don't actually use the app_state for anything. So a default one + // is ok. + app_state aaa; for (int i = 0; i < 10; ++i) { // now spin around sending and receiving this a few times ostringstream oss; packet_writer pw(oss); istringstream iss(tmp); - read_packets(iss, pw); + read_packets(iss, pw, aaa); BOOST_CHECK(oss.str() == tmp); tmp = oss.str(); } ============================================================ --- packet.hh 39fc6a33b1554136d2cf8ed85a69ca0de408807f +++ packet.hh 0745d303425673413b765c61d664242953466171 @@ -226,6 +226,6 @@ virtual void open_valve(); }; -size_t read_packets(std::istream & in, packet_consumer & cons); +size_t read_packets(std::istream & in, packet_consumer & cons, app_state & app); #endif ============================================================ --- tests/t_dropkey_2.at 52a101950139d3799bf23b1f789de3503d37741f +++ tests/t_dropkey_2.at 1a15229900da781d07f0f6776f942dc0ff2d0b38 @@ -1,32 +1,11 @@ # -*- Autoconf -*- AT_SETUP([drop a public and private key]) MONOTONE_SETUP -AT_DATA(key.txt, [@<:@pubkey address@hidden@:>@ -MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCPUdR/bM41m2KIpS0eXlTG91PSWvOUdwY4 -6aKd+DXZFma8Hi00Wvwmr+0JJdWqPwyxR/Dr2a2Z7Db76lUiNlhvRw3yoKP2ip9Jjfe0LReG -5aJ5u1l5L5VPiZ5iZq9PjxNDAYASpb89yBT7BJZ6OAXuE9zHFR506Apg7UB4Em184wIBEQ== -@<:@end@:>@ -@<:@privkey address@hidden@:>@ -ZOC+Y7Y9QGlMneYNH5zexwV6IlWb8Q9IhW2Jn+qVhlxpocqN6AI60NXgzVupUOyNvTPsc2kP -mwjaHGaIr3SZE6E3riS8BnMNnvvCo5FZE5R2Hm4O+MST2LOINFX1eNSNch6pXGnjmTA6MO2Z -9YuZ1AERPdy/T2DD3EBNMZM6uylc6IJlwW8JMe6DWaAaGmoAb35NCEgw6uw1UjIEXTJRrv15 -cTMSjAP+KZCfuoRsF8aTB42cvaN+Zb5xti1UuIASiWOo8vwubkw36yg5De5mjmrMt35EQZz5 -c0NmOdrPhM4lhCLFXdnmZYLb+fVQ5l1Jps8Suw+R9tLXBXZW0naW3CTHEEq5FNKq/gs08bPC -BwZVTkjwCca4U05TlBVw1EaKQ4p1vXMuKZ+KOuU/7mGkuGUoLiDsUdiMwE5gtdGxeDoV1xIC -NPWRfdF1Vq4J0+enYXtR1Hsf0b6XGTEm+ROXSZoJD9YLv5s2at0ZS5NzlF7YBEVn0Sr4xst8 -J93peP//bJVR0+WvcCfkw/rxm5dJSOcmmOZDRybLxLvfaQimMcXziKBvTexBCxhMbBSZCZpm -D4RIX398204YEXTci7aEWBKSj+PxsGa0GKpZd6MjC3LrzcBv3+aL1v2665HOxLrAqolF8Dqs -B0ack2LFLIBVM1XSr8U5bHJfsbmfRo+ozMKW1zRbfiGxi3JU6NZdC43BXq2dtFuegsZBc4wp -ZFUYD1E/OkiAPJFkDT5fgjjnzDY/owEY/+1waEq6FOnfce3GQSO5MCVXkRm0p3PwTGv/kURi -I/vg5ZHwjfqj3GOWcTMO/PKumwX4hV4HSZOQHAIqgR8mTDA69yn9 -@<:@end@:>@ -]) +AT_CHECK((echo address@hidden; echo address@hidden) | MONOTONE genkey address@hidden, [], [ignore], [ignore]) -AT_CHECK(MONOTONE read < key.txt, [], [ignore], [ignore]) - AT_CHECK(MONOTONE privkey address@hidden, [], [stdout], [ignore]) AT_CHECK(QGREP('address@hidden' stdout), []) ============================================================ --- tests/t_read_privkey.at +++ tests/t_read_privkey.at d03aae665c6a20fb4434dc2004a7ca37171027d5 @@ -0,0 +1,35 @@ +AT_SETUP([read and convert old privkey packet]) +MONOTONE_SETUP + +# this is an old privkey generated with 0.23 + +AT_DATA(pkt, [@<:@privkey address@hidden@:>@ +LKWvWrFPIkgZbnvBr/ZUFYHUE33psk0itcGSVbVK8BFGJz+M34Ys/OxizUNtkHRey6ttZg65 +/sCeKWjfJ8eV5zcyNC+V6KwZiG5EooOu+7fRN8ksIeiMvvgCM4RFPokmPrT9P4REEZ0CfVKr +m4CUlyDF94uq/gBEuhXuuzAJVchzfw+j6dt3krB4btgDdHAu6Wo9vKbJnJrd6hGqJPWs/Emb +6n/5ObzL8EiqOMRlfjUYw8rWmQoRPtTCKtj4hvfnsnvOhX3E/TWdm7keSpK/mfHNx8ldWdII +/dZgBHXWfUreALln2ZCm4/dPPfFEnZHEIjY/NcCmoVLzh4vZol/6e6VLCyQAS155VlDN2/vY +R3MFDBv6qX45+sAMX8KPebiVrxBT+eyt3uXGQQLnarTBQQ6/4QSe/MCaIXTc/IP4f6kxriLo +e0r66zpKFFQmP9jBWQaIcD/QW26L5Xr2DI1ANKE8ynulzHMSBdbEASFA5ZHFQgwJvqKgOZ1T +UG6cSKzRPSqCYGwKhoRjwwYWvC57E3bsgXDnSdrLhBr7Fxt318UeDr7qOmcrzIHQyC6sw3AQ +FKPvBENrfkDI5nbEW3Nd//wCFm374sozh4eleg5KLQbmgD0EJ1TqEaPb9jB/iBKq/tXcSTBJ +cEKrXluN07CjYLhmr0gSVMtA60O8lnvxtgQNLOWrVziA+mqa9sq88zaIC7nXYOsiE5IdHAbh +GPY/hCVVdq/jZOX1dCmh923NWZfTHOXK3lNzcYkUZjx9CUHoiUh4eUpq3XMJBy63BRQ7z5Ry +vvQ+v3hYrpSnBocemFP1/aDAKUYlvvuzh5ojgvHXVKeEbgaXf/E9IQ== +@<:@end@:>@ +]) + +AT_CHECK(MONOTONE read pkt, [], [ignore], [stderr]) +AT_CHECK(QGREP "read 1 packet" stderr) +AT_CHECK(MONOTONE ls keys, [], [stdout]) +AT_CHECK(QGREP "address@hidden" stdout) + +ADD_FILE(foo, [foo +]) + +# check that we can use the key we just read +# if it imported wrong, it'll fail by not accepting the passphrase + +AT_CHECK((echo address@hidden; echo address@hidden) | MONOTONE ci -b foo -m bar, [], [ignore], [ignore]) + +AT_CLEANUP ============================================================ --- testsuite.at 80576368fe0f091078e2cff77c2a8c56253a4e0c +++ testsuite.at bdc90ade96c294f4b14b061e1e6d0adbf002f60c @@ -757,3 +757,4 @@ m4_include(tests/t_database_sig_cleanup.at) m4_include(tests/t_update_switch_branch.at) m4_include(tests/t_mixed_case_pwd.at) +m4_include(tests/t_read_privkey.at)