* keygen.c (generate_subkeypair): Detect primary key on-card and
authorWerner Koch <wk@gnupg.org>
Thu, 27 Jan 2005 11:48:33 +0000 (11:48 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 27 Jan 2005 11:48:33 +0000 (11:48 +0000)
ask for the passphrase.  Return an error if the primary key is a
plain stub.

* keyedit.c (change_passphrase): Don't ever change any stub key.
Print a note if a key consists of only stub keys.  Reported by
Dany Nativel.  These are bugs #401 and #402.

g10/ChangeLog
g10/keyedit.c
g10/keygen.c

index 96dcd0c..74adadb 100644 (file)
@@ -1,3 +1,13 @@
+2005-01-27  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (generate_subkeypair): Detect primary key on-card and
+       ask for the passphrase.  Return an error if the primary key is a
+       plain stub.
+
+       * keyedit.c (change_passphrase): Don't ever change any stub key.
+       Print a note if a key consists of only stub keys.  Reported by
+       Dany Nativel.  These are bugs #401 and #402.
+
 2005-01-26  Werner Koch  <wk@g10code.com>
 
        * ccid-driver.c (parse_ccid_descriptor): Need the CSM workaround
index 39a5a65..84fc6d4 100644 (file)
@@ -1069,6 +1069,7 @@ change_passphrase( KBNODE keyblock )
     PKT_secret_key *sk;
     char *passphrase = NULL;
     int no_primary_secrets = 0;
+    int any;
 
     node = find_kbnode( keyblock, PKT_SECRET_KEY );
     if( !node ) {
@@ -1077,6 +1078,25 @@ change_passphrase( KBNODE keyblock )
     }
     sk = node->pkt->pkt.secret_key;
 
+    for (any = 0, node=keyblock; node; node = node->next) {
+       if (node->pkt->pkttype == PKT_SECRET_KEY 
+            || node->pkt->pkttype == PKT_SECRET_SUBKEY) {
+           PKT_secret_key *tmpsk = node->pkt->pkt.secret_key;
+            if (!(tmpsk->is_protected
+                  && (tmpsk->protect.s2k.mode == 1001 
+                      || tmpsk->protect.s2k.mode == 1002))) {
+                any = 1;
+                break;
+            }
+        }
+    }
+    if (!any) {
+        tty_printf (_("Key has only stub or on-card key items - "
+                      "no passphrase to change.\n"));
+        goto leave;
+    }
+        
+    /* See how to handle this key.  */
     switch( is_secret_key_protected( sk ) ) {
       case -1:
        rc = G10ERR_PUBKEY_ALGO;
@@ -1089,6 +1109,10 @@ change_passphrase( KBNODE keyblock )
            tty_printf(_("Secret parts of primary key are not available.\n"));
            no_primary_secrets = 1;
        }
+       else if( sk->protect.s2k.mode == 1002 ) {
+           tty_printf(_("Secret parts of primary key are store on-card.\n"));
+           no_primary_secrets = 1;
+       }
        else {
            tty_printf(_("Key is protected.\n"));
            rc = check_secret_key( sk, 0 );
@@ -1098,14 +1122,18 @@ change_passphrase( KBNODE keyblock )
        break;
     }
 
-    /* unprotect all subkeys (use the supplied passphrase or ask)*/
+    /* Unprotect all subkeys (use the supplied passphrase or ask)*/
     for(node=keyblock; !rc && node; node = node->next ) {
        if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
            PKT_secret_key *subsk = node->pkt->pkt.secret_key;
-           set_next_passphrase( passphrase );
-           rc = check_secret_key( subsk, 0 );
-           if( !rc && !passphrase )
-               passphrase = get_last_passphrase();
+            if ( !(subsk->is_protected
+                   && (subsk->protect.s2k.mode == 1001 
+                       || subsk->protect.s2k.mode == 1002))) {
+                set_next_passphrase( passphrase );
+                rc = check_secret_key( subsk, 0 );
+                if( !rc && !passphrase )
+                    passphrase = get_last_passphrase();
+            }
        }
     }
 
@@ -1149,13 +1177,18 @@ change_passphrase( KBNODE keyblock )
                for(node=keyblock; !rc && node; node = node->next ) {
                    if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
                        PKT_secret_key *subsk = node->pkt->pkt.secret_key;
-                       subsk->protect.algo = dek->algo;
-                       subsk->protect.s2k = *s2k;
-                       rc = protect_secret_key( subsk, dek );
+                        if ( !(subsk->is_protected
+                               && (subsk->protect.s2k.mode == 1001 
+                                   || subsk->protect.s2k.mode == 1002))) {
+                            subsk->protect.algo = dek->algo;
+                            subsk->protect.s2k = *s2k;
+                            rc = protect_secret_key( subsk, dek );
+                        }
                    }
                }
                if( rc )
-                   log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
+                   log_error("protect_secret_key failed: %s\n",
+                              g10_errstr(rc) );
                else
                    changed++;
                break;
index a20c48c..29f1fc6 100644 (file)
@@ -1,6 +1,6 @@
 /* keygen.c - generate a key pair
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- *               2004 Free Software Foundation, Inc.
+ *               2004, 2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -3002,6 +3002,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
     DEK *dek = NULL;
     STRING2KEY *s2k = NULL;
     u32 cur_time;
+    int ask_pass = 0;
 
     /* break out the primary secret key */
     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
@@ -3032,20 +3033,31 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
        goto leave;
     }
 
-    /* unprotect to get the passphrase */
+    if (pri_sk->is_protected && pri_sk->protect.s2k.mode == 1001) {
+        tty_printf(_("Secret parts of primary key are not available.\n"));
+        rc = G10ERR_NO_SECKEY;
+        goto leave;
+    }
+
+
+    /* Unprotect to get the passphrase.  */
     switch( is_secret_key_protected( pri_sk ) ) {
       case -1:
        rc = G10ERR_PUBKEY_ALGO;
        break;
       case 0:
-       tty_printf("This key is not protected.\n");
+       tty_printf(_("This key is not protected.\n"));
        break;
+      case -2:
+        tty_printf(_("Secret parts of primary key are store on-card.\n"));
+        ask_pass = 1;
+        break;
       default:
-       tty_printf("Key is protected.\n");
-       rc = check_secret_key( pri_sk, 0 );
-       if( !rc )
-           passphrase = get_last_passphrase();
-       break;
+        tty_printf(_("Key is protected.\n"));
+        rc = check_secret_key( pri_sk, 0 );
+        if( !rc )
+            passphrase = get_last_passphrase();
+        break;
     }
     if( rc )
        goto leave;
@@ -3058,7 +3070,9 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
                                                  _("Really create? (y/N) ")))
        goto leave;
 
-    if( passphrase ) {
+    if (ask_pass)
+        dek = do_ask_passphrase (&s2k);
+    else if (passphrase) {
        s2k = m_alloc_secure( sizeof *s2k );
        s2k->mode = opt.s2k_mode;
        s2k->hash_algo = S2K_DIGEST_ALGO;