std::string overkey(const Key::Ptr & key){ std::string key_str = key -> raw(); // remove private data by copying over to Tag 6 Tag6 tag6(key_str); key_str = tag6.raw(); return "\x99" + unhexlify(makehex(key_str.size(), 4)) + key_str; }
TEST(Tag6, read_write) { const std::string raw = std::string(1, version) + unhexlify(makehex(timestamp, 8)) + std::string(1, pka) + OpenPGP::write_MPI(mpi[0]) + OpenPGP::write_MPI(mpi[1]); OpenPGP::Packet::Tag6 tag6(raw); TAG6_EQ(tag6); EXPECT_EQ(tag6.raw(), raw); }
PGPPublicKey revoke_with_cert(const PGPPublicKey & pub, PGPPublicKey & revoke){ if (pub.get_ASCII_Armor() != 1){ throw std::runtime_error("Error: A public key is required."); } if (revoke.get_ASCII_Armor() != 1){ throw std::runtime_error("Error: A revocation signature is required."); } // only expects 1 signature packet if (!revoke.get_packets().size()){ throw std::runtime_error("Error: No packets found in revocation key."); } if (revoke.get_packets().size() > 1){ std::cerr << "Warning: Multiple packets found. Only reading first packet." << std::endl; } if (revoke.get_packets()[0] -> get_tag() != 2){ throw std::runtime_error("Error: Packet is not a signature packet"); } std::string raw = revoke.get_packets()[0] -> raw(); Tag2::Ptr tag2 = std::make_shared<Tag2>(raw); if ((tag2 -> get_type() != 0x20) && (tag2 -> get_type() != 0x28)){ std::stringstream s; s << static_cast <unsigned int> (tag2->get_type()); throw std::runtime_error("Error: Invalid signature type found: " + s.str()); } // which packet to look for uint8_t which = (tag2 -> get_type() == 0x20)?6:14; std::string r_keyid = tag2 -> get_keyid(); std::string k_keyid = ""; if (!r_keyid.size()){ throw std::runtime_error("Error: No key id found."); } // find key with key id for(Packet::Ptr const & p: pub.get_packets()){ if (p -> get_tag() == which){ raw = p -> raw(); Tag6 tag6(raw); k_keyid = tag6.get_keyid(); break; } } if (r_keyid != k_keyid){ throw std::runtime_error("Error: Revocation Certificate does not revoke this Public Key."); } if (!verify_revoke(pub, revoke)){ throw std::runtime_error("Error: This revocation certificate was not signed by this key."); } // Create output key PGPPublicKey revoked(pub); std::vector <Packet::Ptr> old_packets = pub.get_packets_clone(); std::vector <Packet::Ptr> new_packets; unsigned int i = 0; // push all packets up to and including revoked packet into new packets do{ new_packets.push_back(old_packets[i]); } while ((i < old_packets.size()) && (old_packets[i++] -> get_tag() != which)); // append revocation signature to key new_packets.push_back(tag2); // append rest of packets while (i < old_packets.size()){ new_packets.push_back(old_packets[i++]); } revoked.set_packets(new_packets); // clear out data tag2.reset(); old_packets.clear(); new_packets.clear(); return revoked; }