1 /* certreqgen.c - Generate a key and a certification request
2 * Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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,
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"
42 Suppress actual key generation (useful for syntax checking).
44 Perform the key generation. Note that an implicit commit is done
45 at the next "Key-Type" parameter.
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:
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
65 Key-Length: <length-in-bits>
66 Length of the key in bits. Default is 1024.
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.
76 This is the DN name of the subject in rfc2253 format.
78 The is an email address for the altSubjectName
80 The is an DNS name for the altSubjectName
82 The is an URI for the altSubjectName
86 %echo Generating a standard key
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" :-)
127 struct para_data_s
*next
;
136 struct reqgen_ctrl_s
{
139 ksba_writer_t writer
;
143 static const char oidstr_keyUsage
[] = "2.5.29.15";
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
);
158 release_parameter_list (struct para_data_s
*r
)
160 struct para_data_s
*r2
;
169 static struct para_data_s
*
170 get_parameter (struct para_data_s
*para
, enum para_name key
, int seq
)
172 struct para_data_s
*r
;
174 for (r
= para
; r
; r
= r
->next
)
175 if ( r
->key
== key
&& !seq
--)
181 get_parameter_value (struct para_data_s
*para
, enum para_name key
, int seq
)
183 struct para_data_s
*r
= get_parameter (para
, key
, seq
);
184 return (r
&& *r
->u
.value
)? r
->u
.value
: NULL
;
188 get_parameter_algo (struct para_data_s
*para
, enum para_name key
)
190 struct para_data_s
*r
= get_parameter (para
, key
, 0);
193 if (digitp (r
->u
.value
))
194 return atoi( r
->u
.value
);
195 return gcry_pk_map_name (r
->u
.value
);
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. */
203 parse_parameter_usage (struct para_data_s
*para
, enum para_name key
)
205 struct para_data_s
*r
= get_parameter (para
, key
, 0);
210 return 0; /* none (this is an optional parameter)*/
214 while ( (p
= strsep (&pn
, " \t,")) )
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
;
224 log_error ("line %d: invalid usage list\n", r
->lnr
);
225 return -1; /* error */
234 get_parameter_uint (struct para_data_s
*para
, enum para_name key
)
236 struct para_data_s
*r
= get_parameter (para
, key
, 0);
241 if (r
->key
== pKEYUSAGE
)
244 return (unsigned int)strtoul (r
->u
.value
, NULL
, 10);
249 /* Read the certificate generation parameters from FP and generate
250 (all) certificate requests. */
252 read_parameters (ctrl_t ctrl
, FILE *fp
, ksba_writer_t writer
)
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 },
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
;
275 memset (&outctrl
, 0, sizeof (outctrl
));
276 outctrl
.writer
= writer
;
280 while (fgets (line
, DIM(line
)-1, fp
) )
282 char *keyword
, *value
;
285 if (*line
&& line
[strlen(line
)-1] != '\n')
287 err
= "line too long";
290 for (p
=line
; spacep (p
); p
++)
292 if (!*p
|| *p
== '#')
298 for (; *p
&& !spacep (p
); p
++)
302 for (; spacep (p
); p
++)
305 trim_trailing_spaces (value
);
307 if (!ascii_strcasecmp (keyword
, "%echo"))
308 log_info ("%s\n", value
);
309 else if (!ascii_strcasecmp (keyword
, "%dry-run"))
311 else if (!ascii_strcasecmp( keyword
, "%commit"))
313 rc
= proc_parameters (ctrl
, para
, &outctrl
);
317 release_parameter_list (para
);
321 log_info ("skipping control `%s' (%s)\n", keyword
, value
);
327 if (!(p
= strchr (p
, ':')) || p
== keyword
)
329 err
= "missing colon";
334 for (; spacep (p
); p
++)
338 err
= "missing argument";
342 trim_trailing_spaces (value
);
344 for (i
=0; (keywords
[i
].name
345 && ascii_strcasecmp (keywords
[i
].name
, keyword
)); i
++)
347 if (!keywords
[i
].name
)
349 err
= "unknown keyword";
352 if (keywords
[i
].key
!= pKEYTYPE
&& !para
)
354 err
= "parameter block does not start with \"Key-Type\"";
358 if (keywords
[i
].key
== pKEYTYPE
&& para
)
360 rc
= proc_parameters (ctrl
, para
, &outctrl
);
364 release_parameter_list (para
);
367 else if (!keywords
[i
].allow_dups
)
369 for (r
= para
; r
&& r
->key
!= keywords
[i
].key
; r
= r
->next
)
373 err
= "duplicate keyword";
378 r
= xtrycalloc (1, sizeof *r
+ strlen( value
));
384 r
->lnr
= outctrl
.lnr
;
385 r
->key
= keywords
[i
].key
;
386 strcpy (r
->u
.value
, value
);
393 log_error ("line %d: %s\n", outctrl
.lnr
, err
);
394 rc
= gpg_error (GPG_ERR_GENERAL
);
398 log_error ("line %d: read error: %s\n", outctrl
.lnr
, strerror(errno
) );
399 rc
= gpg_error (GPG_ERR_GENERAL
);
403 rc
= proc_parameters (ctrl
, para
, &outctrl
);
410 rc
= gpg_error (GPG_ERR_NO_DATA
);
413 release_parameter_list (para
);
417 /* check whether there are invalid characters in the email address S */
419 has_invalid_email_chars (const char *s
)
422 static char valid_chars
[] = "01234567890_-."
423 "abcdefghijklmnopqrstuvwxyz"
424 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
431 else if (!at_seen
&& !( !!strchr (valid_chars
, *s
) || *s
== '+'))
433 else if (at_seen
&& !strchr (valid_chars
, *s
))
440 /* Check that all required parameters are given and perform the action */
442 proc_parameters (ctrl_t ctrl
,
443 struct para_data_s
*para
, struct reqgen_ctrl_s
*outctrl
)
446 struct para_data_s
*r
;
451 unsigned char keyparms
[100];
455 size_t erroff
, errlen
;
456 char *cardkeyid
= NULL
;
458 /* Check that we have all required parameters; */
459 assert (get_parameter (para
, pKEYTYPE
, 0));
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
)
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);
473 if ( (i
< 1 || i
!= GCRY_PK_RSA
) && !cardkeyid
)
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
);
480 /* Check the keylength. */
481 if (!get_parameter (para
, pKEYLENGTH
, 0))
484 nbits
= get_parameter_uint (para
, pKEYLENGTH
);
485 if ((nbits
< 1024 || nbits
> 4096) && !cardkeyid
)
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);
492 return gpg_error (GPG_ERR_INV_PARAMETER
);
495 /* Check the usage. */
496 if (parse_parameter_usage (para
, pKEYUSAGE
))
499 return gpg_error (GPG_ERR_INV_PARAMETER
);
502 /* Check that there is a subject name and that this DN fits our
504 if (!(s
=get_parameter_value (para
, pNAMEDN
, 0)))
506 r
= get_parameter (para
, pNAMEDN
, 0);
507 log_error (_("line %d: no subject name given\n"), r
->lnr
);
509 return gpg_error (GPG_ERR_INV_PARAMETER
);
511 err
= ksba_dn_teststr (s
, 0, &erroff
, &errlen
);
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
);
519 log_error (_("line %d: invalid subject name `%s' at pos %d\n"),
520 r
->lnr
, s
, (int)erroff
);
523 return gpg_error (GPG_ERR_INV_PARAMETER
);
526 /* Check that the optional email address is okay. */
527 for (seq
=0; (s
=get_parameter_value (para
, pNAMEEMAIL
, seq
)); seq
++)
529 if (has_invalid_email_chars (s
)
531 || s
[strlen(s
)-1] == '@'
532 || s
[strlen(s
)-1] == '.'
535 r
= get_parameter (para
, pNAMEEMAIL
, seq
);
536 log_error (_("line %d: not a valid email address\n"), r
->lnr
);
538 return gpg_error (GPG_ERR_INV_PARAMETER
);
542 if (cardkeyid
) /* Take the key from the current smart card. */
544 rc
= gpgsm_agent_readkey (ctrl
, 1, cardkeyid
, &public);
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
));
554 else if ((s
=get_parameter_value (para
, pKEYGRIP
, 0))) /* Use existing key.*/
556 rc
= gpgsm_agent_readkey (ctrl
, 0, s
, &public);
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
));
566 else /* Generate new key. */
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);
575 r
= get_parameter (para
, pKEYTYPE
, 0);
576 log_error (_("line %d: key generation failed: %s\n"),
577 r
->lnr
, gpg_strerror (rc
));
583 rc
= create_request (ctrl
, para
, cardkeyid
, public, outctrl
);
591 /* Parameters are checked, the key pair has been created. Now
592 generate the request and write it out */
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
)
603 ksba_stop_reason_t stopreason
;
612 err
= ksba_certreq_new (&cr
);
616 rc
= gcry_md_open (&md
, GCRY_MD_SHA1
, 0);
619 log_error ("md_open failed: %s\n", gpg_strerror (rc
));
623 gcry_md_start_debug (md
, "cr.cri");
625 ksba_certreq_set_hash_function (cr
, HASH_FNC
, md
);
626 ksba_certreq_set_writer (cr
, outctrl
->writer
);
628 err
= ksba_certreq_add_subject (cr
, get_parameter_value (para
, pNAMEDN
, 0));
631 log_error ("error setting the subject's name: %s\n",
637 for (seq
=0; (s
= get_parameter_value (para
, pNAMEEMAIL
, seq
)); seq
++)
639 buf
= xtrymalloc (strlen (s
) + 3);
648 err
= ksba_certreq_add_subject (cr
, buf
);
652 log_error ("error setting the subject's alternate name: %s\n",
659 for (seq
=0; (s
= get_parameter_value (para
, pNAMEDNS
, seq
)); seq
++)
663 snprintf (numbuf
, DIM(numbuf
), "%u:", (unsigned int)len
);
664 buf
= p
= xtrymalloc (11 + strlen (numbuf
) + len
+ 3);
670 p
= stpcpy (p
, "(8:dns-name");
671 p
= stpcpy (p
, numbuf
);
675 err
= ksba_certreq_add_subject (cr
, buf
);
679 log_error ("error setting the subject's alternate name: %s\n",
686 for (seq
=0; (s
= get_parameter_value (para
, pNAMEURI
, seq
)); seq
++)
690 snprintf (numbuf
, DIM(numbuf
), "%u:", (unsigned int)len
);
691 buf
= p
= xtrymalloc (6 + strlen (numbuf
) + len
+ 3);
697 p
= stpcpy (p
, "(3:uri");
698 p
= stpcpy (p
, numbuf
);
702 err
= ksba_certreq_add_subject (cr
, buf
);
706 log_error ("error setting the subject's alternate name: %s\n",
714 err
= ksba_certreq_set_public_key (cr
, public);
717 log_error ("error setting the public key: %s\n",
724 use
= get_parameter_uint (para
, pKEYUSAGE
);
725 if (use
== GCRY_PK_USAGE_SIGN
)
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);
733 else if (use
== GCRY_PK_USAGE_ENCR
)
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);
742 err
= 0; /* Both or none given: don't request one. */
745 log_error ("error setting the key usage: %s\n",
754 err
= ksba_certreq_build (cr
, &stopreason
);
757 log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err
));
761 if (stopreason
== KSBA_SR_NEED_SIG
)
765 unsigned char grip
[20];
767 unsigned char *sigval
;
770 n
= gcry_sexp_canon_len (public, 0, NULL
, NULL
);
773 log_error ("libksba did not return a proper S-Exp\n");
774 err
= gpg_error (GPG_ERR_BUG
);
777 rc
= gcry_sexp_sscan (&s_pkey
, NULL
, (const char*)public, n
);
780 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
783 if ( !gcry_pk_get_keygrip (s_pkey
, grip
) )
785 rc
= gpg_error (GPG_ERR_GENERAL
);
786 log_error ("can't figure out the keygrip\n");
787 gcry_sexp_release (s_pkey
);
790 gcry_sexp_release (s_pkey
);
791 for (n
=0; n
< 20; n
++)
792 sprintf (hexgrip
+n
*2, "%02X", grip
[n
]);
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
),
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
),
808 log_error ("signing failed: %s\n", gpg_strerror (rc
));
812 err
= ksba_certreq_set_sig_val (cr
, sigval
);
816 log_error ("failed to store the sig_val: %s\n",
823 while (stopreason
!= KSBA_SR_READY
);
828 ksba_certreq_release (cr
);
834 /* Create a new key by reading the parameters from in_fd. Multiple
835 keys may be created */
837 gpgsm_genkey (ctrl_t ctrl
, int in_fd
, FILE *out_fp
)
841 Base64Context b64writer
= NULL
;
842 ksba_writer_t writer
;
844 in_fp
= fdopen (dup (in_fd
), "rb");
847 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
848 log_error ("fdopen() failed: %s\n", strerror (errno
));
852 ctrl
->pem_name
= "CERTIFICATE REQUEST";
853 rc
= gpgsm_create_writer (&b64writer
, ctrl
, out_fp
, &writer
);
856 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
860 rc
= read_parameters (ctrl
, in_fp
, writer
);
863 log_error ("error creating certificate request: %s\n",
868 rc
= gpgsm_finish_writer (b64writer
);
871 log_error ("write failed: %s\n", gpg_strerror (rc
));
875 gpgsm_status (ctrl
, STATUS_KEY_CREATED
, "P");
876 log_info ("certificate request created\n");
879 gpgsm_destroy_writer (b64writer
);