Line data Source code
1 : /* certreqgen.c - Generate a key and a certification [request]
2 : * Copyright (C) 2002, 2003, 2005, 2007, 2010,
3 : * 2011 Free Software Foundation, Inc.
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * GnuPG is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : /*
22 : The format of the parameter file is described in the manual under
23 : "Unattended Usage".
24 :
25 : Here is an example:
26 : $ cat >foo <<EOF
27 : %echo Generating a standard key
28 : Key-Type: RSA
29 : Key-Length: 2048
30 : Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Ddorf,C=DE
31 : Name-Email: joe@foo.bar
32 : # Do a commit here, so that we can later print a "done"
33 : %commit
34 : %echo done
35 : EOF
36 :
37 : This parameter file was used to create the STEED CA:
38 : Key-Type: RSA
39 : Key-Length: 1024
40 : Key-Grip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
41 : Key-Usage: cert
42 : Serial: 1
43 : Name-DN: CN=The STEED Self-Signing Nonthority
44 : Not-Before: 2011-11-11
45 : Not-After: 2106-02-06
46 : Subject-Key-Id: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
47 : Extension: 2.5.29.19 c 30060101ff020101
48 : Extension: 1.3.6.1.4.1.11591.2.2.2 n 0101ff
49 : Signing-Key: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
50 : %commit
51 :
52 : */
53 :
54 :
55 : #include <config.h>
56 : #include <stdio.h>
57 : #include <stdlib.h>
58 : #include <string.h>
59 : #include <errno.h>
60 : #include <unistd.h>
61 : #include <time.h>
62 : #include <assert.h>
63 :
64 : #include "gpgsm.h"
65 : #include <gcrypt.h>
66 : #include <ksba.h>
67 :
68 : #include "keydb.h"
69 : #include "i18n.h"
70 :
71 :
72 : enum para_name
73 : {
74 : pKEYTYPE,
75 : pKEYLENGTH,
76 : pKEYGRIP,
77 : pKEYUSAGE,
78 : pNAMEDN,
79 : pNAMEEMAIL,
80 : pNAMEDNS,
81 : pNAMEURI,
82 : pSERIAL,
83 : pISSUERDN,
84 : pNOTBEFORE,
85 : pNOTAFTER,
86 : pSIGNINGKEY,
87 : pHASHALGO,
88 : pAUTHKEYID,
89 : pSUBJKEYID,
90 : pEXTENSION
91 : };
92 :
93 : struct para_data_s
94 : {
95 : struct para_data_s *next;
96 : int lnr;
97 : enum para_name key;
98 : union {
99 : unsigned int usage;
100 : char value[1];
101 : } u;
102 : };
103 :
104 : struct reqgen_ctrl_s
105 : {
106 : int lnr;
107 : int dryrun;
108 : };
109 :
110 :
111 : static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
112 : static const char oidstr_subjectKeyIdentifier[] = "2.5.29.14";
113 : static const char oidstr_keyUsage[] = "2.5.29.15";
114 : static const char oidstr_basicConstraints[] = "2.5.29.19";
115 : static const char oidstr_standaloneCertificate[] = "1.3.6.1.4.1.11591.2.2.1";
116 :
117 :
118 : static int proc_parameters (ctrl_t ctrl,
119 : struct para_data_s *para,
120 : estream_t out_fp,
121 : struct reqgen_ctrl_s *outctrl);
122 : static int create_request (ctrl_t ctrl,
123 : struct para_data_s *para,
124 : const char *carddirect,
125 : ksba_const_sexp_t public,
126 : ksba_const_sexp_t sigkey,
127 : ksba_writer_t writer);
128 :
129 :
130 :
131 : static void
132 0 : release_parameter_list (struct para_data_s *r)
133 : {
134 : struct para_data_s *r2;
135 :
136 0 : for (; r ; r = r2)
137 : {
138 0 : r2 = r->next;
139 0 : xfree(r);
140 : }
141 0 : }
142 :
143 : static struct para_data_s *
144 0 : get_parameter (struct para_data_s *para, enum para_name key, int seq)
145 : {
146 : struct para_data_s *r;
147 :
148 0 : for (r = para; r ; r = r->next)
149 0 : if ( r->key == key && !seq--)
150 0 : return r;
151 0 : return NULL;
152 : }
153 :
154 : static const char *
155 0 : get_parameter_value (struct para_data_s *para, enum para_name key, int seq)
156 : {
157 0 : struct para_data_s *r = get_parameter (para, key, seq);
158 0 : return (r && *r->u.value)? r->u.value : NULL;
159 : }
160 :
161 : static int
162 0 : get_parameter_algo (struct para_data_s *para, enum para_name key)
163 : {
164 0 : struct para_data_s *r = get_parameter (para, key, 0);
165 0 : if (!r)
166 0 : return -1;
167 0 : if (digitp (r->u.value))
168 0 : return atoi( r->u.value );
169 0 : return gcry_pk_map_name (r->u.value);
170 : }
171 :
172 : /* Parse the usage parameter. Returns 0 on success. Note that we
173 : only care about sign and encrypt and don't (yet) allow all the
174 : other X.509 usage to be specified; instead we will use a fixed
175 : mapping to the X.509 usage flags. */
176 : static int
177 0 : parse_parameter_usage (struct para_data_s *para, enum para_name key)
178 : {
179 0 : struct para_data_s *r = get_parameter (para, key, 0);
180 : char *p, *pn;
181 : unsigned int use;
182 :
183 0 : if (!r)
184 0 : return 0; /* none (this is an optional parameter)*/
185 :
186 0 : use = 0;
187 0 : pn = r->u.value;
188 0 : while ( (p = strsep (&pn, " \t,")) )
189 : {
190 0 : if (!*p)
191 : ;
192 0 : else if ( !ascii_strcasecmp (p, "sign") )
193 0 : use |= GCRY_PK_USAGE_SIGN;
194 0 : else if ( !ascii_strcasecmp (p, "encrypt")
195 0 : || !ascii_strcasecmp (p, "encr") )
196 0 : use |= GCRY_PK_USAGE_ENCR;
197 0 : else if ( !ascii_strcasecmp (p, "cert") )
198 0 : use |= GCRY_PK_USAGE_CERT;
199 : else
200 : {
201 0 : log_error ("line %d: invalid usage list\n", r->lnr);
202 0 : return -1; /* error */
203 : }
204 : }
205 0 : r->u.usage = use;
206 0 : return 0;
207 : }
208 :
209 :
210 : static unsigned int
211 0 : get_parameter_uint (struct para_data_s *para, enum para_name key)
212 : {
213 0 : struct para_data_s *r = get_parameter (para, key, 0);
214 :
215 0 : if (!r)
216 0 : return 0;
217 :
218 0 : if (r->key == pKEYUSAGE)
219 0 : return r->u.usage;
220 :
221 0 : return (unsigned int)strtoul (r->u.value, NULL, 10);
222 : }
223 :
224 :
225 :
226 : /* Read the certificate generation parameters from FP and generate
227 : (all) certificate requests. */
228 : static int
229 0 : read_parameters (ctrl_t ctrl, estream_t fp, estream_t out_fp)
230 : {
231 : static struct {
232 : const char *name;
233 : enum para_name key;
234 : int allow_dups;
235 : } keywords[] = {
236 : { "Key-Type", pKEYTYPE},
237 : { "Key-Length", pKEYLENGTH },
238 : { "Key-Grip", pKEYGRIP },
239 : { "Key-Usage", pKEYUSAGE },
240 : { "Name-DN", pNAMEDN },
241 : { "Name-Email", pNAMEEMAIL, 1 },
242 : { "Name-DNS", pNAMEDNS, 1 },
243 : { "Name-URI", pNAMEURI, 1 },
244 : { "Serial", pSERIAL },
245 : { "Issuer-DN", pISSUERDN },
246 : { "Creation-Date", pNOTBEFORE },
247 : { "Not-Before", pNOTBEFORE },
248 : { "Expire-Date", pNOTAFTER },
249 : { "Not-After", pNOTAFTER },
250 : { "Signing-Key", pSIGNINGKEY },
251 : { "Hash-Algo", pHASHALGO },
252 : { "Authority-Key-Id", pAUTHKEYID },
253 : { "Subject-Key-Id", pSUBJKEYID },
254 : { "Extension", pEXTENSION, 1 },
255 : { NULL, 0 }
256 : };
257 : char line[1024], *p;
258 0 : const char *err = NULL;
259 : struct para_data_s *para, *r;
260 0 : int i, rc = 0, any = 0;
261 : struct reqgen_ctrl_s outctrl;
262 :
263 0 : memset (&outctrl, 0, sizeof (outctrl));
264 :
265 0 : err = NULL;
266 0 : para = NULL;
267 0 : while (es_fgets (line, DIM(line)-1, fp) )
268 : {
269 : char *keyword, *value;
270 :
271 0 : outctrl.lnr++;
272 0 : if (*line && line[strlen(line)-1] != '\n')
273 : {
274 0 : err = "line too long";
275 0 : break;
276 : }
277 0 : for (p=line; spacep (p); p++)
278 : ;
279 0 : if (!*p || *p == '#')
280 0 : continue;
281 :
282 0 : keyword = p;
283 0 : if (*keyword == '%')
284 : {
285 0 : for (; *p && !ascii_isspace (*p); p++)
286 : ;
287 0 : if (*p)
288 0 : *p++ = 0;
289 0 : for (; ascii_isspace (*p); p++)
290 : ;
291 0 : value = p;
292 0 : trim_trailing_spaces (value);
293 :
294 0 : if (!ascii_strcasecmp (keyword, "%echo"))
295 0 : log_info ("%s\n", value);
296 0 : else if (!ascii_strcasecmp (keyword, "%dry-run"))
297 0 : outctrl.dryrun = 1;
298 0 : else if (!ascii_strcasecmp( keyword, "%commit"))
299 : {
300 0 : rc = proc_parameters (ctrl, para, out_fp, &outctrl);
301 0 : if (rc)
302 0 : goto leave;
303 0 : any = 1;
304 0 : release_parameter_list (para);
305 0 : para = NULL;
306 : }
307 : else
308 0 : log_info ("skipping control '%s' (%s)\n", keyword, value);
309 :
310 0 : continue;
311 : }
312 :
313 :
314 0 : if (!(p = strchr (p, ':')) || p == keyword)
315 : {
316 0 : err = "missing colon";
317 0 : break;
318 : }
319 0 : if (*p)
320 0 : *p++ = 0;
321 0 : for (; spacep (p); p++)
322 : ;
323 0 : if (!*p)
324 : {
325 0 : err = "missing argument";
326 0 : break;
327 : }
328 0 : value = p;
329 0 : trim_trailing_spaces (value);
330 :
331 0 : for (i=0; (keywords[i].name
332 0 : && ascii_strcasecmp (keywords[i].name, keyword)); i++)
333 : ;
334 0 : if (!keywords[i].name)
335 : {
336 0 : err = "unknown keyword";
337 0 : break;
338 : }
339 0 : if (keywords[i].key != pKEYTYPE && !para)
340 : {
341 0 : err = "parameter block does not start with \"Key-Type\"";
342 0 : break;
343 : }
344 :
345 0 : if (keywords[i].key == pKEYTYPE && para)
346 : {
347 0 : rc = proc_parameters (ctrl, para, out_fp, &outctrl);
348 0 : if (rc)
349 0 : goto leave;
350 0 : any = 1;
351 0 : release_parameter_list (para);
352 0 : para = NULL;
353 : }
354 0 : else if (!keywords[i].allow_dups)
355 : {
356 0 : for (r = para; r && r->key != keywords[i].key; r = r->next)
357 : ;
358 0 : if (r)
359 : {
360 0 : err = "duplicate keyword";
361 0 : break;
362 : }
363 : }
364 :
365 0 : r = xtrycalloc (1, sizeof *r + strlen( value ));
366 0 : if (!r)
367 : {
368 0 : err = "out of core";
369 0 : break;
370 : }
371 0 : r->lnr = outctrl.lnr;
372 0 : r->key = keywords[i].key;
373 0 : strcpy (r->u.value, value);
374 0 : r->next = para;
375 0 : para = r;
376 : }
377 :
378 0 : if (err)
379 : {
380 0 : log_error ("line %d: %s\n", outctrl.lnr, err);
381 0 : rc = gpg_error (GPG_ERR_GENERAL);
382 : }
383 0 : else if (es_ferror(fp))
384 : {
385 0 : log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) );
386 0 : rc = gpg_error (GPG_ERR_GENERAL);
387 : }
388 0 : else if (para)
389 : {
390 0 : rc = proc_parameters (ctrl, para, out_fp, &outctrl);
391 0 : if (rc)
392 0 : goto leave;
393 0 : any = 1;
394 : }
395 :
396 0 : if (!rc && !any)
397 0 : rc = gpg_error (GPG_ERR_NO_DATA);
398 :
399 : leave:
400 0 : release_parameter_list (para);
401 0 : return rc;
402 : }
403 :
404 : /* check whether there are invalid characters in the email address S */
405 : static int
406 0 : has_invalid_email_chars (const char *s)
407 : {
408 0 : int at_seen=0;
409 : static char valid_chars[] = "01234567890_-."
410 : "abcdefghijklmnopqrstuvwxyz"
411 : "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
412 0 : for (; *s; s++)
413 : {
414 0 : if (*s & 0x80)
415 0 : return 1;
416 0 : if (*s == '@')
417 0 : at_seen++;
418 0 : else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+'))
419 0 : return 1;
420 0 : else if (at_seen && !strchr (valid_chars, *s))
421 0 : return 1;
422 : }
423 0 : return at_seen != 1;
424 : }
425 :
426 :
427 : /* Check that all required parameters are given and perform the action */
428 : static int
429 0 : proc_parameters (ctrl_t ctrl, struct para_data_s *para,
430 : estream_t out_fp, struct reqgen_ctrl_s *outctrl)
431 : {
432 : gpg_error_t err;
433 : struct para_data_s *r;
434 : const char *s, *string;
435 : int i;
436 : unsigned int nbits;
437 : char numbuf[20];
438 : unsigned char keyparms[100];
439 0 : int rc = 0;
440 0 : ksba_sexp_t public = NULL;
441 0 : ksba_sexp_t sigkey = NULL;
442 : int seq;
443 : size_t erroff, errlen;
444 0 : char *cardkeyid = NULL;
445 :
446 : /* Check that we have all required parameters; */
447 0 : assert (get_parameter (para, pKEYTYPE, 0));
448 :
449 : /* We can only use RSA for now. There is a problem with pkcs-10 on
450 : how to use ElGamal because it is expected that a PK algorithm can
451 : always be used for signing. Another problem is that on-card
452 : generated encryption keys may not be used for signing. */
453 0 : i = get_parameter_algo (para, pKEYTYPE);
454 0 : if (!i && (s = get_parameter_value (para, pKEYTYPE, 0)) && *s)
455 : {
456 : /* Hack to allow creation of certificates directly from a smart
457 : card. For example: "Key-Type: card:OPENPGP.3". */
458 0 : if (!strncmp (s, "card:", 5) && s[5])
459 0 : cardkeyid = xtrystrdup (s+5);
460 : }
461 0 : if ( (i < 1 || i != GCRY_PK_RSA) && !cardkeyid )
462 : {
463 0 : r = get_parameter (para, pKEYTYPE, 0);
464 0 : log_error (_("line %d: invalid algorithm\n"), r->lnr);
465 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
466 : }
467 :
468 : /* Check the keylength. NOTE: If you change this make sure that it
469 : macthes the gpgconflist item in gpgsm.c */
470 0 : if (!get_parameter (para, pKEYLENGTH, 0))
471 0 : nbits = 2048;
472 : else
473 0 : nbits = get_parameter_uint (para, pKEYLENGTH);
474 0 : if ((nbits < 1024 || nbits > 4096) && !cardkeyid)
475 : {
476 : /* The BSI specs dated 2002-11-25 don't allow lengths below 1024. */
477 0 : r = get_parameter (para, pKEYLENGTH, 0);
478 0 : log_error (_("line %d: invalid key length %u (valid are %d to %d)\n"),
479 : r->lnr, nbits, 1024, 4096);
480 0 : xfree (cardkeyid);
481 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
482 : }
483 :
484 : /* Check the usage. */
485 0 : if (parse_parameter_usage (para, pKEYUSAGE))
486 : {
487 0 : xfree (cardkeyid);
488 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
489 : }
490 :
491 : /* Check that there is a subject name and that this DN fits our
492 : requirements. */
493 0 : if (!(s=get_parameter_value (para, pNAMEDN, 0)))
494 : {
495 0 : r = get_parameter (para, pNAMEDN, 0);
496 0 : log_error (_("line %d: no subject name given\n"), r->lnr);
497 0 : xfree (cardkeyid);
498 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
499 : }
500 0 : err = ksba_dn_teststr (s, 0, &erroff, &errlen);
501 0 : if (err)
502 : {
503 0 : r = get_parameter (para, pNAMEDN, 0);
504 0 : if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME)
505 0 : log_error (_("line %d: invalid subject name label '%.*s'\n"),
506 : r->lnr, (int)errlen, s+erroff);
507 : else
508 0 : log_error (_("line %d: invalid subject name '%s' at pos %d\n"),
509 : r->lnr, s, (int)erroff);
510 :
511 0 : xfree (cardkeyid);
512 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
513 : }
514 :
515 : /* Check that the optional email address is okay. */
516 0 : for (seq=0; (s=get_parameter_value (para, pNAMEEMAIL, seq)); seq++)
517 : {
518 0 : if (has_invalid_email_chars (s)
519 0 : || *s == '@'
520 0 : || s[strlen(s)-1] == '@'
521 0 : || s[strlen(s)-1] == '.'
522 0 : || strstr(s, ".."))
523 : {
524 0 : r = get_parameter (para, pNAMEEMAIL, seq);
525 0 : log_error (_("line %d: not a valid email address\n"), r->lnr);
526 0 : xfree (cardkeyid);
527 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
528 : }
529 : }
530 :
531 : /* Check the optional serial number. */
532 0 : string = get_parameter_value (para, pSERIAL, 0);
533 0 : if (string)
534 : {
535 0 : if (!strcmp (string, "random"))
536 : ; /* Okay. */
537 : else
538 : {
539 0 : for (s=string, i=0; hexdigitp (s); s++, i++)
540 : ;
541 0 : if (*s)
542 : {
543 0 : r = get_parameter (para, pSERIAL, 0);
544 0 : log_error (_("line %d: invalid serial number\n"), r->lnr);
545 0 : xfree (cardkeyid);
546 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
547 : }
548 : }
549 : }
550 :
551 : /* Check the optional issuer DN. */
552 0 : string = get_parameter_value (para, pISSUERDN, 0);
553 0 : if (string)
554 : {
555 0 : err = ksba_dn_teststr (string, 0, &erroff, &errlen);
556 0 : if (err)
557 : {
558 0 : r = get_parameter (para, pISSUERDN, 0);
559 0 : if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME)
560 0 : log_error (_("line %d: invalid issuer name label '%.*s'\n"),
561 : r->lnr, (int)errlen, string+erroff);
562 : else
563 0 : log_error (_("line %d: invalid issuer name '%s' at pos %d\n"),
564 : r->lnr, string, (int)erroff);
565 0 : xfree (cardkeyid);
566 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
567 : }
568 : }
569 :
570 : /* Check the optional creation date. */
571 0 : string = get_parameter_value (para, pNOTBEFORE, 0);
572 0 : if (string && !string2isotime (NULL, string))
573 : {
574 0 : r = get_parameter (para, pNOTBEFORE, 0);
575 0 : log_error (_("line %d: invalid date given\n"), r->lnr);
576 0 : xfree (cardkeyid);
577 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
578 : }
579 :
580 :
581 : /* Check the optional expire date. */
582 0 : string = get_parameter_value (para, pNOTAFTER, 0);
583 0 : if (string && !string2isotime (NULL, string))
584 : {
585 0 : r = get_parameter (para, pNOTAFTER, 0);
586 0 : log_error (_("line %d: invalid date given\n"), r->lnr);
587 0 : xfree (cardkeyid);
588 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
589 : }
590 :
591 : /* Get the optional signing key. */
592 0 : string = get_parameter_value (para, pSIGNINGKEY, 0);
593 0 : if (string)
594 : {
595 0 : rc = gpgsm_agent_readkey (ctrl, 0, string, &sigkey);
596 0 : if (rc)
597 : {
598 0 : r = get_parameter (para, pKEYTYPE, 0);
599 0 : log_error (_("line %d: error getting signing key by keygrip '%s'"
600 : ": %s\n"), r->lnr, s, gpg_strerror (rc));
601 0 : xfree (cardkeyid);
602 0 : return rc;
603 : }
604 : }
605 :
606 : /* Check the optional hash-algo. */
607 : {
608 : int mdalgo;
609 :
610 0 : string = get_parameter_value (para, pHASHALGO, 0);
611 0 : if (string && !((mdalgo = gcry_md_map_name (string))
612 : && (mdalgo == GCRY_MD_SHA1
613 0 : || mdalgo == GCRY_MD_SHA256
614 0 : || mdalgo == GCRY_MD_SHA384
615 0 : || mdalgo == GCRY_MD_SHA512)))
616 : {
617 0 : r = get_parameter (para, pHASHALGO, 0);
618 0 : log_error (_("line %d: invalid hash algorithm given\n"), r->lnr);
619 0 : xfree (cardkeyid);
620 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
621 : }
622 : }
623 :
624 : /* Check the optional AuthorityKeyId. */
625 0 : string = get_parameter_value (para, pAUTHKEYID, 0);
626 0 : if (string)
627 : {
628 0 : for (s=string, i=0; hexdigitp (s); s++, i++)
629 : ;
630 0 : if (*s || (i&1))
631 : {
632 0 : r = get_parameter (para, pAUTHKEYID, 0);
633 0 : log_error (_("line %d: invalid authority-key-id\n"), r->lnr);
634 0 : xfree (cardkeyid);
635 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
636 : }
637 : }
638 :
639 : /* Check the optional SubjectKeyId. */
640 0 : string = get_parameter_value (para, pSUBJKEYID, 0);
641 0 : if (string)
642 : {
643 0 : for (s=string, i=0; hexdigitp (s); s++, i++)
644 : ;
645 0 : if (*s || (i&1))
646 : {
647 0 : r = get_parameter (para, pSUBJKEYID, 0);
648 0 : log_error (_("line %d: invalid subject-key-id\n"), r->lnr);
649 0 : xfree (cardkeyid);
650 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
651 : }
652 : }
653 :
654 : /* Check the optional extensions. */
655 0 : for (seq=0; (string=get_parameter_value (para, pEXTENSION, seq)); seq++)
656 : {
657 0 : int okay = 0;
658 :
659 0 : s = strpbrk (string, " \t:");
660 0 : if (s)
661 : {
662 0 : s++;
663 0 : while (spacep (s))
664 0 : s++;
665 0 : if (*s && strchr ("nNcC", *s))
666 : {
667 0 : s++;
668 0 : while (spacep (s))
669 0 : s++;
670 0 : if (*s == ':')
671 0 : s++;
672 0 : if (*s)
673 : {
674 0 : while (spacep (s))
675 0 : s++;
676 0 : for (i=0; hexdigitp (s); s++, i++)
677 : ;
678 0 : if (!((*s && *s != ':') || !i || (i&1)))
679 0 : okay = 1;
680 : }
681 : }
682 : }
683 0 : if (!okay)
684 : {
685 0 : r = get_parameter (para, pEXTENSION, seq);
686 0 : log_error (_("line %d: invalid extension syntax\n"), r->lnr);
687 0 : xfree (cardkeyid);
688 0 : return gpg_error (GPG_ERR_INV_PARAMETER);
689 : }
690 : }
691 :
692 : /* Create or retrieve the public key. */
693 0 : if (cardkeyid) /* Take the key from the current smart card. */
694 : {
695 0 : rc = gpgsm_agent_readkey (ctrl, 1, cardkeyid, &public);
696 0 : if (rc)
697 : {
698 0 : r = get_parameter (para, pKEYTYPE, 0);
699 0 : log_error (_("line %d: error reading key '%s' from card: %s\n"),
700 : r->lnr, cardkeyid, gpg_strerror (rc));
701 0 : xfree (sigkey);
702 0 : xfree (cardkeyid);
703 0 : return rc;
704 : }
705 : }
706 0 : else if ((s=get_parameter_value (para, pKEYGRIP, 0))) /* Use existing key.*/
707 : {
708 0 : rc = gpgsm_agent_readkey (ctrl, 0, s, &public);
709 0 : if (rc)
710 : {
711 0 : r = get_parameter (para, pKEYTYPE, 0);
712 0 : log_error (_("line %d: error getting key by keygrip '%s': %s\n"),
713 : r->lnr, s, gpg_strerror (rc));
714 0 : xfree (sigkey);
715 0 : xfree (cardkeyid);
716 0 : return rc;
717 : }
718 : }
719 0 : else if (!outctrl->dryrun) /* Generate new key. */
720 : {
721 0 : sprintf (numbuf, "%u", nbits);
722 0 : snprintf ((char*)keyparms, DIM (keyparms)-1,
723 : "(6:genkey(3:rsa(5:nbits%d:%s)))",
724 0 : (int)strlen (numbuf), numbuf);
725 0 : rc = gpgsm_agent_genkey (ctrl, keyparms, &public);
726 0 : if (rc)
727 : {
728 0 : r = get_parameter (para, pKEYTYPE, 0);
729 0 : log_error (_("line %d: key generation failed: %s <%s>\n"),
730 : r->lnr, gpg_strerror (rc), gpg_strsource (rc));
731 0 : xfree (sigkey);
732 0 : xfree (cardkeyid);
733 0 : return rc;
734 : }
735 : }
736 :
737 :
738 0 : if (!outctrl->dryrun)
739 : {
740 0 : Base64Context b64writer = NULL;
741 : ksba_writer_t writer;
742 : int create_cert ;
743 :
744 0 : create_cert = !!get_parameter_value (para, pSERIAL, 0);
745 :
746 0 : ctrl->pem_name = create_cert? "CERTIFICATE" : "CERTIFICATE REQUEST";
747 0 : rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
748 0 : if (rc)
749 0 : log_error ("can't create writer: %s\n", gpg_strerror (rc));
750 : else
751 : {
752 0 : rc = create_request (ctrl, para, cardkeyid, public, sigkey, writer);
753 0 : if (!rc)
754 : {
755 0 : rc = gpgsm_finish_writer (b64writer);
756 0 : if (rc)
757 0 : log_error ("write failed: %s\n", gpg_strerror (rc));
758 : else
759 : {
760 0 : gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
761 0 : log_info ("certificate%s created\n",
762 : create_cert?"":" request");
763 : }
764 : }
765 0 : gpgsm_destroy_writer (b64writer);
766 : }
767 : }
768 :
769 0 : xfree (sigkey);
770 0 : xfree (public);
771 0 : xfree (cardkeyid);
772 :
773 0 : return rc;
774 : }
775 :
776 :
777 : /* Parameters are checked, the key pair has been created. Now
778 : generate the request and write it out */
779 : static int
780 0 : create_request (ctrl_t ctrl,
781 : struct para_data_s *para,
782 : const char *carddirect,
783 : ksba_const_sexp_t public,
784 : ksba_const_sexp_t sigkey,
785 : ksba_writer_t writer)
786 : {
787 : ksba_certreq_t cr;
788 : gpg_error_t err;
789 : gcry_md_hd_t md;
790 : ksba_stop_reason_t stopreason;
791 0 : int rc = 0;
792 : const char *s, *string;
793 : unsigned int use;
794 : int seq;
795 : char *buf, *p;
796 : size_t len;
797 : char numbuf[30];
798 : ksba_isotime_t atime;
799 0 : int certmode = 0;
800 : int mdalgo;
801 :
802 0 : err = ksba_certreq_new (&cr);
803 0 : if (err)
804 0 : return err;
805 :
806 0 : string = get_parameter_value (para, pHASHALGO, 0);
807 0 : if (string)
808 0 : mdalgo = gcry_md_map_name (string);
809 : else
810 0 : mdalgo = GCRY_MD_SHA256;
811 0 : rc = gcry_md_open (&md, mdalgo, 0);
812 0 : if (rc)
813 : {
814 0 : log_error ("md_open failed: %s\n", gpg_strerror (rc));
815 0 : goto leave;
816 : }
817 0 : if (DBG_HASHING)
818 0 : gcry_md_debug (md, "cr.cri");
819 :
820 0 : ksba_certreq_set_hash_function (cr, HASH_FNC, md);
821 0 : ksba_certreq_set_writer (cr, writer);
822 :
823 0 : err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN, 0));
824 0 : if (err)
825 : {
826 0 : log_error ("error setting the subject's name: %s\n",
827 : gpg_strerror (err));
828 0 : rc = err;
829 0 : goto leave;
830 : }
831 :
832 0 : for (seq=0; (s = get_parameter_value (para, pNAMEEMAIL, seq)); seq++)
833 : {
834 0 : buf = xtrymalloc (strlen (s) + 3);
835 0 : if (!buf)
836 : {
837 0 : rc = out_of_core ();
838 0 : goto leave;
839 : }
840 0 : *buf = '<';
841 0 : strcpy (buf+1, s);
842 0 : strcat (buf+1, ">");
843 0 : err = ksba_certreq_add_subject (cr, buf);
844 0 : xfree (buf);
845 0 : if (err)
846 : {
847 0 : log_error ("error setting the subject's alternate name: %s\n",
848 : gpg_strerror (err));
849 0 : rc = err;
850 0 : goto leave;
851 : }
852 : }
853 :
854 0 : for (seq=0; (s = get_parameter_value (para, pNAMEDNS, seq)); seq++)
855 : {
856 0 : len = strlen (s);
857 0 : assert (len);
858 0 : snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
859 0 : buf = p = xtrymalloc (11 + strlen (numbuf) + len + 3);
860 0 : if (!buf)
861 : {
862 0 : rc = out_of_core ();
863 0 : goto leave;
864 : }
865 0 : p = stpcpy (p, "(8:dns-name");
866 0 : p = stpcpy (p, numbuf);
867 0 : p = stpcpy (p, s);
868 0 : strcpy (p, ")");
869 :
870 0 : err = ksba_certreq_add_subject (cr, buf);
871 0 : xfree (buf);
872 0 : if (err)
873 : {
874 0 : log_error ("error setting the subject's alternate name: %s\n",
875 : gpg_strerror (err));
876 0 : rc = err;
877 0 : goto leave;
878 : }
879 : }
880 :
881 0 : for (seq=0; (s = get_parameter_value (para, pNAMEURI, seq)); seq++)
882 : {
883 0 : len = strlen (s);
884 0 : assert (len);
885 0 : snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
886 0 : buf = p = xtrymalloc (6 + strlen (numbuf) + len + 3);
887 0 : if (!buf)
888 : {
889 0 : rc = out_of_core ();
890 0 : goto leave;
891 : }
892 0 : p = stpcpy (p, "(3:uri");
893 0 : p = stpcpy (p, numbuf);
894 0 : p = stpcpy (p, s);
895 0 : strcpy (p, ")");
896 :
897 0 : err = ksba_certreq_add_subject (cr, buf);
898 0 : xfree (buf);
899 0 : if (err)
900 : {
901 0 : log_error ("error setting the subject's alternate name: %s\n",
902 : gpg_strerror (err));
903 0 : rc = err;
904 0 : goto leave;
905 : }
906 : }
907 :
908 :
909 0 : err = ksba_certreq_set_public_key (cr, public);
910 0 : if (err)
911 : {
912 0 : log_error ("error setting the public key: %s\n",
913 : gpg_strerror (err));
914 0 : rc = err;
915 0 : goto leave;
916 : }
917 :
918 : /* Set key usage flags. */
919 0 : use = get_parameter_uint (para, pKEYUSAGE);
920 0 : if (use)
921 : {
922 : unsigned int mask, pos;
923 : unsigned char der[4];
924 :
925 0 : der[0] = 0x03;
926 0 : der[1] = 0x02;
927 0 : der[2] = 0;
928 0 : der[3] = 0;
929 0 : if ((use & GCRY_PK_USAGE_SIGN))
930 : {
931 : /* For signing only we encode the bits:
932 : KSBA_KEYUSAGE_DIGITAL_SIGNATURE
933 : KSBA_KEYUSAGE_NON_REPUDIATION = 0b11 -> 0b11000000 */
934 0 : der[3] |= 0xc0;
935 : }
936 0 : if ((use & GCRY_PK_USAGE_ENCR))
937 : {
938 : /* For encrypt only we encode the bits:
939 : KSBA_KEYUSAGE_KEY_ENCIPHERMENT
940 : KSBA_KEYUSAGE_DATA_ENCIPHERMENT = 0b1100 -> 0b00110000 */
941 0 : der[3] |= 0x30;
942 : }
943 0 : if ((use & GCRY_PK_USAGE_CERT))
944 : {
945 : /* For certify only we encode the bits:
946 : KSBA_KEYUSAGE_KEY_CERT_SIGN
947 : KSBA_KEYUSAGE_CRL_SIGN = 0b1100000 -> 0b00000110 */
948 0 : der[3] |= 0x06;
949 : }
950 :
951 : /* Count number of unused bits. */
952 0 : for (mask=1, pos=0; pos < 8 * sizeof mask; pos++, mask <<= 1)
953 : {
954 0 : if ((der[3] & mask))
955 0 : break;
956 0 : der[2]++;
957 : }
958 :
959 0 : err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, der, 4);
960 0 : if (err)
961 : {
962 0 : log_error ("error setting the key usage: %s\n",
963 : gpg_strerror (err));
964 0 : rc = err;
965 0 : goto leave;
966 : }
967 : }
968 :
969 :
970 : /* See whether we want to create an X.509 certificate. */
971 0 : string = get_parameter_value (para, pSERIAL, 0);
972 0 : if (string)
973 : {
974 0 : certmode = 1;
975 :
976 : /* Store the serial number. */
977 0 : if (!strcmp (string, "random"))
978 : {
979 : char snbuf[3+8+1];
980 :
981 0 : memcpy (snbuf, "(8:", 3);
982 0 : gcry_create_nonce (snbuf+3, 8);
983 : /* Clear high bit to guarantee a positive integer. */
984 0 : snbuf[3] &= 0x7f;
985 0 : snbuf[3+8] = ')';
986 0 : err = ksba_certreq_set_serial (cr, snbuf);
987 : }
988 : else
989 : {
990 : char *hexbuf;
991 :
992 : /* Allocate a buffer large enough to prefix the string with
993 : a '0' so to have an even number of digits. Prepend two
994 : further '0' so that the binary result will have a leading
995 : 0 byte and thus can't be the representation of a negative
996 : number. Note that ksba_certreq_set_serial strips all
997 : unneeded leading 0 bytes. */
998 0 : hexbuf = p = xtrymalloc (2 + 1 + strlen (string) + 1);
999 0 : if (!hexbuf)
1000 : {
1001 0 : err = gpg_error_from_syserror ();
1002 0 : goto leave;
1003 : }
1004 0 : if ((strlen (string) & 1))
1005 0 : *p++ = '0';
1006 0 : *p++ = '0';
1007 0 : *p++ = '0';
1008 0 : strcpy (p, string);
1009 0 : for (p=hexbuf, len=0; p[0] && p[1]; p += 2)
1010 0 : ((unsigned char*)hexbuf)[len++] = xtoi_2 (p);
1011 : /* Now build the S-expression. */
1012 0 : snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len);
1013 0 : buf = p = xtrymalloc (1 + strlen (numbuf) + len + 1 + 1);
1014 0 : if (!buf)
1015 : {
1016 0 : err = gpg_error_from_syserror ();
1017 0 : xfree (hexbuf);
1018 0 : goto leave;
1019 : }
1020 0 : p = stpcpy (stpcpy (buf, "("), numbuf);
1021 0 : memcpy (p, hexbuf, len);
1022 0 : p += len;
1023 0 : strcpy (p, ")");
1024 0 : xfree (hexbuf);
1025 0 : err = ksba_certreq_set_serial (cr, buf);
1026 0 : xfree (buf);
1027 : }
1028 0 : if (err)
1029 : {
1030 0 : log_error ("error setting the serial number: %s\n",
1031 : gpg_strerror (err));
1032 0 : goto leave;
1033 : }
1034 :
1035 :
1036 : /* Store the issuer DN. If no issuer DN is given and no signing
1037 : key has been set we add the standalone extension and the
1038 : basic constraints to mark it as a self-signed CA
1039 : certificate. */
1040 0 : string = get_parameter_value (para, pISSUERDN, 0);
1041 0 : if (string)
1042 : {
1043 : /* Issuer DN given. Note that this may be the same as the
1044 : subject DN and thus this could as well be a self-signed
1045 : certificate. However the caller needs to explicitly
1046 : specify basicConstraints and so forth. */
1047 0 : err = ksba_certreq_set_issuer (cr, string);
1048 0 : if (err)
1049 : {
1050 0 : log_error ("error setting the issuer DN: %s\n",
1051 : gpg_strerror (err));
1052 0 : goto leave;
1053 : }
1054 :
1055 : }
1056 0 : else if (!string && !sigkey)
1057 : {
1058 : /* Self-signed certificate requested. Add basicConstraints
1059 : and the custom GnuPG standalone extension. */
1060 0 : err = ksba_certreq_add_extension (cr, oidstr_basicConstraints, 1,
1061 : "\x30\x03\x01\x01\xff", 5);
1062 0 : if (err)
1063 0 : goto leave;
1064 0 : err = ksba_certreq_add_extension (cr, oidstr_standaloneCertificate, 0,
1065 : "\x01\x01\xff", 3);
1066 0 : if (err)
1067 0 : goto leave;
1068 : }
1069 :
1070 : /* Store the creation date. */
1071 0 : string = get_parameter_value (para, pNOTBEFORE, 0);
1072 0 : if (string)
1073 : {
1074 0 : if (!string2isotime (atime, string))
1075 0 : BUG (); /* We already checked the value. */
1076 : }
1077 : else
1078 0 : gnupg_get_isotime (atime);
1079 0 : err = ksba_certreq_set_validity (cr, 0, atime);
1080 0 : if (err)
1081 : {
1082 0 : log_error ("error setting the creation date: %s\n",
1083 : gpg_strerror (err));
1084 0 : goto leave;
1085 : }
1086 :
1087 :
1088 : /* Store the expire date. If it is not given, libksba inserts a
1089 : default value. */
1090 0 : string = get_parameter_value (para, pNOTAFTER, 0);
1091 0 : if (string)
1092 : {
1093 0 : if (!string2isotime (atime, string))
1094 0 : BUG (); /* We already checked the value. */
1095 0 : err = ksba_certreq_set_validity (cr, 1, atime);
1096 0 : if (err)
1097 : {
1098 0 : log_error ("error setting the expire date: %s\n",
1099 : gpg_strerror (err));
1100 0 : goto leave;
1101 : }
1102 : }
1103 :
1104 :
1105 : /* Figure out the signing algorithm. If no sigkey has been
1106 : given we set it to the public key to create a self-signed
1107 : certificate. */
1108 0 : if (!sigkey)
1109 0 : sigkey = public;
1110 :
1111 : {
1112 : unsigned char *siginfo;
1113 :
1114 0 : err = transform_sigval (sigkey,
1115 : gcry_sexp_canon_len (sigkey, 0, NULL, NULL),
1116 : mdalgo, &siginfo, NULL);
1117 0 : if (!err)
1118 : {
1119 0 : err = ksba_certreq_set_siginfo (cr, siginfo);
1120 0 : xfree (siginfo);
1121 : }
1122 0 : if (err)
1123 : {
1124 0 : log_error ("error setting the siginfo: %s\n",
1125 : gpg_strerror (err));
1126 0 : rc = err;
1127 0 : goto leave;
1128 : }
1129 : }
1130 :
1131 : /* Insert the AuthorityKeyId. */
1132 0 : string = get_parameter_value (para, pAUTHKEYID, 0);
1133 0 : if (string)
1134 : {
1135 : char *hexbuf;
1136 :
1137 : /* Allocate a buffer for in-place conversion. We also add 4
1138 : extra bytes space for the tags and lengths fields. */
1139 0 : hexbuf = xtrymalloc (4 + strlen (string) + 1);
1140 0 : if (!hexbuf)
1141 : {
1142 0 : err = gpg_error_from_syserror ();
1143 0 : goto leave;
1144 : }
1145 0 : strcpy (hexbuf+4, string);
1146 0 : for (p=hexbuf+4, len=0; p[0] && p[1]; p += 2)
1147 0 : ((unsigned char*)hexbuf)[4+len++] = xtoi_2 (p);
1148 0 : if (len > 125)
1149 : {
1150 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
1151 0 : xfree (hexbuf);
1152 0 : goto leave;
1153 : }
1154 0 : hexbuf[0] = 0x30; /* Tag for a Sequence. */
1155 0 : hexbuf[1] = len+2;
1156 0 : hexbuf[2] = 0x80; /* Context tag for an implicit Octet string. */
1157 0 : hexbuf[3] = len;
1158 0 : err = ksba_certreq_add_extension (cr, oidstr_authorityKeyIdentifier,
1159 : 0,
1160 : hexbuf, 4+len);
1161 0 : xfree (hexbuf);
1162 0 : if (err)
1163 : {
1164 0 : log_error ("error setting the authority-key-id: %s\n",
1165 : gpg_strerror (err));
1166 0 : goto leave;
1167 : }
1168 : }
1169 :
1170 : /* Insert the SubjectKeyId. */
1171 0 : string = get_parameter_value (para, pSUBJKEYID, 0);
1172 0 : if (string)
1173 : {
1174 : char *hexbuf;
1175 :
1176 : /* Allocate a buffer for in-place conversion. We also add 2
1177 : extra bytes space for the tag and length field. */
1178 0 : hexbuf = xtrymalloc (2 + strlen (string) + 1);
1179 0 : if (!hexbuf)
1180 : {
1181 0 : err = gpg_error_from_syserror ();
1182 0 : goto leave;
1183 : }
1184 0 : strcpy (hexbuf+2, string);
1185 0 : for (p=hexbuf+2, len=0; p[0] && p[1]; p += 2)
1186 0 : ((unsigned char*)hexbuf)[2+len++] = xtoi_2 (p);
1187 0 : if (len > 127)
1188 : {
1189 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
1190 0 : xfree (hexbuf);
1191 0 : goto leave;
1192 : }
1193 0 : hexbuf[0] = 0x04; /* Tag for an Octet string. */
1194 0 : hexbuf[1] = len;
1195 0 : err = ksba_certreq_add_extension (cr, oidstr_subjectKeyIdentifier, 0,
1196 : hexbuf, 2+len);
1197 0 : xfree (hexbuf);
1198 0 : if (err)
1199 : {
1200 0 : log_error ("error setting the subject-key-id: %s\n",
1201 : gpg_strerror (err));
1202 0 : goto leave;
1203 : }
1204 : }
1205 :
1206 : /* Insert additional extensions. */
1207 0 : for (seq=0; (string = get_parameter_value (para, pEXTENSION, seq)); seq++)
1208 : {
1209 : char *hexbuf;
1210 : char *oidstr;
1211 0 : int crit = 0;
1212 :
1213 0 : s = strpbrk (string, " \t:");
1214 0 : if (!s)
1215 : {
1216 0 : err = gpg_error (GPG_ERR_INTERNAL);
1217 0 : goto leave;
1218 : }
1219 :
1220 0 : oidstr = xtrymalloc (s - string + 1);
1221 0 : if (!oidstr)
1222 : {
1223 0 : err = gpg_error_from_syserror ();
1224 0 : goto leave;
1225 : }
1226 0 : memcpy (oidstr, string, (s-string));
1227 0 : oidstr[(s-string)] = 0;
1228 :
1229 0 : s++;
1230 0 : while (spacep (s))
1231 0 : s++;
1232 0 : if (!*s)
1233 : {
1234 0 : err = gpg_error (GPG_ERR_INTERNAL);
1235 0 : xfree (oidstr);
1236 0 : goto leave;
1237 : }
1238 :
1239 0 : if (strchr ("cC", *s))
1240 0 : crit = 1;
1241 0 : s++;
1242 0 : while (spacep (s))
1243 0 : s++;
1244 0 : if (*s == ':')
1245 0 : s++;
1246 0 : while (spacep (s))
1247 0 : s++;
1248 :
1249 0 : hexbuf = xtrystrdup (s);
1250 0 : if (!hexbuf)
1251 : {
1252 0 : err = gpg_error_from_syserror ();
1253 0 : xfree (oidstr);
1254 0 : goto leave;
1255 : }
1256 0 : for (p=hexbuf, len=0; p[0] && p[1]; p += 2)
1257 0 : ((unsigned char*)hexbuf)[len++] = xtoi_2 (p);
1258 0 : err = ksba_certreq_add_extension (cr, oidstr, crit,
1259 : hexbuf, len);
1260 0 : xfree (oidstr);
1261 0 : xfree (hexbuf);
1262 : }
1263 : }
1264 : else
1265 0 : sigkey = public;
1266 :
1267 : do
1268 : {
1269 0 : err = ksba_certreq_build (cr, &stopreason);
1270 0 : if (err)
1271 : {
1272 0 : log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err));
1273 0 : rc = err;
1274 0 : goto leave;
1275 : }
1276 0 : if (stopreason == KSBA_SR_NEED_SIG)
1277 : {
1278 : gcry_sexp_t s_pkey;
1279 : size_t n;
1280 : unsigned char grip[20];
1281 : char hexgrip[41];
1282 : unsigned char *sigval, *newsigval;
1283 : size_t siglen;
1284 :
1285 0 : n = gcry_sexp_canon_len (sigkey, 0, NULL, NULL);
1286 0 : if (!n)
1287 : {
1288 0 : log_error ("libksba did not return a proper S-Exp\n");
1289 0 : rc = gpg_error (GPG_ERR_BUG);
1290 0 : goto leave;
1291 : }
1292 0 : rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)sigkey, n);
1293 0 : if (rc)
1294 : {
1295 0 : log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
1296 0 : goto leave;
1297 : }
1298 0 : if ( !gcry_pk_get_keygrip (s_pkey, grip) )
1299 : {
1300 0 : rc = gpg_error (GPG_ERR_GENERAL);
1301 0 : log_error ("can't figure out the keygrip\n");
1302 0 : gcry_sexp_release (s_pkey);
1303 0 : goto leave;
1304 : }
1305 0 : gcry_sexp_release (s_pkey);
1306 0 : bin2hex (grip, 20, hexgrip);
1307 :
1308 0 : log_info ("about to sign the %s for key: &%s\n",
1309 : certmode? "certificate":"CSR", hexgrip);
1310 :
1311 0 : if (carddirect)
1312 0 : rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
1313 : gcry_md_read (md, mdalgo),
1314 0 : gcry_md_get_algo_dlen (mdalgo),
1315 : mdalgo,
1316 : &sigval, &siglen);
1317 : else
1318 : {
1319 : char *orig_codeset;
1320 : char *desc;
1321 :
1322 0 : orig_codeset = i18n_switchto_utf8 ();
1323 0 : desc = percent_plus_escape
1324 0 : (_("To complete this certificate request please enter"
1325 : " the passphrase for the key you just created once"
1326 : " more.\n"));
1327 0 : i18n_switchback (orig_codeset);
1328 0 : rc = gpgsm_agent_pksign (ctrl, hexgrip, desc,
1329 : gcry_md_read(md, mdalgo),
1330 0 : gcry_md_get_algo_dlen (mdalgo),
1331 : mdalgo,
1332 : &sigval, &siglen);
1333 0 : xfree (desc);
1334 : }
1335 0 : if (rc)
1336 : {
1337 0 : log_error ("signing failed: %s\n", gpg_strerror (rc));
1338 0 : goto leave;
1339 : }
1340 :
1341 0 : err = transform_sigval (sigval, siglen, mdalgo,
1342 : &newsigval, NULL);
1343 0 : xfree (sigval);
1344 0 : if (!err)
1345 : {
1346 0 : err = ksba_certreq_set_sig_val (cr, newsigval);
1347 0 : xfree (newsigval);
1348 : }
1349 0 : if (err)
1350 : {
1351 0 : log_error ("failed to store the sig_val: %s\n",
1352 : gpg_strerror (err));
1353 0 : rc = err;
1354 0 : goto leave;
1355 : }
1356 : }
1357 : }
1358 0 : while (stopreason != KSBA_SR_READY);
1359 :
1360 :
1361 : leave:
1362 0 : gcry_md_close (md);
1363 0 : ksba_certreq_release (cr);
1364 0 : return rc;
1365 : }
1366 :
1367 :
1368 :
1369 : /* Create a new key by reading the parameters from IN_FP. Multiple
1370 : keys may be created */
1371 : int
1372 0 : gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, estream_t out_stream)
1373 : {
1374 : int rc;
1375 :
1376 0 : rc = read_parameters (ctrl, in_stream, out_stream);
1377 0 : if (rc)
1378 : {
1379 0 : log_error ("error creating certificate request: %s <%s>\n",
1380 : gpg_strerror (rc), gpg_strsource (rc));
1381 0 : goto leave;
1382 : }
1383 :
1384 : leave:
1385 0 : return rc;
1386 : }
|