~nutznboltz-deactivatedaccount/ubuntu/precise/gnutls26/fix-lp926350

« back to all changes in this revision

Viewing changes to src/certtool-common.c

  • Committer: Package Import Robot
  • Author(s): Andreas Metzler
  • Date: 2011-10-01 15:28:13 UTC
  • mfrom: (12.1.20 sid)
  • Revision ID: package-import@ubuntu.com-20111001152813-yygm1c4cxonfxhzy
Tags: 2.12.11-1
* New upstream version.
  + Allow CA importing of 0 certificates to succeed. Closes: #640639
* Add libp11-kit-dev to libgnutls-dev dependencies. (see #643811)
* [20_guiledocstring.diff] guile: Fix docstring extraction with CPP 4.5+.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 
3
 *   2011 Free Software Foundation, Inc.
 
4
 *
 
5
 * This file is part of GnuTLS.
 
6
 *
 
7
 * GnuTLS is free software: you can redistribute it and/or modify it
 
8
 * 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
 * GnuTLS is distributed in the hope that it will be useful, but
 
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * 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
 
19
 * <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
#include <config.h>
 
23
 
 
24
#include <gnutls/gnutls.h>
 
25
#include <gnutls/extra.h>
 
26
#include <gnutls/x509.h>
 
27
#include <gnutls/openpgp.h>
 
28
#include <gnutls/pkcs12.h>
 
29
#include <gnutls/pkcs11.h>
 
30
#include <gnutls/abstract.h>
 
31
 
 
32
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
#include <ctype.h>
 
36
#include <time.h>
 
37
#include <unistd.h>
 
38
#include <errno.h>
 
39
#include <sys/types.h>
 
40
#include <sys/stat.h>
 
41
#include <fcntl.h>
 
42
#include <error.h>
 
43
#include "certtool-common.h"
 
44
#include "certtool-cfg.h"
 
45
 
 
46
/* Gnulib portability files. */
 
47
#include <read-file.h>
 
48
 
 
49
unsigned char buffer[64 * 1024];
 
50
const int buffer_size = sizeof (buffer);
 
51
 
 
52
 
 
53
FILE *
 
54
safe_open_rw (const char *file, int privkey_op)
 
55
{
 
56
  mode_t omask = 0;
 
57
  FILE *fh;
 
58
 
 
59
  if (privkey_op != 0)
 
60
    {
 
61
      omask = umask (S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
 
62
    }
 
63
 
 
64
  fh = fopen (file, "wb");
 
65
 
 
66
  if (privkey_op != 0)
 
67
    {
 
68
      umask (omask);
 
69
    }
 
70
 
 
71
  return fh;
 
72
}
 
73
 
 
74
gnutls_datum_t *
 
75
load_secret_key (int mand, common_info_st * info)
 
76
{
 
77
  unsigned char raw_key[64];
 
78
  size_t raw_key_size = sizeof (raw_key);
 
79
  static gnutls_datum_t key;
 
80
  gnutls_datum_t hex_key;
 
81
  int ret;
 
82
 
 
83
  fprintf (stderr, "Loading secret key...\n");
 
84
 
 
85
  if (info->secret_key == NULL)
 
86
    {
 
87
      if (mand)
 
88
        error (EXIT_FAILURE, 0, "missing --secret-key");
 
89
      else
 
90
        return NULL;
 
91
    }
 
92
 
 
93
  hex_key.data = (char *) info->secret_key;
 
94
  hex_key.size = strlen (info->secret_key);
 
95
 
 
96
  ret = gnutls_hex_decode (&hex_key, raw_key, &raw_key_size);
 
97
  if (ret < 0)
 
98
    error (EXIT_FAILURE, 0, "hex_decode: %s", gnutls_strerror (ret));
 
99
 
 
100
  key.data = raw_key;
 
101
  key.size = raw_key_size;
 
102
 
 
103
  return &key;
 
104
}
 
105
 
 
106
static gnutls_privkey_t _load_privkey(gnutls_datum_t *dat, common_info_st * info)
 
107
{
 
108
int ret;
 
109
gnutls_privkey_t key;
 
110
gnutls_x509_privkey_t xkey;
 
111
 
 
112
  ret = gnutls_x509_privkey_init (&xkey);
 
113
  if (ret < 0)
 
114
    error (EXIT_FAILURE, 0, "x509_privkey_init: %s", gnutls_strerror (ret));
 
115
 
 
116
  ret = gnutls_privkey_init (&key);
 
117
  if (ret < 0)
 
118
    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
 
119
 
 
120
  if (info->pkcs8)
 
121
    {
 
122
      const char *pass = get_pass ();
 
123
      ret =
 
124
        gnutls_x509_privkey_import_pkcs8 (xkey, dat, info->incert_format,
 
125
                                          pass, 0);
 
126
    }
 
127
  else
 
128
    ret = gnutls_x509_privkey_import (xkey, dat, info->incert_format);
 
129
 
 
130
  if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
 
131
    {
 
132
      error (EXIT_FAILURE, 0,
 
133
             "import error: could not find a valid PEM header; "
 
134
             "check if your key is PKCS #8 or PKCS #12 encoded");
 
135
    }
 
136
 
 
137
  if (ret < 0)
 
138
    error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s",
 
139
           info->privkey, gnutls_strerror (ret));
 
140
 
 
141
  ret = gnutls_privkey_import_x509(key, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
 
142
  if (ret < 0)
 
143
    error (EXIT_FAILURE, 0, "gnutls_privkey_import_x509: %s",
 
144
           gnutls_strerror (ret));
 
145
  
 
146
  return key;
 
147
}
 
148
 
 
149
#ifdef ENABLE_PKCS11
 
150
 
 
151
static gnutls_privkey_t _load_pkcs11_privkey(const char* url)
 
152
{
 
153
int ret;
 
154
gnutls_pkcs11_privkey_t p11key;
 
155
gnutls_privkey_t key;
 
156
 
 
157
  ret = gnutls_privkey_init (&key);
 
158
  if (ret < 0)
 
159
    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
 
160
 
 
161
  ret = gnutls_pkcs11_privkey_init (&p11key);
 
162
  if (ret < 0)
 
163
    error (EXIT_FAILURE, 0, "pkcs11_privkey_init: %s", gnutls_strerror (ret));
 
164
 
 
165
  ret = gnutls_pkcs11_privkey_import_url(p11key, url, 0);
 
166
  if (ret < 0)
 
167
    error (EXIT_FAILURE, 0, "importing PKCS #11 key: %s: %s",
 
168
           url, gnutls_strerror (ret));
 
169
 
 
170
  ret = gnutls_privkey_import_pkcs11(key, p11key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
 
171
  if (ret < 0)
 
172
    error (EXIT_FAILURE, 0, "gnutls_privkey_import_pkcs11: %s",
 
173
           gnutls_strerror (ret));
 
174
  
 
175
  return key;
 
176
}
 
177
 
 
178
static gnutls_pubkey_t _load_pkcs11_pubkey(const char* url)
 
179
{
 
180
int ret;
 
181
gnutls_pkcs11_obj_t obj;
 
182
gnutls_x509_crt_t xcrt;
 
183
gnutls_pubkey_t pubkey;
 
184
unsigned int obj_flags = 0;
 
185
 
 
186
  ret = gnutls_pubkey_init (&pubkey);
 
187
  if (ret < 0)
 
188
    {
 
189
      fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
 
190
               gnutls_strerror (ret));
 
191
      exit (1);
 
192
    }
 
193
 
 
194
  ret = gnutls_pkcs11_obj_init (&obj);
 
195
  if (ret < 0)
 
196
    {
 
197
      fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
 
198
               gnutls_strerror (ret));
 
199
      exit (1);
 
200
    }
 
201
 
 
202
  ret = gnutls_pkcs11_obj_import_url (obj, url, obj_flags);
 
203
  if (ret < 0)
 
204
    {
 
205
      fprintf (stderr, "Error in %s:%d: %s: %s\n", __func__, __LINE__,
 
206
               gnutls_strerror (ret), url);
 
207
      exit (1);
 
208
    }
 
209
 
 
210
  switch (gnutls_pkcs11_obj_get_type (obj))
 
211
    {
 
212
    case GNUTLS_PKCS11_OBJ_X509_CRT:
 
213
      ret = gnutls_x509_crt_init (&xcrt);
 
214
      if (ret < 0)
 
215
        {
 
216
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
 
217
                   gnutls_strerror (ret));
 
218
          exit (1);
 
219
        }
 
220
 
 
221
      ret = gnutls_x509_crt_import_pkcs11 (xcrt, obj);
 
222
      if (ret < 0)
 
223
        {
 
224
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
 
225
                   gnutls_strerror (ret));
 
226
          exit (1);
 
227
        }
 
228
 
 
229
      ret = gnutls_pubkey_import_x509 (pubkey, xcrt, 0);
 
230
      if (ret < 0)
 
231
        {
 
232
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
 
233
                   gnutls_strerror (ret));
 
234
          exit (1);
 
235
        }
 
236
 
 
237
      gnutls_x509_crt_deinit (xcrt);
 
238
      break;
 
239
    case GNUTLS_PKCS11_OBJ_PUBKEY:
 
240
 
 
241
      ret = gnutls_pubkey_import_pkcs11 (pubkey, obj, 0);
 
242
      if (ret < 0)
 
243
        {
 
244
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
 
245
                   gnutls_strerror (ret));
 
246
          exit (1);
 
247
        }
 
248
 
 
249
      break;
 
250
    default:
 
251
      {
 
252
        fprintf(stderr, "Unsupported PKCS #11 object\n");
 
253
        exit (1);
 
254
        break;
 
255
      }
 
256
    }
 
257
  
 
258
  gnutls_pkcs11_obj_deinit (obj);
 
259
  return pubkey;
 
260
}
 
261
 
 
262
#endif /* ENABLE_PKCS11 */
 
263
 
 
264
/* Load the private key.
 
265
 * @mand should be non zero if it is required to read a private key.
 
266
 */
 
267
gnutls_privkey_t
 
268
load_private_key (int mand, common_info_st * info)
 
269
{
 
270
  gnutls_privkey_t key;
 
271
  gnutls_datum_t dat;
 
272
  size_t size;
 
273
 
 
274
  if (!info->privkey && !mand)
 
275
    return NULL;
 
276
 
 
277
  if (info->privkey == NULL)
 
278
    error (EXIT_FAILURE, 0, "missing --load-privkey");
 
279
 
 
280
#ifdef ENABLE_PKCS11
 
281
  if (strncmp(info->privkey, "pkcs11:", 7) == 0)
 
282
    return _load_pkcs11_privkey(info->privkey);
 
283
#endif
 
284
 
 
285
  dat.data = read_binary_file (info->privkey, &size);
 
286
  dat.size = size;
 
287
 
 
288
  if (!dat.data)
 
289
    error (EXIT_FAILURE, errno, "reading --load-privkey: %s", info->privkey);
 
290
 
 
291
  key = _load_privkey(&dat, info);
 
292
 
 
293
  free (dat.data);
 
294
 
 
295
  return key;
 
296
}
 
