~ubuntu-branches/ubuntu/maverick/gnutls26/maverick-updates

« back to all changes in this revision

Viewing changes to lib/gnutls_openpgp.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Metzler
  • Date: 2009-04-14 14:23:19 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090414142319-ok7xejzbqkofno1q
Tags: 2.6.5-1
* Sync sections in debian/control with override file. libgnutls26-dbg is
  section debug, guile-gnutls is section lisp.
* New upstream version. (Needed for Libtasn1-3 2.0)
* New patch 15_tasn1inpc.diff. Make sure libtasn1 is listed in Libs.private.
* Standards-Version: 3.8.1, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
3
 
 *
4
 
 * Author: Timo Schulz, Nikos Mavrogiannopoulos
5
 
 *
6
 
 * This file is part of GNUTLS.
7
 
 *
8
 
 * The GNUTLS library is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU Lesser General Public License
10
 
 * as published by the Free Software Foundation; either version 2.1 of
11
 
 * the License, or (at your option) any later version.
12
 
 *
13
 
 * This library is distributed in the hope that it will be useful, but
14
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * Lesser General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public
19
 
 * License along with this library; if not, write to the Free Software
20
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21
 
 * USA
22
 
 *
23
 
 */
24
 
 
25
 
#include "gnutls_int.h"
26
 
#include "gnutls_errors.h"
27
 
#include "gnutls_mpi.h"
28
 
#include "gnutls_num.h"
29
 
#include "gnutls_cert.h"
30
 
#include "gnutls_datum.h"
31
 
#include "gnutls_global.h"
32
 
#include "openpgp/gnutls_openpgp.h"
33
 
#include "read-file.h"
34
 
#include <gnutls_str.h>
35
 
#include <gnutls_sig.h>
36
 
#include <stdio.h>
37
 
#include <gcrypt.h>
38
 
#include <time.h>
39
 
#include <sys/stat.h>
40
 
 
41
 
#define datum_append(x, y, z) _gnutls_datum_append_m (x, y, z, gnutls_realloc)
42
 
 
43
 
/* Map an OpenCDK error type to a GnuTLS error type. */
44
 
int
45
 
_gnutls_map_cdk_rc (int rc)
46
 
{
47
 
  switch (rc)
48
 
    {
49
 
    case CDK_Success:
50
 
      return 0;
51
 
    case CDK_Too_Short:
52
 
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
53
 
    case CDK_General_Error:
54
 
      return GNUTLS_E_INTERNAL_ERROR;
55
 
    case CDK_File_Error:
56
 
      return GNUTLS_E_FILE_ERROR;
57
 
    case CDK_MPI_Error:
58
 
      return GNUTLS_E_MPI_SCAN_FAILED;
59
 
    case CDK_Error_No_Key:
60
 
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
61
 
    case CDK_Armor_Error:
62
 
      return GNUTLS_E_BASE64_DECODING_ERROR;
63
 
    case CDK_Inv_Value:
64
 
      return GNUTLS_E_INVALID_REQUEST;
65
 
    default:
66
 
      return GNUTLS_E_INTERNAL_ERROR;
67
 
    }
68
 
}
69
 
 
70
 
/*-
71
 
 * _gnutls_openpgp_raw_crt_to_gcert - Converts raw OpenPGP data to GnuTLS certs
72
 
 * @cert: the certificate to store the data.
73
 
 * @raw: the buffer which contains the whole OpenPGP key packets.
74
 
 *
75
 
 * The RFC2440 (OpenPGP Message Format) data is converted to a GnuTLS
76
 
 * specific certificate.
77
 
 -*/
78
 
int
79
 
_gnutls_openpgp_raw_crt_to_gcert (gnutls_cert * gcert,
80
 
                                  const gnutls_datum_t * raw, const gnutls_openpgp_keyid_t keyid)
81
 
{
82
 
  gnutls_openpgp_crt_t pcrt;
83
 
  int ret;
84
 
 
85
 
  ret = gnutls_openpgp_crt_init (&pcrt);
86
 
  if (ret < 0)
87
 
    {
88
 
      gnutls_assert ();
89
 
      return ret;
90
 
    }
91
 
 
92
 
  ret = gnutls_openpgp_crt_import (pcrt, raw, GNUTLS_OPENPGP_FMT_RAW);
93
 
  if (ret < 0)
94
 
    {
95
 
      gnutls_assert ();
96
 
      gnutls_openpgp_crt_deinit (pcrt);
97
 
      return ret;
98
 
    }
99
 
 
100
 
  if (keyid != NULL)
101
 
    {
102
 
      ret = gnutls_openpgp_crt_set_preferred_key_id( pcrt, keyid);
103
 
      if (ret < 0)
104
 
        {
105
 
          gnutls_assert();
106
 
          gnutls_openpgp_crt_deinit (pcrt);
107
 
          return ret;
108
 
        }
109
 
    }
110
 
 
111
 
  ret = _gnutls_openpgp_crt_to_gcert (gcert, pcrt);
112
 
  gnutls_openpgp_crt_deinit (pcrt);
113
 
 
114
 
  return ret;
115
 
}
116
 
 
117
 
