gpg: Prepare for a new export option export-realclean.

* g10/options.h (EXPORT_REALCLEAN): New.  Also re-assign other values
to keep them more in sync with the corresponding import values.
* g10/export.c (parse_export_options): Add "export-realclean".
(do_export_stream): Call clean_all_uids directly with the options
arg.
* g10/import.c (import_one_real): Change for direct use of options in
clean_all_uids.
* g10/key-clean.c (is_trusted_key_sig): New.  Stub for now.
(clean_sigs_from_uid): Re-purpose self_only to a general options arg.
Implement EXPORT_REALCLEAN code path.
(clean_one_uid): Re-purpose self_only to a general options arg.
(clean_all_uids): Ditto.
* g10/keyedit.c (keyedit_menu): Use EXPORT_MINIMAL instead of a simple
flag.
(menu_clean): Re-purpose self_only to a general options arg.

* g10/keyid.c (fpr20_from_pk): Factor code out to ....
(fpr20_from_fpr): new.  Remove useless case for ARRAY being NULL.
* g10/tdbio.c (tdbio_search_trust_byfpr): Add arg fprlen and use
fpr20_from_fpr if needed.
(tdbio_search_trust_bypk): Pass 20 for the fingerprint length.
--

Note that this code has no function yet.  Another patch will follow to
extract the trusted-keys flag from the trustdb.
This commit is contained in:
Werner Koch 2024-03-04 14:22:42 +01:00
parent 233bf39323
commit 74e4dd3668
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
11 changed files with 105 additions and 46 deletions

View File

@ -129,6 +129,8 @@ parse_export_options(char *str,unsigned int *options,int noisy)
N_("export revocation keys marked as \"sensitive\"")},
{"export-clean",EXPORT_CLEAN,NULL,
N_("remove unusable parts from key during export")},
{"export-realclean",EXPORT_MINIMAL|EXPORT_REALCLEAN|EXPORT_CLEAN,NULL,
NULL},
{"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
N_("remove as much as possible from key during export")},
@ -166,7 +168,7 @@ parse_export_options(char *str,unsigned int *options,int noisy)
{
*options |= (EXPORT_LOCAL_SIGS | EXPORT_ATTRIBUTES
| EXPORT_SENSITIVE_REVKEYS);
*options &= ~(EXPORT_CLEAN | EXPORT_MINIMAL
*options &= ~(EXPORT_CLEAN | EXPORT_MINIMAL | EXPORT_REALCLEAN
| EXPORT_DANE_FORMAT);
}
@ -643,7 +645,7 @@ canon_pk_algo (enum gcry_pk_algos algo)
}
/* Take an s-expression wit the public and private key and change the
/* Take an s-expression with the public and private key and change the
* parameter array in PK to include the secret parameters. */
static gpg_error_t
secret_key_to_mode1003 (gcry_sexp_t s_key, PKT_public_key *pk)
@ -2366,8 +2368,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
if ((options & EXPORT_CLEAN))
{
merge_keys_and_selfsig (ctrl, keyblock);
clean_all_uids (ctrl, keyblock, opt.verbose,
(options&EXPORT_MINIMAL), NULL, NULL);
clean_all_uids (ctrl, keyblock, opt.verbose, options, NULL, NULL);
clean_all_subkeys (ctrl, keyblock, opt.verbose,
(options&EXPORT_MINIMAL)? KEY_CLEAN_ALL
/**/ : KEY_CLEAN_AUTHENCR,

View File

@ -2081,7 +2081,9 @@ import_one_real (ctrl_t ctrl,
{
merge_keys_and_selfsig (ctrl, keyblock);
clean_all_uids (ctrl, keyblock,
opt.verbose, (options&IMPORT_MINIMAL), NULL, NULL);
opt.verbose,
(options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0,
NULL, NULL);
clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE,
NULL, NULL);
}
@ -2233,7 +2235,8 @@ import_one_real (ctrl_t ctrl,
if ((options & IMPORT_CLEAN))
{
merge_keys_and_selfsig (ctrl, keyblock);
clean_all_uids (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
clean_all_uids (ctrl, keyblock, opt.verbose,
(options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0,
&n_uids_cleaned,&n_sigs_cleaned);
clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE,
NULL, NULL);
@ -2331,7 +2334,7 @@ import_one_real (ctrl_t ctrl,
{
merge_keys_and_selfsig (ctrl, keyblock_orig);
clean_all_uids (ctrl, keyblock_orig, opt.verbose,
(options&IMPORT_MINIMAL),
(options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0,
&n_uids_cleaned,&n_sigs_cleaned);
clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, KEY_CLEAN_NONE,
NULL, NULL);

View File

@ -91,6 +91,7 @@ mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
continue;
}
node->flag |= 1<<NF_CONSIDER;
}
/* Reset the remaining flags. */
for (; node; node = node->next)
@ -215,9 +216,22 @@ mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
}
/* Return true if the signature at NODE has is from a key specified by
* the --trusted-key option and is exportable. */
static int
is_trusted_key_sig (kbnode_t node)
{
if (!node->pkt->pkt.signature->flags.exportable)
return 0;
/* Not yet implemented. */
return 0;
}
/* Note: OPTIONS are from the EXPORT_* set. */
static int
clean_sigs_from_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
int noisy, int self_only)
int noisy, unsigned int options)
{
int deleted = 0;
kbnode_t node;
@ -256,8 +270,15 @@ clean_sigs_from_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
{
int keep;
keep = self_only? (node->pkt->pkt.signature->keyid[0] == keyid[0]
&& node->pkt->pkt.signature->keyid[1] == keyid[1]) : 1;
if ((options & EXPORT_REALCLEAN))
keep = ((node->pkt->pkt.signature->keyid[0] == keyid[0]
&& node->pkt->pkt.signature->keyid[1] == keyid[1])
|| is_trusted_key_sig (node));
else if ((options & EXPORT_MINIMAL))
keep = (node->pkt->pkt.signature->keyid[0] == keyid[0]
&& node->pkt->pkt.signature->keyid[1] == keyid[1]);
else
keep = 1;
/* Keep usable uid sigs ... */
if ((node->flag & (1<<NF_USABLE)) && keep)
@ -364,10 +385,12 @@ clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy)
}
/* Needs to be called after a merge_keys_and_selfsig() */
/* Needs to be called after a merge_keys_and_selfsig().
* Note: OPTIONS are from the EXPORT_* set. */
void
clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
int noisy, int self_only, int *uids_cleaned, int *sigs_cleaned)
int noisy, unsigned int options,
int *uids_cleaned, int *sigs_cleaned)
{
int dummy = 0;
@ -386,15 +409,15 @@ clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
*uids_cleaned += clean_uid_from_key (keyblock, uidnode, noisy);
if (!uidnode->pkt->pkt.user_id->flags.compacted)
*sigs_cleaned += clean_sigs_from_uid (ctrl, keyblock, uidnode,
noisy, self_only);
noisy, options);
}
/* NB: This function marks the deleted nodes only and the caller is
* responsible to skip or remove them. Needs to be called after a
* merge_keys_and_selfsig(). */
* merge_keys_and_selfsig. Note: OPTIONS are from the EXPORT_* set. */
void
clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, unsigned int options,
int *uids_cleaned, int *sigs_cleaned)
{
kbnode_t node;
@ -405,7 +428,7 @@ clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
node = node->next)
{
if (node->pkt->pkttype == PKT_USER_ID)
clean_one_uid (ctrl, keyblock, node, noisy, self_only,
clean_one_uid (ctrl, keyblock, node, noisy, options,
uids_cleaned, sigs_cleaned);
}

View File

@ -40,9 +40,10 @@ void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
u32 curtime, u32 *next_expire);
void clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
int noisy, int self_only,
int noisy, unsigned int options,
int *uids_cleaned, int *sigs_cleaned);
void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock,
int noisy, unsigned int options,
int *uids_cleaned,int *sigs_cleaned);
void clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock,
int noisy, int clean_level,

