From a479804c86bc24bfab101f39464db3ecfbaedf6d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 6 Jul 2016 14:03:50 +0200 Subject: [PATCH] gpg: New options --recipient-file and --hidden-recipient-file. * g10/gpg.c (oRecipientFile, oHiddenRecipientFile): New. (opts): Add options --recipient-file and --hidden-recipient-file. (main): Implement them. Also remove duplicate code from similar options. * g10/keydb.h (PK_LIST_FROM_FILE): New. (PK_LIST_SHIFT): Bump up. * g10/pkclist.c (expand_group): Take care of PK_LIST_FROM_FILE. (find_and_check_key): Add and implement arg FROM_FILE. (build_pk_list): Pass new value for new arg. * g10/getkey.c (get_pubkey_fromfile): New. * g10/gpgv.c (read_key_from_file): New stub. * g10/test-stubs.c (read_key_from_file): New stub. * g10/server.c (cmd_recipient): Add flag --file. * g10/import.c (read_key_from_file): New. * tests/openpgp/defs.scm (key-file1): New. (key-file2): New. * tests/openpgp/setup.scm: Add their private keys and import the key-file1. * tests/openpgp/encrypt.scm: Add new test. -- Signed-off-by: Werner Koch --- doc/gpg.texi | 21 ++++++-- g10/getkey.c | 54 ++++++++++++++++++- g10/gpg.c | 54 +++++++++++-------- g10/gpgv.c | 11 ++++ g10/import.c | 107 ++++++++++++++++++++++++++++++++++++++ g10/keydb.h | 22 +++++--- g10/main.h | 2 + g10/pkclist.c | 99 ++++++++++++++++++++--------------- g10/server.c | 6 ++- g10/test-stubs.c | 9 ++++ tests/openpgp/defs.scm | 3 ++ tests/openpgp/encrypt.scm | 15 ++++++ tests/openpgp/setup.scm | 9 +++- 13 files changed, 330 insertions(+), 82 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 9a60890b1..11d3a65f2 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2037,6 +2037,22 @@ limited countermeasure against traffic analysis. If this option or @option{--recipient} is not specified, GnuPG asks for the user ID unless @option{--default-recipient} is given. +@item --recipient-file @var{file} +@itemx -f +@opindex recipient-file +This option is similar to @option{--recipient} except that it +encrypts to a key stored in the given file. @var{file} must be the +name of a file containing exactly one key. @command{gpg} assumes that +the key in this file is fully valid. + +@item --hidden-recipient-file @var{file} +@itemx -F +@opindex hidden-recipient-file +This option is similar to @option{--hidden-recipient} except that it +encrypts to a key stored in the given file. @var{file} must be the +name of a file containing exactly one key. @command{gpg} assumes that +the key in this file is fully valid. + @item --encrypt-to @code{name} @opindex encrypt-to Same as @option{--recipient} but this one is intended for use in the @@ -2055,11 +2071,6 @@ recipients given either by use of @option{--recipient} or by the asked user id. No trust checking is performed for these user ids and even disabled keys can be used. -@item --encrypt-to-default-key -@opindex encrypt-to-default-key -If the default secret key is taken from @option{--default-key}, then -also encrypt to that key. - @item --no-encrypt-to @opindex no-encrypt-to Disable the use of all @option{--encrypt-to} and diff --git a/g10/getkey.c b/g10/getkey.c index f34127de5..90fd175b4 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1,7 +1,7 @@ /* getkey.c - Get a key from the database * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, * 2007, 2008, 2010 Free Software Foundation, Inc. - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015, 2016 g10 Code GmbH * * This file is part of GnuPG. * @@ -143,6 +143,11 @@ static void merge_selfsigs (kbnode_t keyblock); static int lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key, int want_secret); +static kbnode_t finish_lookup (kbnode_t keyblock, + unsigned int req_usage, int want_exact, + unsigned int *r_flags); +static void print_status_key_considered (kbnode_t keyblock, unsigned int flags); + #if 0 static void @@ -1454,6 +1459,53 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk, } +/* Get a public key from a file. + * + * PK is the buffer to store the key. The caller needs to make sure + * that PK->REQ_USAGE is valid. PK->REQ_USAGE is passed through to + * the lookup function and is a mask of PUBKEY_USAGE_SIG, + * PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. If this is non-zero, only + * keys with the specified usage will be returned. + * + * FNAME is the file name. That file should contain exactly one + * keyblock. + * + * This function returns 0 on success. Otherwise, an error code is + * returned. In particular, GPG_ERR_NO_PUBKEY is returned if the key + * is not found. + * + * The self-signed data has already been merged into the public key + * using merge_selfsigs. The caller must release the content of PK by + * calling release_public_key_parts (or, if PK was malloced, using + * free_public_key). + */ +gpg_error_t +get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname) +{ + gpg_error_t err; + kbnode_t keyblock; + kbnode_t found_key; + unsigned int infoflags; + + err = read_key_from_file (ctrl, fname, &keyblock); + if (!err) + { + /* Warning: node flag bits 0 and 1 should be preserved by + * merge_selfsigs. FIXME: Check whether this still holds. */ + merge_selfsigs (keyblock); + found_key = finish_lookup (keyblock, pk->req_usage, 0, &infoflags); + print_status_key_considered (keyblock, infoflags); + if (found_key) + pk_from_block (pk, keyblock, found_key); + else + err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); + } + + release_kbnode (keyblock); + return err; +} + + /* Lookup a key with the specified fingerprint. * * If PK is not NULL, the public key of the first result is returned diff --git a/g10/gpg.c b/g10/gpg.c index cf0e64505..34009bb3a 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -81,6 +81,8 @@ enum cmd_and_opt_values aSym = 'c', aDecrypt = 'd', aEncr = 'e', + oRecipientFile = 'f', + oHiddenRecipientFile = 'F', oInteractive = 'i', aListKeys = 'k', oDryRun = 'n', @@ -506,6 +508,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")), ARGPARSE_s_s (oHiddenRecipient, "hidden-recipient", "@"), + ARGPARSE_s_s (oRecipientFile, "recipient-file", "@"), + ARGPARSE_s_s (oHiddenRecipientFile, "hidden-recipient-file", "@"), ARGPARSE_s_s (oRecipient, "remote-user", "@"), /* (old option name) */ ARGPARSE_s_s (oDefRecipient, "default-recipient", "@"), ARGPARSE_s_n (oDefRecipientSelf, "default-recipient-self", "@"), @@ -2838,38 +2842,46 @@ main (int argc, char **argv) else opt.s2k_count = 0; /* Auto-calibrate when needed. */ break; - case oNoEncryptTo: opt.no_encrypt_to = 1; break; - case oEncryptTo: /* store the recipient in the second list */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO); - if (configfp) - sl->flags |= PK_LIST_CONFIG; - break; - case oHiddenEncryptTo: /* store the recipient in the second list */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) - | PK_LIST_ENCRYPT_TO|PK_LIST_HIDDEN); - if (configfp) - sl->flags |= PK_LIST_CONFIG; - break; - case oEncryptToDefaultKey: - opt.encrypt_to_default_key = configfp ? 2 : 1; - break; - case oRecipient: /* store the recipient */ + + case oRecipient: + case oHiddenRecipient: + case oRecipientFile: + case oHiddenRecipientFile: + /* Store the recipient. Note that we also store the + * option as private data in the flags. This is achieved + * by shifting the option value to the left so to keep + * enough space for the flags. */ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); sl->flags = (pargs.r_opt << PK_LIST_SHIFT); if (configfp) sl->flags |= PK_LIST_CONFIG; + if (pargs.r_opt == oHiddenRecipient + || pargs.r_opt == oHiddenRecipientFile) + sl->flags |= PK_LIST_HIDDEN; + if (pargs.r_opt == oRecipientFile + || pargs.r_opt == oHiddenRecipientFile) + sl->flags |= PK_LIST_FROM_FILE; any_explicit_recipient = 1; break; - case oHiddenRecipient: /* store the recipient with a flag */ + + case oEncryptTo: + case oHiddenEncryptTo: + /* Store an additional recipient. */ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_HIDDEN); + sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO); if (configfp) sl->flags |= PK_LIST_CONFIG; - any_explicit_recipient = 1; + if (pargs.r_opt == oHiddenEncryptTo) + sl->flags |= PK_LIST_HIDDEN; break; + case oNoEncryptTo: + opt.no_encrypt_to = 1; + break; + case oEncryptToDefaultKey: + opt.encrypt_to_default_key = configfp ? 2 : 1; + break; + case oTrySecretKey: add_to_strlist2 (&opt.secret_keys_to_try, pargs.r.ret_str, utf8_strings); diff --git a/g10/gpgv.c b/g10/gpgv.c index 9ccc0da99..d238ee06f 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -416,6 +416,17 @@ keyserver_import_ldap (const char *name) return -1; } + +gpg_error_t +read_key_from_file (ctrl_t ctrl, const char *fname, kbnode_t *r_keyblock) +{ + (void)ctrl; + (void)fname; + (void)r_keyblock; + return -1; +} + + /* Stub: * No encryption here but mainproc links to these functions. */ diff --git a/g10/import.c b/g10/import.c index 8cfd6eae0..e03532834 100644 --- a/g10/import.c +++ b/g10/import.c @@ -220,6 +220,113 @@ import_release_stats_handle (import_stats_t p) } +/* Read a key from a file. Only the first key in the file is + * considered and stored at R_KEYBLOCK. FNAME is the name of the + * file. + */ +gpg_error_t +read_key_from_file (ctrl_t ctrl, const char *fname, kbnode_t *r_keyblock) +{ + gpg_error_t err; + iobuf_t inp; + PACKET *pending_pkt = NULL; + kbnode_t keyblock = NULL; + u32 keyid[2]; + int v3keys; /* Dummy */ + int non_self; /* Dummy */ + + (void)ctrl; + + *r_keyblock = NULL; + + inp = iobuf_open (fname); + if (!inp) + err = gpg_error_from_syserror (); + else if (is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + err = gpg_error (GPG_ERR_EPERM); + } + else + err = 0; + if (err) + { + log_error (_("can't open '%s': %s\n"), + iobuf_is_pipe_filename (fname)? "[stdin]": fname, + gpg_strerror (err)); + if (gpg_err_code (err) == GPG_ERR_ENOENT) + err = gpg_error (GPG_ERR_NO_PUBKEY); + goto leave; + } + + /* Push the armor filter. */ + { + armor_filter_context_t *afx; + afx = new_armor_context (); + afx->only_keyblocks = 1; + push_armor_filter (afx, inp); + release_armor_context (afx); + } + + /* Read the first non-v3 keyblock. */ + while (!(err = read_block (inp, &pending_pkt, &keyblock, &v3keys))) + { + if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) + break; + log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype); + release_kbnode (keyblock); + keyblock = NULL; + } + if (err) + { + if (gpg_err_code (err) != GPG_ERR_INV_KEYRING) + log_error (_("error reading '%s': %s\n"), + iobuf_is_pipe_filename (fname)? "[stdin]": fname, + gpg_strerror (err)); + goto leave; + } + + keyid_from_pk (keyblock->pkt->pkt.public_key, keyid); + + if (!find_next_kbnode (keyblock, PKT_USER_ID)) + { + err = gpg_error (GPG_ERR_NO_USER_ID); + goto leave; + } + + collapse_uids (&keyblock); + + clear_kbnode_flags (keyblock); + if (chk_self_sigs (keyblock, keyid, &non_self)) + { + err = gpg_error (GPG_ERR_INV_KEYRING); + goto leave; + } + + if (!delete_inv_parts (keyblock, keyid, 0) ) + { + err = gpg_error (GPG_ERR_NO_USER_ID); + goto leave; + } + + *r_keyblock = keyblock; + keyblock = NULL; + + leave: + if (inp) + { + iobuf_close (inp); + /* Must invalidate that ugly cache to actually close the file. */ + iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname); + } + release_kbnode (keyblock); + /* FIXME: Do we need to free PENDING_PKT ? */ + return err; +} + + + /* * Import the public keys from the given filename. Input may be armored. * This function rejects all keys which are not validly self signed on at diff --git a/g10/keydb.h b/g10/keydb.h index a30cf7ac7..4e8f3f291 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -70,15 +70,16 @@ enum resource_type { /* Bit flags used with build_pk_list. */ enum { - PK_LIST_ENCRYPT_TO=1, /* This is an encrypt-to recipient. */ - PK_LIST_HIDDEN=2, /* This is a hidden recipient. */ - PK_LIST_CONFIG=4 /* Specified via config file. */ + PK_LIST_ENCRYPT_TO = 1, /* This is an encrypt-to recipient. */ + PK_LIST_HIDDEN = 2, /* This is a hidden recipient. */ + PK_LIST_CONFIG = 4, /* Specified via config file. */ + PK_LIST_FROM_FILE = 8 /* Take key from file with that name. */ }; -/* To store private data in the flags they must be left shifted by - this value. */ +/* To store private data in the flags the private data must be left + shifted by this value. */ enum { - PK_LIST_SHIFT=3 + PK_LIST_SHIFT = 4 }; /**************** @@ -104,7 +105,7 @@ struct pk_list { PK_LIST next; PKT_public_key *pk; - int flags; /* flag bit 1==throw_keyid */ + int flags; /* See PK_LIST_ constants. */ }; /* Structure to hold a list of secret key certificates. */ @@ -228,7 +229,8 @@ void release_pk_list (PK_LIST pk_list); int build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list); gpg_error_t find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, - int mark_hidden, pk_list_t *pk_list_addr); + int mark_hidden, int from_file, + pk_list_t *pk_list_addr); int algo_available( preftype_t preftype, int algo, const union pref_hint *hint ); @@ -322,6 +324,10 @@ int get_pubkey_byname (ctrl_t ctrl, KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd, int include_unusable, int no_akl ); +/* Get a public key directly from file FNAME. */ +gpg_error_t get_pubkey_fromfile (ctrl_t ctrl, + PKT_public_key *pk, const char *fname); + /* Return the public key with the key id KEYID iff the secret key is * available and store it at PK. */ gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid); diff --git a/g10/main.h b/g10/main.h index 3ee276202..ec20b28df 100644 --- a/g10/main.h +++ b/g10/main.h @@ -350,6 +350,8 @@ typedef gpg_error_t (*import_screener_t)(kbnode_t keyblock, void *arg); int parse_import_options(char *str,unsigned int *options,int noisy); gpg_error_t parse_and_set_import_filter (const char *string); +gpg_error_t read_key_from_file (ctrl_t ctrl, const char *fname, + kbnode_t *r_keyblock); void import_keys (ctrl_t ctrl, char **fnames, int nnames, import_stats_t stats_hd, unsigned int options); int import_keys_stream (ctrl_t ctrl, iobuf_t inp, import_stats_t stats_hd, diff --git a/g10/pkclist.c b/g10/pkclist.c index 8efa95432..6315a6d55 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -775,14 +775,16 @@ expand_id(const char *id,strlist_t *into,unsigned int flags) } /* For simplicity, and to avoid potential loops, we only expand once - - you can't make an alias that points to an alias. */ + * you can't make an alias that points to an alias. */ static strlist_t -expand_group(strlist_t input) +expand_group (strlist_t input) { - strlist_t sl,output=NULL,rover; + strlist_t output = NULL; + strlist_t sl, rover; - for(rover=input;rover;rover=rover->next) - if(expand_id(rover->d,&output,rover->flags)==0) + for (rover = input; rover; rover = rover->next) + if (!(rover->flags & PK_LIST_FROM_FILE) + && !expand_id(rover->d,&output,rover->flags)) { /* Didn't find any groups, so use the existing string */ sl=add_to_strlist(&output,rover->d); @@ -794,17 +796,18 @@ expand_group(strlist_t input) /* Helper for build_pk_list to find and check one key. This helper is - also used directly in server mode by the RECIPIENTS command. On - success the new key is added to PK_LIST_ADDR. NAME is the user id - of the key. USE the requested usage and a set MARK_HIDDEN will mark - the key in the updated list as a hidden recipient. */ + * also used directly in server mode by the RECIPIENTS command. On + * success the new key is added to PK_LIST_ADDR. NAME is the user id + * of the key. USE the requested usage and a set MARK_HIDDEN will + * mark the key in the updated list as a hidden recipient. If + * FROM_FILE is true, NAME is is not a user ID but the name of a file + * holding a key. */ gpg_error_t find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, - int mark_hidden, pk_list_t *pk_list_addr) + int mark_hidden, int from_file, pk_list_t *pk_list_addr) { int rc; PKT_public_key *pk; - int trustlevel; if (!name || !*name) return gpg_error (GPG_ERR_INV_USER_ID); @@ -814,7 +817,10 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, return gpg_error_from_syserror (); pk->req_usage = use; - rc = get_pubkey_byname (ctrl, NULL, pk, name, NULL, NULL, 0, 0); + if (from_file) + rc = get_pubkey_fromfile (ctrl, pk, name); + else + rc = get_pubkey_byname (ctrl, NULL, pk, name, NULL, NULL, 0, 0); if (rc) { int code; @@ -844,24 +850,28 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, } /* Key found and usable. Check validity. */ - trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1); - if ( (trustlevel & TRUST_FLAG_DISABLED) ) + if (!from_file) { - /* Key has been disabled. */ - send_status_inv_recp (13, name); - log_info (_("%s: skipped: public key is disabled\n"), name); - free_public_key (pk); - return GPG_ERR_UNUSABLE_PUBKEY; - } + int trustlevel; - if ( !do_we_trust_pre (pk, trustlevel) ) - { - /* We don't trust this key. */ - send_status_inv_recp (10, name); - free_public_key (pk); - return GPG_ERR_UNUSABLE_PUBKEY; + trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1); + if ( (trustlevel & TRUST_FLAG_DISABLED) ) + { + /* Key has been disabled. */ + send_status_inv_recp (13, name); + log_info (_("%s: skipped: public key is disabled\n"), name); + free_public_key (pk); + return GPG_ERR_UNUSABLE_PUBKEY; + } + + if ( !do_we_trust_pre (pk, trustlevel) ) + { + /* We don't trust this key. */ + send_status_inv_recp (10, name); + free_public_key (pk); + return GPG_ERR_UNUSABLE_PUBKEY; + } } - /* Note: do_we_trust may have changed the trustlevel. */ /* Skip the actual key if the key is already present in the list. */ @@ -894,22 +904,24 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, /* This is the central function to collect the keys for recipients. - It is thus used to prepare a public key encryption. encrypt-to - keys, default keys and the keys for the actual recipients are all - collected here. When not in batch mode and no recipient has been - passed on the commandline, the function will also ask for - recipients. - - RCPTS is a string list with the recipients; NULL is an allowed - value but not very useful. Group expansion is done on these names; - they may be in any of the user Id formats we can handle. The flags - bits for each string in the string list are used for: - Bit 0 (PK_LIST_ENCRYPT_TO): This is an encrypt-to recipient. - Bit 1 (PK_LIST_HIDDEN) : This is a hidden recipient. - - On success a list of keys is stored at the address RET_PK_LIST; the - caller must free this list. On error the value at this address is - not changed. + * It is thus used to prepare a public key encryption. encrypt-to + * keys, default keys and the keys for the actual recipients are all + * collected here. When not in batch mode and no recipient has been + * passed on the commandline, the function will also ask for + * recipients. + * + * RCPTS is a string list with the recipients; NULL is an allowed + * value but not very useful. Group expansion is done on these names; + * they may be in any of the user Id formats we can handle. The flags + * bits for each string in the string list are used for: + * + * - PK_LIST_ENCRYPT_TO :: This is an encrypt-to recipient. + * - PK_LIST_HIDDEN :: This is a hidden recipient. + * - PK_LIST_FROM_FILE :: The argument is a file with a key. + * + * On success a list of keys is stored at the address RET_PK_LIST; the + * caller must free this list. On error the value at this address is + * not changed. */ int build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list) @@ -1269,6 +1281,7 @@ build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list) rc = find_and_check_key (ctrl, remusr->d, PUBKEY_USAGE_ENC, !!(remusr->flags&PK_LIST_HIDDEN), + !!(remusr->flags&PK_LIST_FROM_FILE), &pk_list); if (rc) goto fail; diff --git a/g10/server.c b/g10/server.c index 771a8a7a9..258f08a5d 100644 --- a/g10/server.c +++ b/g10/server.c @@ -177,6 +177,7 @@ output_notify (assuan_context_t ctx, char *line) /* RECIPIENT [--hidden] + RECIPIENT [--hidden] --file Set the recipient for the encryption. should be the internal representation of the key; the server may accept any other @@ -192,9 +193,10 @@ cmd_recipient (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; - int hidden; + int hidden, file; hidden = has_option (line,"--hidden"); + file = has_option (line,"--file"); line = skip_options (line); /* FIXME: Expand groups @@ -204,7 +206,7 @@ cmd_recipient (assuan_context_t ctx, char *line) remusr = rcpts; */ - err = find_and_check_key (ctrl, line, PUBKEY_USAGE_ENC, hidden, + err = find_and_check_key (ctrl, line, PUBKEY_USAGE_ENC, hidden, file, &ctrl->server_local->recplist); if (err) diff --git a/g10/test-stubs.c b/g10/test-stubs.c index f4d952665..6f50759d5 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -228,6 +228,15 @@ keyserver_import_ldap (const char *name) return -1; } +gpg_error_t +read_key_from_file (ctrl_t ctrl, const char *fname, kbnode_t *r_keyblock) +{ + (void)ctrl; + (void)fname; + (void)r_keyblock; + return -1; +} + /* Stub: * No encryption here but mainproc links to these functions. */ diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index 4257b286e..8ceffc815 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -35,6 +35,9 @@ ;; first and then search for the encryption subkey.) (define dsa-usrname2 "0xCB879DE9") +(define key-file1 "samplekeys/rsa-rsa-sample-1.asc") +(define key-file2 "samplekeys/ed25519-cv25519-sample-1.asc") + (define plain-files '("plain-1" "plain-2" "plain-3")) (define data-files '("data-500" "data-9000" "data-32000" "data-80000")) (define exp-files '()) diff --git a/tests/openpgp/encrypt.scm b/tests/openpgp/encrypt.scm index 5a3e1788c..7452fc5b5 100755 --- a/tests/openpgp/encrypt.scm +++ b/tests/openpgp/encrypt.scm @@ -43,3 +43,18 @@ (tr:assert-identity source))) (append plain-files data-files))) all-cipher-algos) + + +;; We encrypt to two keys and we have also put the first key into our +;; pubring, so that decryption will work. +(for-each-p + "Checking encryption using a key from file" + (lambda (source) + (tr:do + (tr:open source) + (tr:gpg "" `(--yes -v --no-keyring --encrypt + --recipient-file ,(in-srcdir key-file1) + --hidden-recipient-file ,(in-srcdir key-file2))) + (tr:gpg "" '(--yes)) + (tr:assert-identity source))) + plain-files) diff --git a/tests/openpgp/setup.scm b/tests/openpgp/setup.scm index ce2e42c44..9ad19c284 100755 --- a/tests/openpgp/setup.scm +++ b/tests/openpgp/setup.scm @@ -91,12 +91,17 @@ "1DF48228FEFF3EC2481B106E0ACA8C465C662CC5" "A2832820DC9F40751BDCD375BB0945BA33EC6B4C" "ADE710D74409777B7729A7653373D820F67892E0" - "CEFC51AF91F68A2904FBFF62C4F075A4785B803F")) + "CEFC51AF91F68A2904FBFF62C4F075A4785B803F" + "1E28F20E41B54C2D1234D896096495FF57E08D18" + "EB33B687EB8581AB64D04852A54453E85F3DF62D" + "C6A6390E9388CDBAD71EAEA698233FE5E04F001E" + "D69102E0F5AC6B6DB8E4D16DA8E18CF46D88CAE3")) (info "Importing public demo and test keys") (call-check `(,@GPG --yes --import ,(in-srcdir "pubdemo.asc") - ,(in-srcdir "pubring.asc"))) + ,(in-srcdir "pubring.asc") + ,(in-srcdir key-file1))) ;; (letfd ((source (open (in-srcdir "pubring.pkr.asc") O_RDONLY))) ;; ((gpg-pipe '(--dearmor) '(--yes --import) STDERR_FILENO) ;; source CLOSED_FD))