# # patch "ChangeLog" # from [685c474f29d68ac662b431cc8e412343789e1e6d] # to [5c06ef2f363ca1a97d94368001fa85e31d2131f8] # # patch "botan/pkcs8.cpp" # from [6d12f636a9d038c815ba1a19ed4b5dafa2f4a052] # to [4fb05c8f93f40c1596eba7da193d8829d424f10b] # # patch "botan/pkcs8.h" # from [d6bc45f4d153674b5120c345ef1753b7fcbed396] # to [11f18b4308866683969bc31733e13aa023927d64] # # patch "commands.cc" # from [10b5b48c3a9202ae481022dd03ddc778343ab16d] # to [30f92c2f7eee55dda3d43ae5643224edba7c59c1] # # patch "keys.cc" # from [b43ff403dae506d2958e518965ed12c57dc1d93a] # to [7b5ef93c3fcad578dbc30201d66f98d0a62405af] # # patch "packet.cc" # from [ef8866949aab6ca49284575de0c4c63494efe3d1] # to [84ada81f0afdae3f0bb702f6383c91d3b429c0e0] # # patch "testsuite.at" # from [925c7087ae848ad85724183ab80d3a042686571d] # to [48e49271ecdf069dcde09ada32c00900cf66bd5b] # ======================================================================== --- ChangeLog 685c474f29d68ac662b431cc8e412343789e1e6d +++ ChangeLog 5c06ef2f363ca1a97d94368001fa85e31d2131f8 @@ -1,3 +1,12 @@ +2005-09-27 Matt Johnston + + * botan/pkcs8.cc, keys.cc: fix monotone-specific pkcs8 key + parsing. + * commands.cc: ls keys shows keystore-only pubkeys as well + * packet.cc: fix unit tests + * testsuite.at: use keypair packet rather than privkey/pubkey + packets. + 2005-09-26 Matt Johnston * commands.cc, keys.cc, others: use standard ======================================================================== --- botan/pkcs8.cpp 6d12f636a9d038c815ba1a19ed4b5dafa2f4a052 +++ botan/pkcs8.cpp 4fb05c8f93f40c1596eba7da193d8829d424f10b @@ -24,29 +24,18 @@ * Whether it is encrypted will be determined, * * returned in is_encrypted. * *************************************************/ -SecureVector PKCS8_maybe_enc_extract(DataSource& source, - AlgorithmIdentifier& alg_id, - bool& is_encrypted) + SecureVector PKCS8_extract_unencrypted(DataSource& source, + AlgorithmIdentifier& alg_id) { SecureVector enc_pkcs8_key; u32bit version = 0; - is_encrypted = false; try { BER_Decoder decoder(source); BER_Decoder sequence = BER::get_subsequence(decoder); - - try { - BER::decode(sequence, version); - } - catch(Decoding_Error) { - is_encrypted = true; - } - + BER::decode(sequence, version); BER::decode(sequence, alg_id); BER::decode(sequence, enc_pkcs8_key, OCTET_STRING); - if (is_encrypted) - sequence.discard_remaining(); sequence.verify_end(); } catch(Decoding_Error) @@ -57,7 +46,6 @@ if (version != 0) throw Decoding_Error("PKCS #8: Unknown version number"); - return enc_pkcs8_key; } @@ -88,7 +76,8 @@ * PEM decode and/or decrypt a private key * *************************************************/ SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, - AlgorithmIdentifier& pk_alg_id) + AlgorithmIdentifier& pk_alg_id, + bool encrypted = true) { AlgorithmIdentifier pbe_alg_id; SecureVector key_data, key; @@ -97,14 +86,17 @@ try { if(BER::maybe_BER(source) && !PEM_Code::matches(source)) { - key_data = PKCS8_maybe_enc_extract(source, pbe_alg_id, is_encrypted); - if(key_data.is_empty()) - throw Decoding_Error("PKCS #8 private key decoding failed"); - if(!is_encrypted) + if (encrypted) + key_data = PKCS8_extract(source, pbe_alg_id); + else { + // monotone specific, for unencrypted non-PEM + key_data = PKCS8_extract_unencrypted(source, pbe_alg_id); pk_alg_id = pbe_alg_id; return key_data; // just plain unencrypted BER } + if(key_data.is_empty()) + throw Decoding_Error("PKCS #8 private key decoding failed"); } else { @@ -268,11 +260,12 @@ /************************************************* * Extract a private key and return it * *************************************************/ -PKCS8_PrivateKey* load_key(DataSource& source, const User_Interface& ui) +PKCS8_PrivateKey* load_key(DataSource& source, const User_Interface& ui, + bool encrypted) { AlgorithmIdentifier alg_id; - SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); + SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id, encrypted); const std::string alg_name = OIDS::lookup(alg_id.oid); if(alg_name == "") @@ -298,27 +291,30 @@ /************************************************* * Extract a private key and return it * *************************************************/ -PKCS8_PrivateKey* load_key(const std::string& fsname, const User_Interface& ui) +PKCS8_PrivateKey* load_key(const std::string& fsname, const User_Interface& ui, + bool encrypted) { DataSource_Stream source(fsname); - return PKCS8::load_key(source, ui); + return PKCS8::load_key(source, ui, encrypted); } /************************************************* * Extract a private key and return it * *************************************************/ -PKCS8_PrivateKey* load_key(DataSource& source, const std::string& pass) +PKCS8_PrivateKey* load_key(DataSource& source, const std::string& pass, + bool encrypted) { - return PKCS8::load_key(source, User_Interface(pass)); + return PKCS8::load_key(source, User_Interface(pass), encrypted); } /************************************************* * Extract a private key and return it * *************************************************/ -PKCS8_PrivateKey* load_key(const std::string& fsname, const std::string& pass) +PKCS8_PrivateKey* load_key(const std::string& fsname, const std::string& pass, + bool encrypted) { DataSource_Stream source(fsname); - return PKCS8::load_key(source, User_Interface(pass)); + return PKCS8::load_key(source, User_Interface(pass), encrypted); } /************************************************* ======================================================================== --- botan/pkcs8.h d6bc45f4d153674b5120c345ef1753b7fcbed396 +++ botan/pkcs8.h 11f18b4308866683969bc31733e13aa023927d64 @@ -44,11 +44,15 @@ std::string PEM_encode(const PKCS8_PrivateKey&, const std::string&, const std::string& = ""); -PKCS8_PrivateKey* load_key(DataSource&, const User_Interface&); -PKCS8_PrivateKey* load_key(DataSource&, const std::string& = ""); +PKCS8_PrivateKey* load_key(DataSource&, const User_Interface&, + bool encrypted = true); +PKCS8_PrivateKey* load_key(DataSource&, const std::string& = "", + bool encrypted = true); -PKCS8_PrivateKey* load_key(const std::string&, const User_Interface&); -PKCS8_PrivateKey* load_key(const std::string&, const std::string& = ""); +PKCS8_PrivateKey* load_key(const std::string&, const User_Interface&, + bool encrypted = true); +PKCS8_PrivateKey* load_key(const std::string&, const std::string& = "", + bool encrypted = true); PKCS8_PrivateKey* copy_key(const PKCS8_PrivateKey&); ======================================================================== --- commands.cc 10b5b48c3a9202ae481022dd03ddc778343ab16d +++ commands.cc 30f92c2f7eee55dda3d43ae5643224edba7c59c1 @@ -602,51 +602,82 @@ static void ls_keys(string const & name, app_state & app, vector const & args) { - vector pubkeys; - vector privkeys; transaction_guard guard(app.db); + vector pubs; + vector privkeys; if (args.size() == 0) { - app.db.get_key_ids("", pubkeys); + app.db.get_key_ids("", pubs); app.keys.get_key_ids("", privkeys); } else if (args.size() == 1) { - app.db.get_key_ids(idx(args, 0)(), pubkeys); + app.db.get_key_ids(idx(args, 0)(), pubs); app.keys.get_key_ids(idx(args, 0)(), privkeys); } else throw usage(name); + + // true if it is in the database, false otherwise + map pubkeys; + for (vector::const_iterator i = pubs.begin(); + i != pubs.end(); i++) + pubkeys[*i] = true; + bool all_in_db = true; + for (vector::const_iterator i = privkeys.begin(); + i != privkeys.end(); i++) + { + if (pubkeys.find(*i) == pubkeys.end()) + { + pubkeys[*i] = false; + all_in_db = false; + } + } + if (pubkeys.size() > 0) { cout << endl << "[public keys]" << endl; - for (size_t i = 0; i < pubkeys.size(); ++i) + for (map::iterator i = pubkeys.begin(); + i != pubkeys.end(); i++) { - rsa_keypair_id keyid = idx(pubkeys, i)(); base64 pub_encoded; hexenc hash_code; + rsa_keypair_id keyid = i->first; + bool indb = i->second; - app.db.get_key(keyid, pub_encoded); + if (indb) + app.db.get_key(keyid, pub_encoded); + else + { + keypair kp; + app.keys.get_key_pair(keyid, kp); + pub_encoded = kp.pub; + } key_hash_code(keyid, pub_encoded, hash_code); - cout << hash_code << " " << keyid << endl; + if (indb) + cout << hash_code << " " << keyid << endl; + else + cout << hash_code << " " << keyid << " (*)" << endl; } + if (!all_in_db) + cout << "(*) - only in keystore" << endl; cout << endl; } if (privkeys.size() > 0) { cout << endl << "[private keys]" << endl; - for (size_t i = 0; i < privkeys.size(); ++i) + for (vector::iterator i = privkeys.begin(); + i != privkeys.end(); i++) { - rsa_keypair_id keyid = idx(privkeys, i)(); keypair kp; hexenc hash_code; - app.keys.get_key_pair(keyid, kp); - key_hash_code(keyid, kp.priv, hash_code); - cout << hash_code << " " << keyid << endl; + app.keys.get_key_pair(*i, kp); + key_hash_code(*i, kp.priv, hash_code); + cout << hash_code << " " << *i << endl; } cout << endl; } @@ -820,7 +851,7 @@ keypair kp; P(F("generating key-pair '%s'\n") % ident); generate_key_pair(app.lua, ident, kp); - P(F("storing key-pair '%s' in database\n") % ident); + P(F("storing key-pair '%s' in keystore\n") % ident); app.keys.put_key_pair(ident, kp); guard.commit(); ======================================================================== --- keys.cc b43ff403dae506d2958e518965ed12c57dc1d93a +++ keys.cc 7b5ef93c3fcad578dbc30201d66f98d0a62405af @@ -191,11 +191,13 @@ bool force = false; L(F("base64-decoding %d-byte private key\n") % priv().size()); + L(F("priv '%s'\n") % priv()); decode_base64(priv, decoded_key); for (int i = 0; i < 3; ++i) { get_passphrase(lua, id, phrase, false, force); L(F("have %d-byte encrypted private key\n") % decoded_key().size()); + L(F("decoded '%s'\n") % decoded_key()); shared_ptr pkcs8_key; try @@ -258,7 +260,7 @@ { Pipe p; p.process_msg(decrypted_key); - pkcs8_key = shared_ptr(PKCS8::load_key(p)); + pkcs8_key = shared_ptr(PKCS8::load_key(p, "", false)); } catch (...) { @@ -587,14 +589,14 @@ BOOST_CHECKPOINT("signing plaintext"); string plaintext("test string to sign"); base64 sig; - make_signature(app, key, privkey, plaintext, sig); + make_signature(app, key, kp.priv, plaintext, sig); BOOST_CHECKPOINT("checking signature"); - BOOST_CHECK(check_signature(app, key, pubkey, plaintext, sig)); + BOOST_CHECK(check_signature(app, key, kp.pub, plaintext, sig)); string broken_plaintext = plaintext + " ...with a lie"; BOOST_CHECKPOINT("checking non-signature"); - BOOST_CHECK(!check_signature(app, key, pubkey, broken_plaintext, sig)); + BOOST_CHECK(!check_signature(app, key, kp.pub, broken_plaintext, sig)); } void ======================================================================== --- packet.cc ef8866949aab6ca49284575de0c4c63494efe3d1 +++ packet.cc 84ada81f0afdae3f0bb702f6383c91d3b429c0e0 @@ -1552,16 +1552,15 @@ diff(mdata.inner(), mdata2.inner(), del2); pw.consume_manifest_delta(mid, mid2, manifest_delta(del)); + keypair kp; // a public key packet - base64 puk; - encode_base64(rsa_pub_key("this is not a real rsa key"), puk); - pw.consume_public_key(rsa_keypair_id("address@hidden"), puk); + encode_base64(rsa_pub_key("this is not a real rsa key"), kp.pub); + pw.consume_public_key(rsa_keypair_id("address@hidden"), kp.pub); // a private key packet - base64< rsa_priv_key > pik; - encode_base64(rsa_priv_key("this is not a real rsa key either!"), pik); + encode_base64(rsa_priv_key("this is not a real rsa key either!"), kp.priv); - pw.consume_key_pair(rsa_keypair_id("address@hidden"), puk, pik); + pw.consume_key_pair(rsa_keypair_id("address@hidden"), kp); } ======================================================================== --- testsuite.at 925c7087ae848ad85724183ab80d3a042686571d +++ testsuite.at 48e49271ecdf069dcde09ada32c00900cf66bd5b @@ -42,25 +42,25 @@ # 20050..53347. _PORT=`echo $RANDOM | awk 'BEGIN {a=1;srand()} END {printf "%.0f\n", ((rand() * 529 + 20050 + $a) % 64512 + 1024)}'` -AT_DATA(test_keys, [@<:@pubkey address@hidden@:>@ -MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCfN/cAMabgb6T7m8ksGnpQ7LO6hOdnc/7V -yivrRGtmpwSItljht1bmgLQF37KiSPoMEDUb1stfKxaMsYiy8iTyoQ+M2EVFP37n2rtnNZ0H -oVcQd2sRsCerQFh9nslRPymlkQXUlOiNFN6RlFNcdjkucqNe+YorFX21EYw7XuT5XwIBEQ== +AT_DATA(test_keys, [@<:@keypair address@hidden@:>@ +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6Pz+IvvOCDDqzN9WFO/zOjL7s9dVCS+zn +s/L9jQ2kHfNWXFof4GcgmMu4DfU4sUrRz39QxDlUrxEOvmIc9z3DNuIcbFZx7UZg9DWfdmDm +vbW79bZlVMeIudAIUwa6euX163AK5hacmqJfuB5U7awQM9o3rn8JYULleAoz5QTtawIDAQAB# +MIICyTBDBgkqhkiG9w0BBQ0wNjAeBgkqhkiG9w0BBQwwEQQIvYSV8ucj9m4CAggAAgEYMBQG +CCqGSIb3DQMHBAg/BZPM2O3QfASCAoBBGkVz4E/Pr1CsIioC92eCz4qWLclhc53HgHSCEo9I +XdNCTpCs/oxOXhQ0WQCPFhYEaxU8STgZm0Yhq8WEF1QfxOPOU8nDiwMT0L7/ARruu5bTCxnW +B3kkn+XiO5GldVJhULFlrl91t83yMsTSw+vyCyxZkqewBLR7mqHQUe2suVquMyutxxr2vZgV +QMfRxk65fSvySUHeNaj1dmakYcpP+35iejyUTAtAGuBsv2C68bwif4wkpLpedghNCtmccSdQ +t9QDF3yy6Q42tAW/OK6/t836/qn39f+47Kp4LMJUMmxNrtV7IntIkgBGgnGsqP9Br2B4GYXc +sWK0YApA3+Sf3kfH/wQ6Hib8nN4YxUTxxnS9WNHvRFrXCmfbGd5vAzi4lKCm/W+2Nlpd4DDQ +3JZjjCR73PMfKtHJCGULkNkK/9kRyhLYql2u/ZUJoEcdZxzEpYgExW8Wu1CrCVtWd+ueXs1h +or6Fdua7Gg4cjMgVg6EUSxdMBFQCX8heD8JeG6jMFNR9hTxe8o/PK8Ys63JyLMLRUv3Ud+f8 +8T0TtCZV5+rgLfvb6k89uDJJK228WuJB6rp8S+qqq30RFPmkzW8JNulRilY+wrIfcowA6+TA +T5WKzFOIbkZd/R34tNLJMjTJlUq6SQKaOlQnqOEFbyY/GXgzYgnmc3tl8pigXEJvNzU5GiuB +ib35QQbzh87KlfLtWELK+8ZoyhZAZAMr97IavUbuFubOyEoEozUliARyRZ1ZudM4Ii+J6TRX +cmLryIBlz3OXgUUBSwJPwtWuR4tZ8nIt7cVJr7pxLblGfeFuu01HWN55hv4C78/aNSipVYCF +OFt8n7wQHxbbJvoTIdd/ @<:@end@:>@ -@<:@privkey address@hidden@:>@ -npy0jyqbZdylFkMjdR9OvlqmDHuBGXpGFPt94h96aG+Lp+OdBCmWx8GueHk8FKkexwPqhRBM -PPopUeuwqxuSX+yEodMl5IHBmin0nLnbOeBjtasjemBFEmdNl/jPDF/AeQ2WHhanB731dSQc -vzLOQfKAYmfk56PPULi9oJJNUxaCkvsWtvaI+HUHZrjyyV7dA4Vsc6Jvx2Yf1+MdDAEGk/Rw -ZtP0LmuoiyvRDFqBF8aTmnotyb4kRKohnJ7VF+y6hYvmtMpM3TKnpR7EbojBzNPqKuO7nPUz -jGxA7F84O24Vbf128PNSI5vj4istow26aPjn28qPjfRrkV30WLL/dXfYJkfkTqglYnoEXvF/ -xZoVxxNeAX58mgy0A1ErVxv8U7TwuP983GHEpLwy3gbiP+9akAJCr8r823DHmQqq5QDELibP -cuXZfOttpfVRkcbMhjeF0M6czc4HoKgHTAnf/18hzdZwGX/WWvRIBHImbUJ+mDbp2ByDTfKf -ErGXSvZ3HxCqBD8yx1SnXhV8IDHaBmV9wwYcN+H2cxOWGZk7g7xJS19+a3UQB3c3sSXQVJBp -6QpCZgysxkZwzuXDzzLZPT9SLZz4K2p7+7BwMbpy9ZxcyAzmiEtpA24UP06jtjFN7WcXAdx/ -E5Gmoe9b1EiXWdReHjUGpc6k0LQ0PPXAwqrcGdwYbOLDZ5xsQ5AsEYSFtyTS60D1nHBcdNmW -M0eOUJFdJf/uNe/2EApc3a8TyEkZtVqiYtOVV3qDB9NmU4bVOkDqzl1F7zJwATWbmasSdkM3 -6lxDkczBfCrEjH5p5Y8DU+ge4e4LRtknY9oBOJ7EQO0twYJg3k0= -@<:@end@:>@ ]) AT_DATA(test_hooks.lua, [