mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Import OpenPGP keys into the agent.
This commit is contained in:
parent
71bc88fbae
commit
87fac99112
23 changed files with 1669 additions and 282 deletions
|
@ -1,3 +1,32 @@
|
|||
2010-08-30 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keyid.c (KEYID_STR_SIZE): New
|
||||
(keystr): Use snprintf and new macro.
|
||||
(keystr_with_sub): New.
|
||||
(keystr_from_sk_with_sub): New.
|
||||
(keystr_from_pk_with_sub): New.
|
||||
|
||||
2010-08-27 Werner Koch <wk@g10code.com>
|
||||
|
||||
* gpg.c (main): Change scope of CTRL to the entire function.
|
||||
|
||||
* import.c (import_secret_one, import, import_keys_internal)
|
||||
(import_keys, import_keys_stream): Add arg CTRL.
|
||||
* call-agent.c (agent_keywrap_key): New.
|
||||
(agent_import_key, inq_import_key_parms): New.
|
||||
|
||||
2010-08-26 Werner Koch <wk@g10code.com>
|
||||
|
||||
* misc.c (openpgp_pk_algo_name): New.
|
||||
(openpgp_md_algo_name): New.
|
||||
|
||||
2010-08-24 Werner Koch <wk@g10code.com>
|
||||
|
||||
* options.h (IMPORT_SK2PK): Remove.
|
||||
* import.c (parse_import_options): Turn convert-sk-to-pk into a
|
||||
dummy option.
|
||||
(sec_to_pub_keyblock): Use modern functions.
|
||||
|
||||
2010-08-16 Werner Koch <wk@g10code.com>
|
||||
|
||||
* gpg.c (list_config, gpgconf_list): Use es_printf.
|
||||
|
|
101
g10/call-agent.c
101
g10/call-agent.c
|
@ -77,6 +77,13 @@ struct genkey_parm_s
|
|||
const char *keyparms;
|
||||
};
|
||||
|
||||
struct import_key_parm_s
|
||||
{
|
||||
ctrl_t ctrl;
|
||||
assuan_context_t ctx;
|
||||
const void *key;
|
||||
size_t keylen;
|
||||
};
|
||||
|
||||
|
||||
static gpg_error_t learn_status_cb (void *opaque, const char *line);
|
||||
|
@ -1706,3 +1713,97 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||
*r_buf = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Retrieve a key encryption key from the agent. With FOREXPORT true
|
||||
the key shall be used for export, with false for import. On success
|
||||
the new key is stored at R_KEY and its length at R_KEKLEN. */
|
||||
gpg_error_t
|
||||
agent_keywrap_key (ctrl_t ctrl, int forexport, void **r_kek, size_t *r_keklen)
|
||||
{
|
||||
gpg_error_t err;
|
||||
membuf_t data;
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
|
||||
*r_kek = NULL;
|
||||
err = start_agent (ctrl, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
snprintf (line, DIM(line)-1, "KEYWRAP_KEY %s",
|
||||
forexport? "--export":"--import");
|
||||
|
||||
init_membuf_secure (&data, 64);
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
membuf_data_cb, &data,
|
||||
default_inq_cb, ctrl, NULL, NULL);
|
||||
if (err)
|
||||
{
|
||||
xfree (get_membuf (&data, &len));
|
||||
return err;
|
||||
}
|
||||
buf = get_membuf (&data, &len);
|
||||
if (!buf)
|
||||
return gpg_error_from_syserror ();
|
||||
*r_kek = buf;
|
||||
*r_keklen = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Handle the inquiry for an IMPORT_KEY command. */
|
||||
static gpg_error_t
|
||||
inq_import_key_parms (void *opaque, const char *line)
|
||||
{
|
||||
struct import_key_parm_s *parm = opaque;
|
||||
gpg_error_t err;
|
||||
|
||||
if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
|
||||
{
|
||||
err = assuan_send_data (parm->ctx, parm->key, parm->keylen);
|
||||
}
|
||||
else
|
||||
err = default_inq_cb (parm->ctrl, line);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Call the agent to import a key into the agent. */
|
||||
gpg_error_t
|
||||
agent_import_key (ctrl_t ctrl, const char *desc, const void *key, size_t keylen)
|
||||
{
|
||||
gpg_error_t err;
|
||||
struct import_key_parm_s parm;
|
||||
|
||||
err = start_agent (ctrl, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
|
||||
snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
|
||||
line[DIM(line)-1] = 0;
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
parm.ctrl = ctrl;
|
||||
parm.ctx = agent_ctx;
|
||||
parm.key = key;
|
||||
parm.keylen = keylen;
|
||||
|
||||
err = assuan_transact (agent_ctx, "IMPORT_KEY",
|
||||
NULL, NULL, inq_import_key_parms, &parm, NULL, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -163,6 +163,14 @@ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||
gcry_sexp_t s_ciphertext,
|
||||
unsigned char **r_buf, size_t *r_buflen);
|
||||
|
||||
/* Retrieve a key encryption key. */
|
||||
gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,
|
||||
void **r_kek, size_t *r_keklen);
|
||||
|
||||
/* Send a key to the agent. */
|
||||
gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc,
|
||||
const void *key, size_t keylen);
|
||||
|
||||
|
||||
#endif /*GNUPG_G10_CALL_AGENT_H*/
|
||||
|
||||
|
|
51
g10/gpg.c
51
g10/gpg.c
|
@ -1925,6 +1925,7 @@ main (int argc, char **argv)
|
|||
int any_explicit_recipient = 0;
|
||||
int require_secmem=0,got_secmem=0;
|
||||
struct assuan_malloc_hooks malloc_hooks;
|
||||
ctrl_t ctrl;
|
||||
|
||||
#ifdef __riscos__
|
||||
opt.lock_once = 1;
|
||||
|
@ -1984,23 +1985,24 @@ main (int argc, char **argv)
|
|||
opt.pgp2_workarounds = 1;
|
||||
opt.escape_from = 1;
|
||||
opt.flags.require_cross_cert = 1;
|
||||
opt.import_options=IMPORT_SK2PK;
|
||||
opt.export_options=EXPORT_ATTRIBUTES;
|
||||
opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
|
||||
opt.keyserver_options.export_options=EXPORT_ATTRIBUTES;
|
||||
opt.keyserver_options.options=
|
||||
KEYSERVER_HONOR_KEYSERVER_URL|KEYSERVER_HONOR_PKA_RECORD;
|
||||
opt.verify_options=
|
||||
VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
|
||||
opt.trust_model=TM_AUTO;
|
||||
opt.mangle_dos_filenames=0;
|
||||
opt.min_cert_level=2;
|
||||
set_screen_dimensions();
|
||||
opt.keyid_format=KF_SHORT;
|
||||
opt.def_sig_expire="0";
|
||||
opt.def_cert_expire="0";
|
||||
set_homedir ( default_homedir () );
|
||||
opt.passphrase_repeat=1;
|
||||
opt.import_options = 0;
|
||||
opt.export_options = EXPORT_ATTRIBUTES;
|
||||
opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG;
|
||||
opt.keyserver_options.export_options = EXPORT_ATTRIBUTES;
|
||||
opt.keyserver_options.options = (KEYSERVER_HONOR_KEYSERVER_URL
|
||||
| KEYSERVER_HONOR_PKA_RECORD );
|
||||
opt.verify_options = (VERIFY_SHOW_POLICY_URLS
|
||||
| VERIFY_SHOW_STD_NOTATIONS
|
||||
| VERIFY_SHOW_KEYSERVER_URLS);
|
||||
opt.trust_model = TM_AUTO;
|
||||
opt.mangle_dos_filenames = 0;
|
||||
opt.min_cert_level = 2;
|
||||
set_screen_dimensions ();
|
||||
opt.keyid_format = KF_SHORT;
|
||||
opt.def_sig_expire = "0";
|
||||
opt.def_cert_expire = "0";
|
||||
set_homedir (default_homedir ());
|
||||
opt.passphrase_repeat = 1;
|
||||
|
||||
/* Check whether we have a config file on the command line. */
|
||||
orig_argc = argc;
|
||||
|
@ -3403,6 +3405,9 @@ main (int argc, char **argv)
|
|||
if(fname && utf8_strings)
|
||||
opt.flags.utf8_filename=1;
|
||||
|
||||
ctrl = xtrycalloc (1, sizeof *ctrl);
|
||||
gpg_init_default_ctrl (ctrl);
|
||||
|
||||
switch( cmd ) {
|
||||
case aPrimegen:
|
||||
case aPrintMD:
|
||||
|
@ -3438,13 +3443,7 @@ main (int argc, char **argv)
|
|||
switch( cmd )
|
||||
{
|
||||
case aServer:
|
||||
{
|
||||
ctrl_t ctrl = xtrycalloc (1, sizeof *ctrl);
|
||||
gpg_init_default_ctrl (ctrl);
|
||||
gpg_server (ctrl);
|
||||
gpg_deinit_default_ctrl (ctrl);
|
||||
xfree (ctrl);
|
||||
}
|
||||
gpg_server (ctrl);
|
||||
break;
|
||||
|
||||
case aStore: /* only store the file */
|
||||
|
@ -3704,7 +3703,7 @@ main (int argc, char **argv)
|
|||
case aFastImport:
|
||||
opt.import_options |= IMPORT_FAST;
|
||||
case aImport:
|
||||
import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
|
||||
import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options);
|
||||
break;
|
||||
|
||||
/* TODO: There are a number of command that use this same
|
||||
|
@ -4055,6 +4054,8 @@ main (int argc, char **argv)
|
|||
}
|
||||
|
||||
/* cleanup */
|
||||
gpg_deinit_default_ctrl (ctrl);
|
||||
xfree (ctrl);
|
||||
release_armor_context (afx);
|
||||
FREE_STRLIST(remusr);
|
||||
FREE_STRLIST(locusr);
|
||||
|
|
568
g10/import.c
568
g10/import.c
|
@ -1,6 +1,6 @@
|
|||
/* import.c - import a key into our key storage.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
* 2007 Free Software Foundation, Inc.
|
||||
* 2007, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -37,6 +37,8 @@
|
|||
#include "ttyio.h"
|
||||
#include "status.h"
|
||||
#include "keyserver-internal.h"
|
||||
#include "call-agent.h"
|
||||
#include "../common/membuf.h"
|
||||
|
||||
struct stats_s {
|
||||
ulong count;
|
||||
|
@ -58,14 +60,15 @@ struct stats_s {
|
|||
};
|
||||
|
||||
|
||||
static int import( IOBUF inp, const char* fname,struct stats_s *stats,
|
||||
unsigned char **fpr,size_t *fpr_len,unsigned int options );
|
||||
static int import (ctrl_t ctrl,
|
||||
IOBUF inp, const char* fname, struct stats_s *stats,
|
||||
unsigned char **fpr, size_t *fpr_len, unsigned int options);
|
||||
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
|
||||
static void revocation_present(KBNODE keyblock);
|
||||
static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats,
|
||||
unsigned char **fpr,size_t *fpr_len,
|
||||
unsigned int options,int from_sk);
|
||||
static int import_secret_one( const char *fname, KBNODE keyblock,
|
||||
static int import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
||||
struct stats_s *stats, unsigned int options);
|
||||
static int import_revoke_cert( const char *fname, KBNODE node,
|
||||
struct stats_s *stats);
|
||||
|
@ -96,8 +99,6 @@ parse_import_options(char *str,unsigned int *options,int noisy)
|
|||
N_("repair damage from the pks keyserver during import")},
|
||||
{"fast-import",IMPORT_FAST,NULL,
|
||||
N_("do not update the trustdb after import")},
|
||||
{"convert-sk-to-pk",IMPORT_SK2PK,NULL,
|
||||
N_("create a public key when importing a secret key")},
|
||||
{"merge-only",IMPORT_MERGE_ONLY,NULL,
|
||||
N_("only accept updates to existing keys")},
|
||||
{"import-clean",IMPORT_CLEAN,NULL,
|
||||
|
@ -111,6 +112,7 @@ parse_import_options(char *str,unsigned int *options,int noisy)
|
|||
{"import-unusable-sigs",0,NULL,NULL},
|
||||
{"import-clean-sigs",0,NULL,NULL},
|
||||
{"import-clean-uids",0,NULL,NULL},
|
||||
{"convert-sk-to-pk",0, NULL,NULL},
|
||||
{NULL,0,NULL,NULL}
|
||||
};
|
||||
|
||||
|
@ -161,7 +163,7 @@ import_release_stats_handle (void *p)
|
|||
*
|
||||
*/
|
||||
static int
|
||||
import_keys_internal( IOBUF inp, char **fnames, int nnames,
|
||||
import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
|
||||
void *stats_handle, unsigned char **fpr, size_t *fpr_len,
|
||||
unsigned int options )
|
||||
{
|
||||
|
@ -172,7 +174,7 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
|
|||
stats = import_new_stats_handle ();
|
||||
|
||||
if (inp) {
|
||||
rc = import( inp, "[stream]", stats, fpr, fpr_len, options);
|
||||
rc = import (ctrl, inp, "[stream]", stats, fpr, fpr_len, options);
|
||||
}
|
||||
else {
|
||||
if( !fnames && !nnames )
|
||||
|
@ -193,7 +195,7 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
|
|||
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
|
||||
else
|
||||
{
|
||||
rc = import( inp2, fname, stats, fpr, fpr_len, options );
|
||||
rc = import (ctrl, inp2, fname, stats, fpr, fpr_len, options);
|
||||
iobuf_close(inp2);
|
||||
/* Must invalidate that ugly cache to actually close it. */
|
||||
iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
|
||||
|
@ -224,21 +226,23 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
|
|||
}
|
||||
|
||||
void
|
||||
import_keys( char **fnames, int nnames,
|
||||
import_keys (ctrl_t ctrl, char **fnames, int nnames,
|
||||
void *stats_handle, unsigned int options )
|
||||
{
|
||||
import_keys_internal(NULL,fnames,nnames,stats_handle,NULL,NULL,options);
|
||||
import_keys_internal (ctrl, NULL, fnames, nnames, stats_handle,
|
||||
NULL, NULL, options);
|
||||
}
|
||||
|
||||
int
|
||||
import_keys_stream( IOBUF inp, void *stats_handle,
|
||||
unsigned char **fpr, size_t *fpr_len,unsigned int options )
|
||||
import_keys_stream (ctrl_t ctrl, IOBUF inp, void *stats_handle,
|
||||
unsigned char **fpr, size_t *fpr_len,unsigned int options)
|
||||
{
|
||||
return import_keys_internal(inp,NULL,0,stats_handle,fpr,fpr_len,options);
|
||||
return import_keys_internal (ctrl, inp, NULL, 0, stats_handle,
|
||||
fpr, fpr_len, options);
|
||||
}
|
||||
|
||||
static int
|
||||
import( IOBUF inp, const char* fname,struct stats_s *stats,
|
||||
import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats,
|
||||
unsigned char **fpr,size_t *fpr_len,unsigned int options )
|
||||
{
|
||||
PACKET *pending_pkt = NULL;
|
||||
|
@ -262,7 +266,7 @@ import( IOBUF inp, const char* fname,struct stats_s *stats,
|
|||
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
|
||||
rc = import_one( fname, keyblock, stats, fpr, fpr_len, options, 0);
|
||||
else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
|
||||
rc = import_secret_one( fname, keyblock, stats, options );
|
||||
rc = import_secret_one (ctrl, fname, keyblock, stats, options);
|
||||
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
|
||||
&& keyblock->pkt->pkt.signature->sig_class == 0x20 )
|
||||
rc = import_revoke_cert( fname, keyblock, stats );
|
||||
|
@ -528,7 +532,7 @@ fix_pks_corruption(KBNODE keyblock)
|
|||
equal. Although direct key signatures are now checked during
|
||||
import, there might still be bogus signatures sitting in a keyring.
|
||||
We need to detect and delete them before doing a merge. This
|
||||
fucntion returns the number of removed sigs. */
|
||||
function returns the number of removed sigs. */
|
||||
static int
|
||||
fix_bad_direct_key_sigs (kbnode_t keyblock, u32 *keyid)
|
||||
{
|
||||
|
@ -1076,66 +1080,298 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Walk a secret keyblock and produce a public keyblock out of it. */
|
||||
static KBNODE
|
||||
sec_to_pub_keyblock(KBNODE sec_keyblock)
|
||||
|
||||
/* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The
|
||||
function prints diagnostics and returns an error code. */
|
||||
static gpg_error_t
|
||||
transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
|
||||
{
|
||||
KBNODE secnode,pub_keyblock=NULL,ctx=NULL;
|
||||
gpg_error_t err = 0;
|
||||
void *kek = NULL;
|
||||
size_t keklen;
|
||||
kbnode_t ctx = NULL;
|
||||
kbnode_t node;
|
||||
PKT_secret_key *main_sk, *sk;
|
||||
int nskey;
|
||||
membuf_t mbuf;
|
||||
int i, j;
|
||||
size_t n;
|
||||
void *format_args_buf_ptr[PUBKEY_MAX_NSKEY];
|
||||
int format_args_buf_int[PUBKEY_MAX_NSKEY];
|
||||
void *format_args[2*PUBKEY_MAX_NSKEY];
|
||||
gcry_sexp_t skey, prot, tmpsexp;
|
||||
unsigned char *transferkey = NULL;
|
||||
size_t transferkeylen;
|
||||
gcry_cipher_hd_t cipherhd = NULL;
|
||||
unsigned char *wrappedkey = NULL;
|
||||
size_t wrappedkeylen;
|
||||
|
||||
while((secnode=walk_kbnode(sec_keyblock,&ctx,0)))
|
||||
/* Get the current KEK. */
|
||||
err = agent_keywrap_key (ctrl, 0, &kek, &keklen);
|
||||
if (err)
|
||||
{
|
||||
KBNODE pubnode;
|
||||
log_error ("error getting the KEK: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if(secnode->pkt->pkttype==PKT_SECRET_KEY ||
|
||||
secnode->pkt->pkttype==PKT_SECRET_SUBKEY)
|
||||
/* Prepare a cipher context. */
|
||||
err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
|
||||
GCRY_CIPHER_MODE_AESWRAP, 0);
|
||||
if (!err)
|
||||
err = gcry_cipher_setkey (cipherhd, kek, keklen);
|
||||
if (err)
|
||||
goto leave;
|
||||
xfree (kek);
|
||||
kek = NULL;
|
||||
|
||||
main_sk = NULL;
|
||||
while ((node = walk_kbnode (sec_keyblock, &ctx, 0)))
|
||||
{
|
||||
if (node->pkt->pkttype != PKT_SECRET_KEY
|
||||
&& node->pkt->pkttype != PKT_SECRET_SUBKEY)
|
||||
continue;
|
||||
sk = node->pkt->pkt.secret_key;
|
||||
if (!main_sk)
|
||||
main_sk = sk;
|
||||
|
||||
/* Convert our internal secret key object into an S-expression. */
|
||||
nskey = pubkey_get_nskey (sk->pubkey_algo);
|
||||
if (!nskey || nskey > PUBKEY_MAX_NSKEY)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
log_error ("internal error: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
init_membuf (&mbuf, 50);
|
||||
put_membuf_str (&mbuf, "(skey");
|
||||
for (i=j=0; i < nskey; i++)
|
||||
{
|
||||
if (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE))
|
||||
{
|
||||
put_membuf_str (&mbuf, " e %b");
|
||||
format_args_buf_ptr[i] = gcry_mpi_get_opaque (sk->skey[i], &n);
|
||||
format_args_buf_int[i] = (n+7)/8;
|
||||
format_args[j++] = format_args_buf_int + i;
|
||||
format_args[j++] = format_args_buf_ptr + i;
|
||||
}
|
||||
else
|
||||
{
|
||||
put_membuf_str (&mbuf, " _ %m");
|
||||
format_args[j++] = sk->skey + i;
|
||||
}
|
||||
}
|
||||
put_membuf_str (&mbuf, ")\n");
|
||||
put_membuf (&mbuf, "", 1);
|
||||
{
|
||||
char *format = get_membuf (&mbuf, NULL);
|
||||
if (!format)
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
err = gcry_sexp_build_array (&skey, NULL, format, format_args);
|
||||
xfree (format);
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
log_error ("error building skey array: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (sk->is_protected)
|
||||
{
|
||||
char countbuf[35];
|
||||
|
||||
snprintf (countbuf, sizeof countbuf, "%lu",
|
||||
(unsigned long)sk->protect.s2k.count);
|
||||
err = gcry_sexp_build
|
||||
(&prot, NULL,
|
||||
" (protection %s %s %b %d %s %b %s)\n",
|
||||
sk->protect.sha1chk? "sha1":"sum",
|
||||
openpgp_cipher_algo_name (sk->protect.algo),
|
||||
(int)sk->protect.ivlen, sk->protect.iv,
|
||||
sk->protect.s2k.mode,
|
||||
openpgp_md_algo_name (sk->protect.s2k.hash_algo),
|
||||
(int)sizeof (sk->protect.s2k.salt), sk->protect.s2k.salt,
|
||||
countbuf);
|
||||
}
|
||||
else
|
||||
err = gcry_sexp_build (&prot, NULL, " (protection none)\n");
|
||||
|
||||
tmpsexp = NULL;
|
||||
xfree (transferkey);
|
||||
transferkey = NULL;
|
||||
if (!err)
|
||||
err = gcry_sexp_build (&tmpsexp, NULL,
|
||||
"(openpgp-private-key\n"
|
||||
" (version %d)\n"
|
||||
" (algo %s)\n"
|
||||
" %S\n"
|
||||
" (csum %d)\n"
|
||||
" %S)\n",
|
||||
sk->version,
|
||||
openpgp_pk_algo_name (sk->pubkey_algo),
|
||||
skey, (int)(unsigned long)sk->csum, prot);
|
||||
gcry_sexp_release (skey);
|
||||
gcry_sexp_release (prot);
|
||||
if (!err)
|
||||
err = make_canon_sexp_pad (tmpsexp, 1, &transferkey, &transferkeylen);
|
||||
gcry_sexp_release (tmpsexp);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error building transfer key: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Wrap the key. */
|
||||
wrappedkeylen = transferkeylen + 8;
|
||||
xfree (wrappedkey);
|
||||
wrappedkey = xtrymalloc (wrappedkeylen);
|
||||
if (!wrappedkey)
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen,
|
||||
transferkey, transferkeylen);
|
||||
if (err)
|
||||
goto leave;
|
||||
xfree (transferkey);
|
||||
transferkey = NULL;
|
||||
|
||||
/* Send the wrapped key to the agent. */
|
||||
{
|
||||
char *uid, *desc;
|
||||
size_t uidlen;
|
||||
u32 keyid[2];
|
||||
char *orig_codeset;
|
||||
|
||||
keyid_from_sk (sk, keyid);
|
||||
uid = get_user_id (keyid, &uidlen);
|
||||
orig_codeset = i18n_switchto_utf8 ();
|
||||
desc = xtryasprintf (_("Please enter the passphrase to import the"
|
||||
" secret key for the OpenPGP certificate:\n"
|
||||
"\"%.*s\"\n" \
|
||||
"%u-bit %s key, ID %s,\n"
|
||||
"created %s.\n"),
|
||||
(int)uidlen, uid,
|
||||
nbits_from_sk (sk),
|
||||
openpgp_pk_algo_name (sk->pubkey_algo),
|
||||
(main_sk == sk
|
||||
? keystr_from_sk (sk)
|
||||
: keystr_from_sk_with_sub (main_sk, sk)),
|
||||
strtimestamp (sk->timestamp));
|
||||
i18n_switchback (orig_codeset);
|
||||
xfree (uid);
|
||||
if (desc)
|
||||
{
|
||||
uid = percent_plus_escape (desc);
|
||||
xfree (desc);
|
||||
desc = uid;
|
||||
}
|
||||
err = agent_import_key (ctrl, desc, wrappedkey, wrappedkeylen);
|
||||
xfree (desc);
|
||||
}
|
||||
if (!err)
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info (_("key %s: secret key imported\n"),
|
||||
keystr_from_sk_with_sub (main_sk, sk));
|
||||
/* stats->count++; */
|
||||
/* stats->secret_read++; */
|
||||
/* stats->secret_imported++; */
|
||||
}
|
||||
else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info (_("key %s: secret key already exists\n"),
|
||||
keystr_from_sk_with_sub (main_sk, sk));
|
||||
err = 0;
|
||||
/* stats->count++; */
|
||||
/* stats->secret_read++; */
|
||||
/* stats->secret_dups++; */
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error (_("key %s: error sending to agent: %s\n"),
|
||||
keystr_from_sk_with_sub (main_sk, sk),
|
||||
gpg_strerror (err));
|
||||
if (sk->protect.algo == GCRY_CIPHER_IDEA
|
||||
&& gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
|
||||
{
|
||||
write_status (STATUS_RSA_OR_IDEA);
|
||||
idea_cipher_warn (0);
|
||||
}
|
||||
if (gpg_err_code (err) == GPG_ERR_CANCELED)
|
||||
break; /* Don't try the other subkeys. */
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
xfree (wrappedkey);
|
||||
xfree (transferkey);
|
||||
gcry_cipher_close (cipherhd);
|
||||
xfree (kek);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Walk a secret keyblock and produce a public keyblock out of it.
|
||||
Returns a new node or NULL on error. */
|
||||
static kbnode_t
|
||||
sec_to_pub_keyblock (kbnode_t sec_keyblock)
|
||||
{
|
||||
kbnode_t pub_keyblock = NULL;
|
||||
kbnode_t ctx = NULL;
|
||||
kbnode_t secnode, pubnode;
|
||||
|
||||
while ((secnode = walk_kbnode (sec_keyblock, &ctx, 0)))
|
||||
{
|
||||
if (secnode->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| secnode->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
/* Make a public key. We only need to convert enough to
|
||||
write the keyblock out. */
|
||||
PACKET *pkt;
|
||||
PKT_secret_key *sk;
|
||||
PKT_public_key *pk;
|
||||
int n, i;
|
||||
|
||||
PKT_secret_key *sk=secnode->pkt->pkt.secret_key;
|
||||
PACKET *pkt=xmalloc_clear(sizeof(PACKET));
|
||||
PKT_public_key *pk=xmalloc_clear(sizeof(PKT_public_key));
|
||||
int n;
|
||||
pkt = xcalloc (1, sizeof *pkt);
|
||||
sk = secnode->pkt->pkt.secret_key;
|
||||
pk = xcalloc (1, sizeof *pk);
|
||||
|
||||
if(secnode->pkt->pkttype==PKT_SECRET_KEY)
|
||||
pkt->pkttype=PKT_PUBLIC_KEY;
|
||||
if (secnode->pkt->pkttype == PKT_SECRET_KEY)
|
||||
pkt->pkttype = PKT_PUBLIC_KEY;
|
||||
else
|
||||
pkt->pkttype=PKT_PUBLIC_SUBKEY;
|
||||
pkt->pkttype = PKT_PUBLIC_SUBKEY;
|
||||
|
||||
pkt->pkt.public_key=pk;
|
||||
pkt->pkt.public_key = pk;
|
||||
|
||||
pk->version=sk->version;
|
||||
pk->timestamp=sk->timestamp;
|
||||
pk->expiredate=sk->expiredate;
|
||||
pk->pubkey_algo=sk->pubkey_algo;
|
||||
pk->version = sk->version;
|
||||
pk->timestamp = sk->timestamp;
|
||||
pk->expiredate = sk->expiredate;
|
||||
pk->pubkey_algo = sk->pubkey_algo;
|
||||
|
||||
n=pubkey_get_npkey(pk->pubkey_algo);
|
||||
if(n==0)
|
||||
n = pubkey_get_npkey (pk->pubkey_algo);
|
||||
if (!n)
|
||||
{
|
||||
/* we can't properly extract the pubkey without knowing
|
||||
/* We can't properly extract the pubkey without knowing
|
||||
the number of MPIs */
|
||||
release_kbnode(pub_keyblock);
|
||||
release_kbnode (pub_keyblock);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<n;i++)
|
||||
pk->pkey[i]=mpi_copy(sk->skey[i]);
|
||||
}
|
||||
|
||||
pubnode=new_kbnode(pkt);
|
||||
for (i=0; i < n; i++)
|
||||
pk->pkey[i] = mpi_copy (sk->skey[i]);
|
||||
pubnode = new_kbnode (pkt);
|
||||
}
|
||||
else
|
||||
{
|
||||
pubnode=clone_kbnode(secnode);
|
||||
pubnode = clone_kbnode (secnode);
|
||||
}
|
||||
|
||||
if(pub_keyblock==NULL)
|
||||
pub_keyblock=pubnode;
|
||||
if (!pub_keyblock)
|
||||
pub_keyblock = pubnode;
|
||||
else
|
||||
add_kbnode(pub_keyblock,pubnode);
|
||||
add_kbnode (pub_keyblock, pubnode);
|
||||
}
|
||||
|
||||
return pub_keyblock;
|
||||
|
@ -1148,132 +1384,126 @@ sec_to_pub_keyblock(KBNODE sec_keyblock)
|
|||
* with the trust calculation.
|
||||
*/
|
||||
static int
|
||||
import_secret_one( const char *fname, KBNODE keyblock,
|
||||
import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
||||
struct stats_s *stats, unsigned int options)
|
||||
{
|
||||
PKT_secret_key *sk;
|
||||
KBNODE node, uidnode;
|
||||
u32 keyid[2];
|
||||
int rc = 0;
|
||||
|
||||
/* get the key and print some info about it */
|
||||
node = find_kbnode( keyblock, PKT_SECRET_KEY );
|
||||
if( !node )
|
||||
BUG();
|
||||
|
||||
sk = node->pkt->pkt.secret_key;
|
||||
keyid_from_sk( sk, keyid );
|
||||
uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
|
||||
|
||||
if( opt.verbose )
|
||||
{
|
||||
log_info( "sec %4u%c/%s %s ",
|
||||
nbits_from_sk( sk ),
|
||||
pubkey_letter( sk->pubkey_algo ),
|
||||
keystr_from_sk(sk), datestr_from_sk(sk) );
|
||||
if( uidnode )
|
||||
print_utf8_buffer (es_stderr, uidnode->pkt->pkt.user_id->name,
|
||||
uidnode->pkt->pkt.user_id->len );
|
||||
log_printf ("\n");
|
||||
}
|
||||
stats->secret_read++;
|
||||
|
||||
if( !uidnode )
|
||||
{
|
||||
log_error( _("key %s: no user ID\n"), keystr_from_sk(sk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sk->protect.algo>110)
|
||||
{
|
||||
log_error(_("key %s: secret key with invalid cipher %d"
|
||||
" - skipped\n"),keystr_from_sk(sk),sk->protect.algo);
|
||||
return 0;
|
||||
}
|
||||
PKT_secret_key *sk;
|
||||
KBNODE node, uidnode;
|
||||
u32 keyid[2];
|
||||
int have_seckey;
|
||||
int rc = 0;
|
||||
|
||||
/* Get the key and print some info about it */
|
||||
node = find_kbnode (keyblock, PKT_SECRET_KEY);
|
||||
if (!node)
|
||||
BUG ();
|
||||
|
||||
sk = node->pkt->pkt.secret_key;
|
||||
keyid_from_sk (sk, keyid);
|
||||
uidnode = find_next_kbnode (keyblock, PKT_USER_ID);
|
||||
|
||||
if (opt.verbose)
|
||||
{
|
||||
log_info ("sec %4u%c/%s %s ",
|
||||
nbits_from_sk (sk),
|
||||
pubkey_letter (sk->pubkey_algo),
|
||||
keystr_from_sk (sk), datestr_from_sk (sk));
|
||||
if (uidnode)
|
||||
print_utf8_buffer (es_stderr, uidnode->pkt->pkt.user_id->name,
|
||||
uidnode->pkt->pkt.user_id->len);
|
||||
log_printf ("\n");
|
||||
}
|
||||
stats->secret_read++;
|
||||
|
||||
if (!uidnode)
|
||||
{
|
||||
log_error( _("key %s: no user ID\n"), keystr_from_sk(sk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* A quick check to not import keys with an invalid protection
|
||||
cipher algorithm (only checks the primary key, though). */
|
||||
if (sk->protect.algo > 110)
|
||||
{
|
||||
log_error (_("key %s: secret key with invalid cipher %d"
|
||||
" - skipped\n"),keystr_from_sk(sk),sk->protect.algo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SELINUX_HACKS
|
||||
if (1)
|
||||
{
|
||||
/* We don't allow to import secret keys because that may be used
|
||||
to put a secret key into the keyring and the user might later
|
||||
be tricked into signing stuff with that key. */
|
||||
log_error (_("importing secret keys not allowed\n"));
|
||||
return 0;
|
||||
}
|
||||
if (1)
|
||||
{
|
||||
/* We don't allow to import secret keys because that may be used
|
||||
to put a secret key into the keyring and the user might later
|
||||
be tricked into signing stuff with that key. */
|
||||
log_error (_("importing secret keys not allowed\n"));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
clear_kbnode_flags( keyblock );
|
||||
clear_kbnode_flags( keyblock );
|
||||
|
||||
have_seckey = have_secret_key_with_kid (keyid);
|
||||
|
||||
/* do we have this key already in one of our secrings ? */
|
||||
rc = -1 /* fixme seckey_available( keyid ) is not anymore
|
||||
available and has been replaced by
|
||||
have_secret_key_with_kid. We need to rework the entire
|
||||
secret key import code. The solution I am currently
|
||||
thinking about is to move that code into a helper
|
||||
program. */;
|
||||
if( rc == G10ERR_NO_SECKEY && !(opt.import_options&IMPORT_MERGE_ONLY) )
|
||||
{
|
||||
/* simply insert this key */
|
||||
KEYDB_HANDLE hd = keydb_new (); /* FIXME*/
|
||||
if (!have_seckey && !(opt.import_options&IMPORT_MERGE_ONLY) )
|
||||
{
|
||||
/* We don't have this key, insert as a new key. */
|
||||
kbnode_t pub_keyblock;
|
||||
|
||||
/* get default resource */
|
||||
rc = keydb_locate_writable (hd, NULL);
|
||||
if (rc) {
|
||||
log_error (_("no default secret keyring: %s\n"), g10_errstr (rc));
|
||||
keydb_release (hd);
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
rc = keydb_insert_keyblock (hd, keyblock );
|
||||
if (rc)
|
||||
log_error (_("error writing keyring `%s': %s\n"),
|
||||
keydb_get_resource_name (hd), g10_errstr(rc) );
|
||||
keydb_release (hd);
|
||||
/* we are ready */
|
||||
if( !opt.quiet )
|
||||
log_info( _("key %s: secret key imported\n"), keystr_from_sk(sk));
|
||||
stats->secret_imported++;
|
||||
if (is_status_enabled ())
|
||||
print_import_ok (NULL, sk, 1|16);
|
||||
stats->secret_imported++;
|
||||
if (is_status_enabled ())
|
||||
print_import_ok (NULL, sk, 1|16);
|
||||
|
||||
if(options&IMPORT_SK2PK)
|
||||
{
|
||||
/* Try and make a public key out of this. */
|
||||
/* Make a public key out of this. */
|
||||
pub_keyblock = sec_to_pub_keyblock (keyblock);
|
||||
if (!pub_keyblock)
|
||||
log_error ("oops: FIXME (bad error message)\n");
|
||||
else
|
||||
{
|
||||
import_one (fname, pub_keyblock, stats,
|
||||
NULL, NULL, opt.import_options, 1);
|
||||
/* Fixme: We should check for an invalid keyblock and
|
||||
cancel the secret key import in this case. */
|
||||
release_kbnode (pub_keyblock);
|
||||
|
||||
/* Read the keyblock again to get the effects of a merge. */
|
||||
/* Fixme: we should do this based on the fingerprint or
|
||||
even better let import_one return the merged
|
||||
keyblock. */
|
||||
node = get_pubkeyblock (keyid);
|
||||
if (!node)
|
||||
log_error ("oops: error getting public keyblock again\n");
|
||||
else
|
||||
{
|
||||
if (!transfer_secret_keys (ctrl, keyblock))
|
||||
{
|
||||
if (!opt.quiet)
|
||||
log_info (_("key %s: secret key imported\n"),
|
||||
keystr_from_sk (sk));
|
||||
check_prefs (node);
|
||||
}
|
||||
release_kbnode (node);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (have_seckey)
|
||||
{
|
||||
/* We can't yet merge secret keys. - Well, with the new system
|
||||
we can => FIXME */
|
||||
log_error( _("key %s: secret key part already available\n"),
|
||||
keystr_from_sk(sk));
|
||||
stats->secret_dups++;
|
||||
if (is_status_enabled ())
|
||||
print_import_ok (NULL, sk, 16);
|
||||
|
||||
/* TODO: if we ever do merge secret keys, make sure to handle
|
||||
the sec_to_pub_keyblock feature as well. */
|
||||
}
|
||||
else
|
||||
log_error( _("key %s: secret key not found: %s\n"),
|
||||
keystr_from_sk(sk), g10_errstr(rc));
|
||||
|
||||
KBNODE pub_keyblock=sec_to_pub_keyblock(keyblock);
|
||||
if(pub_keyblock)
|
||||
{
|
||||
import_one(fname,pub_keyblock,stats,
|
||||
NULL,NULL,opt.import_options,1);
|
||||
release_kbnode(pub_keyblock);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that the key is definitely incorporated into the keydb,
|
||||
if we have the public part of this key, we need to check if
|
||||
the prefs are rational. */
|
||||
node=get_pubkeyblock(keyid);
|
||||
if(node)
|
||||
{
|
||||
check_prefs(node);
|
||||
release_kbnode(node);
|
||||
}
|
||||
}
|
||||
else if( !rc )
|
||||
{ /* we can't merge secret keys */
|
||||
log_error( _("key %s: already in secret keyring\n"),
|
||||
keystr_from_sk(sk));
|
||||
stats->secret_dups++;
|
||||
if (is_status_enabled ())
|
||||
print_import_ok (NULL, sk, 16);
|
||||
|
||||
/* TODO: if we ever do merge secret keys, make sure to handle
|
||||
the sec_to_pub_keyblock feature as well. */
|
||||
}
|
||||
else
|
||||
log_error( _("key %s: secret key not found: %s\n"),
|
||||
keystr_from_sk(sk), g10_errstr(rc));
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -259,8 +259,13 @@ u32 v3_keyid (gcry_mpi_t a, u32 *ki);
|
|||
void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk );
|
||||
size_t keystrlen(void);
|
||||
const char *keystr(u32 *keyid);
|
||||
const char *keystr_with_sub (u32 *main_kid, u32 *sub_kid);
|
||||
const char *keystr_from_pk(PKT_public_key *pk);
|
||||
const char *keystr_from_pk_with_sub (PKT_public_key *main_pk,
|
||||
PKT_public_key *sub_pk);
|
||||
const char *keystr_from_sk(PKT_secret_key *sk);
|
||||
const char *keystr_from_sk_with_sub (PKT_secret_key *main_sk,
|
||||
PKT_secret_key *sub_sk);
|
||||
const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc);
|
||||
u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
|
||||
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
|
||||
|
|
71
g10/keyid.c
71
g10/keyid.c
|
@ -35,6 +35,9 @@
|
|||
#include "i18n.h"
|
||||
#include "rmd160.h"
|
||||
|
||||
#define KEYID_STR_SIZE 19
|
||||
|
||||
|
||||
int
|
||||
pubkey_letter( int algo )
|
||||
{
|
||||
|
@ -204,35 +207,38 @@ keystrlen(void)
|
|||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
keystr(u32 *keyid)
|
||||
{
|
||||
static char keyid_str[19];
|
||||
|
||||
switch(opt.keyid_format)
|
||||
const char *
|
||||
keystr (u32 *keyid)
|
||||
{
|
||||
static char keyid_str[KEYID_STR_SIZE];
|
||||
|
||||
switch (opt.keyid_format)
|
||||
{
|
||||
case KF_SHORT:
|
||||
sprintf(keyid_str,"%08lX",(ulong)keyid[1]);
|
||||
snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
case KF_LONG:
|
||||
if(keyid[0])
|
||||
sprintf(keyid_str,"%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
|
||||
if (keyid[0])
|
||||
snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
|
||||
(ulong)keyid[0], (ulong)keyid[1]);
|
||||
else
|
||||
sprintf(keyid_str,"%08lX",(ulong)keyid[1]);
|
||||
snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
case KF_0xSHORT:
|
||||
sprintf(keyid_str,"0x%08lX",(ulong)keyid[1]);
|
||||
snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
case KF_0xLONG:
|
||||
if(keyid[0])
|
||||
sprintf(keyid_str,"0x%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
|
||||
snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
|
||||
(ulong)keyid[0],(ulong)keyid[1]);
|
||||
else
|
||||
sprintf(keyid_str,"0x%08lX",(ulong)keyid[1]);
|
||||
snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
@ -240,6 +246,21 @@ keystr(u32 *keyid)
|
|||
return keyid_str;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
keystr_with_sub (u32 *main_kid, u32 *sub_kid)
|
||||
{
|
||||
static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
|
||||
char *p;
|
||||
|
||||
mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
|
||||
p = buffer + strlen (buffer);
|
||||
*p++ = '/';
|
||||
mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
keystr_from_pk(PKT_public_key *pk)
|
||||
{
|
||||
|
@ -248,14 +269,36 @@ keystr_from_pk(PKT_public_key *pk)
|
|||
return keystr(pk->keyid);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
|
||||
{
|
||||
keyid_from_pk (main_pk, NULL);
|
||||
keyid_from_pk (sub_pk, NULL);
|
||||
|
||||
return keystr_with_sub (main_pk->keyid, sub_pk->keyid);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
keystr_from_sk(PKT_secret_key *sk)
|
||||
{
|
||||
keyid_from_sk(sk,NULL);
|
||||
keyid_from_sk (sk,NULL);
|
||||
|
||||
return keystr(sk->keyid);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
keystr_from_sk_with_sub (PKT_secret_key *main_sk, PKT_secret_key *sub_sk)
|
||||
{
|
||||
keyid_from_sk (main_sk, NULL);
|
||||
keyid_from_sk (sub_sk, NULL);
|
||||
|
||||
return keystr_with_sub (main_sk->keyid, sub_sk->keyid);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
keystr_from_desc(KEYDB_SEARCH_DESC *desc)
|
||||
{
|
||||
|
|
|
@ -1494,9 +1494,10 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
|||
gpg complain about "no valid OpenPGP data found". One
|
||||
way to do this could be to continue parsing this
|
||||
line-by-line and make a temp iobuf for each key. */
|
||||
|
||||
import_keys_stream(spawn->fromchild,stats_handle,fpr,fpr_len,
|
||||
opt.keyserver_options.import_options);
|
||||
|
||||
/* FIXME: Pass CTRL. */
|
||||
import_keys_stream (NULL, spawn->fromchild,stats_handle,fpr,fpr_len,
|
||||
opt.keyserver_options.import_options);
|
||||
|
||||
import_print_stats(stats_handle);
|
||||
import_release_stats_handle(stats_handle);
|
||||
|
@ -2037,8 +2038,9 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
|
|||
/* CERTs are always in binary format */
|
||||
opt.no_armor=1;
|
||||
|
||||
rc=import_keys_stream(key,NULL,fpr,fpr_len,
|
||||
opt.keyserver_options.import_options);
|
||||
/* FIXME: Pass CTRL. */
|
||||
rc = import_keys_stream (NULL, key, NULL, fpr, fpr_len,
|
||||
opt.keyserver_options.import_options);
|
||||
|
||||
opt.no_armor=armor_status;
|
||||
|
||||
|
|
11
g10/main.h
11
g10/main.h
|
@ -96,7 +96,9 @@ const char *openpgp_cipher_algo_name (int algo);
|
|||
int openpgp_pk_test_algo( int algo );
|
||||
int openpgp_pk_test_algo2 ( int algo, unsigned int use );
|
||||
int openpgp_pk_algo_usage ( int algo );
|
||||
const char *openpgp_pk_algo_name (int algo);
|
||||
int openpgp_md_test_algo( int algo );
|
||||
const char *openpgp_md_algo_name (int algo);
|
||||
|
||||
#ifdef USE_IDEA
|
||||
void idea_cipher_warn( int show );
|
||||
|
@ -263,10 +265,11 @@ gcry_mpi_t encode_md_value (PKT_public_key *pk,
|
|||
|
||||
/*-- import.c --*/
|
||||
int parse_import_options(char *str,unsigned int *options,int noisy);
|
||||
void import_keys( char **fnames, int nnames,
|
||||
void *stats_hd, unsigned int options );
|
||||
int import_keys_stream( iobuf_t inp,void *stats_hd,unsigned char **fpr,
|
||||
size_t *fpr_len,unsigned int options );
|
||||
void import_keys (ctrl_t ctrl, char **fnames, int nnames,
|
||||
void *stats_hd, unsigned int options);
|
||||
int import_keys_stream (ctrl_t ctrl, iobuf_t inp, void *stats_hd,
|
||||
unsigned char **fpr,
|
||||
size_t *fpr_len, unsigned int options);
|
||||
void *import_new_stats_handle (void);
|
||||
void import_release_stats_handle (void *p);
|
||||
void import_print_stats (void *hd);
|
||||
|
|
35
g10/misc.c
35
g10/misc.c
|
@ -478,6 +478,28 @@ openpgp_pk_algo_usage ( int algo )
|
|||
return use;
|
||||
}
|
||||
|
||||
/* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a
|
||||
string representation of the algorithm name. For unknown algorithm
|
||||
IDs this function returns "?". */
|
||||
const char *
|
||||
openpgp_pk_algo_name (int algo)
|
||||
{
|
||||
switch (algo)
|
||||
{
|
||||
case PUBKEY_ALGO_RSA:
|
||||
case PUBKEY_ALGO_RSA_E:
|
||||
case PUBKEY_ALGO_RSA_S: return "rsa";
|
||||
|
||||
case PUBKEY_ALGO_ELGAMAL:
|
||||
case PUBKEY_ALGO_ELGAMAL_E: return "elg";
|
||||
|
||||
case PUBKEY_ALGO_DSA: return "dsa";
|
||||
|
||||
default: return "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
openpgp_md_test_algo( int algo )
|
||||
{
|
||||
|
@ -491,6 +513,19 @@ openpgp_md_test_algo( int algo )
|
|||
return gcry_md_test_algo (algo);
|
||||
}
|
||||
|
||||
|
||||
/* Map the OpenPGP digest algorithm whose ID is contained in ALGO to a
|
||||
string representation of the algorithm name. For unknown algorithm
|
||||
IDs this function returns "?". */
|
||||
const char *
|
||||
openpgp_md_algo_name (int algo)
|
||||
{
|
||||
if (algo < 0 || algo > 110)
|
||||
return "?";
|
||||
return gcry_md_algo_name (algo);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_IDEA
|
||||
/* Special warning for the IDEA cipher */
|
||||
void
|
||||
|
|
|
@ -320,7 +320,6 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
|
|||
#define IMPORT_LOCAL_SIGS (1<<0)
|
||||
#define IMPORT_REPAIR_PKS_SUBKEY_BUG (1<<1)
|
||||
#define IMPORT_FAST (1<<2)
|
||||
#define IMPORT_SK2PK (1<<3)
|
||||
#define IMPORT_MERGE_ONLY (1<<4)
|
||||
#define IMPORT_MINIMAL (1<<5)
|
||||
#define IMPORT_CLEAN (1<<6)
|
||||
|
|
38
g10/pkglue.c
38
g10/pkglue.c
|
@ -244,41 +244,3 @@ pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check whether SKEY is a suitable secret key. */
|
||||
int
|
||||
REMOVE_ME_pk_check_secret_key (int algo, gcry_mpi_t *skey)
|
||||
{
|
||||
gcry_sexp_t s_skey;
|
||||
int rc;
|
||||
|
||||
if (algo == GCRY_PK_DSA)
|
||||
{
|
||||
rc = gcry_sexp_build (&s_skey, NULL,
|
||||
"(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
|
||||
skey[0], skey[1], skey[2], skey[3], skey[4]);
|
||||
}
|
||||
else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
|
||||
{
|
||||
rc = gcry_sexp_build (&s_skey, NULL,
|
||||
"(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
|
||||
skey[0], skey[1], skey[2], skey[3]);
|
||||
}
|
||||
else if (algo == GCRY_PK_RSA
|
||||
|| algo == GCRY_PK_RSA_S || algo == GCRY_PK_RSA_E)
|
||||
{
|
||||
rc = gcry_sexp_build (&s_skey, NULL,
|
||||
"(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
|
||||
skey[0], skey[1], skey[2], skey[3], skey[4],
|
||||
skey[5]);
|
||||
}
|
||||
else
|
||||
return GPG_ERR_PUBKEY_ALGO;
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
rc = gcry_pk_testkey (s_skey);
|
||||
gcry_sexp_release (s_skey);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue