2006-12-21 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / sm / certreqgen.c
blob0fafea1ec31336db733b99fa98e3a3d31d7fe76f
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,
19 * USA.
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
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
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>
107 #include "gpgsm.h"
108 #include <gcrypt.h>
109 #include <ksba.h>
111 #include "keydb.h"
112 #include "i18n.h"
115 enum para_name {
116 pKEYTYPE,
117 pKEYLENGTH,
118 pKEYGRIP,
119 pKEYUSAGE,
120 pNAMEDN,
121 pNAMEEMAIL,
122 pNAMEDNS,
123 pNAMEURI
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;
136 struct reqgen_ctrl_s {
137 int lnr;
138 int dryrun;
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);
157 static void
158 release_parameter_list (struct para_data_s *r)
160 struct para_data_s *r2;
162 for (; r ; r = r2)
164 r2 = r->next;
165 xfree(r);
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--)
176 return r;
177 return NULL;
180 static const char *
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;
187 static int
188 get_parameter_algo (struct para_data_s *para, enum para_name key)
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);
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)
205 struct para_data_s *r = get_parameter (para, key, 0);
206 char *p, *pn;
207 unsigned int use;
209 if (!r)
210 return 0; /* none (this is an optional parameter)*/
212 use = 0;
213 pn = r->u.value;
214 while ( (p = strsep (&pn, " \t,")) )
216 if (!*p)
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
224 log_error ("line %d: invalid usage list\n", r->lnr);
225 return -1; /* error */
228 r->u.usage = use;
229 return 0;
233 static unsigned int
234 get_parameter_uint (struct para_data_s *para, enum para_name key)
236 struct para_data_s *r = get_parameter (para, key, 0);
238 if (!r)
239 return 0;
241 if (r->key == pKEYUSAGE)
242 return r->u.usage;
244 return (unsigned int)strtoul (r->u.value, NULL, 10);
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)
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 }
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;
275 memset (&outctrl, 0, sizeof (outctrl));
276 outctrl.writer = writer;
278 err = NULL;
279 para = NULL;
280 while (fgets (line, DIM(line)-1, fp) )
282 char *keyword, *value;
284 outctrl.lnr++;
285 if (*line && line[strlen(line)-1] != '\n')
287 err = "line too long";
288 break;
290 for (p=line; spacep (p); p++)
292 if (!*p || *p == '#')
293 continue;
295 keyword = p;
296 if (*keyword == '%')
298 for (; *p && !spacep (p); p++)
300 if (*p)
301 *p++ = 0;
302 for (; spacep (p); p++)
304 value = 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"))
310 outctrl.dryrun = 1;
311 else if (!ascii_strcasecmp( keyword, "%commit"))
313 rc = proc_parameters (ctrl, para, &outctrl);
314 if (rc)
315 goto leave;
316 any = 1;
317 release_parameter_list (para);
318 para = NULL;
320 else
321 log_info ("skipping control `%s' (%s)\n", keyword, value);
323 continue;
327 if (!(p = strchr (p, ':')) || p == keyword)
329 err = "missing colon";
330 break;
332 if (*p)
333 *p++ = 0;
334 for (; spacep (p); p++)
336 if (!*p)
338 err = "missing argument";
339 break;
341 value = p;
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";
350 break;
352 if (keywords[i].key != pKEYTYPE && !para)
354 err = "parameter block does not start with \"Key-Type\"";
355 break;
358 if (keywords[i].key == pKEYTYPE && para)
360 rc = proc_parameters (ctrl, para, &outctrl);
361 if (rc)
362 goto leave;
363 any = 1;
364 release_parameter_list (para);
365 para = NULL;
367 else if (!keywords[i].allow_dups)
369 for (r = para; r && r->key != keywords[i].key; r = r->next)
371 if (r)
373 err = "duplicate keyword";
374 break;
378 r = xtrycalloc (1, sizeof *r + strlen( value ));
379 if (!r)
381 err = "out of core";
382 break;
384 r->lnr = outctrl.lnr;
385 r->key = keywords[i].key;
386 strcpy (r->u.value, value);
387 r->next = para;
388 para = r;
391 if (err)
393 log_error ("line %d: %s\n", outctrl.lnr, err);
394 rc = gpg_error (GPG_ERR_GENERAL);
396 else if (ferror(fp))
398 log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) );
399 rc = gpg_error (GPG_ERR_GENERAL);
401 else if (para)
403 rc = proc_parameters (ctrl, para, &outctrl);
404 if (rc)
405 goto leave;
406 any = 1;
409 if (!rc && !any)
410 rc = gpg_error (GPG_ERR_NO_DATA);
412 leave:
413 release_parameter_list (para);
414 return rc;
417 /* check whether there are invalid characters in the email address S */
418 static int
419 has_invalid_email_chars (const char *s)
421 int at_seen=0;
422 static char valid_chars[] = "01234567890_-."
423 "abcdefghijklmnopqrstuvwxyz"
424 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
425 for (; *s; s++)
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;
436 return at_seen != 1;
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)
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;
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))
482 nbits = 1024;
483 else
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);
491 xfree (cardkeyid);
492 return gpg_error (GPG_ERR_INV_PARAMETER);
495 /* Check the usage. */
496 if (parse_parameter_usage (para, pKEYUSAGE))
498 xfree (cardkeyid);
499 return gpg_error (GPG_ERR_INV_PARAMETER);
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)))
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);
511 err = ksba_dn_teststr (s, 0, &erroff, &errlen);
512 if (err)
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);
522 xfree (cardkeyid);
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)
530 || *s == '@'
531 || s[strlen(s)-1] == '@'
532 || s[strlen(s)-1] == '.'
533 || strstr(s, ".."))
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);
542 if (cardkeyid) /* Take the key from the current smart card. */
544 rc = gpgsm_agent_readkey (ctrl, 1, cardkeyid, &public);
545 if (rc)
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;
554 else if ((s=get_parameter_value (para, pKEYGRIP, 0))) /* Use existing key.*/
556 rc = gpgsm_agent_readkey (ctrl, 0, s, &public);
557 if (rc)
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;
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);
573 if (rc)
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;
583 rc = create_request (ctrl, para, cardkeyid, public, outctrl);
584 xfree (public);
585 xfree (cardkeyid);
587 return rc;
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)
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];
612 err = ksba_certreq_new (&cr);
613 if (err)
614 return err;
616 rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
617 if (rc)
619 log_error ("md_open failed: %s\n", gpg_strerror (rc));
620 goto leave;
622 if (DBG_HASHING)
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));
629 if (err)
631 log_error ("error setting the subject's name: %s\n",
632 gpg_strerror (err));
633 rc = err;
634 goto leave;
637 for (seq=0; (s = get_parameter_value (para, pNAMEEMAIL, seq)); seq++)
639 buf = xtrymalloc (strlen (s) + 3);
640 if (!buf)
642 rc = out_of_core ();
643 goto leave;
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)
652 log_error ("error setting the subject's alternate name: %s\n",
653 gpg_strerror (err));
654 rc = err;
655 goto leave;
659 for (seq=0; (s = get_parameter_value (para, pNAMEDNS, seq)); seq++)
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)
667 rc = out_of_core ();
668 goto leave;
670 p = stpcpy (p, "(8:dns-name");
671 p = stpcpy (p, numbuf);
672 p = stpcpy (p, s);
673 strcpy (p, ")");
675 err = ksba_certreq_add_subject (cr, buf);
676 xfree (buf);
677 if (err)
679 log_error ("error setting the subject's alternate name: %s\n",
680 gpg_strerror (err));
681 rc = err;
682 goto leave;
686 for (seq=0; (s = get_parameter_value (para, pNAMEURI, seq)); seq++)
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)
694 rc = out_of_core ();
695 goto leave;
697 p = stpcpy (p, "(3:uri");
698 p = stpcpy (p, numbuf);
699 p = stpcpy (p, s);
700 strcpy (p, ")");
702 err = ksba_certreq_add_subject (cr, buf);
703 xfree (buf);
704 if (err)
706 log_error ("error setting the subject's alternate name: %s\n",
707 gpg_strerror (err));
708 rc = err;
709 goto leave;
714 err = ksba_certreq_set_public_key (cr, public);
715 if (err)
717 log_error ("error setting the public key: %s\n",
718 gpg_strerror (err));
719 rc = err;
720 goto leave;
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);
741 else
742 err = 0; /* Both or none given: don't request one. */
743 if (err)
745 log_error ("error setting the key usage: %s\n",
746 gpg_strerror (err));
747 rc = err;
748 goto leave;
754 err = ksba_certreq_build (cr, &stopreason);
755 if (err)
757 log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err));
758 rc = err;
759 goto leave;
761 if (stopreason == KSBA_SR_NEED_SIG)
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;
770 n = gcry_sexp_canon_len (public, 0, NULL, NULL);
771 if (!n)
773 log_error ("libksba did not return a proper S-Exp\n");
774 err = gpg_error (GPG_ERR_BUG);
775 goto leave;
777 rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)public, n);
778 if (rc)
780 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
781 goto leave;
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);
788 goto leave;
790 gcry_sexp_release (s_pkey);
791 for (n=0; n < 20; n++)
792 sprintf (hexgrip+n*2, "%02X", grip[n]);
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)
808 log_error ("signing failed: %s\n", gpg_strerror (rc));
809 goto leave;
812 err = ksba_certreq_set_sig_val (cr, sigval);
813 xfree (sigval);
814 if (err)
816 log_error ("failed to store the sig_val: %s\n",
817 gpg_strerror (err));
818 rc = err;
819 goto leave;
823 while (stopreason != KSBA_SR_READY);
826 leave:
827 gcry_md_close (md);
828 ksba_certreq_release (cr);
829 return rc;
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)
839 int rc;
840 FILE *in_fp;
841 Base64Context b64writer = NULL;
842 ksba_writer_t writer;
844 in_fp = fdopen (dup (in_fd), "rb");
845 if (!in_fp)
847 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
848 log_error ("fdopen() failed: %s\n", strerror (errno));
849 return tmperr;
852 ctrl->pem_name = "CERTIFICATE REQUEST";
853 rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
854 if (rc)
856 log_error ("can't create writer: %s\n", gpg_strerror (rc));
857 goto leave;
860 rc = read_parameters (ctrl, in_fp, writer);
861 if (rc)
863 log_error ("error creating certificate request: %s\n",
864 gpg_strerror (rc));
865 goto leave;
868 rc = gpgsm_finish_writer (b64writer);
869 if (rc)
871 log_error ("write failed: %s\n", gpg_strerror (rc));
872 goto leave;
875 gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
876 log_info ("certificate request created\n");
878 leave:
879 gpgsm_destroy_writer (b64writer);
880 fclose (in_fp);
881 return rc;