*** empty log message ***
[gnutls.git] / libextra / gnutls_openpgp.c
blob8deec145cc5542ab70aac0a1422591e1b608a388
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.
1074 * When the trustdb parameter is used, the function checks the
1075 * ownertrust of the key before the signatures are checked. It
1076 * is possible that the key was disabled or the owner is not trusted
1077 * at all. Then we don't check the signatures because it makes no sense.
1079 * The return value is one of the CertificateStatus entries.
1082 gnutls_openpgp_verify_key( const char *trustdb,
1083 const gnutls_datum* keyring,
1084 const gnutls_datum* cert_list,
1085 int cert_list_length )
1087 CDK_KBNODE kb_pk = NULL;
1088 KEYDB_HD khd = NULL;
1089 keybox_blob *blob = NULL;
1090 int rc = 0;
1091 int status = 0;
1093 if (!cert_list || cert_list_length != 1 || !keyring)
1094 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1096 if ( !keyring->size && !trustdb)
1097 return GNUTLS_E_INVALID_REQUEST;
1099 blob = kbx_read_blob(keyring, 0);
1100 if (!blob)
1101 return GNUTLS_CERT_INVALID|GNUTLS_CERT_NOT_TRUSTED;
1102 khd = kbx_to_keydb(blob);
1103 if (!khd) {
1104 rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED;
1105 goto leave;
1108 if ( trustdb ) {
1109 int success = 0;
1110 rc = _gnutls_openpgp_get_key_trust(trustdb, cert_list, &success);
1111 if (!success)
1112 goto leave;
1115 rc = datum_to_kbnode( cert_list, &kb_pk );
1116 if ( rc ) {
1117 goto leave;
1118 return GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED;
1121 rc = cdk_key_check_sigs( kb_pk, khd, &status );
1122 if (rc == CDKERR_NOKEY)
1123 rc = 0; /* fixme */
1125 switch (status) {
1126 case CDK_KEY_INVALID:
1127 rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED;
1128 break;
1130 case CDK_KEY_REVOKED:
1131 rc = GNUTLS_CERT_REVOKED | GNUTLS_CERT_NOT_TRUSTED;
1132 break;
1136 leave:
1137 kbx_blob_release( blob );
1138 cdk_free( khd );
1139 cdk_kbnode_release( kb_pk );
1141 return rc;
1145 * gnutls_openpgp_fingerprint - Gets the fingerprint
1146 * @cert: the raw data that contains the OpenPGP public key.
1147 * @fpr: the buffer to save the fingerprint.
1148 * @fprlen: the integer to save the length of the fingerprint.
1150 * Returns the fingerprint of the OpenPGP key. Depence on the algorithm,
1151 * the fingerprint can be 16 or 20 bytes.
1154 gnutls_openpgp_fingerprint(const gnutls_datum *cert, char *fpr, size_t *fprlen)
1156 CDK_KBNODE kb_pk = NULL, pkt;
1157 PKT_public_key *pk = NULL;
1158 int rc = 0;
1160 if (!cert || !fpr || !fprlen)
1161 return GNUTLS_E_UNKNOWN_ERROR;
1163 *fprlen = 0;
1164 rc = datum_to_kbnode( cert, &kb_pk );
1165 if (rc)
1166 return rc;
1167 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
1168 if ( pkt )
1169 pk = pkt->pkt->pkt.public_key;
1170 if ( !pk )
1171 return GNUTLS_E_UNKNOWN_ERROR;
1173 *fprlen = 20;
1174 if ( is_RSA(pk->pubkey_algo) && pk->version < 4 )
1175 *fprlen = 16;
1176 cdk_pk_get_fingerprint( pk, fpr );
1178 return 0;
1182 * gnutls_openpgp_keyid - Gets the keyID
1183 * @cert: the raw data that contains the OpenPGP public key.
1184 * @keyid: the buffer to save the keyid.
1186 * Returns the 64-bit keyID of the OpenPGP key.
1189 gnutls_openpgp_keyid( const gnutls_datum *cert, opaque keyid[8] )
1191 CDK_KBNODE kb_pk = NULL, pkt;
1192 PKT_public_key *pk = NULL;
1193 u32 kid[2];
1194 int rc = 0;
1196 if (!cert || !keyid)
1197 return GNUTLS_E_UNKNOWN_ERROR;
1199 rc = datum_to_kbnode( cert, &kb_pk );
1200 if ( rc )
1201 return rc;
1203 pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY );
1204 if ( pkt )
1205 pk = pkt->pkt->pkt.public_key;
1206 if ( !pk )
1207 return GNUTLS_E_UNKNOWN_ERROR;
1208 cdk_pk_get_keyid( pk, kid );
1209 keyid[0] = kid[0] >> 24; keyid[1] = kid[0] >> 16;
1210 keyid[2] = kid[0] >> 8; keyid[3] = kid[0];
1211 keyid[4] = kid[1] >> 24; keyid[5] = kid[1] >> 16;
1212 keyid[6] = kid[1] >> 8; keyid[7] = kid[1];
1214 return 0;
1218 * gnutls_openpgp_add_keyring_file - Adds a keyring file for OpenPGP
1219 * @keyring: data buffer to store the file.
1220 * @name: filename of the keyring.
1222 * The function is used to set keyrings that will be used internally
1223 * by various OpenCDK functions. For example to find a key when it
1224 * is needed for an operations.
1227 gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name)
1229 CDK_IOBUF inp = NULL;
1230 uint8 *blob;
1231 size_t nbytes;
1232 int enc = 0;
1233 int rc = 0;
1235 if (!keyring || !name)
1236 return GNUTLS_E_INVALID_PARAMETERS;
1238 rc = cdk_iobuf_open( &inp, name, IOBUF_MODE_RD );
1239 if ( rc )
1240 return GNUTLS_E_FILE_ERROR;
1241 enc = cdk_armor_filter_use( inp );
1242 cdk_iobuf_close( inp );
1244 blob = kbx_data_to_keyring( KBX_BLOB_FILE, enc, name,
1245 strlen(name), &nbytes);
1246 if ( blob && nbytes ) {
1247 if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) {
1248 gnutls_assert();
1249 return GNUTLS_E_MEMORY_ERROR;
1251 gnutls_free(blob);
1254 return 0;
1258 * gnutls_openpgp_add_keyring_mem - Adds keyring data for OpenPGP
1259 * @keyring: data buffer to store the file.
1260 * @data: the binary data of the keyring.
1261 * @len: the size of the binary buffer.
1263 * Same as gnutls_openpgp_add_keyring_mem but now we store the
1264 * data instead of the filename.
1267 gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring,
1268 const opaque *data, size_t len)
1270 uint8 *blob;
1271 size_t nbytes = 0;
1273 if (!keyring || !data || !len)
1274 return GNUTLS_E_INVALID_PARAMETERS;
1276 blob = kbx_data_to_keyring( KBX_BLOB_DATA, 0, data, len, &nbytes );
1277 if ( blob && nbytes ) {
1278 if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) {
1279 gnutls_assert();
1280 return GNUTLS_E_MEMORY_ERROR;
1282 gnutls_free(blob);
1285 return 0;
1289 * gnutls_certificate_set_openpgp_keyring_file - Adds a keyring file for OpenPGP * @c: A certificate credentials structure
1290 * @file: filename of the keyring.
1292 * The function is used to set keyrings that will be used internally
1293 * by various OpenPGP functions. For example to find a key when it
1294 * is needed for an operations. The keyring will also be used at the
1295 * verification functions.
1299 gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c,
1300 const char *file)
1302 if (!c || !file)
1303 return GNUTLS_E_INVALID_PARAMETERS;
1305 if ( !file_exist(file) )
1306 return GNUTLS_E_FILE_ERROR;
1308 return gnutls_openpgp_add_keyring_file(&c->keyring, file);
1312 gnutls_certificate_set_openpgp_keyring_mem( GNUTLS_CERTIFICATE_CREDENTIALS c,
1313 const opaque *data, size_t dlen )
1315 CDK_IOBUF out = NULL;
1316 CDK_BSTRING a = NULL;
1317 armor_filter_s afx;
1318 int rc = 0;
1320 if ( !c || !data || !dlen )
1321 return GNUTLS_E_INVALID_PARAMETERS;
1323 rc = cdk_iobuf_create( &out, NULL );
1324 if ( rc )
1325 return GNUTLS_E_FILE_ERROR;
1326 rc = cdk_iobuf_write( out, data, dlen );
1327 if ( rc ) {
1328 cdk_iobuf_close( out );
1329 return GNUTLS_E_FILE_ERROR;
1331 /* Maybe it's a little confusing that we check the output..
1332 but it's possible, that the data we want to add, is armored
1333 and we only want to store plaintext keyring data. */
1334 if ( cdk_armor_filter_use( out ) ) {
1335 memset( &afx, 0, sizeof afx );
1336 rc = cdk_armor_filter( &afx, IOBUF_CTRL_UNDERFLOW, out );
1337 if ( rc ) {
1338 cdk_iobuf_close( out );
1339 return GNUTLS_E_ASCII_ARMOR_ERROR;
1343 a = cdk_iobuf_read_mem( out, 0 );
1344 if ( a ) {
1345 rc = gnutls_openpgp_add_keyring_mem( &c->keyring, a->d, a->len );
1346 cdk_free( a );
1348 else
1349 rc = GNUTLS_E_UNKNOWN_ERROR;
1350 cdk_iobuf_close( out );
1352 return rc;
1356 * gnutls_openpgp_recv_key - Receives a key from a HKP keyserver.
1357 * @host - the hostname of the keyserver.
1358 * @port - the service port (if not set use 11371).
1359 * @keyid - The 32-bit keyID (rightmost bits keyid[1])
1360 * @key - Context to store the raw (dearmored) key.
1362 * Try to connect to a public keyserver to get the specified key.
1365 gnutls_openpgp_recv_key(const char *host, short port, uint32 keyid,
1366 gnutls_datum *key)
1368 CDK_IOBUF buf = NULL;
1369 CDK_BSTRING a = NULL;
1370 struct hostent *hp;
1371 struct sockaddr_in sock;
1372 armor_filter_s afx;
1373 char *request = NULL;
1374 char buffer[4096];
1375 int fd = -1;
1376 int rc = 0, state = 0;
1377 ssize_t nbytes = 0, n = 0;
1379 if ( !host || !key )
1380 return GNUTLS_E_INVALID_PARAMETERS;
1382 if ( !port )
1383 port = 11371; /* standard service port */
1385 hp = gethostbyname( host );
1386 if ( hp == NULL )
1387 return -1;
1389 memset( &sock, 0, sizeof sock );
1390 memcpy( &sock.sin_addr, hp->h_addr, hp->h_length );
1391 sock.sin_family = hp->h_addrtype;
1392 sock.sin_port = htons( port );
1394 fd = socket(AF_INET, SOCK_STREAM, 0);
1395 if ( fd == -1 )
1396 return -1;
1397 setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (char *)1, 1 );
1398 if ( connect( fd, (struct sockaddr*)&sock, sizeof(sock) ) == -1 ) {
1399 close(fd);
1400 return -1;
1403 n = strlen(host)+100;
1404 request = cdk_alloc_clear( n + 1 );
1405 if ( request == NULL ) {
1406 close( fd );
1407 return -1;
1409 snprintf( request, n,
1410 "GET /pks/lookup?op=get&search=0x%08X HTTP/1.0\r\n"
1411 "Host: %s:%d\r\n", (u32)keyid, host, port );
1413 if ( write( fd, request, strlen(request) ) == -1 ) {
1414 cdk_free( request );
1415 close( fd );
1416 return -1;
1418 cdk_free( request );
1420 buf = cdk_iobuf_temp();
1421 while ( (n = read(fd, buffer, sizeof(buffer)-1)) > 0 )
1423 buffer[n] = '\0';
1424 nbytes += n;
1425 if ( nbytes > cdk_iobuf_get_length( buf ) )
1426 cdk_iobuf_expand(buf, n);
1427 cdk_iobuf_write(buf, buffer, n);
1428 if ( strstr(buffer, "<pre>") || strstr(buffer, "</pre>") )
1429 state++;
1432 if ( state != 2 ) {
1433 rc = GNUTLS_E_UNKNOWN_ERROR;
1434 goto leave;
1436 memset( &afx, 0, sizeof afx );
1437 rc = cdk_armor_filter( &afx, IOBUF_CTRL_UNDERFLOW, buf );
1438 if ( rc ) {
1439 rc = GNUTLS_E_ASCII_ARMOR_ERROR;
1440 goto leave;
1442 a = cdk_iobuf_read_mem(buf, 0 );
1443 if ( a ) {
1444 rc = gnutls_set_datum( key, a->d, a->len );
1445 if ( rc < 0 )
1446 rc = GNUTLS_E_MEMORY_ERROR;
1447 cdk_free( a );
1450 leave:
1451 cdk_iobuf_close(buf);
1452 close(fd);
1454 return 0;
1458 * _gnutls_openpgp_request_key - Receives a key from a database, key server etc
1459 * @ret - a pointer to gnutls_datum structure.
1460 * @cred - a GNUTLS_CERTIFICATE_CREDENTIALS structure.
1461 * @key_fingerprint - The keyFingerprint
1462 * @key_fingerprint_size - the size of the fingerprint
1464 * Retrieves a key from a local database, keyring, or a key server. The
1465 * return value is locally allocated.
1469 _gnutls_openpgp_request_key( gnutls_datum* ret,
1470 const GNUTLS_CERTIFICATE_CREDENTIALS cred,
1471 opaque* key_fpr,
1472 int key_fpr_size)
1474 uint32 keyid;
1475 int rc = 0;
1477 if (!ret || !cred || !key_fpr)
1478 return GNUTLS_E_INVALID_PARAMETERS;
1480 if ( key_fpr_size != 16 && key_fpr_size != 20 )
1481 return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */
1483 rc = gnutls_openpgp_get_key( ret, &cred->keyring, KEY_ATTR_FPR, key_fpr );
1484 if ( rc >= 0 )
1485 goto leave;
1487 keyid = buffer_to_u32( key_fpr + (key_fpr_size-4) );
1488 rc = gnutls_openpgp_recv_key( cred->pgp_key_server,
1489 cred->pgp_key_server_port,
1490 keyid, ret );
1492 leave:
1493 return rc;
1497 * gnutls_certificate_set_openpgp_keyserver - Used to set an OpenPGP key server
1498 * @res: the destination context to save the data.
1499 * @server: is the key server address
1500 * @port: is the key server port to connect to
1502 * This funtion will set a key server for use with openpgp keys. This
1503 * key server will only be used if the peer sends a key fingerprint instead
1504 * of a key in the handshake. Using a key server may delay the handshake
1505 * process.
1509 gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res,
1510 char* keyserver,
1511 int port)
1513 if ( !res || !keyserver )
1514 return GNUTLS_E_ILLEGAL_PARAMETER;
1516 if (!port)
1517 port = 11371;
1519 gnutls_free( res->pgp_key_server);
1520 res->pgp_key_server = gnutls_strdup( keyserver );
1521 if ( res->pgp_key_server == NULL)
1522 return GNUTLS_E_MEMORY_ERROR;
1524 res->pgp_key_server_port = port;
1526 return 0;
1529 static void
1530 xml_add_tag( gnutls_datum *xmlkey, const char *tag, const char *val )
1532 char *p = NULL;
1534 p = gnutls_calloc( 1, strlen( tag ) + 6 + 1 ); /* 6 chars + null */
1535 strcat( p, " <" );
1536 strcat( p, tag );
1537 strcat( p, ">" );
1538 gnutls_datum_append( xmlkey, p, strlen( p ) );
1539 gnutls_free( p ); p = NULL;
1541 gnutls_datum_append( xmlkey, val, strlen( val ) );
1543 p = gnutls_calloc( 1, strlen( tag ) + 4 + 1 );
1544 strcat( p, "</" );
1545 strcat( p, tag );
1546 strcat( p, ">\n" );
1547 gnutls_datum_append( xmlkey, p, strlen( p ) );
1548 gnutls_free( p ); p = NULL;
1551 static void
1552 xml_add_key( gnutls_datum *xmlkey, PKT_public_key *pk, int sub )
1554 const char *algo, *s;
1555 char keyid[16], fpr[41], tmp[32];
1556 byte fingerpr[20];
1557 u32 kid[2];
1558 int i = 0;
1560 s = sub? " <SUBKEY>\n" : " <MAINKEY>\n";
1561 gnutls_datum_append( xmlkey, s, strlen( s ) );
1563 cdk_pk_get_keyid( pk, kid );
1564 snprintf( keyid, 16, "%08X%08X", kid[0], kid[1] );
1565 xml_add_tag( xmlkey, "KEYID", keyid );
1567 cdk_pk_get_fingerprint( pk, fingerpr );
1568 for ( i = 0; i < 20; i++ )
1569 sprintf( fpr + 2 * i, "%02X", fingerpr[i] );
1570 fpr[40] = '\0';
1571 xml_add_tag( xmlkey, "FINGERPRINT", fpr );
1573 if ( is_DSA( pk->pubkey_algo ) ) algo = "DSA";
1574 else algo = "RSA";
1575 xml_add_tag( xmlkey, "PKALGO", algo );
1577 sprintf( tmp, "%d", cdk_pk_get_nbits( pk ) );
1578 xml_add_tag( xmlkey, "KEYLEN", tmp );
1580 sprintf( tmp, "%u", pk->timestamp );
1581 xml_add_tag( xmlkey, "CREATED", tmp );
1583 if ( pk->expiredate ) {
1584 sprintf( tmp, "%u", pk->expiredate );
1585 xml_add_tag( xmlkey, "EXPIREDATE", tmp );
1588 sprintf( tmp, "%d", pk->is_revoked );
1589 xml_add_tag( xmlkey, "REVOKED", tmp );
1591 s = sub? " </SUBKEY>\n" : " </MAINKEY>\n";
1592 gnutls_datum_append( xmlkey, s, strlen( s ) );
1595 static void
1596 xml_add_userid( gnutls_datum *xmlkey, gnutls_openpgp_name *dn,
1597 PKT_user_id *id )
1599 const char *s;
1600 char *p, *name, tmp[32];
1602 s = " <USERID>\n";
1603 gnutls_datum_append( xmlkey, s, strlen( s ) );
1605 p = strchr( dn->name, '<' );
1606 if ( p ) {
1607 int len = (p - dn->name - 1);
1608 name = gnutls_calloc( 1, len );
1609 memcpy( name, dn->name, len );
1610 xml_add_tag( xmlkey, "NAME", name );
1611 gnutls_free( name );
1613 else
1614 xml_add_tag( xmlkey, "NAME", dn->name );
1615 xml_add_tag( xmlkey, "EMAIL", dn->email );
1617 sprintf( tmp, "%d", id->is_primary );
1618 xml_add_tag( xmlkey, "PRIMARY", tmp );
1620 sprintf( tmp, "%d", id->is_revoked );
1621 xml_add_tag( xmlkey, "REVOKED", tmp );
1623 s = " </USERID>\n";
1624 gnutls_datum_append( xmlkey, s, strlen( s ) );
1627 static void
1628 xml_add_sig( gnutls_datum *xmlkey, PKT_signature *sig )
1630 const char *algo, *s;
1631 char tmp[32], keyid[16];
1632 u32 kid[2];
1634 s = " <SIGNATURE>\n";
1635 gnutls_datum_append( xmlkey, s, strlen( s ) );
1637 sprintf( tmp, "%d", sig->version );
1638 xml_add_tag( xmlkey, "VERSION", tmp );
1640 sprintf( tmp, "%d", sig->sig_class );
1641 xml_add_tag( xmlkey, "SIGCLASS", tmp );
1643 sprintf( tmp, "%d", sig->flags.expired );
1644 xml_add_tag( xmlkey, "EXPIRED", tmp );
1646 if ( is_DSA( sig->pubkey_algo ) ) algo = "DSA";
1647 else algo = "RSA";
1648 xml_add_tag( xmlkey, "PKALGO", algo );
1650 if ( sig->digest_algo == GCRY_MD_SHA1 ) algo = "SHA1";
1651 else algo = "MD5";
1652 xml_add_tag( xmlkey, "MDALGO", algo );
1654 sprintf( tmp, "%u", sig->timestamp );
1655 xml_add_tag( xmlkey, "CREATED", tmp );
1657 cdk_sig_get_keyid( sig, kid );
1658 snprintf( keyid, 16, "%08X%08X", kid[0], kid[1] );
1659 xml_add_tag( xmlkey, "KEYID", keyid );
1661 s = " </SIGNATURE>\n";
1662 gnutls_datum_append( xmlkey, s, strlen( s ) );
1666 * gnutls_certificate_openpgp_get_as_xml - Return a certificate as a XML fragment
1667 * @cert: the certificate which holds the whole OpenPGP key.
1668 * @ext: extension mode (1/0), 1 means include key signatures.
1669 * @xmlkey: he datum struct to store the XML result.
1671 * This function will return the all OpenPGP key information encapsulated as
1672 * a XML string.
1675 gnutls_certificate_openpgp_get_as_xml( const gnutls_datum *cert, int ext,
1676 gnutls_datum *xmlkey )
1678 CDK_KBNODE kb_pk, p;
1679 PACKET *pkt;
1680 gnutls_openpgp_name dn;
1681 const char *s;
1682 int idx = 0, rc = 0;
1684 if ( !cert || !xmlkey )
1685 return GNUTLS_E_INVALID_PARAMETERS;
1687 rc = datum_to_kbnode( cert, &kb_pk );
1688 if ( rc )
1689 return rc;
1691 memset( xmlkey, 0, sizeof *xmlkey );
1693 s = "<OPENPGPKEY>\n";
1694 gnutls_datum_append( xmlkey, s, strlen( s ) );
1696 for ( p = kb_pk; p; p = p->next ) {
1697 pkt = p->pkt;
1698 switch ( pkt->pkttype ) {
1699 case PKT_PUBLIC_KEY:
1700 xml_add_key( xmlkey, pkt->pkt.public_key, 0 );
1701 break;
1703 case PKT_PUBLIC_SUBKEY:
1704 xml_add_key( xmlkey, pkt->pkt.public_key, 1 );
1705 break;
1707 case PKT_USER_ID:
1708 gnutls_openpgp_extract_key_name( cert, idx, &dn );
1709 xml_add_userid( xmlkey, &dn, pkt->pkt.user_id ); idx++;
1710 break;
1712 case PKT_SIGNATURE:
1713 if ( ext )
1714 xml_add_sig( xmlkey, pkt->pkt.signature );
1715 break;
1718 s = "</OPENPGPKEY>\n";
1719 gnutls_datum_append( xmlkey, s, strlen( s ) );
1721 return rc;
1725 * gnutls_certificate_set_openpgp_trustdb - Used to set an GnuPG trustdb
1726 * @res: the destination context to save the data.
1727 * @trustdb: is the trustdb filename
1729 * This funtion will set a GnuPG trustdb which will be used in key
1730 * verification functions. Only version 3 trustdb files are supported.
1734 gnutls_certificate_set_openpgp_trustdb( GNUTLS_CERTIFICATE_CREDENTIALS res,
1735 char* trustdb )
1737 if ( !res || !trustdb )
1738 return GNUTLS_E_ILLEGAL_PARAMETER;
1740 if ( cdk_trustdb_check( trustdb, 3 ) ) {
1741 /* The trustdb version is less then 3 and this mean the old
1742 format is still used. We don't support this format. */
1743 return GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED;
1746 gnutls_free( res->pgp_trustdb);
1747 res->pgp_trustdb = gnutls_strdup( trustdb );
1748 if ( res->pgp_trustdb==NULL )
1749 return GNUTLS_E_MEMORY_ERROR;
1751 return 0;
1754 #else /*!HAVE_LIBOPENCDK*/
1757 _gnutls_openpgp_key2gnutls_key(gnutls_private_key *pkey,
1758 gnutls_datum raw_key)
1760 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1764 _gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw)
1766 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1770 gnutls_certificate_set_openpgp_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res,
1771 gnutls_datum *cert,
1772 gnutls_datum *key)
1774 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1778 gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res,
1779 char* CERTFILE,
1780 char* KEYFILE)
1782 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1786 gnutls_openpgp_extract_key_name( const gnutls_datum *cert, int idx,
1787 gnutls_openpgp_name *dn )
1789 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1793 gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, int *r_bits)
1795 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1799 gnutls_openpgp_extract_key_version( const gnutls_datum *cert )
1801 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1804 time_t
1805 gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert )
1807 return (time_t)-1;
1810 time_t
1811 gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert )
1813 return (time_t)-1;
1817 gnutls_openpgp_verify_key(const char* ign, const gnutls_datum* keyring,
1818 const gnutls_datum* cert_list,
1819 int cert_list_length)
1821 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1825 gnutls_openpgp_fingerprint(const gnutls_datum *cert, char *fpr, size_t *fprlen)
1827 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1831 gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name)
1833 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1837 gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring,
1838 const char *data, size_t len)
1840 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1844 gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c,
1845 const char *file)
1847 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1851 gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c,
1852 const char *file)
1854 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1858 _gnutls_openpgp_request_key( gnutls_datum* ret,
1859 const GNUTLS_CERTIFICATE_CREDENTIALS cred,
1860 opaque* key_fpr,
1861 int key_fpr_size)
1863 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1867 gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res,
1868 char* keyserver,
1869 int port)
1871 return;
1875 gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res,
1876 char* trustdb)
1878 return;
1881 #endif /* HAVE_LIBOPENCDK */