*** empty log message ***
[gnutls.git] / libextra / gnutls_openpgp.c
blob8a85ff87de706f3f5db37d20f04ea8085b268e53
1 /*
2 * Copyright (C) 2002 Timo Schulz <twoaday@freakmail.de>
4 * This file is part of GNUTLS.
6 * GNUTLS-EXTRA 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.
11 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include "gnutls_int.h"
22 #include "gnutls_errors.h"
23 #include "gnutls_mpi.h"
24 #include "gnutls_cert.h"
25 #include "gnutls_datum.h"
26 #include "gnutls_global.h"
27 #include "auth_cert.h"
28 #include "gnutls_openpgp.h"
30 #ifdef HAVE_LIBOPENCDK
32 #include <stdio.h>
33 #include <gcrypt.h>
34 #include <opencdk.h>
35 #include <time.h>
36 #include <sys/stat.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #include <netdb.h>
41 #include <assert.h>
43 #define OPENPGP_NAME_SIZE GNUTLS_X509_CN_SIZE
45 typedef struct {
46 int type;
47 int armored;
48 size_t size;
49 uint8 *data;
50 } keybox_blob;
52 typedef enum {
53 KBX_BLOB_FILE = 0x00,
54 KBX_BLOB_DATA = 0x01
55 } keyring_blob_types;
57 static void
58 release_mpi_array( GNUTLS_MPI *arr, size_t n )
60 GNUTLS_MPI x;
62 while ( arr && n-- ) {
63 x = *arr;
64 _gnutls_mpi_release( &x );
65 *arr = NULL; arr++;
69 static u32
70 buffer_to_u32( const uint8 *buffer )
72 const uint8 *p = buffer;
74 if ( !p )
75 return 0;
76 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
79 static int
80 file_exist(const char *file)
82 FILE *fp;
84 if (!file)
85 return 0;
87 fp = fopen(file, "r");
88 if ( fp ) {
89 fclose(fp);
90 return 1;
93 return 0;
96 static int
97 kbx_blob_new( keybox_blob **r_ctx )
99 keybox_blob *c;
101 if ( !r_ctx )
102 return GNUTLS_E_INVALID_PARAMETERS;
104 c = cdk_alloc_clear( sizeof * c);
105 if ( !c )
106 return GNUTLS_E_MEMORY_ERROR;
107 *r_ctx = c;
109 return 0;
110 } /* kbx_blob_new */
112 static void
113 kbx_blob_release( keybox_blob *ctx )
115 if ( ctx ) {
116 cdk_free( ctx->data );
117 cdk_free( ctx );
119 } /* kbx_blob_release */
121 static KEYDB_HD
122 kbx_to_keydb( keybox_blob *blob )
124 KEYDB_HD khd = NULL;
126 if ( !blob )
127 return NULL;
129 khd = cdk_alloc_clear( sizeof *khd );
130 if ( !khd )
131 return NULL;
132 khd->used = 1;
133 if ( blob->type == KBX_BLOB_FILE ) { /* file */
134 khd->name = cdk_strdup( blob->data );
135 khd->type = blob->armored? KEYDB_TYPE_ARMORED: KEYDB_TYPE_KEYRING;
137 else if ( blob->type == KBX_BLOB_DATA ) { /* data */
138 cdk_iobuf_new( &khd->buf, blob->size );
139 cdk_iobuf_write( khd->buf, blob->data, blob->size );
140 khd->type = KEYDB_TYPE_DATA;
142 else { /* error */
143 cdk_free( khd );
144 khd = NULL;
147 return khd;
148 } /* kbx_to_keydb */
150 /* Extract a keybox blob from the given position. */
151 static keybox_blob*
152 kbx_read_blob( const gnutls_datum* keyring, size_t pos )
154 keybox_blob *blob = NULL;
156 if ( !keyring || !keyring->data )
157 return NULL;
159 if ( pos > keyring->size )
160 return NULL;
162 kbx_blob_new( &blob );
163 blob->type = keyring->data[pos];
164 if ( blob->type != KBX_BLOB_FILE &&
165 blob->type != KBX_BLOB_DATA ) {
166 kbx_blob_release( blob );
167 return NULL;
169 blob->armored = keyring->data[pos+1];
170 blob->size = buffer_to_u32( keyring->data+pos+2 );
171 if ( !blob->size ) {
172 kbx_blob_release( blob );
173 return NULL;
175 blob->data = cdk_alloc_clear( blob->size + 1 );
176 if ( !blob->data )
177 return NULL;
178 memcpy( blob->data, keyring->data+(pos+6), blob->size );
179 blob->data[blob->size] = '\0';
181 return blob;
182 } /* kbx_read_blob */
184 /* Creates a keyring blob from raw data
186 * Format:
187 * 1 octet type
188 * 1 octet armored
189 * 4 octet size of blob
190 * n octets data
192 static byte*
193 kbx_data_to_keyring( int type, int enc, const char *data,
194 size_t size, size_t *r_size )
196 uint8 *p = NULL;
198 if ( !data )
199 return NULL;
201 p = gnutls_malloc( 1+4+size );
202 if ( !p )
203 return NULL;
204 p[0] = type; /* type: {keyring,name} */
205 p[1] = enc; /* encoded: {plain, armored} */
206 p[2] = (size >> 24) & 0xff;
207 p[3] = (size >> 16) & 0xff;
208 p[4] = (size >> 8) & 0xff;
209 p[5] = (size ) & 0xff;
210 memcpy( p+6, data, size );
211 if ( r_size )
212 *r_size = 6+size;
214 return p;
215 } /* kbx_data_to_keyring */
217 static int
218 kbnode_to_datum( CDK_KBNODE kb_pk, gnutls_datum *raw )
220 CDK_KBNODE p = NULL;
221 CDK_BSTRING dat = NULL;
222 CDK_IOBUF a = NULL;
223 PACKET pkt = {0};
224 int rc = 0;
226 if ( !kb_pk || !raw )
227 return GNUTLS_E_INVALID_PARAMETERS;
229 /* fixme: conver the whole key */
230 for (p=kb_pk; p && p->pkt->pkttype; p=p->next) {
231 if (p->pkt->pkttype == PKT_PUBLIC_KEY) {
232 a = cdk_iobuf_temp();
233 pkt.pkttype = PKT_PUBLIC_KEY;
234 pkt.pkt.public_key = p->pkt->pkt.public_key;
235 rc = cdk_pkt_build( a, &pkt );
236 if ( rc ) {
237 rc = GNUTLS_E_UNKNOWN_ERROR;
238 goto fail;
240 dat = cdk_iobuf_read_mem( a, 0 );
241 if ( dat ) {
242 rc = gnutls_set_datum( raw, dat->d, dat->len );
243 if ( rc < 0 ) {
244 gnutls_assert();
245 rc = GNUTLS_E_MEMORY_ERROR;
246 goto fail;
252 fail:
253 cdk_free( dat );
254 cdk_iobuf_close( a );
255 return rc;
258 static int
259 datum_to_kbnode( const gnutls_datum *raw, CDK_KBNODE *r_pkt )
261 CDK_IOBUF buf;
262 CDK_KBNODE pkt = NULL;
263 int dummy = 0;
264 int rc = 0;
266 if ( !raw || !r_pkt )
267 return GNUTLS_E_INVALID_PARAMETERS;
269 cdk_iobuf_new( &buf, raw->size );
270 cdk_iobuf_write( buf, raw->data, raw->size );
271 rc = cdk_keydb_get_keyblock( buf, &pkt, &dummy );
272 if ( rc && rc != CDKERR_EOF ) {
273 rc = GNUTLS_E_UNKNOWN_ERROR;
274 goto fail;
276 else
277 rc = 0;
279 fail:
280 cdk_iobuf_close( buf );
281 *r_pkt = (!rc)? pkt : NULL;
283 return rc;
286 static int
287 iobuf_to_datum( CDK_IOBUF buf, gnutls_datum *raw )
289 CDK_BSTRING a = NULL;
290 int rc = 0;
292 if ( !buf || !raw )
293 return GNUTLS_E_INVALID_PARAMETERS;
295 a = cdk_iobuf_read_mem( buf, 0 );
296 if ( a ) {
297 rc = gnutls_set_datum( raw, a->d, a->len );
298 if ( rc < 0 ) {
299 rc = GNUTLS_E_MEMORY_ERROR;
300 goto fail;
303 else
304 rc = GNUTLS_E_UNKNOWN_ERROR;
306 fail:
307 cdk_free( a );
308 return rc;
311 static int
312 openpgp_pk_to_gnutls_cert(gnutls_cert *cert, PKT_public_key *pk)
314 size_t nbytes = 0;
315 int algo, i;
316 int rc = 0;
318 if (!cert || !pk)
319 return GNUTLS_E_INVALID_PARAMETERS;
321 /* GnuTLS OpenPGP doesn't support ELG keys */
322 if ( is_ELG(pk->pubkey_algo) )
323 return GNUTLS_E_UNWANTED_ALGORITHM;
325 algo = is_DSA(pk->pubkey_algo)? GNUTLS_PK_DSA : GNUTLS_PK_RSA;
326 cert->subject_pk_algorithm = algo;
327 cert->version = pk->version;
328 cert->valid = 0; /* fixme: should set after the verification */
329 cert->cert_type = GNUTLS_CRT_OPENPGP;
331 if (is_DSA(pk->pubkey_algo) || pk->pubkey_algo == GCRY_PK_RSA_S)
332 cert->keyUsage = GNUTLS_X509KEY_DIGITAL_SIGNATURE;
333 else if (pk->pubkey_algo == GCRY_PK_RSA_E)
334 cert->keyUsage = GNUTLS_X509KEY_ENCIPHER_ONLY;
335 else if (pk->pubkey_algo == GCRY_PK_RSA)
336 cert->keyUsage = GNUTLS_X509KEY_DIGITAL_SIGNATURE
337 | GNUTLS_X509KEY_ENCIPHER_ONLY;
339 cert->params_size = cdk_pk_get_npkey( pk->pubkey_algo );
340 for (i=0; i<cert->params_size; i++) {
341 nbytes = pk->mpi[i].bytes+2;
342 rc = _gnutls_mpi_scan_pgp( &cert->params[i],
343 pk->mpi[i].data, &nbytes );
344 if ( rc ) {
345 rc = GNUTLS_E_MPI_SCAN_FAILED;
346 goto fail;
349 cert->expiration_time = pk->expiredate;
350 cert->activation_time = pk->timestamp;
352 fail:
353 if ( rc )
354 release_mpi_array(cert->params, i-1);
356 return rc;
359 static int
360 openpgp_sig_to_gnutls_cert(gnutls_cert *cert, PKT_signature *sig)
362 CDK_IOBUF buf = NULL;
363 CDK_BSTRING a = NULL;
364 PACKET pkt;
365 size_t sigsize = 0;
366 int rc = 0;
368 if (!cert || !sig)
369 return GNUTLS_E_INVALID_PARAMETERS;
371 sigsize = 20 + sig->hashed_size + sig->unhashed_size + 2*MAX_MPI_BYTES;
372 cdk_iobuf_new( &buf, sigsize );
373 memset( &pkt, 0, sizeof pkt );
374 pkt.pkttype = PKT_SIGNATURE;
375 pkt.pkt.signature = sig;
376 rc = cdk_pkt_build( buf, &pkt );
377 if ( rc )
378 goto fail;
379 a = cdk_iobuf_read_mem( buf, 0 );
380 if ( a ) {
381 rc = gnutls_datum_append( &cert->signature, a->d, a->len );
382 if (rc < 0) {
383 gnutls_assert();
384 rc = GNUTLS_E_MEMORY_ERROR;
385 goto fail;
388 else
389 rc = GNUTLS_E_UNKNOWN_ERROR;
391 fail:
392 cdk_free( a );
393 cdk_iobuf_close( buf );
395 return rc;
399 * _gnutls_openpgp_key2gnutls_key - Converts an OpenPGP secret key to GnuTLS
400 * @pkey: the GnuTLS private key context to store the key.
401 * @raw_key: the raw data which contains the whole key packets.
403 * The RFC2440 (OpenPGP Message Format) data is converted into the
404 * GnuTLS specific data which is need to perform secret key operations.
407 _gnutls_openpgp_key2gnutls_key( gnutls_private_key *pkey,
408 gnutls_datum raw_key )
410 CDK_KBNODE p = NULL, kb_sk;
411 CDK_IOBUF buf;
412 PKT_secret_key *sk = NULL;
413 int pke_algo, i, j, eof = 0;
414 size_t nbytes = 0;
415 int rc = 0;
417 if ( !pkey || raw_key.size <= 0 )
418 return GNUTLS_E_INVALID_PARAMETERS;
420 cdk_secmem_init( 16384 );
421 cdk_iobuf_new( &buf, raw_key.size );
422 cdk_iobuf_write( buf, raw_key.data, raw_key.size );
424 rc = cdk_keydb_get_keyblock( buf, &kb_sk, &eof );
425 if ( !kb_sk || rc ) {
426 rc = GNUTLS_E_UNKNOWN_ERROR;
427 goto leave;
429 p = cdk_kbnode_find( kb_sk, PKT_SECRET_KEY );
430 if ( !p ) {
431 rc = GNUTLS_E_UNKNOWN_ERROR;
432 goto leave;
434 sk = p->pkt->pkt.secret_key;
435 pke_algo = sk->pk->pubkey_algo;
436 pkey->params_size = cdk_pk_get_npkey( pke_algo );
437 for ( i = 0; i < pkey->params_size; i++ ) {
438 nbytes = sk->pk->mpi[i].bytes+2;
439 rc = _gnutls_mpi_scan_pgp( &pkey->params[i],
440 sk->pk->mpi[i].data, &nbytes );
441 if ( rc ) {
442 rc = GNUTLS_E_MPI_SCAN_FAILED;
443 release_mpi_array( pkey->params, i-1 );
444 goto leave;
447 pkey->params_size += cdk_pk_get_nskey( pke_algo );
448 for (j=0; j<cdk_pk_get_nskey( pke_algo ); j++, i++) {
449 nbytes = sk->mpi[j]->bytes+2;
450 rc = _gnutls_mpi_scan_pgp(&pkey->params[i],
451 sk->mpi[j]->data, &nbytes);
452 if ( rc ) {
453 rc = GNUTLS_E_MPI_SCAN_FAILED;
454 release_mpi_array(pkey->params, i-1);
455 goto leave;
458 if ( is_ELG(pke_algo) )
459 return GNUTLS_E_UNWANTED_ALGORITHM;
460 else if ( is_DSA(pke_algo) )
461 pkey->pk_algorithm = GNUTLS_PK_DSA;
462 else if ( is_RSA(pke_algo) )
463 pkey->pk_algorithm = GNUTLS_PK_RSA;
464 rc = gnutls_set_datum( &pkey->raw, raw_key.data, raw_key.size );
465 if ( rc < 0 ) {
466 release_mpi_array(pkey->params, i);
467 rc = GNUTLS_E_MEMORY_ERROR;
470 leave:
471 cdk_iobuf_close( buf );
472 cdk_kbnode_release( kb_sk );
474 return rc;
478 * _gnutls_openpgp_cert2gnutls_cert - Converts raw OpenPGP data to GnuTLS certs
479 * @cert: the certificate to store the data.
480 * @raw: the buffer which contains the whole OpenPGP key packets.
482 * The RFC2440 (OpenPGP Message Format) data is converted to a GnuTLS
483 * specific certificate.
486 _gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw)
488 CDK_KBNODE p, kb_pk = NULL;
489 PKT_public_key *pk = NULL;
490 int rc = 0;
492 if ( !cert )
493 return GNUTLS_E_INVALID_PARAMETERS;
495 memset( cert, 0, sizeof *cert );
496 rc = datum_to_kbnode( &raw, &kb_pk );
497 if ( rc )
498 return rc;
499 p = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
500 if ( !p ) {
501 rc = GNUTLS_E_UNKNOWN_ERROR;
502 goto fail;
504 pk = p->pkt->pkt.public_key;
505 rc = gnutls_set_datum( &cert->raw, raw.data, raw.size );
506 if ( rc < 0 ) {
507 rc = GNUTLS_E_MEMORY_ERROR;
508 goto fail;
510 rc = openpgp_pk_to_gnutls_cert( cert, pk );
512 fail:
513 cdk_kbnode_release( kb_pk );
515 return rc;
519 * gnutls_openpgp_get_key - Retrieve a key from the keyring.
520 * @key: the destination context to save the key.
521 * @keyring: the datum struct that contains all keyring information.
522 * @attr: The attribute (keyid, fingerprint, ...).
523 * @by: What attribute is used.
525 * This function can be used to retrieve keys by different pattern
526 * from a binary or a file keyring.
529 gnutls_openpgp_get_key(gnutls_datum *key, const gnutls_datum *keyring,
530 key_attr_t by, opaque *pattern)
532 keybox_blob *blob = NULL;
533 KEYDB_HD khd = NULL;
534 CDK_KBNODE pk = NULL;
535 KEYDB_SEARCH ks;
536 int rc = 0;
538 if ( !key || !keyring || by == KEY_ATTR_NONE )
539 return GNUTLS_E_INVALID_PARAMETERS;
541 blob = kbx_read_blob( keyring, 0 );
542 if (!blob)
543 return GNUTLS_E_MEMORY_ERROR;
544 khd = kbx_to_keydb( blob );
545 ks.type = by;
546 switch (by) {
547 case KEY_ATTR_SHORT_KEYID:
548 ks.u.keyid[1] = buffer_to_u32(pattern);
549 break;
551 case KEY_ATTR_KEYID:
552 ks.u.keyid[0] = buffer_to_u32(pattern);
553 ks.u.keyid[1] = buffer_to_u32(pattern+4);
554 break;
556 case KEY_ATTR_FPR:
557 memcpy(ks.u.fpr, pattern, 20);
558 break;
560 default:
561 goto leave;
564 rc = cdk_keydb_search( khd, &ks, &pk );
565 if ( rc ) {
566 rc = GNUTLS_E_UNKNOWN_ERROR;
567 goto leave;
570 if ( !cdk_kbnode_find( pk, PKT_PUBLIC_KEY ) ) {
571 rc = GNUTLS_E_UNKNOWN_ERROR;
572 goto leave;
575 rc = kbnode_to_datum( pk, key );
577 leave:
578 cdk_free( khd );
579 cdk_kbnode_release( pk );
580 kbx_blob_release( blob );
582 return rc;
586 gnutls_certificate_set_openpgp_key_mem( GNUTLS_CERTIFICATE_CREDENTIALS res,
587 gnutls_datum *cert,
588 gnutls_datum *key )
590 gnutls_datum raw;
591 CDK_KBNODE kb_pk = NULL, pkt;
592 int i = 0;
593 int rc = 0;
595 if ( !res || !key || !cert )
596 return GNUTLS_E_INVALID_PARAMETERS;
598 rc = datum_to_kbnode( cert, &kb_pk );
599 if ( rc )
600 goto leave;
602 /* fixme: too much duplicated code from (set_openpgp_key_file) */
603 res->cert_list = gnutls_realloc(res->cert_list,
604 (1+res->ncerts)*sizeof(gnutls_cert*));
605 if (res->cert_list == NULL) {
606 gnutls_assert();
607 return GNUTLS_E_MEMORY_ERROR;
610 res->cert_list_length = gnutls_realloc(res->cert_list_length,
611 (1+res->ncerts)*sizeof(int));
612 if (res->cert_list_length == NULL) {
613 gnutls_assert();
614 return GNUTLS_E_MEMORY_ERROR;
617 res->cert_list[res->ncerts] = gnutls_calloc(1, sizeof(gnutls_cert));
618 if (res->cert_list[res->ncerts] == NULL) {
619 gnutls_assert();
620 return GNUTLS_E_MEMORY_ERROR;
623 for (i=1, pkt=kb_pk; pkt && pkt->pkt->pkttype; pkt=pkt->next) {
624 if (i > MAX_PARAMS_SIZE)
625 break;
626 if (pkt->pkt->pkttype == PKT_PUBLIC_KEY) {
627 int n = res->ncerts;
628 PKT_public_key *pk = pkt->pkt->pkt.public_key;
629 res->cert_list_length[n] = 1;
630 gnutls_set_datum(&res->cert_list[n][0].raw,
631 cert->data, cert->size);
632 openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk );
633 i++;
635 else if (pkt->pkt->pkttype == PKT_SIGNATURE) {
636 int n = res->ncerts;
637 PKT_signature *sig = pkt->pkt->pkt.signature;
638 openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig );
642 res->ncerts++;
643 res->pkey = gnutls_realloc(res->pkey,
644 (res->ncerts)*sizeof(gnutls_private_key));
645 if (res->pkey == NULL) {
646 gnutls_assert();
647 return GNUTLS_E_MEMORY_ERROR;
649 /* ncerts has been incremented before */
650 gnutls_set_datum(&raw, key->data, key->size);
651 rc =_gnutls_openpgp_key2gnutls_key( &res->pkey[res->ncerts-1], raw);
652 gnutls_free_datum(&raw);
654 leave:
655 cdk_kbnode_release( kb_pk );
657 return rc;
661 * gnutls_certificate_set_openpgp_key_file - Used to set OpenPGP keys
662 * @res: the destination context to save the data.
663 * @CERTFILE: the file that contains the public key.
664 * @KEYFILE: the file that contains the secret key.
666 * This funtion is used to load OpenPGP keys into the GnuTLS structure.
667 * It doesn't matter whether the keys are armored or but, but the files
668 * should only contain one key which should not be encrypted.
671 gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res,
672 char* CERTFILE,
673 char* KEYFILE)
675 CDK_IOBUF inp = NULL;
676 CDK_KBNODE kb_pk = NULL, pkt;
677 armor_filter_s afx;
678 gnutls_datum raw;
679 int eof = 0, i = 0;
680 int rc = 0;
682 if ( !res || !KEYFILE || !CERTFILE )
683 return GNUTLS_E_INVALID_PARAMETERS;
685 if ( !file_exist(CERTFILE) || !file_exist(KEYFILE) )
686 return GNUTLS_E_FILE_ERROR;
688 rc = cdk_iobuf_open(&inp, CERTFILE, IOBUF_MODE_RD);
689 if ( rc )
690 return GNUTLS_E_FILE_ERROR;
691 if ( cdk_armor_filter_use( inp ) ) {
692 memset( &afx, 0, sizeof afx );
693 rc = cdk_armor_filter( &afx, IOBUF_CTRL_UNDERFLOW, inp );
694 if ( rc ) {
695 cdk_iobuf_close( inp );
696 rc = GNUTLS_E_ASCII_ARMOR_ERROR;
697 goto leave;
699 /*cdk_iobuf_close( inp );*/
702 res->cert_list = gnutls_realloc(res->cert_list,
703 (1+res->ncerts)*sizeof(gnutls_cert*));
704 if (res->cert_list == NULL) {
705 gnutls_assert();
706 return GNUTLS_E_MEMORY_ERROR;
709 res->cert_list_length = gnutls_realloc(res->cert_list_length,
710 (1+res->ncerts)*sizeof(int));
711 if (res->cert_list_length == NULL) {
712 gnutls_assert();
713 return GNUTLS_E_MEMORY_ERROR;
716 res->cert_list[res->ncerts] = gnutls_calloc(1, sizeof(gnutls_cert));
717 if (res->cert_list[res->ncerts] == NULL) {
718 gnutls_assert();
719 return GNUTLS_E_MEMORY_ERROR;
722 do {
723 rc = cdk_keydb_get_keyblock( inp, &kb_pk, &eof );
724 if ( !kb_pk || rc )
725 break;
726 for (i=1, pkt=kb_pk; pkt && pkt->pkt->pkttype; pkt=pkt->next) {
727 if (i > MAX_PARAMS_SIZE)
728 break;
729 if (pkt->pkt->pkttype == PKT_PUBLIC_KEY) {
730 int n = res->ncerts;
731 PKT_public_key *pk = pkt->pkt->pkt.public_key;
732 res->cert_list_length[n] = 1;
733 iobuf_to_datum(inp, &res->cert_list[n][0].raw);
734 openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk );
735 i++;
737 else if (pkt->pkt->pkttype == PKT_SIGNATURE) {
738 int n = res->ncerts;
739 PKT_signature *sig = pkt->pkt->pkt.signature;
740 openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig );
743 } while (!eof && !rc);
745 cdk_iobuf_close(inp);
746 if ( rc ) {
747 cdk_kbnode_release( kb_pk );
748 rc = GNUTLS_E_UNKNOWN_ERROR;
749 goto leave;
751 cdk_kbnode_release( kb_pk );
753 rc = cdk_iobuf_open( &inp, KEYFILE, IOBUF_MODE_RD );
754 if ( rc )
755 return GNUTLS_E_FILE_ERROR;
756 if ( cdk_armor_filter_use( inp ) ) {
757 memset( &afx, 0, sizeof afx );
758 rc = cdk_armor_filter( &afx, IOBUF_CTRL_UNDERFLOW, inp );
759 if ( rc ) {
760 cdk_iobuf_close( inp );
761 rc = GNUTLS_E_ASCII_ARMOR_ERROR;
762 goto leave;
764 /*cdk_iobuf_close( inp );*/
767 iobuf_to_datum( inp, &raw );
768 cdk_iobuf_close( inp );
770 res->pkey = gnutls_realloc(res->pkey,
771 (res->ncerts+1)*sizeof(gnutls_private_key));
772 if (res->pkey == NULL) {
773 gnutls_assert();
774 return GNUTLS_E_MEMORY_ERROR;
777 res->ncerts++;
779 /* ncerts has been incremented before */
780 rc =_gnutls_openpgp_key2gnutls_key( &res->pkey[res->ncerts-1], raw);
782 leave:
784 return rc;
788 gnutls_openpgp_count_key_names( const gnutls_datum *cert )
790 CDK_KBNODE kb_pk = NULL, pkt;
791 int nuids = 0;
793 if ( !cert )
794 return 0;
796 if ( datum_to_kbnode( cert, &kb_pk ) )
797 return 0;
798 for ( pkt=kb_pk; pkt; pkt=pkt->next ) {
799 if ( pkt->pkt->pkttype == PKT_USER_ID )
800 nuids++;
803 return nuids;
804 } /* gnutls_openpgp_count_key_names */
807 * gnutls_openpgp_extract_key_name - Extracts the userID
808 * @cert: the raw data that contains the OpenPGP public key.
809 * @dn: the structure to store the userID specific data in.
811 * Extracts the userID from the raw OpenPGP key.
814 gnutls_openpgp_extract_key_name( const gnutls_datum *cert,
815 int idx,
816 gnutls_openpgp_name *dn )
818 CDK_KBNODE kb_pk = NULL, pkt;
819 PKT_user_id *uid = NULL;
820 char *email;
821 int pos = 0, pos1 = 0, pos2 = 0;
822 size_t size = 0;
823 int rc = 0;
825 if (!cert || !dn)
826 return GNUTLS_E_INVALID_PARAMETERS;
828 if ( idx < 0 || idx > gnutls_openpgp_count_key_names( cert ) )
829 return GNUTLS_E_UNKNOWN_ERROR;
831 memset(dn, 0, sizeof *dn);
832 rc = datum_to_kbnode( cert, &kb_pk );
833 if ( rc )
834 return rc;
835 if ( !idx )
836 pkt = cdk_kbnode_find( kb_pk, PKT_USER_ID );
837 else {
838 for ( pos=0, pkt=kb_pk; pkt; pkt=pkt->next ) {
839 if ( pkt->pkt->pkttype == PKT_USER_ID && ++pos == idx )
840 break;
843 if ( pkt )
844 uid = pkt->pkt->pkt.user_id;
845 if ( !uid ) {
846 rc = GNUTLS_E_UNKNOWN_ERROR;
847 goto leave;
849 size = uid->len < OPENPGP_NAME_SIZE? uid->len : OPENPGP_NAME_SIZE-1;
850 memcpy(dn->name, uid->name, size);
851 dn->name[size] = '\0'; /* make sure it's a string */
853 /* Extract the email address from the userID string and save
854 it to the email field. */
855 email = strchr(uid->name, '<');
856 if ( email )
857 pos1 = email-uid->name+1;
858 email = strchr(uid->name, '>');
859 if ( email )
860 pos2 = email-uid->name+1;
861 if (pos1 && pos2) {
862 pos2 -= pos1;
863 size = pos2 < OPENPGP_NAME_SIZE? pos2 : OPENPGP_NAME_SIZE-1;
864 memcpy(dn->email, uid->name+pos1, size);
865 dn->email[size-1] = '\0'; /* make sure it's a string */
867 if ( uid->is_revoked ) {
868 rc = GNUTLS_E_OPENPGP_UID_REVOKED;
869 goto leave;
872 leave:
873 cdk_kbnode_release( kb_pk );
875 return rc;
879 * gnutls_openpgp_extract_key_pk_algorithm - This function returns the
880 * key's PublicKey algorithm
881 * @cert: is an OpenPGP key
882 * @bits: if bits is non null it will hold the size of the parameters' in bits
884 * This function will return the public key algorithm of an OpenPGP
885 * certificate.
887 * If bits is non null, it should have enough size to hold the parameters
888 * size in bits. For RSA the bits returned is the modulus.
889 * For DSA the bits returned are of the public exponent.
891 * Returns a member of the GNUTLS_PKAlgorithm enumeration on success,
892 * or a negative value on error.
896 gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, int *r_bits)
898 CDK_KBNODE kb_pk = NULL, pkt;
899 int algo = 0;
901 if ( !cert )
902 return GNUTLS_E_INVALID_PARAMETERS;
904 if ( datum_to_kbnode( cert, &kb_pk ) )
905 return 0;
906 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
907 if ( pkt && r_bits)
908 *r_bits = cdk_pk_get_nbits( pkt->pkt->pkt.public_key );
909 algo = pkt->pkt->pkt.public_key->pubkey_algo;
910 if ( is_RSA( algo ) )
911 algo = GNUTLS_PK_RSA;
912 else if ( is_DSA( algo ) )
913 algo = GNUTLS_PK_DSA;
914 else
915 algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
916 cdk_kbnode_release( kb_pk );
918 return algo;
923 * gnutls_openpgp_extract_key_version - Extracts the version of the key.
924 * @cert: the raw data that contains the OpenPGP public key.
926 * Extract the version of the OpenPGP key.
929 gnutls_openpgp_extract_key_version( const gnutls_datum *cert )
931 CDK_KBNODE kb_pk = NULL, pkt;
932 int version = 0;
934 if (!cert)
935 return GNUTLS_E_INVALID_PARAMETERS;
937 if ( datum_to_kbnode( cert, &kb_pk ) )
938 return 0;
939 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
940 if ( pkt )
941 version = pkt->pkt->pkt.public_key->version;
942 cdk_kbnode_release( kb_pk );
944 return version;
948 * gnutls_openpgp_extract_key_creation_time - Extract the timestamp
949 * @cert: the raw data that contains the OpenPGP public key.
951 * Returns the timestamp when the OpenPGP key was created.
953 time_t
954 gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert )
956 CDK_KBNODE kb_pk = NULL, pkt;
957 time_t timestamp = 0;
959 if (!cert)
960 return GNUTLS_E_INVALID_PARAMETERS;
962 if ( datum_to_kbnode( cert, &kb_pk ) )
963 return 0;
964 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
965 if ( pkt )
966 timestamp = pkt->pkt->pkt.public_key->timestamp;
967 cdk_kbnode_release( kb_pk );
969 return timestamp;
973 * gnutls_openpgp_extract_key_expiration_time - Extract the expire date
974 * @cert: the raw data that contains the OpenPGP public key.
976 * Returns the time when the OpenPGP key expires. A value of '0' means
977 * that the key doesn't expire at all.
979 time_t
980 gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert )
982 CDK_KBNODE kb_pk = NULL, pkt;
983 time_t expiredate = 0;
985 if (!cert)
986 return GNUTLS_E_INVALID_PARAMETERS;
988 if ( datum_to_kbnode( cert, &kb_pk ) )
989 return 0;
990 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
991 if ( pkt )
992 expiredate = pkt->pkt->pkt.public_key->expiredate;
993 cdk_kbnode_release( kb_pk );
995 return expiredate;
999 _gnutls_openpgp_get_key_trust(const char *trustdb,
1000 const gnutls_datum *key,
1001 int *r_success)
1003 CDK_KBNODE kb_pk = NULL, pkt;
1004 CDK_IOBUF buf;
1005 PKT_public_key *pk = NULL;
1006 int flags = 0, ot = 0, trustval = 0;
1007 int rc = 0;
1009 if ( !trustdb || !key || !r_success )
1010 return GNUTLS_E_INVALID_REQUEST;
1012 *r_success = 0;
1013 rc = datum_to_kbnode( key, &kb_pk );
1014 if ( rc )
1015 return GNUTLS_E_UNKNOWN_ERROR;
1017 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
1018 if ( pkt )
1019 pk = pkt->pkt->pkt.public_key;
1020 if ( !pk )
1021 return GNUTLS_E_UNKNOWN_ERROR;
1023 rc = cdk_iobuf_open( &buf, trustdb, IOBUF_MODE_RD );
1024 if ( rc ) {
1025 trustval = GNUTLS_E_FILE_ERROR;
1026 goto leave;
1028 rc = cdk_trustdb_get_ownertrust( buf, pk, &ot, &flags );
1029 cdk_iobuf_close( buf );
1030 if ( rc ) { /* no ownertrust record was found */
1031 trustval = 0;
1032 *r_success = 1;
1033 goto leave;
1036 if (flags & TRUST_FLAG_DISABLED) {
1037 trustval |= GNUTLS_CERT_NOT_TRUSTED;
1038 trustval |= GNUTLS_CERT_INVALID;
1039 goto leave;
1041 if (flags & TRUST_FLAG_REVOKED) {
1042 trustval |= GNUTLS_CERT_NOT_TRUSTED;
1043 trustval |= GNUTLS_CERT_REVOKED;
1045 switch (ot) {
1046 case TRUST_NEVER:
1047 trustval |= GNUTLS_CERT_NOT_TRUSTED;
1048 break;
1050 case TRUST_UNKNOWN:
1051 case TRUST_UNDEFINED:
1052 case TRUST_MARGINAL:
1054 case TRUST_FULLY:
1055 case TRUST_ULTIMATE:
1056 trustval |= 1; /* means okay */
1057 *r_success = 1;
1058 break;
1061 leave:
1062 cdk_kbnode_release( kb_pk );
1063 return trustval;
1067 * gnutls_openpgp_verify_key - Verify all signatures on the key
1068 * @cert_list: the structure that holds the certificates.
1069 * @cert_list_lenght: the items in the cert_list.
1071 * Verify all signatures in the certificate list. When the key
1072 * is not available, the signature is skipped.
1073 * The return value is one of the CertificateStatus entries.
1076 gnutls_openpgp_verify_key( const char *trustdb,
1077 const gnutls_datum* keyring,
1078 const gnutls_datum* cert_list,
1079 int cert_list_length )
1081 CDK_KBNODE kb_pk = NULL;
1082 KEYDB_HD khd = NULL;
1083 keybox_blob *blob = NULL;
1084 int rc = 0;
1085 int status = 0;
1087 if (!cert_list || cert_list_length != 1 || !keyring)
1088 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1090 if ( !keyring->size && !trustdb)
1091 return GNUTLS_E_INVALID_REQUEST;
1093 blob = kbx_read_blob(keyring, 0);
1094 if (!blob)
1095 return GNUTLS_CERT_INVALID|GNUTLS_CERT_NOT_TRUSTED;
1096 khd = kbx_to_keydb(blob);
1097 if (!khd) {
1098 rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED;
1099 goto leave;
1102 if ( trustdb ) {
1103 int success = 0;
1104 rc = _gnutls_openpgp_get_key_trust(trustdb, cert_list, &success);
1105 if (!success)
1106 goto leave;
1109 rc = datum_to_kbnode( cert_list, &kb_pk );
1110 if ( rc ) {
1111 goto leave;
1112 return GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED;
1115 rc = cdk_key_check_sigs( kb_pk, khd, &status );
1116 if (rc == CDKERR_NOKEY)
1117 rc = 0; /* fixme */
1119 switch (status) {
1120 case CDK_KEY_INVALID:
1121 rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED;
1122 break;
1124 case CDK_KEY_REVOKED:
1125 rc = GNUTLS_CERT_REVOKED | GNUTLS_CERT_NOT_TRUSTED;
1126 break;
1130 leave:
1131 kbx_blob_release( blob );
1132 cdk_free( khd );
1133 cdk_kbnode_release( kb_pk );
1135 return rc;
1139 * gnutls_openpgp_fingerprint - Gets the fingerprint
1140 * @cert: the raw data that contains the OpenPGP public key.
1141 * @fpr: the buffer to save the fingerprint.
1142 * @fprlen: the integer to save the length of the fingerprint.
1144 * Returns the fingerprint of the OpenPGP key. Depence on the algorithm,
1145 * the fingerprint can be 16 or 20 bytes.
1148 gnutls_openpgp_fingerprint(const gnutls_datum *cert, char *fpr, size_t *fprlen)
1150 CDK_KBNODE kb_pk = NULL, pkt;
1151 PKT_public_key *pk = NULL;
1152 int rc = 0;
1154 if (!cert || !fpr || !fprlen)
1155 return GNUTLS_E_UNKNOWN_ERROR;
1157 *fprlen = 0;
1158 rc = datum_to_kbnode( cert, &kb_pk );
1159 if (rc)
1160 return rc;
1161 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
1162 if ( pkt )
1163 pk = pkt->pkt->pkt.public_key;
1164 if ( !pk )
1165 return GNUTLS_E_UNKNOWN_ERROR;
1167 *fprlen = 20;
1168 if ( is_RSA(pk->pubkey_algo) && pk->version < 4 )
1169 *fprlen = 16;
1170 cdk_pk_get_fingerprint( pk, fpr );
1172 return 0;
1176 * gnutls_openpgp_keyid - Gets the keyID
1177 * @cert: the raw data that contains the OpenPGP public key.
1178 * @keyid: the buffer to save the keyid.
1180 * Returns the 64-bit keyID of the OpenPGP key.
1183 gnutls_openpgp_keyid( const gnutls_datum *cert, uint32 *keyid )
1185 CDK_KBNODE kb_pk = NULL, pkt;
1186 PKT_public_key *pk = NULL;
1187 int rc = 0;
1189 if (!cert || !keyid)
1190 return GNUTLS_E_UNKNOWN_ERROR;
1192 rc = datum_to_kbnode( cert, &kb_pk );
1193 if (rc)
1194 return rc;
1196 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
1197 if ( pkt )
1198 pk = pkt->pkt->pkt.public_key;
1199 if ( !pk )
1200 return GNUTLS_E_UNKNOWN_ERROR;
1201 cdk_pk_get_keyid( pk, (u32 *)keyid );
1203 return 0;
1207 * gnutls_openpgp_add_keyring_file - Adds a keyring file for OpenPGP
1208 * @keyring: data buffer to store the file.
1209 * @name: filename of the keyring.
1211 * The function is used to set keyrings that will be used internally
1212 * by various OpenCDK functions. For example to find a key when it
1213 * is needed for an operations.
1216 gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name)
1218 CDK_IOBUF inp = NULL;
1219 uint8 *blob;
1220 size_t nbytes;
1221 int enc = 0;
1222 int rc = 0;
1224 if (!keyring || !name)
1225 return GNUTLS_E_INVALID_PARAMETERS;
1227 rc = cdk_iobuf_open( &inp, name, IOBUF_MODE_RD );
1228 if ( rc )
1229 return GNUTLS_E_FILE_ERROR;
1230 enc = cdk_armor_filter_use( inp );
1231 cdk_iobuf_close( inp );
1233 blob = kbx_data_to_keyring( KBX_BLOB_FILE, enc, name,
1234 strlen(name), &nbytes);
1235 if ( blob && nbytes ) {
1236 if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) {
1237 gnutls_assert();
1238 return GNUTLS_E_MEMORY_ERROR;
1240 gnutls_free(blob);
1243 return 0;
1247 * gnutls_openpgp_add_keyring_mem - Adds keyring data for OpenPGP
1248 * @keyring: data buffer to store the file.
1249 * @data: the binary data of the keyring.
1250 * @len: the size of the binary buffer.
1252 * Same as gnutls_openpgp_add_keyring_mem but now we store the
1253 * data instead of the filename.
1256 gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring,
1257 const char *data, size_t len)
1259 uint8 *blob;
1260 size_t nbytes = 0;
1262 if (!keyring || !data || !len)
1263 return GNUTLS_E_INVALID_PARAMETERS;
1265 blob = kbx_data_to_keyring( KBX_BLOB_DATA, 0, data, len, &nbytes );
1266 if ( blob && nbytes ) {
1267 if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) {
1268 gnutls_assert();
1269 return GNUTLS_E_MEMORY_ERROR;
1271 gnutls_free(blob);
1274 return 0;
1278 gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c,
1279 const char *file)
1281 if (!c || !file)
1282 return GNUTLS_E_INVALID_PARAMETERS;
1284 if ( !file_exist(file) )
1285 return GNUTLS_E_FILE_ERROR;
1287 return gnutls_openpgp_add_keyring_file(&c->keyring, file);
1291 gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c,
1292 const char *file)
1294 CDK_IOBUF inp = NULL;
1295 CDK_BSTRING a = NULL;
1296 armor_filter_s afx;
1297 int rc = 0;
1299 if (!c || !file)
1300 return GNUTLS_E_INVALID_PARAMETERS;
1302 if ( !file_exist(file) )
1303 return GNUTLS_E_FILE_ERROR;
1305 rc = cdk_iobuf_open( &inp, file, IOBUF_MODE_RD );
1306 if ( rc )
1307 return GNUTLS_E_FILE_ERROR;
1308 if ( cdk_armor_filter_use( inp ) ) {
1309 memset( &afx, 0, sizeof afx );
1310 rc = cdk_armor_filter( &afx, IOBUF_CTRL_UNDERFLOW, inp );
1311 if ( rc ) {
1312 cdk_iobuf_close( inp );
1313 return GNUTLS_E_ASCII_ARMOR_ERROR;
1317 a = cdk_iobuf_read_mem( inp, 0 );
1318 if ( a ) {
1319 rc = gnutls_openpgp_add_keyring_mem( &c->keyring, a->d, a->len );
1320 cdk_free( a );
1322 else
1323 rc = GNUTLS_E_UNKNOWN_ERROR;
1324 cdk_iobuf_close( inp );
1326 return rc;
1330 * gnutls_openpgp_recv_key - Receives a key from a HKP keyserver.
1331 * @host - the hostname of the keyserver.
1332 * @port - the service port (if not set use 11371).
1333 * @keyid - The 32-bit keyID (rightmost bits keyid[1])
1334 * @key - Context to store the raw (dearmored) key.
1336 * Try to connect to a public keyserver to get the specified key.
1339 gnutls_openpgp_recv_key(const char *host, short port, uint32 keyid,
1340 gnutls_datum *key)
1342 CDK_IOBUF buf = NULL;
1343 CDK_BSTRING a = NULL;
1344 struct hostent *hp;
1345 struct sockaddr_in sock;
1346 armor_filter_s afx;
1347 char *request = NULL;
1348 char buffer[4096];
1349 int fd = -1;
1350 int rc = 0, state = 0;
1351 ssize_t nbytes = 0, n = 0;
1353 if ( !host || !key )
1354 return GNUTLS_E_INVALID_PARAMETERS;
1356 if ( !port )
1357 port = 11371; /* standard service port */
1359 hp = gethostbyname( host );
1360 if ( hp == NULL )
1361 return -1;
1363 memset( &sock, 0, sizeof sock );
1364 memcpy( &sock.sin_addr, hp->h_addr, hp->h_length );
1365 sock.sin_family = hp->h_addrtype;
1366 sock.sin_port = htons( port );
1368 fd = socket(AF_INET, SOCK_STREAM, 0);
1369 if ( fd == -1 )
1370 return -1;
1371 setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (char *)1, 1 );
1372 if ( connect( fd, (struct sockaddr*)&sock, sizeof(sock) ) == -1 ) {
1373 close(fd);
1374 return -1;
1377 n = strlen(host)+100;
1378 request = cdk_alloc_clear( n + 1 );
1379 if ( request == NULL ) {
1380 close( fd );
1381 return -1;
1383 snprintf( request, n,
1384 "GET /pks/lookup?op=get&search=0x%08X HTTP/1.0\r\n"
1385 "Host: %s:%d\r\n", (u32)keyid, host, port );
1387 if ( write( fd, request, strlen(request) ) == -1 ) {
1388 cdk_free( request );
1389 close( fd );
1390 return -1;
1392 cdk_free( request );
1394 buf = cdk_iobuf_temp();
1395 while ( (n = read(fd, buffer, sizeof(buffer)-1)) > 0 )
1397 buffer[n] = '\0';
1398 nbytes += n;
1399 if ( nbytes > cdk_iobuf_get_length( buf ) )
1400 cdk_iobuf_expand(buf, n);
1401 cdk_iobuf_write(buf, buffer, n);
1402 if ( strstr(buffer, "<pre>") || strstr(buffer, "</pre>") )
1403 state++;
1406 if ( state != 2 ) {
1407 rc = GNUTLS_E_UNKNOWN_ERROR;
1408 goto leave;
1410 memset( &afx, 0, sizeof afx );
1411 rc = cdk_armor_filter( &afx, IOBUF_CTRL_UNDERFLOW, buf );
1412 if ( rc ) {
1413 rc = GNUTLS_E_ASCII_ARMOR_ERROR;
1414 goto leave;
1416 a = cdk_iobuf_read_mem(buf, 0 );
1417 if ( a ) {
1418 rc = gnutls_set_datum( key, a->d, a->len );
1419 if ( rc < 0 )
1420 rc = GNUTLS_E_MEMORY_ERROR;
1421 cdk_free( a );
1424 leave:
1425 cdk_iobuf_close(buf);
1426 close(fd);
1428 return 0;
1432 * _gnutls_openpgp_request_key - Receives a key from a database, key server etc
1433 * @ret - a pointer to gnutls_datum structure.
1434 * @cred - a GNUTLS_CERTIFICATE_CREDENTIALS structure.
1435 * @key_fingerprint - The keyFingerprint
1436 * @key_fingerprint_size - the size of the fingerprint
1438 * Retrieves a key from a local database, keyring, or a key server. The
1439 * return value is locally allocated.
1443 _gnutls_openpgp_request_key( gnutls_datum* ret,
1444 const GNUTLS_CERTIFICATE_CREDENTIALS cred,
1445 opaque* key_fpr,
1446 int key_fpr_size)
1448 uint32 keyid;
1449 int rc = 0;
1451 if (!ret || !cred || !key_fpr)
1452 return GNUTLS_E_INVALID_PARAMETERS;
1454 if ( key_fpr_size != 16 && key_fpr_size != 20 )
1455 return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */
1457 rc = gnutls_openpgp_get_key( ret, &cred->keyring, KEY_ATTR_FPR, key_fpr );
1458 if ( rc >= 0 )
1459 goto leave;
1461 keyid = buffer_to_u32( key_fpr + (key_fpr_size-4) );
1462 rc = gnutls_openpgp_recv_key( cred->pgp_key_server,
1463 cred->pgp_key_server_port,
1464 keyid, ret );
1466 leave:
1467 return rc;
1471 * gnutls_certificate_set_openpgp_keyserver - Used to set an OpenPGP key server
1472 * @res: the destination context to save the data.
1473 * @server: is the key server address
1474 * @port: is the key server port to connect to
1476 * This funtion will set a key server for use with openpgp keys. This
1477 * key server will only be used if the peer sends a key fingerprint instead
1478 * of a key in the handshake. Using a key server may delay the handshake
1479 * process.
1483 gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res,
1484 char* keyserver,
1485 int port)
1487 if ( !res || !keyserver )
1488 return GNUTLS_E_ILLEGAL_PARAMETER;
1490 if (!port)
1491 port = 11371;
1493 res->pgp_key_server = gnutls_strdup( keyserver );
1494 if ( res->pgp_key_server == NULL)
1495 return GNUTLS_E_MEMORY_ERROR;
1497 res->pgp_key_server_port = port;
1499 return 0;
1503 gnutls_certificate_set_openpgp_trustdb( GNUTLS_CERTIFICATE_CREDENTIALS res,
1504 char* trustdb )
1506 if ( !res || !trustdb )
1507 return GNUTLS_E_ILLEGAL_PARAMETER;
1509 if ( cdk_trustdb_check( trustdb, 3 ) ) {
1510 /* The trustdb version is less then 3 and this mean the old
1511 format is still used. We don't support this format. */
1512 return GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED;
1514 res->pgp_trustdb = gnutls_strdup( trustdb );
1515 if ( res->pgp_trustdb==NULL )
1516 return GNUTLS_E_MEMORY_ERROR;
1518 return 0;
1521 #else /*!HAVE_LIBOPENCDK*/
1524 _gnutls_openpgp_key2gnutls_key(gnutls_private_key *pkey,
1525 gnutls_datum raw_key)
1527 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1531 _gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw)
1533 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1537 gnutls_certificate_set_openpgp_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res,
1538 gnutls_datum *cert,
1539 gnutls_datum *key)
1541 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1545 gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res,
1546 char* CERTFILE,
1547 char* KEYFILE)
1549 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1553 gnutls_openpgp_extract_key_name( const gnutls_datum *cert, int idx,
1554 gnutls_openpgp_name *dn )
1556 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1560 gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, int *r_bits)
1562 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1566 gnutls_openpgp_extract_key_version( const gnutls_datum *cert )
1568 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1571 time_t
1572 gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert )
1574 return (time_t)-1;
1577 time_t
1578 gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert )
1580 return (time_t)-1;
1584 gnutls_openpgp_verify_key(const char* ign, const gnutls_datum* keyring,
1585 const gnutls_datum* cert_list,
1586 int cert_list_length)
1588 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1592 gnutls_openpgp_fingerprint(const gnutls_datum *cert, char *fpr, size_t *fprlen)
1594 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1598 gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name)
1600 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1604 gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring,
1605 const char *data, size_t len)
1607 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1611 gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c,
1612 const char *file)
1614 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1618 gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c,
1619 const char *file)
1621 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1625 _gnutls_openpgp_request_key( gnutls_datum* ret,
1626 const GNUTLS_CERTIFICATE_CREDENTIALS cred,
1627 opaque* key_fpr,
1628 int key_fpr_size)
1630 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1634 gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res,
1635 char* keyserver,
1636 int port)
1638 return;
1642 gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res,
1643 char* trustdb)
1645 return;
1648 #endif /* HAVE_LIBOPENCDK */