diff --git a/src/lib/fingerprint.cpp b/src/lib/fingerprint.cpp index 1b77416e2d..de438eca14 100644 --- a/src/lib/fingerprint.cpp +++ b/src/lib/fingerprint.cpp @@ -63,7 +63,7 @@ try { { auto halg = key.version == PGP_V4 ? PGP_HASH_SHA1 : PGP_HASH_SHA256; auto hash = rnp::Hash::create(halg); - signature_hash_key(key, *hash); + signature_hash_key(key, *hash, key.version); fp.length = hash->finish(fp.fingerprint); return RNP_SUCCESS; } diff --git a/src/librepgp/stream-sig.cpp b/src/librepgp/stream-sig.cpp index 8833b7b4b7..a8148aa634 100644 --- a/src/librepgp/stream-sig.cpp +++ b/src/librepgp/stream-sig.cpp @@ -42,26 +42,28 @@ #include "stream-armor.h" #include "pgp-key.h" #include "crypto/signatures.h" +#include #include void -signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash) +signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash, pgp_version_t pgpver) { if (!key.hashed_data) { /* call self recursively if hashed data is not filled, to overcome const restriction */ pgp_key_pkt_t keycp(key, true); keycp.fill_hashed_data(); - signature_hash_key(keycp, hash); + signature_hash_key(keycp, hash, pgpver); return; } - switch (key.version) { + switch (pgpver) { case PGP_V2: FALLTHROUGH_STATEMENT; case PGP_V3: FALLTHROUGH_STATEMENT; case PGP_V4: { + assert(key.hashed_len < ((size_t) 1 << 16)); uint8_t hdr[3] = {0x99, 0x00, 0x00}; write_uint16(hdr + 1, key.hashed_len); hash.add(hdr, 3); @@ -69,6 +71,7 @@ signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash) break; } case PGP_V5: { + assert(key.hashed_len < ((size_t) 1 << 32)); uint8_t hdr[5] = {0x9A, 0x00, 0x00, 0x00, 0x00}; write_uint32(hdr + 1, key.hashed_len); hash.add(&hdr, 5); @@ -77,6 +80,7 @@ signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash) } #if defined(ENABLE_CRYPTO_REFRESH) case PGP_V6: { + assert(key.hashed_len < ((size_t) 1 << 32)); uint8_t hdr[5] = {0x9b, 0x00, 0x00, 0x00, 0x00}; write_uint32(hdr + 1, key.hashed_len); hash.add(hdr, sizeof(hdr)); @@ -85,7 +89,7 @@ signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash) } #endif default: - RNP_LOG("unknown key version: %d", (int) key.version); + RNP_LOG("unknown key/sig version: %d", (int) pgpver); throw rnp::rnp_exception(RNP_ERROR_OUT_OF_MEMORY); } } @@ -121,7 +125,7 @@ signature_hash_certification(const pgp_signature_t & sig, const pgp_userid_pkt_t &userid) { auto hash = signature_init(key, sig); - signature_hash_key(key, *hash); + signature_hash_key(key, *hash, sig.version); signature_hash_userid(userid, *hash, sig.version); return hash; } @@ -132,8 +136,8 @@ signature_hash_binding(const pgp_signature_t &sig, const pgp_key_pkt_t & subkey) { auto hash = signature_init(key, sig); - signature_hash_key(key, *hash); - signature_hash_key(subkey, *hash); + signature_hash_key(key, *hash, sig.version); + signature_hash_key(subkey, *hash, sig.version); return hash; } @@ -141,7 +145,7 @@ std::unique_ptr signature_hash_direct(const pgp_signature_t &sig, const pgp_key_pkt_t &key) { auto hash = signature_init(key, sig); - signature_hash_key(key, *hash); + signature_hash_key(key, *hash, sig.version); return hash; } diff --git a/src/librepgp/stream-sig.h b/src/librepgp/stream-sig.h index a3118974de..2ab04b7c39 100644 --- a/src/librepgp/stream-sig.h +++ b/src/librepgp/stream-sig.h @@ -452,8 +452,10 @@ typedef struct pgp_signature_info_t { * Throws exception on error. * @param key key packet, must be populated * @param hash initialized hash context + * @param pgpver for fingerprint calculation, the key version is required, + * otherwise the signature version is required */ -void signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash); +void signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash, pgp_version_t pgpver); void signature_hash_userid(const pgp_userid_pkt_t &uid, rnp::Hash &hash, pgp_version_t sigver);