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
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
43 #define OPENPGP_NAME_SIZE GNUTLS_X509_CN_SIZE
58 release_mpi_array( GNUTLS_MPI
*arr
, size_t n
)
62 while ( arr
&& n
-- ) {
64 _gnutls_mpi_release( &x
);
70 buffer_to_u32( const uint8
*buffer
)
72 const uint8
*p
= buffer
;
76 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
80 file_exist(const char *file
)
87 fp
= fopen(file
, "r");
97 kbx_blob_new( keybox_blob
**r_ctx
)
102 return GNUTLS_E_INVALID_PARAMETERS
;
104 c
= cdk_alloc_clear( sizeof * c
);
106 return GNUTLS_E_MEMORY_ERROR
;
113 kbx_blob_release( keybox_blob
*ctx
)
116 cdk_free( ctx
->data
);
119 } /* kbx_blob_release */
122 kbx_to_keydb( keybox_blob
*blob
)
129 khd
= cdk_alloc_clear( sizeof *khd
);
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
;
150 /* Extract a keybox blob from the given position. */
152 kbx_read_blob( const gnutls_datum
* keyring
, size_t pos
)
154 keybox_blob
*blob
= NULL
;
156 if ( !keyring
|| !keyring
->data
)
159 if ( pos
> keyring
->size
)
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
);
169 blob
->armored
= keyring
->data
[pos
+1];
170 blob
->size
= buffer_to_u32( keyring
->data
+pos
+2 );
172 kbx_blob_release( blob
);
175 blob
->data
= cdk_alloc_clear( blob
->size
+ 1 );
178 memcpy( blob
->data
, keyring
->data
+(pos
+6), blob
->size
);
179 blob
->data
[blob
->size
] = '\0';
182 } /* kbx_read_blob */
184 /* Creates a keyring blob from raw data
189 * 4 octet size of blob
193 kbx_data_to_keyring( int type
, int enc
, const char *data
,
194 size_t size
, size_t *r_size
)
201 p
= gnutls_malloc( 1+4+size
);
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
);
215 } /* kbx_data_to_keyring */
218 kbnode_to_datum( CDK_KBNODE kb_pk
, gnutls_datum
*raw
)
221 CDK_BSTRING dat
= NULL
;
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
);
237 rc
= GNUTLS_E_UNKNOWN_ERROR
;
240 dat
= cdk_iobuf_read_mem( a
, 0 );
242 rc
= gnutls_set_datum( raw
, dat
->d
, dat
->len
);
245 rc
= GNUTLS_E_MEMORY_ERROR
;
254 cdk_iobuf_close( a
);
259 datum_to_kbnode( const gnutls_datum
*raw
, CDK_KBNODE
*r_pkt
)
262 CDK_KBNODE pkt
= NULL
;
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
;
280 cdk_iobuf_close( buf
);
281 *r_pkt
= (!rc
)? pkt
: NULL
;
287 iobuf_to_datum( CDK_IOBUF buf
, gnutls_datum
*raw
)
289 CDK_BSTRING a
= NULL
;
293 return GNUTLS_E_INVALID_PARAMETERS
;
295 a
= cdk_iobuf_read_mem( buf
, 0 );
297 rc
= gnutls_set_datum( raw
, a
->d
, a
->len
);
299 rc
= GNUTLS_E_MEMORY_ERROR
;
304 rc
= GNUTLS_E_UNKNOWN_ERROR
;
312 openpgp_pk_to_gnutls_cert(gnutls_cert
*cert
, PKT_public_key
*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
);
345 rc
= GNUTLS_E_MPI_SCAN_FAILED
;
349 cert
->expiration_time
= pk
->expiredate
;
350 cert
->activation_time
= pk
->timestamp
;
354 release_mpi_array(cert
->params
, i
-1);
360 openpgp_sig_to_gnutls_cert(gnutls_cert
*cert
, PKT_signature
*sig
)
362 CDK_IOBUF buf
= NULL
;
363 CDK_BSTRING a
= NULL
;
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
);
379 a
= cdk_iobuf_read_mem( buf
, 0 );
381 rc
= gnutls_datum_append( &cert
->signature
, a
->d
, a
->len
);
384 rc
= GNUTLS_E_MEMORY_ERROR
;
389 rc
= GNUTLS_E_UNKNOWN_ERROR
;
393 cdk_iobuf_close( buf
);
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
;
412 PKT_secret_key
*sk
= NULL
;
413 int pke_algo
, i
, j
, eof
= 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
;
429 p
= cdk_kbnode_find( kb_sk
, PKT_SECRET_KEY
);
431 rc
= GNUTLS_E_UNKNOWN_ERROR
;
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
);
442 rc
= GNUTLS_E_MPI_SCAN_FAILED
;
443 release_mpi_array( pkey
->params
, i
-1 );
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
);
453 rc
= GNUTLS_E_MPI_SCAN_FAILED
;
454 release_mpi_array(pkey
->params
, i
-1);
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
);
466 release_mpi_array(pkey
->params
, i
);
467 rc
= GNUTLS_E_MEMORY_ERROR
;
471 cdk_iobuf_close( buf
);
472 cdk_kbnode_release( kb_sk
);
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
;
493 return GNUTLS_E_INVALID_PARAMETERS
;
495 memset( cert
, 0, sizeof *cert
);
496 rc
= datum_to_kbnode( &raw
, &kb_pk
);
499 p
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
501 rc
= GNUTLS_E_UNKNOWN_ERROR
;
504 pk
= p
->pkt
->pkt
.public_key
;
505 rc
= gnutls_set_datum( &cert
->raw
, raw
.data
, raw
.size
);
507 rc
= GNUTLS_E_MEMORY_ERROR
;
510 rc
= openpgp_pk_to_gnutls_cert( cert
, pk
);
513 cdk_kbnode_release( kb_pk
);
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
;
534 CDK_KBNODE pk
= NULL
;
538 if ( !key
|| !keyring
|| by
== KEY_ATTR_NONE
)
539 return GNUTLS_E_INVALID_PARAMETERS
;
541 blob
= kbx_read_blob( keyring
, 0 );
543 return GNUTLS_E_MEMORY_ERROR
;
544 khd
= kbx_to_keydb( blob
);
547 case KEY_ATTR_SHORT_KEYID
:
548 ks
.u
.keyid
[1] = buffer_to_u32(pattern
);
552 ks
.u
.keyid
[0] = buffer_to_u32(pattern
);
553 ks
.u
.keyid
[1] = buffer_to_u32(pattern
+4);
557 memcpy(ks
.u
.fpr
, pattern
, 20);
564 rc
= cdk_keydb_search( khd
, &ks
, &pk
);
566 rc
= GNUTLS_E_UNKNOWN_ERROR
;
570 if ( !cdk_kbnode_find( pk
, PKT_PUBLIC_KEY
) ) {
571 rc
= GNUTLS_E_UNKNOWN_ERROR
;
575 rc
= kbnode_to_datum( pk
, key
);
579 cdk_kbnode_release( pk
);
580 kbx_blob_release( blob
);
586 gnutls_certificate_set_openpgp_key_mem( GNUTLS_CERTIFICATE_CREDENTIALS res
,
591 CDK_KBNODE kb_pk
= NULL
, pkt
;
595 if ( !res
|| !key
|| !cert
)
596 return GNUTLS_E_INVALID_PARAMETERS
;
598 rc
= datum_to_kbnode( cert
, &kb_pk
);
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
) {
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
) {
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
) {
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
)
626 if (pkt
->pkt
->pkttype
== PKT_PUBLIC_KEY
) {
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
);
635 else if (pkt
->pkt
->pkttype
== PKT_SIGNATURE
) {
637 PKT_signature
*sig
= pkt
->pkt
->pkt
.signature
;
638 openpgp_sig_to_gnutls_cert( &res
->cert_list
[n
][0], sig
);
643 res
->pkey
= gnutls_realloc(res
->pkey
,
644 (res
->ncerts
)*sizeof(gnutls_private_key
));
645 if (res
->pkey
== NULL
) {
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
);
655 cdk_kbnode_release( kb_pk
);
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
,
675 CDK_IOBUF inp
= NULL
;
676 CDK_KBNODE kb_pk
= NULL
, pkt
;
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
);
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
);
695 cdk_iobuf_close( inp
);
696 rc
= GNUTLS_E_ASCII_ARMOR_ERROR
;
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
) {
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
) {
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
) {
719 return GNUTLS_E_MEMORY_ERROR
;
723 rc
= cdk_keydb_get_keyblock( inp
, &kb_pk
, &eof
);
726 for (i
=1, pkt
=kb_pk
; pkt
&& pkt
->pkt
->pkttype
; pkt
=pkt
->next
) {
727 if (i
> MAX_PARAMS_SIZE
)
729 if (pkt
->pkt
->pkttype
== PKT_PUBLIC_KEY
) {
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
);
737 else if (pkt
->pkt
->pkttype
== PKT_SIGNATURE
) {
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
);
747 cdk_kbnode_release( kb_pk
);
748 rc
= GNUTLS_E_UNKNOWN_ERROR
;
751 cdk_kbnode_release( kb_pk
);
753 rc
= cdk_iobuf_open( &inp
, KEYFILE
, IOBUF_MODE_RD
);
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
);
760 cdk_iobuf_close( inp
);
761 rc
= GNUTLS_E_ASCII_ARMOR_ERROR
;
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
) {
774 return GNUTLS_E_MEMORY_ERROR
;
779 /* ncerts has been incremented before */
780 rc
=_gnutls_openpgp_key2gnutls_key( &res
->pkey
[res
->ncerts
-1], raw
);
788 gnutls_openpgp_count_key_names( const gnutls_datum
*cert
)
790 CDK_KBNODE kb_pk
= NULL
, pkt
;
796 if ( datum_to_kbnode( cert
, &kb_pk
) )
798 for ( pkt
=kb_pk
; pkt
; pkt
=pkt
->next
) {
799 if ( pkt
->pkt
->pkttype
== PKT_USER_ID
)
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
,
816 gnutls_openpgp_name
*dn
)
818 CDK_KBNODE kb_pk
= NULL
, pkt
;
819 PKT_user_id
*uid
= NULL
;
821 int pos
= 0, pos1
= 0, pos2
= 0;
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
);
836 pkt
= cdk_kbnode_find( kb_pk
, PKT_USER_ID
);
838 for ( pos
=0, pkt
=kb_pk
; pkt
; pkt
=pkt
->next
) {
839 if ( pkt
->pkt
->pkttype
== PKT_USER_ID
&& ++pos
== idx
)
844 uid
= pkt
->pkt
->pkt
.user_id
;
846 rc
= GNUTLS_E_UNKNOWN_ERROR
;
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
, '<');
857 pos1
= email
-uid
->name
+1;
858 email
= strchr(uid
->name
, '>');
860 pos2
= email
-uid
->name
+1;
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
;
873 cdk_kbnode_release( kb_pk
);
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
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
;
902 return GNUTLS_E_INVALID_PARAMETERS
;
904 if ( datum_to_kbnode( cert
, &kb_pk
) )
906 pkt
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
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
;
915 algo
= GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
916 cdk_kbnode_release( kb_pk
);
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
;
935 return GNUTLS_E_INVALID_PARAMETERS
;
937 if ( datum_to_kbnode( cert
, &kb_pk
) )
939 pkt
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
941 version
= pkt
->pkt
->pkt
.public_key
->version
;
942 cdk_kbnode_release( kb_pk
);
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.
954 gnutls_openpgp_extract_key_creation_time( const gnutls_datum
*cert
)
956 CDK_KBNODE kb_pk
= NULL
, pkt
;
957 time_t timestamp
= 0;
960 return GNUTLS_E_INVALID_PARAMETERS
;
962 if ( datum_to_kbnode( cert
, &kb_pk
) )
964 pkt
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
966 timestamp
= pkt
->pkt
->pkt
.public_key
->timestamp
;
967 cdk_kbnode_release( kb_pk
);
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.
980 gnutls_openpgp_extract_key_expiration_time( const gnutls_datum
*cert
)
982 CDK_KBNODE kb_pk
= NULL
, pkt
;
983 time_t expiredate
= 0;
986 return GNUTLS_E_INVALID_PARAMETERS
;
988 if ( datum_to_kbnode( cert
, &kb_pk
) )
990 pkt
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
992 expiredate
= pkt
->pkt
->pkt
.public_key
->expiredate
;
993 cdk_kbnode_release( kb_pk
);
999 _gnutls_openpgp_get_key_trust(const char *trustdb
,
1000 const gnutls_datum
*key
,
1003 CDK_KBNODE kb_pk
= NULL
, pkt
;
1005 PKT_public_key
*pk
= NULL
;
1006 int flags
= 0, ot
= 0, trustval
= 0;
1009 if ( !trustdb
|| !key
|| !r_success
)
1010 return GNUTLS_E_INVALID_REQUEST
;
1013 rc
= datum_to_kbnode( key
, &kb_pk
);
1015 return GNUTLS_E_UNKNOWN_ERROR
;
1017 pkt
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
1019 pk
= pkt
->pkt
->pkt
.public_key
;
1021 return GNUTLS_E_UNKNOWN_ERROR
;
1023 rc
= cdk_iobuf_open( &buf
, trustdb
, IOBUF_MODE_RD
);
1025 trustval
= GNUTLS_E_FILE_ERROR
;
1028 rc
= cdk_trustdb_get_ownertrust( buf
, pk
, &ot
, &flags
);
1029 cdk_iobuf_close( buf
);
1030 if ( rc
) { /* no ownertrust record was found */
1036 if (flags
& TRUST_FLAG_DISABLED
) {
1037 trustval
|= GNUTLS_CERT_NOT_TRUSTED
;
1038 trustval
|= GNUTLS_CERT_INVALID
;
1041 if (flags
& TRUST_FLAG_REVOKED
) {
1042 trustval
|= GNUTLS_CERT_NOT_TRUSTED
;
1043 trustval
|= GNUTLS_CERT_REVOKED
;
1047 trustval
|= GNUTLS_CERT_NOT_TRUSTED
;
1051 case TRUST_UNDEFINED
:
1052 case TRUST_MARGINAL
:
1055 case TRUST_ULTIMATE
:
1056 trustval
|= 1; /* means okay */
1062 cdk_kbnode_release( kb_pk
);
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
;
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);
1095 return GNUTLS_CERT_INVALID
|GNUTLS_CERT_NOT_TRUSTED
;
1096 khd
= kbx_to_keydb(blob
);
1098 rc
= GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
;
1104 rc
= _gnutls_openpgp_get_key_trust(trustdb
, cert_list
, &success
);
1109 rc
= datum_to_kbnode( cert_list
, &kb_pk
);
1112 return GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
;
1115 rc
= cdk_key_check_sigs( kb_pk
, khd
, &status
);
1116 if (rc
== CDKERR_NOKEY
)
1120 case CDK_KEY_INVALID
:
1121 rc
= GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
;
1124 case CDK_KEY_REVOKED
:
1125 rc
= GNUTLS_CERT_REVOKED
| GNUTLS_CERT_NOT_TRUSTED
;
1131 kbx_blob_release( blob
);
1133 cdk_kbnode_release( kb_pk
);
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
;
1154 if (!cert
|| !fpr
|| !fprlen
)
1155 return GNUTLS_E_UNKNOWN_ERROR
;
1158 rc
= datum_to_kbnode( cert
, &kb_pk
);
1161 pkt
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
1163 pk
= pkt
->pkt
->pkt
.public_key
;
1165 return GNUTLS_E_UNKNOWN_ERROR
;
1168 if ( is_RSA(pk
->pubkey_algo
) && pk
->version
< 4 )
1170 cdk_pk_get_fingerprint( pk
, fpr
);
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
;
1189 if (!cert
|| !keyid
)
1190 return GNUTLS_E_UNKNOWN_ERROR
;
1192 rc
= datum_to_kbnode( cert
, &kb_pk
);
1196 pkt
= cdk_kbnode_find( kb_pk
, PKT_PUBLIC_KEY
);
1198 pk
= pkt
->pkt
->pkt
.public_key
;
1200 return GNUTLS_E_UNKNOWN_ERROR
;
1201 cdk_pk_get_keyid( pk
, (u32
*)keyid
);
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
;
1224 if (!keyring
|| !name
)
1225 return GNUTLS_E_INVALID_PARAMETERS
;
1227 rc
= cdk_iobuf_open( &inp
, name
, IOBUF_MODE_RD
);
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 ) {
1238 return GNUTLS_E_MEMORY_ERROR
;
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
)
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 ) {
1269 return GNUTLS_E_MEMORY_ERROR
;
1278 gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c
,
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
,
1294 CDK_IOBUF inp
= NULL
;
1295 CDK_BSTRING a
= NULL
;
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
);
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
);
1312 cdk_iobuf_close( inp
);
1313 return GNUTLS_E_ASCII_ARMOR_ERROR
;
1317 a
= cdk_iobuf_read_mem( inp
, 0 );
1319 rc
= gnutls_openpgp_add_keyring_mem( &c
->keyring
, a
->d
, a
->len
);
1323 rc
= GNUTLS_E_UNKNOWN_ERROR
;
1324 cdk_iobuf_close( inp
);
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
,
1342 CDK_IOBUF buf
= NULL
;
1343 CDK_BSTRING a
= NULL
;
1345 struct sockaddr_in sock
;
1347 char *request
= NULL
;
1350 int rc
= 0, state
= 0;
1351 ssize_t nbytes
= 0, n
= 0;
1353 if ( !host
|| !key
)
1354 return GNUTLS_E_INVALID_PARAMETERS
;
1357 port
= 11371; /* standard service port */
1359 hp
= gethostbyname( host
);
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);
1371 setsockopt( fd
, SOL_SOCKET
, SO_REUSEADDR
, (char *)1, 1 );
1372 if ( connect( fd
, (struct sockaddr
*)&sock
, sizeof(sock
) ) == -1 ) {
1377 n
= strlen(host
)+100;
1378 request
= cdk_alloc_clear( n
+ 1 );
1379 if ( request
== NULL
) {
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
);
1392 cdk_free( request
);
1394 buf
= cdk_iobuf_temp();
1395 while ( (n
= read(fd
, buffer
, sizeof(buffer
)-1)) > 0 )
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>") )
1407 rc
= GNUTLS_E_UNKNOWN_ERROR
;
1410 memset( &afx
, 0, sizeof afx
);
1411 rc
= cdk_armor_filter( &afx
, IOBUF_CTRL_UNDERFLOW
, buf
);
1413 rc
= GNUTLS_E_ASCII_ARMOR_ERROR
;
1416 a
= cdk_iobuf_read_mem(buf
, 0 );
1418 rc
= gnutls_set_datum( key
, a
->d
, a
->len
);
1420 rc
= GNUTLS_E_MEMORY_ERROR
;
1425 cdk_iobuf_close(buf
);
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
,
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
);
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
,
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
1483 gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res
,
1487 if ( !res
|| !keyserver
)
1488 return GNUTLS_E_ILLEGAL_PARAMETER
;
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
;
1503 gnutls_certificate_set_openpgp_trustdb( GNUTLS_CERTIFICATE_CREDENTIALS res
,
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
;
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
,
1541 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
1545 gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res
,
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
;
1572 gnutls_openpgp_extract_key_creation_time( const gnutls_datum
*cert
)
1578 gnutls_openpgp_extract_key_expiration_time( const gnutls_datum
*cert
)
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
,
1614 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
1618 gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c
,
1621 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
1625 _gnutls_openpgp_request_key( gnutls_datum
* ret
,
1626 const GNUTLS_CERTIFICATE_CREDENTIALS cred
,
1630 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
1634 gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res
,
1642 gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res
,
1648 #endif /* HAVE_LIBOPENCDK */