2008-05-15 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / sm / certreqgen.c
blob30b8179fd5339cc083861f50d979675d5ce311df
1 /* certreqgen.c - Generate a key and a certification request
2 * Copyright (C) 2002, 2003, 2005, 2007 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 3 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, see <http://www.gnu.org/licenses/>.
21 The format of the native parameter file is follows:
22 o Text only, line length is limited to about 1000 chars.
23 o You must use UTF-8 encoding to specify non-ascii characters.
24 o Empty lines are ignored.
25 o Leading and trailing spaces are ignored.
26 o A hash sign as the first non white space character is a comment line.
27 o Control statements are indicated by a leading percent sign, the
28 arguments are separated by white space from the keyword.
29 o Parameters are specified by a keyword, followed by a colon. Arguments
30 are separated by white space.
31 o The first parameter must be "Key-Type", control statements
32 may be placed anywhere.
33 o Key generation takes place when either the end of the parameter file
34 is reached, the next "Key-Type" parameter is encountered or at the
35 controlstatement "%commit"
36 o Control statements:
37 %echo <text>
38 Print <text>.
39 %dry-run
40 Suppress actual key generation (useful for syntax checking).
41 %commit
42 Perform the key generation. Note that an implicit commit is done
43 at the next "Key-Type" parameter.
44 %certfile <filename>
45 Do not write the certificate to the keyDB but to <filename>.
46 This must be given before the first
47 commit to take place, duplicate specification of the same filename
48 is ignored, the last filename before a commit is used.
49 The filename is used until a new filename is used (at commit points)
50 and all keys are written to that file. If a new filename is given,
51 this file is created (and overwrites an existing one).
52 Both control statements must be given.
53 o The order of the parameters does not matter except for "Key-Type"
54 which must be the first parameter. The parameters are only for the
55 generated keyblock and parameters from previous key generations are not
56 used. Some syntactically checks may be performed.
57 The currently defined parameters are:
58 Key-Type: <algo>
59 Starts a new parameter block by giving the type of the
60 primary key. The algorithm must be capable of signing.
61 This is a required parameter. For now the only supported
62 algorithm is "rsa".
63 Key-Length: <length-in-bits>
64 Length of the key in bits. Default is 1024.
65 Key-Grip: hexstring
66 This is optional and used to generate a request for an already
67 existing key. Key-Length will be ignored when given,
68 Key-Usage: <usage-list>
69 Space or comma delimited list of key usage, allowed values are
70 "encrypt" and "sign". This is used to generate the KeyUsage extension.
71 Please make sure that the algorithm is capable of this usage. Default
72 is to allow encrypt and sign.
73 Name-DN: subject name
74 This is the DN name of the subject in rfc2253 format.
75 Name-Email: <string>
76 The is an email address for the altSubjectName
77 Name-DNS: <string>
78 The is an DNS name for the altSubjectName
79 Name-URI: <string>
80 The is an URI for the altSubjectName
82 Here is an example:
83 $ cat >foo <<EOF
84 %echo Generating a standard key
85 Key-Type: RSA
86 Key-Length: 1024
87 Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE
88 Name-Email: joe@foo.bar
89 # Do a commit here, so that we can later print "done" :-)
90 %commit
91 %echo done
92 EOF
96 #include <config.h>
97 #include <stdio.h>
98 #include <stdlib.h>
99 #include <string.h>
100 #include <errno.h>
101 #include <unistd.h>
102 #include <time.h>
103 #include <assert.h>
105 #include "gpgsm.h"
106 #include <gcrypt.h>
107 #include <ksba.h>
109 #include "keydb.h"
110 #include "i18n.h"
113 enum para_name {
114 pKEYTYPE,
115 pKEYLENGTH,
116 pKEYGRIP,
117 pKEYUSAGE,
118 pNAMEDN,
119 pNAMEEMAIL,
120 pNAMEDNS,
121 pNAMEURI
124 struct para_data_s {
125 struct para_data_s *next;
126 int lnr;
127 enum para_name key;
128 union {
129 unsigned int usage;
130 char value[1];
131 } u;
134 struct reqgen_ctrl_s {
135 int lnr;
136 int dryrun;
137 ksba_writer_t writer;
141 static const char oidstr_keyUsage[] = "2.5.29.15";
144 static int proc_parameters (ctrl_t ctrl,
145 struct para_data_s *para,
146 struct reqgen_ctrl_s *outctrl);
147 static int create_request (ctrl_t ctrl,
148 struct para_data_s *para,
149 const char *carddirect,
150 ksba_const_sexp_t public,
151 struct reqgen_ctrl_s *outctrl);
155 static void
156 release_parameter_list (struct para_data_s *r)
158 struct para_data_s *r2;
160 for (; r ; r = r2)
162 r2 = r->next;
163 xfree(r);
167 static struct para_data_s *
168 get_parameter (struct para_data_s *para, enum para_name key, int seq)
170 struct para_data_s *r;
172 for (r = para; r ; r = r->next)
173 if ( r->key == key && !seq--)
174 return r;
175 return NULL;
178 static const char *
179 get_parameter_value (struct para_data_s *para, enum para_name key, int seq)
181 struct para_data_s *r = get_parameter (para, key, seq);
182 return (r && *r->u.value)? r->u.value : NULL;
185 static int
186 get_parameter_algo (struct para_data_s *para, enum para_name key)
188 struct para_data_s *r = get_parameter (para, key, 0);
189 if (!r)
190 return -1;
191 if (digitp (r->u.value))
192 return atoi( r->u.value );
193 return gcry_pk_map_name (r->u.value);
196 /* Parse the usage parameter. Returns 0 on success. Note that we
197 only care about sign and encrypt and don't (yet) allow all the
198 other X.509 usage to be specified; instead we will use a fixed
199 mapping to the X.509 usage flags. */
200 static int
201 parse_parameter_usage (struct para_data_s *para, enum para_name key)
203 struct para_data_s *r = get_parameter (para, key, 0);
204 char *p, *pn;
205 unsigned int use;
207 if (!r)
208 return 0; /* none (this is an optional parameter)*/
210 use = 0;
211 pn = r->u.value;
212 while ( (p = strsep (&pn, " \t,")) )
214 if (!*p)
216 else if ( !ascii_strcasecmp (p, "sign") )
217 use |= GCRY_PK_USAGE_SIGN;
218 else if ( !ascii_strcasecmp (p, "encrypt") )
219 use |= GCRY_PK_USAGE_ENCR;
220 else
222 log_error ("line %d: invalid usage list\n", r->lnr);
223 return -1; /* error */
226 r->u.usage = use;
227 return 0;
231 static unsigned int
232 get_parameter_uint (struct para_data_s *para, enum para_name key)
234 struct para_data_s *r = get_parameter (para, key, 0);
236 if (!r)
237 return 0;
239 if (r->key == pKEYUSAGE)
240 return r->u.usage;
242 return (unsigned int)strtoul (r->u.value, NULL, 10);
247 /* Read the certificate generation parameters from FP and generate
248 (all) certificate requests. */
249 static int
250 read_parameters (ctrl_t ctrl, estream_t fp, ksba_writer_t writer)
252 static struct {
253 const char *name;
254 enum para_name key;
255 int allow_dups;
256 } keywords[] = {
257 { "Key-Type", pKEYTYPE},
258 { "Key-Length", pKEYLENGTH },
259 { "Key-Grip", pKEYGRIP },
260 { "Key-Usage", pKEYUSAGE },
261 { "Name-DN", pNAMEDN },
262 { "Name-Email", pNAMEEMAIL, 1 },
263 { "Name-DNS", pNAMEDNS, 1 },
264 { "Name-URI", pNAMEURI, 1 },
265 { NULL, 0 }
267 char line[1024], *p;
268 const char *err = NULL;
269 struct para_data_s *para, *r;
270 int i, rc = 0, any = 0;
271 struct reqgen_ctrl_s outctrl;
273 memset (&outctrl, 0, sizeof (outctrl));
274 outctrl.writer = writer;
276 err = NULL;
277 para = NULL;
278 while (es_fgets (line, DIM(line)-1, fp) )
280 char *keyword, *value;
282 outctrl.lnr++;
283 if (*line && line[strlen(line)-1] != '\n')
285 err = "line too long";
286 break;
288 for (p=line; spacep (p); p++)
290 if (!*p || *p == '#')
291 continue;
293 keyword = p;
294 if (*keyword == '%')
296 for (; *p && !spacep (p); p++)
298 if (*p)
299 *p++ = 0;
300 for (; spacep (p); p++)
302 value = p;
303 trim_trailing_spaces (value);
305 if (!ascii_strcasecmp (keyword, "%echo"))
306 log_info ("%s\n", value);
307 else if (!ascii_strcasecmp (keyword, "%dry-run"))
308 outctrl.dryrun = 1;
309 else if (!ascii_strcasecmp( keyword, "%commit"))
311 rc = proc_parameters (ctrl, para, &outctrl);
312 if (rc)
313 goto leave;
314 any = 1;
315 release_parameter_list (para);
316 para = NULL;
318 else
319 log_info ("skipping control `%s' (%s)\n", keyword, value);
321 continue;
325 if (!(p = strchr (p, ':')) || p == keyword)
327 err = "missing colon";
328 break;
330 if (*p)
331 *p++ = 0;
332 for (; spacep (p); p++)
334 if (!*p)
336 err = "missing argument";
337 break;
339 value = p;
340 trim_trailing_spaces (value);
342 for (i=0; (keywords[i].name
343 && ascii_strcasecmp (keywords[i].name, keyword)); i++)
345 if (!keywords[i].name)
347 err = "unknown keyword";
348 break;
350 if (keywords[i].key != pKEYTYPE && !para)
352 err = "parameter block does not start with \"Key-Type\"";
353 break;
356 if (keywords[i].key == pKEYTYPE && para)
358 rc = proc_parameters (ctrl, para, &outctrl);
359 if (rc)
360 goto leave;
361 any = 1;
362 release_parameter_list (para);
363 para = NULL;
365 else if (!keywords[i].allow_dups)
367 for (r = para; r && r->key != keywords[i].key; r = r->next)
369 if (r)
371 err = "duplicate keyword";
372 break;
376 r = xtrycalloc (1, sizeof *r + strlen( value ));
377 if (!r)
379 err = "out of core";
380 break;
382 r->lnr = outctrl.lnr;
383 r->key = keywords[i].key;
384 strcpy (r->u.value, value);
385 r->next = para;
386 para = r;
389 if (err)
391 log_error ("line %d: %s\n", outctrl.lnr, err);
392 rc = gpg_error (GPG_ERR_GENERAL);
394 else if (es_ferror(fp))
396 log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) );
397 rc = gpg_error (GPG_ERR_GENERAL);
399 else if (para)
401 rc = proc_parameters (ctrl, para, &outctrl);
402 if (rc)
403 goto leave;
404 any = 1;
407 if (!rc && !any)
408 rc = gpg_error (GPG_ERR_NO_DATA);
410 leave:
411 release_parameter_list (para);
412 return rc;
415 /* check whether there are invalid characters in the email address S */
416 static int
417 has_invalid_email_chars (const char *s)
419 int at_seen=0;
420 static char valid_chars[] = "01234567890_-."
421 "abcdefghijklmnopqrstuvwxyz"
422 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
423 for (; *s; s++)
425 if (*s & 0x80)
426 return 1;
427 if (*s == '@')
428 at_seen++;
429 else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+'))
430 return 1;
431 else if (at_seen && !strchr (valid_chars, *s))
432 return 1;
434 return at_seen != 1;
438 /* Check that all required parameters are given and perform the action */
439 static int
440 proc_parameters (ctrl_t ctrl,
441 struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
443 gpg_error_t err;
444 struct para_data_s *r;
445 const char *s;
446 int i;
447 unsigned int nbits;
448 char numbuf[20];
449 unsigned char keyparms[100];
450 int rc;
451 ksba_sexp_t public;
452 int seq;
453 size_t erroff, errlen;
454 char *cardkeyid = NULL;
456 /* Check that we have all required parameters; */
457 assert (get_parameter (para, pKEYTYPE, 0));
459 /* We can only use RSA for now. There is a problem with pkcs-10 on
460 how to use ElGamal because it is expected that a PK algorithm can
461 always be used for signing. Another problem is that on-card
462 generated encryption keys may not be used for signing. */
463 i = get_parameter_algo (para, pKEYTYPE);
464 if (!i && (s = get_parameter_value (para, pKEYTYPE, 0)) && *s)
466 /* Hack to allow creation of certificates directly from a smart
467 card. For example: "Key-Type: card:OPENPGP.3". */
468 if (!strncmp (s, "card:", 5) && s[5])
469 cardkeyid = xtrystrdup (s+5);
471 if ( (i < 1 || i != GCRY_PK_RSA) && !cardkeyid )
473 r = get_parameter (para, pKEYTYPE, 0);
474 log_error (_("line %d: invalid algorithm\n"), r->lnr);
475 return gpg_error (GPG_ERR_INV_PARAMETER);
478 /* Check the keylength. */
479 if (!get_parameter (para, pKEYLENGTH, 0))
480 nbits = 1024;
481 else
482 nbits = get_parameter_uint (para, pKEYLENGTH);
483 if ((nbits < 1024 || nbits > 4096) && !cardkeyid)
485 /* The BSI specs dated 2002-11-25 don't allow lengths below 1024. */
486 r = get_parameter (para, pKEYLENGTH, 0);
487 log_error (_("line %d: invalid key length %u (valid are %d to %d)\n"),
488 r->lnr, nbits, 1024, 4096);
489 xfree (cardkeyid);
490 return gpg_error (GPG_ERR_INV_PARAMETER);
493 /* Check the usage. */
494 if (parse_parameter_usage (para, pKEYUSAGE))
496 xfree (cardkeyid);
497 return gpg_error (GPG_ERR_INV_PARAMETER);
500 /* Check that there is a subject name and that this DN fits our
501 requirements. */
502 if (!(s=get_parameter_value (para, pNAMEDN, 0)))
504 r = get_parameter (para, pNAMEDN, 0);
505 log_error (_("line %d: no subject name given\n"), r->lnr);
506 xfree (cardkeyid);
507 return gpg_error (GPG_ERR_INV_PARAMETER);
509 err = ksba_dn_teststr (s, 0, &erroff, &errlen);
510 if (err)
512 r = get_parameter (para, pNAMEDN, 0);
513 if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME)
514 log_error (_("line %d: invalid subject name label `%.*s'\n"),
515 r->lnr, (int)errlen, s+erroff);
516 else
517 log_error (_("line %d: invalid subject name `%s' at pos %d\n"),
518 r->lnr, s, (int)erroff);
520 xfree (cardkeyid);
521 return gpg_error (GPG_ERR_INV_PARAMETER);
524 /* Check that the optional email address is okay. */
525 for (seq=0; (s=get_parameter_value (para, pNAMEEMAIL, seq)); seq++)
527 if (has_invalid_email_chars (s)
528 || *s == '@'
529 || s[strlen(s)-1] == '@'
530 || s[strlen(s)-1] == '.'
531 || strstr(s, ".."))
533 r = get_parameter (para, pNAMEEMAIL, seq);
534 log_error (_("line %d: not a valid email address\n"), r->lnr);
535 xfree (cardkeyid);
536 return gpg_error (GPG_ERR_INV_PARAMETER);
540 if (cardkeyid) /* Take the key from the current smart card. */
542 rc = gpgsm_agent_readkey (ctrl, 1, cardkeyid, &public);
543 if (rc)
545 r = get_parameter (para, pKEYTYPE, 0);
546 log_error (_("line %d: error reading key `%s' from card: %s\n"),
547 r->lnr, cardkeyid, gpg_strerror (rc));
548 xfree (cardkeyid);
549 return rc;
552 else if ((s=get_parameter_value (para, pKEYGRIP, 0))) /* Use existing key.*/
554 rc = gpgsm_agent_readkey (ctrl, 0, s, &public);
555 if (rc)
557 r = get_parameter (para, pKEYTYPE, 0);
558 log_error (_("line %d: error getting key by keygrip `%s': %s\n"),
559 r->lnr, s, gpg_strerror (rc));
560 xfree (cardkeyid);
561 return rc;
564 else /* Generate new key. */
566 sprintf (numbuf, "%u", nbits);
567 snprintf ((char*)keyparms, DIM (keyparms)-1,
568 "(6:genkey(3:rsa(5:nbits%d:%s)))",
569 (int)strlen (numbuf), numbuf);
570 rc = gpgsm_agent_genkey (ctrl, keyparms, &public);
571 if (rc)
573 r = get_parameter (para, pKEYTYPE, 0);
574 log_error (_("line %d: key generation failed: %s <%s>\n"),
575 r->lnr, gpg_strerror (rc), gpg_strsource (rc));
576 xfree (cardkeyid);
577 return rc;
581 rc = create_request (ctrl, para, cardkeyid, public, outctrl);
582 xfree (public);
583 xfree (cardkeyid);
585 return rc;
589 /* Parameters are checked, the key pair has been created. Now
590 generate the request and write it out */
591 static int
592 create_request (ctrl_t ctrl,
593 struct para_data_s *para,
594 const char *carddirect,
595 ksba_const_sexp_t public,
596 struct reqgen_ctrl_s *outctrl)
598 ksba_certreq_t cr;
599 gpg_error_t err;
600 gcry_md_hd_t md;
601 ksba_stop_reason_t stopreason;
602 int rc = 0;
603 const char *s;
604 unsigned int use;
605 int seq;
606 char *buf, *p;
607 size_t len;
608 char numbuf[30];
610 err = ksba_certreq_new (&cr);
611 if (err)
612 return err;
614 rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
615 if (rc)
617 log_error ("md_open failed: %s\n", gpg_strerror (rc));
618 goto leave;
620 if (DBG_HASHING)
621 gcry_md_start_debug (md, "cr.cri");
623 ksba_certreq_set_hash_function (cr, HASH_FNC, md);
624 ksba_certreq_set_writer (cr, outctrl->writer);
626 err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN, 0));
627 if (err)
629 log_error ("error setting the subject's name: %s\n",
630 gpg_strerror (err));
631 rc = err;
632 goto leave;
635 for (seq=0; (s = get_parameter_value (para, pNAMEEMAIL, seq)); seq++)
637 buf = xtrymalloc (strlen (s) + 3);
638 if (!buf)
640 rc = out_of_core ();
641 goto leave;
643 *buf = '<';
644 strcpy (buf+1, s);
645 strcat (buf+1, ">");
646 err = ksba_certreq_add_subject (cr, buf);
647 xfree (buf);
648 if (err)
650 log_error ("error setting the subject's alternate name: %s\n",
651 gpg_strerror (err));
652 rc = err;
653 goto leave;
657 for (seq=0; (s = get_parameter_value (para, pNAMEDNS, seq)); seq++)
659 len = strlen (s);
660 assert (len);
661 snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
662 buf = p = xtrymalloc (11 + strlen (numbuf) + len + 3);
663 if (!buf)
665 rc = out_of_core ();
666 goto leave;
668 p = stpcpy (p, "(8:dns-name");
669 p = stpcpy (p, numbuf);
670 p = stpcpy (p, s);
671 strcpy (p, ")");
673 err = ksba_certreq_add_subject (cr, buf);
674 xfree (buf);
675 if (err)
677 log_error ("error setting the subject's alternate name: %s\n",
678 gpg_strerror (err));
679 rc = err;
680 goto leave;
684 for (seq=0; (s = get_parameter_value (para, pNAMEURI, seq)); seq++)
686 len = strlen (s);
687 assert (len);
688 snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
689 buf = p = xtrymalloc (6 + strlen (numbuf) + len + 3);
690 if (!buf)
692 rc = out_of_core ();
693 goto leave;
695 p = stpcpy (p, "(3:uri");
696 p = stpcpy (p, numbuf);
697 p = stpcpy (p, s);
698 strcpy (p, ")");
700 err = ksba_certreq_add_subject (cr, buf);
701 xfree (buf);
702 if (err)
704 log_error ("error setting the subject's alternate name: %s\n",
705 gpg_strerror (err));
706 rc = err;
707 goto leave;
712 err = ksba_certreq_set_public_key (cr, public);
713 if (err)
715 log_error ("error setting the public key: %s\n",
716 gpg_strerror (err));
717 rc = err;
718 goto leave;
722 use = get_parameter_uint (para, pKEYUSAGE);
723 if (use == GCRY_PK_USAGE_SIGN)
725 /* For signing only we encode the bits:
726 KSBA_KEYUSAGE_DIGITAL_SIGNATURE
727 KSBA_KEYUSAGE_NON_REPUDIATION */
728 err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
729 "\x03\x02\x06\xC0", 4);
731 else if (use == GCRY_PK_USAGE_ENCR)
733 /* For encrypt only we encode the bits:
734 KSBA_KEYUSAGE_KEY_ENCIPHERMENT
735 KSBA_KEYUSAGE_DATA_ENCIPHERMENT */
736 err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
737 "\x03\x02\x04\x30", 4);
739 else
740 err = 0; /* Both or none given: don't request one. */
741 if (err)
743 log_error ("error setting the key usage: %s\n",
744 gpg_strerror (err));
745 rc = err;
746 goto leave;
752 err = ksba_certreq_build (cr, &stopreason);
753 if (err)
755 log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err));
756 rc = err;
757 goto leave;
759 if (stopreason == KSBA_SR_NEED_SIG)
761 gcry_sexp_t s_pkey;
762 size_t n;
763 unsigned char grip[20];
764 char hexgrip[41];
765 unsigned char *sigval;
766 size_t siglen;
768 n = gcry_sexp_canon_len (public, 0, NULL, NULL);
769 if (!n)
771 log_error ("libksba did not return a proper S-Exp\n");
772 err = gpg_error (GPG_ERR_BUG);
773 goto leave;
775 rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)public, n);
776 if (rc)
778 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
779 goto leave;
781 if ( !gcry_pk_get_keygrip (s_pkey, grip) )
783 rc = gpg_error (GPG_ERR_GENERAL);
784 log_error ("can't figure out the keygrip\n");
785 gcry_sexp_release (s_pkey);
786 goto leave;
788 gcry_sexp_release (s_pkey);
789 bin2hex (grip, 20, hexgrip);
791 if (carddirect)
792 rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
793 gcry_md_read(md, GCRY_MD_SHA1),
794 gcry_md_get_algo_dlen (GCRY_MD_SHA1),
795 GCRY_MD_SHA1,
796 &sigval, &siglen);
797 else
798 rc = gpgsm_agent_pksign (ctrl, hexgrip, NULL,
799 gcry_md_read(md, GCRY_MD_SHA1),
800 gcry_md_get_algo_dlen (GCRY_MD_SHA1),
801 GCRY_MD_SHA1,
802 &sigval, &siglen);
803 if (rc)
805 log_error ("signing failed: %s\n", gpg_strerror (rc));
806 goto leave;
809 err = ksba_certreq_set_sig_val (cr, sigval);
810 xfree (sigval);
811 if (err)
813 log_error ("failed to store the sig_val: %s\n",
814 gpg_strerror (err));
815 rc = err;
816 goto leave;
820 while (stopreason != KSBA_SR_READY);
823 leave:
824 gcry_md_close (md);
825 ksba_certreq_release (cr);
826 return rc;
831 /* Create a new key by reading the parameters from IN_FP. Multiple
832 keys may be created */
834 gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, FILE *out_fp)
836 int rc;
837 Base64Context b64writer = NULL;
838 ksba_writer_t writer;
840 ctrl->pem_name = "CERTIFICATE REQUEST";
841 rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
842 if (rc)
844 log_error ("can't create writer: %s\n", gpg_strerror (rc));
845 goto leave;
848 rc = read_parameters (ctrl, in_stream, writer);
849 if (rc)
851 log_error ("error creating certificate request: %s <%s>\n",
852 gpg_strerror (rc), gpg_strsource (rc));
853 goto leave;
856 rc = gpgsm_finish_writer (b64writer);
857 if (rc)
859 log_error ("write failed: %s\n", gpg_strerror (rc));
860 goto leave;
863 gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
864 log_info ("certificate request created\n");
866 leave:
867 gpgsm_destroy_writer (b64writer);
868 return rc;