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