diff --git a/g10/free-packet.c b/g10/free-packet.c index a80bc7b04..0962af0fc 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -52,18 +52,50 @@ free_symkey_enc( PKT_symkey_enc *enc ) xfree(enc); } +/* This is the core of free_pubkey_enc but does only release the + * allocated members of ENC. */ void -free_pubkey_enc( PKT_pubkey_enc *enc ) +release_pubkey_enc_parts (PKT_pubkey_enc *enc) { - int n, i; - n = pubkey_get_nenc( enc->pubkey_algo ); - if( !n ) - mpi_release(enc->data[0]); - for(i=0; i < n; i++ ) - mpi_release( enc->data[i] ); - xfree(enc); + int n, i; + n = pubkey_get_nenc( enc->pubkey_algo ); + if (!n) + mpi_release (enc->data[0]); + for (i=0; i < n; i++ ) + mpi_release (enc->data[i]); } +void +free_pubkey_enc (PKT_pubkey_enc *enc) +{ + release_pubkey_enc_parts (enc); + xfree (enc); +} + + +/* Copy everything from SRC to DST. This assumes that DST has been + * malloced or statically allocated. */ +void +copy_pubkey_enc_parts (PKT_pubkey_enc *dst, PKT_pubkey_enc *src) +{ + int n, i; + + dst->keyid[0] = src->keyid[0]; + dst->keyid[1] = src->keyid[1]; + dst->version = src->version; + dst->pubkey_algo = src->pubkey_algo; + dst->seskey_algo = src->seskey_algo; + dst->throw_keyid = src->throw_keyid; + + if (!(n = pubkey_get_nenc (dst->pubkey_algo))) + n = 1; /* All data is in the first item as an opaque MPI. */ + for (i=0; i < n; i++) + dst->data[i] = my_mpi_copy (src->data[i]); + for (; i < PUBKEY_MAX_NENC; i++) + dst->data[i] = NULL; +} + + void free_seckey_enc( PKT_signature *sig ) { diff --git a/g10/mainproc.c b/g10/mainproc.c index 42d341d0c..3bb46b574 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1,7 +1,7 @@ /* mainproc.c - handle packets * Copyright (C) 1998-2009 Free Software Foundation, Inc. * Copyright (C) 2013-2014 Werner Koch - * Copyright (C) 2020 g10 Code GmbH + * Copyright (C) 2020, 2024 g10 Code GmbH * * This file is part of GnuPG. * @@ -141,10 +141,7 @@ release_list( CTX c ) { struct pubkey_enc_list *tmp = c->pkenc_list->next; - mpi_release (c->pkenc_list->data[0]); - mpi_release (c->pkenc_list->data[1]); - mpi_release (c->pkenc_list->data[2]); - mpi_release (c->pkenc_list->data[3]); + release_pubkey_enc_parts (&c->pkenc_list->d); xfree (c->pkenc_list); c->pkenc_list = tmp; } @@ -523,21 +520,10 @@ proc_pubkey_enc (CTX c, PACKET *pkt) if (!opt.list_only && !opt.override_session_key) { - struct pubkey_enc_list *x = xmalloc (sizeof *x); + struct pubkey_enc_list *x = xcalloc (1, sizeof *x); - x->keyid[0] = enc->keyid[0]; - x->keyid[1] = enc->keyid[1]; - x->pubkey_algo = enc->pubkey_algo; + copy_pubkey_enc_parts (&x->d, enc); x->result = -1; - x->seskey_algo = enc->seskey_algo; - x->data[0] = x->data[1] = x->data[2] = x->data[3] = NULL; - if (enc->data[0]) - { - x->data[0] = mpi_copy (enc->data[0]); - x->data[1] = mpi_copy (enc->data[1]); - x->data[2] = mpi_copy (enc->data[2]); - x->data[3] = mpi_copy (enc->data[3]); - } x->next = c->pkenc_list; c->pkenc_list = x; } @@ -561,22 +547,22 @@ print_pkenc_list (ctrl_t ctrl, struct pubkey_enc_list *list) pk = xmalloc_clear (sizeof *pk); - pk->pubkey_algo = list->pubkey_algo; - if (!get_pubkey (ctrl, pk, list->keyid)) + pk->pubkey_algo = list->d.pubkey_algo; + if (!get_pubkey (ctrl, pk, list->d.keyid)) { pubkey_string (pk, pkstrbuf, sizeof pkstrbuf); log_info (_("encrypted with %s key, ID %s, created %s\n"), pkstrbuf, keystr_from_pk (pk), strtimestamp (pk->timestamp)); - p = get_user_id_native (ctrl, list->keyid); + p = get_user_id_native (ctrl, list->d.keyid); log_printf (_(" \"%s\"\n"), p); xfree (p); } else log_info (_("encrypted with %s key, ID %s\n"), - openpgp_pk_algo_name (list->pubkey_algo), - keystr(list->keyid)); + openpgp_pk_algo_name (list->d.pubkey_algo), + keystr (list->d.keyid)); if (opt.flags.require_pqc_encryption && pk->pubkey_algo != PUBKEY_ALGO_KYBER) @@ -644,7 +630,7 @@ proc_encrypted (CTX c, PACKET *pkt) { /* Key was not tried or it caused an error. */ char buf[20]; snprintf (buf, sizeof buf, "%08lX%08lX", - (ulong)list->keyid[0], (ulong)list->keyid[1]); + (ulong)list->d.keyid[0], (ulong)list->d.keyid[1]); write_status_text (STATUS_NO_SECKEY, buf); } } @@ -768,8 +754,8 @@ proc_encrypted (CTX c, PACKET *pkt) for (i = c->pkenc_list; i && compliant; i = i->next) { memset (pk, 0, sizeof *pk); - pk->pubkey_algo = i->pubkey_algo; - if (!get_pubkey (c->ctrl, pk, i->keyid) + pk->pubkey_algo = i->d.pubkey_algo; + if (!get_pubkey (c->ctrl, pk, i->d.keyid) && !gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, 0, pk->pkey, nbits_from_pk (pk), NULL)) compliant = 0; diff --git a/g10/packet.h b/g10/packet.h index 6c3e1b80d..80238fcea 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -159,11 +159,8 @@ typedef struct { struct pubkey_enc_list { struct pubkey_enc_list *next; - u32 keyid[2]; - int pubkey_algo; - int seskey_algo; int result; - gcry_mpi_t data[PUBKEY_MAX_NENC]; + PKT_pubkey_enc d; }; @@ -895,19 +892,28 @@ void free_notation (struct notation *notation); /*-- free-packet.c --*/ void free_symkey_enc( PKT_symkey_enc *enc ); + +void release_pubkey_enc_parts (PKT_pubkey_enc *enc); void free_pubkey_enc( PKT_pubkey_enc *enc ); +void copy_pubkey_enc_parts (PKT_pubkey_enc *dst, PKT_pubkey_enc *src); + void free_seckey_enc( PKT_signature *enc ); + void release_public_key_parts( PKT_public_key *pk ); void free_public_key( PKT_public_key *key ); + void free_attributes(PKT_user_id *uid); void free_user_id( PKT_user_id *uid ); void free_comment( PKT_comment *rem ); void free_packet (PACKET *pkt, parse_packet_ctx_t parsectx); prefitem_t *copy_prefs (const prefitem_t *prefs); + PKT_public_key *copy_public_key_basics (PKT_public_key *d, PKT_public_key *s); PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s ); + PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s ); PKT_user_id *scopy_user_id (PKT_user_id *sd ); + int cmp_public_keys( PKT_public_key *a, PKT_public_key *b ); int cmp_signatures( PKT_signature *a, PKT_signature *b ); int cmp_user_ids( PKT_user_id *a, PKT_user_id *b ); diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index dced3dfb0..a83d97495 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -115,23 +115,23 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek) */ for (k = list; k; k = k->next) { - if (!(k->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E - || k->pubkey_algo == PUBKEY_ALGO_ECDH - || k->pubkey_algo == PUBKEY_ALGO_KYBER - || k->pubkey_algo == PUBKEY_ALGO_RSA - || k->pubkey_algo == PUBKEY_ALGO_RSA_E - || k->pubkey_algo == PUBKEY_ALGO_ELGAMAL)) + if (!(k->d.pubkey_algo == PUBKEY_ALGO_ELGAMAL_E + || k->d.pubkey_algo == PUBKEY_ALGO_ECDH + || k->d.pubkey_algo == PUBKEY_ALGO_KYBER + || k->d.pubkey_algo == PUBKEY_ALGO_RSA + || k->d.pubkey_algo == PUBKEY_ALGO_RSA_E + || k->d.pubkey_algo == PUBKEY_ALGO_ELGAMAL)) continue; - if (openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC)) + if (openpgp_pk_test_algo2 (k->d.pubkey_algo, PUBKEY_USAGE_ENC)) continue; - if (sk->pubkey_algo != k->pubkey_algo) + if (sk->pubkey_algo != k->d.pubkey_algo) continue; keyid_from_pk (sk, keyid); - if (!k->keyid[0] && !k->keyid[1]) + if (!k->d.keyid[0] && !k->d.keyid[1]) { if (opt.skip_hidden_recipients) continue; @@ -141,7 +141,7 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek) keystr (keyid)); } else if (opt.try_all_secrets - || (k->keyid[0] == keyid[0] && k->keyid[1] == keyid[1])) + || (k->d.keyid[0] == keyid[0] && k->d.keyid[1] == keyid[1])) { if (!opt.quiet && !(sk->pubkey_usage & PUBKEY_USAGE_XENC_MASK)) log_info (_("used key is not marked for encryption use.\n")); @@ -153,7 +153,7 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek) k->result = err; if (!err) { - if (!opt.quiet && !k->keyid[0] && !k->keyid[1]) + if (!opt.quiet && !k->d.keyid[0] && !k->d.keyid[1]) { log_info (_("okay, we are the anonymous recipient.\n")); if (!(sk->pubkey_usage & PUBKEY_USAGE_XENC_MASK)) @@ -215,28 +215,28 @@ get_it (ctrl_t ctrl, if (sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL || sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E) { - if (!enc->data[0] || !enc->data[1]) + if (!enc->d.data[0] || !enc->d.data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", - enc->data[0], enc->data[1]); + enc->d.data[0], enc->d.data[1]); } else if (sk->pubkey_algo == PUBKEY_ALGO_RSA || sk->pubkey_algo == PUBKEY_ALGO_RSA_E) { - if (!enc->data[0]) + if (!enc->d.data[0]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", - enc->data[0]); + enc->d.data[0]); } else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) { - if (!enc->data[0] || !enc->data[1]) + if (!enc->d.data[0] || !enc->d.data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))", - enc->data[1], enc->data[0]); + enc->d.data[1], enc->d.data[0]); } else if (sk->pubkey_algo == PUBKEY_ALGO_KYBER) { @@ -251,18 +251,18 @@ get_it (ctrl_t ctrl, } else { - fixedinfo[0] = enc->seskey_algo; + fixedinfo[0] = enc->d.seskey_algo; v5_fingerprint_from_pk (sk, fixedinfo+1, NULL); fixedlen = 33; } - if (!enc->data[0] || !enc->data[1] || !enc->data[2]) + if (!enc->d.data[0] || !enc->d.data[1] || !enc->d.data[2]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, "(enc-val(pqc(e%m)(k%m)(s%m)(c%d)(fixed-info%b)))", - enc->data[0], enc->data[1], enc->data[2], - enc->seskey_algo, fixedlen, fixedinfo); + enc->d.data[0], enc->d.data[1], enc->d.data[2], + enc->d.seskey_algo, fixedlen, fixedinfo); } else err = gpg_error (GPG_ERR_BUG); @@ -316,15 +316,17 @@ get_it (ctrl_t ctrl, goto leave; } dek->keylen = nframe; - dek->algo = enc->seskey_algo; + dek->algo = enc->d.seskey_algo; } else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) { gcry_mpi_t decoded; /* At the beginning the frame are the bytes of shared point MPI. */ - err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, - frame, nframe, sk->pkey); + err = pk_ecdh_decrypt (&decoded, fp, + enc->d.data[1], /*encr data as an MPI*/ + frame, nframe, + sk->pkey); if(err) goto leave;