Trust stuff works partly.
[gnupg.git] / g10 / keygen.c
index 958be3a..1f932f7 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <errno.h>
 #include <assert.h>
 #include "util.h"
@@ -112,7 +113,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
            break;
     }
     if( !node )
-       log_bug(NULL); /* no user id packet in tree */
+       BUG(); /* no user id packet in tree */
     uid = node->pkt->pkt.user_id;
     /* get the pkc packet from the pub_tree */
     for( kbctx=NULL; (node=walk_kbtree( pub_root, &kbctx)) ; ) {
@@ -120,7 +121,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
            break;
     }
     if( !node )
-       log_bug(NULL);
+       BUG();
     pkc = node->pkt->pkt.public_cert;
 
     /* and make the signature */
@@ -148,12 +149,11 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
     PKT_public_cert *pkc;
     ELG_public_key pk;
     ELG_secret_key sk;
-    unsigned nbytes;
 
     elg_generate( &pk, &sk, nbits );
 
-    skc = m_alloc( sizeof *skc );
-    pkc = m_alloc( sizeof *pkc );
+    skc = m_alloc_clear( sizeof *skc );
+    pkc = m_alloc_clear( sizeof *pkc );
     skc->timestamp = pkc->timestamp = make_timestamp();
     skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/
     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
@@ -216,8 +216,8 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
 
     rsa_generate( &pk, &sk, nbits );
 
-    skc = m_alloc( sizeof *skc );
-    pkc = m_alloc( sizeof *pkc );
+    skc = m_alloc_clear( sizeof *skc );
+    pkc = m_alloc_clear( sizeof *pkc );
     skc->timestamp = pkc->timestamp = make_timestamp();
     skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/
     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_RSA;
@@ -296,8 +296,6 @@ generate_keypair()
     char *pub_fname = NULL;
     char *sec_fname = NULL;
     char *uid = NULL;
-    IOBUF pub_io = NULL;
-    IOBUF sec_io = NULL;
     KBNODE pub_root = NULL;
     KBNODE sec_root = NULL;
     PKT_secret_cert *skc = NULL;
@@ -305,6 +303,7 @@ generate_keypair()
     int rc;
     int algo;
     const char *algo_name;
+    char *aname, *acomment, *amail;
 
   #ifndef TEST_ALGO
     if( opt.batch || opt.answer_yes || opt.answer_no )
@@ -404,27 +403,112 @@ generate_keypair()
     uid = m_alloc(strlen(TEST_UID)+1);
     strcpy(uid, TEST_UID);
   #else
-    tty_printf( "\nYou need a User-ID to identify your key; please use your name and your\n"
-               "email address in this suggested format:\n"
-               "    \"Heinrich Heine <heinrichh@uni-duesseldorf.de>\n" );
+    tty_printf( "\n"
+"You need a User-ID to identify your key; the software constructs the user id\n"
+"from Real Name, Comment and Email Address in this form:\n"
+"    \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n\n" );
     uid = NULL;
+    aname=acomment=amail=NULL;
     for(;;) {
+       char *p;
+
+       if( !aname ) {
+           for(;;) {
+               m_free(aname);
+               aname = tty_get("Real name: ");
+               trim_spaces(aname);
+               tty_kill_prompt();
+               if( strpbrk( aname, "<([])>" ) )
+                   tty_printf("Invalid character in name\n");
+               else if( isdigit(*aname) )
+                   tty_printf("Name may not start with a digit\n");
+               else if( strlen(aname) < 5 )
+                   tty_printf("Name must be at least 5 characters long\n");
+               else
+                   break;
+           }
+       }
+       if( !amail ) {
+           for(;;) {
+               m_free(amail);
+               amail = tty_get("Email address: ");
+               trim_spaces(amail);
+               strlwr(amail);
+               tty_kill_prompt();
+               if( !*amail )
+                   break;   /* no email address is okay */
+               else if( strcspn( amail, "abcdefghijklmnopqrstuvwxyz_-.@" )
+                        || string_count_chr(amail,'@') != 1
+                        || *amail == '@'
+                        || amail[strlen(amail)-1] == '@'
+                        || amail[strlen(amail)-1] == '.'
+                        || strstr(amail, "..") )
+                   tty_printf("Not a valid email address\n");
+               else
+                   break;
+           }
+       }
+       if( !acomment ) {
+           for(;;) {
+               m_free(acomment);
+               acomment = tty_get("Comment: ");
+               trim_spaces(acomment);
+               tty_kill_prompt();
+               if( !*acomment )
+                   break;   /* no comment is okay */
+               else if( strpbrk( acomment, "()" ) )
+                   tty_printf("Invalid character in comment\n");
+               else
+                   break;
+           }
+       }
+
        m_free(uid);
-       tty_printf("\n");
-       uid = tty_get("Your User-ID: ");
-       tty_kill_prompt();
-       if( strlen(uid) < 5 )
-           tty_printf("Please enter a string of at least 5 characters\n");
-       else  {
-           tty_printf("You selected this USER-ID:\n    \"%s\"\n\n", uid);
-           answer = tty_get("Is this correct? ");
+       uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+12+10);
+       p = stpcpy(p, aname );
+       if( *acomment )
+           p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
+       if( *amail )
+           p = stpcpy(stpcpy(stpcpy(p," <"), amail),">");
+
+       /* append a warning if we do not have dev/random
+        * or it is switched into  quick testmode */
+      #ifdef HAVE_DEV_RANDOM
+       if( quick_random_gen(-1) )
+      #endif
+           strcpy(p, " (INSECURE!)" );
+
+
+       tty_printf("You selected this USER-ID:\n    \"%s\"\n\n", uid);
+       for(;;) {
+           answer = tty_get("Edit (N)ame, (C)omment, (E)mail or (O)kay? ");
            tty_kill_prompt();
-           if( answer_is_yes(answer) ) {
-               m_free(answer);
+           if( strlen(answer) > 1 )
+               ;
+           else if( *answer == 'N' || *answer == 'n' ) {
+               m_free(aname); aname = NULL;
+               break;
+           }
+           else if( *answer == 'C' || *answer == 'c' ) {
+               m_free(acomment); acomment = NULL;
+               break;
+           }
+           else if( *answer == 'E' || *answer == 'e' ) {
+               m_free(amail); amail = NULL;
+               break;
+           }
+           else if( *answer == 'O' || *answer == 'o' ) {
+               m_free(aname); aname = NULL;
+               m_free(acomment); acomment = NULL;
+               m_free(amail); amail = NULL;
                break;
            }
            m_free(answer);
        }
+       m_free(answer);
+       if( !amail && !acomment && !amail )
+           break;
+       m_free(uid); uid = NULL;
     }
   #endif
 
@@ -488,7 +572,7 @@ generate_keypair()
     else if( algo == PUBKEY_ALGO_DSA )
        rc = gen_dsa(nbits, pub_root, sec_root, dek, &skc );
     else
-       log_bug(NULL);
+       BUG();
     if( !rc )
        write_uid(pub_root, uid );
     if( !rc )