View File

@ -573,6 +573,7 @@ const char *colon_expirestr_from_sig (PKT_signature *sig);
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
byte *v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len);
void fpr20_from_pk (PKT_public_key *pk, byte array[20]);
void fpr20_from_fpr (const byte *fpr, unsigned int fprlen, byte array[20]);
char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen);
char *v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen);
char *format_hexfingerprint (const char *fingerprint,

View File

@ -70,7 +70,7 @@ static int menu_adduid (ctrl_t ctrl, kbnode_t keyblock,
int photo, const char *photo_name, const char *uidstr);
static void menu_deluid (KBNODE pub_keyblock);
static int menu_delsig (ctrl_t ctrl, kbnode_t pub_keyblock);
static int menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only);
static int menu_clean (ctrl_t ctrl, kbnode_t keyblock, unsigned int options);
static void menu_delkey (KBNODE pub_keyblock);
static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
static int menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock,
@ -2258,7 +2258,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
break;
case cmdMINIMIZE:
if (menu_clean (ctrl, keyblock, 1))
if (menu_clean (ctrl, keyblock, EXPORT_MINIMAL))
redisplay = modified = 1;
break;
@ -4543,11 +4543,13 @@ menu_delsig (ctrl_t ctrl, kbnode_t pub_keyblock)
}
/* Note: OPTIONS are from the EXPORT_* set. */
static int
menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only)
menu_clean (ctrl_t ctrl, kbnode_t keyblock, unsigned int options)
{
KBNODE uidnode;
int modified = 0, select_all = !count_selected_uids (keyblock);
int modified = 0;
int select_all = !count_selected_uids (keyblock);
for (uidnode = keyblock->next;
uidnode && uidnode->pkt->pkttype != PKT_PUBLIC_SUBKEY;
@ -4561,8 +4563,8 @@ menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only)
uidnode->pkt->pkt.user_id->len,
0);
clean_one_uid (ctrl, keyblock, uidnode, opt.verbose, self_only, &uids,
&sigs);
clean_one_uid (ctrl, keyblock, uidnode, opt.verbose, options,
&uids, &sigs);
if (uids)
{
const char *reason;
@ -4587,7 +4589,7 @@ menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only)
}
else
{
tty_printf (self_only == 1 ?
tty_printf ((options & EXPORT_MINIMAL)?
_("User ID \"%s\": already minimized\n") :
_("User ID \"%s\": already clean\n"), user);
}

View File

@ -1050,6 +1050,32 @@ v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
}
/*
* This is the core of fpr20_from_pk which directly takes a
* fingerprint and its length instead of the public key. See below
* for details.
*/
void
fpr20_from_fpr (const byte *fpr, unsigned int fprlen, byte array[20])
{
if (fprlen >= 32) /* v5 fingerprint (or larger) */
{
memcpy (array + 0, fpr + 20, 4);
memcpy (array + 4, fpr + 24, 4);
memcpy (array + 8, fpr + 28, 4);
memcpy (array + 12, fpr + 0, 4); /* kid[0] */
memcpy (array + 16, fpr + 4, 4); /* kid[1] */
}
else if (fprlen == 20) /* v4 fingerprint */
memcpy (array, fpr, 20);
else /* v3 or too short: fill up with zeroes. */
{
memset (array, 0, 20);
memcpy (array, fpr, fprlen);
}
}
/*
* Get FPR20 for the given PK/SK into ARRAY.
*
@ -1066,19 +1092,7 @@ fpr20_from_pk (PKT_public_key *pk, byte array[20])
if (!pk->fprlen)
compute_fingerprint (pk);
if (!array)
array = xmalloc (pk->fprlen);
if (pk->fprlen == 32) /* v5 fingerprint */
{
memcpy (array + 0, pk->fpr + 20, 4);
memcpy (array + 4, pk->fpr + 24, 4);
memcpy (array + 8, pk->fpr + 28, 4);
memcpy (array + 12, pk->fpr + 0, 4); /* kid[0] */
memcpy (array + 16, pk->fpr + 4, 4); /* kid[1] */
}
else /* v4 fingerprint */
memcpy (array, pk->fpr, 20);
fpr20_from_fpr (pk->fpr, pk->fprlen, array);
}