/**
118
 
  * gnutls_certificate_set_openpgp_key - Used to set keys in a gnutls_certificate_credentials_t structure
119
 
  * @res: is an #gnutls_certificate_credentials_t structure.
120
 
  * @key: contains an openpgp public key
121
 
  * @pkey: is an openpgp private key
122
 
  *
123
 
  * This function sets a certificate/private key pair in the 
124
 
  * gnutls_certificate_credentials_t structure. This function may be called
125
 
  * more than once (in case multiple keys/certificates exist for the
126
 
  * server).
127
 
  *
128
 
  * With this function the subkeys of the certificate are not used.
129
 
  *
130
 
  **/
131
 
int
132
 
gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t
133
 
                                    res, gnutls_openpgp_crt_t crt,
134
 
                                    gnutls_openpgp_privkey_t pkey)
135
 
{
136
 
  int ret;
137
 
  
138
 
  /* this should be first */
139
 
 
140
 
  res->pkey = gnutls_realloc_fast (res->pkey,
141
 
                                   (res->ncerts + 1) * 
142
 
                                   sizeof (gnutls_privkey));
143
 
  if (res->pkey == NULL)
144
 
    {
145
 
      gnutls_assert ();
146
 
      return GNUTLS_E_MEMORY_ERROR;
147
 
    }
148
 
 
149
 
  ret = _gnutls_openpgp_privkey_to_gkey (&res->pkey[res->ncerts], pkey);
150
 
  if (ret < 0)
151
 
    {
152
 
      gnutls_assert ();
153
 
      return ret;
154
 
    }
155
 
 
156
 
  res->cert_list = gnutls_realloc_fast (res->cert_list,
157
 
                                        (1 +
158
 
                                         res->ncerts) *
159
 
                                        sizeof (gnutls_cert *));
160
 
  if (res->cert_list == NULL)
161
 
    {
162
 
      gnutls_assert ();
163
 
      return GNUTLS_E_MEMORY_ERROR;
164
 
    }
165
 
 
166
 
  res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
167
 
                                               (1 +
168
 
                                                res->ncerts) * sizeof (int));
169
 
  if (res->cert_list_length == NULL)
170
 
    {
171
 
      gnutls_assert ();
172
 
      return GNUTLS_E_MEMORY_ERROR;
173
 
    }
174
 
 
175
 
  res->cert_list[res->ncerts] = gnutls_calloc (1, sizeof (gnutls_cert));
176
 
  if (res->cert_list[res->ncerts] == NULL)
177
 
    {
178
 
      gnutls_assert ();
179
 
      return GNUTLS_E_MEMORY_ERROR;
180
 
    }
181
 
 
182
 
  res->cert_list_length[res->ncerts] = 1;
183
 
 
184
 
  ret = _gnutls_openpgp_crt_to_gcert (res->cert_list[res->ncerts], crt);
185
 
  if (ret < 0)
186
 
    {
187
 
      gnutls_assert ();
188
 
      return ret;
189
 
    }
190
 
 
191
 
  res->ncerts++;
192
 
 
193
 
  /* FIXME: Check if the keys match. */
194
 
 
195
 
  return 0;
196
 
}
197
 
 
198
 
/*-
199
 
 * gnutls_openpgp_get_key - Retrieve a key from the keyring.
200
 
 * @key: the destination context to save the key.
201
 
 * @keyring: the datum struct that contains all keyring information.
202
 
 * @attr: The attribute (keyid, fingerprint, ...).
203
 
 * @by: What attribute is used.
204
 
 *
205
 
 * This function can be used to retrieve keys by different pattern
206
 
 * from a binary or a file keyring.
207
 
 -*/
208
 
int
209
 
gnutls_openpgp_get_key (gnutls_datum_t * key,
210
 
                        gnutls_openpgp_keyring_t keyring, key_attr_t by,
211
 
                        opaque * pattern)
212
 
