#include #include #include "pgpkey.h" #include #include #define PGP_PACKET_TAG_PUBLIC_KEY 6 #define PGP_PACKET_TAG_USER_ID 13 #define PGP_PACKET_TAG_SIGNATURE 2 #define PGP_CRC24_INIT 0xB704CEL #define PGP_CRC24_POLY 0x1864CFBL #define PGP_CERTIFICATE_START_STRING "-----BEGIN PGP PUBLIC KEY BLOCK-----" #define PGP_CERTIFICATE_END_STRING "-----END PGP PUBLIC KEY BLOCK-----" // // All size are big endian // MPI: 2 bytes size (length in bits) + string of octets // bool PGPKeyManagement::createMinimalKey(const std::string& pgp_certificate,std::string& cleaned_certificate) { try { // 0 - Extract Radix64 portion of the certificate // int n = pgp_certificate.length() ; int i=0 ; std::string version_string = "" ; while(i < n && pgp_certificate[i] != '\n') ++i ; // remove first part -----BEGIN PGP CERTIFICATE----- ++i ; while(i < n && pgp_certificate[i] != '\n') version_string += pgp_certificate[i++] ; // remove first part Version: [fdfdfdf] ++i ; while(i < n && pgp_certificate[i] != '\n') ++i ; // remove blank line ++i ; int j=n-1 ; while(j>0 && pgp_certificate[j] != '=' && j>=i) --j ; std::string radix_cert = pgp_certificate.substr(i,j-i) ; std::cerr << "extracted radix cert: " << std::endl; std::cerr << radix_cert ; // 1 - Convert armored key into binary key // char *keydata = NULL ; size_t len = 0 ; Radix64::decode(radix_cert,keydata,len) ; unsigned char *data = (unsigned char *)keydata ; std::cerr << "Total size: " << len << std::endl; uint8_t packet_tag; uint32_t packet_length ; // 2 - parse key data, only keep public key data, user id and self-signature. bool public_key=false ; bool own_signature=false ; bool user_id=false ; while(true) { PGPKeyParser::read_packetHeader(data,packet_tag,packet_length) ; std::cerr << "Header:" << std::endl; std::cerr << " Packet tag: " << (int)packet_tag << std::endl; std::cerr << " Packet length: " << packet_length << std::endl; data += packet_length ; if(packet_tag == PGP_PACKET_TAG_PUBLIC_KEY) public_key = true ; if(packet_tag == PGP_PACKET_TAG_USER_ID) user_id = true ; if(packet_tag == PGP_PACKET_TAG_SIGNATURE) own_signature = true ; if(public_key && own_signature && user_id) break ; if( (uint64_t)data - (uint64_t)keydata >= len ) break ; } std::string outstring ; Radix64::encode(keydata,(uint64_t)data - (uint64_t)keydata,outstring) ; uint32_t crc = compute24bitsCRC((unsigned char *)keydata,(uint64_t)data - (uint64_t)keydata) ; unsigned char tmp[3] = { (crc >> 16) & 0xff, (crc >> 8) & 0xff, crc & 0xff } ; std::string crc_string ; Radix64::encode((const char *)tmp,3,crc_string) ; std::cerr << "After signature pruning: " << std::endl; std::cerr << outstring << std::endl; cleaned_certificate = std::string(PGP_CERTIFICATE_START_STRING) + "\n" + version_string + "\n\n" ; for(uint32_t i=0;i> 2 ; int length_size ; switch(length_type) { case 0: length_size = 1 ; break ; case 1: length_size = 2 ; break ; case 2: length_size = 4 ; break ; default: throw std::runtime_error("Unhandled length type!") ; } packet_length = 0 ; for(int k=0;k