# # # patch "cert.cc" # from [1c70b1dfcbaad3c189b5c4a427ceed49271eb416] # to [7085104c5883eac077e0aec090559279b25a7bff] # # patch "cert.hh" # from [1e8a8efe49dbc5fce5b37d1f3d2a193299745337] # to [a4a81eb418cd6a9ac0d79c47ab2376a9fe2a1999] # # patch "database.cc" # from [740238591234f3300f543dfde1f1661f74d794e6] # to [531d8e9f50ca3321e36abbd8d03797ea55b15c27] # # patch "database.hh" # from [e051b0dd5eca6894ae8bfc7a734d04f2ca7c7c52] # to [3a3eb474823b087fda8af2813e8f503b53a8c76e] # # patch "migrate_schema.cc" # from [0dd8011da6b286ac902294f79107909c6fdd35df] # to [9a6e368654792628c71f636433df270cf8a93d65] # # patch "netsync.cc" # from [0e92e7594fd82cf3e3b89ee5285e5ed7eab03828] # to [993bfd387d60a57bd06843d6ebb1f5521cca5575] # # patch "project.cc" # from [8f652daf294704da0bc1a4617fc003e6911a99e2] # to [0ddb4808db30f531e639622b0b21b8380ca95982] # # patch "project.hh" # from [4738c610b3c8115d55913a130f8f2f7672cff6c7] # to [e62f10cec3dee378d94ae1527f2355e3115d03cb] # ============================================================ --- cert.cc 1c70b1dfcbaad3c189b5c4a427ceed49271eb416 +++ cert.cc 7085104c5883eac077e0aec090559279b25a7bff @@ -10,6 +10,7 @@ #include "base.hh" #include "cert.hh" #include "constants.hh" +#include "database.hh" // lookup key name for hashing #include "netio.hh" #include "simplestring_xform.hh" #include "transforms.hh" @@ -43,7 +44,7 @@ static void // netio support static void -read_cert(string const & in, cert & t) +read_cert(database & db, string const & in, cert & t) { size_t pos = 0; id hash = id(extract_substring(in, pos, @@ -66,33 +67,36 @@ read_cert(string const & in, cert & t) key_id(key, origin::network), rsa_sha1_signature(sig, origin::network)); + + key_name keyname; + rsa_pub_key junk; + db.get_pubkey(tmp.key, keyname, junk); + id check; - tmp.hash_code(check); + tmp.hash_code(keyname, check); if (!(check == hash)) throw bad_decode(F("calculated cert hash '%s' does not match '%s'") % check % hash); t = tmp; } -cert::cert(std::string const & s) +cert::cert(database & db, std::string const & s) { - read_cert(s, *this); + read_cert(db, s, *this); } -cert::cert(std::string const & s, origin::type m) +cert::cert(database & db, std::string const & s, origin::type m) : origin_aware(m) { - read_cert(s, *this); + read_cert(db, s, *this); } void -cert::marshal_for_netio(string & out) const +cert::marshal_for_netio(key_name const & keyname, string & out) const { - string name, key; id hash; + hash_code(keyname, hash); - hash_code(hash); - out.append(hash()); out.append(this->ident.inner()()); insert_variable_length_string(this->name(), out); @@ -124,21 +128,26 @@ void } void -cert::hash_code(id & out) const +cert::hash_code(key_name const & keyname, id & out) const { + base64 sig_encoded(encode_base64(this->sig)); + base64 val_encoded(encode_base64(this->value)); + string ident_encoded(encode_hexenc(this->ident.inner()(), + this->ident.inner().made_from)); string tmp; - tmp.reserve(4 + ident.inner()().size() - + this->name().size() + value().size() - + this->key.inner()().size() + sig().size()); - tmp.append(ident.inner()()); + tmp.reserve(4 + ident_encoded.size() + + this->name().size() + val_encoded().size() + + this->key.inner()().size() + sig_encoded().size()); + + tmp.append(ident_encoded); tmp += ':'; tmp.append(this->name()); tmp += ':'; - tmp.append(value()); + append_without_ws(tmp, val_encoded()); tmp += ':'; - tmp.append(this->key.inner()()); + tmp.append(keyname()); tmp += ':'; - tmp.append(sig()); + append_without_ws(tmp, sig_encoded()); data tdat(tmp, origin::internal); calculate_ident(tdat, out); ============================================================ --- cert.hh 1e8a8efe49dbc5fce5b37d1f3d2a193299745337 +++ cert.hh a4a81eb418cd6a9ac0d79c47ab2376a9fe2a1999 @@ -12,6 +12,8 @@ #include "vocab.hh" +class database; + // Certs associate an opaque name/value pair with a revision ID, and // are accompanied by an RSA public-key signature attesting to the // association. Users can write as much extra meta-data as they like @@ -38,8 +40,8 @@ struct cert : public origin_aware {} // These understand the netsync serialization. - explicit cert(std::string const & s); - cert(std::string const & s, origin::type m); + cert(database & db, std::string const & s); + cert(database & db, std::string const & s, origin::type m); revision_id ident; cert_name name; @@ -50,9 +52,9 @@ struct cert : public origin_aware bool operator<(cert const & other) const; bool operator==(cert const & other) const; - void hash_code(id & out) const; + void hash_code(key_name const & keyname, id & out) const; void signable_text(std::string & out) const; - void marshal_for_netio(std::string & out) const; + void marshal_for_netio(key_name const & keyname, std::string & out) const; }; #endif // __CERT_HH__ ============================================================ --- database.cc 740238591234f3300f543dfde1f1661f74d794e6 +++ database.cc 531d8e9f50ca3321e36abbd8d03797ea55b15c27 @@ -375,6 +375,8 @@ private: void put_cert(cert const & t, string const & table); void results_to_certs(results const & res, vector & certs); + void results_to_certs(results const & res, + vector > & certs); void oldstyle_results_to_certs(results const & res, vector & certs); @@ -410,7 +412,7 @@ private: void get_certs(cert_name const & name, cert_value const & val, - vector & certs, + vector > & certs, string const & table); outdated_indicator_factory cert_stamper; @@ -3124,8 +3126,14 @@ database_impl::put_cert(cert const & t, database_impl::put_cert(cert const & t, string const & table) { + results res; + fetch(res, 1, one_row, + query("SELECT name FROM public_keys WHERE id = ?") + % blob(t.key.inner()())); + key_name keyname(res[0][0], origin::database); + id thash; - t.hash_code(thash); + t.hash_code(keyname, thash); rsa_sha1_signature sig; string insert = "INSERT INTO " + table + " VALUES(?, ?, ?, ?, ?, ?)"; @@ -3157,6 +3165,24 @@ void } void +database_impl::results_to_certs(results const & res, + vector > & certs) +{ + certs.clear(); + for (size_t i = 0; i < res.size(); ++i) + { + cert t; + t = cert(revision_id(res[i][0], origin::database), + cert_name(res[i][1], origin::database), + cert_value(res[i][2], origin::database), + key_id(res[i][3], origin::database), + rsa_sha1_signature(res[i][4], origin::database)); + certs.push_back(make_pair(id(res[i][5], origin::database), + t)); + } +} + +void database_impl::oldstyle_results_to_certs(results const & res, vector & certs) { @@ -3288,14 +3314,14 @@ database_impl::get_certs(cert_name const void database_impl::get_certs(cert_name const & name, cert_value const & val, - vector & certs, + vector > & certs, string const & table) { results res; - query q("SELECT revision_id, name, value, keypair_id, signature FROM " + table + + query q("SELECT revision_id, name, value, keypair_id, signature, hash FROM " + table + " WHERE name = ? AND value = ?"); - fetch(res, 5, any_rows, + fetch(res, 6, any_rows, q % text(name()) % blob(val())); results_to_certs(res, certs); @@ -3425,7 +3451,7 @@ database::get_revision_certs(cert_name c outdated_indicator database::get_revision_certs(cert_name const & name, cert_value const & val, - vector & certs) + vector > & certs) { imp->get_certs(name, val, certs, "revision_certs"); return imp->cert_stamper.get_indicator(); ============================================================ --- database.hh e051b0dd5eca6894ae8bfc7a734d04f2ca7c7c52 +++ database.hh 3a3eb474823b087fda8af2813e8f503b53a8c76e @@ -287,8 +287,8 @@ public: // Only used by get_branch_certs (project.cc) outdated_indicator get_revision_certs(cert_name const & name, - cert_value const & val, - std::vector & certs); + cert_value const & val, + std::vector > & certs); // Only used by revision_is_in_branch (project.cc) outdated_indicator get_revision_certs(revision_id const & ident, ============================================================ --- migrate_schema.cc 0dd8011da6b286ac902294f79107909c6fdd35df +++ migrate_schema.cc 9a6e368654792628c71f636433df270cf8a93d65 @@ -748,8 +748,7 @@ char const migrate_certs_to_key_hash[] = "CREATE INDEX revision_certs__revision_id ON revision_certs (revision_id);\n" "INSERT INTO revision_certs(hash, revision_id, name, value, keypair_id, signature)\n" - "SELECT sha1(':', a.id, a.name, a.value, b.id, a.signature), " - " a.id, a.name, a.value, b.id, a.signature\n" + "SELECT a.hash, a.id, a.name, a.value, b.id, a.signature\n" "FROM revision_certs_tmp a JOIN public_keys b\n" "ON a.keypair = b.name;\n" ============================================================ --- netsync.cc 0e92e7594fd82cf3e3b89ee5285e5ed7eab03828 +++ netsync.cc 993bfd387d60a57bd06843d6ebb1f5521cca5575 @@ -1134,7 +1134,10 @@ session::note_cert(id const & i) cert c; string str; project.db.get_revision_cert(i, c); - c.marshal_for_netio(str); + key_name keyname; + rsa_pub_key junk; + project.db.get_pubkey(c.key, keyname, junk); + c.marshal_for_netio(keyname, str); queue_data_cmd(cert_item, i, str); sent_certs.push_back(c); } @@ -2261,7 +2264,10 @@ session::load_data(netcmd_item_type type cert c; project.db.get_revision_cert(item, c); string tmp; - c.marshal_for_netio(out); + key_name keyname; + rsa_pub_key junk; + project.db.get_pubkey(c.key, keyname, junk); + c.marshal_for_netio(keyname, out); } break; } @@ -2359,9 +2365,12 @@ session::process_data_cmd(netcmd_item_ty case cert_item: { - cert c(dat); + cert c(project.db, dat); + key_name keyname; + rsa_pub_key junk; + project.db.get_pubkey(c.key, keyname, junk); id tmp; - c.hash_code(tmp); + c.hash_code(keyname, tmp); if (! (tmp == item)) throw bad_decode(F("hash check failed for revision cert '%s'") % hitem()); if (project.db.put_revision_cert(c)) @@ -3459,21 +3468,19 @@ session::rebuild_merkle_trees(set certs; + vector > certs; project.get_branch_certs(*i, certs); - for (vector::const_iterator j = certs.begin(); + for (vector >::const_iterator j = certs.begin(); j != certs.end(); j++) { - revision_id rid(j->ident); + revision_id rid(j->second.ident); insert_with_parents(rid, rev_refiner, rev_enumerator, revision_ids, revisions_ticker); // Branch certs go in here, others later on. - id item; - j->hash_code(item); - cert_refiner.note_local_item(item); - rev_enumerator.note_cert(rid, item); - if (inserted_keys.find(j->key) == inserted_keys.end()) - inserted_keys.insert(j->key); + cert_refiner.note_local_item(j->first); + rev_enumerator.note_cert(rid, j->first); + if (inserted_keys.find(j->second.key) == inserted_keys.end()) + inserted_keys.insert(j->second.key); } } } ============================================================ --- project.cc 8f652daf294704da0bc1a4617fc003e6911a99e2 +++ project.cc 0ddb4808db30f531e639622b0b21b8380ca95982 @@ -295,7 +295,7 @@ project_t::get_branch_certs(branch_name outdated_indicator project_t::get_branch_certs(branch_name const & branch, - vector & certs) + vector > & certs) { return db.get_revision_certs(branch_cert_name, typecast_vocab(branch), certs); ============================================================ --- project.hh 4738c610b3c8115d55913a130f8f2f7672cff6c7 +++ project.hh e62f10cec3dee378d94ae1527f2355e3115d03cb @@ -120,7 +120,7 @@ public: outdated_indicator get_revision_branches(revision_id const & id, std::set & branches); outdated_indicator get_branch_certs(branch_name const & branch, - std::vector & certs); + std::vector > & certs); void put_standard_certs(key_store & keys, revision_id const & id,