#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <assert.h>
#include "gpg.h"
#include "options.h"
#include "call-agent.h"
#include "../common/membuf.h"
-struct stats_s
+struct import_stats_s
{
ulong count;
ulong no_user_id;
static int import (ctrl_t ctrl,
- IOBUF inp, const char* fname, struct stats_s *stats,
+ IOBUF inp, const char* fname, struct import_stats_s *stats,
unsigned char **fpr, size_t *fpr_len, unsigned int options,
import_screener_t screener, void *screener_arg);
static int read_block (IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root,
int *r_v3keys);
static void revocation_present (ctrl_t ctrl, kbnode_t keyblock);
static int import_one (ctrl_t ctrl,
- const char *fname, kbnode_t keyblock,struct stats_s *stats,
+ const char *fname, kbnode_t keyblock,
+ struct import_stats_s *stats,
unsigned char **fpr, size_t *fpr_len,
unsigned int options, int from_sk, int silent,
import_screener_t screener, void *screener_arg);
static int import_secret_one (ctrl_t ctrl, const char *fname, kbnode_t keyblock,
- struct stats_s *stats, int batch,
+ struct import_stats_s *stats, int batch,
unsigned int options, int for_migration,
import_screener_t screener, void *screener_arg);
static int import_revoke_cert( const char *fname, kbnode_t node,
- struct stats_s *stats);
+ struct import_stats_s *stats);
static int chk_self_sigs (const char *fname, kbnode_t keyblock,
PKT_public_key *pk, u32 *keyid, int *non_self );
static int delete_inv_parts (const char *fname, kbnode_t keyblock,
}
-void *
+import_stats_t
import_new_stats_handle (void)
{
- return xmalloc_clear ( sizeof (struct stats_s) );
+ return xmalloc_clear ( sizeof (struct import_stats_s) );
}
void
-import_release_stats_handle (void *p)
+import_release_stats_handle (import_stats_t p)
{
xfree (p);
}
*/
static int
import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
- void *stats_handle, unsigned char **fpr, size_t *fpr_len,
+ import_stats_t stats_handle,
+ unsigned char **fpr, size_t *fpr_len,
unsigned int options,
import_screener_t screener, void *screener_arg)
{
int i;
int rc = 0;
- struct stats_s *stats = stats_handle;
+ struct import_stats_s *stats = stats_handle;
if (!stats)
stats = import_new_stats_handle ();
iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname);
if (rc)
log_error ("import from '%s' failed: %s\n",
- fname, g10_errstr(rc) );
+ fname, gpg_strerror (rc) );
}
if (!fname)
break;
void
import_keys (ctrl_t ctrl, char **fnames, int nnames,
- void *stats_handle, unsigned int options )
+ import_stats_t stats_handle, unsigned int options )
{
import_keys_internal (ctrl, NULL, fnames, nnames, stats_handle,
NULL, NULL, options, NULL, NULL);
}
int
-import_keys_stream (ctrl_t ctrl, IOBUF inp, void *stats_handle,
+import_keys_stream (ctrl_t ctrl, IOBUF inp, import_stats_t stats_handle,
unsigned char **fpr, size_t *fpr_len, unsigned int options)
{
return import_keys_internal (ctrl, inp, NULL, 0, stats_handle,
/* Variant of import_keys_stream reading from an estream_t. */
int
-import_keys_es_stream (ctrl_t ctrl, estream_t fp, void *stats_handle,
+import_keys_es_stream (ctrl_t ctrl, estream_t fp,
+ import_stats_t stats_handle,
unsigned char **fpr, size_t *fpr_len,
unsigned int options,
import_screener_t screener, void *screener_arg)
static int
-import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats,
+import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats,
unsigned char **fpr,size_t *fpr_len, unsigned int options,
import_screener_t screener, void *screener_arg)
{
&& gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
{
stats->not_imported++;
- rc = 0;
}
else if (rc)
break;
stats->v3keys += v3keys;
if (rc == -1)
rc = 0;
- else if (rc && gpg_err_code (rc) != G10ERR_INV_KEYRING)
- log_error (_("error reading '%s': %s\n"), fname, g10_errstr(rc));
+ else if (rc && gpg_err_code (rc) != GPG_ERR_INV_KEYRING)
+ log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (rc));
return rc;
}
kbnode_t keyblock = NULL; /* Need to initialize because gcc can't
grasp the return semantics of
read_block. */
- struct stats_s *stats;
+ struct import_stats_s *stats;
int v3keys;
inp = iobuf_open (fname);
import_release_stats_handle (stats);
if (err == -1)
err = 0;
- else if (err && gpg_err_code (err) != G10ERR_INV_KEYRING)
+ else if (err && gpg_err_code (err) != GPG_ERR_INV_KEYRING)
log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
else if (err)
log_error ("import from '%s' failed: %s\n", fname, gpg_strerror (err));
void
-import_print_stats (void *hd)
+import_print_stats (import_stats_t stats)
{
- struct stats_s *stats = hd;
-
if (!opt.quiet)
{
log_info(_("Total number processed: %lu\n"),
in_v3key = 0;
while ((rc=parse_packet(a, pkt)) != -1)
{
- if (rc && (gpg_err_code (rc) == GPG_ERR_INV_PACKET
+ if (rc && (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY
&& (pkt->pkttype == PKT_PUBLIC_KEY
- || pkt->pkttype == PKT_SECRET_KEY)
- && (pkt->pkt.public_key->version == 2
- || pkt->pkt.public_key->version == 3)))
+ || pkt->pkttype == PKT_SECRET_KEY)))
{
in_v3key = 1;
++*r_v3keys;
; /* Do not show a diagnostic. */
else
{
- log_error("read_block: read error: %s\n", g10_errstr(rc) );
- rc = G10ERR_INV_KEYRING;
+ log_error("read_block: read error: %s\n", gpg_strerror (rc) );
+ rc = GPG_ERR_INV_KEYRING;
goto ready;
}
free_packet( pkt );
case PKT_COMPRESSED:
if (check_compress_algo (pkt->pkt.compressed->algorithm))
{
- rc = G10ERR_COMPR_ALGO;
+ rc = GPG_ERR_COMPR_ALGO;
goto ready;
}
else
for (i = 0; i < n; i++, pos += 2)
sprintf (buf+pos, "%02X", fpr[i]);
strcat (buf, " ");
- pos += 1;
strcat (buf, id->name);
write_status_text (STATUS_IMPORT_CHECK, buf);
xfree (buf);
*/
static int
import_one (ctrl_t ctrl,
- const char *fname, kbnode_t keyblock, struct stats_s *stats,
+ const char *fname, kbnode_t keyblock, struct import_stats_s *stats,
unsigned char **fpr, size_t *fpr_len, unsigned int options,
int from_sk, int silent,
import_screener_t screener, void *screener_arg)
/* Do we have this key already in one of our pubrings ? */
pk_orig = xmalloc_clear( sizeof *pk_orig );
rc = get_pubkey_byfprint_fast (pk_orig, fpr2, fpr2len);
- if (rc && rc != G10ERR_NO_PUBKEY && rc != G10ERR_UNU_PUBKEY )
+ if (rc && gpg_err_code (rc) != GPG_ERR_NO_PUBKEY
+ && gpg_err_code (rc) != GPG_ERR_UNUSABLE_PUBKEY )
{
if (!silent)
log_error (_("key %s: public key not found: %s\n"),
- keystr(keyid), g10_errstr(rc));
+ keystr(keyid), gpg_strerror (rc));
}
else if ( rc && (opt.import_options&IMPORT_MERGE_ONLY) )
{
}
else if (rc ) /* Insert this key. */
{
- KEYDB_HANDLE hd = keydb_new ();
+ KEYDB_HANDLE hd;
+
+ hd = keydb_new ();
+ if (!hd)
+ return gpg_error_from_syserror ();
- rc = keydb_locate_writable (hd, NULL);
+ rc = keydb_locate_writable (hd);
if (rc)
{
- log_error (_("no writable keyring found: %s\n"), g10_errstr (rc));
+ log_error (_("no writable keyring found: %s\n"), gpg_strerror (rc));
keydb_release (hd);
- return G10ERR_GENERAL;
+ return GPG_ERR_GENERAL;
}
if (opt.verbose > 1 )
log_info (_("writing to '%s'\n"), keydb_get_resource_name (hd) );
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_get_resource_name (hd), gpg_strerror (rc));
else if (!(opt.import_options & IMPORT_KEEP_OWNERTTRUST))
{
/* This should not be possible since we delete the
/* Now read the original keyblock again so that we can use
that handle for updating the keyblock. */
hd = keydb_new ();
+ if (!hd)
+ {
+ rc = gpg_error_from_syserror ();
+ goto leave;
+ }
keydb_disable_caching (hd);
rc = keydb_search_fpr (hd, fpr2);
if (rc )
{
log_error (_("key %s: can't locate original keyblock: %s\n"),
- keystr(keyid), g10_errstr(rc));
+ keystr(keyid), gpg_strerror (rc));
keydb_release (hd);
goto leave;
}
if (rc)
{
log_error (_("key %s: can't read original keyblock: %s\n"),
- keystr(keyid), g10_errstr(rc));
+ keystr(keyid), gpg_strerror (rc));
keydb_release (hd);
goto leave;
}
rc = keydb_update_keyblock (hd, keyblock_orig);
if (rc)
log_error (_("error writing keyring '%s': %s\n"),
- keydb_get_resource_name (hd), g10_errstr(rc) );
+ keydb_get_resource_name (hd), gpg_strerror (rc) );
else if (non_self)
revalidation_mark ();
{
xfree (*fpr);
/* Note that we need to compare against 0 here because
- COUNT gets only incremented after returning form this
+ COUNT gets only incremented after returning from this
function. */
if (!stats->count)
*fpr = fingerprint_from_pk (pk, NULL, fpr_len);
function prints diagnostics and returns an error code. If BATCH is
true the secret keys are stored by gpg-agent in the transfer format
(i.e. no re-protection and aksing for passphrases). */
-static gpg_error_t
-transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock,
- int batch)
+gpg_error_t
+transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
+ kbnode_t sec_keyblock, int batch, int force)
{
gpg_error_t err = 0;
void *kek = NULL;
unsigned char *wrappedkey = NULL;
size_t wrappedkeylen;
char *cache_nonce = NULL;
+ int stub_key_skipped = 0;
/* Get the current KEK. */
err = agent_keywrap_key (ctrl, 0, &kek, &keklen);
if (!ski)
BUG ();
- stats->count++;
- stats->secret_read++;
+ if (stats)
+ {
+ stats->count++;
+ stats->secret_read++;
+ }
/* We ignore stub keys. The way we handle them in other parts
of the code is by asking the agent whether any secret key is
has been inserted and a stub key is in turn generated by the
agent. */
if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002)
- continue;
+ {
+ stub_key_skipped = 1;
+ continue;
+ }
/* Convert our internal secret key object into an S-expression. */
nskey = pubkey_get_nskey (pk->pubkey_algo);
err = gpg_error_from_syserror ();
else
{
- err = gcry_sexp_build (&curve, NULL, "(curve %s)", curvestr);
+ const char *curvename = openpgp_oid_to_curve (curvestr, 1);
+ err = gcry_sexp_build (&curve, NULL, "(curve %s)",
+ curvename?curvename:curvestr);
xfree (curvestr);
if (!err)
{
{
char *desc = gpg_format_keydesc (pk, FORMAT_KEYDESC_IMPORT, 1);
err = agent_import_key (ctrl, desc, &cache_nonce,
- wrappedkey, wrappedkeylen, batch);
+ wrappedkey, wrappedkeylen, batch, force);
xfree (desc);
}
if (!err)
if (opt.verbose)
log_info (_("key %s: secret key imported\n"),
keystr_from_pk_with_sub (main_pk, pk));
- stats->secret_imported++;
+ if (stats)
+ stats->secret_imported++;
}
else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
{
log_info (_("key %s: secret key already exists\n"),
keystr_from_pk_with_sub (main_pk, pk));
err = 0;
- stats->secret_dups++;
+ if (stats)
+ stats->secret_dups++;
}
else
{
}
}
+ if (!err && stub_key_skipped)
+ /* We need to notify user how to migrate stub keys. */
+ err = gpg_error (GPG_ERR_NOT_PROCESSED);
+
leave:
gcry_sexp_release (curve);
xfree (cache_nonce);
/****************
* Ditto for secret keys. Handling is simpler than for public keys.
* We allow secret key importing only when allow is true, this is so
- * that a secret key can not be imported accidently and thereby tampering
+ * that a secret key can not be imported accidentally and thereby tampering
* with the trust calculation.
*/
static int
import_secret_one (ctrl_t ctrl, const char *fname, kbnode_t keyblock,
- struct stats_s *stats, int batch, unsigned int options,
+ struct import_stats_s *stats, int batch, unsigned int options,
int for_migration,
import_screener_t screener, void *screener_arg)
{
keystr_from_pk (pk));
else
{
+ gpg_error_t err;
+
nr_prev = stats->secret_imported;
- if (!transfer_secret_keys (ctrl, stats, keyblock, batch))
+ err = transfer_secret_keys (ctrl, stats, keyblock, batch, 0);
+ if (gpg_err_code (err) == GPG_ERR_NOT_PROCESSED)
+ {
+ /* TRANSLATORS: For smartcard, each private key on
+ host has a reference (stub) to a smartcard and
+ actual private key data is stored on the card. A
+ single smartcard can have up to three private key
+ data. Importing private key stub is always
+ skipped in 2.1, and it returns
+ GPG_ERR_NOT_PROCESSED. Instead, user should be
+ suggested to run 'gpg --card-status', then,
+ references to a card will be automatically
+ created again. */
+ log_info (_("To migrate '%s', with each smartcard, "
+ "run: %s\n"), "secring.gpg", "gpg --card-status");
+ err = 0;
+ }
+ if (!err)
{
int status = 16;
if (!opt.quiet)
* Import a revocation certificate; this is a single signature packet.
*/
static int
-import_revoke_cert( const char *fname, kbnode_t node, struct stats_s *stats )
+import_revoke_cert (const char *fname, kbnode_t node,
+ struct import_stats_s *stats)
{
PKT_public_key *pk = NULL;
kbnode_t onode;
(void)fname;
- assert( !node->next );
- assert( node->pkt->pkttype == PKT_SIGNATURE );
- assert( node->pkt->pkt.signature->sig_class == 0x20 );
+ log_assert (!node->next );
+ log_assert (node->pkt->pkttype == PKT_SIGNATURE );
+ log_assert (node->pkt->pkt.signature->sig_class == 0x20 );
keyid[0] = node->pkt->pkt.signature->keyid[0];
keyid[1] = node->pkt->pkt.signature->keyid[1];
pk = xmalloc_clear( sizeof *pk );
rc = get_pubkey( pk, keyid );
- if (rc == G10ERR_NO_PUBKEY )
+ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY )
{
log_error(_("key %s: no public key -"
" can't apply revocation certificate\n"), keystr(keyid));
else if (rc )
{
log_error(_("key %s: public key not found: %s\n"),
- keystr(keyid), g10_errstr(rc));
+ keystr(keyid), gpg_strerror (rc));
goto leave;
}
/* Read the original keyblock. */
hd = keydb_new ();
+ if (!hd)
+ {
+ rc = gpg_error_from_syserror ();
+ goto leave;
+ }
+
{
byte afp[MAX_FINGERPRINT_LEN];
size_t an;
if (rc)
{
log_error (_("key %s: can't locate original keyblock: %s\n"),
- keystr(keyid), g10_errstr(rc));
+ keystr(keyid), gpg_strerror (rc));
goto leave;
}
rc = keydb_get_keyblock (hd, &keyblock );
if (rc)
{
log_error (_("key %s: can't read original keyblock: %s\n"),
- keystr(keyid), g10_errstr(rc));
+ keystr(keyid), gpg_strerror (rc));
goto leave;
}
if (rc )
{
log_error( _("key %s: invalid revocation certificate"
- ": %s - rejected\n"), keystr(keyid), g10_errstr(rc));
+ ": %s - rejected\n"), keystr(keyid), gpg_strerror (rc));
goto leave;
}
rc = keydb_update_keyblock (hd, keyblock );
if (rc)
log_error (_("error writing keyring '%s': %s\n"),
- keydb_get_resource_name (hd), g10_errstr(rc) );
+ keydb_get_resource_name (hd), gpg_strerror (rc) );
keydb_release (hd);
hd = NULL;
char *p = utf8_to_native
(unode->pkt->pkt.user_id->name,
strlen (unode->pkt->pkt.user_id->name),0);
- log_info (gpg_err_code(rc) == G10ERR_PUBKEY_ALGO ?
+ log_info (gpg_err_code(rc) == GPG_ERR_PUBKEY_ALGO ?
_("key %s: unsupported public key "
"algorithm on user ID \"%s\"\n"):
_("key %s: invalid self-signature "
if ( rc )
{
if (opt.verbose)
- log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ?
+ log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
_("key %s: unsupported public key algorithm\n"):
_("key %s: invalid direct key signature\n"),
keystr (keyid));
if ( rc )
{
if (opt.verbose)
- log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ?
+ log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
_("key %s: unsupported public key"
" algorithm\n"):
_("key %s: invalid subkey binding\n"),
if ( rc )
{
if(opt.verbose)
- log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ?
+ log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
_("key %s: unsupported public"
" key algorithm\n"):
_("key %s: invalid subkey revocation\n"),
if(opt.verbose)
log_info( _("key %s: invalid revocation"
" certificate: %s - skipped\n"),
- keystr(keyid), g10_errstr(rc));
+ keystr(keyid), gpg_strerror (rc));
delete_kbnode( node );
}
}
{
u32 keyid[2];
- keyid_from_fingerprint(sig->revkey[idx]->fpr,
+ keyid_from_fingerprint(sig->revkey[idx].fpr,
MAX_FINGERPRINT_LEN,keyid);
for(inode=keyblock->next;inode;inode=inode->next)
itself? */
int rc;
- rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx]->fpr,
+ rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx].fpr,
MAX_FINGERPRINT_LEN);
- if(rc==G10ERR_NO_PUBKEY || rc==G10ERR_UNU_PUBKEY)
+ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
+ || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY)
{
char *tempkeystr=xstrdup(keystr_from_pk(pk));
/* No, so try and get it */
- if(opt.keyserver
- && (opt.keyserver_options.options
- & KEYSERVER_AUTO_KEY_RETRIEVE))
+ if ((opt.keyserver_options.options
+ & KEYSERVER_AUTO_KEY_RETRIEVE)
+ && keyserver_any_configured (ctrl))
{
log_info(_("WARNING: key %s may be revoked:"
" fetching revocation key %s\n"),
tempkeystr,keystr(keyid));
keyserver_import_fprint (ctrl,
- sig->revkey[idx]->fpr,
+ sig->revkey[idx].fpr,
MAX_FINGERPRINT_LEN,
opt.keyserver);
/* Do we have it now? */
rc=get_pubkey_byfprint_fast (NULL,
- sig->revkey[idx]->fpr,
+ sig->revkey[idx].fpr,
MAX_FINGERPRINT_LEN);
}
- if(rc==G10ERR_NO_PUBKEY || rc==G10ERR_UNU_PUBKEY)
+ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
+ || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY)
log_info(_("WARNING: key %s may be revoked:"
" revocation key %s not present.\n"),
tempkeystr,keystr(keyid));
(void)fname;
(void)keyid;
- assert(node->pkt->pkttype == PKT_USER_ID );
+ log_assert (node->pkt->pkttype == PKT_USER_ID );
/* find the position */
for (n = keyblock; n; n_where = n, n = n->next)
(void)fname;
(void)keyid;
- assert(dst->pkt->pkttype == PKT_USER_ID );
- assert(src->pkt->pkttype == PKT_USER_ID );
+ log_assert (dst->pkt->pkttype == PKT_USER_ID);
+ log_assert (src->pkt->pkttype == PKT_USER_ID);
for (n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next)
{
(void)fname;
(void)keyid;
- assert (dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || dst->pkt->pkttype == PKT_SECRET_SUBKEY);
+ log_assert (dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || dst->pkt->pkttype == PKT_SECRET_SUBKEY);
for (n=src->next; n ; n = n->next)
{
(void)fname;
(void)keyid;
- assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY );
+ log_assert (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY);
while (node)
{