297
 
 
298
/* Load the private key.
 
299
 * @mand should be non zero if it is required to read a private key.
 
300
 */
 
301
gnutls_x509_privkey_t
 
302
load_x509_private_key (int mand, common_info_st * info)
 
303
{
 
304
  gnutls_x509_privkey_t key;
 
305
  int ret;
 
306
  gnutls_datum_t dat;
 
307
  size_t size;
 
308
 
 
309
  if (!info->privkey && !mand)
 
310
    return NULL;
 
311
 
 
312
  if (info->privkey == NULL)
 
313
    error (EXIT_FAILURE, 0, "missing --load-privkey");
 
314
 
 
315
  ret = gnutls_x509_privkey_init (&key);
 
316
  if (ret < 0)
 
317
    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
 
318
 
 
319
  dat.data = read_binary_file (info->privkey, &size);
 
320
  dat.size = size;
 
321
 
 
322
  if (!dat.data)
 
323
    error (EXIT_FAILURE, errno, "reading --load-privkey: %s", info->privkey);
 
324
 
 
325
  if (info->pkcs8)
 
326
    {
 
327
      const char *pass = get_pass ();
 
328
      ret =
 
329
        gnutls_x509_privkey_import_pkcs8 (key, &dat, info->incert_format,
 
330
                                          pass, 0);
 
331
    }
 
332
  else
 
333
    ret = gnutls_x509_privkey_import (key, &dat, info->incert_format);
 
334
 
 
335
  free (dat.data);
 
336
 
 
337
  if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
 
338
    {
 
339
      error (EXIT_FAILURE, 0,
 
340
             "import error: could not find a valid PEM header; "
 
341
             "check if your key is PKCS #8 or PKCS #12 encoded");
 
342
    }
 
343
 
 
344
  if (ret < 0)
 
345
    error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s",
 
346
           info->privkey, gnutls_strerror (ret));
 
347
 
 
348
  return key;
 
349
}
 
350
 
 
351
/* Loads the certificate
 
352
 * If mand is non zero then a certificate is mandatory. Otherwise
 
353
 * null will be returned if the certificate loading fails.
 
354
 */
 
355
gnutls_x509_crt_t
 
356
load_cert (int mand, common_info_st * info)
 
357
{
 
358
  gnutls_x509_crt_t *crt;
 
359
  size_t size;
 
360
 
 
361
  crt = load_cert_list (mand, &size, info);
 
362
 
 
363
  return crt ? crt[0] : NULL;
 
364
}
 
365
 
 
366
#define MAX_CERTS 256
 
