From fc7d25527f41028f15da216e2ffa087becaf7eff Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 30 Oct 2003 15:57:55 +0000 Subject: *** empty log message *** --- libextra/openpgp/compat.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++ libextra/openpgp/extras.c | 186 +++++++++++++++++++++++++++++++++++ libextra/openpgp/verify.c | 209 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 637 insertions(+) create mode 100644 libextra/openpgp/compat.c create mode 100644 libextra/openpgp/extras.c create mode 100644 libextra/openpgp/verify.c (limited to 'libextra') diff --git a/libextra/openpgp/compat.c b/libextra/openpgp/compat.c new file mode 100644 index 0000000000..9cc9f2d915 --- /dev/null +++ b/libextra/openpgp/compat.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2002 Timo Schulz + * Portions Copyright (C) 2003 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS-EXTRA. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* Compatibility functions on OpenPGP key parsing. + */ + +#include +#include +#include +#include + +#ifdef HAVE_LIBOPENCDK + +/*- + * gnutls_openpgp_verify_key - Verify all signatures on the key + * @cert_list: the structure that holds the certificates. + * @cert_list_lenght: the items in the cert_list. + * + * Verify all signatures in the certificate list. When the key + * is not available, the signature is skipped. + * + * When the trustdb parameter is used, the function checks the + * ownertrust of the key before the signatures are checked. It + * is possible that the key was disabled or the owner is not trusted + * at all. Then we don't check the signatures because it makes no sense. + * + * The return value is one of the CertificateStatus entries. + * + * NOTE: this function does not verify using any "web of trust". You + * may use GnuPG for that purpose, or any other external PGP application. + -*/ +int gnutls_openpgp_verify_key(const char *trustdb, + const gnutls_datum * keyring, + const gnutls_datum * cert_list, + int cert_list_length) +{ + int ret = 0; + gnutls_openpgp_key key = NULL; + gnutls_openpgp_keyring ring = NULL; + gnutls_openpgp_trustdb tdb = NULL; + unsigned int verify; + + if (!cert_list || cert_list_length != 1 || !keyring) { + gnutls_assert(); + return GNUTLS_E_NO_CERTIFICATE_FOUND; + } + + ret = gnutls_openpgp_key_init( &key); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_openpgp_key_import( key, &cert_list[0], 0); + if (ret < 0) { + gnutls_assert(); + goto leave; + } + + + + if (trustdb) { /* Use the trustDB */ + ret = gnutls_openpgp_trustdb_init( &tdb); + if (ret < 0) { + gnutls_assert(); + goto leave; + } + + ret = gnutls_openpgp_trustdb_import_file( tdb, trustdb); + if (ret < 0) { + gnutls_assert(); + goto leave; + } + + ret = gnutls_openpgp_key_verify_trustdb( key, tdb, 0, &verify); + if (ret < 0) { + gnutls_assert(); + goto leave; + } + + ret = verify; + goto leave; + } + + if (!keyring) { + ret = GNUTLS_CERT_NOT_TRUSTED | GNUTLS_CERT_INVALID; + goto leave; + } + + /* use the keyring + */ + ret = gnutls_openpgp_keyring_init( &ring); + if (ret < 0) { + gnutls_assert(); + goto leave; + } + + ret = gnutls_openpgp_keyring_import( ring, keyring, 0); + if (ret < 0) { + gnutls_assert(); + goto leave; + } + + ret = gnutls_openpgp_key_verify_ring( key, ring, 0, &verify); + if (ret < 0) { + gnutls_assert(); + goto leave; + } + + ret = verify; + goto leave; + +leave: + gnutls_openpgp_key_deinit( key); + gnutls_openpgp_trustdb_deinit( tdb); + gnutls_openpgp_keyring_deinit( ring); + return ret; + +} + +/*- + * gnutls_openpgp_fingerprint - Gets the fingerprint + * @cert: the raw data that contains the OpenPGP public key. + * @fpr: the buffer to save the fingerprint. + * @fprlen: the integer to save the length of the fingerprint. + * + * Returns the fingerprint of the OpenPGP key. Depence on the algorithm, + * the fingerprint can be 16 or 20 bytes. + -*/ +int gnutls_openpgp_fingerprint(const gnutls_datum * cert, + unsigned char *fpr, size_t * fprlen) +{ + gnutls_openpgp_key key; + int ret; + + ret = gnutls_openpgp_key_init( &key); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_openpgp_key_import( key, cert, 0); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_openpgp_key_get_fingerprint( key, fpr, fprlen); + + gnutls_openpgp_key_deinit( key); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + return 0; +} + +/*- + * gnutls_openpgp_extract_key_creation_time - Extract the timestamp + * @cert: the raw data that contains the OpenPGP public key. + * + * Returns the timestamp when the OpenPGP key was created. + -*/ +time_t gnutls_openpgp_extract_key_creation_time(const gnutls_datum * cert) +{ + gnutls_openpgp_key key; + int ret; + time_t tim; + + ret = gnutls_openpgp_key_init( &key); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_openpgp_key_import( key, cert, 0); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + tim = gnutls_openpgp_key_get_creation_time( key); + + gnutls_openpgp_key_deinit( key); + + return tim; +} + + +/*- + * gnutls_openpgp_extract_key_expiration_time - Extract the expire date + * @cert: the raw data that contains the OpenPGP public key. + * + * Returns the time when the OpenPGP key expires. A value of '0' means + * that the key doesn't expire at all. + -*/ +time_t gnutls_openpgp_extract_key_expiration_time(const gnutls_datum * cert) +{ + gnutls_openpgp_key key; + int ret; + time_t tim; + + ret = gnutls_openpgp_key_init( &key); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_openpgp_key_import( key, cert, 0); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + tim = gnutls_openpgp_key_get_expiration_time( key); + + gnutls_openpgp_key_deinit( key); + + return tim; +} + +#endif diff --git a/libextra/openpgp/extras.c b/libextra/openpgp/extras.c new file mode 100644 index 0000000000..42982b49c4 --- /dev/null +++ b/libextra/openpgp/extras.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2003 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS-EXTRA. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* Functions on OpenPGP keyring and trustdb parsing + */ + +#include + +#ifdef HAVE_LIBOPENCDK + +#include +#include +#include +#include +#include +#include + +/* Keyring stuff. + */ + +/** + * gnutls_openpgp_keyring_init - This function initializes a gnutls_openpgp_keyring structure + * @keyring: The structure to be initialized + * + * This function will initialize an OpenPGP keyring structure. + * + * Returns 0 on success. + * + **/ +int gnutls_openpgp_keyring_init(gnutls_openpgp_keyring * keyring) +{ + *keyring = gnutls_calloc( 1, sizeof(gnutls_openpgp_keyring_int)); + + if (*keyring) { + return 0; /* success */ + } + return GNUTLS_E_MEMORY_ERROR; +} + +/** + * gnutls_openpgp_keyring_deinit - This function deinitializes memory used by a gnutls_openpgp_keyring structure + * @keyring: The structure to be initialized + * + * This function will deinitialize a CRL structure. + * + **/ +void gnutls_openpgp_keyring_deinit(gnutls_openpgp_keyring keyring) +{ + if (!keyring) return; + + if (keyring->hd) { + cdk_free( keyring->hd); + keyring->hd = NULL; + } + + gnutls_free(keyring); +} + +/** + * gnutls_openpgp_keyring_import - This function will import a RAW or BASE64 encoded key + * @keyring: The structure to store the parsed key. + * @data: The RAW or BASE64 encoded keyring. + * @format: One of gnutls_openpgp_keyring_fmt elements. + * + * This function will convert the given RAW or Base64 encoded keyring + * to the native gnutls_openpgp_keyring format. The output will be stored in 'keyring'. + * + * Returns 0 on success. + * + **/ +int gnutls_openpgp_keyring_import(gnutls_openpgp_keyring keyring, + const gnutls_datum * data, + gnutls_openpgp_key_fmt format) +{ +int rc; +keybox_blob *blob = NULL; + + + blob = kbx_read_blob( data, 0); + if( !blob ) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + keyring->hd = kbx_to_keydb( blob); + if( !keyring->hd ) { + gnutls_assert(); + rc = GNUTLS_E_INTERNAL_ERROR; + goto leave; + } + + rc = 0; + + leave: + kbx_blob_release( blob ); + return rc; +} + + +/* TrustDB stuff. + */ + +/** + * gnutls_openpgp_trustdb_init - This function initializes a gnutls_openpgp_trustdb structure + * @trustdb: The structure to be initialized + * + * This function will initialize an OpenPGP trustdb structure. + * + * Returns 0 on success. + * + **/ +int gnutls_openpgp_trustdb_init(gnutls_openpgp_trustdb * trustdb) +{ + *trustdb = gnutls_calloc( 1, sizeof(gnutls_openpgp_trustdb_int)); + + if (*trustdb) { + return 0; /* success */ + } + return GNUTLS_E_MEMORY_ERROR; +} + +/** + * gnutls_openpgp_trustdb_deinit - This function deinitializes memory used by a gnutls_openpgp_trustdb structure + * @trustdb: The structure to be initialized + * + * This function will deinitialize a CRL structure. + * + **/ +void gnutls_openpgp_trustdb_deinit(gnutls_openpgp_trustdb trustdb) +{ + if (!trustdb) return; + + if (trustdb->st) { + cdk_stream_close( trustdb->st); + trustdb->st = NULL; + } + + gnutls_free(trustdb); +} + +/** + * gnutls_openpgp_trustdb_import_file - This function will import a RAW or BASE64 encoded key + * @trustdb: The structure to store the parsed key. + * @file: The file that holds the trustdb. + * + * This function will convert the given RAW or Base64 encoded trustdb + * to the native gnutls_openpgp_trustdb format. The output will be stored in 'trustdb'. + * + * Returns 0 on success. + * + **/ +int gnutls_openpgp_trustdb_import_file(gnutls_openpgp_trustdb trustdb, + const char * file) +{ +int rc; + + + rc = cdk_stream_open( file, &trustdb->st); + if( rc ) { + rc = _gnutls_map_cdk_rc( rc ); + gnutls_assert(); + return rc; + } + + return 0; +} + +#endif diff --git a/libextra/openpgp/verify.c b/libextra/openpgp/verify.c new file mode 100644 index 0000000000..af3518af4f --- /dev/null +++ b/libextra/openpgp/verify.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2002 Timo Schulz + * Portions Copyright (C) 2003 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS-EXTRA. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* Functions on OpenPGP key parsing + */ + +#include +#include +#include +#include + +#ifdef HAVE_LIBOPENCDK + +static int +openpgp_get_key_trust( gnutls_openpgp_trustdb trustdb, + gnutls_openpgp_key key, unsigned int *r_trustval ) +{ + CDK_PACKET *pkt; + cdk_pkt_pubkey_t pk = NULL; + int flags = 0, ot = 0; + int rc = 0; + + if( !trustdb || !key || !r_trustval ) { + gnutls_assert( ); + return GNUTLS_E_INVALID_REQUEST; + } + + *r_trustval = 0; + + pkt = cdk_kbnode_find_packet( key->knode, CDK_PKT_PUBLIC_KEY ); + if( !pkt ) { + rc = GNUTLS_E_OPENPGP_GETKEY_FAILED; + goto leave; + } + pk = pkt->pkt.public_key; + + rc = cdk_trustdb_get_ownertrust( trustdb->st, pk, &ot, &flags ); + + if ( rc ) { /* no ownertrust record was found */ + rc = 0; + *r_trustval = 0; + goto leave; + } + + if( flags & CDK_TFLAG_DISABLED ) { + *r_trustval |= GNUTLS_CERT_NOT_TRUSTED; + *r_trustval |= GNUTLS_CERT_INVALID; + goto leave; + } + + if( flags & CDK_TFLAG_REVOKED ) { + *r_trustval |= GNUTLS_CERT_NOT_TRUSTED; + *r_trustval |= GNUTLS_CERT_REVOKED; + } + + switch( ot ) { + case CDK_TRUST_NEVER: + *r_trustval |= GNUTLS_CERT_NOT_TRUSTED; + break; + case CDK_TRUST_UNKNOWN: + case CDK_TRUST_UNDEFINED: + case CDK_TRUST_MARGINAL: + case CDK_TRUST_FULLY: + case CDK_TRUST_ULTIMATE: + *r_trustval |= 1; /* means okay */ + rc = 0; + break; + } + +leave: + if( rc ) + *r_trustval |= GNUTLS_CERT_NOT_TRUSTED; + return rc; +} + +/** + * gnutls_openpgp_key_verify_ring - Verify all signatures on the key + * @key: the structure that holds the key. + * @keyring: holds the keyring to check against + * @flags: unused (should be 0) + * @verify: will hold the certificate verification output. + * + * Verify all signatures in the certificate list. When the key + * is not available, the signature is skipped. + * + * The certificate verification output will be put in 'verify' and will be + * one or more of the gnutls_certificate_status enumerated elements bitwise or'd. + * + * GNUTLS_CERT_INVALID\: A signature on the key is invalid. + * + * GNUTLS_CERT_REVOKED\: The key has been revoked. + * + * GNUTLS_CERT_NOT_TRUSTED\: The key is either invalid or revoked. + * + * NOTE: this function does not verify using any "web of trust". You + * may use GnuPG for that purpose, or any other external PGP application. + * + * Returns 0 on success. + **/ +int gnutls_openpgp_key_verify_ring( gnutls_openpgp_key key, + gnutls_openpgp_keyring keyring, + unsigned int flags, unsigned int *verify) +{ + int rc = 0; + int status = 0; + + if( !key || !keyring ) { + gnutls_assert(); + return GNUTLS_E_NO_CERTIFICATE_FOUND; + } + + rc = cdk_pk_check_sigs( key->knode, keyring->hd, &status ); + if( rc == CDK_Error_No_Key ) + rc = GNUTLS_E_NO_CERTIFICATE_FOUND; /* fixme */ + + switch( status ) { + case CDK_KEY_INVALID: + *verify = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED; + rc = 0; + break; + + case CDK_KEY_REVOKED: + *verify = GNUTLS_CERT_REVOKED | GNUTLS_CERT_NOT_TRUSTED; + rc = 0; + break; + default: + rc = 0; + } + + if( rc ) { + gnutls_assert(); + } + return rc; +} + +/** + * gnutls_openpgp_key_verify_trustdb - Verify all signatures on the key + * @key: the structure that holds the key. + * @trustdb: holds the trustdb to check against + * @flags: unused (should be 0) + * @verify: will hold the certificate verification output. + * + * Verify all signatures in the certificate list. When the key + * is not available, the signature is skipped. + * + * The function checks the ownertrust of the key before the signatures are checked. + * It is possible that the key was disabled or the owner is not trusted + * at all. Then we don't check the signatures because it makes no sense. + * + * The certificate verification output will be put in 'verify' and will be + * one or more of the gnutls_certificate_status enumerated elements bitwise or'd. + * + * NOTE: this function does not verify using any "web of trust". You + * may use GnuPG for that purpose, or any other external PGP application. + * + * Returns 0 on success. + **/ +int gnutls_openpgp_key_verify_trustdb( gnutls_openpgp_key key, + gnutls_openpgp_trustdb trustdb, + unsigned int flags, unsigned int *verify) +{ + cdk_keydb_hd_t hd = NULL; + int rc = 0; + int status = 0; + + if( !key) { + gnutls_assert(); + return GNUTLS_E_NO_CERTIFICATE_FOUND; + } + + if( !trustdb) { + gnutls_assert( ); + return GNUTLS_E_INVALID_REQUEST; + } + + rc = openpgp_get_key_trust( trustdb, key, verify); + if( rc) + goto leave; + + rc = 0; + +leave: + cdk_free( hd ); + if( rc ) { + gnutls_assert(); + } + return rc; +} + +#endif -- cgit v1.2.1