gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_99_0-70-g6e4e6b0


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_99_0-70-g6e4e6b0
Date: Wed, 20 Apr 2011 22:24:41 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=6e4e6b0aa30acc8db68fcc19a9406abcfe44ae9c

The branch, master has been updated
       via  6e4e6b0aa30acc8db68fcc19a9406abcfe44ae9c (commit)
       via  ce1ceebc782aa6b920ceaef7754e9f87bb0820d0 (commit)
       via  1a02ec18e9e39f82cee7f9cff74e1f1574bac472 (commit)
       via  8d328d1a17fc98073a55d94b7de17e55987494ef (commit)
       via  f6a7872bb964bd35105a561c7ef67cf8d3c085b7 (commit)
      from  1880d4807b8ff20e8e1fa4dd1104baea5802d193 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 6e4e6b0aa30acc8db68fcc19a9406abcfe44ae9c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Thu Apr 21 00:21:56 2011 +0200

    Added gnutls_certificate_set_retrieve_function2() to replace
    gnutls_certificate_set_retrieve_function(). The new one is a
    efficient for busy servers because it eliminates the need
    for the server to encode the certificate to DER format.

commit ce1ceebc782aa6b920ceaef7754e9f87bb0820d0
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Apr 20 20:08:12 2011 +0200

    Added GNUTLS_E_USER_ERROR

commit 1a02ec18e9e39f82cee7f9cff74e1f1574bac472
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Apr 20 19:45:20 2011 +0200

    Eliminated the need for sign_algo in gnutls_pcert_st. This means
    that we don't follow RFC5246 by letter, but there wasn't any other
    implementation using the sign_algorithm part of the certificate
    selection, and this helps reduce complexity.

commit 8d328d1a17fc98073a55d94b7de17e55987494ef
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Apr 20 19:31:11 2011 +0200

    Added readme for libcfg.

commit f6a7872bb964bd35105a561c7ef67cf8d3c085b7
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Apr 20 19:26:08 2011 +0200

    No need to check for -maes and -mpclmul with the current AES-NI code.

-----------------------------------------------------------------------

Summary of changes:
 configure.ac                    |    7 +-
 doc/examples/ex-cert-select.c   |   98 +++++-----------
 lib/auth/cert.c                 |   52 ++++++---
 lib/auth/cert.h                 |    6 +-
 lib/ext/signature.c             |   60 +----------
 lib/ext/signature.h             |    2 -
 lib/gnutls_alert.c              |    4 +
 lib/gnutls_cert.c               |   48 ++++++++-
 lib/gnutls_errors.c             |    2 +
 lib/gnutls_pcert.c              |    2 -
 lib/includes/gnutls/abstract.h  |   25 ++++-
 lib/includes/gnutls/gnutls.h.in |    6 +-
 lib/libgnutls.map               |    7 +
 src/certtool.c                  |    2 +-
 src/cfg/Makefile.am             |    2 +-
 src/cfg/README                  |    6 +
 src/cli.c                       |  244 ++++++++++++++++++---------------------
 tests/x509dn.c                  |    5 +-
 18 files changed, 285 insertions(+), 293 deletions(-)
 create mode 100644 src/cfg/README

diff --git a/configure.ac b/configure.ac
index 85fa87a..3fb1adc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,15 +79,14 @@ hw_accel=none
 if test "$use_accel" != "no"; then
 case $host_cpu in
   i?86 | x86_64 | amd64)
-    GCC_FLAG_ADD([-maes -mpclmul],[X86])
-
-    if test "x$X86" = "xyes";then
+dnl    GCC_FLAG_ADD([-maes -mpclmul],[X86])
+dnl    if test "x$X86" = "xyes";then
       if test "$host_cpu" = "x86_64" -o "$host_cpu" = "amd64";then
         hw_accel="x86-64"
       else
         hw_accel="x86"
       fi
-    fi
+dnl    fi
   ;;
   *)
   ;;
diff --git a/doc/examples/ex-cert-select.c b/doc/examples/ex-cert-select.c
index 09b9a5e..461820c 100644
--- a/doc/examples/ex-cert-select.c
+++ b/doc/examples/ex-cert-select.c
@@ -13,6 +13,7 @@
 #include <unistd.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
+#include <gnutls/abstract.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -30,13 +31,15 @@
 extern int tcp_connect (void);
 extern void tcp_close (int sd);
 
-static int cert_callback (gnutls_session_t session,
-                          const gnutls_datum_t * req_ca_rdn, int nreqs,
-                          const gnutls_pk_algorithm_t * sign_algos,
-                          int sign_algos_length, gnutls_retr2_st * st);
+static int
+cert_callback (gnutls_session_t session,
+               const gnutls_datum_t * req_ca_rdn, int nreqs,
+               const gnutls_pk_algorithm_t * sign_algos,
+               int sign_algos_length, gnutls_pcert_st** pcert,
+               unsigned int *pcert_length, gnutls_privkey_t* pkey);
 
