fingerprints and self signatures added
[gnupg.git] / g10 / keygen.c
1 /* keygen.c - generate a key pair
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * G10 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include "util.h"
28 #include "main.h"
29 #include "packet.h"
30 #include "cipher.h"
31 #include "ttyio.h"
32 #include "options.h"
33
34 #if 0
35   #define TEST_ALGO  1
36   #define TEST_NBITS 256
37   #define TEST_UID   "Karl Test"
38 #endif
39
40
41 static int
42 answer_is_yes( const char *s )
43 {
44     if( !stricmp(s, "yes") )
45         return 1;
46     if( *s == 'y' && !s[1] )
47         return 1;
48     if( *s == 'Y' && !s[1] )
49         return 1;
50     return 0;
51 }
52
53
54 static u16
55 checksum_u16( unsigned n )
56 {
57     u16 a;
58
59     a  = (n >> 8) & 0xff;
60     a |= n & 0xff;
61     return a;
62 }
63
64 static u16
65 checksum( byte *p, unsigned n )
66 {
67     u16 a;
68
69     for(a=0; n; n-- )
70         a += *p++;
71     return a;
72 }
73
74 static u16
75 checksum_mpi( MPI a )
76 {
77     u16 csum;
78     byte *buffer;
79     unsigned nbytes;
80
81     buffer = mpi_get_buffer( a, &nbytes, NULL );
82     csum = checksum_u16( nbytes*8 );
83     csum += checksum( buffer, nbytes );
84     m_free( buffer );
85     return csum;
86 }
87
88
89
90 static void
91 write_uid( IOBUF out, const char *s, PKT_user_id **upkt )
92 {
93     PACKET pkt;
94     size_t n = strlen(s);
95     int rc;
96
97     pkt.pkttype = PKT_USER_ID;
98     pkt.pkt.user_id = m_alloc( sizeof *pkt.pkt.user_id + n - 1 );
99     pkt.pkt.user_id->len = n;
100     strcpy(pkt.pkt.user_id->name, s);
101     if( (rc = build_packet( out, &pkt )) )
102         log_error("build_packet(user_id) failed: %s\n", g10_errstr(rc) );
103     if( upkt ) {
104         *upkt = pkt.pkt.user_id;
105         pkt.pkt.user_id = NULL;
106     }
107     free_packet( &pkt );
108 }
109
110
111 static int
112 write_selfsig( IOBUF out, PKT_public_cert *pkc, PKT_user_id *uid,
113                                                 PKT_secret_cert *skc )
114 {
115     PACKET pkt;
116     PKT_signature *sig;
117     int rc=0;
118
119     if( opt.verbose )
120         log_info("writing self signature\n");
121
122     rc = make_keysig_packet( &sig, pkc, uid, skc, 0x13, DIGEST_ALGO_RMD160 );
123     if( rc ) {
124         log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
125         return rc;
126     }
127
128     pkt.pkttype = PKT_SIGNATURE;
129     pkt.pkt.signature = sig;
130     if( (rc = build_packet( out, &pkt )) )
131         log_error("build_packet(signature) failed: %s\n", g10_errstr(rc) );
132     free_packet( &pkt );
133     return rc;
134 }
135
136
137 #ifdef HAVE_RSA_CIPHER
138 static int
139 gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
140         PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc )
141 {
142     int rc;
143     PACKET pkt1, pkt2;
144     PKT_secret_cert *skc;
145     PKT_public_cert *pkc;
146     RSA_public_key pk;
147     RSA_secret_key sk;
148
149     init_packet(&pkt1);
150     init_packet(&pkt2);
151
152     rsa_generate( &pk, &sk, nbits );
153
154     skc = m_alloc( sizeof *skc );
155     pkc = m_alloc( sizeof *pkc );
156     skc->timestamp = pkc->timestamp = make_timestamp();
157     skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/
158     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_RSA;
159                        memset(&pkc->mfx, 0, sizeof pkc->mfx);
160                        pkc->d.rsa.rsa_n = pk.n;
161                        pkc->d.rsa.rsa_e = pk.e;
162     skc->d.rsa.rsa_n = sk.n;
163     skc->d.rsa.rsa_e = sk.e;
164     skc->d.rsa.rsa_d = sk.d;
165     skc->d.rsa.rsa_p = sk.p;
166     skc->d.rsa.rsa_q = sk.q;
167     skc->d.rsa.rsa_u = sk.u;
168     skc->d.rsa.csum  = checksum_mpi( skc->d.rsa.rsa_d );
169     skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p );
170     skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q );
171     skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_u );
172     if( !dek ) {
173         skc->d.rsa.is_protected = 0;
174         skc->d.rsa.protect_algo = 0;
175     }
176     else {
177         skc->d.rsa.is_protected = 1;
178         skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
179         randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1);
180         skc->d.rsa.csum += checksum( skc->d.rsa.protect.blowfish.iv, 8 );
181         rc = protect_secret_key( skc, dek );
182         if( rc ) {
183             log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
184             goto leave;
185         }
186     }
187
188     pkt1.pkttype = PKT_PUBLIC_CERT;
189     pkt1.pkt.public_cert = pkc;
190     pkt2.pkttype = PKT_SECRET_CERT;
191     pkt2.pkt.secret_cert = skc;
192
193     if( (rc = build_packet( pub_io, &pkt1 )) ) {
194         log_error("build public_cert packet failed: %s\n", g10_errstr(rc) );
195         goto leave;
196     }
197     if( (rc = build_packet( sec_io, &pkt2 )) ) {
198         log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) );
199         goto leave;
200     }
201     *ret_pkc = pkt1.pkt.public_cert;
202     pkt1.pkt.public_cert = NULL;
203     *ret_skc = pkt1.pkt.secret_cert;
204     pkt1.pkt.secret_cert = NULL;
205
206   leave:
207     free_packet(&pkt1);
208     free_packet(&pkt2);
209     return rc;
210 }
211 #endif /*HAVE_RSA_CIPHER*/
212
213 static int
214 gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
215         PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc )
216 {
217     int rc;
218     PACKET pkt1, pkt2;
219     PKT_secret_cert *skc, *unprotected_skc;
220     PKT_public_cert *pkc;
221     ELG_public_key pk;
222     ELG_secret_key sk;
223     unsigned nbytes;
224
225     init_packet(&pkt1);
226     init_packet(&pkt2);
227
228     elg_generate( &pk, &sk, nbits );
229
230     skc = m_alloc( sizeof *skc );
231     pkc = m_alloc( sizeof *pkc );
232     skc->timestamp = pkc->timestamp = make_timestamp();
233     skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/
234     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
235                        memset(&pkc->mfx, 0, sizeof pkc->mfx);
236                        pkc->d.elg.p = pk.p;
237                        pkc->d.elg.g = pk.g;
238                        pkc->d.elg.y = pk.y;
239     skc->d.elg.p = sk.p;
240     skc->d.elg.g = sk.g;
241     skc->d.elg.y = sk.y;
242     skc->d.elg.x = sk.x;
243
244     skc->d.elg.csum = checksum_mpi( skc->d.elg.x );
245     unprotected_skc = copy_secret_cert( NULL, skc );
246     if( !dek ) {
247         skc->d.elg.is_protected = 0;
248         skc->d.elg.protect_algo = 0;
249     }
250     else {
251         skc->d.elg.is_protected = 0;
252         skc->d.elg.protect_algo = CIPHER_ALGO_BLOWFISH;
253         randomize_buffer(skc->d.elg.protect.blowfish.iv, 8, 1);
254         rc = protect_secret_key( skc, dek );
255         if( rc ) {
256             log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
257             goto leave;
258         }
259     }
260
261     pkt1.pkttype = PKT_PUBLIC_CERT;
262     pkt1.pkt.public_cert = pkc;
263     pkt2.pkttype = PKT_SECRET_CERT;
264     pkt2.pkt.secret_cert = skc;
265
266     if( (rc = build_packet( pub_io, &pkt1 )) ) {
267         log_error("build public_cert packet failed: %s\n", g10_errstr(rc) );
268         goto leave;
269     }
270     if( (rc = build_packet( sec_io, &pkt2 )) ) {
271         log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) );
272         goto leave;
273     }
274     *ret_pkc = pkt1.pkt.public_cert;
275     pkt1.pkt.public_cert = NULL;
276     *ret_skc = unprotected_skc;
277     unprotected_skc = NULL;
278
279
280   leave:
281     free_packet(&pkt1);
282     free_packet(&pkt2);
283     if( unprotected_skc )
284         free_secret_cert( unprotected_skc );
285     return rc;
286 }
287
288
289
290 /****************
291  * Generate a keypair
292  */
293 void
294 generate_keypair()
295 {
296     char *answer;
297     unsigned nbits;
298     char *pub_fname = "./pubring.g10";
299     char *sec_fname = "./secring.g10";
300     char *uid = NULL;
301     IOBUF pub_io = NULL;
302     IOBUF sec_io = NULL;
303     PKT_public_cert *pkc = NULL;
304     PKT_secret_cert *skc = NULL;
305     PKT_user_id *upkt = NULL;
306     DEK *dek = NULL;
307     int rc;
308     int algo;
309     const char *algo_name;
310
311   #ifndef TEST_ALGO
312     if( opt.batch || opt.answer_yes || opt.answer_no )
313         log_fatal("Key generation can only be used in interactive mode\n");
314
315     tty_printf("Please select the algorithm to use:\n"
316                "   (1) ElGamal is the suggested one.\n"
317            #ifdef HAVE_RSA_CIPHER
318                "   (2) RSA cannot be used inthe U.S.\n"
319            #endif
320                );
321   #endif
322
323     for(;;) {
324       #ifdef TEST_ALGO
325         algo = TEST_ALGO;
326       #else
327         answer = tty_get("Your selection? (1,2) ");
328         tty_kill_prompt();
329         algo = *answer? atoi(answer): 1;
330         m_free(answer);
331       #endif
332         if( algo == 1 ) {
333             algo = PUBKEY_ALGO_ELGAMAL;
334             algo_name = "ElGamal";
335             break;
336         }
337       #ifdef HAVE_RSA_CIPHER
338         else if( algo == 2 ) {
339             algo = PUBKEY_ALGO_RSA;
340             algo_name = "RSA";
341             break;
342         }
343       #endif
344     }
345
346
347
348     tty_printf("About to generate a new %s keypair.\n"
349           #ifndef TEST_NBITS
350                "              minimum keysize is  768 bits\n"
351                "              default keysize is 1024 bits\n"
352                "    highest suggested keysize is 2048 bits\n"
353           #endif
354                                                              , algo_name );
355     for(;;) {
356       #ifdef TEST_NBITS
357         nbits = TEST_NBITS;
358       #else
359         answer = tty_get("What keysize do you want? (1024) ");
360         tty_kill_prompt();
361         nbits = *answer? atoi(answer): 1024;
362         m_free(answer);
363       #endif
364         if( nbits < 128 ) /* FIXME: change this to 768 */
365             tty_printf("keysize too small; please select a larger one\n");
366         else if( nbits > 2048 ) {
367             tty_printf("Keysizes larger than 2048 are not suggested, because "
368                        "computations take REALLY long!\n");
369             answer = tty_get("Are you sure, that you want this keysize? ");
370             tty_kill_prompt();
371             if( answer_is_yes(answer) ) {
372                 m_free(answer);
373                 tty_printf("Okay, but keep in mind that your monitor "
374                            "and keyboard radiation is also very vulnerable "
375                            "to attacks!\n");
376                 break;
377             }
378             m_free(answer);
379         }
380         else
381             break;
382     }
383     tty_printf("Requested keysize is %u bits\n", nbits );
384     if( (nbits % 32) ) {
385         nbits = ((nbits + 31) / 32) * 32;
386         tty_printf("rounded up to %u bits\n", nbits );
387     }
388
389   #ifdef TEST_UID
390     uid = m_alloc(strlen(TEST_UID)+1);
391     strcpy(uid, TEST_UID);
392   #else
393     tty_printf( "\nYou need a User-ID to identify your key; please use your name and your\n"
394                 "email address in this suggested format:\n"
395                 "    \"Heinrich Heine <heinrichh@uni-duesseldorf.de>\n" );
396     uid = NULL;
397     for(;;) {
398         m_free(uid);
399         tty_printf("\n");
400         uid = tty_get("Your User-ID: ");
401         tty_kill_prompt();
402         if( strlen(uid) < 5 )
403             tty_printf("Please enter a string of at least 5 characters\n");
404         else  {
405             tty_printf("You selected this USER-ID:\n    \"%s\"\n\n", uid);
406             answer = tty_get("Is this correct? ");
407             tty_kill_prompt();
408             if( answer_is_yes(answer) ) {
409                 m_free(answer);
410                 break;
411             }
412             m_free(answer);
413         }
414     }
415   #endif
416
417
418     tty_printf( "You need a Passphrase to protect your secret key.\n\n" );
419
420     dek = m_alloc_secure( sizeof *dek );
421     dek->algo = CIPHER_ALGO_BLOWFISH;
422     rc = make_dek_from_passphrase( dek , 2 );
423     if( rc == -1 ) {
424         m_free(dek); dek = NULL;
425         tty_printf(
426             "You don't what a passphrase - this is probably a *bad* idea!\n"
427             "I will do it anyway.  You can change your passphrase at anytime,\n"
428             "using this program with the option \"--change-passphrase\"\n\n" );
429     }
430     else if( rc ) {
431         m_free(dek); dek = NULL;
432         m_free(uid);
433         log_error("Error getting the passphrase: %s\n", g10_errstr(rc) );
434         return;
435     }
436
437
438     /* now check wether we a are allowed to write the keyrings */
439     if( !(rc=overwrite_filep( pub_fname )) ) {
440         if( !(pub_io = iobuf_create( pub_fname )) )
441             log_error("can't create %s: %s\n", pub_fname, strerror(errno) );
442         else if( opt.verbose )
443             log_info("writing to '%s'\n", pub_fname );
444     }
445     else if( rc != -1 ) {
446         log_error("Oops: overwrite_filep(%s): %s\n", pub_fname, g10_errstr(rc) );
447         m_free(uid);
448         return;
449     }
450     else {
451         m_free(uid);
452         return;
453     }
454     if( !(rc=overwrite_filep( sec_fname )) ) {
455         if( !(sec_io = iobuf_create( sec_fname )) )
456             log_error("can't create %s: %s\n", sec_fname, strerror(errno) );
457         else if( opt.verbose )
458             log_info("writing to '%s'\n", sec_fname );
459     }
460     else if( rc != -1 ) {
461         log_error("Oops: overwrite_filep(%s): %s\n", sec_fname, g10_errstr(rc) );
462         m_free(uid);
463         return;
464     }
465     else {
466         iobuf_cancel(pub_io);
467         m_free(uid);
468         return;
469     }
470
471     write_comment( pub_io, "#public key created by G10 pre-release " VERSION );
472     write_comment( sec_io, "#secret key created by G10 pre-release " VERSION );
473
474     if( algo == PUBKEY_ALGO_ELGAMAL )
475         rc = gen_elg(nbits, pub_io, sec_io, dek, &pkc, &skc);
476   #ifdef HAVE_RSA_CIPHER
477     else if( algo == PUBKEY_ALGO_RSA )
478         rc = gen_rsa(nbits, pub_io, sec_io, dek, &pkc, &skc);
479   #endif
480     else
481         log_bug(NULL);
482     if( !rc )
483         write_uid(pub_io, uid, &upkt );
484     if( !rc )
485         write_uid(sec_io, uid, NULL );
486     if( !rc )
487         rc = write_selfsig(pub_io, pkc, upkt, skc );
488
489     if( rc ) {
490         iobuf_cancel(pub_io);
491         iobuf_cancel(sec_io);
492         tty_printf("Key generation failed: %s\n", g10_errstr(rc) );
493     }
494     else {
495         iobuf_close(pub_io);
496         iobuf_close(sec_io);
497         tty_printf("public and secret key created and signed.\n" );
498     }
499     if( pkc )
500         free_public_cert( pkc );
501     if( skc )
502         free_secret_cert( skc );
503     if( upkt )
504         free_user_id( upkt );
505     m_free(uid);
506     m_free(dek);
507 }
508