{
213
 
  cdk_kbnode_t knode = NULL;
214
 
  unsigned long keyid[2];
215
 
  unsigned char *buf;
216
 
  void *desc;
217
 
  size_t len;
218
 
  int rc = 0;
219
 
  cdk_keydb_search_t st;
220
 
 
221
 
  if (!key || !keyring || by == KEY_ATTR_NONE)
222
 
    {
223
 
      gnutls_assert ();
224
 
      return GNUTLS_E_INVALID_REQUEST;
225
 
    }
226
 
 
227
 
  memset (key, 0, sizeof *key);
228
 
 
229
 
  if (by == KEY_ATTR_SHORT_KEYID)
230
 
    {
231
 
      keyid[0] = _gnutls_read_uint32(pattern);
232
 
      desc = keyid;
233
 
    }
234
 
  else if (by == KEY_ATTR_KEYID)
235
 
    {
236
 
      keyid[0] = _gnutls_read_uint32(pattern);
237
 
      keyid[1] = _gnutls_read_uint32(pattern + 4);
238
 
      desc = keyid;
239
 
    }
240
 
  else
241
 
    desc = pattern;
242
 
  rc = cdk_keydb_search_start (&st, keyring->db, by, desc);
243
 
  if (!rc)
244
 
    rc = cdk_keydb_search (st, keyring->db, &knode);
245
 
    
246
 
  cdk_keydb_search_release( st);
247
 
 
248
 
  if (rc)
249
 
    {
250
 
      rc = _gnutls_map_cdk_rc (rc);
251
 
      goto leave;
252
 
    }
253
 
 
254
 
  if (!cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY))
255
 
    {
256
 
      rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
257
 
      goto leave;
258
 
    }
259
 
  
260
 
  /* We let the function allocate the buffer to avoid
261
 
     to call the function twice. */
262
 
  rc = cdk_kbnode_write_to_mem_alloc (knode, &buf, &len);
263
 
  if (!rc)
264
 
    datum_append (key, buf, len);
265
 
  cdk_free (buf);
266
 
 
267
 
leave:
268
 
  cdk_kbnode_release (knode);
269
 
  return rc;
270
 
}
271
 
 
272
 
/**
273
 
 * gnutls_certificate_set_openpgp_key_mem - Used to set OpenPGP keys
274
 
 * @res: the destination context to save the data.
275
 
 * @cert: the datum that contains the public key.
276
 
 * @key: the datum that contains the secret key.
277
 
 * @format: the format of the keys
278
 
 *
279
 
 * This funtion is used to load OpenPGP keys into the GnuTLS credential 
280
 
 * structure. The files should contain non encrypted keys.
281
 
 *
282
 
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
283
 
 *   negative error value.
284
 
 **/
285
 
int
286
 
gnutls_certificate_set_openpgp_key_mem (gnutls_certificate_credentials_t
287
 
                                        res, const gnutls_datum_t * icert,
288
 
                                        const gnutls_datum_t * ikey,
289
 
                                        gnutls_openpgp_crt_fmt_t format)
290
 
{
291
 
  return gnutls_certificate_set_openpgp_key_mem2 (res, icert, ikey,
292
 
                                                  NULL, format);
293
 
}
294
 
 
295
 
 
296
 
/**
297
 
 * gnutls_certificate_set_openpgp_key_file - Used to set OpenPGP keys
298
 
 * @res: the destination context to save the data.
299
 
 * @certfile: the file that contains the public key.
300
 
 * @keyfile: the file that contains the secret key.
301
 
 * @format: the format of the keys
302
 
 *
303
 
 * This funtion is used to load OpenPGP keys into the GnuTLS
304
 
 * credentials structure.  The files should only contain one key which
305
 
 * is not encrypted.
306
 
 *
307
 
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
308
 
 *   negative error value.
309
 
 **/
310
 
int
311
 
gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
312
 
                                         res, const char *certfile,
313
 
                                         const char *keyfile,
314
 
                                         gnutls_openpgp_crt_fmt_t format)
315
 
{
316
 
  return gnutls_certificate_set_openpgp_key_file2 (res, certfile,
317
 
                                                   keyfile, NULL, format);
318
 
}
319
 
 
320
 
static int get_keyid( gnutls_openpgp_keyid_t keyid, const char* str)
321
 
