4ffd8363e9dfab25211a5b2413bfa29ac7bacbc9
[gnupg.git] / sm / certreqgen.c
1 /* certreqgen.c - Generate a key and a certification request
2  *      Copyright (C) 2002, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 /*
23 The format of the native parameter file is follows:
24   o Text only, line length is limited to about 1000 chars.
25   o You must use UTF-8 encoding to specify non-ascii characters.
26   o Empty lines are ignored.
27   o Leading and trailing spaces are ignored.
28   o A hash sign as the first non white space character is a comment line.
29   o Control statements are indicated by a leading percent sign, the
30     arguments are separated by white space from the keyword.
31   o Parameters are specified by a keyword, followed by a colon.  Arguments
32     are separated by white space.
33   o The first parameter must be "Key-Type", control statements
34     may be placed anywhere.
35   o Key generation takes place when either the end of the parameter file
36     is reached, the next "Key-Type" parameter is encountered or at the
37     controlstatement "%commit"
38   o Control statements:
39     %echo <text>
40         Print <text>.
41     %dry-run
42         Suppress actual key generation (useful for syntax checking).
43     %commit
44         Perform the key generation.  Note that an implicit commit is done
45         at the next "Key-Type" parameter.
46     %certfile <filename>
47         Do not write the certificate to the keyDB but to <filename>.
48         This must be given before the first
49         commit to take place, duplicate specification of the same filename
50         is ignored, the last filename before a commit is used.
51         The filename is used until a new filename is used (at commit points)
52         and all keys are written to that file.  If a new filename is given,
53         this file is created (and overwrites an existing one).
54         Both control statements must be given.
55    o The order of the parameters does not matter except for "Key-Type"
56      which must be the first parameter.  The parameters are only for the
57      generated keyblock and parameters from previous key generations are not
58      used. Some syntactically checks may be performed.
59      The currently defined parameters are:
60      Key-Type: <algo>
61         Starts a new parameter block by giving the type of the
62         primary key. The algorithm must be capable of signing.
63         This is a required parameter.  For now the only supported
64         algorithm is "rsa".
65      Key-Length: <length-in-bits>
66         Length of the key in bits.  Default is 1024.
67      Key-Grip: hexstring
68         This is optional and used to generate a request for an already
69         existing key.  Key-Length will be ignored when given,
70      Key-Usage: <usage-list>
71         Space or comma delimited list of key usage, allowed values are
72         "encrypt" and "sign".  This is used to generate the KeyUsage extension.
73         Please make sure that the algorithm is capable of this usage.  Default
74         is to allow encrypt and sign.
75      Name-DN: subject name
76         This is the DN name of the subject in rfc2253 format.
77      Name-Email: <string>
78         The is an email address for the altSubjectName
79      Name-DNS: <string> 
80         The is an DNS name for the altSubjectName
81      Name-URI: <string> 
82         The is an URI for the altSubjectName
83
84 Here is an example:
85 $ cat >foo <<EOF
86 %echo Generating a standard key
87 Key-Type: RSA
88 Key-Length: 1024
89 Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE
90 Name-Email: joe@foo.bar
91 # Do a commit here, so that we can later print "done" :-)
92 %commit
93 %echo done
94 EOF
95 */
96
97
98 #include <config.h>
99 #include <stdio.h>
100 #include <stdlib.h>
101 #include <string.h>
102 #include <errno.h>
103 #include <unistd.h> 
104 #include <time.h>
105 #include <assert.h>
106
107 #include "gpgsm.h"
108 #include <gcrypt.h>
109 #include <ksba.h>
110
111 #include "keydb.h"
112 #include "i18n.h"
113
114
115 enum para_name {
116   pKEYTYPE,
117   pKEYLENGTH,
118   pKEYGRIP,
119   pKEYUSAGE,
120   pNAMEDN,
121   pNAMEEMAIL,
122   pNAMEDNS,
123   pNAMEURI
124 };
125
126 struct para_data_s {
127   struct para_data_s *next;
128   int lnr;
129   enum para_name key;
130   union {
131     unsigned int usage; 
132     char value[1];
133   } u;
134 };
135
136 struct reqgen_ctrl_s {
137   int lnr;
138   int dryrun;
139   ksba_writer_t writer;
140 };
141
142
143 static const char oidstr_keyUsage[] = "2.5.29.15";
144
145
146 static int proc_parameters (ctrl_t ctrl,
147                             struct para_data_s *para,
148                             struct reqgen_ctrl_s *outctrl);
149 static int create_request (ctrl_t ctrl,
150                            struct para_data_s *para,
151                            const char *carddirect,
152                            ksba_const_sexp_t public,
153                            struct reqgen_ctrl_s *outctrl);
154
155
156 \f
157 static void
158 release_parameter_list (struct para_data_s *r)
159 {
160   struct para_data_s *r2;
161   
162   for (; r ; r = r2)
163     {
164       r2 = r->next;
165       xfree(r);
166     }
167 }
168
169 static struct para_data_s *
170 get_parameter (struct para_data_s *para, enum para_name key, int seq)
171 {
172   struct para_data_s *r;
173   
174   for (r = para; r ; r = r->next)
175     if ( r->key == key && !seq--)
176       return r;
177   return NULL;
178 }
179
180 static const char *
181 get_parameter_value (struct para_data_s *para, enum para_name key, int seq)
182 {
183   struct para_data_s *r = get_parameter (para, key, seq);
184   return (r && *r->u.value)? r->u.value : NULL;
185 }
186
187 static int
188 get_parameter_algo (struct para_data_s *para, enum para_name key)
189 {
190   struct para_data_s *r = get_parameter (para, key, 0);
191   if (!r)
192     return -1;
193   if (digitp (r->u.value))
194     return atoi( r->u.value );
195   return gcry_pk_map_name (r->u.value); 
196 }
197
198 /* Parse the usage parameter.  Returns 0 on success.  Note that we
199    only care about sign and encrypt and don't (yet) allow all the
200    other X.509 usage to be specified; instead we will use a fixed
201    mapping to the X.509 usage flags. */
202 static int
203 parse_parameter_usage (struct para_data_s *para, enum para_name key)
204 {
205   struct para_data_s *r = get_parameter (para, key, 0);
206   char *p, *pn;
207   unsigned int use;
208   
209   if (!r)
210     return 0; /* none (this is an optional parameter)*/
211     
212   use = 0;
213   pn = r->u.value;
214   while ( (p = strsep (&pn, " \t,")) )
215     {
216       if (!*p)
217         ;
218       else if ( !ascii_strcasecmp (p, "sign") )
219         use |= GCRY_PK_USAGE_SIGN;
220       else if ( !ascii_strcasecmp (p, "encrypt") )
221         use |= GCRY_PK_USAGE_ENCR;
222       else
223         {
224           log_error ("line %d: invalid usage list\n", r->lnr);
225           return -1; /* error */
226         }
227     }
228   r->u.usage = use;
229   return 0;
230 }
231
232
233 static unsigned int
234 get_parameter_uint (struct para_data_s *para, enum para_name key)
235 {
236   struct para_data_s *r = get_parameter (para, key, 0);
237
238   if (!r)
239     return 0;
240
241   if (r->key == pKEYUSAGE)
242     return r->u.usage;
243
244   return (unsigned int)strtoul (r->u.value, NULL, 10);
245 }
246
247
248
249 /* Read the certificate generation parameters from FP and generate
250    (all) certificate requests.  */
251 static int
252 read_parameters (ctrl_t ctrl, FILE *fp, ksba_writer_t writer)
253 {
254   static struct {
255     const char *name;
256     enum para_name key;
257     int allow_dups;
258   } keywords[] = {
259     { "Key-Type",       pKEYTYPE},
260     { "Key-Length",     pKEYLENGTH },
261     { "Key-Grip",       pKEYGRIP },
262     { "Key-Usage",      pKEYUSAGE },
263     { "Name-DN",        pNAMEDN },
264     { "Name-Email",     pNAMEEMAIL, 1 },
265     { "Name-DNS",       pNAMEDNS, 1 },
266     { "Name-URI",       pNAMEURI, 1 },
267     { NULL, 0 }
268   };
269   char line[1024], *p;
270   const char *err = NULL;
271   struct para_data_s *para, *r;
272   int i, rc = 0, any = 0;
273   struct reqgen_ctrl_s outctrl;
274
275   memset (&outctrl, 0, sizeof (outctrl));
276   outctrl.writer = writer;
277
278   err = NULL;
279   para = NULL;
280   while (fgets (line, DIM(line)-1, fp) )
281     {
282       char *keyword, *value;
283
284       outctrl.lnr++;
285       if (*line && line[strlen(line)-1] != '\n')
286         {
287           err = "line too long";
288           break;
289         }
290       for (p=line; spacep (p); p++)
291         ;
292       if (!*p || *p == '#')
293         continue;
294
295       keyword = p;
296       if (*keyword == '%')
297         {
298           for (; *p && !spacep (p); p++)
299             ;
300           if (*p)
301             *p++ = 0;
302           for (; spacep (p); p++)
303             ;
304           value = p;
305           trim_trailing_spaces (value);
306
307           if (!ascii_strcasecmp (keyword, "%echo"))
308             log_info ("%s\n", value);
309           else if (!ascii_strcasecmp (keyword, "%dry-run"))
310             outctrl.dryrun = 1;
311           else if (!ascii_strcasecmp( keyword, "%commit"))
312             {
313               rc = proc_parameters (ctrl, para, &outctrl);
314               if (rc)
315                 goto leave;
316               any = 1;
317               release_parameter_list (para);
318               para = NULL;
319             }
320           else
321             log_info ("skipping control `%s' (%s)\n", keyword, value);
322
323           continue;
324         }
325
326
327       if (!(p = strchr (p, ':')) || p == keyword)
328         {
329           err = "missing colon";
330           break;
331         }
332       if (*p)
333         *p++ = 0;
334       for (; spacep (p); p++)
335         ;
336       if (!*p)
337         {
338           err = "missing argument";
339           break;
340         }
341       value = p;
342       trim_trailing_spaces (value);
343
344       for (i=0; (keywords[i].name
345                  && ascii_strcasecmp (keywords[i].name, keyword)); i++)
346         ;
347       if (!keywords[i].name)
348         {
349           err = "unknown keyword";
350           break;
351         }
352       if (keywords[i].key != pKEYTYPE && !para)
353         {
354           err = "parameter block does not start with \"Key-Type\"";
355           break;
356         }
357
358       if (keywords[i].key == pKEYTYPE && para)
359         {
360           rc = proc_parameters (ctrl, para, &outctrl);
361           if (rc)
362             goto leave;
363           any = 1;
364           release_parameter_list (para);
365           para = NULL;
366         }
367       else if (!keywords[i].allow_dups)
368         {
369           for (r = para; r && r->key != keywords[i].key; r = r->next)
370             ;
371           if (r)
372             {
373               err = "duplicate keyword";
374               break;
375             }
376         }
377
378       r = xtrycalloc (1, sizeof *r + strlen( value ));
379       if (!r)
380         {
381           err = "out of core";
382           break;
383         }
384       r->lnr = outctrl.lnr;
385       r->key = keywords[i].key;
386       strcpy (r->u.value, value);
387       r->next = para;
388       para = r;
389     }
390
391   if (err)
392     {
393       log_error ("line %d: %s\n", outctrl.lnr, err);
394       rc = gpg_error (GPG_ERR_GENERAL);
395     }
396   else if (ferror(fp))
397     {
398       log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) );
399       rc = gpg_error (GPG_ERR_GENERAL);
400     }
401   else if (para)
402     {
403       rc = proc_parameters (ctrl, para, &outctrl);
404       if (rc)
405         goto leave;
406       any = 1;
407     }
408
409   if (!rc && !any)
410     rc = gpg_error (GPG_ERR_NO_DATA);
411
412  leave:
413   release_parameter_list (para);
414   return rc;
415 }
416
417 /* check whether there are invalid characters in the email address S */
418 static int
419 has_invalid_email_chars (const char *s)
420 {
421   int at_seen=0;
422   static char valid_chars[] = "01234567890_-."
423                               "abcdefghijklmnopqrstuvwxyz"
424                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
425   for (; *s; s++)
426     {
427       if (*s & 0x80)
428         return 1;
429       if (*s == '@')
430         at_seen++;
431       else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+'))
432         return 1;
433       else if (at_seen && !strchr (valid_chars, *s))
434         return 1;
435     }
436   return at_seen != 1;
437 }
438
439
440 /* Check that all required parameters are given and perform the action */
441 static int
442 proc_parameters (ctrl_t ctrl,
443                  struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
444 {
445   gpg_error_t err;
446   struct para_data_s *r;
447   const char *s;
448   int i;
449   unsigned int nbits;
450   char numbuf[20];
451   unsigned char keyparms[100];
452   int rc;
453   ksba_sexp_t public;
454   int seq;
455   size_t erroff, errlen;
456   char *cardkeyid = NULL;
457
458   /* Check that we have all required parameters; */
459   assert (get_parameter (para, pKEYTYPE, 0));
460
461   /* We can only use RSA for now.  There is a problem with pkcs-10 on
462      how to use ElGamal because it is expected that a PK algorithm can
463      always be used for signing. Another problem is that on-card
464      generated encryption keys may not be used for signing.  */
465   i = get_parameter_algo (para, pKEYTYPE);
466   if (!i && (s = get_parameter_value (para, pKEYTYPE, 0)) && *s)
467     {
468       /* Hack to allow creation of certificates directly from a smart
469          card.  For example: "Key-Type: card:OPENPGP.3".  */
470       if (!strncmp (s, "card:", 5) && s[5])
471         cardkeyid = xtrystrdup (s+5);
472     }
473   if ( (i < 1 || i != GCRY_PK_RSA) && !cardkeyid )
474     {
475       r = get_parameter (para, pKEYTYPE, 0);
476       log_error (_("line %d: invalid algorithm\n"), r->lnr);
477       return gpg_error (GPG_ERR_INV_PARAMETER);
478     }
479   
480   /* Check the keylength. */
481   if (!get_parameter (para, pKEYLENGTH, 0))
482     nbits = 1024;
483   else
484     nbits = get_parameter_uint (para, pKEYLENGTH);
485   if ((nbits < 1024 || nbits > 4096) && !cardkeyid)
486     {
487       /* The BSI specs dated 2002-11-25 don't allow lengths below 1024. */
488       r = get_parameter (para, pKEYLENGTH, 0);
489       log_error (_("line %d: invalid key length %u (valid are %d to %d)\n"),
490                  r->lnr, nbits, 1024, 4096);
491       xfree (cardkeyid);
492       return gpg_error (GPG_ERR_INV_PARAMETER);
493     }
494     
495   /* Check the usage. */
496   if (parse_parameter_usage (para, pKEYUSAGE))
497     {
498       xfree (cardkeyid);
499       return gpg_error (GPG_ERR_INV_PARAMETER);
500     }
501
502   /* Check that there is a subject name and that this DN fits our
503      requirements. */
504   if (!(s=get_parameter_value (para, pNAMEDN, 0)))
505     {
506       r = get_parameter (para, pNAMEDN, 0);
507       log_error (_("line %d: no subject name given\n"), r->lnr);
508       xfree (cardkeyid);
509       return gpg_error (GPG_ERR_INV_PARAMETER);
510     }
511   err = ksba_dn_teststr (s, 0, &erroff, &errlen);
512   if (err)
513     {
514       r = get_parameter (para, pNAMEDN, 0);
515       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME)
516         log_error (_("line %d: invalid subject name label `%.*s'\n"),
517                    r->lnr, (int)errlen, s+erroff);
518       else
519         log_error (_("line %d: invalid subject name `%s' at pos %d\n"),
520                    r->lnr, s, (int)erroff);
521
522       xfree (cardkeyid);
523       return gpg_error (GPG_ERR_INV_PARAMETER);
524     }
525
526   /* Check that the optional email address is okay. */
527   for (seq=0; (s=get_parameter_value (para, pNAMEEMAIL, seq)); seq++)
528     { 
529       if (has_invalid_email_chars (s)
530           || *s == '@'
531           || s[strlen(s)-1] == '@'
532           || s[strlen(s)-1] == '.'
533           || strstr(s, ".."))
534         {
535           r = get_parameter (para, pNAMEEMAIL, seq);
536           log_error (_("line %d: not a valid email address\n"), r->lnr);
537           xfree (cardkeyid);
538           return gpg_error (GPG_ERR_INV_PARAMETER);
539         }
540     }
541
542   if (cardkeyid) /* Take the key from the current smart card. */
543     {
544       rc = gpgsm_agent_readkey (ctrl, 1, cardkeyid, &public);
545       if (rc)
546         {
547           r = get_parameter (para, pKEYTYPE, 0);
548           log_error (_("line %d: error reading key `%s' from card: %s\n"),
549                      r->lnr, cardkeyid, gpg_strerror (rc));
550           xfree (cardkeyid);
551           return rc;
552         }
553     }
554   else if ((s=get_parameter_value (para, pKEYGRIP, 0))) /* Use existing key.*/
555     {
556       rc = gpgsm_agent_readkey (ctrl, 0, s, &public);
557       if (rc)
558         {
559           r = get_parameter (para, pKEYTYPE, 0);
560           log_error (_("line %d: error getting key by keygrip `%s': %s\n"),
561                      r->lnr, s, gpg_strerror (rc));
562           xfree (cardkeyid);
563           return rc;
564         }
565     }
566   else /* Generate new key.  */
567     {
568       sprintf (numbuf, "%u", nbits);
569       snprintf ((char*)keyparms, DIM (keyparms)-1, 
570                 "(6:genkey(3:rsa(5:nbits%d:%s)))",
571                 (int)strlen (numbuf), numbuf);
572       rc = gpgsm_agent_genkey (ctrl, keyparms, &public);
573       if (rc)
574         {
575           r = get_parameter (para, pKEYTYPE, 0);
576           log_error (_("line %d: key generation failed: %s\n"),
577                      r->lnr, gpg_strerror (rc));
578           xfree (cardkeyid);
579           return rc;
580         }
581     }
582
583   rc = create_request (ctrl, para, cardkeyid, public, outctrl);
584   xfree (public);
585   xfree (cardkeyid);
586
587   return rc;
588 }
589
590
591 /* Parameters are checked, the key pair has been created.  Now
592    generate the request and write it out */
593 static int
594 create_request (ctrl_t ctrl, 
595                 struct para_data_s *para, 
596                 const char *carddirect,
597                 ksba_const_sexp_t public,
598                 struct reqgen_ctrl_s *outctrl)
599 {
600   ksba_certreq_t cr;
601   gpg_error_t err;
602   gcry_md_hd_t md;
603   ksba_stop_reason_t stopreason;
604   int rc = 0;
605   const char *s;
606   unsigned int use;
607   int seq;
608   char *buf, *p;
609   size_t len;
610   char numbuf[30];
611
612   err = ksba_certreq_new (&cr);
613   if (err)
614     return err;
615
616   rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
617   if (rc)
618     {
619       log_error ("md_open failed: %s\n", gpg_strerror (rc));
620       goto leave;
621     }
622   if (DBG_HASHING)
623     gcry_md_start_debug (md, "cr.cri");
624
625   ksba_certreq_set_hash_function (cr, HASH_FNC, md);
626   ksba_certreq_set_writer (cr, outctrl->writer);
627   
628   err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN, 0));
629   if (err)
630     {
631       log_error ("error setting the subject's name: %s\n",
632                  gpg_strerror (err));
633       rc = err;
634       goto leave;
635     }
636
637   for (seq=0; (s = get_parameter_value (para, pNAMEEMAIL, seq)); seq++)
638     {
639       buf = xtrymalloc (strlen (s) + 3);
640       if (!buf)
641         {
642           rc = out_of_core ();
643           goto leave;
644         }
645       *buf = '<';
646       strcpy (buf+1, s);
647       strcat (buf+1, ">");
648       err = ksba_certreq_add_subject (cr, buf);
649       xfree (buf);
650       if (err)
651         {
652           log_error ("error setting the subject's alternate name: %s\n",
653                      gpg_strerror (err));
654           rc = err;
655           goto leave;
656         }
657     }
658
659   for (seq=0; (s = get_parameter_value (para, pNAMEDNS, seq)); seq++)
660     {
661       len = strlen (s);
662       assert (len);
663       snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
664       buf = p = xtrymalloc (11 + strlen (numbuf) + len + 3);
665       if (!buf)
666         {
667           rc = out_of_core ();
668           goto leave;
669         }
670       p = stpcpy (p, "(8:dns-name");
671       p = stpcpy (p, numbuf);
672       p = stpcpy (p, s);
673       strcpy (p, ")");
674
675       err = ksba_certreq_add_subject (cr, buf);
676       xfree (buf);
677       if (err)
678         {
679           log_error ("error setting the subject's alternate name: %s\n",
680                      gpg_strerror (err));
681           rc = err;
682           goto leave;
683         }
684     }
685
686   for (seq=0; (s = get_parameter_value (para, pNAMEURI, seq)); seq++)
687     {
688       len = strlen (s);
689       assert (len);
690       snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
691       buf = p = xtrymalloc (6 + strlen (numbuf) + len + 3);
692       if (!buf)
693         {
694           rc = out_of_core ();
695           goto leave;
696         }
697       p = stpcpy (p, "(3:uri");
698       p = stpcpy (p, numbuf);
699       p = stpcpy (p, s);
700       strcpy (p, ")");
701
702       err = ksba_certreq_add_subject (cr, buf);
703       xfree (buf);
704       if (err)
705         {
706           log_error ("error setting the subject's alternate name: %s\n",
707                      gpg_strerror (err));
708           rc = err;
709           goto leave;
710         }
711     }
712
713
714   err = ksba_certreq_set_public_key (cr, public);
715   if (err)
716     {
717       log_error ("error setting the public key: %s\n",
718                  gpg_strerror (err));
719       rc = err;
720       goto leave;
721     }
722
723   
724   use = get_parameter_uint (para, pKEYUSAGE);
725   if (use == GCRY_PK_USAGE_SIGN)
726     {
727       /* For signing only we encode the bits:
728          KSBA_KEYUSAGE_DIGITAL_SIGNATURE
729          KSBA_KEYUSAGE_NON_REPUDIATION */
730       err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, 
731                                         "\x03\x02\x06\xC0", 4);
732     }
733   else if (use == GCRY_PK_USAGE_ENCR)
734     {
735       /* For encrypt only we encode the bits:
736          KSBA_KEYUSAGE_KEY_ENCIPHERMENT
737          KSBA_KEYUSAGE_DATA_ENCIPHERMENT */
738       err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, 
739                                         "\x03\x02\x04\x30", 4);
740     }
741   else
742     err = 0; /* Both or none given: don't request one. */
743   if (err)
744     {
745       log_error ("error setting the key usage: %s\n",
746                  gpg_strerror (err));
747       rc = err;
748       goto leave;
749     }
750
751                
752   do
753     {
754       err = ksba_certreq_build (cr, &stopreason);
755       if (err)
756         {
757           log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err));
758           rc = err;
759           goto leave;
760         }
761       if (stopreason == KSBA_SR_NEED_SIG)
762         {
763           gcry_sexp_t s_pkey;
764           size_t n;
765           unsigned char grip[20];
766           char hexgrip[41];
767           unsigned char *sigval;
768           size_t siglen;
769
770           n = gcry_sexp_canon_len (public, 0, NULL, NULL);
771           if (!n)
772             {
773               log_error ("libksba did not return a proper S-Exp\n");
774               err = gpg_error (GPG_ERR_BUG);
775               goto leave;
776             }
777           rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)public, n);
778           if (rc)
779             {
780               log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
781               goto leave;
782             }
783           if ( !gcry_pk_get_keygrip (s_pkey, grip) )
784             {
785               rc = gpg_error (GPG_ERR_GENERAL);
786               log_error ("can't figure out the keygrip\n");
787               gcry_sexp_release (s_pkey);
788               goto leave;
789             }
790           gcry_sexp_release (s_pkey);
791           for (n=0; n < 20; n++)
792             sprintf (hexgrip+n*2, "%02X", grip[n]);
793
794           if (carddirect)
795             rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
796                                      gcry_md_read(md, GCRY_MD_SHA1), 
797                                      gcry_md_get_algo_dlen (GCRY_MD_SHA1),
798                                      GCRY_MD_SHA1,
799                                      &sigval, &siglen);
800           else
801             rc = gpgsm_agent_pksign (ctrl, hexgrip, NULL,
802                                      gcry_md_read(md, GCRY_MD_SHA1), 
803                                      gcry_md_get_algo_dlen (GCRY_MD_SHA1),
804                                      GCRY_MD_SHA1,
805                                      &sigval, &siglen);
806           if (rc)
807             {
808               log_error ("signing failed: %s\n", gpg_strerror (rc));
809               goto leave;
810             }
811           
812           err = ksba_certreq_set_sig_val (cr, sigval);
813           xfree (sigval);
814           if (err)
815             {
816               log_error ("failed to store the sig_val: %s\n",
817                          gpg_strerror (err));
818               rc = err;
819               goto leave;
820             }
821         }
822     }
823   while (stopreason != KSBA_SR_READY);   
824   
825
826  leave:
827   gcry_md_close (md);
828   ksba_certreq_release (cr);
829   return rc;  
830 }
831
832
833 \f
834 /* Create a new key by reading the parameters from in_fd or in_stream.
835    Multiple keys may be created */
836 int
837 gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *in_stream, FILE *out_fp)
838 {
839   int rc;
840   FILE *in_fp;
841   Base64Context b64writer = NULL;
842   ksba_writer_t writer;
843
844   if (in_stream)
845     in_fp = in_stream;
846   else
847     in_fp = fdopen (dup (in_fd), "rb");
848   if (!in_fp)
849     {
850       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
851       log_error ("fdopen() failed: %s\n", strerror (errno));
852       return tmperr;
853     }
854
855   ctrl->pem_name = "CERTIFICATE REQUEST";
856   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
857   if (rc)
858     {
859       log_error ("can't create writer: %s\n", gpg_strerror (rc));
860       goto leave;
861     }
862
863   rc = read_parameters (ctrl, in_fp, writer);
864   if (rc)
865     {
866       log_error ("error creating certificate request: %s\n",
867                  gpg_strerror (rc));
868       goto leave;
869     }
870
871   rc = gpgsm_finish_writer (b64writer);
872   if (rc) 
873     {
874       log_error ("write failed: %s\n", gpg_strerror (rc));
875       goto leave;
876     }
877
878   gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
879   log_info ("certificate request created\n");
880
881  leave:
882   gpgsm_destroy_writer (b64writer);
883   if (!in_stream)
884     fclose (in_fp);
885   return rc;
886 }
887