Merge branch 'master' into key-storage-work

--
This commit is contained in:
Werner Koch 2013-03-20 10:00:12 +01:00
commit eaa6dc3a8b
26 changed files with 484 additions and 261 deletions

4
.gitignore vendored
View File

@ -154,7 +154,5 @@ tools/mk-tdata
tools/symcryptrun
tools/watchgnupg
tools/gpgtar
private-keys-v1.d/
x.parm
private-keys-v1.d/

View File

@ -405,7 +405,8 @@ void agent_reload_trustlist (void);
/*-- divert-scd.c --*/
int divert_pksign (ctrl_t ctrl,
const unsigned char *digest, size_t digestlen, int algo,
const unsigned char *shadow_info, unsigned char **r_sig);
const unsigned char *shadow_info, unsigned char **r_sig,
size_t *r_siglen);
int divert_pkdecrypt (ctrl_t ctrl,
const unsigned char *cipher,
const unsigned char *shadow_info,

View File

@ -596,18 +596,15 @@ static gpg_error_t
inq_quality (void *opaque, const char *line)
{
assuan_context_t ctx = opaque;
const char *s;
char *pin;
int rc;
int percent;
char numbuf[20];
if (!strncmp (line, "QUALITY", 7) && (line[7] == ' ' || !line[7]))
if ((s = has_leading_keyword (line, "QUALITY")))
{
line += 7;
while (*line == ' ')
line++;
pin = unescape_passphrase_string (line);
pin = unescape_passphrase_string (s);
if (!pin)
rc = gpg_error_from_syserror ();
else

View File

@ -701,17 +701,15 @@ static gpg_error_t
inq_needpin (void *opaque, const char *line)
{
struct inq_needpin_s *parm = opaque;
const char *s;
char *pin;
size_t pinlen;
int rc;
parm->any_inq_seen = 1;
if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
if ((s = has_leading_keyword (line, "NEEDPIN")))
{
line += 7;
while (*line == ' ')
line++;
line = s;
pinlen = 90;
pin = gcry_malloc_secure (pinlen);
if (!pin)
@ -722,17 +720,11 @@ inq_needpin (void *opaque, const char *line)
rc = assuan_send_data (parm->ctx, pin, pinlen);
xfree (pin);
}
else if (!strncmp (line, "POPUPPINPADPROMPT", 17)
&& (line[17] == ' ' || !line[17]))
else if ((s = has_leading_keyword (line, "POPUPPINPADPROMPT")))
{
line += 17;
while (*line == ' ')
line++;
rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
rc = parm->getpin_cb (parm->getpin_cb_arg, s, NULL, 1);
}
else if (!strncmp (line, "DISMISSPINPADPROMPT", 19)
&& (line[19] == ' ' || !line[19]))
else if ((s = has_leading_keyword (line, "DISMISSPINPADPROMPT")))
{
rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
}
@ -833,10 +825,6 @@ agent_card_pksign (ctrl_t ctrl,
char *p, line[ASSUAN_LINELENGTH];
membuf_t data;
struct inq_needpin_s inqparm;
size_t len;
unsigned char *sigbuf;
size_t sigbuflen;
int prepend_nul;
*r_buf = NULL;
rc = start_scd (ctrl);
@ -876,32 +864,13 @@ agent_card_pksign (ctrl_t ctrl,
if (rc)
{
size_t len;
xfree (get_membuf (&data, &len));
return unlock_scd (ctrl, rc);
}
sigbuf = get_membuf (&data, &sigbuflen);
/* Create an S-expression from it which is formatted like this:
"(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))". We better make sure
that this won't be interpreted as a negative number. */
prepend_nul = (sigbuflen && (*sigbuf & 0x80));
*r_buflen = 21 + 11 + prepend_nul + sigbuflen + 4;
p = xtrymalloc (*r_buflen);
*r_buf = (unsigned char*)p;
if (!p)
return unlock_scd (ctrl, out_of_core ());
p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
sprintf (p, "%u:", (unsigned int)sigbuflen + prepend_nul);
p += strlen (p);
if (prepend_nul)
*p++ = 0;
memcpy (p, sigbuf, sigbuflen);
p += sigbuflen;
strcpy (p, ")))");
xfree (sigbuf);
assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
*r_buf = get_membuf (&data, r_buflen);
return unlock_scd (ctrl, 0);
}
@ -1069,7 +1038,7 @@ inq_writekey_parms (void *opaque, const char *line)
{
struct writekey_parm_s *parm = opaque;
if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
if (has_leading_keyword (line, "KEYDATA"))
return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
else
return inq_needpin (opaque, line);

View File

@ -1247,6 +1247,8 @@ ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
gpg_error_t err;
int i;
(void)spec;
innerlen = 0;
for (i = 0; i < DIM(data); i++)
{

View File

@ -2197,6 +2197,7 @@ cmd_keytocard (assuan_context_t ctx, char *line)
gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
gcry_sexp_release (s_skey);
keydatalen--; /* Decrement for last '\0'. */
/* Add timestamp "created-at" in the private key */
timestamp = isotime2epoch (timestamp_str);
snprintf (keydata+keydatalen-1, 30, "(10:created-at10:%010lu))", timestamp);

View File

@ -335,7 +335,8 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
int
divert_pksign (ctrl_t ctrl,
const unsigned char *digest, size_t digestlen, int algo,
const unsigned char *shadow_info, unsigned char **r_sig)
const unsigned char *shadow_info, unsigned char **r_sig,
size_t *r_siglen)
{
int rc;
char *kid;
@ -369,7 +370,10 @@ divert_pksign (ctrl_t ctrl,
}
if (!rc)
*r_sig = sigval;
{
*r_sig = sigval;
*r_siglen = siglen;
}
xfree (kid);

View File

@ -828,7 +828,7 @@ agent_public_key_from_file (ctrl_t ctrl,
int i, idx;
gcry_sexp_t s_skey;
char algoname[6];
char elems[6];
char elems[7];
gcry_sexp_t uri_sexp, comment_sexp;
const char *uri, *comment;
size_t uri_length, comment_length;

View File

@ -278,24 +278,104 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (!s_skey)
{
/* Divert operation to the smartcard */
gcry_sexp_t s_pkey, l;
const char *name;
size_t len;
unsigned char *buf = NULL;
size_t len = 0;
int is_RSA = 0;
int is_ECDSA = 0;
/* Check keytype by public key */
rc = agent_public_key_from_file (ctrl, ctrl->keygrip, &s_pkey);
if (rc)
{
log_error ("failed to read the public key\n");
goto leave;
}
l = gcry_sexp_cadr (s_pkey);
name = gcry_sexp_nth_data (l, 0, &len);
if (len == 3 && !memcmp (name, "rsa", 3))
is_RSA = 1;
else if (len == 5 && !memcmp (name, "ecdsa", 5))
is_ECDSA = 1;
gcry_sexp_release (l);
gcry_sexp_release (s_pkey);
rc = divert_pksign (ctrl,
ctrl->digest.value,
ctrl->digest.valuelen,
ctrl->digest.algo,
shadow_info, &buf);
shadow_info, &buf, &len);
if (rc)
{
log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
goto leave;
}
len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
assert (len);
rc = gcry_sexp_sscan (&s_sig, NULL, (char*)buf, len);
if (is_RSA)
{
if (*buf & 0x80)
{
len++;
buf = xtryrealloc (buf, len);
if (!buf)
goto leave;
memmove (buf + 1, buf, len - 1);
*buf = 0;
}
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))", len, buf);
}
else if (is_ECDSA)
{
unsigned char *r_buf_allocated = NULL;
unsigned char *s_buf_allocated = NULL;
unsigned char *r_buf, *s_buf;
int r_buflen, s_buflen;
r_buflen = s_buflen = len/2;
if (*buf & 0x80)
{
r_buflen++;
r_buf_allocated = xtrymalloc (r_buflen);
if (!r_buf_allocated)
goto leave;
r_buf = r_buf_allocated;
memcpy (r_buf + 1, buf, len/2);
*r_buf = 0;
}
else
r_buf = buf;
if (*(buf + len/2) & 0x80)
{
s_buflen++;
s_buf_allocated = xtrymalloc (s_buflen);
if (!s_buf_allocated)
{
xfree (r_buf_allocated);
goto leave;
}
s_buf = s_buf_allocated;
memcpy (s_buf + 1, buf + len/2, len/2);
*s_buf = 0;
}
else
s_buf = buf + len/2;
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(ecdsa(r%b)(s%b)))",
r_buflen, r_buf,
s_buflen, s_buf);
xfree (r_buf_allocated);
xfree (s_buf_allocated);
}
else
rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
xfree (buf);
if (rc)
{

View File

@ -34,16 +34,6 @@
#include <gcrypt.h> /* We need this for the memory function protos. */
#include <errno.h> /* We need errno. */
#include <gpg-error.h> /* We need gpg_error_t. */
/* Add error codes available only in newer versions of libgpg-error. */
#ifndef GPG_ERR_NO_KEYSERVER
#define GPG_ERR_NO_KEYSERVER 186
#endif
#ifndef GPG_ERR_INV_CURVE
#define GPG_ERR_INV_CURVE 187
#endif
#ifndef GPG_ERR_UNKNOWN_CURVE
#define GPG_ERR_UNKNOWN_CURVE 188
#endif
/* Hash function used with libksba. */

View File

@ -43,7 +43,7 @@ m4_define([mym4_full_version],[mym4_version[]mym4_betastring])
AC_INIT([gnupg],[mym4_full_version], [http://bugs.gnupg.org])
NEED_GPG_ERROR_VERSION=1.10
NEED_GPG_ERROR_VERSION=1.11
NEED_LIBGCRYPT_API=1
NEED_LIBGCRYPT_VERSION=1.5.0

View File

@ -161,6 +161,7 @@ described here.
- s :: Sign
- c :: Certify
- a :: Authentication
- ? :: Unknown capability
A key may have any combination of them in any order. In addition
to these letters, the primary key has uppercase versions of the

View File

@ -2418,7 +2418,7 @@ check. @code{value} may be any printable string; it will be encoded in
UTF8, so you should check that your @option{--display-charset} is set
correctly. If you prefix @code{name} with an exclamation mark (!), the
notation data will be flagged as critical
(rfc2440:5.2.3.15). @option{--sig-notation} sets a notation for data
(rfc4880:5.2.3.16). @option{--sig-notation} sets a notation for data
signatures. @option{--cert-notation} sets a notation for key signatures
(certifications). @option{--set-notation} sets both.
@ -2440,7 +2440,7 @@ meaningful when using the OpenPGP smartcard.
@opindex sig-policy-url
@opindex cert-policy-url
@opindex set-policy-url
Use @code{string} as a Policy URL for signatures (rfc2440:5.2.3.19). If
Use @code{string} as a Policy URL for signatures (rfc4880:5.2.3.20). If
you prefix it with an exclamation mark (!), the policy URL packet will
be flagged as critical. @option{--sig-policy-url} sets a policy url for
data signatures. @option{--cert-policy-url} sets a policy url for key

View File

@ -607,6 +607,10 @@ agent_keytocard (const char *hexgrip, int keyno, int force,
{
int rc;
char line[ASSUAN_LINELENGTH];
struct default_inq_parm_s parm;
memset (&parm, 0, sizeof parm);
parm.ctx = agent_ctx;
snprintf (line, DIM(line)-1, "KEYTOCARD %s%s %s OPENPGP.%d %s",
force?"--force ": "", hexgrip, serialno, keyno, timestamp);
@ -616,8 +620,8 @@ agent_keytocard (const char *hexgrip, int keyno, int force,
if (rc)
return rc;
rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb,
NULL, NULL, NULL);
rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
NULL, NULL);
if (rc)
return rc;
@ -721,7 +725,7 @@ inq_writecert_parms (void *opaque, const char *line)
int rc;
struct writecert_parm_s *parm = opaque;
if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
if (has_leading_keyword (line, "CERTDATA"))
{
rc = assuan_send_data (parm->dflt->ctx,
parm->certdata, parm->certdatalen);
@ -774,7 +778,7 @@ inq_writekey_parms (void *opaque, const char *line)
int rc;
struct writekey_parm_s *parm = opaque;
if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
if (has_leading_keyword (line, "KEYDATA"))
{
rc = assuan_send_data (parm->dflt->ctx, parm->keydata, parm->keydatalen);
}
@ -1467,9 +1471,9 @@ keyinfo_status_cb (void *opaque, const char *line)
char **serialno = opaque;
const char *s, *s2;
if (!strncmp (line, "KEYINFO ", 8) && !*serialno)
if ((s = has_leading_keyword (line, "KEYINFO ")) && !*serialno)
{
s = strchr (line+8, ' ');
s = strchr (s, ' ');
if (s && s[1] == 'T' && s[2] == ' ' && s[3])
{
s += 3;
@ -1571,7 +1575,7 @@ inq_genkey_parms (void *opaque, const char *line)
struct genkey_parm_s *parm = opaque;
gpg_error_t err;
if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
if (has_leading_keyword (line, "KEYPARAM"))
{
err = assuan_send_data (parm->dflt->ctx,
parm->keyparms, strlen (parm->keyparms));
@ -1798,7 +1802,7 @@ inq_ciphertext_cb (void *opaque, const char *line)
struct cipher_parm_s *parm = opaque;
int rc;
if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
if (has_leading_keyword (line, "CIPHERTEXT"))
{
assuan_begin_confidential (parm->ctx);
rc = assuan_send_data (parm->dflt->ctx,
@ -1980,7 +1984,7 @@ 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]))
if (has_leading_keyword (line, "KEYDATA"))
{
err = assuan_send_data (parm->dflt->ctx, parm->key, parm->keylen);
}

View File

@ -515,12 +515,12 @@ ks_put_inq_cb (void *opaque, const char *line)
struct ks_put_parm_s *parm = opaque;
gpg_error_t err = 0;
if (!strncmp (line, "KEYBLOCK", 8) && (line[8] == ' ' || !line[8]))
if (has_leading_keyword (line, "KEYBLOCK"))
{
if (parm->data)
err = assuan_send_data (parm->ctx, parm->data, parm->datalen);
}
else if (!strncmp (line, "KEYBLOCK_INFO", 13) && (line[13]==' ' || !line[13]))
else if (has_leading_keyword (line, "KEYBLOCK_INFO"))
{
kbnode_t node;
estream_t fp;

View File

@ -550,7 +550,9 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
tty_fprintf (fp, " %u%c",
info.key_attr[i].nbits,
info.key_attr[i].algo == 1? 'R':
info.key_attr[i].algo == 17? 'D': '?');
info.key_attr[i].algo == 17? 'D':
info.key_attr[i].algo == 18? 'e':
info.key_attr[i].algo == 19? 'E': '?');
tty_fprintf (fp, "\n");
}
tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
@ -1560,7 +1562,7 @@ card_store_subkey (KBNODE node, int use)
nbits = nbits_from_pk (pk);
if (!is_RSA (pk->pubkey_algo) || (!info.is_v2 && nbits != 1024) )
if (!info.is_v2 && nbits != 1024)
{
tty_printf ("You may only store a 1024 bit RSA key on the card\n");
tty_printf ("\n");

View File

@ -1291,13 +1291,19 @@ parse_key_usage (PKT_signature * sig)
if (flags)
key_usage |= PUBKEY_USAGE_UNKNOWN;
if (!key_usage)
key_usage |= PUBKEY_USAGE_NONE;
}
else if (p) /* Key flags of length zero. */
key_usage |= PUBKEY_USAGE_NONE;
/* We set PUBKEY_USAGE_UNKNOWN to indicate that this key has a
capability that we do not handle. This serves to distinguish
between a zero key usage which we handle as the default
capabilities for that algorithm, and a usage that we do not
handle. */
handle. Likewise we use PUBKEY_USAGE_NONE to indicate that
key_flags have been given but they do not specify any usage. */
return key_usage;
}

View File

@ -216,9 +216,6 @@ do_add_key_flags (PKT_signature *sig, unsigned int use)
if (use & PUBKEY_USAGE_AUTH)
buf[0] |= 0x20;
if (!buf[0])
return;
build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1);
}

View File

@ -627,6 +627,9 @@ print_capabilities (PKT_public_key *pk, KBNODE keyblock)
if ((use & PUBKEY_USAGE_AUTH))
es_putc ('a', es_stdout);
if ((use & PUBKEY_USAGE_UNKNOWN))
es_putc ('?', es_stdout);
if (keyblock)
{
/* Figure out the usable capabilities. */

View File

@ -323,7 +323,7 @@ main ( int argc, char **argv)
int orig_argc;
char **orig_argv;
gpg_error_t err = 0;
const char *fname;
/* const char *fname; */
int may_coredump;
FILE *configfp = NULL;
char *configname = NULL;
@ -334,10 +334,10 @@ main ( int argc, char **argv)
char *logfile = NULL;
int greeting = 0;
int nogreeting = 0;
int debug_wait = 0;
/* int debug_wait = 0; */
int use_random_seed = 1;
int nodetach = 0;
int nokeysetup = 0;
/* int nodetach = 0; */
/* int nokeysetup = 0; */
enum cmd_and_opt_values cmd = 0;
struct server_control_s ctrl;
strlist_t recipients = NULL;
@ -473,13 +473,13 @@ main ( int argc, char **argv)
case aGPGConfTest:
set_cmd (&cmd, pargs.r_opt);
nogreeting = 1;
nokeysetup = 1;
/* nokeysetup = 1; */
break;
case aServer:
case aMount:
case aUmount:
nokeysetup = 1;
/* nokeysetup = 1; */
case aCreate:
set_cmd (&cmd, pargs.r_opt);
break;
@ -504,13 +504,13 @@ main ( int argc, char **argv)
case oLogFile: logfile = pargs.r.ret_str; break;
case oNoLogFile: logfile = NULL; break;
case oNoDetach: nodetach = 1; break;
case oNoDetach: /*nodetach = 1; */break;
case oDebug: debug_value |= pargs.r.ret_ulong; break;
case oDebugAll: debug_value = ~0; break;
case oDebugNone: debug_value = 0; break;
case oDebugLevel: debug_level = pargs.r.ret_str; break;
case oDebugWait: debug_wait = pargs.r.ret_int; break;
case oDebugWait: /*debug_wait = pargs.r.ret_int; */break;
case oDebugAllowCoreDump:
may_coredump = enable_core_dumps ();
break;
@ -653,7 +653,7 @@ main ( int argc, char **argv)
}
/* Store given filename into FNAME. */
fname = argc? *argv : NULL;
/* fname = argc? *argv : NULL; */
/* Parse all given encryption keys. This does a lookup of the keys
and stops if any of the given keys was not found. */

View File

@ -54,9 +54,14 @@
#define PUBKEY_USAGE_SIG GCRY_PK_USAGE_SIGN /* Good for signatures. */
#define PUBKEY_USAGE_ENC GCRY_PK_USAGE_ENCR /* Good for encryption. */
#define PUBKEY_USAGE_CERT GCRY_PK_USAGE_CERT /* Also good to certify keys. */
#define PUBKEY_USAGE_CERT GCRY_PK_USAGE_CERT /* Also good to certify keys.*/
#define PUBKEY_USAGE_AUTH GCRY_PK_USAGE_AUTH /* Good for authentication. */
#define PUBKEY_USAGE_UNKNOWN GCRY_PK_USAGE_UNKN /* Unknown usage flag. */
#define PUBKEY_USAGE_NONE 256 /* No usage given. */
#if (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR | GCRY_PK_USAGE_CERT \
| GCRY_PK_USAGE_AUTH | GCRY_PK_USAGE_UNKN) >= 256
# error Please choose another value for PUBKEY_USAGE_NONE
#endif
#define DIGEST_ALGO_MD5 /* 1 */ GCRY_MD_MD5
#define DIGEST_ALGO_SHA1 /* 2 */ GCRY_MD_SHA1

View File

@ -116,6 +116,16 @@ static struct {
};
/* Type of keys. */
typedef enum
{
KEY_TYPE_ECDH,
KEY_TYPE_ECDSA,
KEY_TYPE_RSA,
}
key_type_t;
/* The format of RSA private keys. */
typedef enum
{
@ -128,6 +138,15 @@ typedef enum
rsa_key_format_t;
/* Elliptic Curves. */
enum
{
CURVE_NIST_P256,
CURVE_NIST_P384,
CURVE_NIST_P521
};
/* One cache item for DOs. */
struct cache_s {
struct cache_s *next;
@ -199,15 +218,27 @@ struct app_local_s {
int fixedlen_admin;
} pinpad;
struct
{
unsigned int n_bits; /* Size of the modulus in bits. The rest
of this strucuire is only valid if
this is not 0. */
unsigned int e_bits; /* Size of the public exponent in bits. */
rsa_key_format_t format;
} keyattr[3];
struct
{
key_type_t key_type;
union {
struct {
unsigned int n_bits; /* Size of the modulus in bits. The rest
of this strucuire is only valid if
this is not 0. */
unsigned int e_bits; /* Size of the public exponent in bits. */
rsa_key_format_t format;
} rsa;
struct {
int curve;
} ecdsa;
struct {
int curve;
int hashalgo;
int cipheralgo;
} ecdh;
};
} keyattr[3];
};
@ -844,19 +875,60 @@ send_key_data (ctrl_t ctrl, const char *name,
}
static void
get_ecc_key_parameters (int curve, int *r_n_bits, const char **r_curve_oid)
{
if (curve == CURVE_NIST_P256)
{
*r_n_bits = 256;
*r_curve_oid = "1.2.840.10045.3.1.7";
}
else if (curve == CURVE_NIST_P384)
{
*r_n_bits = 384;
*r_curve_oid = "1.3.132.0.34";
}
else
{
*r_n_bits = 521;
*r_curve_oid = "1.3.132.0.35";
}
}
static void
send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number)
{
char buffer[200];
int n_bits;
const char *curve_oid;
assert (number >=0 && number < DIM(app->app_local->keyattr));
/* We only support RSA thus the algo identifier is fixed to 1. */
snprintf (buffer, sizeof buffer, "%d 1 %u %u %d",
number+1,
app->app_local->keyattr[number].n_bits,
app->app_local->keyattr[number].e_bits,
app->app_local->keyattr[number].format);
if (app->app_local->keyattr[number].key_type == KEY_TYPE_RSA)
snprintf (buffer, sizeof buffer, "%d 1 %u %u %d",
number+1,
app->app_local->keyattr[number].rsa.n_bits,
app->app_local->keyattr[number].rsa.e_bits,
app->app_local->keyattr[number].rsa.format);
else if (app->app_local->keyattr[number].key_type == KEY_TYPE_ECDSA)
{
get_ecc_key_parameters (app->app_local->keyattr[number].ecdsa.curve,
&n_bits, &curve_oid);
snprintf (buffer, sizeof buffer, "%d 19 %u %s",
number+1, n_bits, curve_oid);
}
else if (app->app_local->keyattr[number].key_type == KEY_TYPE_ECDH)
{
get_ecc_key_parameters (app->app_local->keyattr[number].ecdh.curve,
&n_bits, &curve_oid);
snprintf (buffer, sizeof buffer, "%d 18 %u %s %d %d",
number+1, n_bits, curve_oid,
app->app_local->keyattr[number].ecdh.hashalgo,
app->app_local->keyattr[number].ecdh.cipheralgo);
}
else
snprintf (buffer, sizeof buffer, "0 0 UNKNOWN");
send_status_direct (ctrl, keyword, buffer);
}
@ -1154,6 +1226,18 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
#endif /*GNUPG_MAJOR_VERSION > 1*/
static const char *
get_curve_name (int curve)
{
if (curve == CURVE_NIST_P256)
return "NIST P-256";
else if (curve == CURVE_NIST_P384)
return "NIST P-384";
else
return "NIST P-521";
}
/* Get the public key for KEYNO and store it as an S-expresion with
the APP handle. On error that field gets cleared. If we already
know about the public key we will just return. Note that this does
@ -1171,11 +1255,14 @@ get_public_key (app_t app, int keyno)
gpg_error_t err = 0;
unsigned char *buffer;
const unsigned char *keydata, *m, *e;
size_t buflen, keydatalen, mlen, elen;
size_t buflen, keydatalen;
size_t mlen = 0;
size_t elen = 0;
unsigned char *mbuf = NULL;
unsigned char *ebuf = NULL;
char *keybuf = NULL;
char *keybuf_p;
gcry_sexp_t s_pkey;
size_t len;
if (keyno < 1 || keyno > 3)
return gpg_error (GPG_ERR_INV_ID);
@ -1227,51 +1314,34 @@ get_public_key (app_t app, int keyno)
goto leave;
}
m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
if (!m)
if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
{
err = gpg_error (GPG_ERR_CARD);
log_error (_("response does not contain the RSA modulus\n"));
goto leave;
}
e = find_tlv (keydata, keydatalen, 0x0082, &elen);
if (!e)
{
err = gpg_error (GPG_ERR_CARD);
log_error (_("response does not contain the RSA public exponent\n"));
goto leave;
}
/* Prepend numbers with a 0 if needed. */
if (mlen && (*m & 0x80))
{
mbuf = xtrymalloc ( mlen + 1);
if (!mbuf)
m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
if (!m)
{
err = gpg_error_from_syserror ();
err = gpg_error (GPG_ERR_CARD);
log_error (_("response does not contain the RSA modulus\n"));
goto leave;
}
*mbuf = 0;
memcpy (mbuf+1, m, mlen);
mlen++;
m = mbuf;
}
if (elen && (*e & 0x80))
{
ebuf = xtrymalloc ( elen + 1);
if (!ebuf)
e = find_tlv (keydata, keydatalen, 0x0082, &elen);
if (!e)
{
err = gpg_error_from_syserror ();
err = gpg_error (GPG_ERR_CARD);
log_error (_("response does not contain the RSA public exponent\n"));
goto leave;
}
}
else
{
m = find_tlv (keydata, keydatalen, 0x0086, &mlen);
if (!m)
{
err = gpg_error (GPG_ERR_CARD);
log_error (_("response does not contain the EC public point\n"));
goto leave;
}
*ebuf = 0;
memcpy (ebuf+1, e, elen);
elen++;
e = ebuf;
}
}
else
{
@ -1328,29 +1398,88 @@ get_public_key (app_t app, int keyno)
}
}
/* Allocate a buffer to construct the S-expression. */
/* FIXME: We should provide a generalized S-expression creation
mechanism. */
keybuf = xtrymalloc (50 + 2*35 + mlen + elen + 1);
if (!keybuf)
mbuf = xtrymalloc ( mlen + 1);
if (!mbuf)
{
err = gpg_error_from_syserror ();
goto leave;
}
/* Prepend numbers with a 0 if needed. */
if (mlen && (*m & 0x80))
{
*mbuf = 0;
memcpy (mbuf+1, m, mlen);
mlen++;
}
else
memcpy (mbuf, m, mlen);
sprintf (keybuf, "(10:public-key(3:rsa(1:n%u:", (unsigned int) mlen);
keybuf_p = keybuf + strlen (keybuf);
memcpy (keybuf_p, m, mlen);
keybuf_p += mlen;
sprintf (keybuf_p, ")(1:e%u:", (unsigned int)elen);
keybuf_p += strlen (keybuf_p);
memcpy (keybuf_p, e, elen);
keybuf_p += elen;
strcpy (keybuf_p, ")))");
keybuf_p += strlen (keybuf_p);
ebuf = xtrymalloc ( elen + 1);
if (!ebuf)
{
err = gpg_error_from_syserror ();
goto leave;
}
/* Prepend numbers with a 0 if needed. */
if (elen && (*e & 0x80))
{
*ebuf = 0;
memcpy (ebuf+1, e, elen);
elen++;
}
else
memcpy (ebuf, e, elen);
if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
{
err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))",
mlen, mbuf, elen, ebuf);
if (err)
goto leave;
len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
keybuf = xtrymalloc (len);
if (!keybuf)
{
gcry_sexp_release (s_pkey);
err = gpg_error_from_syserror ();
goto leave;
}
gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
gcry_sexp_release (s_pkey);
}
else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECDSA)
{
const char *curve_name
= get_curve_name (app->app_local->keyattr[keyno].ecdsa.curve);
err = gcry_sexp_build (&s_pkey, NULL,
"(public-key(ecdsa(curve%s)(q%b)))",
curve_name, mlen, mbuf);
if (err)
goto leave;
len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
keybuf = xtrymalloc (len);
if (!keybuf)
{
gcry_sexp_release (s_pkey);
err = gpg_error_from_syserror ();
goto leave;
}
gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
gcry_sexp_release (s_pkey);
}
else
{
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
goto leave;
}
app->app_local->pk[keyno].key = (unsigned char*)keybuf;
app->app_local->pk[keyno].keylen = (keybuf_p - keybuf);
app->app_local->pk[keyno].keylen = len - 1; /* Decrement for trailing '\0' */
leave:
/* Set a flag to indicate that we tried to read the key. */
@ -2395,7 +2524,7 @@ build_privkey_template (app_t app, int keyno,
*result = NULL;
*resultlen = 0;
switch (app->app_local->keyattr[keyno].format)
switch (app->app_local->keyattr[keyno].rsa.format)
{
case RSA_STD:
case RSA_STD_N:
@ -2409,7 +2538,7 @@ build_privkey_template (app_t app, int keyno,
}
/* Get the required length for E. */
rsa_e_reqlen = app->app_local->keyattr[keyno].e_bits/8;
rsa_e_reqlen = app->app_local->keyattr[keyno].rsa.e_bits/8;
assert (rsa_e_len <= rsa_e_reqlen);
/* Build the 7f48 cardholder private key template. */
@ -2425,8 +2554,8 @@ build_privkey_template (app_t app, int keyno,
tp += add_tlv (tp, 0x93, rsa_q_len);
datalen += rsa_q_len;
if (app->app_local->keyattr[keyno].format == RSA_STD_N
|| app->app_local->keyattr[keyno].format == RSA_CRT_N)
if (app->app_local->keyattr[keyno].rsa.format == RSA_STD_N
|| app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N)
{
tp += add_tlv (tp, 0x97, rsa_n_len);
datalen += rsa_n_len;
@ -2478,8 +2607,8 @@ build_privkey_template (app_t app, int keyno,
memcpy (tp, rsa_q, rsa_q_len);
tp += rsa_q_len;
if (app->app_local->keyattr[keyno].format == RSA_STD_N
|| app->app_local->keyattr[keyno].format == RSA_CRT_N)
if (app->app_local->keyattr[keyno].rsa.format == RSA_STD_N
|| app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N)
{
memcpy (tp, rsa_n, rsa_n_len);
tp += rsa_n_len;
@ -2764,7 +2893,7 @@ do_writekey (app_t app, ctrl_t ctrl,
goto leave;
}
maxbits = app->app_local->keyattr[keyno].n_bits;
maxbits = app->app_local->keyattr[keyno].rsa.n_bits;
nbits = rsa_n? count_bits (rsa_n, rsa_n_len) : 0;
if (opt.verbose)
log_info ("RSA modulus size is %u bits (%u bytes)\n",
@ -2775,7 +2904,7 @@ do_writekey (app_t app, ctrl_t ctrl,
/* Try to switch the key to a new length. */
err = change_keyattr (app, keyno, nbits, pincb, pincb_arg);
if (!err)
maxbits = app->app_local->keyattr[keyno].n_bits;
maxbits = app->app_local->keyattr[keyno].rsa.n_bits;
}
if (nbits != maxbits)
{
@ -2785,7 +2914,7 @@ do_writekey (app_t app, ctrl_t ctrl,
goto leave;
}
maxbits = app->app_local->keyattr[keyno].e_bits;
maxbits = app->app_local->keyattr[keyno].rsa.e_bits;
if (maxbits > 32 && !app->app_local->extcap.is_v2)
maxbits = 32; /* Our code for v1 does only support 32 bits. */
nbits = rsa_e? count_bits (rsa_e, rsa_e_len) : 0;
@ -2797,7 +2926,7 @@ do_writekey (app_t app, ctrl_t ctrl,
goto leave;
}
maxbits = app->app_local->keyattr[keyno].n_bits/2;
maxbits = app->app_local->keyattr[keyno].rsa.n_bits/2;
nbits = rsa_p? count_bits (rsa_p, rsa_p_len) : 0;
if (nbits != maxbits)
{
@ -2966,7 +3095,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
to put a limit on the max. allowed keysize. 2048 bit will
already lead to a 527 byte long status line and thus a 4096 bit
key would exceed the Assuan line length limit. */
keybits = app->app_local->keyattr[keyno].n_bits;
keybits = app->app_local->keyattr[keyno].rsa.n_bits;
if (keybits > 4096)
return gpg_error (GPG_ERR_TOO_LARGE);
@ -3287,14 +3416,23 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
memcpy (data + sizeof b ## _prefix, indata, indatalen); \
}
X(SHA1, sha1, 1)
else X(RMD160, rmd160, 1)
else X(SHA224, sha224, app->app_local->extcap.is_v2)
else X(SHA256, sha256, app->app_local->extcap.is_v2)
else X(SHA384, sha384, app->app_local->extcap.is_v2)
else X(SHA512, sha512, app->app_local->extcap.is_v2)
if (use_auth
|| app->app_local->keyattr[use_auth? 2: 0].key_type == KEY_TYPE_RSA)
{
X(SHA1, sha1, 1)
else X(RMD160, rmd160, 1)
else X(SHA224, sha224, app->app_local->extcap.is_v2)
else X(SHA256, sha256, app->app_local->extcap.is_v2)
else X(SHA384, sha384, app->app_local->extcap.is_v2)
else X(SHA512, sha512, app->app_local->extcap.is_v2)
else
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
}
else
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
{
datalen = indatalen;
memcpy (data, indata, indatalen);
}
#undef X
/* Redirect to the AUTH command if asked to. */
@ -3386,6 +3524,14 @@ do_auth (app_t app, const char *keyidstr,
if (indatalen > 101) /* For a 2048 bit key. */
return gpg_error (GPG_ERR_INV_VALUE);
if (app->app_local->keyattr[2].key_type == KEY_TYPE_ECDSA
&& (indatalen == 51 || indatalen == 67 || indatalen == 83))
{
const char *p = (const char *)indata + 19;
indata = p;
indatalen -= 19;
}
/* Check whether an OpenPGP card of any version has been requested. */
if (!strcmp (keyidstr, "OPENPGP.3"))
;
@ -3753,6 +3899,22 @@ parse_historical (struct app_local_s *apploc,
}
static int
parse_ecc_curve (const unsigned char *buffer, size_t buflen)
{
int curve;
if (buflen == 6 && buffer[5] == 0x22)
curve = CURVE_NIST_P384;
else if (buflen == 6 && buffer[5] == 0x23)
curve = CURVE_NIST_P521;
else
curve = CURVE_NIST_P256;
return curve;
}
/* Parse and optionally show the algorithm attributes for KEYNO.
KEYNO must be in the range 0..2. */
static void
@ -3765,7 +3927,8 @@ parse_algorithm_attribute (app_t app, int keyno)
assert (keyno >=0 && keyno <= 2);
app->app_local->keyattr[keyno].n_bits = 0;
app->app_local->keyattr[keyno].key_type = KEY_TYPE_RSA;
app->app_local->keyattr[keyno].rsa.n_bits = 0;
relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL);
if (!relptr)
@ -3784,27 +3947,41 @@ parse_algorithm_attribute (app_t app, int keyno)
log_info ("Key-Attr-%s ..: ", desc[keyno]);
if (*buffer == 1 && (buflen == 5 || buflen == 6))
{
app->app_local->keyattr[keyno].n_bits = (buffer[1]<<8 | buffer[2]);
app->app_local->keyattr[keyno].e_bits = (buffer[3]<<8 | buffer[4]);
app->app_local->keyattr[keyno].format = 0;
app->app_local->keyattr[keyno].rsa.n_bits = (buffer[1]<<8 | buffer[2]);
app->app_local->keyattr[keyno].rsa.e_bits = (buffer[3]<<8 | buffer[4]);
app->app_local->keyattr[keyno].rsa.format = 0;
if (buflen < 6)
app->app_local->keyattr[keyno].format = RSA_STD;
app->app_local->keyattr[keyno].rsa.format = RSA_STD;
else
app->app_local->keyattr[keyno].format = (buffer[5] == 0? RSA_STD :
buffer[5] == 1? RSA_STD_N :
buffer[5] == 2? RSA_CRT :
buffer[5] == 3? RSA_CRT_N :
RSA_UNKNOWN_FMT);
app->app_local->keyattr[keyno].rsa.format = (buffer[5] == 0? RSA_STD :
buffer[5] == 1? RSA_STD_N :
buffer[5] == 2? RSA_CRT :
buffer[5] == 3? RSA_CRT_N :
RSA_UNKNOWN_FMT);
if (opt.verbose)
log_printf
("RSA, n=%u, e=%u, fmt=%s\n",
app->app_local->keyattr[keyno].n_bits,
app->app_local->keyattr[keyno].e_bits,
app->app_local->keyattr[keyno].format == RSA_STD? "std" :
app->app_local->keyattr[keyno].format == RSA_STD_N?"std+n":
app->app_local->keyattr[keyno].format == RSA_CRT? "crt" :
app->app_local->keyattr[keyno].format == RSA_CRT_N?"crt+n":"?");
app->app_local->keyattr[keyno].rsa.n_bits,
app->app_local->keyattr[keyno].rsa.e_bits,
app->app_local->keyattr[keyno].rsa.format == RSA_STD? "std" :
app->app_local->keyattr[keyno].rsa.format == RSA_STD_N?"std+n":
app->app_local->keyattr[keyno].rsa.format == RSA_CRT? "crt" :
app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N?"crt+n":"?");
}
else if (*buffer == 19) /* ECDSA */
{
app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECDSA;
app->app_local->keyattr[keyno].ecdsa.curve
= parse_ecc_curve (buffer + 1, buflen - 1);
}
else if (*buffer == 18 && buflen == 11) /* ECDH */
{
app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECDH;
app->app_local->keyattr[keyno].ecdh.curve
= parse_ecc_curve (buffer + 1, buflen - 1);
app->app_local->keyattr[keyno].ecdh.hashalgo = buffer[1];
app->app_local->keyattr[keyno].ecdh.cipheralgo = buffer[2];
}
else if (opt.verbose)
log_printhex ("", buffer, buflen);

View File

@ -2839,7 +2839,7 @@ ccid_transceive_apdu_level (ccid_driver_t handle,
/* The maximum length for a short APDU T=1 block is 261. For an
extended APDU T=1 block the maximum length 65544; however
extended APDU exchange level is not fully supported yet. */
if (apdulen > 289)
if (apdulen > sizeof (send_buffer) - 10)
return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
msg[0] = PC_to_RDR_XfrBlock;

View File

@ -138,7 +138,7 @@ default_inq_cb (void *opaque, const char *line)
gpg_error_t err;
ctrl_t ctrl = opaque;
if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
{
err = gpgsm_proxy_pinentry_notify (ctrl, line);
if (err)
@ -315,7 +315,7 @@ inq_ciphertext_cb (void *opaque, const char *line)
struct cipher_parm_s *parm = opaque;
int rc;
if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
if (has_leading_keyword (line, "CIPHERTEXT"))
{
assuan_begin_confidential (parm->ctx);
rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen);
@ -437,7 +437,7 @@ inq_genkey_parms (void *opaque, const char *line)
struct genkey_parm_s *parm = opaque;
int rc;
if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
if (has_leading_keyword (line, "KEYPARAM"))
{
rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
}
@ -693,14 +693,14 @@ static gpg_error_t
istrusted_status_cb (void *opaque, const char *line)
{
struct rootca_flags_s *flags = opaque;
const char *s;
if (!strncmp (line, "TRUSTLISTFLAG", 13) && (line[13]==' ' || !line[13]))
if ((s = has_leading_keyword (line, "TRUSTLISTFLAG")))
{
for (line += 13; *line == ' '; line++)
;
if (!strncmp (line, "relax", 5) && (line[5] == ' ' || !line[5]))
line = s;
if (has_leading_keyword (line, "relax"))
flags->relax = 1;
else if (!strncmp (line, "cm", 2) && (line[2] == ' ' || !line[2]))
else if (has_leading_keyword (line, "cm"))
flags->chain_model = 1;
}
return 0;
@ -824,14 +824,14 @@ static gpg_error_t
learn_status_cb (void *opaque, const char *line)
{
struct learn_parm_s *parm = opaque;
const char *s;
/* Pass progress data to the caller. */
if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
if ((s = has_leading_keyword (line, "PROGRESS")))
{
line = s;
if (parm->ctrl)
{
for (line += 8; *line == ' '; line++)
;
if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
return gpg_error (GPG_ERR_ASS_CANCELED);
}
@ -1017,9 +1017,9 @@ keyinfo_status_cb (void *opaque, const char *line)
char **serialno = opaque;
const char *s, *s2;
if (!strncmp (line, "KEYINFO ", 8) && !*serialno)
if ((s = has_leading_keyword (line, "KEYINFO")) && !*serialno)
{
s = strchr (line+8, ' ');
s = strchr (s, ' ');
if (s && s[1] == 'T' && s[2] == ' ' && s[3])
{
s += 3;
@ -1172,7 +1172,7 @@ 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]))
if (has_leading_keyword (line, "KEYDATA"))
{
assuan_begin_confidential (parm->ctx);
err = assuan_send_data (parm->ctx, parm->key, parm->keylen);

View File

@ -282,47 +282,40 @@ static gpg_error_t
inq_certificate (void *opaque, const char *line)
{
struct inq_certificate_parm_s *parm = opaque;
const char *s;
int rc;
size_t n;
const unsigned char *der;
size_t derlen;
int issuer_mode = 0;
ksba_sexp_t ski = NULL;
if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
if ((s = has_leading_keyword (line, "SENDCERT")))
{
line += 8;
line = s;
}
else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12]))
else if ((s = has_leading_keyword (line, "SENDCERT_SKI")))
{
size_t n;
/* Send a certificate where a sourceKeyIdentifier is included. */
line += 12;
while (*line == ' ')
line++;
line = s;
ski = make_simple_sexp_from_hexstr (line, &n);
line += n;
while (*line == ' ')
line++;
}
else if (!strncmp (line, "SENDISSUERCERT", 14)
&& (line[14] == ' ' || !line[14]))
else if ((s = has_leading_keyword (line, "SENDISSUERCERT")))
{
line += 14;
line = s;
issuer_mode = 1;
}
else if (!strncmp (line, "ISTRUSTED", 9) && (line[9]==' ' || !line[9]))
else if ((s = has_leading_keyword (line, "ISTRUSTED")))
{
/* The server is asking us whether the certificate is a trusted
root certificate. */
const char *s;
size_t n;
char fpr[41];
struct rootca_flags_s rootca_flags;
line += 9;
while (*line == ' ')
line++;
line = s;
for (s=line,n=0; hexdigitp (s); s++, n++)
;
@ -410,22 +403,21 @@ static gpg_error_t
isvalid_status_cb (void *opaque, const char *line)
{
struct isvalid_status_parm_s *parm = opaque;
const char *s;
if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
if ((s = has_leading_keyword (line, "PROGRESS")))
{
if (parm->ctrl)
{
for (line += 8; *line == ' '; line++)
;
line = s;
if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
return gpg_error (GPG_ERR_ASS_CANCELED);
}
}
else if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24)
&& (line[24]==' ' || !line[24]))
else if ((s = has_leading_keyword (line, "ONLY_VALID_IF_CERT_VALID")))
{
parm->seen++;
if (!line[24] || !unhexify_fpr (line+25, parm->fpr))
if (!*s || !unhexify_fpr (s, parm->fpr))
parm->seen++; /* Bumb it to indicate an error. */
}
return 0;
@ -693,23 +685,22 @@ static gpg_error_t
lookup_status_cb (void *opaque, const char *line)
{
struct lookup_parm_s *parm = opaque;
const char *s;
if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
if ((s = has_leading_keyword (line, "PROGRESS")))
{
if (parm->ctrl)
{
for (line += 8; *line == ' '; line++)
;
line = s;
if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
return gpg_error (GPG_ERR_ASS_CANCELED);
}
}
else if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
else if ((s = has_leading_keyword (line, "TRUNCATED")))
{
if (parm->ctrl)
{
for (line +=9; *line == ' '; line++)
;
line = s;
gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
}
}
@ -878,16 +869,17 @@ static gpg_error_t
run_command_inq_cb (void *opaque, const char *line)
{
struct run_command_parm_s *parm = opaque;
const char *s;
int rc = 0;
if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) )
if ((s = has_leading_keyword (line, "SENDCERT")))
{ /* send the given certificate */
int err;
ksba_cert_t cert;
const unsigned char *der;
size_t derlen;
line += 8;
line = s;
if (!*line)
return gpg_error (GPG_ERR_ASS_PARAMETER);
@ -907,9 +899,9 @@ run_command_inq_cb (void *opaque, const char *line)
ksba_cert_release (cert);
}
}
else if ( !strncmp (line, "PRINTINFO", 9) && (line[9] == ' ' || !line[9]) )
else if ((s = has_leading_keyword (line, "PRINTINFO")))
{ /* Simply show the message given in the argument. */
line += 9;
line = s;
log_info ("dirmngr: %s\n", line);
}
else
@ -925,17 +917,17 @@ static gpg_error_t
run_command_status_cb (void *opaque, const char *line)
{
ctrl_t ctrl = opaque;
const char *s;
if (opt.verbose)
{
log_info ("dirmngr status: %s\n", line);
}
if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
if ((s = has_leading_keyword (line, "PROGRESS")))
{
if (ctrl)
{
for (line += 8; *line == ' '; line++)
;
line = s;
if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
return gpg_error (GPG_ERR_ASS_CANCELED);
}

View File

@ -3382,7 +3382,6 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
int in_rule = 0;
int got_match = 0;
int runtime[GC_BACKEND_NR];
int used_components[GC_COMPONENT_NR];
int backend_id, component_id;
char *fname;
@ -3393,8 +3392,6 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
runtime[backend_id] = 0;
for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
used_components[component_id] = 0;
config = fopen (fname, "r");
if (!config)
@ -3621,9 +3618,6 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
if (defaults)
{
assert (component_id >= 0 && component_id < GC_COMPONENT_NR);
used_components[component_id] = 1;
/* Here we explicitly allow to update the value again. */
if (newflags)
{