~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to sm/certreqgen.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* certreqgen.c - Generate a key and a certification request
 
2
 *      Copyright (C) 2002, 2003 Free Software Foundation, Inc.
 
3
 *
 
4
 * This file is part of GnuPG.
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
 
19
 */
 
20
 
 
21
/*
 
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"
 
37
  o Control statements:
 
38
    %echo <text>
 
39
        Print <text>.
 
40
    %dry-run
 
41
        Suppress actual key generation (useful for syntax checking).
 
42
    %commit
 
43
        Perform the key generation.  Note that an implicit commit is done
 
44
        at the next "Key-Type" parameter.
 
45
    %certfile <filename>
 
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:
 
59
     Key-Type: <algo>
 
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
 
63
        algorithm is "rsa".
 
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.
 
71
     Name-DN: subject name
 
72
        This is the DN name of the subject in rfc2253 format.
 
73
     Name-Email: <string>
 
74
        The ist the email address
 
75
 
 
76
Here is an example:
 
77
$ cat >foo <<EOF
 
78
%echo Generating a standard key
 
79
Key-Type: RSA
 
80
Key-Length: 1024
 
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" :-)
 
84
%commit
 
85
%echo done
 
86
EOF
 
87
*/
 
88
 
 
89
 
 
90
#include <config.h>
 
91
#include <stdio.h>
 
92
#include <stdlib.h>
 
93
#include <string.h>
 
94
#include <errno.h>
 
95
#include <unistd.h> 
 
96
#include <time.h>
 
97
#include <assert.h>
 
98
 
 
99
#include "gpgsm.h"
 
100
#include <gcrypt.h>
 
101
#include <ksba.h>
 
102
 
 
103
#include "keydb.h"
 
104
#include "i18n.h"
 
105
 
 
106
 
 
107
enum para_name {
 
108
  pKEYTYPE,
 
109
  pKEYLENGTH,
 
110
  pKEYUSAGE,
 
111
  pNAMEDN,
 
112
  pNAMEEMAIL
 
113
};
 
114
 
 
115
struct para_data_s {
 
116
  struct para_data_s *next;
 
117
  int lnr;
 
118
  enum para_name key;
 
119
  union {
 
120
    unsigned int usage; 
 
121
    char value[1];
 
122
  } u;
 
123
};
 
124
 
 
125
struct reqgen_ctrl_s {
 
126
  int lnr;
 
127
  int dryrun;
 
128
  ksba_writer_t writer;
 
129
};
 
130
 
 
131
 
 
132
static const char oidstr_keyUsage[] = "2.5.29.15";
 
133
 
 
134
 
 
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);
 
142
 
 
143
 
 
144
 
 
145
static void
 
146
release_parameter_list (struct para_data_s *r)
 
147
{
 
148
  struct para_data_s *r2;
 
149
  
 
150
  for (; r ; r = r2)
 
151
    {
 
152
      r2 = r->next;
 
153
      xfree(r);
 
154
    }
 
155
}
 
156
 
 
157
static struct para_data_s *
 
158
get_parameter (struct para_data_s *para, enum para_name key)
 
159
{
 
160
  struct para_data_s *r;
 
161
  
 
162
  for (r = para; r && r->key != key; r = r->next)
 
163
    ;
 
164
  return r;
 
165
}
 
166
 
 
167
static const char *
 
168
get_parameter_value (struct para_data_s *para, enum para_name key)
 
169
{
 
170
  struct para_data_s *r = get_parameter (para, key);
 
171
  return (r && *r->u.value)? r->u.value : NULL;
 
172
}
 
173
 
 
174
static int
 
175
get_parameter_algo (struct para_data_s *para, enum para_name key)
 
176
{
 
177
  struct para_data_s *r = get_parameter (para, key);
 
178
  if (!r)
 
179
    return -1;
 
180
  if (digitp (r->u.value))
 
181
    return atoi( r->u.value );
 
182
  return gcry_pk_map_name (r->u.value); 
 
183
}
 
184
 
 
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. */
 
189
static int
 
190
parse_parameter_usage (struct para_data_s *para, enum para_name key)
 
191
{
 
192
  struct para_data_s *r = get_parameter (para, key);
 
193
  char *p, *pn;
 
194
  unsigned int use;
 
195
  
 
196
  if (!r)
 
197
    return 0; /* none (this is an optional parameter)*/
 
198
    
 
199
  use = 0;
 
200
  pn = r->u.value;
 
201
  while ( (p = strsep (&pn, " \t,")) )
 
202
    {
 
203
      if (!*p)
 
204
        ;
 
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;
 
209
      else
 
210
        {
 
211
          log_error ("line %d: invalid usage list\n", r->lnr);
 
212
          return -1; /* error */
 
213
        }
 
214
    }
 
215
  r->u.usage = use;
 
216
  return 0;
 
217
}
 
218
 
 
219
 
 
220
static unsigned int
 
221
get_parameter_uint (struct para_data_s *para, enum para_name key)
 
222
{
 
223
  struct para_data_s *r = get_parameter (para, key);
 
224
 
 
225
  if (!r)
 
226
    return 0;
 
227
 
 
228
  if (r->key == pKEYUSAGE)
 
229
    return r->u.usage;
 
230
 
 
231
  return (unsigned int)strtoul (r->u.value, NULL, 10);
 
232
}
 
233
 
 
234
 
 
235
 
 
236
/* Read the certificate generation parameters from FP and generate
 
237
   (all) certificate requests.  */
 
238
static int
 
239
read_parameters (ctrl_t ctrl, FILE *fp, ksba_writer_t writer)
 
240
{
 
241
  static struct {
 
242
    const char *name;
 
243
    enum para_name key;
 
244
  } keywords[] = {
 
245
    { "Key-Type",       pKEYTYPE},
 
246
    { "Key-Length",     pKEYLENGTH },
 
247
    { "Key-Usage",      pKEYUSAGE },
 
248
    { "Name-DN",        pNAMEDN },
 
249
    { "Name-Email",     pNAMEEMAIL },
 
250
    { NULL, 0 }
 
251
  };
 
252
  char line[1024], *p;
 
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;
 
257
 
 
258
  memset (&outctrl, 0, sizeof (outctrl));
 
259
  outctrl.writer = writer;
 
260
 
 
261
  err = NULL;
 
262
  para = NULL;
 
263
  while (fgets (line, DIM(line)-1, fp) )
 
264
    {
 
265
      char *keyword, *value;
 
266
 
 
267
      outctrl.lnr++;
 
268
      if (*line && line[strlen(line)-1] != '\n')
 
269
        {
 
270
          err = "line too long";
 
271
          break;
 
272
        }
 
273
      for (p=line; spacep (p); p++)
 
274
        ;
 
275
      if (!*p || *p == '#')
 
276
        continue;
 
277
 
 
278
      keyword = p;
 
279
      if (*keyword == '%')
 
280
        {
 
281
          for (; *p && !spacep (p); p++)
 
282
            ;
 
283
          if (*p)
 
284
            *p++ = 0;
 
285
          for (; spacep (p); p++)
 
286
            ;
 
287
          value = p;
 
288
          trim_trailing_spaces (value);
 
289
 
 
290
          if (!ascii_strcasecmp (keyword, "%echo"))
 
291
            log_info ("%s\n", value);
 
292
          else if (!ascii_strcasecmp (keyword, "%dry-run"))
 
293
            outctrl.dryrun = 1;
 
294
          else if (!ascii_strcasecmp( keyword, "%commit"))
 
295
            {
 
296
              rc = proc_parameters (ctrl, para, &outctrl);
 
297
              if (rc)
 
298
                goto leave;
 
299
              any = 1;
 
300
              release_parameter_list (para);
 
301
              para = NULL;
 
302
            }
 
303
          else
 
304
            log_info ("skipping control `%s' (%s)\n", keyword, value);
 
305
 
 
306
          continue;
 
307
        }
 
308
 
 
309
 
 
310
      if (!(p = strchr (p, ':')) || p == keyword)
 
311
        {
 
312
          err = "missing colon";
 
313
          break;
 
314
        }
 
315
      if (*p)
 
316
        *p++ = 0;
 
317
      for (; spacep (p); p++)
 
318
        ;
 
319
      if (!*p)
 
320
        {
 
321
          err = "missing argument";
 
322
          break;
 
323
        }
 
324
      value = p;
 
325
      trim_trailing_spaces (value);
 
326
 
 
327
      for (i=0; (keywords[i].name
 
328
                 && ascii_strcasecmp (keywords[i].name, keyword)); i++)
 
329
        ;
 
330
      if (!keywords[i].name)
 
331
        {
 
332
          err = "unknown keyword";
 
333
          break;
 
334
        }
 
335
      if (keywords[i].key != pKEYTYPE && !para)
 
336
        {
 
337
          err = "parameter block does not start with \"Key-Type\"";
 
338
          break;
 
339
        }
 
340
 
 
341
      if (keywords[i].key == pKEYTYPE && para)
 
342
        {
 
343
          rc = proc_parameters (ctrl, para, &outctrl);
 
344
          if (rc)
 
345
            goto leave;
 
346
          any = 1;
 
347
          release_parameter_list (para);
 
348
          para = NULL;
 
349
        }
 
350
      else
 
351
        {
 
352
          for (r = para; r && r->key != keywords[i].key; r = r->next)
 
353
            ;
 
354
          if (r)
 
355
            {
 
356
              err = "duplicate keyword";
 
357
              break;
 
358
            }
 
359
        }
 
360
 
 
361
      r = xtrycalloc (1, sizeof *r + strlen( value ));
 
362
      if (!r)
 
363
        {
 
364
          err = "out of core";
 
365
          break;
 
366
        }
 
367
      r->lnr = outctrl.lnr;
 
368
      r->key = keywords[i].key;
 
369
      strcpy (r->u.value, value);
 
370
      r->next = para;
 
371
      para = r;
 
372
    }
 
373
 
 
374
  if (err)
 
375
    {
 
376
      log_error ("line %d: %s\n", outctrl.lnr, err);
 
377
      rc = gpg_error (GPG_ERR_GENERAL);
 
378
    }
 
379
  else if (ferror(fp))
 
380
    {
 
381
      log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) );
 
382
      rc = gpg_error (GPG_ERR_GENERAL);
 
383
    }
 
384
  else if (para)
 
385
    {
 
386
      rc = proc_parameters (ctrl, para, &outctrl);
 
387
      if (rc)
 
388
        goto leave;
 
389
      any = 1;
 
390
    }
 
391
 
 
392
  if (!rc && !any)
 
393
    rc = gpg_error (GPG_ERR_NO_DATA);
 
394
 
 
395
 leave:
 
396
  release_parameter_list (para);
 
397
  return rc;
 
398
}
 
399
 
 
400
/* check whether there are invalid characters in the email address S */
 
401
static int
 
402
has_invalid_email_chars (const char *s)
 
403
{
 
404
  int at_seen=0;
 
405
  static char valid_chars[] = "01234567890_-."
 
406
                              "abcdefghijklmnopqrstuvwxyz"
 
407
                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
408
  for (; *s; s++)
 
409
    {
 
410
      if (*s & 0x80)
 
411
        return 1;
 
412
      if (*s == '@')
 
413
        at_seen++;
 
414
      else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+'))
 
415
        return 1;
 
416
      else if (at_seen && !strchr (valid_chars, *s))
 
417
        return 1;
 
418
    }
 
419
  return at_seen != 1;
 
420
}
 
421
 
 
422
 
 
423
/* Check that all required parameters are given and perform the action */
 
424
static int
 
425
proc_parameters (ctrl_t ctrl,
 
426
                 struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
 
427
{
 
428
  struct para_data_s *r;
 
429
  const char *s;
 
430
  int i;
 
431
  unsigned int nbits;
 
432
  char numbuf[20];
 
433
  unsigned char keyparms[100];
 
434
  int rc;
 
435
  ksba_sexp_t public;
 
436
  
 
437
  /* check that we have all required parameters */
 
438
  assert (get_parameter (para, pKEYTYPE));
 
439
 
 
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 )
 
445
    {
 
446
      r = get_parameter (para, pKEYTYPE);
 
447
      log_error (_("line %d: invalid algorithm\n"), r->lnr);
 
448
      return gpg_error (GPG_ERR_INV_PARAMETER);
 
449
    }
 
450
  
 
451
  /* check the keylength */
 
452
  if (!get_parameter (para, pKEYLENGTH))
 
453
    nbits = 1024;
 
454
  else
 
455
    nbits = get_parameter_uint (para, pKEYLENGTH);
 
456
  if (nbits < 1024 || nbits > 4096)
 
457
    {
 
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);
 
463
    }
 
464
    
 
465
  /* check the usage */
 
466
  if (parse_parameter_usage (para, pKEYUSAGE))
 
467
    return gpg_error (GPG_ERR_INV_PARAMETER);
 
468
 
 
469
  /* check that there is a subject name and that this DN fits our
 
470
     requirements */
 
471
  if (!(s=get_parameter_value (para, pNAMEDN)))
 
472
    {
 
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);
 
476
    }
 
477
  /* fixme check s */
 
478
 
 
479
  /* check that the optional email address is okay */
 
480
  if ((s=get_parameter_value (para, pNAMEEMAIL)))
 
481
    { 
 
482
      if (has_invalid_email_chars (s)
 
483
          || *s == '@'
 
484
          || s[strlen(s)-1] == '@'
 
485
          || s[strlen(s)-1] == '.'
 
486
          || strstr(s, ".."))
 
487
        {
 
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);
 
491
        }
 
492
    }
 
493
 
 
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);
 
498
  if (rc)
 
499
    {
 
500
      r = get_parameter (para, pKEYTYPE);
 
501
      log_error (_("line %d: key generation failed: %s\n"),
 
502
                 r->lnr, gpg_strerror (rc));
 
503
      return rc;
 
504
    }
 
505
 
 
506
  rc = create_request (ctrl, para, public, outctrl);
 
507
  xfree (public);
 
508
 
 
509
  return rc;
 
510
}
 
511
 
 
512
 
 
513
/* Parameters are checked, the key pair has been created.  Now
 
514
   generate the request and write it out */
 
515
static int
 
516
create_request (ctrl_t ctrl,
 
517
                struct para_data_s *para, ksba_const_sexp_t public,
 
518
                struct reqgen_ctrl_s *outctrl)
 
519
{
 
520
  ksba_certreq_t cr;
 
521
  gpg_error_t err;
 
522
  gcry_md_hd_t md;
 
523
  ksba_stop_reason_t stopreason;
 
524
  int rc = 0;
 
525
  const char *s;
 
526
  unsigned int use;
 
527
 
 
528
  err = ksba_certreq_new (&cr);
 
529
  if (err)
 
530
    return err;
 
531
 
 
532
  rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
 
533
  if (rc)
 
534
    {
 
535
      log_error ("md_open failed: %s\n", gpg_strerror (rc));
 
536
      goto leave;
 
537
    }
 
538
  if (DBG_HASHING)
 
539
    gcry_md_start_debug (md, "cr.cri");
 
540
 
 
541
  ksba_certreq_set_hash_function (cr, HASH_FNC, md);
 
542
  ksba_certreq_set_writer (cr, outctrl->writer);
 
543
  
 
544
  err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN));
 
545
  if (err)
 
546
    {
 
547
      log_error ("error setting the subject's name: %s\n",
 
548
                 gpg_strerror (err));
 
549
      rc = err;
 
550
      goto leave;
 
551
    }
 
552
 
 
553
  s = get_parameter_value (para, pNAMEEMAIL);
 
554
  if (s)
 
555
    {
 
556
      char *buf;
 
557
 
 
558
      buf = xtrymalloc (strlen (s) + 3);
 
559
      if (!buf)
 
560
        {
 
561
          rc = OUT_OF_CORE (errno);
 
562
          goto leave;
 
563
        }
 
564
      *buf = '<';
 
565
      strcpy (buf+1, s);
 
566
      strcat (buf+1, ">");
 
567
      err = ksba_certreq_add_subject (cr, buf);
 
568
      xfree (buf);
 
569
      if (err)
 
570
        {
 
571
          log_error ("error setting the subject's alternate name: %s\n",
 
572
                     gpg_strerror (err));
 
573
          rc = err;
 
574
          goto leave;
 
575
        }
 
576
    }
 
577
 
 
578
 
 
579
  err = ksba_certreq_set_public_key (cr, public);
 
580
  if (err)
 
581
    {
 
582
      log_error ("error setting the public key: %s\n",
 
583
                 gpg_strerror (err));
 
584
      rc = err;
 
585
      goto leave;
 
586
    }
 
587
 
 
588
  
 
589
  use = get_parameter_uint (para, pKEYUSAGE);
 
590
  if (use == GCRY_PK_USAGE_SIGN)
 
591
    {
 
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);
 
597
    }
 
598
  else if (use == GCRY_PK_USAGE_ENCR)
 
599
    {
 
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);
 
605
    }
 
606
  else
 
607
    err = 0; /* Both or none given: don't request one. */
 
608
  if (err)
 
609
    {
 
610
      log_error ("error setting the key usage: %s\n",
 
611
                 gpg_strerror (err));
 
612
      rc = err;
 
613
      goto leave;
 
614
    }
 
615
 
 
616
               
 
617
  do
 
618
    {
 
619
      err = ksba_certreq_build (cr, &stopreason);
 
620
      if (err)
 
621
        {
 
622
          log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err));
 
623
          rc = err;
 
624
          goto leave;
 
625
        }
 
626
      if (stopreason == KSBA_SR_NEED_SIG)
 
627
        {
 
628
          gcry_sexp_t s_pkey;
 
629
          size_t n;
 
630
          unsigned char grip[20], hexgrip[41];
 
631
          char *sigval;
 
632
          size_t siglen;
 
633
 
 
634
          n = gcry_sexp_canon_len (public, 0, NULL, NULL);
 
635
          if (!n)
 
636
            {
 
637
              log_error ("libksba did not return a proper S-Exp\n");
 
638
              err = gpg_error (GPG_ERR_BUG);
 
639
              goto leave;
 
640
            }
 
641
          rc = gcry_sexp_sscan (&s_pkey, NULL, public, n);
 
642
          if (rc)
 
643
            {
 
644
              log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
 
645
              goto leave;
 
646
            }
 
647
          if ( !gcry_pk_get_keygrip (s_pkey, grip) )
 
648
            {
 
649
              rc = gpg_error (GPG_ERR_GENERAL);
 
650
              log_error ("can't figure out the keygrip\n");
 
651
              gcry_sexp_release (s_pkey);
 
652
              goto leave;
 
653
            }
 
654
          gcry_sexp_release (s_pkey);
 
655
          for (n=0; n < 20; n++)
 
656
            sprintf (hexgrip+n*2, "%02X", grip[n]);
 
657
 
 
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),
 
661
                                   GCRY_MD_SHA1,
 
662
                                   &sigval, &siglen);
 
663
          if (rc)
 
664
            {
 
665
              log_error ("signing failed: %s\n", gpg_strerror (rc));
 
666
              goto leave;
 
667
            }
 
668
          
 
669
          err = ksba_certreq_set_sig_val (cr, sigval);
 
670
          xfree (sigval);
 
671
          if (err)
 
672
            {
 
673
              log_error ("failed to store the sig_val: %s\n",
 
674
                         gpg_strerror (err));
 
675
              rc = err;
 
676
              goto leave;
 
677
            }
 
678
        }
 
679
    }
 
680
  while (stopreason != KSBA_SR_READY);   
 
681
  
 
682
 
 
683
 leave:
 
684
  gcry_md_close (md);
 
685
  ksba_certreq_release (cr);
 
686
  return rc;  
 
687
}
 
688
 
 
689
 
 
690
 
 
691
/* Create a new key by reading the parameters from in_fd.  Multiple
 
692
   keys may be created */
 
693
int
 
694
gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp)
 
695
{
 
696
  int rc;
 
697
  FILE *in_fp;
 
698
  Base64Context b64writer = NULL;
 
699
  ksba_writer_t writer;
 
700
 
 
701
  in_fp = fdopen (dup (in_fd), "rb");
 
702
  if (!in_fp)
 
703
    {
 
704
      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
 
705
      log_error ("fdopen() failed: %s\n", strerror (errno));
 
706
      return tmperr;
 
707
    }
 
708
 
 
709
  ctrl->pem_name = "CERTIFICATE REQUEST";
 
710
  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
 
711
  if (rc)
 
712
    {
 
713
      log_error ("can't create writer: %s\n", gpg_strerror (rc));
 
714
      goto leave;
 
715
    }
 
716
 
 
717
  rc = read_parameters (ctrl, in_fp, writer);
 
718
  if (rc)
 
719
    {
 
720
      log_error ("error creating certificate request: %s\n",
 
721
                 gpg_strerror (rc));
 
722
      goto leave;
 
723
    }
 
724
 
 
725
  rc = gpgsm_finish_writer (b64writer);
 
726
  if (rc) 
 
727
    {
 
728
      log_error ("write failed: %s\n", gpg_strerror (rc));
 
729
      goto leave;
 
730
    }
 
731
 
 
732
  gpgsm_status (ctrl, STATUS_KEY_CREATED, "P");
 
733
  log_info ("certificate request created\n");
 
734
 
 
735
 leave:
 
736
  gpgsm_destroy_writer (b64writer);
 
737
  fclose (in_fp);
 
738
  return rc;
 
739
}
 
740