-gnutls_x509_crt_t crt;
-gnutls_x509_privkey_t key;
+gnutls_pcert_st crt;
+gnutls_privkey_t key;
 
 /* Helper functions to load a certificate and key
  * files into memory.
@@ -77,19 +80,19 @@ load_keys (void)
 {
   int ret;
   gnutls_datum_t data;
+  gnutls_x509_privkey_t x509_key;
 
   data = load_file (CERT_FILE);
   if (data.data == NULL)
     {
-      fprintf (stderr, "*** Error loading cert file.\n");
+      fprintf (stderr, "*** Error loading certificate file.\n");
       exit (1);
     }
-  gnutls_x509_crt_init (&crt);
-
-  ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM);
+  
+  ret = gnutls_pcert_import_x509_raw(&crt, &data, GNUTLS_X509_FMT_PEM, 0);
   if (ret < 0)
     {
-      fprintf (stderr, "*** Error loading key file: %s\n",
+      fprintf (stderr, "*** Error loading certificate file: %s\n",
                gnutls_strerror (ret));
       exit (1);
     }
@@ -103,9 +106,9 @@ load_keys (void)
       exit (1);
     }
 
-  gnutls_x509_privkey_init (&key);
+  gnutls_x509_privkey_init (&x509_key);
 
-  ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM);
+  ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
   if (ret < 0)
     {
       fprintf (stderr, "*** Error loading key file: %s\n",
@@ -113,8 +116,17 @@ load_keys (void)
       exit (1);
     }
 
-  unload_file (data);
+  gnutls_privkey_init (&key);
 
+  ret = gnutls_privkey_import_x509(key, x509_key, 
GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+  if (ret < 0)
+    {
+      fprintf (stderr, "*** Error importing key: %s\n", 
+               gnutls_strerror (ret));
+      exit (1);
+    }
+
+  unload_file (data);
 }
 
 int
@@ -143,7 +155,7 @@ main (void)
    */
   gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM);
 
-  gnutls_certificate_set_retrieve_function (xcred, cert_callback);
+  gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
 
   /* Initialize TLS session 
    */
