summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-30 15:57:55 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-30 15:57:55 +0000
commitfc7d25527f41028f15da216e2ffa087becaf7eff (patch)
treed7c093533bba400a12e306772bfdf37639f4f483
parent602377951c230c2d6ca05f88c6445ee2d12ecd26 (diff)
downloadgnutls-fc7d25527f41028f15da216e2ffa087becaf7eff.tar.gz
*** empty log message ***
-rw-r--r--lib/gnutls.h.in.in19
-rw-r--r--lib/x509/pkcs12_bag.c4
-rw-r--r--libextra/openpgp/compat.c242
-rw-r--r--libextra/openpgp/extras.c186
-rw-r--r--libextra/openpgp/verify.c209
5 files changed, 655 insertions, 5 deletions
diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in
index 94966e3656..e892b51f3b 100644
--- a/lib/gnutls.h.in.in
+++ b/lib/gnutls.h.in.in
@@ -106,10 +106,23 @@ typedef enum gnutls_handshake_description { GNUTLS_HANDSHAKE_HELLO_REQUEST,
GNUTLS_HANDSHAKE_FINISHED=20
} gnutls_handshake_description;
+/* Note that the status bits have different meanings
+ * in openpgp keys and x.509 certificate verification.
+ */
typedef enum gnutls_certificate_status {
- GNUTLS_CERT_NOT_TRUSTED=2,
- GNUTLS_CERT_INVALID=4, /* refers to certificate chain */
- GNUTLS_CERT_REVOKED=32, /* will be present only if crls are checked */
+ GNUTLS_CERT_NOT_TRUSTED=2, /* will be set if the certificate
+ * was not verified.
+ */
+ GNUTLS_CERT_INVALID=4, /* in X.509 API will be set only when
+ * verifying certificate chains.
+ */
+ GNUTLS_CERT_REVOKED=32, /* in X.509 this will be set only if CRLs are checked
+ */
+
+ /* Those are extra information about the verification
+ * process. Will be set only if the certificate was
+ * not verified.
+ */
GNUTLS_CERT_ISSUER_NOT_FOUND=64,
GNUTLS_CERT_ISSUER_NOT_CA=128
} gnutls_certificate_status;
diff --git a/lib/x509/pkcs12_bag.c b/lib/x509/pkcs12_bag.c
index 2617c56700..79d9d15823 100644
--- a/lib/x509/pkcs12_bag.c
+++ b/lib/x509/pkcs12_bag.c
@@ -118,12 +118,12 @@ int gnutls_pkcs12_bag_get_count(gnutls_pkcs12_bag bag)
* gnutls_pkcs12_bag_get_data - This function returns the bag's data
* @bag: The bag
* @indx: The element of the bag to get the data from
- * @data: where the data will be copied to. Should be treated as constant.
+ * @data: where the bag's data will be. Should be treated as constant.
*
* This function will return the bag's data.
*
**/
-int gnutls_pkcs12_bag_get_data(gnutls_pkcs12_bag bag, int indx, gnutls_const_datum* data)
+int gnutls_pkcs12_bag_get_data(gnutls_pkcs12_bag bag, int indx, gnutls_const_datum * data)
{
if (indx >= bag->bag_elements)
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
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 <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls_openpgp.h>
+#include <openpgp.h>
+
+#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 <gnutls_int.h>
+
+#ifdef HAVE_LIBOPENCDK
+
+#include <gnutls_datum.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <opencdk.h>
+#include <gnutls_openpgp.h>
+#include <openpgp.h>
+
+/* 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 <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls_openpgp.h>
+#include <openpgp.h>
+
+#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