{
322
 
    size_t keyid_size = sizeof(keyid);
323
 
 
324
 
    if (strlen(str) != 16)
325
 
      {
326
 
        _gnutls_debug_log("The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
327
 
        return GNUTLS_E_INVALID_REQUEST;
328
 
      }  
329
 
 
330
 
    if (_gnutls_hex2bin (str, strlen(str), keyid, &keyid_size) < 0)
331
 
      {
332
 
        _gnutls_debug_log("Error converting hex string: %s.\n", str);
333
 
        return GNUTLS_E_INVALID_REQUEST;
334
 
      }
335
 
          
336
 
    return 0;
337
 
}
338
 
 
339
 
/**
340
 
 * gnutls_certificate_set_openpgp_key_mem2 - Used to set OpenPGP keys
341
 
 * @res: the destination context to save the data.
342
 
 * @cert: the datum that contains the public key.
343
 
 * @key: the datum that contains the secret key.
344
 
 * @subkey_id: a hex encoded subkey id
345
 
 * @format: the format of the keys
346
 
 *
347
 
 * This funtion is used to load OpenPGP keys into the GnuTLS
348
 
 * credentials structure.  The files should only contain one key which
349
 
 * is not encrypted.
350
 
 *
351
 
 * The special keyword "auto" is also accepted as &subkey_id. In that
352
 
 * case the gnutls_openpgp_crt_get_auth_subkey() will be used to
353
 
 * retrieve the subkey.
354
 
 *
355
 
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
356
 
 *   negative error value.
357
 
 *
358
 
 * Since: 2.4.0
359
 
 **/
360
 
int
361
 
gnutls_certificate_set_openpgp_key_mem2 (gnutls_certificate_credentials_t
362
 
                                        res, const gnutls_datum_t * icert,
363
 
                                        const gnutls_datum_t * ikey,
364
 
                                        const char* subkey_id,
365
 
                                        gnutls_openpgp_crt_fmt_t format)
366
 
{
367
 
  gnutls_openpgp_privkey_t key;
368
 
  gnutls_openpgp_crt_t cert;
369
 
  int ret;
370
 
 
371
 
  ret = gnutls_openpgp_privkey_init( &key);
372
 
  if (ret < 0) {
373
 
    gnutls_assert();
374
 
    return ret;
375
 
  }
376
 
 
377
 
  ret = gnutls_openpgp_privkey_import( key, ikey, format, NULL, 0);
378
 
  if (ret < 0) {
379
 
    gnutls_assert();
380
 
    gnutls_openpgp_privkey_deinit( key);
381
 
    return ret;
382
 
  }
383
 
 
384
 
  ret = gnutls_openpgp_crt_init( &cert);
385
 
  if (ret < 0) {
386
 
    gnutls_assert();
387
 
    gnutls_openpgp_privkey_deinit( key);
388
 
    return ret;
389
 
  }
390
 
 
391
 
  ret = gnutls_openpgp_crt_import( cert, icert, format);
392
 
  if (ret < 0) {
393
 
    gnutls_assert();
394
 
    gnutls_openpgp_privkey_deinit( key);
395
 
    gnutls_openpgp_crt_deinit( cert);
396
 
    return ret;
397
 
  }
398
 
 
399
 
  if (subkey_id != NULL)
400
 
    {
401
 
      gnutls_openpgp_keyid_t keyid;
402
 
      
403
 
      if (strcasecmp( subkey_id, "auto")==0)
404
 
        ret = gnutls_openpgp_crt_get_auth_subkey( cert, keyid, 1);
405
 
      else
406
 
        ret = get_keyid( keyid, subkey_id);
407
 
 
408
 
      if (ret >= 0)
409
 
        {
410
 
          ret = gnutls_openpgp_crt_set_preferred_key_id( cert, keyid);
411
 
          if (ret >= 0)
412
 
            ret = gnutls_openpgp_privkey_set_preferred_key_id( key, keyid);
413
 
        }
414
 
 
415
 
      if (ret < 0)
416
 
        {
417
 
          gnutls_assert();
418
 
          gnutls_openpgp_privkey_deinit( key);
419
 
          gnutls_openpgp_crt_deinit( cert);
420
 
          return ret;
421
 
        }
422
 
    }
423
 
 
424
 
  ret = gnutls_certificate_set_openpgp_key( res, cert, key);
425
 
 
426
 
  gnutls_openpgp_privkey_deinit( key);
427
 
  gnutls_openpgp_crt_deinit( cert);
428
 
  
429
 
  return ret;
430
 
}
431
 
 
432
 
 
433
 
/**
434
 
 * gnutls_certificate_set_openpgp_key_file2 - Used to set OpenPGP keys
435
 
 * @res: the destination context to save the data.
436
 
 * @certfile: the file that contains the public key.
437
 
 * @keyfile: the file that contains the secret key.
438
 
 * @subkey_id: a hex encoded subkey id
439
 
 * @format: the format of the keys
440
 
 *
441
 
 * This funtion is used to load OpenPGP keys into the GnuTLS credential 
442
 
 * structure. The files should contain non encrypted keys.
443
 
 *
444
 
 * The special keyword "auto" is also accepted as &subkey_id. In that case
445
 
 * the gnutls_openpgp_crt_get_auth_subkey() will be used to retrieve the subkey.
446
 
 *
447
 
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
448
 
 *   negative error value.
449
 
 *
450
 
 * Since: 2.4.0
451
 
 **/
452
 
int
453
 
gnutls_certificate_set_openpgp_key_file2 (gnutls_certificate_credentials_t
454
 
                                         res, const char *certfile,
455
 
                                         const char *keyfile,
456
 
                                         const char* subkey_id,
457
 
                                         gnutls_openpgp_crt_fmt_t format)
458
 
{
459
 
  struct stat statbuf;
460
 
  gnutls_datum_t key, cert;
461
 
  int rc;
462
 
  size_t size;
463
 
 
464
 
  if (!res || !keyfile || !certfile)
465
 
    {
466
 
      gnutls_assert ();
467
 
      return GNUTLS_E_INVALID_REQUEST;
468
 
    }
469
 
 
470
 
  if (stat (certfile, &statbuf) || stat (keyfile, &statbuf))
471
 
    {
472
 
      gnutls_assert ();
473
 
      return GNUTLS_E_FILE_ERROR;
474
 
    }
475
 
 
476
 
  cert.data = read_binary_file (certfile, &size);
477
 
  cert.size = (unsigned int)size;
478
 
  if (cert.data == NULL)
479
 
    {
480
 
      gnutls_assert ();
481
 
      return GNUTLS_E_FILE_ERROR;
482
 
    }
483
 
 
484
 
  key.data = read_binary_file (keyfile, &size);
485
 
  key.size = (unsigned int)size;
486
 
  if (key.data == NULL)
487
 
    {
488
 
      gnutls_assert ();
489
 
      free (cert.data);
490
 
      return GNUTLS_E_FILE_ERROR;
491
 
    }
492
 
 
493
 
  rc = gnutls_certificate_set_openpgp_key_mem2 (res, &cert, &key, subkey_id, format);
494
 
 
495
 
  free (cert.data);
496
 
  free (key.data);
497
 
 
498
 
  if (rc < 0)
499
 
    {
500
 
      gnutls_assert ();
501
 
      return rc;
502
 
    }
503
 
 
504
 
  return 0;
505
 
}
506
 
 
507
 
 
508
 
int
509
 
gnutls_openpgp_count_key_names (const gnutls_datum_t * cert)
510
 
{
511
 
  cdk_kbnode_t knode, p, ctx;
512
 
  cdk_packet_t pkt;
513
 
  int nuids;
514
 
 
515
 
  if (cert == NULL)
516
 
    {
517
 
      gnutls_assert ();
518
 
      return 0;
519
 
    }
520
 
  
521
 
  if (cdk_kbnode_read_from_mem (&knode, cert->data, cert->size))
522
 
    {
523
 
      gnutls_assert ();
524
 
      return 0;
525
 
    }
526
 
  
527
 
  ctx = NULL;  
528
 
  for (nuids = 0;;)
529
 
    {
530
 
      p = cdk_kbnode_walk (knode, &ctx, 0);
531
 
      if (!p)
532
 
        break;
533
 
      pkt = cdk_kbnode_get_packet (p);
534
 
      if (pkt->pkttype == CDK_PKT_USER_ID)
535
 
        nuids++;
536
 
    }
537
 
  
538
 
  cdk_kbnode_release (knode);
539
 
  return nuids;
540
 
}
541
 
 
542
 
 
543
 
/**
544
 
 * gnutls_certificate_set_openpgp_keyring_file - Sets a keyring file for OpenPGP
545
 
 * @c: A certificate credentials structure
546
 
 * @file: filename of the keyring.
547
 
 *
548
 
 * The function is used to set keyrings that will be used internally
549
 
 * by various OpenPGP functions. For example to find a key when it
550
 
 * is needed for an operations. The keyring will also be used at the
551
 
 * verification functions.
552
 
 *
553
 
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
554
 
 *   negative error value.
555
 
 **/
556
 
int
557
 
gnutls_certificate_set_openpgp_keyring_file (gnutls_certificate_credentials_t c,
558
 
                                             const char *file,
559
 
                                             gnutls_openpgp_crt_fmt_t format)
560
 
{
561
 
  gnutls_datum_t ring;
562
 
  size_t size;
563
 
  int rc;
564
 
 
565
 
  if (!c || !file)
566
 
    {
567
 
      gnutls_assert ();
568
 
      return GNUTLS_E_INVALID_REQUEST;
569
 
    }
570
 
 
571
 
  ring.data = read_binary_file (file, &size);
572
 
  ring.size = (unsigned int)size;
573
 
  if (ring.data == NULL)
574
 
    {
575
 
      gnutls_assert ();
576
 
      return GNUTLS_E_FILE_ERROR;
577
 
    }
578
 
 
579
 
  rc = gnutls_certificate_set_openpgp_keyring_mem (c, ring.data, ring.size, format);
580
 
  
581
 
  free( ring.data);
582
 
  
583
 
  return rc;
584
 
}
585
 
 
586
 
/**
587
 
 * gnutls_certificate_set_openpgp_keyring_mem - Add keyring data for OpenPGP
588
 
 * @c: A certificate credentials structure
589
 
 * @data: buffer with keyring data.
590
 
 * @dlen: length of data buffer.
591
 
 *
592
 
 * The function is used to set keyrings that will be used internally
593
 
 * by various OpenPGP functions. For example to find a key when it
594
 
 * is needed for an operations. The keyring will also be used at the
595
 
 * verification functions.
596
 
 *
597
 
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
598
 
 *   negative error value.
599
 
 **/
600
 
int
601
 
gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
602
 
                                            c, const opaque * data,
603
 
                                            size_t dlen, gnutls_openpgp_crt_fmt_t format)