@@ -225,7 +237,8 @@ static int
 cert_callback (gnutls_session_t session,
                const gnutls_datum_t * req_ca_rdn, int nreqs,
                const gnutls_pk_algorithm_t * sign_algos,
-               int sign_algos_length, gnutls_retr2_st * st)
+               int sign_algos_length, gnutls_pcert_st** pcert,
+               unsigned int *pcert_length, gnutls_privkey_t* pkey)
 {
   char issuer_dn[256];
   int i, ret;
@@ -255,59 +268,12 @@ cert_callback (gnutls_session_t session,
    * The certificate must be of any of the "sign algorithms"
    * supported by the server.
    */
-
   type = gnutls_certificate_type_get (session);
   if (type == GNUTLS_CRT_X509)
     {
-      /* check if the certificate we are sending is signed
-       * with an algorithm that the server accepts */
-      gnutls_sign_algorithm_t cert_algo, req_algo;
-      int i, match = 0;
-
-      ret = gnutls_x509_crt_get_signature_algorithm (crt);
-      if (ret < 0)
-        {
-          /* error reading signature algorithm 
-           */
-          return -1;
-        }
-      cert_algo = ret;
-
-      i = 0;
-      do
-        {
-          ret = gnutls_sign_algorithm_get_requested (session, i, &req_algo);
-          if (ret >= 0 && cert_algo == req_algo)
-            {
-              match = 1;
-              break;
-            }
-
-          /* server has not requested anything specific */
-          if (i == 0 && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
-            {
-              match = 1;
-              break;
-            }
-          i++;
-        }
-      while (ret >= 0);
-
-      if (match == 0)
-        {
-          printf
-            ("- Could not find a suitable certificate to send to server\n");
-          return -1;
-        }
-
-      st->cert_type = type;
-      st->ncerts = 1;
-
-      st->cert.x509 = &crt;
-      st->key.x509 = key;
-      st->key_type = GNUTLS_PRIVKEY_X509;
-
-      st->deinit_all = 0;
+      *pcert_length = 1;
+      *pcert = &crt;
+      *pkey = key;
     }
   else
     {
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
index 275e9bf..ac87412 100644
--- a/lib/auth/cert.c
+++ b/lib/auth/cert.c
@@ -459,6 +459,8 @@ call_get_cert_callback (gnutls_session_t session,
   gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
   gnutls_certificate_credentials_t cred;
   gnutls_retr2_st st2;
+  gnutls_pcert_st *pcert = NULL;
+  unsigned int pcert_length = 0;
 
   cred = (gnutls_certificate_credentials_t)
     _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
@@ -470,7 +472,31 @@ call_get_cert_callback (gnutls_session_t session,
 
   memset (&st2, 0, sizeof (st2));
 
-  if (cred->get_cert_callback)
+  if (cred->get_cert_callback2)
+    {
+      /* we avoid all allocations and transformations */
+      ret = cred->get_cert_callback2 (session, issuers_dn, issuers_dn_length,
+                                     pk_algos, pk_algos_length, 
+                                     &pcert, &pcert_length, &local_key);
+      if (ret < 0)
+        return gnutls_assert_val(GNUTLS_E_USER_ERROR);
+
+      if (pcert_length > 0 && type != pcert[0].type)
+        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+      if (pcert_length == 0)
+        {
+          pcert = NULL;
+          local_key = NULL;
+        }
+      _gnutls_selected_certs_set (session, pcert,
+                              pcert_length,
+                              local_key, 0);
+      
+      return 0;
+
+    }
+  else if (cred->get_cert_callback)
     {
       ret = cred->get_cert_callback (session, issuers_dn, issuers_dn_length,
                                      pk_algos, pk_algos_length, &st2);
@@ -511,7 +537,7 @@ call_get_cert_callback (gnutls_session_t session,
   if (ret < 0)
     {
       gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
+      return GNUTLS_E_USER_ERROR;
     }
 
   if (st2.ncerts == 0)
@@ -663,7 +689,7 @@ _select_client_cert (gnutls_session_t session,
     }
 
   if (cred->client_get_cert_callback != NULL
-      || cred->get_cert_callback != NULL)
+      || cred->get_cert_callback != NULL || cred->get_cert_callback2 != NULL)
     {
 
       /* use a callback to get certificate 
@@ -1121,14 +1147,6 @@ _gnutls_proc_x509_server_certificate (gnutls_session_t 
session,
           goto cleanup;
         }
 
-       ret = _gnutls_session_sign_algo_enabled (session,
-                             peer_certificate_list[j].sign_algo);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          goto cleanup;
-        }
-       
       p += len;
     }
 
@@ -2054,7 +2072,8 @@ _gnutls_server_select_cert (gnutls_session_t session,
   /* If the callback which retrieves certificate has been set,
    * use it and leave.
    */
-  if (cred->server_get_cert_callback != NULL)
+  if (cred->server_get_cert_callback != NULL || cred->server_get_cert_callback 
||
+      cred->get_cert_callback2)
     {
       ret = call_get_cert_callback (session, NULL, 0, NULL, 0);
       if (ret < 0)
@@ -2082,15 +2101,10 @@ _gnutls_server_select_cert (gnutls_session_t session,
       if (requested_algo == GNUTLS_PK_ANY ||
           requested_algo == pk)
         {
-          /* if cert type and signature algorithm matches
+          /* if cert type matches
            */
          /* *INDENT-OFF* */
-         if (session->security_parameters.cert_type == 
cred->cert_list[i][0].type
-             && (cred->cert_list[i][0].type == GNUTLS_CRT_OPENPGP
-                 ||    /* FIXME: make this a check for certificate
-                          type capabilities */
-                 _gnutls_session_sign_algo_requested
-                 (session, cred->cert_list[i][0].sign_algo) == 0))
+         if (session->security_parameters.cert_type == 
cred->cert_list[i][0].type)
            {
              idx = i;
              break;
diff --git a/lib/auth/cert.h b/lib/auth/cert.h
index d26935b..d8e29dd 100644
--- a/lib/auth/cert.h
+++ b/lib/auth/cert.h
@@ -84,11 +84,15 @@ typedef struct gnutls_certificate_credentials_st
    */
   gnutls_datum_t x509_rdn_sequence;
 
+  /* It's a mess here. However we need to keep the old 3 functions
+   * for compatibility */
+  gnutls_certificate_retrieve_function *get_cert_callback; /* deprecated */
   gnutls_certificate_client_retrieve_function *client_get_cert_callback;       
 /* deprecated */
   gnutls_certificate_server_retrieve_function *server_get_cert_callback;       
 /* deprecated */
+  gnutls_certificate_retrieve_function2 *get_cert_callback2;
+
   gnutls_certificate_verify_function *verify_callback;
 
-  gnutls_certificate_retrieve_function *get_cert_callback;
 } certificate_credentials_st;
 
 typedef struct rsa_info_st
diff --git a/lib/ext/signature.c b/lib/ext/signature.c
index ad8f3b8..61e33df 100644
--- a/lib/ext/signature.c
+++ b/lib/ext/signature.c
@@ -251,8 +251,7 @@ _gnutls_signature_algorithm_send_params (gnutls_session_t 
session,
 }
 
 /* Returns a requested by the peer signature algorithm that
- * matches the given public key algorithm. Index can be increased
- * to return the second choice etc.
+ * matches the given certificate's public key algorithm. 
  */
 gnutls_sign_algorithm_t
 _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_pcert_st* cert)
@@ -293,63 +292,6 @@ _gnutls_session_get_sign_algo (gnutls_session_t session, 
gnutls_pcert_st* cert)
   return GNUTLS_SIGN_UNKNOWN;
 }
 
-
-/* Check if the given signature algorithm is accepted by
- * the peer. Returns 0 on success or a negative value
- * on error.
- */
-int
-_gnutls_session_sign_algo_requested (gnutls_session_t session,
-                                     gnutls_sign_algorithm_t sig)
-{
-  unsigned i;
-  int ret, hash;
-  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
-  sig_ext_st *priv;
-  extension_priv_data_t epriv;
-
-  if (!_gnutls_version_has_selectable_sighash (ver))
-    {
-      return 0;
-    }
-
-  ret =
-    _gnutls_ext_get_session_data (session,
-                                  GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
-                                  &epriv);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      /* extension not received allow SHA1 and SHA256 */
-      hash = _gnutls_sign_get_hash_algorithm (sig);
-      if (hash == GNUTLS_DIG_SHA1 || hash == GNUTLS_DIG_SHA256)
-        return 0;
-      else
-        return ret;
-    }
-  priv = epriv.ptr;
-
-  if (priv->sign_algorithms_size == 0)
-    /* none set, allow all */
-    {
-      return 0;
-    }
-
-  for (i = 0; i < priv->sign_algorithms_size; i++)
-    {
-      _gnutls_handshake_log("HSK[%p]: allowed sign algorithm: %s (%d)-- want 
%s (%d)\n", session,
-            gnutls_sign_get_name(priv->sign_algorithms[i]), 
priv->sign_algorithms[i],
-            gnutls_sign_get_name(sig), sig);
-            
-      if (priv->sign_algorithms[i] == sig)
-        {
-          return 0;             /* ok */
-        }
-    }
-
-  return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
-}
-
 /* Check if the given signature algorithm is supported.
  * This means that it is enabled by the priority functions,
  * and in case of a server a matching certificate exists.
diff --git a/lib/ext/signature.h b/lib/ext/signature.h
index 89b31d7..0c74e3e 100644
--- a/lib/ext/signature.h
+++ b/lib/ext/signature.h
@@ -32,8 +32,6 @@
 
 extern extension_entry_st ext_mod_sig;
 
-int _gnutls_session_sign_algo_requested (gnutls_session_t session,
-                                         gnutls_sign_algorithm_t sig);
 gnutls_sign_algorithm_t
 _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_pcert_st* 
cert);
 int _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
diff --git a/lib/gnutls_alert.c b/lib/gnutls_alert.c
index 0663669..abd0265 100644
--- a/lib/gnutls_alert.c
+++ b/lib/gnutls_alert.c
@@ -214,6 +214,10 @@ gnutls_error_to_alert (int err, int *level)
       ret = GNUTLS_A_UNSUPPORTED_EXTENSION;
       _level = GNUTLS_AL_FATAL;
       break;
+    case GNUTLS_E_USER_ERROR:
+      ret = GNUTLS_A_USER_CANCELED;
+      _level = GNUTLS_AL_FATAL;
+      break;
     case GNUTLS_E_UNEXPECTED_PACKET:
     case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET:
       ret = GNUTLS_A_UNEXPECTED_MESSAGE;
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index f587f16..91ad7ca 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -305,6 +305,8 @@ gnutls_certificate_server_set_request (gnutls_session_t 
session,
  *
  * This function sets a callback to be called in order to retrieve the
  * certificate to be used in the handshake.
+ * You are advised to use gnutls_certificate_set_retrieve_function2() because 
it
+ * is much more efficient in the processing it requires from gnutls.
  *
  * The callback's function prototype is:
  * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int 
nreqs,
@@ -343,6 +345,8 @@ void gnutls_certificate_client_set_retrieve_function
  *
  * This function sets a callback to be called in order to retrieve the
  * certificate to be used in the handshake.
+ * You are advised to use gnutls_certificate_set_retrieve_function2() because 
it
+ * is much more efficient in the processing it requires from gnutls.
  *
  * The callback's function prototype is:
  * int (*callback)(gnutls_session_t, gnutls_retr_st* st);
@@ -369,7 +373,9 @@ void gnutls_certificate_server_set_retrieve_function
  * @func: is the callback function
  *
  * This function sets a callback to be called in order to retrieve the
- * certificate to be used in the handshake.
+ * certificate to be used in the handshake. You are advised
+ * to use gnutls_certificate_set_retrieve_function2() because it
+ * is much more efficient in the processing it requires from gnutls.
  *
  * The callback's function prototype is:
  * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int 
nreqs,
@@ -404,6 +410,46 @@ void gnutls_certificate_set_retrieve_function
 }
 
 /**
+ * gnutls_certificate_set_retrieve_function2:
+ * @cred: is a #gnutls_certificate_credentials_t structure.
+ * @func: is the callback function
+ *
+ * This function sets a callback to be called in order to retrieve the
+ * certificate to be used in the handshake.
+ *
+ * The callback's function prototype is:
+ * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int 
nreqs,
+ * const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length, 
gnutls_pcert_st* st);
+ *
+ * @req_ca_cert is only used in X.509 certificates.
+ * Contains a list with the CA names that the server considers trusted.
+ * Normally we should send a certificate that is signed
+ * by one of these CAs. These names are DER encoded. To get a more
+ * meaningful value use the function gnutls_x509_rdn_get().
+ *
+ * @pk_algos contains a list with server's acceptable signature algorithms.
+ * The certificate returned should support the server's given algorithms.
+ *
+ * @st should contain the certificates and private keys.
+ *
+ * If the callback function is provided then gnutls will call it, in the
+ * handshake, after the certificate request message has been received.
+ *
+ * In server side pk_algos and req_ca_dn are NULL.
+ *
+ * The callback function should set the certificate list to be sent,
+ * and return 0 on success. If no certificate was selected then the
+ * number of certificates should be set to zero. The value (-1)
+ * indicates error and the handshake will be terminated.
+ **/
+void gnutls_certificate_set_retrieve_function2
+  (gnutls_certificate_credentials_t cred,
+   gnutls_certificate_retrieve_function2 * func)
+{
+  cred->get_cert_callback2 = func;
+}
+
+/**
  * gnutls_certificate_set_verify_function:
  * @cred: is a #gnutls_certificate_credentials_t structure.
  * @func: is the callback function
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index c87f1cf..8096c2e 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -326,6 +326,8 @@ static const gnutls_error_entry error_algorithms[] = {
                GNUTLS_E_PKCS11_USER_ERROR, 1),
   ERROR_ENTRY (N_("The operation timed out"),
                GNUTLS_E_TIMEDOUT, 1),
+  ERROR_ENTRY (N_("The operation was cancelled due to user error"),
+               GNUTLS_E_USER_ERROR, 1),
   {NULL, NULL, 0, 0}
 };
 
diff --git a/lib/gnutls_pcert.c b/lib/gnutls_pcert.c
index 8787058..555c62c 100644
--- a/lib/gnutls_pcert.c
+++ b/lib/gnutls_pcert.c
@@ -53,7 +53,6 @@ size_t sz;
   memset(pcert, 0, sizeof(*pcert));
 
   pcert->type = GNUTLS_CRT_X509;
-  pcert->sign_algo = gnutls_x509_crt_get_signature_algorithm(crt);
   pcert->cert.data = NULL;
 
   sz = 0;
@@ -173,7 +172,6 @@ size_t sz;
   memset(pcert, 0, sizeof(*pcert));
 
   pcert->type = GNUTLS_CRT_OPENPGP;
-  pcert->sign_algo = GNUTLS_SIGN_UNKNOWN;
   pcert->cert.data = NULL;
 
   sz = 0;
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 33eefef..3c6274f 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -156,9 +156,8 @@ int gnutls_x509_crq_privkey_sign (gnutls_x509_crq_t crq,
 /* pcert */
 typedef struct gnutls_pcert_st {
        gnutls_pubkey_t pubkey;
-  gnutls_datum_t cert;
+       gnutls_datum_t cert;
        gnutls_certificate_type_t type;    /* type of the certificate */
-       gnutls_sign_algorithm_t sign_algo; /* sign algorithm of the certificate 
*/
 } gnutls_pcert_st;
 
 /* Do not initialize the "cert" element of
@@ -182,5 +181,27 @@ int gnutls_pcert_import_openpgp (gnutls_pcert_st* pcert,
 
 void gnutls_pcert_deinit (gnutls_pcert_st* pcert);
 
+/* For certificate credentials */
+  /* This is the same as gnutls_certificate_retrieve_function()
+   * but retrieves a gnutls_pcert_st which requires much less processing
+   * within the library.
+   */
+  typedef int gnutls_certificate_retrieve_function2 (gnutls_session_t,
+                                                    const gnutls_datum_t *
+                                                    req_ca_rdn,
+                                                    int nreqs,
+                                                    const
+                                                    gnutls_pk_algorithm_t
+                                                    * pk_algos,
+                                                    int pk_algos_length,
+                                                    gnutls_pcert_st **,
+                                                    unsigned int *pcert_length,
+                                                    gnutls_privkey_t *privkey);
+
+
+  void gnutls_certificate_set_retrieve_function2
+    (gnutls_certificate_credentials_t cred,
+     gnutls_certificate_retrieve_function2 * func);
+
 
 #endif
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 3e7a715..0cdbffd 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1480,6 +1480,10 @@ extern "C"
   /* These are set on the credentials structure.
    */
 
+  /* use gnutls_certificate_set_retrieve_function2() in abstract.h
+   * instead. It's much more efficient.
+   */
+
   typedef int gnutls_certificate_retrieve_function (gnutls_session_t,
                                                     const
                                                     gnutls_datum_t *
@@ -1734,8 +1738,8 @@ extern "C"
 #define GNUTLS_E_PKCS11_USER_ERROR -317
 
 #define GNUTLS_E_CRYPTO_INIT_FAILED -318
-
 #define GNUTLS_E_TIMEDOUT -319
+#define GNUTLS_E_USER_ERROR -320
 
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
 
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 85b301c..87d70cc 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -702,6 +702,13 @@ GNUTLS_3_0_0 {
        gnutls_dtls_prestate_set;
        gnutls_dtls_get_data_mtu;
        gnutls_cipher_set_iv;
+       gnutls_pcert_deinit;
+       gnutls_pcert_import_x509;
+       gnutls_pcert_import_x509_raw;
+       gnutls_pcert_import_openpgp;
+       gnutls_pcert_import_openpgp_raw;
+       gnutls_pubkey_get_openpgp_key_id;
+       gnutls_certificate_set_retrieve_function2;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
diff --git a/src/certtool.c b/src/certtool.c
index 9800bfb..1809660 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -1317,7 +1317,7 @@ void
 pgp_privkey_info (void)
 {
   gnutls_openpgp_privkey_t key;
-  gnutls_openpgp_keyid_t keyid;
+  unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
   size_t size;
   int ret, i, subkeys;
   gnutls_datum_t pem;
diff --git a/src/cfg/Makefile.am b/src/cfg/Makefile.am
index 9d47df0..bb0b25a 100644
--- a/src/cfg/Makefile.am
+++ b/src/cfg/Makefile.am
@@ -1,4 +1,4 @@
-EXTRA_DIST = cfg+.h  cfgfile.h  cmdline.h  shared.h \
+EXTRA_DIST = cfg+.h  cfgfile.h  cmdline.h  shared.h README \
        cfg+.c  cfgfile.c  cmdline.c  parse.c  props.c  shared.c
 
 SUBDIRS = platon
diff --git a/src/cfg/README b/src/cfg/README
new file mode 100644
index 0000000..bbe901a
--- /dev/null
+++ b/src/cfg/README
@@ -0,0 +1,6 @@
+The libcfg+ library is not part of the GnuTLS library, but is 
+used by GnuTLS programs. It is licensed under the GNU GPL v2.
+
+Original site:
+http://platon.sk/projects/libcfg+/
+
diff --git a/src/cli.c b/src/cli.c
index 31eb80e..88aa645 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -34,8 +34,8 @@
 #include <error.h>
 
 #include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
 #include <gnutls/dtls.h>
-#include <gnutls/extra.h>
 #include <gnutls/x509.h>
 #include <gnutls/openpgp.h>
 #include <gnutls/pkcs11.h>
@@ -135,13 +135,11 @@ unload_file (gnutls_datum_t data)
 
 #define MAX_CRT 6
 static unsigned int x509_crt_size;
-static gnutls_x509_crt_t x509_crt[MAX_CRT];
-static gnutls_x509_privkey_t x509_key = NULL;
+static gnutls_pcert_st x509_crt[MAX_CRT];
+static gnutls_privkey_t x509_key = NULL;
 
-static gnutls_pkcs11_privkey_t pkcs11_key = NULL;
-
-static gnutls_openpgp_crt_t pgp_crt = NULL;
-static gnutls_openpgp_privkey_t pgp_key = NULL;
+static gnutls_pcert_st pgp_crt;
+static gnutls_privkey_t pgp_key = NULL;
 
 static void
 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
@@ -170,22 +168,26 @@ static void
 load_keys (void)
 {
   unsigned int crt_num;
-  int ret;
+  int ret, i;
   gnutls_datum_t data;
+  gnutls_x509_crt_t crt_list[MAX_CRT];
+  gnutls_pkcs11_privkey_t pkcs11_key;
+  gnutls_x509_privkey_t tmp_key;
+  uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
 
   if (x509_certfile != NULL && x509_keyfile != NULL)
     {
       if (strncmp (x509_certfile, "pkcs11:", 7) == 0)
         {
           crt_num = 1;
-          gnutls_x509_crt_init (&x509_crt[0]);
+          gnutls_x509_crt_init (&crt_list[0]);
 
           ret =
-            gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile, 0);
+            gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, 0);
 
           if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
             ret =
-              gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile,
+              gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile,
                                                  GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
 
           if (ret < 0)
@@ -207,7 +209,7 @@ load_keys (void)
 
           crt_num = MAX_CRT;
           ret =
-            gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
+            gnutls_x509_crt_list_import (crt_list, &crt_num, &data,
                                          GNUTLS_X509_FMT_PEM,
                                          
GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
           if (ret < 0)
@@ -229,10 +231,29 @@ load_keys (void)
             }
           x509_crt_size = ret;
         }
-      fprintf (stdout, "Processed %d client certificates...\n", ret);
+      
+      for (i=0;i<x509_crt_size;i++)
+        {
+          ret = gnutls_pcert_import_x509(&x509_crt[i], crt_list[i], 0);
+          if (ret < 0)
+            {
+              fprintf(stderr, "*** Error importing crt to pcert: %s\n",
+                gnutls_strerror(ret));
+              exit(1);
+            }
+          gnutls_x509_crt_deinit(crt_list[i]);
+        }
 
       unload_file (data);
 
+      ret = gnutls_privkey_init(&x509_key);
+      if (ret < 0)
+         {
+           fprintf (stderr, "*** Error initializing key: %s\n",
+                    gnutls_strerror (ret));
+           exit (1);
+         }
+
       if (strncmp (x509_keyfile, "pkcs11:", 7) == 0)
         {
           gnutls_pkcs11_privkey_init (&pkcs11_key);
@@ -245,6 +266,14 @@ load_keys (void)
                        gnutls_strerror (ret));
               exit (1);
             }
+
+          ret = gnutls_privkey_import_pkcs11( x509_key, pkcs11_key, 
GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+          if (ret < 0)
+            {
+              fprintf (stderr, "*** Error loading url: %s\n",
+                       gnutls_strerror (ret));
+              exit (1);
+            }
         }
       else
         {
@@ -255,10 +284,10 @@ load_keys (void)
               exit (1);
             }
 
-          gnutls_x509_privkey_init (&x509_key);
+          gnutls_x509_privkey_init (&tmp_key);
 
           ret =
-            gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
+            gnutls_x509_privkey_import (tmp_key, &data, GNUTLS_X509_FMT_PEM);
           if (ret < 0)
             {
               fprintf (stderr, "*** Error loading key file: %s\n",
@@ -266,25 +295,43 @@ load_keys (void)
               exit (1);
             }
 
+          ret = gnutls_privkey_import_x509( x509_key, tmp_key, 
GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+          if (ret < 0)
+            {
+              fprintf (stderr, "*** Error loading url: %s\n",
+                       gnutls_strerror (ret));
+              exit (1);
+            }
+
           unload_file (data);
         }
 
       fprintf (stdout, "Processed %d client X.509 certificates...\n",
                x509_crt_size);
     }
+
+
 #ifdef ENABLE_OPENPGP
+  if (info.pgp_subkey != NULL)
+    {
+      get_keyid (keyid, info.pgp_subkey);
+    }
+
   if (pgp_certfile != NULL && pgp_keyfile != NULL)
     {
+      gnutls_openpgp_crt_t tmp_pgp_crt;
+
       data = load_file (pgp_certfile);
       if (data.data == NULL)
         {
           fprintf (stderr, "*** Error loading PGP cert file.\n");
           exit (1);
         }
-      gnutls_openpgp_crt_init (&pgp_crt);
+
+      gnutls_openpgp_crt_init (&tmp_pgp_crt);
 
       ret =
-        gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
+        gnutls_pcert_import_openpgp_raw (&pgp_crt, &data, 
GNUTLS_OPENPGP_FMT_BASE64, info.pgp_subkey!=NULL?keyid:NULL, 0);
       if (ret < 0)
         {
           fprintf (stderr,
@@ -292,10 +339,17 @@ load_keys (void)
                    gnutls_strerror (ret));
           exit (1);
         }
-
-
+ 
       unload_file (data);
 
+      ret = gnutls_privkey_init(&pgp_key);
+      if (ret < 0)
+         {
+           fprintf (stderr, "*** Error initializing key: %s\n",
+                    gnutls_strerror (ret));
+           exit (1);
+         }
+
       if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0)
         {
           gnutls_pkcs11_privkey_init (&pkcs11_key);
@@ -307,9 +361,18 @@ load_keys (void)
                        gnutls_strerror (ret));
               exit (1);
             }
+
+          ret = gnutls_privkey_import_pkcs11( pgp_key, pkcs11_key, 
GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+          if (ret < 0)
+            {
+              fprintf (stderr, "*** Error loading url: %s\n",
+                       gnutls_strerror (ret));
+              exit (1);
+            }
         }
       else
         {
+          gnutls_openpgp_privkey_t tmp_pgp_key;
 
           data = load_file (pgp_keyfile);
           if (data.data == NULL)
@@ -318,10 +381,10 @@ load_keys (void)
               exit (1);
             }
 
-          gnutls_openpgp_privkey_init (&pgp_key);
+          gnutls_openpgp_privkey_init (&tmp_pgp_key);
 
           ret =
-            gnutls_openpgp_privkey_import (pgp_key, &data,
+            gnutls_openpgp_privkey_import (tmp_pgp_key, &data,
                                            GNUTLS_OPENPGP_FMT_BASE64, NULL,
                                            0);
           if (ret < 0)
@@ -332,40 +395,31 @@ load_keys (void)
               exit (1);
             }
 
-          unload_file (data);
-        }
-
-      if (info.pgp_subkey != NULL)
-        {
-          gnutls_openpgp_keyid_t keyid;
-
-          if (strcasecmp (info.pgp_subkey, "auto") == 0)
+          if (info.pgp_subkey != NULL)
             {
-              ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
+              ret =
+                gnutls_openpgp_privkey_set_preferred_key_id (tmp_pgp_key, 
keyid);
               if (ret < 0)
                 {
                   fprintf (stderr,
-                           "*** Error setting preferred sub key id (%s): %s\n",
-                           info.pgp_subkey, gnutls_strerror (ret));
+                      "*** Error setting preferred sub key id (%s): %s\n",
+                      info.pgp_subkey, gnutls_strerror (ret));
                   exit (1);
                 }
             }
-          else
-            get_keyid (keyid, info.pgp_subkey);
 
-          ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid);
-          if (ret >= 0)
-            ret =
-              gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid);
+          ret = gnutls_privkey_import_openpgp( pgp_key, tmp_pgp_key, 
GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
           if (ret < 0)
             {
-              fprintf (stderr,
-                       "*** Error setting preferred sub key id (%s): %s\n",
-                       info.pgp_subkey, gnutls_strerror (ret));
+              fprintf (stderr, "*** Error loading url: %s\n",
+                       gnutls_strerror (ret));
               exit (1);
             }
+
+          unload_file (data);
         }
 
+
       fprintf (stdout, "Processed 1 client PGP certificate...\n");
     }
 #endif
@@ -401,10 +455,11 @@ static int
 cert_callback (gnutls_session_t session,
                const gnutls_datum_t * req_ca_rdn, int nreqs,
                const gnutls_pk_algorithm_t * sign_algos,
-               int sign_algos_length, gnutls_retr2_st * st)
+               int sign_algos_length, gnutls_pcert_st **pcert,
+               unsigned int *pcert_length, gnutls_privkey_t * pkey)
 {
   char issuer_dn[256];
-  int i, ret;
+  int i, ret, cert_type;
   size_t len;
 
   if (verbose)
@@ -434,62 +489,17 @@ cert_callback (gnutls_session_t session,
    * supported by the server.
    */
 
-  st->cert_type = gnutls_certificate_type_get (session);
+  cert_type = gnutls_certificate_type_get (session);
 
-  st->ncerts = 0;
+  *pcert_length = 0;
 
-  if (st->cert_type == GNUTLS_CRT_X509)
+  if (cert_type == GNUTLS_CRT_X509)
     {
-      gnutls_sign_algorithm_t cert_algo, req_algo;
-      int i, match = 0;
-
       if (x509_crt_size > 0)
         {
-          ret = gnutls_x509_crt_get_signature_algorithm (x509_crt[0]);
-          if (ret < 0)
-            {
-              /* error reading signature algorithm */
-              return -1;
-            }
-          cert_algo = ret;
-
-          i = 0;
-          do
-            {
-              ret =
-                gnutls_sign_algorithm_get_requested (session, i, &req_algo);
-              if (ret >= 0 && cert_algo == req_algo)
-                {
-                  match = 1;
-                  break;
-                }
-
-              /* server has not requested anything specific */
-              if (i == 0 && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
-                {
-                  match = 1;
-                  break;
-                }
-              i++;
-            }
-          while (ret >= 0);
-
-          if (match == 0)
-            {
-              printf
-                ("- Could not find a suitable certificate to send to 
server\n");
-              return -1;
-            }
-
           if (x509_key != NULL)
             {
-              st->key.x509 = x509_key;
-              st->key_type = GNUTLS_PRIVKEY_X509;
-            }
-          else if (pkcs11_key != NULL)
-            {
-              st->key.pkcs11 = pkcs11_key;
-              st->key_type = GNUTLS_PRIVKEY_PKCS11;
+              *pkey = x509_key;
             }
           else
             {
@@ -497,48 +507,23 @@ cert_callback (gnutls_session_t session,
               return -1;
             }
 
-          st->ncerts = x509_crt_size;
-
-          st->cert.x509 = x509_crt;
-
-          st->deinit_all = 0;
-
-          return 0;
+          *pcert_length = x509_crt_size;
+          *pcert = x509_crt;
         }
 
     }
-  else if (st->cert_type == GNUTLS_CRT_OPENPGP)
+  else if (cert_type == GNUTLS_CRT_OPENPGP)
     {
-      if (pgp_crt != NULL)
+      if (pgp_key != NULL)
         {
+          *pkey = pgp_key;
 
-          if (pgp_key != NULL)
-            {
-              st->key.pgp = pgp_key;
-              st->key_type = GNUTLS_PRIVKEY_OPENPGP;
-            }
-          else if (pkcs11_key != NULL)
-            {
-              st->key.pkcs11 = pkcs11_key;
-              st->key_type = GNUTLS_PRIVKEY_PKCS11;
-            }
-          else
-            {
-              printf ("- Could not find a suitable key to send to server\n");
-              return -1;
-            }
-
-          st->ncerts = 1;
-
-          st->cert.pgp = pgp_crt;
-
-          st->deinit_all = 0;
-
-          return 0;
+          *pcert_length = 1;
+          *pcert = &pgp_crt;
         }
     }
 
-  printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
+  printf ("- Successfully sent %u certificate(s) to server.\n", *pcert_length);
   return 0;
 
 }
@@ -586,7 +571,7 @@ init_tls_session (const char *hostname)
     gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
   gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
 
-  gnutls_certificate_set_retrieve_function (xcred, cert_callback);
+  gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
   gnutls_certificate_set_verify_function (xcred, cert_verify_callback);
   gnutls_certificate_set_verify_flags (xcred, 0);
 
@@ -741,12 +726,6 @@ main (int argc, char **argv)
       exit (1);
     }
 
-  if ((ret = gnutls_global_init_extra ()) < 0)
-    {
-      fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
-      exit (1);
-    }
-
   pkcs11_common ();
   gaa_parser (argc, argv);
   if (hostname == NULL)
@@ -1490,3 +1469,4 @@ socket_open (socket_st * hd, const char *hostname, const 
char *service)
 
   return;
 }
+
diff --git a/tests/x509dn.c b/tests/x509dn.c
index cf6cc2b..4ee44c1 100644
--- a/tests/x509dn.c
+++ b/tests/x509dn.c
@@ -115,7 +115,8 @@ static int
 cert_callback (gnutls_session_t session,
                const gnutls_datum_t * req_ca_rdn, int nreqs,
                const gnutls_pk_algorithm_t * sign_algos,
-               int sign_algos_length, gnutls_retr2_st * st)
+               int sign_algos_length, gnutls_pcert_st ** pcert,
+               unsigned int* pcert_length, gnutls_privkey_t *pkey)
 {
   int result;
   gnutls_x509_dn_t dn;
@@ -199,7 +200,7 @@ client (void)
    */
   gnutls_certificate_set_x509_trust_mem (xcred, &ca, GNUTLS_X509_FMT_PEM);
 
-  gnutls_certificate_set_retrieve_function (xcred, cert_callback);
+  gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
 
   /* Initialize TLS session
    */


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]