diff --git a/src/lib/crypto/signatures.cpp b/src/lib/crypto/signatures.cpp index 71b623d08..a932d3c7f 100644 --- a/src/lib/crypto/signatures.cpp +++ b/src/lib/crypto/signatures.cpp @@ -47,7 +47,7 @@ signature_hash_finish(const pgp_signature_t & sig, rnp::Hash & hash, const pgp_literal_hdr_t *hdr) { - hash.add(sig.hashed_data, sig.hashed_len); + hash.add(sig.hashed_data); switch (sig.version) { case PGP_V4: #if defined(ENABLE_CRYPTO_REFRESH) @@ -56,12 +56,12 @@ signature_hash_finish(const pgp_signature_t & sig, { uint8_t trailer[6] = {0x00, 0xff, 0x00, 0x00, 0x00, 0x00}; trailer[0] = sig.version; - write_uint32(&trailer[2], sig.hashed_len); + write_uint32(&trailer[2], sig.hashed_data.size()); hash.add(trailer, 6); break; } case PGP_V5: { - uint64_t hash_len = sig.hashed_len; + uint64_t hash_len = sig.hashed_data.size(); if (sig.is_document()) { uint8_t doc_trailer[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /* This data is not added to the hash_len as per spec */ @@ -96,7 +96,7 @@ signature_init(const pgp_key_pkt_t &key, const pgp_signature_t &sig) #if defined(ENABLE_CRYPTO_REFRESH) if (key.version == PGP_V6) { - hash->add(sig.salt, sig.salt_size); + hash->add(sig.salt); } #endif @@ -132,7 +132,7 @@ signature_calculate(pgp_signature_t & sig, } /* Copy left 16 bits to signature */ - memcpy(sig.lbits, hval.data(), 2); + std::copy(hval.begin(), hval.begin() + 2, sig.lbits.begin()); pgp_signature_material_t material = {}; /* Some algos require used hash algorithm for signing */ @@ -181,7 +181,7 @@ signature_validate(const pgp_signature_t & sig, auto hval = signature_hash_finish(sig, hash, hdr); /* compare lbits */ - if (memcmp(hval.data(), sig.lbits, 2)) { + if (memcmp(hval.data(), sig.lbits.data(), 2)) { RNP_LOG("wrong lbits"); return RNP_ERROR_SIGNATURE_INVALID; } diff --git a/src/lib/pgp-key.cpp b/src/lib/pgp-key.cpp index 3bef122e1..3897f2693 100644 --- a/src/lib/pgp-key.cpp +++ b/src/lib/pgp-key.cpp @@ -2437,8 +2437,8 @@ pgp_key_t::sign_init(rnp::RNG & rng, } #if defined(ENABLE_CRYPTO_REFRESH) if (version == PGP_V6) { - sig.salt_size = rnp::Hash::size(sig.halg) / 2; - rng.get(sig.salt, sig.salt_size); + sig.salt.resize(rnp::Hash::size(sig.halg) / 2); + rng.get(sig.salt.data(), sig.salt.size()); } #endif } diff --git a/src/lib/types.h b/src/lib/types.h index c393213f8..11849c514 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -227,9 +227,9 @@ typedef struct pgp_key_protection_t { uint8_t iv[PGP_MAX_BLOCK_SIZE]; } pgp_key_protection_t; -typedef struct pgp_key_pkt_t pgp_key_pkt_t; -typedef struct pgp_userid_pkt_t pgp_userid_pkt_t; -typedef struct pgp_signature_t pgp_signature_t; +typedef struct pgp_key_pkt_t pgp_key_pkt_t; +typedef struct pgp_userid_pkt_t pgp_userid_pkt_t; +typedef struct pgp_signature_t pgp_signature_t; typedef struct pgp_one_pass_sig_t pgp_one_pass_sig_t; typedef enum { diff --git a/src/librepgp/stream-dump.cpp b/src/librepgp/stream-dump.cpp index 79a7319cb..82f47e042 100644 --- a/src/librepgp/stream-dump.cpp +++ b/src/librepgp/stream-dump.cpp @@ -815,7 +815,7 @@ stream_dump_signature_pkt(rnp_dump_ctx_t *ctx, pgp_signature_t *sig, pgp_dest_t indent_dest_decrease(dst); } - dst_print_hex(dst, "lbits", sig->lbits, sizeof(sig->lbits), false); + dst_print_hex(dst, "lbits", sig->lbits.data(), sig->lbits.size(), false); dst_printf(dst, "signature material:\n"); indent_dest_increase(dst); @@ -2019,7 +2019,7 @@ stream_dump_signature_pkt_json(rnp_dump_ctx_t * ctx, } } - if (!json_add_hex(pkt, "lbits", sig->lbits, sizeof(sig->lbits))) { + if (!json_add_hex(pkt, "lbits", sig->lbits.data(), sig->lbits.size())) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } diff --git a/src/librepgp/stream-packet.cpp b/src/librepgp/stream-packet.cpp index 3a9101e5c..b5983f935 100644 --- a/src/librepgp/stream-packet.cpp +++ b/src/librepgp/stream-packet.cpp @@ -465,6 +465,11 @@ pgp_packet_body_t::pgp_packet_body_t(const uint8_t *data, size_t len) secure_ = false; } +pgp_packet_body_t::pgp_packet_body_t(const std::vector &data) + : pgp_packet_body_t(data.data(), data.size()) +{ +} + pgp_packet_body_t::~pgp_packet_body_t() { if (secure_) { @@ -551,6 +556,17 @@ pgp_packet_body_t::get(uint8_t *val, size_t len) noexcept return true; } +bool +pgp_packet_body_t::get(std::vector &val, size_t len) +{ + if (pos_ + len > data_.size()) { + return false; + } + val.assign(data_.data() + pos_, data_.data() + pos_ + len); + pos_ += len; + return true; +} + bool pgp_packet_body_t::get(pgp_key_id_t &val) noexcept { diff --git a/src/librepgp/stream-packet.h b/src/librepgp/stream-packet.h index a412eb17e..11f3ee75b 100644 --- a/src/librepgp/stream-packet.h +++ b/src/librepgp/stream-packet.h @@ -68,6 +68,7 @@ typedef struct pgp_packet_body_t { * @param len number of available bytes in mem */ pgp_packet_body_t(const uint8_t *data, size_t len); + pgp_packet_body_t(const std::vector &data); pgp_packet_body_t(const pgp_packet_body_t &src) = delete; pgp_packet_body_t(pgp_packet_body_t &&src) = delete; @@ -107,6 +108,12 @@ typedef struct pgp_packet_body_t { * @return true on success or false otherwise (if end of the packet is reached) **/ bool get(uint8_t *val, size_t len) noexcept; + /** + * @brief Get some bytes of data to vector, resizing it accordingly. + * + * @param len number of bytes to read. + */ + bool get(std::vector &val, size_t len); /** @brief get next keyid from the packet body, populated with read() call. * @param val result will be stored here on success * @return true on success or false otherwise (if end of the packet is reached) diff --git a/src/librepgp/stream-sig.cpp b/src/librepgp/stream-sig.cpp index 665d12724..717dd31dc 100644 --- a/src/librepgp/stream-sig.cpp +++ b/src/librepgp/stream-sig.cpp @@ -183,148 +183,12 @@ process_pgp_signatures(pgp_source_t &src, pgp_signature_list_t &sigs) return RNP_SUCCESS; } -pgp_signature_t::pgp_signature_t(const pgp_signature_t &src) -{ - version = src.version; - type_ = src.type_; - palg = src.palg; - halg = src.halg; - memcpy(lbits, src.lbits, sizeof(src.lbits)); -#if defined(ENABLE_CRYPTO_REFRESH) - if (version == PGP_V6) { - salt_size = src.salt_size; - memcpy(salt, src.salt, salt_size); - } -#endif - creation_time = src.creation_time; - signer = src.signer; - - hashed_len = src.hashed_len; - hashed_data = NULL; - if (src.hashed_data) { - if (!(hashed_data = (uint8_t *) malloc(hashed_len))) { - throw std::bad_alloc(); - } - memcpy(hashed_data, src.hashed_data, hashed_len); - } - material_len = src.material_len; - material_buf = NULL; - if (src.material_buf) { - if (!(material_buf = (uint8_t *) malloc(material_len))) { - throw std::bad_alloc(); - } - memcpy(material_buf, src.material_buf, material_len); - } - subpkts = src.subpkts; -} - -pgp_signature_t::pgp_signature_t(pgp_signature_t &&src) -{ - version = src.version; - type_ = src.type_; - palg = src.palg; - halg = src.halg; - memcpy(lbits, src.lbits, sizeof(src.lbits)); -#if defined(ENABLE_CRYPTO_REFRESH) - if (version == PGP_V6) { - salt_size = src.salt_size; - memcpy(salt, src.salt, salt_size); - } -#endif - creation_time = src.creation_time; - signer = src.signer; - hashed_len = src.hashed_len; - hashed_data = src.hashed_data; - src.hashed_data = NULL; - material_len = src.material_len; - material_buf = src.material_buf; - src.material_buf = NULL; - subpkts = std::move(src.subpkts); -} - -pgp_signature_t & -pgp_signature_t::operator=(pgp_signature_t &&src) -{ - if (this == &src) { - return *this; - } - - version = src.version; - type_ = src.type_; - palg = src.palg; - halg = src.halg; - memcpy(lbits, src.lbits, sizeof(src.lbits)); - creation_time = src.creation_time; - signer = src.signer; - hashed_len = src.hashed_len; - free(hashed_data); - hashed_data = src.hashed_data; - src.hashed_data = NULL; - material_len = src.material_len; - free(material_buf); - material_buf = src.material_buf; - src.material_buf = NULL; - subpkts = std::move(src.subpkts); - - return *this; -} - -pgp_signature_t & -pgp_signature_t::operator=(const pgp_signature_t &src) -{ - if (this == &src) { - return *this; - } - - version = src.version; - type_ = src.type_; - palg = src.palg; - halg = src.halg; - memcpy(lbits, src.lbits, sizeof(src.lbits)); -#if defined(ENABLE_CRYPTO_REFRESH) - if (version == PGP_V6) { - salt_size = src.salt_size; - memcpy(salt, src.salt, salt_size); - } -#endif - creation_time = src.creation_time; - signer = src.signer; - - hashed_len = src.hashed_len; - free(hashed_data); - hashed_data = NULL; - if (src.hashed_data) { - if (!(hashed_data = (uint8_t *) malloc(hashed_len))) { - throw std::bad_alloc(); - } - memcpy(hashed_data, src.hashed_data, hashed_len); - } - material_len = src.material_len; - free(material_buf); - material_buf = NULL; - if (src.material_buf) { - if (!(material_buf = (uint8_t *) malloc(material_len))) { - throw std::bad_alloc(); - } - memcpy(material_buf, src.material_buf, material_len); - } - subpkts = src.subpkts; - - return *this; -} - bool pgp_signature_t::operator==(const pgp_signature_t &src) const { - if ((lbits[0] != src.lbits[0]) || (lbits[1] != src.lbits[1])) { - return false; - } // TODO-V6: could also compare salt - if ((hashed_len != src.hashed_len) || memcmp(hashed_data, src.hashed_data, hashed_len)) { - return false; - } - return (material_len == src.material_len) && - !memcmp(material_buf, src.material_buf, material_len); + return (lbits == src.lbits) && (hashed_data == src.hashed_data) && + (material_buf == src.material_buf); } bool @@ -333,18 +197,12 @@ pgp_signature_t::operator!=(const pgp_signature_t &src) const return !(*this == src); } -pgp_signature_t::~pgp_signature_t() -{ - free(hashed_data); - free(material_buf); -} - pgp_sig_id_t pgp_signature_t::get_id() const { auto hash = rnp::Hash::create(PGP_HASH_SHA1); - hash->add(hashed_data, hashed_len); - hash->add(material_buf, material_len); + hash->add(hashed_data); + hash->add(material_buf); pgp_sig_id_t res = {0}; static_assert(std::tuple_size::value == PGP_SHA1_HASH_SIZE, "pgp_sig_id_t size mismatch"); @@ -901,13 +759,7 @@ pgp_signature_t::parse_v2v3(pgp_packet_body_t &pkt) return RNP_ERROR_BAD_FORMAT; } /* hashed data */ - free(hashed_data); - if (!(hashed_data = (uint8_t *) malloc(5))) { - RNP_LOG("allocation failed"); - return RNP_ERROR_OUT_OF_MEMORY; - } - memcpy(hashed_data, &buf[1], 5); - hashed_len = 5; + hashed_data.assign(buf + 1, buf + 6); /* signature type */ type_ = (pgp_sig_type_t) buf[1]; /* creation time */ @@ -1059,23 +911,18 @@ pgp_signature_t::parse_v4up(pgp_packet_body_t &pkt) return RNP_ERROR_BAD_FORMAT; } /* building hashed data */ - free(hashed_data); size_t hlen = 4 + splen + splen_size; - if (!(hashed_data = (uint8_t *) malloc(hlen))) { - RNP_LOG("allocation failed"); - return RNP_ERROR_OUT_OF_MEMORY; - } + hashed_data.resize(hlen); hashed_data[0] = version; static_assert(sizeof(buf) == 3, "Wrong signature header size."); pkt.skip_back(3 + splen_size); - if (!pkt.get(hashed_data + 1, hlen - 1)) { + if (!pkt.get(hashed_data.data() + 1, hlen - 1)) { RNP_LOG("cannot get hashed subpackets data"); return RNP_ERROR_BAD_FORMAT; } - hashed_len = hlen; /* parsing hashed subpackets */ - if (!parse_subpackets(hashed_data + 4 + splen_size, splen, true)) { + if (!parse_subpackets(hashed_data.data() + 4 + splen_size, splen, true)) { RNP_LOG("failed to parse hashed subpackets"); return RNP_ERROR_BAD_FORMAT; } @@ -1133,13 +980,14 @@ pgp_signature_t::parse(pgp_packet_body_t &pkt) } /* left 16 bits of the hash */ - if (!pkt.get(lbits, 2)) { + if (!pkt.get(lbits.data(), 2)) { RNP_LOG("not enough data for hash left bits"); return RNP_ERROR_BAD_FORMAT; } #if defined(ENABLE_CRYPTO_REFRESH) if (ver == PGP_V6) { + uint8_t salt_size = 0; if (!pkt.get(salt_size)) { RNP_LOG("not enough data for v6 salt size octet"); return RNP_ERROR_BAD_FORMAT; @@ -1156,18 +1004,8 @@ pgp_signature_t::parse(pgp_packet_body_t &pkt) #endif /* raw signature material */ - material_len = pkt.left(); - if (!material_len) { - RNP_LOG("No signature material"); - return RNP_ERROR_BAD_FORMAT; - } - material_buf = (uint8_t *) malloc(material_len); - if (!material_buf) { - RNP_LOG("Allocation failed"); - return RNP_ERROR_OUT_OF_MEMORY; - } /* we cannot fail here */ - pkt.get(material_buf, material_len); + pkt.get(material_buf, pkt.left()); /* check whether it can be parsed */ pgp_signature_material_t material = {}; if (!parse_material(material)) { @@ -1190,7 +1028,7 @@ pgp_signature_t::parse(pgp_source_t &src) bool pgp_signature_t::parse_material(pgp_signature_material_t &material) const { - pgp_packet_body_t pkt(material_buf, material_len); + pgp_packet_body_t pkt(material_buf); switch (palg) { case PGP_PKA_RSA: @@ -1295,25 +1133,25 @@ pgp_signature_t::write(pgp_dest_t &dst, bool hdr) const if (version < PGP_V4) { /* for v3 signatures hashed data includes only type + creation_time */ pktbody.add_byte(version); - pktbody.add_byte(hashed_len); - pktbody.add(hashed_data, hashed_len); + pktbody.add_byte(hashed_data.size()); + pktbody.add(hashed_data); pktbody.add(signer); pktbody.add_byte(palg); pktbody.add_byte(halg); } else { /* for v4 sig->hashed_data must contain most of signature fields */ - pktbody.add(hashed_data, hashed_len); + pktbody.add(hashed_data); pktbody.add_subpackets(*this, false); } - pktbody.add(lbits, 2); + pktbody.add(lbits.data(), 2); #if defined(ENABLE_CRYPTO_REFRESH) if (version == PGP_V6) { - pktbody.add_byte(salt_size); - pktbody.add(salt, salt_size); + pktbody.add_byte(salt.size()); + pktbody.add(salt); } #endif /* write mpis */ - pktbody.add(material_buf, material_len); + pktbody.add(material_buf); pktbody.write(dst, hdr); } @@ -1379,14 +1217,7 @@ pgp_signature_t::write_material(const pgp_signature_material_t &material) RNP_LOG("Unknown pk algorithm : %d", (int) palg); throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS); } - free(material_buf); - material_buf = (uint8_t *) malloc(pktbody.size()); - if (!material_buf) { - RNP_LOG("allocation failed"); - throw rnp::rnp_exception(RNP_ERROR_OUT_OF_MEMORY); - } - memcpy(material_buf, pktbody.data(), pktbody.size()); - material_len = pktbody.size(); + material_buf.assign(pktbody.data(), pktbody.data() + pktbody.size()); } void @@ -1408,15 +1239,7 @@ pgp_signature_t::fill_hashed_data() hbody.add_byte(halg); hbody.add_subpackets(*this, true); } - - free(hashed_data); - hashed_data = (uint8_t *) malloc(hbody.size()); - if (!hashed_data) { - RNP_LOG("allocation failed"); - throw std::bad_alloc(); - } - memcpy(hashed_data, hbody.data(), hbody.size()); - hashed_len = hbody.size(); + hashed_data.assign(hbody.data(), hbody.data() + hbody.size()); } void diff --git a/src/librepgp/stream-sig.h b/src/librepgp/stream-sig.h index f7b96de97..67ec9d5aa 100644 --- a/src/librepgp/stream-sig.h +++ b/src/librepgp/stream-sig.h @@ -52,13 +52,11 @@ typedef struct pgp_signature_t { public: pgp_version_t version; /* common v3 and v4 fields */ - pgp_pubkey_alg_t palg; - pgp_hash_alg_t halg; - uint8_t lbits[2]; - uint8_t * hashed_data; - size_t hashed_len; - uint8_t * material_buf; /* raw signature material */ - size_t material_len; /* raw signature material length */ + pgp_pubkey_alg_t palg; + pgp_hash_alg_t halg; + std::array lbits; + std::vector hashed_data; + std::vector material_buf; /* raw signature material */ /* v3 - only fields */ uint32_t creation_time; @@ -69,21 +67,14 @@ typedef struct pgp_signature_t { #if defined(ENABLE_CRYPTO_REFRESH) /* v6 - only fields */ - uint8_t salt[PGP_MAX_SALT_SIZE_V6_SIG]; - uint8_t salt_size; + std::vector salt; #endif pgp_signature_t() : type_(PGP_SIG_BINARY), version(PGP_VUNKNOWN), palg(PGP_PKA_NOTHING), - halg(PGP_HASH_UNKNOWN), hashed_data(NULL), hashed_len(0), material_buf(NULL), - material_len(0), creation_time(0){}; - pgp_signature_t(const pgp_signature_t &src); - pgp_signature_t(pgp_signature_t &&src); - pgp_signature_t &operator=(pgp_signature_t &&src); - pgp_signature_t &operator=(const pgp_signature_t &src); - bool operator==(const pgp_signature_t &src) const; - bool operator!=(const pgp_signature_t &src) const; - ~pgp_signature_t(); + halg(PGP_HASH_UNKNOWN), creation_time(0){}; + bool operator==(const pgp_signature_t &src) const; + bool operator!=(const pgp_signature_t &src) const; /* @brief Get signature's type */ pgp_sig_type_t diff --git a/src/tests/generatekey.cpp b/src/tests/generatekey.cpp index 4af3da29e..8da1c5c3e 100644 --- a/src/tests/generatekey.cpp +++ b/src/tests/generatekey.cpp @@ -1040,8 +1040,8 @@ TEST_F(rnp_tests, test_generated_key_sigs) psig = &pub.get_sig(0).sig; ssig = &sec.get_sig(0).sig; // make sure our sig MPI is not NULL - assert_int_not_equal(psig->material_len, 0); - assert_int_not_equal(ssig->material_len, 0); + assert_int_not_equal(psig->material_buf.size(), 0); + assert_int_not_equal(ssig->material_buf.size(), 0); // make sure we're targeting the right packet assert_int_equal(PGP_PKT_SIGNATURE, pub.get_sig(0).rawpkt.tag); assert_int_equal(PGP_PKT_SIGNATURE, sec.get_sig(0).rawpkt.tag); @@ -1170,8 +1170,8 @@ TEST_F(rnp_tests, test_generated_key_sigs) psig = &pub.get_sig(0).sig; ssig = &sec.get_sig(0).sig; // make sure our sig MPI is not NULL - assert_int_not_equal(psig->material_len, 0); - assert_int_not_equal(ssig->material_len, 0); + assert_int_not_equal(psig->material_buf.size(), 0); + assert_int_not_equal(ssig->material_buf.size(), 0); // make sure we're targeting the right packet assert_int_equal(PGP_PKT_SIGNATURE, pub.get_sig(0).rawpkt.tag); assert_int_equal(PGP_PKT_SIGNATURE, sec.get_sig(0).rawpkt.tag);