604
 
{
605
 
  gnutls_datum ddata;
606
 
  int rc;
607
 
  
608
 
  ddata.data = (void*)data;
609
 
  ddata.size = dlen;
610
 
  
611
 
  if (!c || !data || !dlen)
612
 
    {
613
 
      gnutls_assert ();
614
 
      return GNUTLS_E_INVALID_REQUEST;
615
 
    }
616
 
 
617
 
  rc = gnutls_openpgp_keyring_init( &c->keyring);
618
 
  if (rc < 0) {
619
 
    gnutls_assert();
620
 
    return rc;
621
 
  }
622
 
  
623
 
  rc = gnutls_openpgp_keyring_import( c->keyring, &ddata, format);
624
 
  if ( rc < 0) {
625
 
    gnutls_assert();
626
 
    gnutls_openpgp_keyring_deinit( c->keyring);
627
 
    return rc;
628
 
  }
629
 
  
630
 
  return 0;
631
 
}
632
 
 
633
 
/*-
634
 
 * _gnutls_openpgp_request_key - Receives a key from a database, key server etc
635
 
 * @ret - a pointer to gnutls_datum_t structure.
636
 
 * @cred - a gnutls_certificate_credentials_t structure.
637
 
 * @key_fingerprint - The keyFingerprint
638
 
 * @key_fingerprint_size - the size of the fingerprint
639
 
 *
640
 
 * Retrieves a key from a local database, keyring, or a key server. The
641
 
 * return value is locally allocated.
642
 
 *
643
 
 -*/