367
 
 
368
/* Loads a certificate list
 
369
 */
 
370
gnutls_x509_crt_t *
 
371
load_cert_list (int mand, size_t * crt_size, common_info_st * info)
 
372
{
 
373
  FILE *fd;
 
374
  static gnutls_x509_crt_t crt[MAX_CERTS];
 
375
  char *ptr;
 
376
  int ret, i;
 
377
  gnutls_datum_t dat;
 
378
  size_t size;
 
379
  int ptr_size;
 
380
 
 
381
  *crt_size = 0;
 
382
  fprintf (stderr, "Loading certificate list...\n");
 
383
 
 
384
  if (info->cert == NULL)
 
385
    {
 
386
      if (mand)
 
387
        error (EXIT_FAILURE, 0, "missing --load-certificate");
 
388
      else
 
389
        return NULL;
 
390
    }
 
391
 
 
392
  fd = fopen (info->cert, "r");
 
393
  if (fd == NULL)
 
394
    error (EXIT_FAILURE, errno, "%s", info->cert);
 
395
 
 
396
  size = fread (buffer, 1, sizeof (buffer) - 1, fd);
 
397
  buffer[size] = 0;
 
398
 
 
399
  fclose (fd);
 
400
 
 
401
  ptr = buffer;
 
402
  ptr_size = size;
 
403
 
 
404
  for (i = 0; i < MAX_CERTS; i++)
 
405
    {
 
406
      ret = gnutls_x509_crt_init (&crt[i]);
 
407
      if (ret < 0)
 
408
        error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
 
409
 
 
410
      dat.data = ptr;
 
411
      dat.size = ptr_size;
 
412
 
 
413
      ret = gnutls_x509_crt_import (crt[i], &dat, info->incert_format);
 
414
      if (ret < 0 && *crt_size > 0)
 
415
        break;
 
416
      if (ret < 0)
 
417
        error (EXIT_FAILURE, 0, "crt_import: %s", gnutls_strerror (ret));
 
418
 
 
419
      ptr = strstr (ptr, "---END");
 
420
      if (ptr == NULL)
 
421
        break;
 
422
      ptr++;
 
423
 
 
424
      ptr_size = size;
 
425
      ptr_size -=
 
426
        (unsigned int) ((unsigned char *) ptr - (unsigned char *) buffer);
 
427
 
 
428
      if (ptr_size < 0)
 
429
        break;
 
430
 
 
431
      (*crt_size)++;
 
432
    }
 
433
  fprintf (stderr, "Loaded %d certificates.\n", (int) *crt_size);
 
434
 
 
435
  return crt;
 
436
}
 
437
 
 
438
/* Load the Certificate Request.
 
439
 */
 
440
gnutls_x509_crq_t
 
441
load_request (common_info_st * info)
 
442
{
 
443
  gnutls_x509_crq_t crq;
 
444
  int ret;
 
445
  gnutls_datum_t dat;
 
446
  size_t size;
 
447
 
 
448
  if (!info->request)
 
449
    return NULL;
 
450
 
 
451
  ret = gnutls_x509_crq_init (&crq);
 
452
  if (ret < 0)
 
453
    error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
 
454
 
 
455
  dat.data = read_binary_file (info->request, &size);
 
456
  dat.size = size;
 
457
 
 
458
  if (!dat.data)
 
459
    error (EXIT_FAILURE, errno, "reading --load-request: %s", info->request);
 
460
 
 
461
  ret = gnutls_x509_crq_import (crq, &dat, info->incert_format);
 
462
  if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
 
463
    {
 
464
      error (EXIT_FAILURE, 0,
 
465
             "import error: could not find a valid PEM header");
 
466
    }
 
467
 
 
468
  free (dat.data);
 
469
  if (ret < 0)
 
470
    error (EXIT_FAILURE, 0, "importing --load-request: %s: %s",
 
471
           info->request, gnutls_strerror (ret));
 
472
 
 
473
  return crq;
 
474
}
 
475
 
 
476
/* Load the CA's private key.
 
477
 */
 
478
gnutls_privkey_t
 
479
load_ca_private_key (common_info_st * info)
 
