aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/keygen.c258
1 files changed, 149 insertions, 109 deletions
diff --git a/g10/keygen.c b/g10/keygen.c
index 98ef29efb..e2bdfc144 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -89,7 +89,8 @@ enum para_name {
pSERIALNO,
pCARDBACKUPKEY,
pHANDLE,
- pKEYSERVER
+ pKEYSERVER,
+ pKEYGRIP
};
struct para_data_s {
@@ -3653,8 +3654,9 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
{ "Preferences", pPREFERENCES },
{ "Revoker", pREVOKER },
{ "Handle", pHANDLE },
- { "Keyserver", pKEYSERVER },
- { NULL, 0 }
+ { "Keyserver", pKEYSERVER },
+ { "Keygrip", pKEYGRIP },
+ { NULL, 0 }
};
IOBUF fp;
byte *line;
@@ -4175,137 +4177,166 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
else if (full) /* Full featured key generation. */
{
int subkey_algo;
- char *curve = NULL;
-
- /* Fixme: To support creating a primary key by keygrip we better
- also define the keyword for the parameter file. Note that
- the subkey case will never be asserted if a keygrip has been
- given. */
- algo = ask_algo (ctrl, 0, &subkey_algo, &use, NULL);
- if (subkey_algo)
+ char *key_from_hexgrip = NULL;
+
+ algo = ask_algo (ctrl, 0, &subkey_algo, &use, &key_from_hexgrip);
+ if (key_from_hexgrip)
{
- /* Create primary and subkey at once. */
- both = 1;
- if (algo == PUBKEY_ALGO_ECDSA
- || algo == PUBKEY_ALGO_EDDSA
- || algo == PUBKEY_ALGO_ECDH)
+ r = xmalloc_clear( sizeof *r + 20 );
+ r->key = pKEYTYPE;
+ sprintf( r->u.value, "%d", algo);
+ r->next = para;
+ para = r;
+
+ if (use)
{
- curve = ask_curve (&algo, &subkey_algo);
- r = xmalloc_clear( sizeof *r + 20 );
- r->key = pKEYTYPE;
- sprintf( r->u.value, "%d", algo);
- r->next = para;
- para = r;
- nbits = 0;
- r = xmalloc_clear (sizeof *r + strlen (curve));
- r->key = pKEYCURVE;
- strcpy (r->u.value, curve);
+ r = xmalloc_clear( sizeof *r + 25 );
+ r->key = pKEYUSAGE;
+ sprintf( r->u.value, "%s%s%s",
+ (use & PUBKEY_USAGE_SIG)? "sign ":"",
+ (use & PUBKEY_USAGE_ENC)? "encrypt ":"",
+ (use & PUBKEY_USAGE_AUTH)? "auth":"" );
r->next = para;
para = r;
}
- else
+
+ r = xmalloc_clear( sizeof *r + 40 );
+ r->key = pKEYGRIP;
+ strcpy (r->u.value, key_from_hexgrip);
+ r->next = para;
+ para = r;
+
+ xfree (key_from_hexgrip);
+ }
+ else
+ {
+ char *curve = NULL;
+
+ if (subkey_algo)
{
+ /* Create primary and subkey at once. */
+ both = 1;
+ if (algo == PUBKEY_ALGO_ECDSA
+ || algo == PUBKEY_ALGO_EDDSA
+ || algo == PUBKEY_ALGO_ECDH)
+ {
+ curve = ask_curve (&algo, &subkey_algo);
+ r = xmalloc_clear( sizeof *r + 20 );
+ r->key = pKEYTYPE;
+ sprintf( r->u.value, "%d", algo);
+ r->next = para;
+ para = r;
+ nbits = 0;
+ r = xmalloc_clear (sizeof *r + strlen (curve));
+ r->key = pKEYCURVE;
+ strcpy (r->u.value, curve);
+ r->next = para;
+ para = r;
+ }
+ else
+ {
+ r = xmalloc_clear( sizeof *r + 20 );
+ r->key = pKEYTYPE;
+ sprintf( r->u.value, "%d", algo);
+ r->next = para;
+ para = r;
+ nbits = ask_keysize (algo, 0);
+ r = xmalloc_clear( sizeof *r + 20 );
+ r->key = pKEYLENGTH;
+ sprintf( r->u.value, "%u", nbits);
+ r->next = para;
+ para = r;
+ }
r = xmalloc_clear( sizeof *r + 20 );
- r->key = pKEYTYPE;
- sprintf( r->u.value, "%d", algo);
+ r->key = pKEYUSAGE;
+ strcpy( r->u.value, "sign" );
r->next = para;
para = r;
- nbits = ask_keysize (algo, 0);
+
r = xmalloc_clear( sizeof *r + 20 );
- r->key = pKEYLENGTH;
- sprintf( r->u.value, "%u", nbits);
+ r->key = pSUBKEYTYPE;
+ sprintf( r->u.value, "%d", subkey_algo);
+ r->next = para;
+ para = r;
+ r = xmalloc_clear( sizeof *r + 20 );
+ r->key = pSUBKEYUSAGE;
+ strcpy( r->u.value, "encrypt" );
r->next = para;
para = r;
- }
- r = xmalloc_clear( sizeof *r + 20 );
- r->key = pKEYUSAGE;
- strcpy( r->u.value, "sign" );
- r->next = para;
- para = r;
-
- r = xmalloc_clear( sizeof *r + 20 );
- r->key = pSUBKEYTYPE;
- sprintf( r->u.value, "%d", subkey_algo);
- r->next = para;
- para = r;
- r = xmalloc_clear( sizeof *r + 20 );
- r->key = pSUBKEYUSAGE;
- strcpy( r->u.value, "encrypt" );
- r->next = para;
- para = r;
- if (algo == PUBKEY_ALGO_ECDSA
- || algo == PUBKEY_ALGO_EDDSA
- || algo == PUBKEY_ALGO_ECDH)
+ if (algo == PUBKEY_ALGO_ECDSA
+ || algo == PUBKEY_ALGO_EDDSA
+ || algo == PUBKEY_ALGO_ECDH)
+ {
+ if (algo == PUBKEY_ALGO_EDDSA
+ && subkey_algo == PUBKEY_ALGO_ECDH)
+ {
+ /* Need to switch to a different curve for the
+ encryption key. */
+ xfree (curve);
+ curve = xstrdup ("Curve25519");
+ }
+ r = xmalloc_clear (sizeof *r + strlen (curve));
+ r->key = pSUBKEYCURVE;
+ strcpy (r->u.value, curve);
+ r->next = para;
+ para = r;
+ }
+ }
+ else /* Create only a single key. */
{
- if (algo == PUBKEY_ALGO_EDDSA
- && subkey_algo == PUBKEY_ALGO_ECDH)
+ /* For ECC we need to ask for the curve before storing the
+ algo because ask_curve may change the algo. */
+ if (algo == PUBKEY_ALGO_ECDSA
+ || algo == PUBKEY_ALGO_EDDSA
+ || algo == PUBKEY_ALGO_ECDH)
{
- /* Need to switch to a different curve for the
- encryption key. */
- xfree (curve);
- curve = xstrdup ("Curve25519");
+ curve = ask_curve (&algo, NULL);
+ r = xmalloc_clear (sizeof *r + strlen (curve));
+ r->key = pKEYCURVE;
+ strcpy (r->u.value, curve);
+ r->next = para;
+ para = r;
}
- r = xmalloc_clear (sizeof *r + strlen (curve));
- r->key = pSUBKEYCURVE;
- strcpy (r->u.value, curve);
+
+ r = xmalloc_clear( sizeof *r + 20 );
+ r->key = pKEYTYPE;
+ sprintf( r->u.value, "%d", algo );
r->next = para;
para = r;
+
+ if (use)
+ {
+ r = xmalloc_clear( sizeof *r + 25 );
+ r->key = pKEYUSAGE;
+ sprintf( r->u.value, "%s%s%s",
+ (use & PUBKEY_USAGE_SIG)? "sign ":"",
+ (use & PUBKEY_USAGE_ENC)? "encrypt ":"",
+ (use & PUBKEY_USAGE_AUTH)? "auth":"" );
+ r->next = para;
+ para = r;
+ }
+ nbits = 0;
}
- }
- else /* Create only a single key. */
- {
- /* For ECC we need to ask for the curve before storing the
- algo because ask_curve may change the algo. */
+
if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH)
{
- curve = ask_curve (&algo, NULL);
- r = xmalloc_clear (sizeof *r + strlen (curve));
- r->key = pKEYCURVE;
- strcpy (r->u.value, curve);
- r->next = para;
- para = r;
+ /* The curve has already been set. */
}
-
- r = xmalloc_clear( sizeof *r + 20 );
- r->key = pKEYTYPE;
- sprintf( r->u.value, "%d", algo );
- r->next = para;
- para = r;
-
- if (use)
+ else
{
- r = xmalloc_clear( sizeof *r + 25 );
- r->key = pKEYUSAGE;
- sprintf( r->u.value, "%s%s%s",
- (use & PUBKEY_USAGE_SIG)? "sign ":"",
- (use & PUBKEY_USAGE_ENC)? "encrypt ":"",
- (use & PUBKEY_USAGE_AUTH)? "auth":"" );
+ nbits = ask_keysize (both? subkey_algo : algo, nbits);
+ r = xmalloc_clear( sizeof *r + 20 );
+ r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
+ sprintf( r->u.value, "%u", nbits);
r->next = para;
para = r;
}
- nbits = 0;
- }
- if (algo == PUBKEY_ALGO_ECDSA
- || algo == PUBKEY_ALGO_EDDSA
- || algo == PUBKEY_ALGO_ECDH)
- {
- /* The curve has already been set. */
- }
- else
- {
- nbits = ask_keysize (both? subkey_algo : algo, nbits);
- r = xmalloc_clear( sizeof *r + 20 );
- r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
- sprintf( r->u.value, "%u", nbits);
- r->next = para;
- para = r;
+ xfree (curve);
}
-
- xfree (curve);
}
else /* Default key generation. */
{
@@ -4547,6 +4578,9 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
int did_sub = 0;
u32 timestamp;
char *cache_nonce = NULL;
+ int algo;
+ u32 expire;
+ const char *key_from_hexgrip = NULL;
if (outctrl->dryrun)
{
@@ -4612,20 +4646,26 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
node of the subkey but that is more work than just to pass the
current timestamp. */
- if (!card)
- err = do_create (get_parameter_algo( para, pKEYTYPE, NULL ),
+ algo = get_parameter_algo( para, pKEYTYPE, NULL );
+ expire = get_parameter_u32( para, pKEYEXPIRE );
+ key_from_hexgrip = get_parameter_value (para, pKEYGRIP);
+ if (key_from_hexgrip)
+ err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
+ pub_root, timestamp, expire, 0);
+ else if (!card)
+ err = do_create (algo,
get_parameter_uint( para, pKEYLENGTH ),
get_parameter_value (para, pKEYCURVE),
pub_root,
timestamp,
- get_parameter_u32( para, pKEYEXPIRE ), 0,
+ expire, 0,
outctrl->keygen_flags,
get_parameter_passphrase (para),
&cache_nonce, NULL);
else
- err = gen_card_key (1, get_parameter_algo( para, pKEYTYPE, NULL ),
+ err = gen_card_key (1, algo,
1, pub_root, &timestamp,
- get_parameter_u32 (para, pKEYEXPIRE));
+ expire);
/* Get the pointer to the generated public key packet. */
if (!err)