From 6cd64cbf3c65b472d42796efa6b7cb62e9200c57 Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Wed, 8 Jan 2025 18:01:28 +0200 Subject: [PATCH 1/9] Avoid warnigs in IDE about the absence of SOURCE_PATH_SIZE. --- src/lib/logging.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/logging.h b/src/lib/logging.h index 3a0a2fa4e..b4fe07279 100644 --- a/src/lib/logging.h +++ b/src/lib/logging.h @@ -59,6 +59,9 @@ class LogStop { } // namespace rnp /* remove "src" */ +#ifndef SOURCE_PATH_SIZE +#define SOURCE_PATH_SIZE 0 +#endif #define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3])) #define RNP_LOG_FD(fd, ...) \ From c85e9cca4f611a8bce964eb33319f96d636e21a8 Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Wed, 8 Jan 2025 18:01:56 +0200 Subject: [PATCH 2/9] Refactor encrypted_add_password/init_encrypted_dst. --- src/librepgp/stream-write.cpp | 203 ++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 96 deletions(-) diff --git a/src/librepgp/stream-write.cpp b/src/librepgp/stream-write.cpp index 7af51807b..08f61f2d8 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -679,93 +679,115 @@ encrypted_sesk_set_ad(pgp_crypt_t *crypt, pgp_sk_sesskey_t *skey) #endif static rnp_result_t -encrypted_add_password(rnp_symmetric_pass_info_t * pass, - pgp_dest_encrypted_param_t *param, - uint8_t * key, - const unsigned keylen, - bool singlepass) +encrypted_add_password_v4(rnp_symmetric_pass_info_t &pass, + pgp_symm_alg_t ealg, + rnp::secure_bytes & key, + size_t keylen, + pgp_sk_sesskey_t & skey, + bool singlepass) { - pgp_sk_sesskey_t skey = {}; - pgp_crypt_t kcrypt; - - skey.s2k = pass->s2k; + skey.version = PGP_SKSK_V4; + if (singlepass) { + /* if there are no public keys then we do not encrypt session key in the packet */ + skey.alg = ealg; + skey.enckeylen = 0; + key.assign(pass.key.data(), pass.key.data() + keylen); + return RNP_SUCCESS; + } + /* We may use different algo for CEK and KEK */ + skey.enckeylen = keylen + 1; + skey.enckey[0] = ealg; + memcpy(&skey.enckey[1], key.data(), keylen); + skey.alg = pass.s2k_cipher; + pgp_crypt_t kcrypt; + if (!pgp_cipher_cfb_start(&kcrypt, skey.alg, pass.key.data(), NULL)) { + RNP_LOG("key encryption failed"); + return RNP_ERROR_BAD_PARAMETERS; + } + pgp_cipher_cfb_encrypt(&kcrypt, skey.enckey, skey.enckey, skey.enckeylen); + pgp_cipher_cfb_finish(&kcrypt); + return RNP_SUCCESS; +} - if (param->auth_type != rnp::AuthType::AEADv1) { - skey.version = PGP_SKSK_V4; - if (singlepass) { - /* if there are no public keys then we do not encrypt session key in the packet */ - skey.alg = param->ctx->ealg; - skey.enckeylen = 0; - memcpy(key, pass->key.data(), keylen); - } else { - /* We may use different algo for CEK and KEK */ - skey.enckeylen = keylen + 1; - skey.enckey[0] = param->ctx->ealg; - memcpy(&skey.enckey[1], key, keylen); - skey.alg = pass->s2k_cipher; - if (!pgp_cipher_cfb_start(&kcrypt, skey.alg, pass->key.data(), NULL)) { - RNP_LOG("key encryption failed"); - return RNP_ERROR_BAD_PARAMETERS; - } - pgp_cipher_cfb_encrypt(&kcrypt, skey.enckey, skey.enckey, skey.enckeylen); - pgp_cipher_cfb_finish(&kcrypt); - } - } else { +static rnp_result_t +encrypted_add_password_v5(rnp_symmetric_pass_info_t &pass, + pgp_aead_alg_t aalg, + rnp::RNG & rng, + rnp::secure_bytes & key, + size_t keylen, + pgp_sk_sesskey_t & skey) +{ #if !defined(ENABLE_AEAD) - RNP_LOG("AEAD support is not enabled."); - return RNP_ERROR_NOT_IMPLEMENTED; + RNP_LOG("AEAD support is not enabled."); + return RNP_ERROR_NOT_IMPLEMENTED; #else - /* AEAD-encrypted v5 packet */ - if ((param->ctx->aalg != PGP_AEAD_EAX) && (param->ctx->aalg != PGP_AEAD_OCB)) { - RNP_LOG("unsupported AEAD algorithm"); - return RNP_ERROR_BAD_PARAMETERS; - } + /* AEAD-encrypted v5 packet */ + if ((aalg != PGP_AEAD_EAX) && (aalg != PGP_AEAD_OCB)) { + RNP_LOG("unsupported AEAD algorithm"); + return RNP_ERROR_BAD_PARAMETERS; + } - skey.version = PGP_SKSK_V5; - skey.alg = pass->s2k_cipher; - skey.aalg = param->ctx->aalg; - skey.ivlen = pgp_cipher_aead_nonce_len(skey.aalg); - skey.enckeylen = keylen + pgp_cipher_aead_tag_len(skey.aalg); + skey.version = PGP_SKSK_V5; + skey.alg = pass.s2k_cipher; + skey.aalg = aalg; + skey.ivlen = pgp_cipher_aead_nonce_len(skey.aalg); + skey.enckeylen = keylen + pgp_cipher_aead_tag_len(skey.aalg); + rng.get(skey.iv, skey.ivlen); - try { - param->ctx->ctx->rng.get(skey.iv, skey.ivlen); - } catch (const std::exception &e) { - return RNP_ERROR_RNG; // LCOV_EXCL_LINE - } - - /* initialize cipher */ - if (!pgp_cipher_aead_init(&kcrypt, skey.alg, skey.aalg, pass->key.data(), false)) { - return RNP_ERROR_BAD_PARAMETERS; - } + /* initialize cipher */ + pgp_crypt_t kcrypt; + if (!pgp_cipher_aead_init(&kcrypt, skey.alg, skey.aalg, pass.key.data(), false)) { + return RNP_ERROR_BAD_PARAMETERS; + } - /* set additional data */ - if (!encrypted_sesk_set_ad(&kcrypt, &skey)) { - return RNP_ERROR_BAD_STATE; // LCOV_EXCL_LINE - } + /* set additional data */ + if (!encrypted_sesk_set_ad(&kcrypt, &skey)) { + return RNP_ERROR_BAD_STATE; // LCOV_EXCL_LINE + } - /* calculate nonce */ - uint8_t nonce[PGP_AEAD_MAX_NONCE_LEN]; - size_t nlen = pgp_cipher_aead_nonce(skey.aalg, skey.iv, nonce, 0); + /* calculate nonce */ + uint8_t nonce[PGP_AEAD_MAX_NONCE_LEN]; + size_t nlen = pgp_cipher_aead_nonce(skey.aalg, skey.iv, nonce, 0); - /* start cipher, encrypt key and get tag */ - bool res = pgp_cipher_aead_start(&kcrypt, nonce, nlen) && - pgp_cipher_aead_finish(&kcrypt, skey.enckey, key, keylen); + /* start cipher, encrypt key and get tag */ + bool res = pgp_cipher_aead_start(&kcrypt, nonce, nlen) && + pgp_cipher_aead_finish(&kcrypt, skey.enckey, key.data(), keylen); - pgp_cipher_aead_destroy(&kcrypt); + pgp_cipher_aead_destroy(&kcrypt); - if (!res) { - return RNP_ERROR_BAD_STATE; - } + return res ? RNP_SUCCESS : RNP_ERROR_BAD_STATE; #endif +} + +static rnp_result_t +encrypted_add_password(rnp_symmetric_pass_info_t & pass, + pgp_dest_encrypted_param_t ¶m, + rnp::secure_bytes & key, + const size_t keylen, + bool singlepass) +{ + pgp_sk_sesskey_t skey = {}; + skey.s2k = pass.s2k; + + rnp_result_t ret = RNP_ERROR_GENERIC; + if (param.auth_type != rnp::AuthType::AEADv1) { + ret = encrypted_add_password_v4(pass, param.ctx->ealg, key, keylen, skey, singlepass); + } else { + ret = encrypted_add_password_v5( + pass, param.ctx->aalg, param.ctx->ctx->rng, key, keylen, skey); + } + + if (ret) { + return ret; } /* Writing symmetric key encrypted session key packet */ try { - skey.write(*param->pkt.origdst); + skey.write(*param.pkt.origdst); } catch (const std::exception &e) { return RNP_ERROR_WRITE; // LCOV_EXCL_LINE } - return param->pkt.origdst->werr; + return param.pkt.origdst->werr; } static rnp_result_t @@ -921,14 +943,7 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) static rnp_result_t init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *writedst) { - pgp_dest_encrypted_param_t *param; - bool singlepass = true; - unsigned pkeycount = 0; - unsigned skeycount = 0; - unsigned keylen; - rnp_result_t ret = RNP_ERROR_GENERIC; - - keylen = pgp_key_size(handler->ctx->ealg); + size_t keylen = pgp_key_size(handler->ctx->ealg); if (!keylen) { RNP_LOG("unknown symmetric algorithm"); return RNP_ERROR_BAD_PARAMETERS; @@ -957,24 +972,24 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr } } + auto pkeycount = handler->ctx->recipients.size(); + auto skeycount = handler->ctx->passwords.size(); + if (!pkeycount && !skeycount) { + RNP_LOG("no recipients"); + return RNP_ERROR_BAD_PARAMETERS; + } + if (!init_dst_common(dst, 0)) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } - try { - param = new pgp_dest_encrypted_param_t(); - dst->param = param; - } catch (const std::exception &e) { - /* LCOV_EXCL_START */ - RNP_LOG("%s", e.what()); - return RNP_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_END */ + auto param = new (std::nothrow) pgp_dest_encrypted_param_t(); + if (!param) { + return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } + dst->param = param; param->auth_type = handler->ctx->aalg == PGP_AEAD_NONE ? rnp::AuthType::MDC : rnp::AuthType::AEADv1; - pkeycount = handler->ctx->recipients.size(); - skeycount = handler->ctx->passwords.size(); - #if defined(ENABLE_CRYPTO_REFRESH) /* in the case of PKESK (pkeycount > 0) and all keys are PKESKv6/SEIPDv2 capable, upgrade * to AEADv2 */ @@ -991,14 +1006,11 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr dst->close = encrypted_dst_close; dst->type = PGP_STREAM_ENCRYPTED; + rnp_result_t ret = RNP_ERROR_GENERIC; rnp::secure_bytes enckey(keylen, 0); /* content encryption key */ - if (!pkeycount && !skeycount) { - RNP_LOG("no recipients"); - ret = RNP_ERROR_BAD_PARAMETERS; - goto finish; - } - if ((pkeycount > 0) || (skeycount > 1) || param->is_aead_auth()) { + bool singlepass = !pkeycount && (skeycount == 1) && !param->is_aead_auth(); + if (!singlepass) { try { handler->ctx->ctx->rng.get(enckey.data(), keylen); } catch (const std::exception &e) { @@ -1007,7 +1019,6 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr goto finish; /* LCOV_EXCL_END */ } - singlepass = false; } /* Configuring and writing pk-encrypted session keys */ @@ -1031,8 +1042,8 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr /* Configuring and writing sk-encrypted session key(s) */ for (auto &passinfo : handler->ctx->passwords) { - ret = encrypted_add_password(&passinfo, param, enckey.data(), keylen, singlepass); - if (ret != RNP_SUCCESS) { + ret = encrypted_add_password(passinfo, *param, enckey, keylen, singlepass); + if (ret) { goto finish; } } From 97a256caac3d017cbe2e043170d11c6a8bf42399 Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Fri, 10 Jan 2025 19:26:15 +0200 Subject: [PATCH 3/9] Add security context, key provider and password provider to rnp_ctx_t by reference. --- src/lib/ffi-priv-types.h | 42 ++++++++++++++++++++++---------- src/lib/rnp.cpp | 31 ++++-------------------- src/librepgp/stream-ctx.cpp | 4 ++-- src/librepgp/stream-ctx.h | 30 +++++++++++++++-------- src/librepgp/stream-parse.cpp | 4 ++-- src/librepgp/stream-write.cpp | 45 +++++++++++++++++++++-------------- 6 files changed, 84 insertions(+), 72 deletions(-) diff --git a/src/lib/ffi-priv-types.h b/src/lib/ffi-priv-types.h index 6b249b1f0..8d8688095 100644 --- a/src/lib/ffi-priv-types.h +++ b/src/lib/ffi-priv-types.h @@ -187,11 +187,17 @@ struct rnp_op_sign_signature_st { typedef std::list rnp_op_sign_signatures_t; struct rnp_op_sign_st { - rnp_ffi_t ffi{}; - rnp_input_t input{}; - rnp_output_t output{}; - rnp_ctx_t rnpctx{}; - rnp_op_sign_signatures_t signatures{}; + rnp_ffi_t ffi; + rnp_input_t input; + rnp_output_t output; + rnp_ctx_t rnpctx; + rnp_op_sign_signatures_t signatures; + + rnp_op_sign_st(rnp_ffi_t affi, rnp_input_t in, rnp_output_t out) + : ffi(affi), input(in), output(out), + rnpctx(ffi->context, ffi->key_provider, ffi->pass_provider) + { + } }; struct rnp_op_verify_signature_st { @@ -201,11 +207,11 @@ struct rnp_op_verify_signature_st { }; struct rnp_op_verify_st { - rnp_ffi_t ffi{}; - rnp_input_t input{}; + rnp_ffi_t ffi; + rnp_input_t input; rnp_input_t detached_input{}; /* for detached signature will be source file/data */ rnp_output_t output{}; - rnp_ctx_t rnpctx{}; + rnp_ctx_t rnpctx; /* these fields are filled after operation execution */ std::vector signatures_; pgp_literal_hdr_t lithdr{}; @@ -225,15 +231,25 @@ struct rnp_op_verify_st { rnp_symenc_handle_t used_symenc{}; size_t encrypted_layers{}; + rnp_op_verify_st(rnp_ffi_t affi, rnp_input_t in) + : ffi(affi), input(in), rnpctx(ffi->context, ffi->key_provider, ffi->pass_provider) + { + } ~rnp_op_verify_st(); }; struct rnp_op_encrypt_st { - rnp_ffi_t ffi{}; - rnp_input_t input{}; - rnp_output_t output{}; - rnp_ctx_t rnpctx{}; - rnp_op_sign_signatures_t signatures{}; + rnp_ffi_t ffi; + rnp_input_t input; + rnp_output_t output; + rnp_ctx_t rnpctx; + rnp_op_sign_signatures_t signatures; + + rnp_op_encrypt_st(rnp_ffi_t affi, rnp_input_t in, rnp_output_t out) + : ffi(affi), input(in), output(out), + rnpctx(ffi->context, ffi->key_provider, ffi->pass_provider) + { + } }; #define RNP_LOCATOR_MAX_SIZE (MAX_ID_LENGTH + 1) diff --git a/src/lib/rnp.cpp b/src/lib/rnp.cpp index cc245bb36..25d136e33 100644 --- a/src/lib/rnp.cpp +++ b/src/lib/rnp.cpp @@ -120,15 +120,6 @@ ffi_key_provider(const pgp_key_request_ctx_t *ctx, void *userdata) return find_key(ffi, ctx->search, ctx->secret, true); } -static void -rnp_ctx_init_ffi(rnp_ctx_t &ctx, rnp_ffi_t ffi) -{ - ctx.ctx = &ffi->context; - ctx.ealg = DEFAULT_PGP_SYMM_ALG; - ctx.aalg = PGP_AEAD_NONE; - ctx.abits = DEFAULT_AEAD_CHUNK_BITS; -} - static const id_str_pair sig_type_map[] = {{PGP_SIG_BINARY, "binary"}, {PGP_SIG_TEXT, "text"}, {PGP_SIG_STANDALONE, "standalone"}, @@ -2589,11 +2580,7 @@ try { return RNP_ERROR_NULL_POINTER; } - *op = new rnp_op_encrypt_st(); - rnp_ctx_init_ffi((*op)->rnpctx, ffi); - (*op)->ffi = ffi; - (*op)->input = input; - (*op)->output = output; + *op = new rnp_op_encrypt_st(ffi, input, output); return RNP_SUCCESS; } FFI_GUARD @@ -2958,11 +2945,7 @@ try { return RNP_ERROR_NULL_POINTER; } - *op = new rnp_op_sign_st(); - rnp_ctx_init_ffi((*op)->rnpctx, ffi); - (*op)->ffi = ffi; - (*op)->input = input; - (*op)->output = output; + *op = new rnp_op_sign_st(ffi, input, output); return RNP_SUCCESS; } FFI_GUARD @@ -3320,10 +3303,7 @@ try { return RNP_ERROR_NULL_POINTER; } - *op = new rnp_op_verify_st(); - rnp_ctx_init_ffi((*op)->rnpctx, ffi); - (*op)->ffi = ffi; - (*op)->input = input; + *op = new rnp_op_verify_st(ffi, input); (*op)->output = output; return RNP_SUCCESS; @@ -3340,11 +3320,8 @@ try { return RNP_ERROR_NULL_POINTER; } - *op = new rnp_op_verify_st(); - rnp_ctx_init_ffi((*op)->rnpctx, ffi); + *op = new rnp_op_verify_st(ffi, signature); (*op)->rnpctx.detached = true; - (*op)->ffi = ffi; - (*op)->input = signature; (*op)->detached_input = input; return RNP_SUCCESS; diff --git a/src/librepgp/stream-ctx.cpp b/src/librepgp/stream-ctx.cpp index 96edbd443..dc7f3a43f 100644 --- a/src/librepgp/stream-ctx.cpp +++ b/src/librepgp/stream-ctx.cpp @@ -41,9 +41,9 @@ rnp_ctx_t::add_encryption_password(const std::string &password, info.s2k.usage = PGP_S2KU_ENCRYPTED_AND_HASHED; info.s2k.specifier = PGP_S2KS_ITERATED_AND_SALTED; info.s2k.hash_alg = halg; - ctx->rng.get(info.s2k.salt, sizeof(info.s2k.salt)); + sec_ctx.rng.get(info.s2k.salt, sizeof(info.s2k.salt)); if (!iterations) { - iterations = ctx->s2k_iterations(halg); + iterations = sec_ctx.s2k_iterations(halg); } if (!iterations) { return RNP_ERROR_BAD_PARAMETERS; diff --git a/src/librepgp/stream-ctx.h b/src/librepgp/stream-ctx.h index fa140c313..8f4453e3c 100644 --- a/src/librepgp/stream-ctx.h +++ b/src/librepgp/stream-ctx.h @@ -35,6 +35,8 @@ #include #include "pgp-key.h" #include "crypto/mem.h" +#include "key-provider.h" +#include "pass-provider.h" #include "sec_profile.hpp" /* signature info structure */ @@ -93,18 +95,18 @@ typedef struct rnp_symmetric_pass_info_t { */ typedef struct rnp_ctx_t { - std::string filename{}; /* name of the input file to store in literal data packet */ + std::string filename; /* name of the input file to store in literal data packet */ int64_t filemtime{}; /* file modification time to store in literal data packet */ int64_t sigcreate{}; /* signature creation time */ uint64_t sigexpire{}; /* signature expiration time */ bool clearsign{}; /* cleartext signature */ bool detached{}; /* detached signature */ - pgp_hash_alg_t halg{}; /* hash algorithm */ - pgp_symm_alg_t ealg{}; /* encryption algorithm */ + pgp_hash_alg_t halg; /* hash algorithm */ + pgp_symm_alg_t ealg; /* encryption algorithm */ int zalg{}; /* compression algorithm used */ int zlevel{}; /* compression level */ - pgp_aead_alg_t aalg{}; /* non-zero to use AEAD */ - int abits{}; /* AEAD chunk bits */ + pgp_aead_alg_t aalg; /* non-zero to use AEAD */ + int abits; /* AEAD chunk bits */ bool overwrite{}; /* allow to overwrite output file if exists */ bool armor{}; /* whether to use ASCII armor on output */ bool no_wrap{}; /* do not wrap source in literal data packet */ @@ -114,12 +116,20 @@ typedef struct rnp_ctx_t { #if defined(ENABLE_PQC) bool pref_pqc_enc_subkey{}; /* prefer to encrypt to PQC subkey */ #endif - std::list recipients{}; /* recipients of the encrypted message */ - std::list passwords{}; /* passwords to encrypt message */ - std::list signers{}; /* keys to which sign message */ - rnp::SecurityContext * ctx{}; /* pointer to rnp::RNG */ + std::list recipients; /* recipients of the encrypted message */ + std::list passwords; /* passwords to encrypt message */ + std::list signers; /* keys to which sign message */ + rnp::SecurityContext & sec_ctx; /* security context */ + rnp::KeyProvider & key_provider; /* Key provider */ + pgp_password_provider_t & pass_provider; /* Password provider */ + + rnp_ctx_t(rnp::SecurityContext & sctx, + rnp::KeyProvider & kprov, + pgp_password_provider_t &pprov) + : halg(DEFAULT_PGP_HASH_ALG), ealg(DEFAULT_PGP_SYMM_ALG), aalg(PGP_AEAD_NONE), + abits(DEFAULT_AEAD_CHUNK_BITS), sec_ctx(sctx), key_provider(kprov), + pass_provider(pprov){}; - rnp_ctx_t() = default; rnp_ctx_t(const rnp_ctx_t &) = delete; rnp_ctx_t(rnp_ctx_t &&) = delete; diff --git a/src/librepgp/stream-parse.cpp b/src/librepgp/stream-parse.cpp index eaff5dca7..11ba93ac6 100644 --- a/src/librepgp/stream-parse.cpp +++ b/src/librepgp/stream-parse.cpp @@ -907,7 +907,7 @@ signed_validate_signature(pgp_source_signed_param_t ¶m, pgp_signature_info_t } auto shash = hash->clone(); key->validate_sig( - sinfo, *shash, *param.handler->ctx->ctx, param.has_lhdr ? ¶m.lhdr : NULL); + sinfo, *shash, param.handler->ctx->sec_ctx, param.has_lhdr ? ¶m.lhdr : NULL); } catch (const std::exception &e) { /* LCOV_EXCL_START */ RNP_LOG("Signature validation failed: %s", e.what()); @@ -2346,7 +2346,7 @@ init_encrypted_src(pgp_parse_handler_t *handler, pgp_source_t *src, pgp_source_t /* Try to initialize the decryption */ rnp::LogStop logstop(hidden); - if (encrypted_try_key(param, pubenc, *seckey, *handler->ctx->ctx)) { + if (encrypted_try_key(param, pubenc, *seckey, handler->ctx->sec_ctx)) { have_key = true; /* inform handler that we used this pubenc */ if (handler->on_decryption_start) { diff --git a/src/librepgp/stream-write.cpp b/src/librepgp/stream-write.cpp index 08f61f2d8..30f76ef26 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -648,7 +648,7 @@ encrypted_add_recipient(pgp_write_handler_t * handler, assert(ecdh); ecdh->enc.fp = userkey->fp().vec(); } - auto ret = userkey->pkt().material->encrypt(*handler->ctx->ctx, *material, enckey); + auto ret = userkey->pkt().material->encrypt(handler->ctx->sec_ctx, *material, enckey); if (ret) { return ret; } @@ -774,7 +774,7 @@ encrypted_add_password(rnp_symmetric_pass_info_t & pass, ret = encrypted_add_password_v4(pass, param.ctx->ealg, key, keylen, skey, singlepass); } else { ret = encrypted_add_password_v5( - pass, param.ctx->aalg, param.ctx->ctx->rng, key, keylen, skey); + pass, param.ctx->aalg, param.ctx->sec_ctx.rng, key, keylen, skey); } if (ret) { @@ -819,7 +819,7 @@ encrypted_start_cfb(pgp_dest_encrypted_param_t *param, uint8_t *enckey) /* generating and writing iv/password check bytes */ blsize = pgp_block_size(param->ctx->ealg); try { - param->ctx->ctx->rng.get(enchdr, blsize); + param->ctx->sec_ctx.rng.get(enchdr, blsize); enchdr[blsize] = enchdr[blsize - 2]; enchdr[blsize + 1] = enchdr[blsize - 1]; @@ -881,7 +881,7 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) } #endif try { - param->ctx->ctx->rng.get(iv_or_salt, iv_or_salt_len); + param->ctx->sec_ctx.rng.get(iv_or_salt, iv_or_salt_len); } catch (const std::exception &e) { return RNP_ERROR_RNG; // LCOV_EXCL_LINE } @@ -1012,7 +1012,7 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr bool singlepass = !pkeycount && (skeycount == 1) && !param->is_aead_auth(); if (!singlepass) { try { - handler->ctx->ctx->rng.get(enckey.data(), keylen); + handler->ctx->sec_ctx.rng.get(enckey.data(), keylen); } catch (const std::exception &e) { /* LCOV_EXCL_START */ ret = RNP_ERROR_RNG; @@ -1254,7 +1254,7 @@ signed_fill_signature(pgp_dest_signed_param_t ¶m, /* calculate the signature */ auto hdr = param.has_lhdr ? ¶m.lhdr : NULL; signature_calculate( - sig, *signer.key->pkt().material, *listh->clone(), *param.ctx->ctx, hdr); + sig, *signer.key->pkt().material, *listh->clone(), param.ctx->sec_ctx, hdr); } static rnp_result_t @@ -1265,18 +1265,18 @@ signed_write_signature(pgp_dest_signed_param_t *param, try { pgp_signature_t sig; if (signer->onepass.version) { - signer->key->sign_init(param->ctx->ctx->rng, + signer->key->sign_init(param->ctx->sec_ctx.rng, sig, signer->onepass.halg, - param->ctx->ctx->time(), + param->ctx->sec_ctx.time(), signer->key->version()); sig.palg = signer->onepass.palg; sig.set_type(signer->onepass.type); } else { - signer->key->sign_init(param->ctx->ctx->rng, + signer->key->sign_init(param->ctx->sec_ctx.rng, sig, signer->halg, - param->ctx->ctx->time(), + param->ctx->sec_ctx.time(), signer->key->version()); /* line below should be checked */ sig.set_type(param->ctx->detached ? PGP_SIG_BINARY : PGP_SIG_TEXT); @@ -1393,7 +1393,7 @@ signed_add_signer(pgp_dest_signed_param_t *param, rnp_signer_info_t *signer, boo return RNP_ERROR_BAD_PARAMETERS; } /* validate signing key material if didn't before */ - signer->key->material()->validate(*param->ctx->ctx, false); + signer->key->material()->validate(param->ctx->sec_ctx, false); if (!signer->key->pkt().material->valid()) { RNP_LOG("attempt to sign to the key with invalid material"); return RNP_ERROR_NO_SUITABLE_KEY; @@ -2088,8 +2088,12 @@ rnp_encrypt_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t rnp_result_t rnp_compress_src(pgp_source_t &src, pgp_dest_t &dst, pgp_compression_type_t zalg, int zlevel) { - pgp_write_handler_t handler = {}; - rnp_ctx_t ctx; + pgp_write_handler_t handler = {}; + rnp::SecurityContext sec_ctx; + rnp::KeyProvider key_prov; + pgp_password_provider_t pass_prov; + rnp_ctx_t ctx(sec_ctx, key_prov, pass_prov); + ctx.zalg = zalg; ctx.zlevel = zlevel; handler.ctx = &ctx; @@ -2108,7 +2112,11 @@ rnp_compress_src(pgp_source_t &src, pgp_dest_t &dst, pgp_compression_type_t zalg rnp_result_t rnp_wrap_src(pgp_source_t &src, pgp_dest_t &dst, const std::string &filename, uint32_t modtime) { - rnp_ctx_t ctx{}; + rnp::SecurityContext sec_ctx; + rnp::KeyProvider key_prov; + pgp_password_provider_t pass_prov; + rnp_ctx_t ctx(sec_ctx, key_prov, pass_prov); + ctx.filename = filename; ctx.filemtime = modtime; @@ -2133,11 +2141,12 @@ rnp_raw_encrypt_src(pgp_source_t & src, const std::string & password, rnp::SecurityContext &secctx) { - pgp_write_handler_t handler = {}; - rnp_ctx_t ctx; + pgp_write_handler_t handler = {}; + rnp::SecurityContext sec_ctx; + rnp::KeyProvider key_prov; + pgp_password_provider_t pass_prov; + rnp_ctx_t ctx(sec_ctx, key_prov, pass_prov); - ctx.ctx = &secctx; - ctx.ealg = DEFAULT_PGP_SYMM_ALG; handler.ctx = &ctx; pgp_dest_t encrypted = {}; From c234125227aeca9957245aed448c2d19e6ad6e66 Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Fri, 10 Jan 2025 20:29:12 +0200 Subject: [PATCH 4/9] Refactor out rnp_write_handler_t and use references instead of pointers where applicable. --- src/lib/rnp.cpp | 27 +--- src/librepgp/stream-write.cpp | 297 ++++++++++++++++------------------ src/librepgp/stream-write.h | 14 +- 3 files changed, 146 insertions(+), 192 deletions(-) diff --git a/src/lib/rnp.cpp b/src/lib/rnp.cpp index 25d136e33..c64e13d29 100644 --- a/src/lib/rnp.cpp +++ b/src/lib/rnp.cpp @@ -2863,20 +2863,6 @@ try { } FFI_GUARD -static pgp_write_handler_t -pgp_write_handler(pgp_password_provider_t *pass_provider, - rnp_ctx_t * rnpctx, - void * param, - rnp::KeyProvider * key_provider) -{ - pgp_write_handler_t handler{}; - handler.password_provider = pass_provider; - handler.ctx = rnpctx; - handler.param = param; - handler.key_provider = key_provider; - return handler; -} - static rnp_result_t rnp_op_add_signatures(rnp_op_sign_signatures_t &opsigs, rnp_ctx_t &ctx) { @@ -2912,14 +2898,12 @@ try { if (!op->rnpctx.halg) { op->rnpctx.halg = DEFAULT_PGP_HASH_ALG; } - pgp_write_handler_t handler = - pgp_write_handler(&op->ffi->pass_provider, &op->rnpctx, NULL, &op->ffi->key_provider); - rnp_result_t ret; + rnp_result_t ret = RNP_ERROR_GENERIC; if (!op->signatures.empty() && (ret = rnp_op_add_signatures(op->signatures, op->rnpctx))) { return ret; } - ret = rnp_encrypt_sign_src(&handler, &op->input->src, &op->output->dst); + ret = rnp_encrypt_sign_src(op->rnpctx, op->input->src, op->output->dst); dst_flush(&op->output->dst); op->output->keep = ret == RNP_SUCCESS; @@ -3109,14 +3093,11 @@ try { if (!op->rnpctx.halg) { op->rnpctx.halg = DEFAULT_PGP_HASH_ALG; } - pgp_write_handler_t handler = - pgp_write_handler(&op->ffi->pass_provider, &op->rnpctx, NULL, &op->ffi->key_provider); - - rnp_result_t ret; + rnp_result_t ret = RNP_ERROR_GENERIC; if ((ret = rnp_op_add_signatures(op->signatures, op->rnpctx))) { return ret; } - ret = rnp_sign_src(&handler, &op->input->src, &op->output->dst); + ret = rnp_sign_src(op->rnpctx, op->input->src, op->output->dst); dst_flush(&op->output->dst); op->output->keep = ret == RNP_SUCCESS; diff --git a/src/librepgp/stream-write.cpp b/src/librepgp/stream-write.cpp index 30f76ef26..425f16a19 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -229,23 +229,23 @@ partial_dst_close(pgp_dest_t *dst, bool discard) } static rnp_result_t -init_partial_pkt_dst(pgp_dest_t *dst, pgp_dest_t *writedst) +init_partial_pkt_dst(pgp_dest_t &dst, pgp_dest_t &writedst) { - pgp_dest_partial_param_t *param; + pgp_dest_partial_param_t *param = NULL; - if (!init_dst_common(dst, sizeof(*param))) { + if (!init_dst_common(&dst, sizeof(*param))) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } - param = (pgp_dest_partial_param_t *) dst->param; - param->writedst = writedst; + param = (pgp_dest_partial_param_t *) dst.param; + param->writedst = &writedst; param->partlen = PGP_PARTIAL_PKT_BLOCK_SIZE; param->parthdr = 0xE0 | PGP_PARTIAL_PKT_SIZE_BITS; - dst->param = param; - dst->write = partial_dst_write; - dst->finish = partial_dst_finish; - dst->close = partial_dst_close; - dst->type = PGP_STREAM_PARLEN_PACKET; + dst.param = param; + dst.write = partial_dst_write; + dst.finish = partial_dst_finish; + dst.close = partial_dst_close; + dst.type = PGP_STREAM_PARLEN_PACKET; return RNP_SUCCESS; } @@ -254,46 +254,46 @@ init_partial_pkt_dst(pgp_dest_t *dst, pgp_dest_t *writedst) * Allocates part len destination if needed and writes header **/ static bool -init_streamed_packet(pgp_dest_packet_param_t *param, pgp_dest_t *dst) +init_streamed_packet(pgp_dest_packet_param_t ¶m, pgp_dest_t &dst) { - rnp_result_t ret; + rnp_result_t ret = RNP_ERROR_GENERIC; - if (param->partial) { - param->hdr[0] = param->tag | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT; - dst_write(dst, ¶m->hdr, 1); + if (param.partial) { + param.hdr[0] = param.tag | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT; + dst_write(&dst, ¶m.hdr, 1); - if ((param->writedst = (pgp_dest_t *) calloc(1, sizeof(*param->writedst))) == NULL) { + if (!(param.writedst = (pgp_dest_t *) calloc(1, sizeof(*param.writedst)))) { RNP_LOG("part len dest allocation failed"); return false; } - ret = init_partial_pkt_dst(param->writedst, dst); + ret = init_partial_pkt_dst(*param.writedst, dst); if (ret) { /* LCOV_EXCL_START */ - free(param->writedst); - param->writedst = NULL; + free(param.writedst); + param.writedst = NULL; return false; /* LCOV_EXCL_END */ } - param->origdst = dst; + param.origdst = &dst; - param->hdr[1] = ((pgp_dest_partial_param_t *) param->writedst->param)->parthdr; - param->hdrlen = 2; + param.hdr[1] = ((pgp_dest_partial_param_t *) param.writedst->param)->parthdr; + param.hdrlen = 2; return true; } /* LCOV_EXCL_START this branch is not used at all */ - if (param->indeterminate) { - if (param->tag > 0xf) { + if (param.indeterminate) { + if (param.tag > 0xf) { RNP_LOG("indeterminate tag > 0xf"); } - param->hdr[0] = ((param->tag & 0xf) << PGP_PTAG_OF_CONTENT_TAG_SHIFT) | - PGP_PTAG_OLD_LEN_INDETERMINATE; - param->hdrlen = 1; - dst_write(dst, ¶m->hdr, 1); + param.hdr[0] = ((param.tag & 0xf) << PGP_PTAG_OF_CONTENT_TAG_SHIFT) | + PGP_PTAG_OLD_LEN_INDETERMINATE; + param.hdrlen = 1; + dst_write(&dst, ¶m.hdr, 1); - param->writedst = dst; - param->origdst = dst; + param.writedst = &dst; + param.origdst = &dst; return true; } @@ -574,16 +574,16 @@ encrypted_dst_close(pgp_dest_t *dst, bool discard) } static rnp_result_t -encrypted_add_recipient(pgp_write_handler_t * handler, - pgp_dest_t * dst, +encrypted_add_recipient(rnp_ctx_t & ctx, + pgp_dest_t & dst, pgp_key_t * userkey, const rnp::secure_bytes &key, pgp_pkesk_version_t pkesk_version) { - pgp_dest_encrypted_param_t *param = (pgp_dest_encrypted_param_t *) dst->param; + pgp_dest_encrypted_param_t *param = (pgp_dest_encrypted_param_t *) dst.param; /* Use primary key if good for encryption, otherwise look in subkey list */ - userkey = find_suitable_key(PGP_OP_ENCRYPT, userkey, handler->key_provider); + userkey = find_suitable_key(PGP_OP_ENCRYPT, userkey, &ctx.key_provider); if (!userkey) { return RNP_ERROR_NO_SUITABLE_KEY; } @@ -648,7 +648,7 @@ encrypted_add_recipient(pgp_write_handler_t * handler, assert(ecdh); ecdh->enc.fp = userkey->fp().vec(); } - auto ret = userkey->pkt().material->encrypt(handler->ctx->sec_ctx, *material, enckey); + auto ret = userkey->pkt().material->encrypt(ctx.sec_ctx, *material, enckey); if (ret) { return ret; } @@ -941,70 +941,69 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) } static rnp_result_t -init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *writedst) +init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) { - size_t keylen = pgp_key_size(handler->ctx->ealg); + size_t keylen = pgp_key_size(ctx.ealg); if (!keylen) { RNP_LOG("unknown symmetric algorithm"); return RNP_ERROR_BAD_PARAMETERS; } - if (handler->ctx->aalg) { - if ((handler->ctx->aalg != PGP_AEAD_EAX) && (handler->ctx->aalg != PGP_AEAD_OCB)) { + if (ctx.aalg != PGP_AEAD_NONE) { + if ((ctx.aalg != PGP_AEAD_EAX) && (ctx.aalg != PGP_AEAD_OCB)) { /* LCOV_EXCL_START */ - RNP_LOG("unknown AEAD algorithm: %d", (int) handler->ctx->aalg); + RNP_LOG("unknown AEAD algorithm: %d", (int) ctx.aalg); return RNP_ERROR_BAD_PARAMETERS; /* LCOV_EXCL_END */ } - if ((pgp_block_size(handler->ctx->ealg) != 16)) { + if ((pgp_block_size(ctx.ealg) != 16)) { /* LCOV_EXCL_START */ RNP_LOG("wrong AEAD symmetric algorithm"); return RNP_ERROR_BAD_PARAMETERS; /* LCOV_EXCL_END */ } - if ((handler->ctx->abits < 0) || (handler->ctx->abits > 16)) { + if ((ctx.abits < 0) || (ctx.abits > 16)) { /* LCOV_EXCL_START */ - RNP_LOG("wrong AEAD chunk bits: %d", handler->ctx->abits); + RNP_LOG("wrong AEAD chunk bits: %d", ctx.abits); return RNP_ERROR_BAD_PARAMETERS; /* LCOV_EXCL_END */ } } - auto pkeycount = handler->ctx->recipients.size(); - auto skeycount = handler->ctx->passwords.size(); + auto pkeycount = ctx.recipients.size(); + auto skeycount = ctx.passwords.size(); if (!pkeycount && !skeycount) { RNP_LOG("no recipients"); return RNP_ERROR_BAD_PARAMETERS; } - if (!init_dst_common(dst, 0)) { + if (!init_dst_common(&dst, 0)) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } auto param = new (std::nothrow) pgp_dest_encrypted_param_t(); if (!param) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } - dst->param = param; - param->auth_type = - handler->ctx->aalg == PGP_AEAD_NONE ? rnp::AuthType::MDC : rnp::AuthType::AEADv1; + dst.param = param; + param->auth_type = ctx.aalg == PGP_AEAD_NONE ? rnp::AuthType::MDC : rnp::AuthType::AEADv1; #if defined(ENABLE_CRYPTO_REFRESH) /* in the case of PKESK (pkeycount > 0) and all keys are PKESKv6/SEIPDv2 capable, upgrade * to AEADv2 */ - if (handler->ctx->enable_pkesk_v6 && handler->ctx->pkeskv6_capable() && pkeycount > 0) { + if (ctx.enable_pkesk_v6 && ctx.pkeskv6_capable() && pkeycount) { param->auth_type = rnp::AuthType::AEADv2; } #endif - param->aalg = handler->ctx->aalg; - param->ctx = handler->ctx; - param->pkt.origdst = writedst; + param->aalg = ctx.aalg; + param->ctx = &ctx; + param->pkt.origdst = &writedst; // the following assignment is covered for the v2 SEIPD case further below - dst->write = param->is_aead_auth() ? encrypted_dst_write_aead : encrypted_dst_write_cfb; - dst->finish = encrypted_dst_finish; - dst->close = encrypted_dst_close; - dst->type = PGP_STREAM_ENCRYPTED; + dst.write = param->is_aead_auth() ? encrypted_dst_write_aead : encrypted_dst_write_cfb; + dst.finish = encrypted_dst_finish; + dst.close = encrypted_dst_close; + dst.type = PGP_STREAM_ENCRYPTED; rnp_result_t ret = RNP_ERROR_GENERIC; rnp::secure_bytes enckey(keylen, 0); /* content encryption key */ @@ -1012,7 +1011,7 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr bool singlepass = !pkeycount && (skeycount == 1) && !param->is_aead_auth(); if (!singlepass) { try { - handler->ctx->sec_ctx.rng.get(enckey.data(), keylen); + ctx.sec_ctx.rng.get(enckey.data(), keylen); } catch (const std::exception &e) { /* LCOV_EXCL_START */ ret = RNP_ERROR_RNG; @@ -1022,26 +1021,26 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr } /* Configuring and writing pk-encrypted session keys */ - for (auto recipient : handler->ctx->recipients) { + for (auto recipient : ctx.recipients) { pgp_pkesk_version_t pkesk_version = PGP_PKSK_V3; #if defined(ENABLE_CRYPTO_REFRESH) if (param->auth_type == rnp::AuthType::AEADv2) { pkesk_version = PGP_PKSK_V6; } - if (handler->ctx->aalg == PGP_AEAD_NONE) { + if (ctx.aalg == PGP_AEAD_NONE) { // set default AEAD if not set // TODO-V6: is this the right place to set the default algorithm? param->ctx->aalg = DEFAULT_AEAD_ALG; } #endif - ret = encrypted_add_recipient(handler, dst, recipient, enckey, pkesk_version); + ret = encrypted_add_recipient(ctx, dst, recipient, enckey, pkesk_version); if (ret) { goto finish; } } /* Configuring and writing sk-encrypted session key(s) */ - for (auto &passinfo : handler->ctx->passwords) { + for (auto &passinfo : ctx.passwords) { ret = encrypted_add_password(passinfo, *param, enckey, keylen, singlepass); if (ret) { goto finish; @@ -1066,7 +1065,7 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr /* initializing partial data length writer */ /* we may use intederminate len packet here as well, for compatibility or so on */ - if (!init_streamed_packet(¶m->pkt, writedst)) { + if (!init_streamed_packet(param->pkt, writedst)) { /* LCOV_EXCL_START */ RNP_LOG("failed to init streamed packet"); ret = RNP_ERROR_BAD_PARAMETERS; @@ -1082,9 +1081,9 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr ret = encrypted_start_cfb(param, enckey.data()); } finish: - handler->ctx->passwords.clear(); + ctx.passwords.clear(); if (ret) { - encrypted_dst_close(dst, true); + encrypted_dst_close(&dst, true); } return ret; } @@ -1384,30 +1383,30 @@ signed_dst_set_literal_hdr(pgp_dest_t &src, const pgp_literal_hdr_t &hdr) } static rnp_result_t -signed_add_signer(pgp_dest_signed_param_t *param, rnp_signer_info_t *signer, bool last) +signed_add_signer(pgp_dest_signed_param_t ¶m, rnp_signer_info_t &signer, bool last) { pgp_dest_signer_info_t sinfo = {}; - if (!signer->key->material() || !signer->key->is_secret()) { + if (!signer.key->material() || !signer.key->is_secret()) { RNP_LOG("secret key required for signing"); return RNP_ERROR_BAD_PARAMETERS; } /* validate signing key material if didn't before */ - signer->key->material()->validate(param->ctx->sec_ctx, false); - if (!signer->key->pkt().material->valid()) { + signer.key->material()->validate(param.ctx->sec_ctx, false); + if (!signer.key->pkt().material->valid()) { RNP_LOG("attempt to sign to the key with invalid material"); return RNP_ERROR_NO_SUITABLE_KEY; } /* copy fields */ - sinfo.key = signer->key; - sinfo.sigcreate = signer->sigcreate; - sinfo.sigexpire = signer->sigexpire; + sinfo.key = signer.key; + sinfo.sigcreate = signer.sigcreate; + sinfo.sigexpire = signer.sigexpire; /* Add hash to the list */ - sinfo.halg = signer->key->material()->adjust_hash(signer->halg); + sinfo.halg = signer.key->material()->adjust_hash(signer.halg); try { - param->hashes.add_alg(sinfo.halg); + param.hashes.add_alg(sinfo.halg); } catch (const std::exception &e) { /* LCOV_EXCL_START */ RNP_LOG("%s", e.what()); @@ -1416,10 +1415,10 @@ signed_add_signer(pgp_dest_signed_param_t *param, rnp_signer_info_t *signer, boo } // Do not add onepass for detached/clearsign - if (param->ctx->detached || param->ctx->clearsign) { + if (param.ctx->detached || param.ctx->clearsign) { sinfo.onepass.version = 0; try { - param->siginfos.push_back(sinfo); + param.siginfos.push_back(sinfo); return RNP_SUCCESS; } catch (const std::exception &e) { /* LCOV_EXCL_START */ @@ -1437,7 +1436,7 @@ signed_add_signer(pgp_dest_signed_param_t *param, rnp_signer_info_t *signer, boo sinfo.onepass.keyid = sinfo.key->keyid(); sinfo.onepass.nested = false; try { - param->siginfos.push_back(sinfo); + param.siginfos.push_back(sinfo); } catch (const std::exception &e) { /* LCOV_EXCL_START */ RNP_LOG("%s", e.what()); @@ -1450,31 +1449,24 @@ signed_add_signer(pgp_dest_signed_param_t *param, rnp_signer_info_t *signer, boo return RNP_SUCCESS; } try { - for (auto it = param->siginfos.rbegin(); it != param->siginfos.rend(); it++) { + for (auto it = param.siginfos.rbegin(); it != param.siginfos.rend(); it++) { pgp_dest_signer_info_t &sinfo = *it; - sinfo.onepass.nested = &sinfo == ¶m->siginfos.front(); - sinfo.onepass.write(*param->writedst); + sinfo.onepass.nested = &sinfo == ¶m.siginfos.front(); + sinfo.onepass.write(*param.writedst); } - return param->writedst->werr; + return param.writedst->werr; } catch (const std::exception &e) { return RNP_ERROR_WRITE; // LCOV_EXCL_LINE } } static rnp_result_t -init_signed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *writedst) +init_signed_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) { - pgp_dest_signed_param_t *param; + pgp_dest_signed_param_t *param = NULL; rnp_result_t ret = RNP_ERROR_GENERIC; - if (!handler->key_provider) { - /* LCOV_EXCL_START */ - RNP_LOG("no key provider"); - return RNP_ERROR_BAD_PARAMETERS; - /* LCOV_EXCL_END */ - } - - if (!init_dst_common(dst, 0)) { + if (!init_dst_common(&dst, 0)) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } try { @@ -1486,25 +1478,25 @@ init_signed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *write /* LCOV_EXCL_END */ } - dst->param = param; - param->writedst = writedst; - param->ctx = handler->ctx; - param->password_provider = handler->password_provider; + dst.param = param; + param->writedst = &writedst; + param->ctx = &ctx; + param->password_provider = &ctx.pass_provider; if (param->ctx->clearsign) { - dst->type = PGP_STREAM_CLEARTEXT; - dst->write = cleartext_dst_write; - dst->finish = cleartext_dst_finish; + dst.type = PGP_STREAM_CLEARTEXT; + dst.write = cleartext_dst_write; + dst.finish = cleartext_dst_finish; param->clr_start = true; } else { - dst->type = PGP_STREAM_SIGNED; - dst->write = signed_dst_write; - dst->finish = param->ctx->detached ? signed_detached_dst_finish : signed_dst_finish; + dst.type = PGP_STREAM_SIGNED; + dst.write = signed_dst_write; + dst.finish = param->ctx->detached ? signed_detached_dst_finish : signed_dst_finish; } - dst->close = signed_dst_close; + dst.close = signed_dst_close; /* Getting signer's infos, writing one-pass signatures if needed */ - for (auto &sg : handler->ctx->signers) { - ret = signed_add_signer(param, &sg, &sg == &handler->ctx->signers.back()); + for (auto &sg : ctx.signers) { + ret = signed_add_signer(*param, sg, &sg == &ctx.signers.back()); if (ret) { RNP_LOG("failed to add one-pass signature for signer"); goto finish; @@ -1537,7 +1529,7 @@ init_signed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *write ret = RNP_SUCCESS; finish: if (ret != RNP_SUCCESS) { - signed_dst_close(dst, true); + signed_dst_close(&dst, true); } return ret; @@ -1703,29 +1695,29 @@ compressed_dst_close(pgp_dest_t *dst, bool discard) } static rnp_result_t -init_compressed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *writedst) +init_compressed_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) { - pgp_dest_compressed_param_t *param; + pgp_dest_compressed_param_t *param = NULL; rnp_result_t ret = RNP_ERROR_GENERIC; - uint8_t buf; - int zret; + uint8_t buf = 0; + int zret = 0; - if (!init_dst_common(dst, sizeof(*param))) { + if (!init_dst_common(&dst, sizeof(*param))) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } - param = (pgp_dest_compressed_param_t *) dst->param; - dst->write = compressed_dst_write; - dst->finish = compressed_dst_finish; - dst->close = compressed_dst_close; - dst->type = PGP_STREAM_COMPRESSED; - param->alg = (pgp_compression_type_t) handler->ctx->zalg; + param = (pgp_dest_compressed_param_t *) dst.param; + dst.write = compressed_dst_write; + dst.finish = compressed_dst_finish; + dst.close = compressed_dst_close; + dst.type = PGP_STREAM_COMPRESSED; + param->alg = (pgp_compression_type_t) ctx.zalg; param->pkt.partial = true; param->pkt.indeterminate = false; param->pkt.tag = PGP_PKT_COMPRESSED; /* initializing partial length or indeterminate packet, writing header */ - if (!init_streamed_packet(¶m->pkt, writedst)) { + if (!init_streamed_packet(param->pkt, writedst)) { /* LCOV_EXCL_START */ RNP_LOG("failed to init streamed packet"); ret = RNP_ERROR_BAD_PARAMETERS; @@ -1743,10 +1735,9 @@ init_compressed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *w case PGP_C_ZLIB: (void) memset(¶m->z, 0x0, sizeof(param->z)); if (param->alg == PGP_C_ZIP) { - zret = deflateInit2( - ¶m->z, handler->ctx->zlevel, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + zret = deflateInit2(¶m->z, ctx.zlevel, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); } else { - zret = deflateInit(¶m->z, handler->ctx->zlevel); + zret = deflateInit(¶m->z, ctx.zlevel); } if (zret != Z_OK) { @@ -1758,7 +1749,7 @@ init_compressed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *w #ifdef HAVE_BZLIB_H case PGP_C_BZIP2: (void) memset(¶m->bz, 0x0, sizeof(param->bz)); - zret = BZ2_bzCompressInit(¶m->bz, handler->ctx->zlevel, 0, 0); + zret = BZ2_bzCompressInit(¶m->bz, ctx.zlevel, 0, 0); if (zret != BZ_OK) { RNP_LOG("failed to init bz, error %d", zret); ret = RNP_ERROR_NOT_SUPPORTED; @@ -1775,9 +1766,8 @@ init_compressed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *w ret = RNP_SUCCESS; finish: if (ret != RNP_SUCCESS) { - compressed_dst_close(dst, true); + compressed_dst_close(&dst, true); } - return ret; } @@ -1835,28 +1825,28 @@ build_literal_hdr(const rnp_ctx_t &ctx, pgp_literal_hdr_t &hdr) } static rnp_result_t -init_literal_dst(pgp_literal_hdr_t &hdr, pgp_dest_t *dst, pgp_dest_t *writedst) +init_literal_dst(pgp_literal_hdr_t &hdr, pgp_dest_t &dst, pgp_dest_t &writedst) { - pgp_dest_packet_param_t *param; + pgp_dest_packet_param_t *param = NULL; - if (!init_dst_common(dst, sizeof(*param))) { + if (!init_dst_common(&dst, sizeof(*param))) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } - param = (pgp_dest_packet_param_t *) dst->param; - dst->write = literal_dst_write; - dst->finish = literal_dst_finish; - dst->close = literal_dst_close; - dst->type = PGP_STREAM_LITERAL; + param = (pgp_dest_packet_param_t *) dst.param; + dst.write = literal_dst_write; + dst.finish = literal_dst_finish; + dst.close = literal_dst_close; + dst.type = PGP_STREAM_LITERAL; param->partial = true; param->indeterminate = false; param->tag = PGP_PKT_LITDATA; /* initializing partial length or indeterminate packet, writing header */ - if (!init_streamed_packet(param, writedst)) { + if (!init_streamed_packet(*param, writedst)) { /* LCOV_EXCL_START */ RNP_LOG("failed to init streamed packet"); - literal_dst_close(dst, true); + literal_dst_close(&dst, true); return RNP_ERROR_BAD_PARAMETERS; /* LCOV_EXCL_END */ } @@ -1877,7 +1867,7 @@ init_literal_dst(pgp_literal_hdr_t &hdr, pgp_dest_t *dst, pgp_dest_t *writedst) } static rnp_result_t -process_stream_sequence(pgp_source_t *src, +process_stream_sequence(pgp_source_t &src, pgp_dest_t * streams, unsigned count, pgp_dest_t * sstream, @@ -1892,9 +1882,9 @@ process_stream_sequence(pgp_source_t *src, } /* processing source stream */ - while (!src->eof_) { + while (!src.eof_) { size_t read = 0; - if (!src->read(readbuf.get(), PGP_INPUT_CACHE_SIZE, &read)) { + if (!src.read(readbuf.get(), PGP_INPUT_CACHE_SIZE, &read)) { RNP_LOG("failed to read from source"); return RNP_ERROR_READ; } else if (!read) { @@ -1929,7 +1919,7 @@ process_stream_sequence(pgp_source_t *src, } rnp_result_t -rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst) +rnp_sign_src(rnp_ctx_t &ctx, pgp_source_t &src, pgp_dest_t &dst) { /* stack of the streams would be as following: [armoring stream] - if armoring is enabled @@ -1940,14 +1930,13 @@ rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst) pgp_dest_t dests[4]; size_t destc = 0; rnp_result_t ret = RNP_ERROR_GENERIC; - rnp_ctx_t & ctx = *handler->ctx; pgp_dest_t * wstream = NULL; pgp_dest_t * sstream = NULL; /* pushing armoring stream, which will write to the output */ if (ctx.armor && !ctx.clearsign) { pgp_armored_msg_t msgt = ctx.detached ? PGP_ARMORED_SIGNATURE : PGP_ARMORED_MESSAGE; - ret = init_armored_dst(&dests[destc], dst, msgt); + ret = init_armored_dst(&dests[destc], &dst, msgt); if (ret) { goto finish; } @@ -1956,8 +1945,7 @@ rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst) /* if compression is enabled then pushing compressing stream */ if (!ctx.detached && !ctx.clearsign && (ctx.zlevel > 0)) { - if ((ret = - init_compressed_dst(handler, &dests[destc], destc ? &dests[destc - 1] : dst))) { + if ((ret = init_compressed_dst(ctx, dests[destc], destc ? dests[destc - 1] : dst))) { goto finish; } destc++; @@ -1965,7 +1953,7 @@ rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst) /* pushing signing stream, which will use handler->ctx to distinguish between * attached/detached/cleartext signature */ - if ((ret = init_signed_dst(handler, &dests[destc], destc ? &dests[destc - 1] : dst))) { + if ((ret = init_signed_dst(ctx, dests[destc], destc ? dests[destc - 1] : dst))) { goto finish; } if (!ctx.clearsign) { @@ -1981,7 +1969,7 @@ rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst) pgp_literal_hdr_t hdr{}; build_literal_hdr(ctx, hdr); - if ((ret = init_literal_dst(hdr, &dests[destc], &dests[destc - 1]))) { + if ((ret = init_literal_dst(hdr, dests[destc], dests[destc - 1]))) { goto finish; } signed_dst_set_literal_hdr(dests[destc - 1], hdr); @@ -2008,7 +1996,7 @@ rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst) } rnp_result_t -rnp_encrypt_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst) +rnp_encrypt_sign_src(rnp_ctx_t &ctx, pgp_source_t &src, pgp_dest_t &dst) { /* stack of the streams would be as following: [armoring stream] - if armoring is enabled @@ -2020,7 +2008,6 @@ rnp_encrypt_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t pgp_dest_t dests[5]; size_t destc = 0; rnp_result_t ret = RNP_SUCCESS; - rnp_ctx_t & ctx = *handler->ctx; pgp_dest_t * sstream = NULL; /* we may use only attached signatures here */ @@ -2031,21 +2018,21 @@ rnp_encrypt_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t /* pushing armoring stream, which will write to the output */ if (ctx.armor) { - if ((ret = init_armored_dst(&dests[destc], dst, PGP_ARMORED_MESSAGE))) { + if ((ret = init_armored_dst(&dests[destc], &dst, PGP_ARMORED_MESSAGE))) { goto finish; } destc++; } /* pushing encrypting stream, which will write to the output or armoring stream */ - if ((ret = init_encrypted_dst(handler, &dests[destc], destc ? &dests[destc - 1] : dst))) { + if ((ret = init_encrypted_dst(ctx, dests[destc], destc ? dests[destc - 1] : dst))) { goto finish; } destc++; /* if compression is enabled then pushing compressing stream */ if (ctx.zlevel > 0) { - if ((ret = init_compressed_dst(handler, &dests[destc], &dests[destc - 1]))) { + if ((ret = init_compressed_dst(ctx, dests[destc], dests[destc - 1]))) { goto finish; } destc++; @@ -2053,7 +2040,7 @@ rnp_encrypt_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t /* pushing signing stream if we have signers */ if (!ctx.signers.empty()) { - if ((ret = init_signed_dst(handler, &dests[destc], &dests[destc - 1]))) { + if ((ret = init_signed_dst(ctx, dests[destc], dests[destc - 1]))) { goto finish; } sstream = &dests[destc]; @@ -2065,7 +2052,7 @@ rnp_encrypt_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t pgp_literal_hdr_t hdr{}; build_literal_hdr(ctx, hdr); - if ((ret = init_literal_dst(hdr, &dests[destc], &dests[destc - 1]))) { + if ((ret = init_literal_dst(hdr, dests[destc], dests[destc - 1]))) { goto finish; } @@ -2088,7 +2075,6 @@ rnp_encrypt_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t rnp_result_t rnp_compress_src(pgp_source_t &src, pgp_dest_t &dst, pgp_compression_type_t zalg, int zlevel) { - pgp_write_handler_t handler = {}; rnp::SecurityContext sec_ctx; rnp::KeyProvider key_prov; pgp_password_provider_t pass_prov; @@ -2096,10 +2082,9 @@ rnp_compress_src(pgp_source_t &src, pgp_dest_t &dst, pgp_compression_type_t zalg ctx.zalg = zalg; ctx.zlevel = zlevel; - handler.ctx = &ctx; pgp_dest_t compressed = {}; - rnp_result_t ret = init_compressed_dst(&handler, &compressed, &dst); + rnp_result_t ret = init_compressed_dst(ctx, compressed, dst); if (ret) { goto done; } @@ -2124,7 +2109,7 @@ rnp_wrap_src(pgp_source_t &src, pgp_dest_t &dst, const std::string &filename, ui pgp_literal_hdr_t hdr{}; build_literal_hdr(ctx, hdr); - rnp_result_t ret = init_literal_dst(hdr, &literal, &dst); + rnp_result_t ret = init_literal_dst(hdr, literal, dst); if (ret) { goto done; } @@ -2141,13 +2126,11 @@ rnp_raw_encrypt_src(pgp_source_t & src, const std::string & password, rnp::SecurityContext &secctx) { - pgp_write_handler_t handler = {}; rnp::SecurityContext sec_ctx; rnp::KeyProvider key_prov; pgp_password_provider_t pass_prov; rnp_ctx_t ctx(sec_ctx, key_prov, pass_prov); - handler.ctx = &ctx; pgp_dest_t encrypted = {}; rnp_result_t ret = RNP_ERROR_GENERIC; @@ -2164,7 +2147,7 @@ rnp_raw_encrypt_src(pgp_source_t & src, goto done; } - ret = init_encrypted_dst(&handler, &encrypted, &dst); + ret = init_encrypted_dst(ctx, encrypted, dst); if (ret) { goto done; } diff --git a/src/librepgp/stream-write.h b/src/librepgp/stream-write.h index 710499974..59cd3d838 100644 --- a/src/librepgp/stream-write.h +++ b/src/librepgp/stream-write.h @@ -34,14 +34,6 @@ #include "stream-common.h" #include "stream-ctx.h" -typedef struct pgp_write_handler_t { - pgp_password_provider_t *password_provider{}; - rnp::KeyProvider * key_provider{}; - rnp_ctx_t * ctx{}; - - void *param{}; -} pgp_write_handler_t; - /** @brief sign the input data, producing attached, detached or cleartext signature. * Type of the signature is controlled by clearsign and detached fields of the * rnp_ctx_t structure @@ -50,7 +42,7 @@ typedef struct pgp_write_handler_t { * @param src input source: file, stdin, memory, whatever else conforming to pgp_source_t * @param dst output destination: file, stdout, memory, whatever else conforming to pgp_dest_t **/ -rnp_result_t rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_dest_t *dst); +rnp_result_t rnp_sign_src(rnp_ctx_t &ctx, pgp_source_t &src, pgp_dest_t &dst); /** @brief encrypt and sign the input data. Signatures will be encrypted together with data. * @param handler handler handler to respond on stream processor callbacks, and additional @@ -58,9 +50,7 @@ rnp_result_t rnp_sign_src(pgp_write_handler_t *handler, pgp_source_t *src, pgp_d * @param src input source: file, stdin, memory, whatever else conforming to pgp_source_t * @param dst output destination: file, stdout, memory, whatever else conforming to pgp_dest_t **/ -rnp_result_t rnp_encrypt_sign_src(pgp_write_handler_t *handler, - pgp_source_t * src, - pgp_dest_t * dst); +rnp_result_t rnp_encrypt_sign_src(rnp_ctx_t &ctx, pgp_source_t &src, pgp_dest_t &dst); /* Following functions are used only in tests currently. Later could be used in CLI for debug * commands like --wrap-literal, --encrypt-raw, --compress-raw, etc. */ From 7fe09e2dd92c82565b52d37a3aeca59f9866bb3a Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Wed, 15 Jan 2025 14:15:27 +0200 Subject: [PATCH 5/9] Fix is_aead_auth() method. --- src/librepgp/stream-write.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/librepgp/stream-write.cpp b/src/librepgp/stream-write.cpp index 425f16a19..a38b8e15d 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -116,13 +116,10 @@ typedef struct pgp_dest_encrypted_param_t { case rnp::AuthType::AEADv2: #endif return true; - break; - case rnp::AuthType::MDC: - case rnp::AuthType::None: + default: return false; } - throw rnp::rnp_exception(RNP_ERROR_GENERIC); - }; + } #ifdef ENABLE_CRYPTO_REFRESH bool @@ -770,7 +767,7 @@ encrypted_add_password(rnp_symmetric_pass_info_t & pass, skey.s2k = pass.s2k; rnp_result_t ret = RNP_ERROR_GENERIC; - if (param.auth_type != rnp::AuthType::AEADv1) { + if (!param.is_aead_auth()) { ret = encrypted_add_password_v4(pass, param.ctx->ealg, key, keylen, skey, singlepass); } else { ret = encrypted_add_password_v5( @@ -1027,10 +1024,9 @@ init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) if (param->auth_type == rnp::AuthType::AEADv2) { pkesk_version = PGP_PKSK_V6; } - if (ctx.aalg == PGP_AEAD_NONE) { + if (param->is_aead_auth() && (param->ctx.aalg == PGP_AEAD_NONE)) { // set default AEAD if not set - // TODO-V6: is this the right place to set the default algorithm? - param->ctx->aalg = DEFAULT_AEAD_ALG; + param->ctx.aalg = DEFAULT_AEAD_ALG; } #endif ret = encrypted_add_recipient(ctx, dst, recipient, enckey, pkesk_version); From 33332f400b69b875f4499fab579bbd02b36b824e Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Wed, 15 Jan 2025 14:44:12 +0200 Subject: [PATCH 6/9] Remove duplication of encrypted_sesk_set_ad. --- src/librepgp/stream-common.cpp | 16 ++++++++++++++++ src/librepgp/stream-common.h | 4 ++++ src/librepgp/stream-parse.cpp | 19 +------------------ src/librepgp/stream-write.cpp | 17 +---------------- 4 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/librepgp/stream-common.cpp b/src/librepgp/stream-common.cpp index c271a181c..392bd8f67 100644 --- a/src/librepgp/stream-common.cpp +++ b/src/librepgp/stream-common.cpp @@ -45,6 +45,7 @@ #include #include "rnp.h" #include "stream-common.h" +#include "stream-packet.h" #include "types.h" #include "file-utils.h" #include "crypto/mem.h" @@ -1230,3 +1231,18 @@ check_enforce_aes_v3_pkesk(pgp_pubkey_alg_t alg, pgp_symm_alg_t salg, pgp_pkesk_ return (ver != PGP_PKSK_V3) || have_pkesk_checksum(alg) || pgp_is_sa_aes(salg); } #endif + +#if defined(ENABLE_AEAD) +bool +encrypted_sesk_set_ad(pgp_crypt_t &crypt, pgp_sk_sesskey_t &skey) +{ + uint8_t ad_data[4]; + + ad_data[0] = PGP_PKT_SK_SESSION_KEY | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT; + ad_data[1] = skey.version; + ad_data[2] = skey.alg; + ad_data[3] = skey.aalg; + + return pgp_cipher_aead_set_ad(&crypt, ad_data, 4); +} +#endif diff --git a/src/librepgp/stream-common.h b/src/librepgp/stream-common.h index ed420a793..91f72bac3 100644 --- a/src/librepgp/stream-common.h +++ b/src/librepgp/stream-common.h @@ -563,5 +563,9 @@ bool check_enforce_aes_v3_pkesk(pgp_pubkey_alg_t alg, pgp_symm_alg_t salg, pgp_pkesk_version_t ver); #endif +#if defined(ENABLE_AEAD) +typedef struct pgp_sk_sesskey_t pgp_sk_sesskey_t; +bool encrypted_sesk_set_ad(pgp_crypt_t &crypt, pgp_sk_sesskey_t &skey); +#endif #endif diff --git a/src/librepgp/stream-parse.cpp b/src/librepgp/stream-parse.cpp index 11ba93ac6..e88b1d370 100644 --- a/src/librepgp/stream-parse.cpp +++ b/src/librepgp/stream-parse.cpp @@ -1662,23 +1662,6 @@ encrypted_try_key(pgp_source_encrypted_param_t *param, return res; } -#if defined(ENABLE_AEAD) -static bool -encrypted_sesk_set_ad(pgp_crypt_t *crypt, pgp_sk_sesskey_t *skey) -{ - /* TODO: this method is exact duplicate as in stream-write.c. Not sure where to put it - */ - uint8_t ad_data[4]; - - ad_data[0] = PGP_PKT_SK_SESSION_KEY | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT; - ad_data[1] = skey->version; - ad_data[2] = skey->alg; - ad_data[3] = skey->aalg; - - return pgp_cipher_aead_set_ad(crypt, ad_data, 4); -} -#endif - static int encrypted_try_password(pgp_source_encrypted_param_t *param, const char *password) { @@ -1738,7 +1721,7 @@ encrypted_try_password(pgp_source_encrypted_param_t *param, const char *password } /* set additional data */ - if (!encrypted_sesk_set_ad(&crypt, &skey)) { + if (!encrypted_sesk_set_ad(crypt, skey)) { RNP_LOG("failed to set ad"); continue; } diff --git a/src/librepgp/stream-write.cpp b/src/librepgp/stream-write.cpp index a38b8e15d..f6ea073f8 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -660,21 +660,6 @@ encrypted_add_recipient(rnp_ctx_t & ctx, } } -#if defined(ENABLE_AEAD) -static bool -encrypted_sesk_set_ad(pgp_crypt_t *crypt, pgp_sk_sesskey_t *skey) -{ - uint8_t ad_data[4]; - - ad_data[0] = PGP_PKT_SK_SESSION_KEY | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT; - ad_data[1] = skey->version; - ad_data[2] = skey->alg; - ad_data[3] = skey->aalg; - - return pgp_cipher_aead_set_ad(crypt, ad_data, 4); -} -#endif - static rnp_result_t encrypted_add_password_v4(rnp_symmetric_pass_info_t &pass, pgp_symm_alg_t ealg, @@ -738,7 +723,7 @@ encrypted_add_password_v5(rnp_symmetric_pass_info_t &pass, } /* set additional data */ - if (!encrypted_sesk_set_ad(&kcrypt, &skey)) { + if (!encrypted_sesk_set_ad(kcrypt, skey)) { return RNP_ERROR_BAD_STATE; // LCOV_EXCL_LINE } From c77547b621474605550b5d1e1056ac4474253d5e Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Fri, 24 Jan 2025 12:45:13 +0200 Subject: [PATCH 7/9] Refactor SKESK writing and check for possible incorrect password try by GnuPG. --- src/lib/crypto/mem.h | 6 + src/librepgp/stream-write.cpp | 272 +++++++++++++++++++--------------- 2 files changed, 160 insertions(+), 118 deletions(-) diff --git a/src/lib/crypto/mem.h b/src/lib/crypto/mem.h index a883c0868..db950670f 100644 --- a/src/lib/crypto/mem.h +++ b/src/lib/crypto/mem.h @@ -123,6 +123,12 @@ template struct secure_array { return &data_[0]; } + const T * + data() const + { + return &data_[0]; + } + std::size_t size() const { diff --git a/src/librepgp/stream-write.cpp b/src/librepgp/stream-write.cpp index f6ea073f8..56e95f1e5 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -89,23 +89,28 @@ typedef struct pgp_dest_compressed_param_t { } pgp_dest_compressed_param_t; typedef struct pgp_dest_encrypted_param_t { - pgp_dest_packet_param_t pkt; /* underlying packet-related params */ - rnp_ctx_t * ctx; /* rnp operation context with additional parameters */ - rnp::AuthType auth_type; /* Authentication type: MDC, AEAD or none */ - pgp_crypt_t encrypt; /* encrypting crypto */ - std::unique_ptr mdc; /* mdc SHA1 hash */ - pgp_aead_alg_t aalg; /* AEAD algorithm used */ - uint8_t iv[PGP_AEAD_MAX_NONCE_LEN]; /* iv for AEAD mode */ - uint8_t ad[PGP_AEAD_MAX_AD_LEN]; /* additional data for AEAD mode */ - size_t adlen; /* length of additional data, including chunk idx */ - size_t chunklen; /* length of the AEAD chunk in bytes */ - size_t chunkout; /* how many bytes from the chunk were written out */ - size_t chunkidx; /* index of the current AEAD chunk */ - size_t cachelen; /* how many bytes are in cache, for AEAD */ - uint8_t cache[PGP_AEAD_CACHE_LEN]; /* pre-allocated cache for encryption */ + pgp_dest_packet_param_t pkt{}; /* underlying packet-related params */ + rnp_ctx_t & ctx; /* rnp operation context with additional parameters */ + rnp::AuthType auth_type{}; /* Authentication type: MDC, AEAD or none */ + pgp_crypt_t encrypt{}; /* encrypting crypto */ + std::unique_ptr mdc; /* mdc SHA1 hash */ + pgp_aead_alg_t aalg; /* AEAD algorithm used */ + uint8_t iv[PGP_AEAD_MAX_NONCE_LEN]{}; /* iv for AEAD mode */ + uint8_t ad[PGP_AEAD_MAX_AD_LEN]{}; /* additional data for AEAD mode */ + size_t adlen{}; /* length of additional data, including chunk idx */ + size_t chunklen{}; /* length of the AEAD chunk in bytes */ + size_t chunkout{}; /* how many bytes from the chunk were written out */ + size_t chunkidx{}; /* index of the current AEAD chunk */ + size_t cachelen{}; /* how many bytes are in cache, for AEAD */ + uint8_t cache[PGP_AEAD_CACHE_LEN]{}; /* pre-allocated cache for encryption */ #ifdef ENABLE_CRYPTO_REFRESH std::array v2_seipd_salt; /* SEIPDv2 salt value */ #endif + std::list skesks; + + pgp_dest_encrypted_param_t(rnp_ctx_t &actx) : ctx(actx), aalg(PGP_AEAD_NONE) + { + } bool is_aead_auth() @@ -321,8 +326,7 @@ close_streamed_packet(pgp_dest_packet_param_t *param, bool discard) static rnp_result_t encrypted_dst_write_cfb(pgp_dest_t *dst, const void *buf, size_t len) { - pgp_dest_encrypted_param_t *param = (pgp_dest_encrypted_param_t *) dst->param; - + auto param = static_cast(dst->param); if (!param) { /* LCOV_EXCL_START */ RNP_LOG("wrong param"); @@ -439,7 +443,7 @@ encrypted_dst_write_aead(pgp_dest_t *dst, const void *buf, size_t len) RNP_LOG("AEAD is not enabled."); return RNP_ERROR_WRITE; #else - pgp_dest_encrypted_param_t *param = (pgp_dest_encrypted_param_t *) dst->param; + auto param = static_cast(dst->param); size_t sz; size_t gran; @@ -508,7 +512,7 @@ encrypted_dst_write_aead(pgp_dest_t *dst, const void *buf, size_t len) static rnp_result_t encrypted_dst_finish(pgp_dest_t *dst) { - pgp_dest_encrypted_param_t *param = (pgp_dest_encrypted_param_t *) dst->param; + auto param = static_cast(dst->param); if (param->is_aead_auth()) { #if !defined(ENABLE_AEAD) @@ -552,8 +556,7 @@ encrypted_dst_finish(pgp_dest_t *dst) static void encrypted_dst_close(pgp_dest_t *dst, bool discard) { - pgp_dest_encrypted_param_t *param = (pgp_dest_encrypted_param_t *) dst->param; - + auto param = static_cast(dst->param); if (!param) { return; // LCOV_EXCL_LINE } @@ -577,7 +580,7 @@ encrypted_add_recipient(rnp_ctx_t & ctx, const rnp::secure_bytes &key, pgp_pkesk_version_t pkesk_version) { - pgp_dest_encrypted_param_t *param = (pgp_dest_encrypted_param_t *) dst.param; + auto param = static_cast(dst.param); /* Use primary key if good for encryption, otherwise look in subkey list */ userkey = find_suitable_key(PGP_OP_ENCRYPT, userkey, &ctx.key_provider); @@ -588,7 +591,7 @@ encrypted_add_recipient(rnp_ctx_t & ctx, #if defined(ENABLE_CRYPTO_REFRESH) || defined(ENABLE_PQC) /* Crypto Refresh: For X25519/X448 PKESKv3, AES is mandated */ /* PQC: AES is mandated for PKESKv3 */ - if (!check_enforce_aes_v3_pkesk(userkey->alg(), param->ctx->ealg, pkesk_version)) { + if (!check_enforce_aes_v3_pkesk(userkey->alg(), param->ctx.ealg, pkesk_version)) { RNP_LOG("attempting to use v3 PKESK with an unencrypted algorithm id in " "combination with a symmetric " "algorithm that is not AES."); @@ -600,7 +603,7 @@ encrypted_add_recipient(rnp_ctx_t & ctx, pgp_pk_sesskey_t pkey; pkey.version = pkesk_version; pkey.alg = userkey->alg(); - pkey.salg = param->ctx->ealg; + pkey.salg = param->ctx.ealg; /* set key_id (used for PKESK v3) and fingerprint (used for PKESK v6) */ pkey.key_id = userkey->keyid(); #if defined(ENABLE_CRYPTO_REFRESH) @@ -660,71 +663,80 @@ encrypted_add_recipient(rnp_ctx_t & ctx, } } -static rnp_result_t -encrypted_add_password_v4(rnp_symmetric_pass_info_t &pass, - pgp_symm_alg_t ealg, - rnp::secure_bytes & key, - size_t keylen, - pgp_sk_sesskey_t & skey, - bool singlepass) +static void +encrypted_add_password_v4_single(pgp_dest_encrypted_param_t ¶m, + rnp::secure_bytes & key, + size_t keylen) { + assert(param.ctx.passwords.size() == 1); + pgp_sk_sesskey_t skey{}; + auto & pass = param.ctx.passwords.front(); skey.version = PGP_SKSK_V4; - if (singlepass) { - /* if there are no public keys then we do not encrypt session key in the packet */ - skey.alg = ealg; - skey.enckeylen = 0; - key.assign(pass.key.data(), pass.key.data() + keylen); - return RNP_SUCCESS; - } + skey.s2k = pass.s2k; + /* if there are no public keys then we do not encrypt session key in the packet */ + skey.alg = param.ctx.ealg; + skey.enckeylen = 0; + key.assign(pass.key.data(), pass.key.data() + keylen); + param.skesks.push_back(skey); +} + +static bool +encrypted_add_password_v4(pgp_dest_encrypted_param_t & param, + const rnp_symmetric_pass_info_t &pass, + const rnp::secure_bytes & key) +{ + pgp_sk_sesskey_t skey{}; + skey.version = PGP_SKSK_V4; + skey.s2k = pass.s2k; /* We may use different algo for CEK and KEK */ - skey.enckeylen = keylen + 1; - skey.enckey[0] = ealg; - memcpy(&skey.enckey[1], key.data(), keylen); + skey.enckeylen = key.size() + 1; + skey.enckey[0] = param.ctx.ealg; + memcpy(&skey.enckey[1], key.data(), key.size()); skey.alg = pass.s2k_cipher; pgp_crypt_t kcrypt; if (!pgp_cipher_cfb_start(&kcrypt, skey.alg, pass.key.data(), NULL)) { RNP_LOG("key encryption failed"); - return RNP_ERROR_BAD_PARAMETERS; + return false; } pgp_cipher_cfb_encrypt(&kcrypt, skey.enckey, skey.enckey, skey.enckeylen); pgp_cipher_cfb_finish(&kcrypt); - return RNP_SUCCESS; + param.skesks.push_back(skey); + return true; } -static rnp_result_t -encrypted_add_password_v5(rnp_symmetric_pass_info_t &pass, - pgp_aead_alg_t aalg, - rnp::RNG & rng, - rnp::secure_bytes & key, - size_t keylen, - pgp_sk_sesskey_t & skey) +static bool +encrypted_add_password_v5(pgp_dest_encrypted_param_t & param, + const rnp_symmetric_pass_info_t &pass, + const rnp::secure_bytes & key) { #if !defined(ENABLE_AEAD) RNP_LOG("AEAD support is not enabled."); return RNP_ERROR_NOT_IMPLEMENTED; #else /* AEAD-encrypted v5 packet */ - if ((aalg != PGP_AEAD_EAX) && (aalg != PGP_AEAD_OCB)) { + if ((param.ctx.aalg != PGP_AEAD_EAX) && (param.ctx.aalg != PGP_AEAD_OCB)) { RNP_LOG("unsupported AEAD algorithm"); - return RNP_ERROR_BAD_PARAMETERS; + return false; } + pgp_sk_sesskey_t skey{}; skey.version = PGP_SKSK_V5; + skey.s2k = pass.s2k; skey.alg = pass.s2k_cipher; - skey.aalg = aalg; + skey.aalg = param.ctx.aalg; skey.ivlen = pgp_cipher_aead_nonce_len(skey.aalg); - skey.enckeylen = keylen + pgp_cipher_aead_tag_len(skey.aalg); - rng.get(skey.iv, skey.ivlen); + skey.enckeylen = key.size() + pgp_cipher_aead_tag_len(skey.aalg); + param.ctx.sec_ctx.rng.get(skey.iv, skey.ivlen); /* initialize cipher */ pgp_crypt_t kcrypt; if (!pgp_cipher_aead_init(&kcrypt, skey.alg, skey.aalg, pass.key.data(), false)) { - return RNP_ERROR_BAD_PARAMETERS; + return false; } /* set additional data */ if (!encrypted_sesk_set_ad(kcrypt, skey)) { - return RNP_ERROR_BAD_STATE; // LCOV_EXCL_LINE + return false; // LCOV_EXCL_LINE } /* calculate nonce */ @@ -733,43 +745,80 @@ encrypted_add_password_v5(rnp_symmetric_pass_info_t &pass, /* start cipher, encrypt key and get tag */ bool res = pgp_cipher_aead_start(&kcrypt, nonce, nlen) && - pgp_cipher_aead_finish(&kcrypt, skey.enckey, key.data(), keylen); + pgp_cipher_aead_finish(&kcrypt, skey.enckey, key.data(), key.size()); pgp_cipher_aead_destroy(&kcrypt); - - return res ? RNP_SUCCESS : RNP_ERROR_BAD_STATE; + if (res) { + param.skesks.push_back(skey); + } + return res; #endif } -static rnp_result_t -encrypted_add_password(rnp_symmetric_pass_info_t & pass, - pgp_dest_encrypted_param_t ¶m, - rnp::secure_bytes & key, - const size_t keylen, - bool singlepass) +static bool +encrypted_build_skesk(pgp_dest_encrypted_param_t ¶m, + rnp::secure_bytes & key, + const size_t keylen) { - pgp_sk_sesskey_t skey = {}; - skey.s2k = pass.s2k; + auto &ctx = param.ctx; + if (ctx.passwords.empty()) { + return true; + } - rnp_result_t ret = RNP_ERROR_GENERIC; - if (!param.is_aead_auth()) { - ret = encrypted_add_password_v4(pass, param.ctx->ealg, key, keylen, skey, singlepass); - } else { - ret = encrypted_add_password_v5( - pass, param.ctx->aalg, param.ctx->sec_ctx.rng, key, keylen, skey); + /* v4 single-password encryption case */ + if (ctx.recipients.empty() && (ctx.passwords.size() == 1) && !param.is_aead_auth()) { + encrypted_add_password_v4_single(param, key, keylen); + return true; } - if (ret) { - return ret; + size_t attempts = 0; +gencek: + ctx.sec_ctx.rng.get(key.data(), keylen); + for (auto &pass : param.ctx.passwords) { + bool res = param.is_aead_auth() ? encrypted_add_password_v5(param, pass, key) : + encrypted_add_password_v4(param, pass, key); + if (!res) { + return false; + } } - /* Writing symmetric key encrypted session key packet */ - try { - skey.write(*param.pkt.origdst); - } catch (const std::exception &e) { - return RNP_ERROR_WRITE; // LCOV_EXCL_LINE + if (param.is_aead_auth()) { + return true; + } + /* Workaround for GnuPG symmetric key validity check: if first byte of the decrypted data + * is a valid symmetric algorithm number then it uses password provided, producing an error + * afterwards. */ + for (auto &pass : param.ctx.passwords) { + for (auto &skey : param.skesks) { + /* attempt to decrypt cek */ + pgp_crypt_t crypt; + if (!pgp_cipher_cfb_start(&crypt, skey.alg, pass.key.data(), NULL)) { + return false; + } + assert(skey.enckeylen == keylen + 1); + rnp::secure_bytes dec(skey.enckeylen, 0); + pgp_cipher_cfb_decrypt(&crypt, dec.data(), skey.enckey, skey.enckeylen); + pgp_cipher_cfb_finish(&crypt); + + /* using the correct key */ + if (!memcmp(dec.data() + 1, key.data(), keylen)) { + continue; + } + + /* check whether the first byte decrypts to valid alg name */ + if (pgp_key_size(static_cast(dec[0]))) { + /* Do not do too many attempts */ + attempts++; + if (attempts >= 8) { + break; + } + /* re-generate CEK */ + param.skesks.clear(); + goto gencek; + } + } } - return param.pkt.origdst->werr; + return true; } static rnp_result_t @@ -794,14 +843,14 @@ encrypted_start_cfb(pgp_dest_encrypted_param_t *param, uint8_t *enckey) } /* initializing the crypto */ - if (!pgp_cipher_cfb_start(¶m->encrypt, param->ctx->ealg, enckey, NULL)) { + if (!pgp_cipher_cfb_start(¶m->encrypt, param->ctx.ealg, enckey, NULL)) { return RNP_ERROR_BAD_PARAMETERS; } /* generating and writing iv/password check bytes */ - blsize = pgp_block_size(param->ctx->ealg); + blsize = pgp_block_size(param->ctx.ealg); try { - param->ctx->sec_ctx.rng.get(enchdr, blsize); + param->ctx.sec_ctx.rng.get(enchdr, blsize); enchdr[blsize] = enchdr[blsize - 2]; enchdr[blsize + 1] = enchdr[blsize - 1]; @@ -838,7 +887,7 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) uint8_t hdr[4 + PGP_AEAD_MAX_NONCE_OR_SALT_LEN]; size_t nlen; - if (pgp_block_size(param->ctx->ealg) != 16) { + if (pgp_block_size(param->ctx.ealg) != 16) { return RNP_ERROR_BAD_PARAMETERS; } @@ -848,12 +897,12 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) #else hdr[0] = 1; #endif - hdr[1] = param->ctx->ealg; - hdr[2] = param->ctx->aalg; - hdr[3] = param->ctx->abits; + hdr[1] = param->ctx.ealg; + hdr[2] = param->ctx.aalg; + hdr[3] = param->ctx.abits; /* generate iv */ - nlen = pgp_cipher_aead_nonce_len(param->ctx->aalg); + nlen = pgp_cipher_aead_nonce_len(param->ctx.aalg); uint8_t *iv_or_salt = param->iv; size_t iv_or_salt_len = nlen; #ifdef ENABLE_CRYPTO_REFRESH @@ -863,7 +912,7 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) } #endif try { - param->ctx->sec_ctx.rng.get(iv_or_salt, iv_or_salt_len); + param->ctx.sec_ctx.rng.get(iv_or_salt, iv_or_salt_len); } catch (const std::exception &e) { return RNP_ERROR_RNG; // LCOV_EXCL_LINE } @@ -895,11 +944,11 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) } seipd_v2_aead_fields_t s2_fields; if (param->auth_type == rnp::AuthType::AEADv2) { - param->aalg = param->ctx->aalg; + param->aalg = param->ctx.aalg; pgp_seipdv2_hdr_t v2_seipd_hdr; - v2_seipd_hdr.cipher_alg = param->ctx->ealg; - v2_seipd_hdr.aead_alg = param->ctx->aalg; - v2_seipd_hdr.chunk_size_octet = param->ctx->abits; + v2_seipd_hdr.cipher_alg = param->ctx.ealg; + v2_seipd_hdr.aead_alg = param->ctx.aalg; + v2_seipd_hdr.chunk_size_octet = param->ctx.abits; v2_seipd_hdr.version = PGP_SE_IP_DATA_V2; memcpy(v2_seipd_hdr.salt, iv_or_salt, PGP_SEIPDV2_SALT_LEN); s2_fields = seipd_v2_key_and_nonce_derivation(v2_seipd_hdr, enckey); @@ -914,7 +963,7 @@ encrypted_start_aead(pgp_dest_encrypted_param_t *param, uint8_t *enckey) /* initialize cipher */ if (!pgp_cipher_aead_init( - ¶m->encrypt, param->ctx->ealg, param->ctx->aalg, enckey, false)) { + ¶m->encrypt, param->ctx.ealg, param->ctx.aalg, enckey, false)) { return RNP_ERROR_BAD_PARAMETERS; } @@ -954,9 +1003,7 @@ init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) } } - auto pkeycount = ctx.recipients.size(); - auto skeycount = ctx.passwords.size(); - if (!pkeycount && !skeycount) { + if (ctx.recipients.empty() && ctx.passwords.empty()) { RNP_LOG("no recipients"); return RNP_ERROR_BAD_PARAMETERS; } @@ -964,7 +1011,7 @@ init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) if (!init_dst_common(&dst, 0)) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } - auto param = new (std::nothrow) pgp_dest_encrypted_param_t(); + auto param = new (std::nothrow) pgp_dest_encrypted_param_t(ctx); if (!param) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } @@ -974,12 +1021,11 @@ init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) #if defined(ENABLE_CRYPTO_REFRESH) /* in the case of PKESK (pkeycount > 0) and all keys are PKESKv6/SEIPDv2 capable, upgrade * to AEADv2 */ - if (ctx.enable_pkesk_v6 && ctx.pkeskv6_capable() && pkeycount) { + if (ctx.enable_pkesk_v6 && ctx.pkeskv6_capable() && !ctx.recipients.empty()) { param->auth_type = rnp::AuthType::AEADv2; } #endif param->aalg = ctx.aalg; - param->ctx = &ctx; param->pkt.origdst = &writedst; // the following assignment is covered for the v2 SEIPD case further below dst.write = param->is_aead_auth() ? encrypted_dst_write_aead : encrypted_dst_write_cfb; @@ -987,19 +1033,12 @@ init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) dst.close = encrypted_dst_close; dst.type = PGP_STREAM_ENCRYPTED; - rnp_result_t ret = RNP_ERROR_GENERIC; rnp::secure_bytes enckey(keylen, 0); /* content encryption key */ - bool singlepass = !pkeycount && (skeycount == 1) && !param->is_aead_auth(); - if (!singlepass) { - try { - ctx.sec_ctx.rng.get(enckey.data(), keylen); - } catch (const std::exception &e) { - /* LCOV_EXCL_START */ - ret = RNP_ERROR_RNG; - goto finish; - /* LCOV_EXCL_END */ - } + /* Build SKESK and generate CEK */ + rnp_result_t ret = RNP_ERROR_BAD_PARAMETERS; + if (!encrypted_build_skesk(*param, enckey, keylen)) { + goto finish; } /* Configuring and writing pk-encrypted session keys */ @@ -1020,12 +1059,9 @@ init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) } } - /* Configuring and writing sk-encrypted session key(s) */ - for (auto &passinfo : ctx.passwords) { - ret = encrypted_add_password(passinfo, *param, enckey, keylen, singlepass); - if (ret) { - goto finish; - } + /* Writing sk-encrypted session key(s) */ + for (auto &skesk : param->skesks) { + skesk.write(*param->pkt.origdst); } /* Initializing partial packet writer */ From 878a7af26c896db4a2ac1ac1e942e96cf5a13f43 Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Fri, 24 Jan 2025 13:54:35 +0200 Subject: [PATCH 8/9] CI: add libbz2-dev to installed Ubuntu packages --- .github/workflows/codeql.yml | 2 +- .github/workflows/coverity.yml | 2 +- .github/workflows/ubuntu.yml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cdc1c1e6e..56c35e724 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: if: ${{ matrix.language == 'cpp' }} run: | sudo apt-get update - sudo apt-get install --yes libjson-c-dev libgtest-dev + sudo apt-get install --yes libbz2-dev libjson-c-dev libgtest-dev - name: After Prepare (cpp) if: ${{ matrix.language == 'cpp' }} diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 895d3bd74..47555a093 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -18,7 +18,7 @@ jobs: - name: Install dependencies run: | sudo apt-get -y update - sudo apt-get -y install cmake libjson-c-dev libbotan-2-dev asciidoctor + sudo apt-get -y install cmake libbz2-dev libjson-c-dev libbotan-2-dev asciidoctor - name: Configure run: | diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index c9f7d9bc9..899ea0153 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -99,7 +99,7 @@ jobs: # Already installed on GHA: build-essential libbz2-dev zlib1g-dev run: | sudo apt-get -y update - sudo apt-get -y install cmake libjson-c-dev ${{ matrix.backend.package }} asciidoctor + sudo apt-get -y install cmake libbz2-dev libjson-c-dev ${{ matrix.backend.package }} asciidoctor - name: Configure run: | @@ -133,7 +133,7 @@ jobs: - name: Install dependencies run: | sudo apt-get -y update - sudo apt-get -y install cmake libjson-c-dev libbotan-2-dev asciidoctor googletest + sudo apt-get -y install cmake libbz2-dev libjson-c-dev libbotan-2-dev asciidoctor googletest - name: Configure run: | @@ -174,7 +174,7 @@ jobs: - name: Install dependencies run: | sudo apt-get -y update - sudo apt-get -y install cmake libjson-c-dev libbotan-2-dev asciidoctor googletest + sudo apt-get -y install cmake libbz2-dev libjson-c-dev libbotan-2-dev asciidoctor googletest - name: Build googletest run: | @@ -221,7 +221,7 @@ jobs: - name: Install dependencies run: | sudo apt-get -y update - sudo apt-get -y install cmake libjson-c-dev libbotan-2-dev asciidoctor + sudo apt-get -y install cmake libbz2-dev libjson-c-dev libbotan-2-dev asciidoctor - name: Checkout sexpp uses: actions/checkout@v4 @@ -286,7 +286,7 @@ jobs: - name: Install dependencies run: | sudo apt-get -y update - sudo apt-get -y install cmake libjson-c-dev libbotan-2-dev asciidoctor + sudo apt-get -y install cmake libbz2-dev libjson-c-dev libbotan-2-dev asciidoctor - name: Configure run: | @@ -323,7 +323,7 @@ jobs: - name: Install dependencies run: | sudo apt-get -y update - sudo apt-get -y install cmake libjson-c-dev libbotan-2-dev asciidoctor + sudo apt-get -y install cmake libbz2-dev libjson-c-dev libbotan-2-dev asciidoctor - name: Download source package uses: actions/download-artifact@v4 From 953375809c7c7feb78775f8faa684f0eeb510c83 Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Fri, 24 Jan 2025 14:51:11 +0200 Subject: [PATCH 9/9] Fix signedness comparison warning. --- src/librepgp/stream-packet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librepgp/stream-packet.cpp b/src/librepgp/stream-packet.cpp index 4137b5005..d4bc88fd5 100644 --- a/src/librepgp/stream-packet.cpp +++ b/src/librepgp/stream-packet.cpp @@ -1149,7 +1149,7 @@ pgp_pk_sesskey_t::parse(pgp_source_t &src) return RNP_ERROR_BAD_FORMAT; } fp.length = fp_len; - if (fp.length && (fp.length != fp_and_key_ver_len - 1)) { + if (fp.length && (fp.length + 1 != fp_and_key_ver_len)) { RNP_LOG("size mismatch (fingerprint size and fp+key version length field)"); return RNP_ERROR_BAD_FORMAT; }