]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
*** empty log message ***
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 30 Oct 2003 15:57:55 +0000 (15:57 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 30 Oct 2003 15:57:55 +0000 (15:57 +0000)
lib/gnutls.h.in.in
lib/x509/pkcs12_bag.c
libextra/openpgp/compat.c [new file with mode: 0644]
libextra/openpgp/extras.c [new file with mode: 0644]
libextra/openpgp/verify.c [new file with mode: 0644]

index 94966e36566763b862b567d9608ad12c3e81ee5a..e892b51f3be0c3b7b0e462a7d325913903860f28 100644 (file)
@@ -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;
index 2617c567003cf606262330a2d431eb7f4c1f2492..79d9d158238ad12df380138618455fbb7f1fc15e 100644 (file)
@@ -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 (file)
index 0000000..9cc9f2d
--- /dev/null
@@ -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 (file)
index 0000000..42982b4
--- /dev/null
@@ -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 (file)
index 0000000..af3518a
--- /dev/null
@@ -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