View File

@ -416,12 +416,13 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
#define EXPORT_ATTRIBUTES (1<<1)
#define EXPORT_SENSITIVE_REVKEYS (1<<2)
#define EXPORT_RESET_SUBKEY_PASSWD (1<<3)
#define EXPORT_MINIMAL (1<<4)
#define EXPORT_CLEAN (1<<5)
#define EXPORT_MINIMAL (1<<5)
#define EXPORT_CLEAN (1<<6)
#define EXPORT_DANE_FORMAT (1<<7)
#define EXPORT_BACKUP (1<<10)
#define EXPORT_REVOCS (1<<11)
#define EXPORT_MODE1003 (1<<12)
#define EXPORT_REALCLEAN (1<<13)
#define LIST_SHOW_PHOTOS (1<<0)
#define LIST_SHOW_POLICY_URLS (1<<1)

View File

@ -193,7 +193,11 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
while (fprlen < MAX_FINGERPRINT_LEN)
fpr[fprlen++] = 0;
rc = tdbio_search_trust_byfpr (ctrl, fpr, &rec);
/* FIXME: The intention is to save the special fpr20 as used
* in the trustdb here. However, the above conversions seems
* not to be aware of this. Or why does it allow up to
* MAX_FINGERPRINT_LEN ? */
rc = tdbio_search_trust_byfpr (ctrl, fpr, 20, &rec);
if( !rc ) { /* found: update */
if (rec.r.trust.ownertrust != otrust)
{

View File

@ -1864,13 +1864,21 @@ cmp_trec_fpr ( const void *fpr, const TRUSTREC *rec )
* Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
*/
gpg_error_t
tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint, TRUSTREC *rec)
tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fpr, unsigned int fprlen,
TRUSTREC *rec)
{
int rc;
byte fingerprint[20];
if (fprlen != 20)
{
fpr20_from_fpr (fpr, fprlen, fingerprint);
fpr = fingerprint;
}
/* Locate the trust record using the hash table */
rc = lookup_hashtable (get_trusthashrec (ctrl), fingerprint, 20,
cmp_trec_fpr, fingerprint, rec );
rc = lookup_hashtable (get_trusthashrec (ctrl), fpr, 20,
cmp_trec_fpr, fpr, rec);
return rc;
}
@ -1887,7 +1895,7 @@ tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec)
byte fingerprint[20];
fpr20_from_pk (pk, fingerprint);
return tdbio_search_trust_byfpr (ctrl, fingerprint, rec);
return tdbio_search_trust_byfpr (ctrl, fingerprint, 20, rec);
}

View File

@ -111,7 +111,8 @@ int tdbio_end_transaction(void);
int tdbio_cancel_transaction(void);
int tdbio_delete_record (ctrl_t ctrl, ulong recnum);
ulong tdbio_new_recnum (ctrl_t ctrl);
gpg_error_t tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint,
gpg_error_t tdbio_search_trust_byfpr (ctrl_t ctrl,
const byte *fpr, unsigned int fprlen,
TRUSTREC *rec);
gpg_error_t tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk,
TRUSTREC *rec);