mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
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 <wk@gnupg.org>
This commit is contained in:
parent
073be51a86
commit
a479804c86
21
doc/gpg.texi
21
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{--recipient} is not specified, GnuPG asks for the user ID unless
|
||||||
@option{--default-recipient} is given.
|
@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}
|
@item --encrypt-to @code{name}
|
||||||
@opindex encrypt-to
|
@opindex encrypt-to
|
||||||
Same as @option{--recipient} but this one is intended for use in the
|
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
|
No trust checking is performed for these user ids and even disabled
|
||||||
keys can be used.
|
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
|
@item --no-encrypt-to
|
||||||
@opindex no-encrypt-to
|
@opindex no-encrypt-to
|
||||||
Disable the use of all @option{--encrypt-to} and
|
Disable the use of all @option{--encrypt-to} and
|
||||||
|
54
g10/getkey.c
54
g10/getkey.c
@ -1,7 +1,7 @@
|
|||||||
/* getkey.c - Get a key from the database
|
/* getkey.c - Get a key from the database
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
* 2007, 2008, 2010 Free Software Foundation, Inc.
|
* 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.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -143,6 +143,11 @@ static void merge_selfsigs (kbnode_t keyblock);
|
|||||||
static int lookup (getkey_ctx_t ctx,
|
static int lookup (getkey_ctx_t ctx,
|
||||||
kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
|
kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
|
||||||
int want_secret);
|
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
|
#if 0
|
||||||
static void
|
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.
|
/* Lookup a key with the specified fingerprint.
|
||||||
*
|
*
|
||||||
* If PK is not NULL, the public key of the first result is returned
|
* If PK is not NULL, the public key of the first result is returned
|
||||||
|
54
g10/gpg.c
54
g10/gpg.c
@ -81,6 +81,8 @@ enum cmd_and_opt_values
|
|||||||
aSym = 'c',
|
aSym = 'c',
|
||||||
aDecrypt = 'd',
|
aDecrypt = 'd',
|
||||||
aEncr = 'e',
|
aEncr = 'e',
|
||||||
|
oRecipientFile = 'f',
|
||||||
|
oHiddenRecipientFile = 'F',
|
||||||
oInteractive = 'i',
|
oInteractive = 'i',
|
||||||
aListKeys = 'k',
|
aListKeys = 'k',
|
||||||
oDryRun = 'n',
|
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 (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
|
||||||
ARGPARSE_s_s (oHiddenRecipient, "hidden-recipient", "@"),
|
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 (oRecipient, "remote-user", "@"), /* (old option name) */
|
||||||
ARGPARSE_s_s (oDefRecipient, "default-recipient", "@"),
|
ARGPARSE_s_s (oDefRecipient, "default-recipient", "@"),
|
||||||
ARGPARSE_s_n (oDefRecipientSelf, "default-recipient-self", "@"),
|
ARGPARSE_s_n (oDefRecipientSelf, "default-recipient-self", "@"),
|
||||||
@ -2838,38 +2842,46 @@ main (int argc, char **argv)
|
|||||||
else
|
else
|
||||||
opt.s2k_count = 0; /* Auto-calibrate when needed. */
|
opt.s2k_count = 0; /* Auto-calibrate when needed. */
|
||||||
break;
|
break;
|
||||||
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
|
|
||||||
case oEncryptTo: /* store the recipient in the second list */
|
case oRecipient:
|
||||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
case oHiddenRecipient:
|
||||||
sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO);
|
case oRecipientFile:
|
||||||
if (configfp)
|
case oHiddenRecipientFile:
|
||||||
sl->flags |= PK_LIST_CONFIG;
|
/* Store the recipient. Note that we also store the
|
||||||
break;
|
* option as private data in the flags. This is achieved
|
||||||
case oHiddenEncryptTo: /* store the recipient in the second list */
|
* by shifting the option value to the left so to keep
|
||||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
* enough space for the flags. */
|
||||||
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 */
|
|
||||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
||||||
sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
|
sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
|
||||||
if (configfp)
|
if (configfp)
|
||||||
sl->flags |= PK_LIST_CONFIG;
|
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;
|
any_explicit_recipient = 1;
|
||||||
break;
|
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 = 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)
|
if (configfp)
|
||||||
sl->flags |= PK_LIST_CONFIG;
|
sl->flags |= PK_LIST_CONFIG;
|
||||||
any_explicit_recipient = 1;
|
if (pargs.r_opt == oHiddenEncryptTo)
|
||||||
|
sl->flags |= PK_LIST_HIDDEN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case oNoEncryptTo:
|
||||||
|
opt.no_encrypt_to = 1;
|
||||||
|
break;
|
||||||
|
case oEncryptToDefaultKey:
|
||||||
|
opt.encrypt_to_default_key = configfp ? 2 : 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case oTrySecretKey:
|
case oTrySecretKey:
|
||||||
add_to_strlist2 (&opt.secret_keys_to_try,
|
add_to_strlist2 (&opt.secret_keys_to_try,
|
||||||
pargs.r.ret_str, utf8_strings);
|
pargs.r.ret_str, utf8_strings);
|
||||||
|
11
g10/gpgv.c
11
g10/gpgv.c
@ -416,6 +416,17 @@ keyserver_import_ldap (const char *name)
|
|||||||
return -1;
|
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:
|
/* Stub:
|
||||||
* No encryption here but mainproc links to these functions.
|
* No encryption here but mainproc links to these functions.
|
||||||
*/
|
*/
|
||||||
|
107
g10/import.c
107
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.
|
* 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
|
* This function rejects all keys which are not validly self signed on at
|
||||||
|
22
g10/keydb.h
22
g10/keydb.h
@ -70,15 +70,16 @@ enum resource_type {
|
|||||||
/* Bit flags used with build_pk_list. */
|
/* Bit flags used with build_pk_list. */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PK_LIST_ENCRYPT_TO=1, /* This is an encrypt-to recipient. */
|
PK_LIST_ENCRYPT_TO = 1, /* This is an encrypt-to recipient. */
|
||||||
PK_LIST_HIDDEN=2, /* This is a hidden recipient. */
|
PK_LIST_HIDDEN = 2, /* This is a hidden recipient. */
|
||||||
PK_LIST_CONFIG=4 /* Specified via config file. */
|
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
|
/* To store private data in the flags the private data must be left
|
||||||
this value. */
|
shifted by this value. */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PK_LIST_SHIFT=3
|
PK_LIST_SHIFT = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
@ -104,7 +105,7 @@ struct pk_list
|
|||||||
{
|
{
|
||||||
PK_LIST next;
|
PK_LIST next;
|
||||||
PKT_public_key *pk;
|
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. */
|
/* 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);
|
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,
|
gpg_error_t find_and_check_key (ctrl_t ctrl,
|
||||||
const char *name, unsigned int use,
|
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,
|
int algo_available( preftype_t preftype, int algo,
|
||||||
const union pref_hint *hint );
|
const union pref_hint *hint );
|
||||||
@ -322,6 +324,10 @@ int get_pubkey_byname (ctrl_t ctrl,
|
|||||||
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
|
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
|
||||||
int include_unusable, int no_akl );
|
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
|
/* Return the public key with the key id KEYID iff the secret key is
|
||||||
* available and store it at PK. */
|
* available and store it at PK. */
|
||||||
gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid);
|
gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid);
|
||||||
|
@ -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);
|
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 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,
|
void import_keys (ctrl_t ctrl, char **fnames, int nnames,
|
||||||
import_stats_t stats_hd, unsigned int options);
|
import_stats_t stats_hd, unsigned int options);
|
||||||
int import_keys_stream (ctrl_t ctrl, iobuf_t inp, import_stats_t stats_hd,
|
int import_keys_stream (ctrl_t ctrl, iobuf_t inp, import_stats_t stats_hd,
|
||||||
|
@ -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 -
|
/* 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
|
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)
|
for (rover = input; rover; rover = rover->next)
|
||||||
if(expand_id(rover->d,&output,rover->flags)==0)
|
if (!(rover->flags & PK_LIST_FROM_FILE)
|
||||||
|
&& !expand_id(rover->d,&output,rover->flags))
|
||||||
{
|
{
|
||||||
/* Didn't find any groups, so use the existing string */
|
/* Didn't find any groups, so use the existing string */
|
||||||
sl=add_to_strlist(&output,rover->d);
|
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
|
/* 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
|
* 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
|
* 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
|
* of the key. USE the requested usage and a set MARK_HIDDEN will
|
||||||
the key in the updated list as a hidden recipient. */
|
* 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
|
gpg_error_t
|
||||||
find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
|
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;
|
int rc;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
int trustlevel;
|
|
||||||
|
|
||||||
if (!name || !*name)
|
if (!name || !*name)
|
||||||
return gpg_error (GPG_ERR_INV_USER_ID);
|
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 ();
|
return gpg_error_from_syserror ();
|
||||||
pk->req_usage = use;
|
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)
|
if (rc)
|
||||||
{
|
{
|
||||||
int code;
|
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. */
|
/* Key found and usable. Check validity. */
|
||||||
trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1);
|
if (!from_file)
|
||||||
if ( (trustlevel & TRUST_FLAG_DISABLED) )
|
|
||||||
{
|
{
|
||||||
/* Key has been disabled. */
|
int trustlevel;
|
||||||
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) )
|
trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1);
|
||||||
{
|
if ( (trustlevel & TRUST_FLAG_DISABLED) )
|
||||||
/* We don't trust this key. */
|
{
|
||||||
send_status_inv_recp (10, name);
|
/* Key has been disabled. */
|
||||||
free_public_key (pk);
|
send_status_inv_recp (13, name);
|
||||||
return GPG_ERR_UNUSABLE_PUBKEY;
|
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
|
/* Skip the actual key if the key is already present in the
|
||||||
list. */
|
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.
|
/* This is the central function to collect the keys for recipients.
|
||||||
It is thus used to prepare a public key encryption. encrypt-to
|
* It is thus used to prepare a public key encryption. encrypt-to
|
||||||
keys, default keys and the keys for the actual recipients are all
|
* keys, default keys and the keys for the actual recipients are all
|
||||||
collected here. When not in batch mode and no recipient has been
|
* collected here. When not in batch mode and no recipient has been
|
||||||
passed on the commandline, the function will also ask for
|
* passed on the commandline, the function will also ask for
|
||||||
recipients.
|
* recipients.
|
||||||
|
*
|
||||||
RCPTS is a string list with the recipients; NULL is an allowed
|
* RCPTS is a string list with the recipients; NULL is an allowed
|
||||||
value but not very useful. Group expansion is done on these names;
|
* 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
|
* 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:
|
* 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.
|
* - PK_LIST_ENCRYPT_TO :: This is an encrypt-to recipient.
|
||||||
|
* - PK_LIST_HIDDEN :: This is a hidden recipient.
|
||||||
On success a list of keys is stored at the address RET_PK_LIST; the
|
* - PK_LIST_FROM_FILE :: The argument is a file with a key.
|
||||||
caller must free this list. On error the value at this address is
|
*
|
||||||
not changed.
|
* 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
|
int
|
||||||
build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list)
|
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,
|
rc = find_and_check_key (ctrl, remusr->d, PUBKEY_USAGE_ENC,
|
||||||
!!(remusr->flags&PK_LIST_HIDDEN),
|
!!(remusr->flags&PK_LIST_HIDDEN),
|
||||||
|
!!(remusr->flags&PK_LIST_FROM_FILE),
|
||||||
&pk_list);
|
&pk_list);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -177,6 +177,7 @@ output_notify (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
/* RECIPIENT [--hidden] <userID>
|
/* RECIPIENT [--hidden] <userID>
|
||||||
|
RECIPIENT [--hidden] --file <filename>
|
||||||
|
|
||||||
Set the recipient for the encryption. <userID> should be the
|
Set the recipient for the encryption. <userID> should be the
|
||||||
internal representation of the key; the server may accept any other
|
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);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int hidden;
|
int hidden, file;
|
||||||
|
|
||||||
hidden = has_option (line,"--hidden");
|
hidden = has_option (line,"--hidden");
|
||||||
|
file = has_option (line,"--file");
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
/* FIXME: Expand groups
|
/* FIXME: Expand groups
|
||||||
@ -204,7 +206,7 @@ cmd_recipient (assuan_context_t ctx, char *line)
|
|||||||
remusr = rcpts;
|
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);
|
&ctrl->server_local->recplist);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -228,6 +228,15 @@ keyserver_import_ldap (const char *name)
|
|||||||
return -1;
|
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:
|
/* Stub:
|
||||||
* No encryption here but mainproc links to these functions.
|
* No encryption here but mainproc links to these functions.
|
||||||
*/
|
*/
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
;; first and then search for the encryption subkey.)
|
;; first and then search for the encryption subkey.)
|
||||||
(define dsa-usrname2 "0xCB879DE9")
|
(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 plain-files '("plain-1" "plain-2" "plain-3"))
|
||||||
(define data-files '("data-500" "data-9000" "data-32000" "data-80000"))
|
(define data-files '("data-500" "data-9000" "data-32000" "data-80000"))
|
||||||
(define exp-files '())
|
(define exp-files '())
|
||||||
|
@ -43,3 +43,18 @@
|
|||||||
(tr:assert-identity source)))
|
(tr:assert-identity source)))
|
||||||
(append plain-files data-files)))
|
(append plain-files data-files)))
|
||||||
all-cipher-algos)
|
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)
|
||||||
|
@ -91,12 +91,17 @@
|
|||||||
"1DF48228FEFF3EC2481B106E0ACA8C465C662CC5"
|
"1DF48228FEFF3EC2481B106E0ACA8C465C662CC5"
|
||||||
"A2832820DC9F40751BDCD375BB0945BA33EC6B4C"
|
"A2832820DC9F40751BDCD375BB0945BA33EC6B4C"
|
||||||
"ADE710D74409777B7729A7653373D820F67892E0"
|
"ADE710D74409777B7729A7653373D820F67892E0"
|
||||||
"CEFC51AF91F68A2904FBFF62C4F075A4785B803F"))
|
"CEFC51AF91F68A2904FBFF62C4F075A4785B803F"
|
||||||
|
"1E28F20E41B54C2D1234D896096495FF57E08D18"
|
||||||
|
"EB33B687EB8581AB64D04852A54453E85F3DF62D"
|
||||||
|
"C6A6390E9388CDBAD71EAEA698233FE5E04F001E"
|
||||||
|
"D69102E0F5AC6B6DB8E4D16DA8E18CF46D88CAE3"))
|
||||||
|
|
||||||
(info "Importing public demo and test keys")
|
(info "Importing public demo and test keys")
|
||||||
(call-check `(,@GPG --yes --import
|
(call-check `(,@GPG --yes --import
|
||||||
,(in-srcdir "pubdemo.asc")
|
,(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)))
|
;; (letfd ((source (open (in-srcdir "pubring.pkr.asc") O_RDONLY)))
|
||||||
;; ((gpg-pipe '(--dearmor) '(--yes --import) STDERR_FILENO)
|
;; ((gpg-pipe '(--dearmor) '(--yes --import) STDERR_FILENO)
|
||||||
;; source CLOSED_FD))
|
;; source CLOSED_FD))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user