644
 
int
645
 
_gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
646
 
                             const gnutls_certificate_credentials_t cred,
647
 
                             opaque * key_fpr, int key_fpr_size)
648
 
{
649
 
  int rc = 0;
650
 
 
651
 
  if (!ret || !cred || !key_fpr)
652
 
    {
653
 
      gnutls_assert ();
654
 
      return GNUTLS_E_INVALID_REQUEST;
655
 
    }
656
 
 
657
 
  if (key_fpr_size != 16 && key_fpr_size != 20)
658
 
    return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */
659
 
 
660
 
  rc = gnutls_openpgp_get_key (ret, cred->keyring, KEY_ATTR_FPR, key_fpr);
661
 
 
662
 
  if (rc >= 0) /* key was found */
663
 
    {
664
 
      rc = 0;
665
 
      goto error;
666
 
    }
667
 
  else
668
 
    rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
669
 
 
670
 
  /* If the callback function was set, then try this one. */
671
 
  if (session->internals.openpgp_recv_key_func != NULL)
672
 
    {
673
 
      rc = session->internals.openpgp_recv_key_func (session,
674
 
                                                     key_fpr,
675
 
                                                     key_fpr_size, ret);
676
 
      if (rc < 0)
677
 
        {
678
 
          gnutls_assert ();
679
 
          rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
680
 
          goto error;
681
 
        }
682
 
    }
683
 
 
684
 
  error:
685
 
 
686
 
  return rc;
687
 
}
688
 
 
689
 
/**
690
 
 * gnutls_openpgp_set_recv_key_function - Used to set a key retrieval callback for PGP keys
691
 
 * @session: a TLS session
692
 
 * @func: the callback
693
 
 *
694
 
 * This funtion will set a key retrieval function for OpenPGP keys. This
695
 
 * callback is only useful in server side, and will be used if the peer
696
 
 * sent a key fingerprint instead of a full key.
697
 
 *
698
 
 **/
