* keygen.c (keygen_set_std_prefs): Add SHA256 and BZip2 to default
[gnupg.git] / g10 / keygen.c
index abef681..26f3cc6 100644 (file)
@@ -1,6 +1,6 @@
 /* keygen.c - generate a key pair
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- *               2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+ *               2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -325,7 +325,7 @@ keygen_set_std_prefs (const char *string,int personal)
     byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS];
     int nsym=0, nhash=0, nzip=0, val, rc=0;
     int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */
-    char dummy_string[45]; /* enough for 15 items */
+    char dummy_string[45+1]; /* Enough for 15 items. */
 
     if (!string || !ascii_strcasecmp (string, "default"))
       {
@@ -335,8 +335,21 @@ keygen_set_std_prefs (const char *string,int personal)
          {
            dummy_string[0]='\0';
 
+            /* The rationale why we use the order AES256,192,128 is
+               for compatibility reasons with PGP.  If gpg would
+               define AES128 first, we would get the somewhat
+               confusing situation:
+
+                 gpg -r pgpkey -r gpgkey  ---gives--> AES256
+                 gpg -r gpgkey -r pgpkey  ---gives--> AES
+                 
+               Note that by using --personal-cipher-preferences it is
+               possible to prefer AES128.
+            */
+
            /* Make sure we do not add more than 15 items here, as we
-              could overflow the size of dummy_string. */
+              could overflow the size of dummy_string.  We currently
+              have at most 12. */
            if(!check_cipher_algo(CIPHER_ALGO_AES256))
              strcat(dummy_string,"S9 ");
            if(!check_cipher_algo(CIPHER_ALGO_AES192))
@@ -356,8 +369,23 @@ keygen_set_std_prefs (const char *string,int personal)
            if(!check_cipher_algo(CIPHER_ALGO_IDEA))
              strcat(dummy_string,"S1 ");
 
-           /* SHA-1, RIPEMD160, ZLIB, ZIP */
-           strcat(dummy_string,"H2 H3 Z2 Z1");
+           /* SHA-1 */
+           strcat(dummy_string,"H2 ");
+
+           if(!check_digest_algo(DIGEST_ALGO_SHA256))
+             strcat(dummy_string,"H8 ");
+
+           /* RIPEMD160 */
+           strcat(dummy_string,"H3 ");
+
+           /* ZLIB */
+           strcat(dummy_string,"Z2 ");
+
+           if(!check_compress_algo(COMPRESS_ALGO_BZIP2))
+             strcat(dummy_string,"Z3 ");
+
+           /* ZIP */
+           strcat(dummy_string,"Z1");
 
            string=dummy_string;
          }
@@ -1486,7 +1514,7 @@ ask_keysize( int algo )
  * Parse an expire string and return it's value in days.
  * Returns -1 on error.
  */
-static int
+int
 parse_expire_string( const char *string )
 {
     int mult;
@@ -1518,7 +1546,7 @@ parse_expire_string( const char *string )
 
 /* object == 0 for a key, and 1 for a sig */
 u32
-ask_expire_interval(int object)
+ask_expire_interval(int object,const char *def_expire)
 {
     char *answer;
     int valid_days=0;
@@ -1527,6 +1555,8 @@ ask_expire_interval(int object)
     switch(object)
       {
       case 0:
+       if(def_expire)
+         BUG();
        tty_printf(_("Please specify how long the key should be valid.\n"
                     "         0 = key does not expire\n"
                     "      <n>  = key expires in n days\n"
@@ -1536,6 +1566,8 @@ ask_expire_interval(int object)
        break;
 
       case 1:
+       if(!def_expire)
+         BUG();
        tty_printf(_("Please specify how long the signature should be valid.\n"
                     "         0 = signature does not expire\n"
                     "      <n>  = signature expires in n days\n"
@@ -1553,20 +1585,36 @@ ask_expire_interval(int object)
      * date */
 
     answer = NULL;
-    for(;;) {
+    for(;;)
+      {
        u32 curtime=make_timestamp();
 
        m_free(answer);
        if(object==0)
          answer = cpr_get("keygen.valid",_("Key is valid for? (0) "));
        else
-         answer = cpr_get("siggen.valid",_("Signature is valid for? (0) "));
+         {
+           char *prompt;
+
+#define PROMPTSTRING _("Signature is valid for? (%s) ")
+           /* This will actually end up larger than necessary because
+              of the 2 bytes for '%s' */
+           prompt=m_alloc(strlen(PROMPTSTRING)+strlen(def_expire)+1);
+           sprintf(prompt,PROMPTSTRING,def_expire);
+#undef PROMPTSTRING
+
+           answer = cpr_get("siggen.valid",prompt);
+           m_free(prompt);
+
+           if(*answer=='\0')
+             answer=m_strdup(def_expire);
+         }
        cpr_kill_prompt();
        trim_spaces(answer);
        valid_days = parse_expire_string( answer );
        if( valid_days < 0 ) {
-           tty_printf(_("invalid value\n"));
-           continue;
+         tty_printf(_("invalid value\n"));
+         continue;
        }
 
        if( !valid_days )
@@ -1577,24 +1625,24 @@ ask_expire_interval(int object)
            interval = 0;
          }
        else {
-           interval = valid_days * 86400L;
-
-           tty_printf(object==0
-                       ? _("Key expires at %s\n")
-                      : _("Signature expires at %s\n"),
-                       asctimestamp((ulong)(curtime + interval) ) );
-            /* FIXME: This check yields warning on alhas: Write a
-               configure check and to this check here only for 32 bit
-               machines */
-           if( (time_t)((ulong)(curtime+interval)) < 0 )
-               tty_printf(_("Your system can't display dates beyond 2038.\n"
-                   "However, it will be correctly handled up to 2106.\n"));
+         interval = valid_days * 86400L;
+
+         tty_printf(object==0
+                    ? _("Key expires at %s\n")
+                    : _("Signature expires at %s\n"),
+                    asctimestamp((ulong)(curtime + interval) ) );
+         /* FIXME: This check yields warning on alhas: Write a
+            configure check and to this check here only for 32 bit
+            machines */
+         if( (time_t)((ulong)(curtime+interval)) < 0 )
+           tty_printf(_("Your system can't display dates beyond 2038.\n"
+                        "However, it will be correctly handled up to 2106.\n"));
        }
 
        if( cpr_enabled() || cpr_get_answer_is_yes("keygen.valid.okay",
-                                           _("Is this correct? (y/N) ")) )
-           break;
-    }
+                                                  _("Is this correct? (y/N) ")) )
+         break;
+      }
     m_free(answer);
     return interval;
 }
@@ -1602,7 +1650,7 @@ ask_expire_interval(int object)
 u32
 ask_expiredate()
 {
-    u32 x = ask_expire_interval(0);
+    u32 x = ask_expire_interval(0,NULL);
     return x? make_timestamp() + x : 0;
 }
 
@@ -1636,7 +1684,8 @@ ask_user_id( int mode )
 
     if( !mode )
        tty_printf( _("\n"
-"You need a user ID to identify your key; the software constructs the user ID\n"
+"You need a user ID to identify your key; "
+                                        "the software constructs the user ID\n"
 "from the Real Name, Comment and Email Address in this form:\n"
 "    \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\n\n") );
     uid = aname = acomment = amail = NULL;
@@ -1731,7 +1780,7 @@ ask_user_id( int mode )
        }
 
        for(;;) {
-            /* Note to translators: These are the allowed answers in
+            /* TRANSLATORS: These are the allowed answers in
                lower and uppercase.  Below you will find the matching
                string which should be translated accordingly and the
                letter changed to match the one in the answer string.
@@ -2559,7 +2608,7 @@ generate_keypair (const char *fname, const char *card_serialno,
       para = r;
     }
    
-  expire = ask_expire_interval(0);
+  expire = ask_expire_interval(0,NULL);
   r = m_alloc_clear( sizeof *r + 20 );
   r->key = pKEYEXPIRE;
   r->u.expire = expire;
@@ -3072,7 +3121,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
     algo = ask_algo( 1, &use );
     assert(algo);
     nbits = ask_keysize( algo );
-    expire = ask_expire_interval(0);
+    expire = ask_expire_interval(0,NULL);
     if( !cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
                                                  _("Really create? (y/N) ")))
        goto leave;
@@ -3190,7 +3239,7 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
     goto leave;
 
   algo = PUBKEY_ALGO_RSA;
-  expire = ask_expire_interval (0);
+  expire = ask_expire_interval (0,NULL);
   if (keyno == 1)
     use = PUBKEY_USAGE_SIG;
   else if (keyno == 2)
@@ -3419,9 +3468,25 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
       }
     else
       {
+        byte array[MAX_FINGERPRINT_LEN];
+        char *fprbuf, *p;
+       
         iobuf_close (fp);
         iobuf_ioctl (NULL, 2, 0, (char*)fname);
         log_info (_("NOTE: backup of card key saved to `%s'\n"), fname);
+
+        fingerprint_from_sk (sk, array, &n);
+        p = fprbuf = xmalloc (MAX_FINGERPRINT_LEN*2 + 1 + 1);
+        for (i=0; i < n ; i++, p += 2)
+          sprintf (p, "%02X", array[i]);
+        *p++ = ' ';
+        *p = 0;
+
+        write_status_text_and_buffer (STATUS_BACKUP_KEY_CREATED,
+                                      fprbuf,
+                                      fname, strlen (fname),
+                                      0);
+        xfree (fprbuf);
       }
     free_packet (pkt);
     m_free (pkt);