// returns formatted length string // partial takes precedence over octets std::string write_old_length(const uint8_t tag, const std::string & data, const Packet::PartialBodyLength part, uint8_t octets) { std::string::size_type length = data.size(); std::string out(1, 0x80 | (tag << 2)); // old header: 10TT TTLL if (part == Packet::PARTIAL) { // partial out[0] |= 3; } else{ // try to use user requested octet length if (octets == 1) { if (length > 255) { octets = 0; } } else if (octets == 2) { if (length > 65535) { octets = 0; } } else if ((octets == 3) || (octets == 4) || (octets > 5)) { octets = 0; } // 1 octet if ((octets == 1) || // user requested ((octets == 0) && // default (length < 256))) { out[0] |= 0; out += std::string(1, length); } // 2 octest else if ((octets == 2) || // user requested ((octets == 0) && // default (256 <= length) && (length < 65536))) { out[0] |= 1; out += unhexlify(makehex(length, 4)); } // 5 octets else if ((octets == 5) || // use requested ((octets == 0) && // default (65536 <= length))) { out[0] |= 2; out += unhexlify(makehex(length, 8)); } } return out + data; }
TEST(Tag2Sub3, read_write) { const std::string raw = unhexlify(makehex(dt, 8)); OpenPGP::Subpacket::Tag2::Sub3 sub3(raw); TAG2_SUB3_EQ(sub3); EXPECT_EQ(sub3.raw(), raw); }
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(test_encoder, test_encode_unicode_string) { char in[4]; unhexlify((uint8_t*)in, "e284a2"); in[3] = '\0'; uint8_t data[4]; pb_ostream_t stream = pb_ostream_from_buffer(data, sizeof(data)); ASSERT_EQ(KRPC_OK, krpc_encode_string(&stream, in)); ASSERT_EQ("03e284a2", hexlify(data, stream.bytes_written)); }
TEST(SHA512Test, test_sha512_short_msg) { ASSERT_EQ(SHA512_SHORT_MSG.size(), SHA512_SHORT_MSG_HEXDIGEST.size()); for ( unsigned int i = 0; i < SHA512_SHORT_MSG.size(); ++i ) { auto sha512 = SHA512(unhexlify(SHA512_SHORT_MSG[i])); EXPECT_EQ(sha512.hexdigest(), SHA512_SHORT_MSG_HEXDIGEST[i]); } }
std::string certification(uint8_t version, const ID::Ptr & id){ if (version == 3){ return id -> raw(); } else if (version == 4){ std::string data = id -> raw(); if (id -> get_tag() == 13){ // User ID packet return "\xb4" + unhexlify(makehex(data.size(), 8)) + data; } else if (id -> get_tag() == 17){// User Attribute packet return "\xd1" + unhexlify(makehex(data.size(), 8)) + data; } } else{ std::stringstream s; s << static_cast <unsigned int> (version); throw std::runtime_error("Error: Certification for version " + s.str() + " not defined."); } return ""; // should never reach here; mainly just to remove compiler warnings }
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); }
TEST(Tag7, 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]) + std::string(1, s2k_con) + secret; OpenPGP::Packet::Tag7 tag7(raw); TAG7_EQ(tag7); EXPECT_EQ(tag7.raw(), raw); }
std::string addtrailer(const std::string & data, const Tag2::Ptr & sig){ std::string trailer = sig -> get_up_to_hashed(); if (sig -> get_version() == 3){ return data + trailer.substr(1, trailer.size() - 1); // remove version from trailer } else if (sig -> get_version() == 4){ return data + trailer + "\x04\xff" + unhexlify(makehex(trailer.size(), 8)); } else{ std::stringstream s; s << static_cast <unsigned int> (sig -> get_version()); throw std::runtime_error("Error: addtrailer for version " + s.str() + " not defined."); } return ""; // should never reach here; mainly just to remove compiler warnings }
/* get the node value of a single line */ static PyObject *nodeof(line *l) { char *s = l->start; ssize_t llen = pathlen(l); PyObject *hash = unhexlify(s + llen + 1, 40); if (!hash) { return NULL; } if (l->hash_suffix != '\0') { char newhash[21]; memcpy(newhash, PyString_AsString(hash), 20); Py_DECREF(hash); newhash[20] = l->hash_suffix; hash = PyString_FromStringAndSize(newhash, 21); } return hash; }
TEST(RSA, sign_pkcs1_v1_5) { ASSERT_EQ(RSA_SIGGEN_N.size(), RSA_SIGGEN_D.size()); auto e = OpenPGP::hextompi(RSA_SIGGEN_E); for ( unsigned int i = 0; i < RSA_SIGGEN_N.size(); ++i ) { auto n = OpenPGP::hextompi(RSA_SIGGEN_N[i]); auto d = OpenPGP::hextompi(RSA_SIGGEN_D[i]); for ( unsigned int x = 0; x < RSA_SIGGEN_MSG[i].size(); ++x ) { auto msg = RSA_SIGGEN_MSG[i][x]; int h = std::get<0>(msg); std::string data = unhexlify(std::get<1>(msg)); std::string digest = OpenPGP::Hash::use(h, data); auto ret = OpenPGP::Sign::with_pka(digest, PKA_RSA, {d}, {n, e}, h); ASSERT_EQ(ret.size(), (std::size_t) 1); EXPECT_EQ(OpenPGP::mpitohex(ret[0]), RSA_SIGGEN_SIG[i][x]); EXPECT_EQ(OpenPGP::Verify::with_pka(digest, h, PKA_RSA, {n, e}, {OpenPGP::hextompi(RSA_SIGGEN_SIG[i][x])}), true); } } }
std::string CAST256::run(const std::string & DATA){ if (!keyset){ throw std::runtime_error("Error: Key has not been set."); } if (DATA.size() != 16){ throw std::runtime_error("Error: Data must be 128 bits in length."); } A = toint(DATA.substr(0, 4), 256); B = toint(DATA.substr(4, 4), 256); C = toint(DATA.substr(8, 4), 256); D = toint(DATA.substr(12, 4), 256); for(uint8_t i = 0; i < 6; i++){ Q(i); } for(uint8_t i = 6; i < 12; i++){ QBAR(i); } return unhexlify(makehex(A, 8) + makehex(B, 8) + makehex(C, 8) + makehex(D, 8)); }
std::string IDEA::run(const std::string & DATA){ if (!keyset){ throw std::runtime_error("Error: Key has not been set"); } if (DATA.size() != 8){ throw std::runtime_error("Error: Data must be 64 bits in length."); } uint16_t x1 = toint(DATA.substr(0, 2), 256); uint16_t x2 = toint(DATA.substr(2, 2), 256); uint16_t x3 = toint(DATA.substr(4, 2), 256); uint16_t x4 = toint(DATA.substr(6, 2), 256); for(uint8_t x = 0; x < 8; x++){ uint16_t t1 = mult(x1, keys[x][0]); uint16_t t2 = static_cast <uint16_t> (x2 + keys[x][1]); uint16_t t3 = static_cast <uint16_t> (x3 + keys[x][2]); uint16_t t4 = mult(x4, keys[x][3]); uint16_t t5 = t1 ^ t3; uint16_t t6 = t2 ^ t4; uint16_t t7 = mult(t5, keys[x][4]); uint16_t t8 = static_cast <uint16_t> (t6 + t7); uint16_t t9 = mult(t8, keys[x][5]); uint16_t t10 = static_cast <uint16_t> (t7 + t9); x1 = t1 ^ t9; x2 = t3 ^ t9; x3 = t2 ^ t10; x4 = t4 ^ t10; } std::swap(x2, x3); x1 = mult(x1, keys[8][0]); x2 = static_cast <uint16_t> (x2 + keys[8][1]); x3 = static_cast <uint16_t> (x3 + keys[8][2]); x4 = mult(x4, keys[8][3]); return unhexlify(makehex(x1, 4) + makehex(x2, 4) + makehex(x3, 4) + makehex(x4, 4)); }
std::string Sub3::raw() const { return unhexlify(makehex(dt, 8)); }
std::string Sub20::raw() const { return flags + unhexlify(makehex(m.size(), 4)) + unhexlify(makehex(n.size(), 4)) + m + n; }
static convert_from_flat_result_t convert_from_flat_helper( from_flat_state_t *state, char *manifest, size_t manifest_sz) { // open the root directory node. open_folder_t *folder = &state->folders[0]; folder->subfolder_name = "/"; folder->subfolder_name_sz = 1; folder->in_use = true; state->open_folder_count++; for (size_t ptr = 0; ptr < manifest_sz;) { // filename is up to the first null. process_path_result_t pp_result = process_path( state, &manifest[ptr], manifest_sz - ptr); switch (pp_result.code) { case PROCESS_PATH_OOM: return COMPOUND_LITERAL(convert_from_flat_result_t) { CONVERT_FROM_FLAT_OOM, NULL}; case PROCESS_PATH_CORRUPT: return COMPOUND_LITERAL(convert_from_flat_result_t) { CONVERT_FROM_FLAT_WTF, NULL}; case PROCESS_PATH_OK: break; } assert(pp_result.code == PROCESS_PATH_OK); node_t *node = pp_result.node; ptr += pp_result.bytes_consumed; size_t remaining = manifest_sz - ptr; if (remaining <= SHA1_BYTES * 2) { // not enough characters for the checksum and the NL. well, that's a // fail. return COMPOUND_LITERAL(convert_from_flat_result_t) { CONVERT_FROM_FLAT_WTF, NULL}; } if (unhexlify(&manifest[ptr], SHA1_BYTES * 2, node->checksum) == false) { return COMPOUND_LITERAL(convert_from_flat_result_t) { CONVERT_FROM_FLAT_WTF, NULL}; } node->checksum_sz = SHA1_BYTES; node->checksum_valid = true; ptr += SHA1_BYTES * 2; // is the next character a NL? if so, then we're done. otherwise, retrieve // it as the flags field. if (manifest[ptr] != '\n') { node->flags = manifest[ptr]; ptr++; } else { node->flags = 0; } ptr++; state->tree->num_leaf_nodes++; } // close the root folder. close_folder_result_t close_result = close_folder(state, 0); if (close_result.code == CLOSE_FOLDER_OOM) { return COMPOUND_LITERAL(convert_from_flat_result_t) { CONVERT_FROM_FLAT_OOM, NULL}; } close_result.node->type = TYPE_ROOT; add_child(state->tree->shadow_root, close_result.node); return COMPOUND_LITERAL(convert_from_flat_result_t) { CONVERT_FROM_FLAT_OK, state->tree}; }
std::string to_sign_50(const Tag2 & sig, const Tag2::Ptr & /*tag2*/){ std::string data = sig.get_without_unhashed(); return "\x88" + unhexlify(makehex(data.size(), 8)) + data; }
std::string SHA512::hexdigest() { context tmp = ctx; uint64_t size = stack.size(); std::string last = stack + "\x80" + std::string((((size & 127) > 111)?239:111) - (size & 127), 0) + unhexlify(makehex((clen+size) << 3, 32)); calc(last, tmp); return makehex(tmp.h0, 16) + makehex(tmp.h1, 16) + makehex(tmp.h2, 16) + makehex(tmp.h3, 16) + makehex(tmp.h4, 16) + makehex(tmp.h5, 16) + makehex(tmp.h6, 16) + makehex(tmp.h7, 16); }
std::string DES::run(const std::string & DATA){ if (!keyset){ throw std::runtime_error("Error: Key has not been set."); } if (DATA.size() != 8){ throw std::runtime_error("Error: Data must be 64 bits in length."); } std::string data = "", temp = ""; for(uint8_t x = 0; x < 8; x++){ data += makebin(static_cast <uint8_t> (DATA[x]), 8); } // IP for(uint8_t x = 0; x < 64; x++){ temp += data[DES_IP[x] - 1]; } data = temp; for(uint8_t x = 0; x < 16; x++){ // split left and right and duplicate right std::string left = data.substr(0, 32); std::string right = data.substr(32, 32); std::string old_right = right; // expand right side uint64_t t = 0; temp = ""; for(uint8_t y = 0; y < 48; y++){ temp += right[DES_EX[y] - 1]; } t = toint(temp, 2); // expanded_right xor key right = makebin(t ^ keys[x], 48); // split right into 8 parts std::string RIGHT[8]; for(uint8_t y = 0; y < 8; y++){ RIGHT[y] = right.substr(6 * y, 6); } // use sboxes temp = ""; for(uint8_t y = 0; y < 8; y++){ std::string s = ""; s += RIGHT[y][0]; s += RIGHT[y][5]; temp += makebin(DES_S_BOX[y][toint(s, 2)][toint(RIGHT[y].substr(1, 4), 2)], 4); } // permutate right = ""; for(uint8_t y = 0; y < 32; y++){ right += temp[DES_P[y]-1]; } // right xor left and combine with old right data = old_right + makebin(toint(left, 2) ^ toint(right, 2), 32); } // reverse last switch data = data.substr(32, 32) + data.substr(0, 32); // IP^-1 uint64_t out = 0; for(uint8_t x = 0; x < 64; x++){ out += static_cast <uint64_t> (data[DES_INVIP[x] - 1] == '1') << (63 - x); } return unhexlify(makehex(out, 16)); }
} else{ std::stringstream s; s << static_cast <unsigned int> (pka); throw std::runtime_error("Error: PKA number " + s.str() + " not allowed or unknown."); } return {}; // should never reach here; mainly just to remove compiler warnings } std::vector <PGPMPI> pka_encrypt(const uint8_t pka, const std::string & data, const std::vector <PGPMPI> & pub){ return pka_encrypt(pka, rawtompi(data), pub); } Packet::Ptr encrypt_data(const std::string & session_key, const std::string & data, const std::string & filename, const uint8_t sym_alg, const uint8_t comp, const bool mdc, const PGPSecretKey::Ptr & signer, const std::string & sig_passphrase){ // generate prefix uint16_t BS = Symmetric_Algorithm_Block_Length.at(Symmetric_Algorithms.at(sym_alg)) >> 3; std::string prefix = unhexlify(zfill(bintohex(BBS().rand(BS << 3)), BS << 1, '0')); std::string to_encrypt; // put data in Literal Data Packet Tag11 tag11; tag11.set_format('t'); tag11.set_filename(filename); tag11.set_time(0); tag11.set_literal(data); to_encrypt = tag11.write(2); // // if message is to be signed // if (signer){ // // find preferred hash and compression algorithms of the signer