699
 
void
700
 
gnutls_openpgp_set_recv_key_function (gnutls_session_t session,
701
 
                                      gnutls_openpgp_recv_key_func func)
702
 
{
703
 
  session->internals.openpgp_recv_key_func = func;
704
 
}
705
 
 
706
 
 
707
 
/* Copies a gnutls_openpgp_privkey_t to a gnutls_privkey structure. */
708
 
int
709
 
_gnutls_openpgp_privkey_to_gkey (gnutls_privkey * dest,
710
 
                                 gnutls_openpgp_privkey_t src)
711
 
{
712
 
  int ret = 0;
713
 
  gnutls_openpgp_keyid_t keyid;
714
 
  char err_buf[33];
715
 
    
716
 
  if (dest==NULL || src == NULL)
717
 
    {
718
 
      gnutls_assert ();
719
 
      return GNUTLS_E_CERTIFICATE_ERROR;
720
 
    }
721
 
 
722
 
  dest->params_size = MAX_PRIV_PARAMS_SIZE;
723
 
 
724
 
  ret = gnutls_openpgp_privkey_get_preferred_key_id( src, keyid);
725
 
 
726
 
  if (ret == 0) 
727
 
    {
728
 
      int idx;
729
 
      uint32_t kid32[2];
730
 
 
731
 
      _gnutls_debug_log("Importing Openpgp key and using openpgp sub key: %s\n",
732
 
        _gnutls_bin2hex( keyid, sizeof(keyid), err_buf, sizeof(err_buf)));
733
 
 
734
 
      KEYID_IMPORT(kid32, keyid);
735
 
  
736
 
      idx = gnutls_openpgp_privkey_get_subkey_idx( src, keyid);
737
 
      if (idx < 0)
738
 
        {
739
 
          gnutls_assert();
740
 
          return idx;
741
 
        }
742
 
                      
743
 
      dest->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm( src, idx, NULL);
744
 
  
745
 
      ret = _gnutls_openpgp_privkey_get_mpis( src, kid32, dest->params, &dest->params_size);
746
 
    }
747
 
  else
748
 
    {
749
 
      _gnutls_debug_log("Importing Openpgp key and using main openpgp key.\n");
750
 
 
751
 
      dest->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm( src, NULL);
752
 
      ret = _gnutls_openpgp_privkey_get_mpis( src, NULL, dest->params, &dest->params_size);
753
 
    }
754
 
 
755
 
  
756
 
  if (ret < 0)
757
 
    {
758
 
      gnutls_assert();
759
 
      return ret;
760
 
    }
761
 
    
762
 
  return 0;
763
 
 
764
 
}
765
 
 
766
 
/* Converts a parsed gnutls_openpgp_crt_t to a gnutls_cert structure.
767
 
 */
768
 
int
769
 
_gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert)
770
 
