applied Mathews typo and grammar fixes
[gnupg.git] / g10 / keygen.c
1 /* keygen.c - generate a key pair
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GNUPG.
5  *
6  * GNUPG 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  * GNUPG 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 <ctype.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include "util.h"
29 #include "main.h"
30 #include "packet.h"
31 #include "cipher.h"
32 #include "ttyio.h"
33 #include "options.h"
34 #include "keydb.h"
35 #include "i18n.h"
36
37
38 #if defined(HAVE_RSA_CIPHER) && 0
39   #define ENABLE_RSA_KEYGEN 1
40 #endif
41
42
43 static void
44 write_uid( KBNODE root, const char *s )
45 {
46     PACKET *pkt = m_alloc_clear(sizeof *pkt );
47     size_t n = strlen(s);
48
49     pkt->pkttype = PKT_USER_ID;
50     pkt->pkt.user_id = m_alloc( sizeof *pkt->pkt.user_id + n - 1 );
51     pkt->pkt.user_id->len = n;
52     strcpy(pkt->pkt.user_id->name, s);
53     add_kbnode( root, new_kbnode( pkt ) );
54 }
55
56
57 static int
58 write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
59 {
60     PACKET *pkt;
61     PKT_signature *sig;
62     PKT_user_id *uid;
63     int rc=0;
64     KBNODE node;
65     PKT_public_cert *pkc;
66
67     if( opt.verbose )
68         log_info(_("writing self signature\n"));
69
70     /* get the uid packet from the list */
71     node = find_kbnode( root, PKT_USER_ID );
72     if( !node )
73         BUG(); /* no user id packet in tree */
74     uid = node->pkt->pkt.user_id;
75     /* get the pkc packet from the pub_tree */
76     node = find_kbnode( pub_root, PKT_PUBLIC_CERT );
77     if( !node )
78         BUG();
79     pkc = node->pkt->pkt.public_cert;
80
81     /* and make the signature */
82     rc = make_keysig_packet( &sig, pkc, uid, skc, 0x13, DIGEST_ALGO_RMD160 );
83     if( rc ) {
84         log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
85         return rc;
86     }
87
88     pkt = m_alloc_clear( sizeof *pkt );
89     pkt->pkttype = PKT_SIGNATURE;
90     pkt->pkt.signature = sig;
91     add_kbnode( root, new_kbnode( pkt ) );
92     return rc;
93 }
94
95
96 static int
97 gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
98         byte *salt, PKT_secret_cert **ret_skc, u16 valid_days )
99 {
100     int rc;
101     int i;
102     PACKET *pkt;
103     PKT_secret_cert *skc;
104     PKT_public_cert *pkc;
105     ELG_public_key pk;
106     ELG_secret_key sk;
107     MPI *factors;
108
109     elg_generate( &pk, &sk, nbits, &factors );
110
111     skc = m_alloc_clear( sizeof *skc );
112     pkc = m_alloc_clear( sizeof *pkc );
113     skc->timestamp = pkc->timestamp = make_timestamp();
114     skc->valid_days = pkc->valid_days = valid_days;
115     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
116                        pkc->d.elg.p = pk.p;
117                        pkc->d.elg.g = pk.g;
118                        pkc->d.elg.y = pk.y;
119     skc->d.elg.p = sk.p;
120     skc->d.elg.g = sk.g;
121     skc->d.elg.y = sk.y;
122     skc->d.elg.x = sk.x;
123     skc->is_protected = 0;
124     skc->protect.algo = 0;
125
126     skc->csum = checksum_mpi( skc->d.elg.x );
127     /* return an unprotected version of the skc */
128     *ret_skc = copy_secret_cert( NULL, skc );
129
130     if( dek ) {
131         skc->protect.algo = CIPHER_ALGO_BLOWFISH;
132         skc->protect.s2k  = 1;
133         skc->protect.hash = DIGEST_ALGO_RMD160;
134         memcpy(skc->protect.salt, salt, 8);
135         randomize_buffer(skc->protect.iv, 8, 1);
136         rc = protect_secret_key( skc, dek );
137         if( rc ) {
138             log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
139             free_public_cert(pkc);
140             free_secret_cert(skc);
141             return rc;
142         }
143     }
144
145     pkt = m_alloc_clear(sizeof *pkt);
146     pkt->pkttype = PKT_PUBLIC_CERT;
147     pkt->pkt.public_cert = pkc;
148     add_kbnode(pub_root, new_kbnode( pkt ));
149
150     /* don't know whether it makes sense to have the factors, so for now
151      * we store them in the secret keyring (but they are secret) */
152     pkt = m_alloc_clear(sizeof *pkt);
153     pkt->pkttype = PKT_SECRET_CERT;
154     pkt->pkt.secret_cert = skc;
155     add_kbnode(sec_root, new_kbnode( pkt ));
156     for(i=0; factors[i]; i++ )
157         add_kbnode( sec_root,
158                     make_mpi_comment_node("#:ELG_factor:", factors[i] ));
159
160     return 0;
161 }
162
163
164
165 #ifdef ENABLE_RSA_KEYGEN
166 static int
167 gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
168         byte *salt, PKT_secret_cert **ret_skc, u16 valid_days )
169 {
170     int rc;
171     PACKET *pkt;
172     PKT_secret_cert *skc;
173     PKT_public_cert *pkc;
174     RSA_public_key pk;
175     RSA_secret_key sk;
176
177     rsa_generate( &pk, &sk, nbits );
178
179     skc = m_alloc_clear( sizeof *skc );
180     pkc = m_alloc_clear( sizeof *pkc );
181     skc->timestamp = pkc->timestamp = make_timestamp();
182     skc->valid_days = pkc->valid_days = valid_days;
183     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_RSA;
184                        memset(&pkc->mfx, 0, sizeof pkc->mfx);
185                        pkc->d.rsa.rsa_n = pk.n;
186                        pkc->d.rsa.rsa_e = pk.e;
187     skc->d.rsa.rsa_n = sk.n;
188     skc->d.rsa.rsa_e = sk.e;
189     skc->d.rsa.rsa_d = sk.d;
190     skc->d.rsa.rsa_p = sk.p;
191     skc->d.rsa.rsa_q = sk.q;
192     skc->d.rsa.rsa_u = sk.u;
193     skc->d.rsa.csum  = checksum_mpi( skc->d.rsa.rsa_d );
194     skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p );
195     skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q );
196     skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_u );
197
198     /* return an unprotected version of the skc */
199     *ret_skc = copy_secret_cert( NULL, skc );
200
201     if( dek ) {
202         skc->d.rsa.is_protected = 1;
203         skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
204         randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1);
205         skc->d.rsa.csum += checksum( skc->d.rsa.protect.blowfish.iv, 8 );
206         rc = protect_secret_key( skc, dek );
207         if( rc ) {
208             log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
209             free_public_cert(pkc);
210             free_secret_cert(skc);
211             return rc;
212         }
213     }
214
215     pkt = m_alloc_clear(sizeof *pkt);
216     pkt->pkttype = PKT_PUBLIC_CERT;
217     pkt->pkt.public_cert = pkc;
218     add_kbnode(pub_root, new_kbnode( pkt ));
219
220     pkt = m_alloc_clear(sizeof *pkt);
221     pkt->pkttype = PKT_SECRET_CERT;
222     pkt->pkt.secret_cert = skc;
223     add_kbnode(sec_root, new_kbnode( pkt ));
224
225     return rc;
226 }
227 #endif /*ENABLE_RSA_KEYGEN*/
228
229
230 static int
231 gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
232          byte *salt, PKT_secret_cert **ret_skc, u16 valid_days )
233 {
234     return G10ERR_GENERAL;
235 }
236
237
238
239 /****************
240  * check valid days:
241  * return 0 on error or the multiplier
242  */
243 static int
244 check_valid_days( const char *s )
245 {
246     if( !isdigit(*s) )
247         return 0;
248     for( s++; *s; s++)
249         if( !isdigit(*s) )
250             break;
251     if( !*s )
252         return 1;
253     if( s[1] )
254         return 0; /* e.g. "2323wc" */
255     if( *s == 'd' || *s == 'D' )
256         return 1;
257     if( *s == 'w' || *s == 'W' )
258         return 7;
259     if( *s == 'm' || *s == 'M' )
260         return 30;
261     if( *s == 'y' || *s == 'Y' )
262         return 365;
263     return 0;
264 }
265
266
267 /****************
268  * Generate a keypair
269  */
270 void
271 generate_keypair()
272 {
273     char *answer;
274     unsigned nbits;
275     char *pub_fname = NULL;
276     char *sec_fname = NULL;
277     char *uid = NULL;
278     KBNODE pub_root = NULL;
279     KBNODE sec_root = NULL;
280     PKT_secret_cert *skc = NULL;
281     DEK *dek = NULL;
282     byte *salt;
283     int rc;
284     int algo;
285     const char *algo_name;
286     char *aname, *acomment, *amail;
287     int valid_days=0;
288
289     if( opt.batch || opt.answer_yes || opt.answer_no ) {
290         log_error(_("Key generation can only be used in interactive mode\n"));
291         return;
292     }
293
294     tty_printf(_("Please select the algorithm to use:\n"
295                  "   (1) ElGamal is the suggested one.\n"
296                  "   (2) DSA can only be used for signatures.\n"));
297   #ifdef ENABLE_RSA_KEYGEN
298     tty_printf(_("   (3) RSA cannot be used in the U.S.\n"));
299   #endif
300
301     for(;;) {
302       #ifdef ENABLE_RSA_KEYGEN
303         answer = tty_get(_("Your selection? (1,2,3) "));
304       #else
305         answer = tty_get(_("Your selection? (1,2) "));
306       #endif
307         tty_kill_prompt();
308         algo = *answer? atoi(answer): 1;
309         m_free(answer);
310         if( algo == 1 ) {
311             algo = PUBKEY_ALGO_ELGAMAL;
312             algo_name = "ElGamal";
313             break;
314         }
315         else if( algo == 2 ) {
316             algo = PUBKEY_ALGO_DSA;
317             algo_name = "DSA";
318             tty_printf(_("Sorry; DSA key generation is not yet supported.\n"));
319         }
320       #ifdef ENABLE_RSA_KEYGEN
321         else if( algo == 3 ) {
322             algo = PUBKEY_ALGO_RSA;
323             algo_name = "RSA";
324             break;
325         }
326       #endif
327     }
328
329
330
331     tty_printf(_("About to generate a new %s keypair.\n"
332                  "              minimum keysize is  768 bits\n"
333                  "              default keysize is 1024 bits\n"
334                  "    highest suggested keysize is 2048 bits\n"), algo_name );
335     for(;;) {
336         answer = tty_get(_("What keysize do you want? (1024) "));
337         tty_kill_prompt();
338         nbits = *answer? atoi(answer): 1024;
339         m_free(answer);
340         if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) )
341             tty_printf(_("DSA only allows keysizes from 512 to 1024\n"));
342         else if( nbits < 768 )
343             tty_printf(_("keysize too small; 768 is smallest value allowed.\n"));
344         else if( nbits > 2048 ) {
345             tty_printf(_("Keysizes larger than 2048 are not suggested, because "
346                          "computations take REALLY long!\n"));
347             answer = tty_get(_("Are you sure, that you want this keysize? "));
348             tty_kill_prompt();
349             if( answer_is_yes(answer) ) {
350                 m_free(answer);
351                 tty_printf(_("Okay, but keep in mind that your monitor "
352                              "and keyboard radiation is also very vulnerable "
353                              "to attacks!\n"));
354                 break;
355             }
356             m_free(answer);
357         }
358         else if( nbits > 1536 ) {
359             answer = tty_get(_("Do you really need such a large keysize? "));
360             tty_kill_prompt();
361             if( answer_is_yes(answer) ) {
362                 m_free(answer);
363                 break;
364             }
365             m_free(answer);
366         }
367         else
368             break;
369     }
370     tty_printf(_("Requested keysize is %u bits\n"), nbits );
371     if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) {
372         nbits = ((nbits + 63) / 64) * 64;
373         tty_printf(_("rounded up to %u bits\n"), nbits );
374     }
375     else if( (nbits % 32) ) {
376         nbits = ((nbits + 31) / 32) * 32;
377         tty_printf(_("rounded up to %u bits\n"), nbits );
378     }
379
380     tty_printf(_("Please specify how long the key should be valid.\n"
381                  "         0 = key does not expire\n"
382                  "      <n>  = key expires in n days\n"
383                  "      <n>w = key expires in n weeks\n"
384                  "      <n>m = key expires in n months\n"
385                  "      <n>y = key expires in n years\n"));
386     answer = NULL;
387     for(;;) {
388         int mult;
389
390         m_free(answer);
391         answer = tty_get(_("Key is valid for? (0) "));
392         tty_kill_prompt();
393         trim_spaces(answer);
394         if( !*answer )
395             valid_days = 0;
396         else if( (mult=check_valid_days(answer)) ) {
397             valid_days = atoi(answer) * mult;
398             if( valid_days < 0 || valid_days > 32767 )
399                 valid_days = 0;
400         }
401         else {
402             tty_printf(_("invalid value\n"));
403             continue;
404         }
405
406         if( !valid_days )
407             tty_printf(_("Key does not expire at all\n"));
408         else {
409             tty_printf(_("Key expires at %s\n"), strtimestamp(
410                        add_days_to_timestamp( make_timestamp(), valid_days )));
411         }
412
413         m_free(answer);
414         answer = tty_get(_("Is this correct (y/n)? "));
415         tty_kill_prompt();
416         if( answer_is_yes(answer) )
417             break;
418     }
419     m_free(answer);
420
421
422
423     tty_printf( _("\n"
424 "You need a User-ID to identify your key; the software constructs the user id\n"
425 "from Real Name, Comment and Email Address in this form:\n"
426 "    \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\n\n") );
427     uid = NULL;
428     aname=acomment=amail=NULL;
429     for(;;) {
430         char *p;
431
432         if( !aname ) {
433             for(;;) {
434                 m_free(aname);
435                 aname = tty_get(_("Real name: "));
436                 trim_spaces(aname);
437                 tty_kill_prompt();
438                 if( strpbrk( aname, "<([])>" ) )
439                     tty_printf(_("Invalid character in name\n"));
440                 else if( isdigit(*aname) )
441                     tty_printf(_("Name may not start with a digit\n"));
442                 else if( strlen(aname) < 5 )
443                     tty_printf(_("Name must be at least 5 characters long\n"));
444                 else
445                     break;
446             }
447         }
448         if( !amail ) {
449             for(;;) {
450                 m_free(amail);
451                 amail = tty_get(_("Email address: "));
452                 trim_spaces(amail);
453                 strlwr(amail);
454                 tty_kill_prompt();
455                 if( !*amail )
456                     break;   /* no email address is okay */
457                 else if( strcspn( amail, "abcdefghijklmnopqrstuvwxyz_-.@" )
458                          || string_count_chr(amail,'@') != 1
459                          || *amail == '@'
460                          || amail[strlen(amail)-1] == '@'
461                          || amail[strlen(amail)-1] == '.'
462                          || strstr(amail, "..") )
463                     tty_printf(_("Not a valid email address\n"));
464                 else
465                     break;
466             }
467         }
468         if( !acomment ) {
469             for(;;) {
470                 m_free(acomment);
471                 acomment = tty_get(_("Comment: "));
472                 trim_spaces(acomment);
473                 tty_kill_prompt();
474                 if( !*acomment )
475                     break;   /* no comment is okay */
476                 else if( strpbrk( acomment, "()" ) )
477                     tty_printf(_("Invalid character in comment\n"));
478                 else
479                     break;
480             }
481         }
482
483         m_free(uid);
484         uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+12+10);
485         p = stpcpy(p, aname );
486         if( *acomment )
487             p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
488         if( *amail )
489             p = stpcpy(stpcpy(stpcpy(p," <"), amail),">");
490
491         /* append a warning if we do not have dev/random
492          * or it is switched into  quick testmode */
493         if( quick_random_gen(-1) )
494             strcpy(p, " (INSECURE!)" );
495
496
497         tty_printf(_("You selected this USER-ID:\n    \"%s\"\n\n"), uid);
498         /* fixme: add a warning if this user-id already exists */
499         for(;;) {
500             answer = tty_get(_("Edit (N)ame, (C)omment, (E)mail or (O)kay? "));
501             tty_kill_prompt();
502             if( strlen(answer) > 1 )
503                 ;
504             else if( *answer == 'N' || *answer == 'n' ) {
505                 m_free(aname); aname = NULL;
506                 break;
507             }
508             else if( *answer == 'C' || *answer == 'c' ) {
509                 m_free(acomment); acomment = NULL;
510                 break;
511             }
512             else if( *answer == 'E' || *answer == 'e' ) {
513                 m_free(amail); amail = NULL;
514                 break;
515             }
516             else if( *answer == 'O' || *answer == 'o' ) {
517                 m_free(aname); aname = NULL;
518                 m_free(acomment); acomment = NULL;
519                 m_free(amail); amail = NULL;
520                 break;
521             }
522             m_free(answer);
523         }
524         m_free(answer);
525         if( !amail && !acomment && !amail )
526             break;
527         m_free(uid); uid = NULL;
528     }
529
530
531     tty_printf(_("You need a Passphrase to protect your secret key.\n\n") );
532
533     dek = m_alloc_secure( sizeof *dek + 8 );
534     salt = (byte*)dek + sizeof *dek;
535     for(;;) {
536         dek->algo = CIPHER_ALGO_BLOWFISH;
537         randomize_buffer(salt, 8, 1);
538         rc = make_dek_from_passphrase( dek , 2, salt );
539         if( rc == -1 ) {
540             m_free(dek); dek = NULL;
541             tty_printf(_(
542             "You don't want a passphrase - this is probably a *bad* idea!\n"
543             "I will do it anyway.  You can change your passphrase at any time,\n"
544             "using this program with the option \"--change-passphrase\"\n\n"));
545             break;
546         }
547         else if( rc == G10ERR_PASSPHRASE ) {
548             tty_printf(_("passphrase not correctly repeated; try again.\n"));
549         }
550         else if( rc ) {
551             m_free(dek); dek = NULL;
552             m_free(uid);
553             log_error("Error getting the passphrase: %s\n", g10_errstr(rc) );
554             return;
555         }
556         else
557             break; /* okay */
558     }
559
560
561     /* now check whether we are allowed to write to the keyrings */
562     pub_fname = make_filename(opt.homedir, "pubring.gpg", NULL );
563     sec_fname = make_filename(opt.homedir, "secring.gpg", NULL );
564     if( opt.verbose ) {
565         tty_printf(_("writing public certificate to '%s'\n"), pub_fname );
566         tty_printf(_("writing secret certificate to '%s'\n"), sec_fname );
567     }
568
569     /* we create the packets as a tree of kbnodes. Because the structure
570      * we create is known in advance we simply generate a linked list
571      * The first packet is a dummy comment packet which we flag
572      * as deleted.  The very first packet must always be a CERT packet.
573      */
574     pub_root = make_comment_node("#"); delete_kbnode(pub_root);
575     sec_root = make_comment_node("#"); delete_kbnode(sec_root);
576
577     tty_printf(_(
578 "We need to generate a lot of random bytes. It is a good idea to perform\n"
579 "some other action (work in another window, move the mouse, utilize the\n"
580 "network and the disks) during the prime generation; this gives the random\n"
581 "number generator a better chance to gain enough entropy.\n") );
582
583     if( algo == PUBKEY_ALGO_ELGAMAL )
584         rc = gen_elg(nbits, pub_root, sec_root, dek, salt,  &skc, valid_days );
585   #ifdef ENABLE_RSA_KEYGEN
586     else if( algo == PUBKEY_ALGO_RSA )
587         rc = gen_rsa(nbits, pub_root, sec_root, dek, salt, &skc, valid_days  );
588   #endif
589     else if( algo == PUBKEY_ALGO_DSA )
590         rc = gen_dsa(nbits, pub_root, sec_root, dek, salt, &skc, valid_days  );
591     else
592         BUG();
593     if( !rc ) {
594         add_kbnode( pub_root,
595                 make_comment_node("#created by GNUPG v" VERSION " ("
596                                             PRINTABLE_OS_NAME ")"));
597         add_kbnode( sec_root,
598                 make_comment_node("#created by GNUPG v" VERSION " ("
599                                             PRINTABLE_OS_NAME ")"));
600     }
601     if( !rc )
602         write_uid(pub_root, uid );
603     if( !rc )
604         write_uid(sec_root, uid );
605     if( !rc )
606         rc = write_selfsig(pub_root, pub_root, skc);
607     if( !rc )
608         rc = write_selfsig(sec_root, pub_root, skc);
609
610     if( !rc ) {
611         KBPOS pub_kbpos;
612         KBPOS sec_kbpos;
613         int rc1 = -1;
614         int rc2 = -1;
615
616         /* we can now write the certificates */
617
618         if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
619             if( add_keyblock_resource( pub_fname, 1, 0 ) ) {
620                 log_error("can add keyblock file '%s'\n", pub_fname );
621                 rc = G10ERR_CREATE_FILE;
622             }
623             else if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
624                 log_error("can get keyblock handle for '%s'\n", pub_fname );
625                 rc = G10ERR_CREATE_FILE;
626             }
627         }
628         if( rc )
629             ;
630         else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
631             if( add_keyblock_resource( sec_fname, 1, 1 ) ) {
632                 log_error("can add keyblock file '%s'\n", sec_fname );
633                 rc = G10ERR_CREATE_FILE;
634             }
635             else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
636                 log_error("can get keyblock handle for '%s'\n", sec_fname );
637                 rc = G10ERR_CREATE_FILE;
638             }
639         }
640
641         if( rc )
642             ;
643         else if( (rc=rc1=lock_keyblock( &pub_kbpos )) )
644             log_error("can't lock public keyring: %s\n", g10_errstr(rc) );
645         else if( (rc=rc2=lock_keyblock( &sec_kbpos )) )
646             log_error("can't lock secret keyring: %s\n", g10_errstr(rc) );
647         else if( (rc=insert_keyblock( &pub_kbpos, pub_root )) )
648             log_error("can't write public key: %s\n", g10_errstr(rc) );
649         else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) )
650             log_error("can't write secret key: %s\n", g10_errstr(rc) );
651         else {
652             tty_printf(_("public and secret key created and signed.\n") );
653         }
654
655         if( !rc1 )
656             unlock_keyblock( &pub_kbpos );
657         if( !rc2 )
658             unlock_keyblock( &sec_kbpos );
659     }
660
661
662     if( rc )
663         tty_printf(_("Key generation failed: %s\n"), g10_errstr(rc) );
664     release_kbnode( pub_root );
665     release_kbnode( sec_root );
666     if( skc ) /* the unprotected  secret certificate */
667         free_secret_cert(skc);
668     m_free(uid);
669     m_free(dek);
670     m_free(pub_fname);
671     m_free(sec_fname);
672 }
673