1
/* certreqgen.c - Generate a key and a certification request
2
* Copyright (C) 2002, 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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"
41
Suppress actual key generation (useful for syntax checking).
43
Perform the key generation. Note that an implicit commit is done
44
at the next "Key-Type" parameter.
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:
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
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.
72
This is the DN name of the subject in rfc2253 format.
74
The ist the email address
78
%echo Generating a standard key
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" :-)
116
struct para_data_s *next;
125
struct reqgen_ctrl_s {
128
ksba_writer_t writer;
132
static const char oidstr_keyUsage[] = "2.5.29.15";
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);
146
release_parameter_list (struct para_data_s *r)
148
struct para_data_s *r2;
157
static struct para_data_s *
158
get_parameter (struct para_data_s *para, enum para_name key)
160
struct para_data_s *r;
162
for (r = para; r && r->key != key; r = r->next)
168
get_parameter_value (struct para_data_s *para, enum para_name key)
170
struct para_data_s *r = get_parameter (para, key);
171
return (r && *r->u.value)? r->u.value : NULL;
175
get_parameter_algo (struct para_data_s *para, enum para_name key)
177
struct para_data_s *r = get_parameter (para, key);
180
if (digitp (r->u.value))
181
return atoi( r->u.value );
182
return gcry_pk_map_name (r->u.value);
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. */
190
parse_parameter_usage (struct para_data_s *para, enum para_name key)
192
struct para_data_s *r = get_parameter (para, key);
197
return 0; /* none (this is an optional parameter)*/
201
while ( (p = strsep (&pn, " \t,")) )
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;
211
log_error ("line %d: invalid usage list\n", r->lnr);
212
return -1; /* error */
221
get_parameter_uint (struct para_data_s *para, enum para_name key)
223
struct para_data_s *r = get_parameter (para, key);
228
if (r->key == pKEYUSAGE)
231
return (unsigned int)strtoul (r->u.value, NULL, 10);
236
/* Read the certificate generation parameters from FP and generate
237
(all) certificate requests. */
239
read_parameters (ctrl_t ctrl, FILE *fp, ksba_writer_t writer)
245
{ "Key-Type", pKEYTYPE},
246
{ "Key-Length", pKEYLENGTH },
247
{ "Key-Usage", pKEYUSAGE },
248
{ "Name-DN", pNAMEDN },
249
{ "Name-Email", pNAMEEMAIL },
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;
258
memset (&outctrl, 0, sizeof (outctrl));
259
outctrl.writer = writer;
263
while (fgets (line, DIM(line)-1, fp) )
265
char *keyword, *value;
268
if (*line && line[strlen(line)-1] != '\n')
270
err = "line too long";
273
for (p=line; spacep (p); p++)
275
if (!*p || *p == '#')
281
for (; *p && !spacep (p); p++)
285
for (; spacep (p); p++)
288
trim_trailing_spaces (value);
290
if (!ascii_strcasecmp (keyword, "%echo"))
291
log_info ("%s\n", value);
292
else if (!ascii_strcasecmp (keyword, "%dry-run"))
294
else if (!ascii_strcasecmp( keyword, "%commit"))
296
rc = proc_parameters (ctrl, para, &outctrl);
300
release_parameter_list (para);
304
log_info ("skipping control `%s' (%s)\n", keyword, value);
310
if (!(p = strchr (p, ':')) || p == keyword)
312
err = "missing colon";
317
for (; spacep (p); p++)
321
err = "missing argument";
325
trim_trailing_spaces (value);
327
for (i=0; (keywords[i].name
328
&& ascii_strcasecmp (keywords[i].name, keyword)); i++)
330
if (!keywords[i].name)
332
err = "unknown keyword";
335
if (keywords[i].key != pKEYTYPE && !para)
337
err = "parameter block does not start with \"Key-Type\"";
341
if (keywords[i].key == pKEYTYPE && para)
343
rc = proc_parameters (ctrl, para, &outctrl);
347
release_parameter_list (para);
352
for (r = para; r && r->key != keywords[i].key; r = r->next)
356
err = "duplicate keyword";
361
r = xtrycalloc (1, sizeof *r + strlen( value ));
367
r->lnr = outctrl.lnr;
368
r->key = keywords[i].key;
369
strcpy (r->u.value, value);
376
log_error ("line %d: %s\n", outctrl.lnr, err);
377
rc = gpg_error (GPG_ERR_GENERAL);
381
log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) );
382
rc = gpg_error (GPG_ERR_GENERAL);
386
rc = proc_parameters (ctrl, para, &outctrl);
393
rc = gpg_error (GPG_ERR_NO_DATA);
396
release_parameter_list (para);
400
/* check whether there are invalid characters in the email address S */
402
has_invalid_email_chars (const char *s)
405
static char valid_chars[] = "01234567890_-."
406
"abcdefghijklmnopqrstuvwxyz"
407
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
414
else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+'))
416
else if (at_seen && !strchr (valid_chars, *s))
423
/* Check that all required parameters are given and perform the action */
425
proc_parameters (ctrl_t ctrl,
426
struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
428
struct para_data_s *r;
433
unsigned char keyparms[100];
437
/* check that we have all required parameters */
438
assert (get_parameter (para, pKEYTYPE));
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 )
446
r = get_parameter (para, pKEYTYPE);
447
log_error (_("line %d: invalid algorithm\n"), r->lnr);
448
return gpg_error (GPG_ERR_INV_PARAMETER);
451
/* check the keylength */
452
if (!get_parameter (para, pKEYLENGTH))
455
nbits = get_parameter_uint (para, pKEYLENGTH);
456
if (nbits < 1024 || nbits > 4096)
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);
465
/* check the usage */
466
if (parse_parameter_usage (para, pKEYUSAGE))
467
return gpg_error (GPG_ERR_INV_PARAMETER);
469
/* check that there is a subject name and that this DN fits our
471
if (!(s=get_parameter_value (para, pNAMEDN)))
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);
479
/* check that the optional email address is okay */
480
if ((s=get_parameter_value (para, pNAMEEMAIL)))
482
if (has_invalid_email_chars (s)
484
|| s[strlen(s)-1] == '@'
485
|| s[strlen(s)-1] == '.'
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);
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);
500
r = get_parameter (para, pKEYTYPE);
501
log_error (_("line %d: key generation failed: %s\n"),
502
r->lnr, gpg_strerror (rc));
506
rc = create_request (ctrl, para, public, outctrl);
513
/* Parameters are checked, the key pair has been created. Now
514
generate the request and write it out */
516
create_request (ctrl_t ctrl,
517
struct para_data_s *para, ksba_const_sexp_t public,
518
struct reqgen_ctrl_s *outctrl)
523
ksba_stop_reason_t stopreason;
528
err = ksba_certreq_new (&cr);
532
rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
535
log_error ("md_open failed: %s\n", gpg_strerror (rc));
539
gcry_md_start_debug (md, "cr.cri");
541
ksba_certreq_set_hash_function (cr, HASH_FNC, md);
542
ksba_certreq_set_writer (cr, outctrl->writer);
544
err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN));
547
log_error ("error setting the subject's name: %s\n",
553
s = get_parameter_value (para, pNAMEEMAIL);
558
buf = xtrymalloc (strlen (s) + 3);
561
rc = OUT_OF_CORE (errno);
567
err = ksba_certreq_add_subject (cr, buf);
571
log_error ("error setting the subject's alternate name: %s\n",
579
err = ksba_certreq_set_public_key (cr, public);
582
log_error ("error setting the public key: %s\n",
589
use = get_parameter_uint (para, pKEYUSAGE);
590
if (use == GCRY_PK_USAGE_SIGN)
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);
598
else if (use == GCRY_PK_USAGE_ENCR)
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);
607
err = 0; /* Both or none given: don't request one. */
610
log_error ("error setting the key usage: %s\n",
619
err = ksba_certreq_build (cr, &stopreason);
622
log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err));
626
if (stopreason == KSBA_SR_NEED_SIG)
630
unsigned char grip[20], hexgrip[41];
634
n = gcry_sexp_canon_len (public, 0, NULL, NULL);
637
log_error ("libksba did not return a proper S-Exp\n");
638
err = gpg_error (GPG_ERR_BUG);
641
rc = gcry_sexp_sscan (&s_pkey, NULL, public, n);
644
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
647
if ( !gcry_pk_get_keygrip (s_pkey, grip) )
649
rc = gpg_error (GPG_ERR_GENERAL);
650
log_error ("can't figure out the keygrip\n");
651
gcry_sexp_release (s_pkey);
654
gcry_sexp_release (s_pkey);
655
for (n=0; n < 20; n++)
656
sprintf (hexgrip+n*2, "%02X", grip[n]);
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),
665
log_error ("signing failed: %s\n", gpg_strerror (rc));
669
err = ksba_certreq_set_sig_val (cr, sigval);
673
log_error ("failed to store the sig_val: %s\n",
680
while (stopreason != KSBA_SR_READY);
685
ksba_certreq_release (cr);
691
/* Create a new key by reading the parameters from in_fd. Multiple
692
keys may be created */
694
gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp)
698
Base64Context b64writer = NULL;
699
ksba_writer_t writer;
701
in_fp = fdopen (dup (in_fd), "rb");
704
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
705
log_error ("fdopen() failed: %s\n", strerror (errno));
709
ctrl->pem_name = "CERTIFICATE REQUEST";
710
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
713
log_error ("can't create writer: %s\n", gpg_strerror (rc));
717
rc = read_parameters (ctrl, in_fp, writer);
720
log_error ("error creating certificate request: %s\n",
725
rc = gpgsm_finish_writer (b64writer);
728
log_error ("write failed: %s\n", gpg_strerror (rc));
732
gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
733
log_info ("certificate request created\n");
736
gpgsm_destroy_writer (b64writer);