{
771
 
  int ret;
772
 
  gnutls_openpgp_keyid_t keyid;
773
 
  char err_buf[33];
774
 
 
775
 
  memset (gcert, 0, sizeof (gnutls_cert));
776
 
  gcert->cert_type = GNUTLS_CRT_OPENPGP;
777
 
  gcert->version = gnutls_openpgp_crt_get_version( cert);
778
 
  gcert->params_size = MAX_PUBLIC_PARAMS_SIZE;
779
 
  
780
 
  ret = gnutls_openpgp_crt_get_preferred_key_id( cert, keyid);
781
 
  
782
 
  if (ret == 0)
783
 
    {
784
 
      int idx;
785
 
      uint32_t kid32[2];
786
 
 
787
 
      _gnutls_debug_log("Importing Openpgp cert and using openpgp sub key: %s\n",
788
 
        _gnutls_bin2hex( keyid, sizeof(keyid), err_buf, sizeof(err_buf)));
789
 
  
790
 
      KEYID_IMPORT(kid32, keyid);
791
 
 
792
 
      idx = gnutls_openpgp_crt_get_subkey_idx( cert, keyid);
793
 
      if (idx < 0)
794
 
        {
795
 
          gnutls_assert();
796
 
          return idx;
797
 
        }
798
 
 
799
 
      gcert->subject_pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm( cert, idx, NULL);
800
 
  
801
 
      gnutls_openpgp_crt_get_subkey_usage( cert, idx, &gcert->key_usage);
802
 
      gcert->use_subkey = 1;
803
 
 
804
 
      memcpy(gcert->subkey_id, keyid, sizeof(keyid));
805
 
 
806
 
      ret = _gnutls_openpgp_crt_get_mpis( cert, kid32, gcert->params, &gcert->params_size);
807
 
    }
808
 
  else
809
 
    {
810
 
      _gnutls_debug_log("Importing Openpgp cert and using main openpgp key\n");
811
 
      gcert->subject_pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm( cert, NULL);
812
 
  
813
 
      gnutls_openpgp_crt_get_key_usage( cert, &gcert->key_usage);
814
 
      ret = _gnutls_openpgp_crt_get_mpis( cert, NULL, gcert->params, &gcert->params_size);
815
 
      gcert->use_subkey = 0;
816
 
    }
817
 
  
818
 
  if (ret < 0)
819
 
    {
820
 
      gnutls_assert();
821
 
      return ret;
822
 
    }
823
 
 
824
 
    { /* copy the raw certificate */
825
 
#define SMALL_RAW 512
826
 
      opaque *raw;
827
 
      size_t raw_size = SMALL_RAW;
828
 
 
829
 
      /* initially allocate a bogus size, just in case the certificate
830
 
       * fits in it. That way we minimize the DER encodings performed.
831
 
       */
832
 
      raw = gnutls_malloc (raw_size);
833
 
      if (raw == NULL)
834
 
        {
835
 
          gnutls_assert ();
836
 
          return GNUTLS_E_MEMORY_ERROR;
837
 
        }
838
 
 
839
 
      ret =
840
 
        gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW, raw, &raw_size);
841
 
      if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
842
 
        {
843
 
          gnutls_assert ();
844
 
          gnutls_free (raw);
845
 
          return ret;
846
 
        }
847
 
 
848
 
      if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
849
 
        {
850
 
          raw = gnutls_realloc (raw, raw_size);
851
 
          if (raw == NULL)
852
 
            {
853
 
              gnutls_assert ();
854
 
              return GNUTLS_E_MEMORY_ERROR;
855
 
            }
856
 
 
857
 
          ret =
858
 
            gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW, raw,
859
 
                                    &raw_size);
860
 
          if (ret < 0)
861
 
            {
862
 
              gnutls_assert ();
863
 
              gnutls_free (raw);
864
 
              return ret;
865
 
            }
866
 
        }
867
 
 
868
 
      gcert->raw.data = raw;
869
 
      gcert->raw.size = raw_size;
870
 
    }
871
 
 
872
 
  return 0;
873
 
 
874
 
}
875
 
 
876
 
 
877
 
/**
878
 
 * gnutls_openpgp_privkey_sign_hash - sign the given data using the private key params
879
 
 * @key: Holds the key
880
 
 * @hash: holds the data to be signed
881
 
 * @signature: will contain newly allocated signature
882
 
 *
883
 
 * This function will sign the given hash using the private key.  You
884
 
 * should use gnutls_openpgp_privkey_set_subkey() before calling this
885
 
 * function to set the subkey to use.
886
 
 *
887
 
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
888
 
 *   negative error value.
889
 
 **/
890
 
int
891
 
gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
892
 
                                  const gnutls_datum_t * hash,
893
 
                                  gnutls_datum_t * signature)
894
 
{
895
 
  int result, i;
896
 
  mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
897
 
  int params_size = MAX_PUBLIC_PARAMS_SIZE;
898
 
  int pk_algorithm;
899
 
  gnutls_openpgp_keyid_t keyid;
900
 
 
901
 
  if (key == NULL)
902
 
    {
903
 
      gnutls_assert ();
904
 
      return GNUTLS_E_INVALID_REQUEST;
905
 
    }
906
 
 
907
 
  result = gnutls_openpgp_privkey_get_preferred_key_id( key, keyid);
908
 
  if (result == 0)
909
 
    {
910
 
      uint32_t kid[2];
911
 
 
912
 
      KEYID_IMPORT( kid, keyid);
913
 
      result = _gnutls_openpgp_privkey_get_mpis (key, kid,
914
 
                                                 params, &params_size);
915
 
    }
916
 
  else
917
 
    {
918
 
      result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
919
 
                                                 params, &params_size);
920
 
    }
921
 
 
922
 
  if (result < 0)
923
 
    {
924
 
      gnutls_assert ();
925
 
      return result;
926
 
    }
927
 
 
928
 
  pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
929
 
 
930
 
  result = _gnutls_sign (pk_algorithm, params,
931
 
                         params_size, hash, signature);
932
 
 
933
 
  for (i=0;i<params_size;i++)
934
 
    _gnutls_mpi_release( &params[i]);
935
 
 
936
 
  if (result < 0)
937
 
    {
938
 
      gnutls_assert ();
939
 
      return result;
940
 
    }
941
 
 
942
 
  return 0;
943
 
}