480
{
 
481
  gnutls_privkey_t key;
 
482
  gnutls_datum_t dat;
 
483
  size_t size;
 
484
 
 
485
  if (info->ca_privkey == NULL)
 
486
    error (EXIT_FAILURE, 0, "missing --load-ca-privkey");
 
487
 
 
488
#ifdef ENABLE_PKCS11
 
489
  if (strncmp(info->ca_privkey, "pkcs11:", 7) == 0)
 
490
    return _load_pkcs11_privkey(info->ca_privkey);
 
491
#endif
 
492
 
 
493
  dat.data = read_binary_file (info->ca_privkey, &size);
 
494
  dat.size = size;
 
495
 
 
496
  if (!dat.data)
 
497
    error (EXIT_FAILURE, errno, "reading --load-ca-privkey: %s",
 
498
           info->ca_privkey);
 
499
 
 
500
  key = _load_privkey(&dat, info);
 
501
 
 
502
  free (dat.data);
 
503
 
 
504
  return key;
 
505
}
 
506
 
 
507
/* Loads the CA's certificate
 
508
 */
 
509
gnutls_x509_crt_t
 
510
load_ca_cert (common_info_st * info)
 
511
{
 
512
  gnutls_x509_crt_t crt;
 
513
  int ret;
 
514
  gnutls_datum_t dat;
 
515
  size_t size;
 
516
 
 
517
  if (info->ca == NULL)
 
518
    error (EXIT_FAILURE, 0, "missing --load-ca-certificate");
 
519
 
 
520
  ret = gnutls_x509_crt_init (&crt);
 
521
  if (ret < 0)
 
522
    error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
 
523
 
 
524
  dat.data = read_binary_file (info->ca, &size);
 
525
  dat.size = size;
 
526
 
 
527
  if (!dat.data)
 
528
    error (EXIT_FAILURE, errno, "reading --load-ca-certificate: %s",
 
529
           info->ca);
 
530
 
 
531
  ret = gnutls_x509_crt_import (crt, &dat, info->incert_format);
 
532
  free (dat.data);
 
533
  if (ret < 0)
 
534
    error (EXIT_FAILURE, 0, "importing --load-ca-certificate: %s: %s",
 
535
           info->ca, gnutls_strerror (ret));
 
536
 
 
537
  return crt;
 
538
}
 
539
 
 
540
/* Load a public key.
 
541
 * @mand should be non zero if it is required to read a public key.
 
542
 */
 
543
gnutls_pubkey_t
 
544
load_pubkey (int mand, common_info_st * info)
 
545
{
 
546
  gnutls_pubkey_t key;
 
547
  int ret;
 
548
  gnutls_datum_t dat;
 
549
  size_t size;
 
550
 
 
551
  if (!info->pubkey && !mand)
 
552
    return NULL;
 
553
 
 
554
  if (info->pubkey == NULL)
 
555
    error (EXIT_FAILURE, 0, "missing --load-pubkey");
 
556
 
 
557
#ifdef ENABLE_PKCS11
 
558
  if (strncmp(info->pubkey, "pkcs11:", 7) == 0)
 
559
    return _load_pkcs11_pubkey(info->pubkey);
 
560
#endif
 
561
 
 
562
  ret = gnutls_pubkey_init (&key);
 
563
  if (ret < 0)
 
564
    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
 
565
 
 
566
  dat.data = read_binary_file (info->pubkey, &size);
 
567
  dat.size = size;
 
568
 
 
569
  if (!dat.data)
 
570
    error (EXIT_FAILURE, errno, "reading --load-pubkey: %s", info->pubkey);
 
571
 
 
572
  ret = gnutls_pubkey_import (key, &dat, info->incert_format);
 
573
 
 
574
  free (dat.data);
 
575
 
 
576
  if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
 
577
    {
 
578
      error (EXIT_FAILURE, 0,
 
579
             "import error: could not find a valid PEM header; "
 
580
             "check if your key has the PUBLIC KEY header");
 
581
    }
 
582
 
 
583
  if (ret < 0)
 
584
    error (EXIT_FAILURE, 0, "importing --load-pubkey: %s: %s",
 
585
           info->pubkey, gnutls_strerror (ret));
 
586
 
 
587
  return key;
 
588
}
 
589
 
 
590
gnutls_pubkey_t load_public_key_or_import(int mand, gnutls_privkey_t privkey, common_info_st * info)
 
591
{
 
592
gnutls_pubkey_t pubkey;
 
593
int ret;
 
594
 
 
595
  ret = gnutls_pubkey_init(&pubkey);
 
596
  if (ret < 0)
 
597
    error (EXIT_FAILURE, 0, "gnutls_pubkey_init: %s",
 
598
           gnutls_strerror (ret));
 
599
 
 
600
  ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0);
 
601
  if (ret < 0) /* could not get (e.g. on PKCS #11 */
 
602
    {
 
603
      gnutls_pubkey_deinit(pubkey);
 
604
      return load_pubkey(mand, info);
 
605
    }
 
606
 
 
607
  return pubkey;
 
608
}
 
609