mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
gpg: Implement v5 keys and v5 signatures.
* g10/build-packet.c (gpg_mpi_write): New optional arg R_NWRITTEN. Allow NULL for OUT. Change all callers. (do_key): Support v5 keys. (build_sig_subpkt_from_sig): Support 32 byte fingerprints. * g10/parse-packet.c (parse_signature): First try to set the keyid from the issuer fingerprint. (parse_key): Support v5 keys. (create_gpg_control): Better make sure to always allocate the static size of the struct in case future compilers print warnings. * g10/keyid.c (hash_public_key): Add v5 support. (keyid_from_pk): Ditto. (keyid_from_fingerprint): Ditto. (fingerprint_from_pk): Ditto. * g10/keygen.c (KEYGEN_FLAG_CREATE_V5_KEY): New. (pVERSION, pSUBVERSION): New. (add_feature_v5): New. (keygen_upd_std_prefs): Call it. (do_create_from_keygrip): Add arg keygen_flags and support the v5 flag. (common_gen): Support the v5 flag. (parse_key_parameter_part): New flags v4 and v5. (parse_key_parameter_string): Add args for version and subversion. (read_parameter_file): New keywords "Key-Version" and "Subkey-Version". (quickgen_set_para): Add arg 'version'. (quick_generate_keypair, generate_keypair): Support version parms. (do_generate_keypair): Support v5 key flag. (generate_subkeypair): Ditto. (generate_card_subkeypair): Preparse for keyflags. (gen_card_key): Ditto. * g10/sig-check.c (check_signature2): Add args extrahash and extrahashlen. (check_signature_end): Ditto. (check_signature_end_simple): Ditto. Use them. * g10/mainproc.c (proc_plaintext): Put extra hash infor into the control packet. (do_check_sig): Add args extrahas and extrahashlen and pass them on. (issuer_fpr_raw): Support 32 byte fingerprint. (check_sig_and_print): get extra hash data and pass it on. -- Note that this is only basic support and requires more fine tuning/fixing. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
f40e9d6a52
commit
01c87d4ce2
8 changed files with 565 additions and 197 deletions
232
g10/keygen.c
232
g10/keygen.c
|
@ -1,6 +1,6 @@
|
|||
/* keygen.c - Generate a key pair
|
||||
* Copyright (C) 1998-2007, 2009-2011 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2014, 2015, 2016 Werner Koch
|
||||
* Copyright (C) 2014, 2015, 2016, 2017, 2018 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -59,6 +59,7 @@ const char *default_expiration_interval = "2y";
|
|||
/* Flag bits used during key generation. */
|
||||
#define KEYGEN_FLAG_NO_PROTECTION 1
|
||||
#define KEYGEN_FLAG_TRANSIENT_KEY 2
|
||||
#define KEYGEN_FLAG_CREATE_V5_KEY 4
|
||||
|
||||
/* Maximum number of supported algorithm preferences. */
|
||||
#define MAX_PREFS 30
|
||||
|
@ -90,7 +91,9 @@ enum para_name {
|
|||
pHANDLE,
|
||||
pKEYSERVER,
|
||||
pKEYGRIP,
|
||||
pSUBKEYGRIP
|
||||
pSUBKEYGRIP,
|
||||
pVERSION, /* Desired version of the key packet. */
|
||||
pSUBVERSION, /* Ditto for the subpacket. */
|
||||
};
|
||||
|
||||
struct para_data_s {
|
||||
|
@ -148,13 +151,13 @@ static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
|
|||
const char *expirestr,
|
||||
int *r_algo, unsigned int *r_usage,
|
||||
u32 *r_expire, unsigned int *r_nbits,
|
||||
const char **r_curve);
|
||||
const char **r_curve, int *r_version);
|
||||
static void do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
||||
struct output_control_s *outctrl, int card );
|
||||
static int write_keyblock (iobuf_t out, kbnode_t node);
|
||||
static gpg_error_t gen_card_key (int keyno, int algo, int is_primary,
|
||||
kbnode_t pub_root, u32 *timestamp,
|
||||
u32 expireval);
|
||||
u32 expireval, int keygen_flags);
|
||||
static unsigned int get_keysize_range (int algo,
|
||||
unsigned int *min, unsigned int *max);
|
||||
|
||||
|
@ -760,6 +763,48 @@ add_feature_aead (PKT_signature *sig, int enabled)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
add_feature_v5 (PKT_signature *sig, int enabled)
|
||||
{
|
||||
const byte *s;
|
||||
size_t n;
|
||||
int i;
|
||||
char *buf;
|
||||
|
||||
s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n );
|
||||
if (s && n && ((enabled && (s[0] & 0x04)) || (!enabled && !(s[0] & 0x04))))
|
||||
return; /* Already set or cleared */
|
||||
|
||||
if (!s || !n)
|
||||
{ /* Create a new one */
|
||||
n = 1;
|
||||
buf = xmalloc_clear (n);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = xmalloc (n);
|
||||
memcpy (buf, s, n);
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
buf[0] |= 0x04; /* v5 key supported */
|
||||
else
|
||||
buf[0] &= ~0x04;
|
||||
|
||||
/* Are there any bits set? */
|
||||
for (i=0; i < n; i++)
|
||||
if (buf[i])
|
||||
break;
|
||||
|
||||
if (i == n)
|
||||
delete_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES);
|
||||
else
|
||||
build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n);
|
||||
|
||||
xfree (buf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_keyserver_modify (PKT_signature *sig,int enabled)
|
||||
{
|
||||
|
@ -848,6 +893,7 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque)
|
|||
/* Make sure that the MDC feature flag is set if needed. */
|
||||
add_feature_mdc (sig,mdc_available);
|
||||
add_feature_aead (sig, aead_available);
|
||||
add_feature_v5 (sig, opt.flags.rfc4880bis);
|
||||
add_keyserver_modify (sig,ks_modify);
|
||||
keygen_add_keyserver_url(sig,NULL);
|
||||
|
||||
|
@ -1370,7 +1416,7 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
|
|||
static int
|
||||
do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
|
||||
kbnode_t pub_root, u32 timestamp, u32 expireval,
|
||||
int is_subkey)
|
||||
int is_subkey, int keygen_flags)
|
||||
{
|
||||
int err;
|
||||
PACKET *pkt;
|
||||
|
@ -1417,7 +1463,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
|
|||
}
|
||||
|
||||
pk->timestamp = timestamp;
|
||||
pk->version = 4;
|
||||
pk->version = (keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4;
|
||||
if (expireval)
|
||||
pk->expiredate = pk->timestamp + expireval;
|
||||
pk->pubkey_algo = algo;
|
||||
|
@ -1484,7 +1530,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
|
|||
}
|
||||
|
||||
pk->timestamp = timestamp;
|
||||
pk->version = 4;
|
||||
pk->version = (keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4;
|
||||
if (expireval)
|
||||
pk->expiredate = pk->timestamp + expireval;
|
||||
pk->pubkey_algo = algo;
|
||||
|
@ -2928,7 +2974,7 @@ ask_user_id (int mode, int full, KBNODE keyblock)
|
|||
/* Basic key generation. Here we divert to the actual generation
|
||||
routines based on the requested algorithm. */
|
||||
static int
|
||||
do_create (int algo, unsigned int nbits, const char *curve, KBNODE pub_root,
|
||||
do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root,
|
||||
u32 timestamp, u32 expiredate, int is_subkey,
|
||||
int keygen_flags, const char *passphrase,
|
||||
char **cache_nonce_addr, char **passwd_nonce_addr)
|
||||
|
@ -3007,12 +3053,14 @@ generate_user_id (KBNODE keyblock, const char *uidstr)
|
|||
* for any parameter. FOR_SUBKEY shall be true if this is used as a
|
||||
* subkey. If CLEAR_CERT is set a default CERT usage will be cleared;
|
||||
* this is useful if for example the default algorithm is used for a
|
||||
* subkey. */
|
||||
* subkey. If R_KEYVERSION is not NULL it will receive the version of
|
||||
* the key; this is currently 4 but can be changed with the flag "v5"
|
||||
* to create a v5 key. */
|
||||
static gpg_error_t
|
||||
parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
|
||||
int *r_algo, unsigned int *r_size,
|
||||
unsigned int *r_keyuse,
|
||||
char const **r_curve)
|
||||
char const **r_curve, int *r_keyversion)
|
||||
{
|
||||
char *flags;
|
||||
int algo;
|
||||
|
@ -3021,6 +3069,7 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
|
|||
int ecdh_or_ecdsa = 0;
|
||||
unsigned int size;
|
||||
int keyuse;
|
||||
int keyversion = 4;
|
||||
int i;
|
||||
const char *s;
|
||||
|
||||
|
@ -3119,6 +3168,13 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
|
|||
return gpg_error (GPG_ERR_INV_FLAG);
|
||||
}
|
||||
}
|
||||
else if (!ascii_strcasecmp (s, "v5"))
|
||||
{
|
||||
if (opt.flags.rfc4880bis)
|
||||
keyversion = 5;
|
||||
}
|
||||
else if (!ascii_strcasecmp (s, "v4"))
|
||||
keyversion = 4;
|
||||
else
|
||||
{
|
||||
xfree (tokens);
|
||||
|
@ -3194,10 +3250,13 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
|
|||
*r_keyuse = keyuse;
|
||||
if (r_curve)
|
||||
*r_curve = curve;
|
||||
if (r_keyversion)
|
||||
*r_keyversion = keyversion;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Parse and return the standard key generation parameter.
|
||||
* The string is expected to be in this format:
|
||||
*
|
||||
|
@ -3228,6 +3287,7 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
|
|||
* ecdsa := Use algorithm ECDSA.
|
||||
* eddsa := Use algorithm EdDSA.
|
||||
* ecdh := Use algorithm ECDH.
|
||||
* v5 := Create version 5 key (requires option --rfc4880bis)
|
||||
*
|
||||
* There are several defaults and fallbacks depending on the
|
||||
* algorithm. PART can be used to select which part of STRING is
|
||||
|
@ -3246,9 +3306,11 @@ parse_key_parameter_string (const char *string, int part,
|
|||
int *r_algo, unsigned int *r_size,
|
||||
unsigned int *r_keyuse,
|
||||
char const **r_curve,
|
||||
int *r_version,
|
||||
int *r_subalgo, unsigned int *r_subsize,
|
||||
unsigned *r_subkeyuse,
|
||||
char const **r_subcurve)
|
||||
unsigned int *r_subkeyuse,
|
||||
char const **r_subcurve,
|
||||
int *r_subversion)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
char *primary, *secondary;
|
||||
|
@ -3261,6 +3323,8 @@ parse_key_parameter_string (const char *string, int part,
|
|||
*r_keyuse = 0;
|
||||
if (r_curve)
|
||||
*r_curve = NULL;
|
||||
if (r_version)
|
||||
*r_version = 4;
|
||||
if (r_subalgo)
|
||||
*r_subalgo = 0;
|
||||
if (r_subsize)
|
||||
|
@ -3269,6 +3333,8 @@ parse_key_parameter_string (const char *string, int part,
|
|||
*r_subkeyuse = 0;
|
||||
if (r_subcurve)
|
||||
*r_subcurve = NULL;
|
||||
if (r_subversion)
|
||||
*r_subversion = 4;
|
||||
|
||||
if (!string || !*string
|
||||
|| !ascii_strcasecmp (string, "default") || !strcmp (string, "-"))
|
||||
|
@ -3283,11 +3349,11 @@ parse_key_parameter_string (const char *string, int part,
|
|||
*secondary++ = 0;
|
||||
if (part == -1 || part == 0)
|
||||
{
|
||||
err = parse_key_parameter_part (primary, 0, 0, r_algo, r_size,
|
||||
r_keyuse, r_curve);
|
||||
err = parse_key_parameter_part (primary, 0, 0, r_algo, r_size,
|
||||
r_keyuse, r_curve, r_version);
|
||||
if (!err && part == -1)
|
||||
err = parse_key_parameter_part (secondary, 1, 0, r_subalgo, r_subsize,
|
||||
r_subkeyuse, r_subcurve);
|
||||
r_subkeyuse, r_subcurve, r_subversion);
|
||||
}
|
||||
else if (part == 1)
|
||||
{
|
||||
|
@ -3300,14 +3366,17 @@ parse_key_parameter_string (const char *string, int part,
|
|||
if (secondary)
|
||||
{
|
||||
err = parse_key_parameter_part (secondary, 1, 0,
|
||||
r_algo, r_size, r_keyuse, r_curve);
|
||||
r_algo, r_size, r_keyuse, r_curve,
|
||||
r_version);
|
||||
if (!err && suggested_use && r_keyuse && !(suggested_use & *r_keyuse))
|
||||
err = parse_key_parameter_part (primary, 1, 1 /*(clear cert)*/,
|
||||
r_algo, r_size, r_keyuse, r_curve);
|
||||
r_algo, r_size, r_keyuse, r_curve,
|
||||
r_version);
|
||||
}
|
||||
else
|
||||
err = parse_key_parameter_part (primary, 1, 0,
|
||||
r_algo, r_size, r_keyuse, r_curve);
|
||||
r_algo, r_size, r_keyuse, r_curve,
|
||||
r_version);
|
||||
}
|
||||
|
||||
xfree (primary);
|
||||
|
@ -3395,9 +3464,8 @@ get_parameter_algo( struct para_data_s *para, enum para_name key,
|
|||
* compatibility with the batch key generation. It would be
|
||||
* better to make full use of parse_key_parameter_string. */
|
||||
parse_key_parameter_string (NULL, 0, 0,
|
||||
&i, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
&i, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
if (r_default)
|
||||
*r_default = 1;
|
||||
}
|
||||
|
@ -3810,6 +3878,8 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
|
|||
{ "Keygrip", pKEYGRIP },
|
||||
{ "Key-Grip", pKEYGRIP },
|
||||
{ "Subkey-grip", pSUBKEYGRIP },
|
||||
{ "Key-Version", pVERSION },
|
||||
{ "Subkey-Version", pSUBVERSION },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
IOBUF fp;
|
||||
|
@ -3954,12 +4024,19 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
|
|||
break;
|
||||
}
|
||||
}
|
||||
r = xmalloc_clear( sizeof *r + strlen( value ) );
|
||||
r->lnr = lnr;
|
||||
r->key = keywords[i].key;
|
||||
strcpy( r->u.value, value );
|
||||
r->next = para;
|
||||
para = r;
|
||||
|
||||
if (!opt.flags.rfc4880bis && (keywords[i].key == pVERSION
|
||||
|| keywords[i].key == pSUBVERSION))
|
||||
; /* Ignore version unless --rfc4880bis is active. */
|
||||
else
|
||||
{
|
||||
r = xmalloc_clear( sizeof *r + strlen( value ) );
|
||||
r->lnr = lnr;
|
||||
r->key = keywords[i].key;
|
||||
strcpy( r->u.value, value );
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
}
|
||||
if( err )
|
||||
log_error("%s:%d: %s\n", fname, lnr, err );
|
||||
|
@ -3994,7 +4071,8 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
|
|||
/* Helper for quick_generate_keypair. */
|
||||
static struct para_data_s *
|
||||
quickgen_set_para (struct para_data_s *para, int for_subkey,
|
||||
int algo, int nbits, const char *curve, unsigned int use)
|
||||
int algo, int nbits, const char *curve, unsigned int use,
|
||||
int version)
|
||||
{
|
||||
struct para_data_s *r;
|
||||
|
||||
|
@ -4033,6 +4111,15 @@ quickgen_set_para (struct para_data_s *para, int for_subkey,
|
|||
para = r;
|
||||
}
|
||||
|
||||
if (opt.flags.rfc4880bis)
|
||||
{
|
||||
r = xmalloc_clear (sizeof *r + 20);
|
||||
r->key = for_subkey? pSUBVERSION : pVERSION;
|
||||
snprintf (r->u.value, 20, "%d", version);
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
|
||||
return para;
|
||||
}
|
||||
|
||||
|
@ -4125,25 +4212,26 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
|
|||
|| !strcmp (usagestr, "-")))
|
||||
{
|
||||
/* Use default key parameters. */
|
||||
int algo, subalgo;
|
||||
int algo, subalgo, version, subversion;
|
||||
unsigned int size, subsize;
|
||||
unsigned int keyuse, subkeyuse;
|
||||
const char *curve, *subcurve;
|
||||
|
||||
err = parse_key_parameter_string (algostr, -1, 0,
|
||||
&algo, &size, &keyuse, &curve,
|
||||
&algo, &size, &keyuse, &curve, &version,
|
||||
&subalgo, &subsize, &subkeyuse,
|
||||
&subcurve);
|
||||
&subcurve, &subversion);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
para = quickgen_set_para (para, 0, algo, size, curve, keyuse);
|
||||
para = quickgen_set_para (para, 0, algo, size, curve, keyuse, version);
|
||||
if (subalgo)
|
||||
para = quickgen_set_para (para, 1,
|
||||
subalgo, subsize, subcurve, subkeyuse);
|
||||
subalgo, subsize, subcurve, subkeyuse,
|
||||
subversion);
|
||||
|
||||
if (*expirestr)
|
||||
{
|
||||
|
@ -4166,21 +4254,22 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
|
|||
else
|
||||
{
|
||||
/* Extended unattended mode. Creates only the primary key. */
|
||||
int algo;
|
||||
int algo, version;
|
||||
unsigned int use;
|
||||
u32 expire;
|
||||
unsigned int nbits;
|
||||
const char *curve;
|
||||
|
||||
err = parse_algo_usage_expire (ctrl, 0, algostr, usagestr, expirestr,
|
||||
&algo, &use, &expire, &nbits, &curve);
|
||||
&algo, &use, &expire, &nbits, &curve,
|
||||
&version);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("Key generation failed: %s\n"), gpg_strerror (err) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
para = quickgen_set_para (para, 0, algo, nbits, curve, use);
|
||||
para = quickgen_set_para (para, 0, algo, nbits, curve, use, version);
|
||||
r = xmalloc_clear (sizeof *r + 20);
|
||||
r->key = pKEYEXPIRE;
|
||||
r->u.expire = expire;
|
||||
|
@ -4494,7 +4583,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||
}
|
||||
else /* Default key generation. */
|
||||
{
|
||||
int subalgo;
|
||||
int subalgo, version, subversion;
|
||||
unsigned int size, subsize;
|
||||
unsigned int keyuse, subkeyuse;
|
||||
const char *curve, *subcurve;
|
||||
|
@ -4509,18 +4598,19 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||
, "--full-generate-key" );
|
||||
|
||||
err = parse_key_parameter_string (NULL, -1, 0,
|
||||
&algo, &size, &keyuse, &curve,
|
||||
&algo, &size, &keyuse, &curve, &version,
|
||||
&subalgo, &subsize,
|
||||
&subkeyuse, &subcurve);
|
||||
&subkeyuse, &subcurve, &subversion);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
|
||||
return;
|
||||
}
|
||||
para = quickgen_set_para (para, 0, algo, size, curve, keyuse);
|
||||
para = quickgen_set_para (para, 0, algo, size, curve, keyuse, version);
|
||||
if (subalgo)
|
||||
para = quickgen_set_para (para, 1,
|
||||
subalgo, subsize, subcurve, subkeyuse);
|
||||
subalgo, subsize, subcurve, subkeyuse,
|
||||
subversion);
|
||||
|
||||
|
||||
}
|
||||
|
@ -4740,6 +4830,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||
int algo;
|
||||
u32 expire;
|
||||
const char *key_from_hexgrip = NULL;
|
||||
unsigned int keygen_flags;
|
||||
|
||||
if (outctrl->dryrun)
|
||||
{
|
||||
|
@ -4808,9 +4899,14 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||
algo = get_parameter_algo( para, pKEYTYPE, NULL );
|
||||
expire = get_parameter_u32( para, pKEYEXPIRE );
|
||||
key_from_hexgrip = get_parameter_value (para, pKEYGRIP);
|
||||
|
||||
keygen_flags = outctrl->keygen_flags;
|
||||
if (get_parameter_uint (para, pVERSION) == 5)
|
||||
keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
||||
|
||||
if (key_from_hexgrip)
|
||||
err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
|
||||
pub_root, timestamp, expire, 0);
|
||||
pub_root, timestamp, expire, 0, keygen_flags);
|
||||
else if (!card)
|
||||
err = do_create (algo,
|
||||
get_parameter_uint( para, pKEYLENGTH ),
|
||||
|
@ -4818,13 +4914,13 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||
pub_root,
|
||||
timestamp,
|
||||
expire, 0,
|
||||
outctrl->keygen_flags,
|
||||
keygen_flags,
|
||||
get_parameter_passphrase (para),
|
||||
&cache_nonce, NULL);
|
||||
else
|
||||
err = gen_card_key (1, algo,
|
||||
1, pub_root, ×tamp,
|
||||
expire);
|
||||
expire, keygen_flags);
|
||||
|
||||
/* Get the pointer to the generated public key packet. */
|
||||
if (!err)
|
||||
|
@ -4863,7 +4959,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||
if (!err && card && get_parameter (para, pAUTHKEYTYPE))
|
||||
{
|
||||
err = gen_card_key (3, get_parameter_algo( para, pAUTHKEYTYPE, NULL ),
|
||||
0, pub_root, ×tamp, expire);
|
||||
0, pub_root, ×tamp, expire, keygen_flags);
|
||||
if (!err)
|
||||
err = write_keybinding (ctrl, pub_root, pri_psk, NULL,
|
||||
PUBKEY_USAGE_AUTH, timestamp, cache_nonce);
|
||||
|
@ -4875,11 +4971,16 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||
|
||||
s = NULL;
|
||||
key_from_hexgrip = get_parameter_value (para, pSUBKEYGRIP);
|
||||
|
||||
keygen_flags = outctrl->keygen_flags;
|
||||
if (get_parameter_uint (para, pSUBVERSION) == 5)
|
||||
keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
||||
|
||||
if (key_from_hexgrip)
|
||||
err = do_create_from_keygrip (ctrl, subkey_algo, key_from_hexgrip,
|
||||
pub_root, timestamp,
|
||||
get_parameter_u32 (para, pSUBKEYEXPIRE),
|
||||
1);
|
||||
1, keygen_flags);
|
||||
else if (!card || (s = get_parameter_value (para, pCARDBACKUPKEY)))
|
||||
{
|
||||
err = do_create (subkey_algo,
|
||||
|
@ -4888,7 +4989,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||
pub_root,
|
||||
timestamp,
|
||||
get_parameter_u32 (para, pSUBKEYEXPIRE), 1,
|
||||
s ? KEYGEN_FLAG_NO_PROTECTION : outctrl->keygen_flags,
|
||||
s? KEYGEN_FLAG_NO_PROTECTION : keygen_flags,
|
||||
get_parameter_passphrase (para),
|
||||
&cache_nonce, NULL);
|
||||
/* Get the pointer to the generated public subkey packet. */
|
||||
|
@ -4908,7 +5009,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||
}
|
||||
else
|
||||
{
|
||||
err = gen_card_key (2, subkey_algo, 0, pub_root, ×tamp, expire);
|
||||
err = gen_card_key (2, subkey_algo, 0, pub_root, ×tamp, expire,
|
||||
keygen_flags);
|
||||
}
|
||||
|
||||
if (!err)
|
||||
|
@ -5032,13 +5134,15 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
|
|||
const char *algostr, const char *usagestr,
|
||||
const char *expirestr,
|
||||
int *r_algo, unsigned int *r_usage, u32 *r_expire,
|
||||
unsigned int *r_nbits, const char **r_curve)
|
||||
unsigned int *r_nbits, const char **r_curve,
|
||||
int *r_version)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int algo;
|
||||
unsigned int use, nbits;
|
||||
u32 expire;
|
||||
int wantuse;
|
||||
int version = 4;
|
||||
const char *curve = NULL;
|
||||
|
||||
*r_curve = NULL;
|
||||
|
@ -5056,8 +5160,8 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
|
|||
|
||||
err = parse_key_parameter_string (algostr, for_subkey? 1 : 0,
|
||||
usagestr? parse_usagestr (usagestr):0,
|
||||
&algo, &nbits, &use, &curve,
|
||||
NULL, NULL, NULL, NULL);
|
||||
&algo, &nbits, &use, &curve, &version,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -5095,6 +5199,7 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
|
|||
*r_usage = use;
|
||||
*r_expire = expire;
|
||||
*r_nbits = nbits;
|
||||
*r_version = version;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5122,6 +5227,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
|
|||
char *serialno = NULL;
|
||||
char *cache_nonce = NULL;
|
||||
char *passwd_nonce = NULL;
|
||||
int keygen_flags = 0;
|
||||
|
||||
interactive = (!algostr || !usagestr || !expirestr);
|
||||
|
||||
|
@ -5203,10 +5309,16 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
|
|||
}
|
||||
else /* Unattended mode. */
|
||||
{
|
||||
int version;
|
||||
|
||||
err = parse_algo_usage_expire (ctrl, 1, algostr, usagestr, expirestr,
|
||||
&algo, &use, &expire, &nbits, &curve);
|
||||
&algo, &use, &expire, &nbits, &curve,
|
||||
&version);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (version == 5)
|
||||
keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
||||
}
|
||||
|
||||
/* Verify the passphrase now so that we get a cache item for the
|
||||
|
@ -5229,7 +5341,8 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
|
|||
if (key_from_hexgrip)
|
||||
{
|
||||
err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
|
||||
keyblock, cur_time, expire, 1);
|
||||
keyblock, cur_time, expire, 1,
|
||||
keygen_flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5245,7 +5358,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
|
|||
passwd = NULL;
|
||||
|
||||
err = do_create (algo, nbits, curve,
|
||||
keyblock, cur_time, expire, 1, 0,
|
||||
keyblock, cur_time, expire, 1, keygen_flags,
|
||||
passwd, &cache_nonce, &passwd_nonce);
|
||||
}
|
||||
if (err)
|
||||
|
@ -5293,6 +5406,7 @@ generate_card_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock,
|
|||
PKT_public_key *sub_pk = NULL;
|
||||
int algo;
|
||||
struct agent_card_info_s info;
|
||||
int keygen_flags = 0; /* FIXME!!! */
|
||||
|
||||
log_assert (keyno >= 1 && keyno <= 3);
|
||||
|
||||
|
@ -5363,7 +5477,8 @@ generate_card_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock,
|
|||
|
||||
/* Note, that depending on the backend, the card key generation may
|
||||
update CUR_TIME. */
|
||||
err = gen_card_key (keyno, algo, 0, pub_keyblock, &cur_time, expire);
|
||||
err = gen_card_key (keyno, algo, 0, pub_keyblock, &cur_time, expire,
|
||||
keygen_flags);
|
||||
/* Get the pointer to the generated public subkey packet. */
|
||||
if (!err)
|
||||
{
|
||||
|
@ -5409,10 +5524,11 @@ write_keyblock( IOBUF out, KBNODE node )
|
|||
}
|
||||
|
||||
|
||||
/* Note that timestamp is an in/out arg. */
|
||||
/* Note that timestamp is an in/out arg.
|
||||
* FIXME: Does not yet support v5 keys. */
|
||||
static gpg_error_t
|
||||
gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root,
|
||||
u32 *timestamp, u32 expireval)
|
||||
u32 *timestamp, u32 expireval, int keygen_flags)
|
||||
{
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
gpg_error_t err;
|
||||
|
@ -5486,7 +5602,7 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root,
|
|||
}
|
||||
|
||||
pk->timestamp = *timestamp;
|
||||
pk->version = 4;
|
||||
pk->version = (keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4;
|
||||
if (expireval)
|
||||
pk->expiredate = pk->timestamp + expireval;
|
||||
pk->pubkey_algo = algo;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue