another s/unsigned char*/byte*/
[gnupg.git] / g10 / keygen.c
index bbda875..c53256c 100644 (file)
@@ -64,7 +64,8 @@ enum para_name {
   pPASSPHRASE_DEK,
   pPASSPHRASE_S2K,
   pSERIALNO,
-  pBACKUPENCDIR
+  pBACKUPENCDIR,
+  pHANDLE
 };
 
 struct para_data_s {
@@ -162,6 +163,49 @@ copy_mpi (MPI a, unsigned char *buffer, size_t len, size_t *ncopied)
 #endif /* ENABLE_CARD_SUPPORT */
 
 
+
+static void
+print_status_key_created (int letter, PKT_public_key *pk, const char *handle)
+{
+  byte array[MAX_FINGERPRINT_LEN], *s;
+  char *buf, *p;
+  size_t i, n;
+  
+  if (!handle)
+    handle = "";
+
+  buf = xmalloc (MAX_FINGERPRINT_LEN*2+31 + strlen (handle) + 1);
+
+  p = buf;
+  if (letter || pk)
+    {
+      *p++ = letter;
+      *p++ = ' ';
+      fingerprint_from_pk (pk, array, &n);
+      s = array;
+      for (i=0; i < n ; i++, s++, p += 2)
+        sprintf (p, "%02X", *s);
+    }
+  if (*handle)
+    {
+      *p++ = ' ';
+      for (i=0; handle[i] && i < 100; i++)
+        *p++ = isspace ((unsigned int)handle[i])? '_':handle[i];
+    }
+  *p = 0;
+  write_status_text ((letter || pk)?STATUS_KEY_CREATED:STATUS_KEY_NOT_CREATED,
+                     buf);
+  xfree (buf);
+}
+
+static void
+print_status_key_not_created (const char *handle)
+{
+  print_status_key_created (0, NULL, handle);
+}
+
+
+
 static void
 write_uid( KBNODE root, const char *s )
 {
@@ -1400,12 +1444,13 @@ ask_keysize( int algo )
                _("Keysizes larger than 2048 are not suggested because\n"
                  "computations take REALLY long!\n"));
            if( cpr_get_answer_is_yes("keygen.size.huge.okay",_(
-                       "Are you sure that you want this keysize? ")) ) {
+                       "Are you sure that you want this keysize? (y/N) ")) )
+             {
                tty_printf(_("Okay, but keep in mind that your monitor "
                             "and keyboard radiation is also very vulnerable "
                             "to attacks!\n"));
                break;
-           }
+             }
        }
        else
            break;
@@ -1529,7 +1574,7 @@ ask_expire_interval(int object)
        }
 
        if( cpr_enabled() || cpr_get_answer_is_yes("keygen.valid.okay",
-                                           _("Is this correct (y/n)? ")) )
+                                           _("Is this correct? (y/N) ")) )
            break;
     }
     m_free(answer);
@@ -2018,7 +2063,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
     char *p;
     int i;
 
-    /* check that we have all required parameters */
+    /* Check that we have all required parameters. */
     assert( get_parameter( para, pKEYTYPE ) );
     i = get_parameter_algo( para, pKEYTYPE );
     if( i < 1 || check_pubkey_algo2( i, PUBKEY_USAGE_SIG ) ) {
@@ -2129,7 +2174,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
 
 /****************
  * Kludge to allow non interactive key generation controlled
- * by a parameter file (which currently is only stdin)
+ * by a parameter file.
  * Note, that string parameters are expected to be in UTF-8
  */
 static void
@@ -2151,10 +2196,13 @@ read_parameter_file( const char *fname )
        { "Passphrase",     pPASSPHRASE },
        { "Preferences",    pPREFERENCES },
        { "Revoker",        pREVOKER },
+        { "Handle",         pHANDLE },
        { NULL, 0 }
     };
-    FILE *fp;
-    char line[1024], *p;
+    IOBUF fp;
+    byte *line;
+    unsigned int maxlen, nline;
+    char *p;
     int lnr;
     const char *err = NULL;
     struct para_data_s *para, *r;
@@ -2163,26 +2211,32 @@ read_parameter_file( const char *fname )
 
     memset( &outctrl, 0, sizeof( outctrl ) );
 
-    if( !fname || !*fname || !strcmp(fname,"-") ) {
-       fp = stdin;
-       fname = "-";
-    }
-    else {
-       fp = fopen( fname, "r" );
-       if( !fp ) {
-           log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
-           return;
-       }
+    if( !fname || !*fname)
+      fname = "-";
+
+    fp = iobuf_open (fname);
+    if (fp && is_secured_file (iobuf_get_fd (fp)))
+      {
+        iobuf_close (fp);
+        fp = NULL;
+        errno = EPERM;
+      }
+    if (!fp) {
+      log_error (_("can't open `%s': %s\n"), fname, strerror(errno) );
+      return;
     }
+    iobuf_ioctl (fp, 3, 1, NULL); /* No file caching. */
 
     lnr = 0;
     err = NULL;
     para = NULL;
-    while( fgets( line, DIM(line)-1, fp ) ) {
+    maxlen = 1024;
+    line = NULL;
+    while ( iobuf_read_line (fp, &line, &nline, &maxlen) ) {
        char *keyword, *value;
 
        lnr++;
-       if( *line && line[strlen(line)-1] != '\n' ) {
+       if( !maxlen ) {
            err = "line too long";
            break;
        }
@@ -2206,7 +2260,9 @@ read_parameter_file( const char *fname )
                outctrl.dryrun = 1;
            else if( !ascii_strcasecmp( keyword, "%commit" ) ) {
                outctrl.lnr = lnr;
-               proc_parameter_file( para, fname, &outctrl, 0 );
+               if (proc_parameter_file( para, fname, &outctrl, 0 ))
+                  print_status_key_not_created 
+                    (get_parameter_value (para, pHANDLE));
                release_parameter_list( para );
                para = NULL;
            }
@@ -2266,7 +2322,9 @@ read_parameter_file( const char *fname )
 
        if( keywords[i].key == pKEYTYPE && para ) {
            outctrl.lnr = lnr;
-           proc_parameter_file( para, fname, &outctrl, 0 );
+           if (proc_parameter_file( para, fname, &outctrl, 0 ))
+              print_status_key_not_created
+                (get_parameter_value (para, pHANDLE));
            release_parameter_list( para );
            para = NULL;
        }
@@ -2289,12 +2347,13 @@ read_parameter_file( const char *fname )
     }
     if( err )
        log_error("%s:%d: %s\n", fname, lnr, err );
-    else if( ferror(fp) ) {
-       log_error("%s:%d: read error: %s\n", fname, lnr, strerror(errno) );
+    else if( iobuf_error (fp) ) {
+       log_error("%s:%d: read error\n", fname, lnr);
     }
     else if( para ) {
        outctrl.lnr = lnr;
-       proc_parameter_file( para, fname, &outctrl, 0 );
+       if (proc_parameter_file( para, fname, &outctrl, 0 ))
+          print_status_key_not_created (get_parameter_value (para, pHANDLE));
     }
 
     if( outctrl.use_files ) { /* close open streams */
@@ -2314,8 +2373,7 @@ read_parameter_file( const char *fname )
     }
 
     release_parameter_list( para );
-    if( strcmp( fname, "-" ) )
-       fclose(fp);
+    iobuf_close (fp);
 }
 
 
@@ -2598,24 +2656,6 @@ generate_raw_key (int algo, unsigned int nbits, u32 created_at,
 
 
 static void
-print_status_key_created (int letter, PKT_public_key *pk)
-{
-  byte array[MAX_FINGERPRINT_LEN], *s;
-  char buf[MAX_FINGERPRINT_LEN*2+30], *p;
-  size_t i, n;
-  
-  p = buf;
-  *p++ = letter;
-  *p++ = ' ';
-  fingerprint_from_pk (pk, array, &n);
-  s = array;
-  for (i=0; i < n ; i++, s++, p += 2)
-    sprintf (p, "%02X", *s);
-  *p = 0;
-  write_status_text (STATUS_KEY_CREATED, buf);
-}
-
-static void
 do_generate_keypair( struct para_data_s *para,
                     struct output_control_s *outctrl, int card )
 {
@@ -2643,9 +2683,14 @@ do_generate_keypair( struct para_data_s *para,
            outctrl->pub.fname =  outctrl->pub.newfname;
            outctrl->pub.newfname = NULL;
 
-           outctrl->pub.stream = iobuf_create( outctrl->pub.fname );
+            if (is_secured_filename (outctrl->pub.fname) ) {
+                outctrl->pub.stream = NULL;
+                errno = EPERM;
+            }
+            else
+                outctrl->pub.stream = iobuf_create( outctrl->pub.fname );
            if( !outctrl->pub.stream ) {
-               log_error("can't create `%s': %s\n", outctrl->pub.newfname,
+               log_error(_("can't create `%s': %s\n"), outctrl->pub.newfname,
                                                     strerror(errno) );
                return;
            }
@@ -2667,10 +2712,15 @@ do_generate_keypair( struct para_data_s *para,
            outctrl->sec.newfname = NULL;
 
            oldmask = umask (077);
-           outctrl->sec.stream = iobuf_create( outctrl->sec.fname );
+            if (is_secured_filename (outctrl->sec.fname) ) {
+                outctrl->sec.stream = NULL;
+                errno = EPERM;
+            }
+            else
+                outctrl->sec.stream = iobuf_create( outctrl->sec.fname );
             umask (oldmask);
            if( !outctrl->sec.stream ) {
-               log_error("can't create `%s': %s\n", outctrl->sec.newfname,
+               log_error(_("can't create `%s': %s\n"), outctrl->sec.newfname,
                                                     strerror(errno) );
                return;
            }
@@ -2887,11 +2937,13 @@ do_generate_keypair( struct para_data_s *para,
            log_error("key generation failed: %s\n", g10_errstr(rc) );
        else
            tty_printf(_("Key generation failed: %s\n"), g10_errstr(rc) );
+        print_status_key_not_created ( get_parameter_value (para, pHANDLE) );
     }
     else {
         PKT_public_key *pk = find_kbnode (pub_root, 
                                     PKT_PUBLIC_KEY)->pkt->pkt.public_key;
-        print_status_key_created (did_sub? 'B':'P', pk);
+        print_status_key_created (did_sub? 'B':'P', pk,
+                                  get_parameter_value (para, pHANDLE));
     }
     release_kbnode( pub_root );
     release_kbnode( sec_root );
@@ -2974,7 +3026,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
     nbits = ask_keysize( algo );
     expire = ask_expire_interval(0);
     if( !cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
-                                                 _("Really create? ") ) )
+                                                 _("Really create? (y/N) ")))
        goto leave;
 
     if( passphrase ) {
@@ -3096,7 +3148,7 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
   else
     use = PUBKEY_USAGE_AUTH;
   if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.cardsub.okay",
-                                               _("Really create? ") ) )
+                                               _("Really create? (y/N) ")))
     goto leave;
 
   if (passphrase)
@@ -3286,7 +3338,13 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
 
     fname = make_filename (backup_dir, name_buffer, NULL);
     oldmask = umask (077);
-    fp = iobuf_create (fname);
+    if (is_secured_filename (fname))
+      {
+        fp = NULL;
+        errno = EPERM;
+      }
+    else
+      fp = iobuf_create (fname);
     umask (oldmask);
     if (!fp) 
       {