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_2-57-g7af8e49


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_99_2-57-g7af8e49
Date: Sat, 04 Jun 2011 18:59:18 +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=7af8e49ad43d5550c1cdf4fa5426c4e7034f08eb

The branch, master has been updated
       via  7af8e49ad43d5550c1cdf4fa5426c4e7034f08eb (commit)
       via  402df96be2bad49e8ea371334ce5df3acb48fbbb (commit)
       via  1c2fecee547e48cfda99635c4d7a76b9d9df6f06 (commit)
       via  31ab16d6491aabf9bee7516304e52ee215b44724 (commit)
       via  966eafa08d4e0dbab4aee6af0794f24aaa00b315 (commit)
       via  0d66f1fc47ec0dec5bfe56928cc46ed47842b360 (commit)
       via  b9f7a3d505d4be7521c3a6927b776ba02be33e5c (commit)
      from  b9dbbec1861b86c9d4b0c2922b430293baa03dc2 (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 7af8e49ad43d5550c1cdf4fa5426c4e7034f08eb
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jun 4 20:58:50 2011 +0200

    Added gnutls_x509_trust_list_add_named_crt() and
    gnutls_x509_trust_list_verify_named_crt() that allow having a
    list of certificates in the trusted list that will be associated
    with a name (e.g. server name) and will not be used as CAs.

commit 402df96be2bad49e8ea371334ce5df3acb48fbbb
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jun 4 10:03:55 2011 +0200

    Added SuiteB ciphersuites. Added SUITEB128 and SUITEB192 priority strings.
    SECURE256 was renamed to SECURE192 (because TLS ciphersuite's security level
    was not enough to justify 256-bits).

commit 1c2fecee547e48cfda99635c4d7a76b9d9df6f06
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jun 4 09:31:03 2011 +0200

    gnutls_ecc_curve_get() was added.

commit 31ab16d6491aabf9bee7516304e52ee215b44724
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jun 4 09:30:39 2011 +0200

    The PRF is now read from the ciphersuite table.

commit 966eafa08d4e0dbab4aee6af0794f24aaa00b315
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jun 4 09:29:27 2011 +0200

    Print information on elliptic curve sessions.

commit 0d66f1fc47ec0dec5bfe56928cc46ed47842b360
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jun 4 08:51:11 2011 +0200

    Split pubkey_verify_sig() to pubkey_verify_hashed_data() and 
pubkey_verify_data().
    Added gnutls_pubkey_verify_data2() to allow verification of a signature 
when the
    signature algorithm cannot be determined by the signature and the public 
key only.

commit b9f7a3d505d4be7521c3a6927b776ba02be33e5c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jun 4 08:00:34 2011 +0200

    Allow all SHA algorithms for DSA signatures.

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

Summary of changes:
 NEWS                                |   24 +++-
 doc/cha-cert-auth.texi              |   31 +++-
 doc/cha-intro-tls.texi              |   18 ++-
 doc/examples/ex-verify.c            |   13 +-
 lib/abstract_int.h                  |   16 ++
 lib/accelerated/intel/aes-gcm-x86.c |    3 +-
 lib/accelerated/intel/aes-x86.c     |    8 +
 lib/algorithms/ciphersuites.c       |   29 +++-
 lib/gnutls_cert.c                   |    2 +-
 lib/gnutls_hash_int.h               |    9 +
 lib/gnutls_priority.c               |  159 +++++++++++-----
 lib/gnutls_pubkey.c                 |  310 +++++++++++++++++++++++++++++-
 lib/gnutls_sig.c                    |  158 ++++++++++++----
 lib/gnutls_sig.h                    |    5 +
 lib/gnutls_state.c                  |   24 ++-
 lib/includes/gnutls/abstract.h      |    6 +
 lib/includes/gnutls/compat.h        |   10 -
 lib/includes/gnutls/gnutls.h.in     |    3 +
 lib/includes/gnutls/x509.h          |   18 ++-
 lib/libgnutls.map                   |    5 +-
 lib/nettle/cipher.c                 |    3 +
 lib/x509/common.c                   |   37 ++++
 lib/x509/common.h                   |   11 +-
 lib/x509/crq.c                      |   15 ++-
 lib/x509/privkey.c                  |   39 ----
 lib/x509/verify-high.c              |  190 ++++++++++++++++--
 lib/x509/verify.c                   |  368 +++++------------------------------
 lib/x509/x509.c                     |   32 +---
 lib/x509/x509_int.h                 |   15 +-
 src/common.c                        |   22 ++-
 tests/Makefile.am                   |    2 +-
 tests/{x509cert.c => x509cert-tl.c} |   76 +++++---
 32 files changed, 1084 insertions(+), 577 deletions(-)
 copy tests/{x509cert.c => x509cert-tl.c} (79%)

diff --git a/NEWS b/NEWS
index 4acf21b..be3e7ff 100644
--- a/NEWS
+++ b/NEWS
@@ -5,12 +5,34 @@ See the end for copying conditions.
 
 * Version 2.99.3 (unreleased)
 
+** libgnutls: Added SUITEB128 and SUITEB192 priority
+strings to enable the NSA SuiteB cryptography ciphersuites.
+
+** libgnutls: Added gnutls_pubkey_verify_data2() that will
+verify data provided the signature algorithm.
+
+** libgnutls: Simplified the handling of handshake messages to 
+be hashed. Instead of hashing during the handshake process we now 
+keep the data until handshake is over and hash them on request. 
+This uses more memory but eliminates issues with TLS 1.2 and 
+simplifies code.
+
 ** libgnutls: Added AES-GCM optimizations using the PCLMULQDQ
 instruction. Uses Andy Polyakov's assembly code.
 
+** libgnutls: Added gnutls_x509_trust_list_add_named_crt() and
+gnutls_x509_trust_list_verify_named_crt() that allow having a
+list of certificates in the trusted list that will be associated
+with a name (e.g. server name) and will not be used as CAs.
+
 ** libgnutls: Added ECDHE-PSK ciphersuites for TLS (RFC 5489).
 
 ** API and ABI modifications:
+gnutls_pubkey_verify_data2: ADDED
+gnutls_ecc_curve_get: ADDED
+gnutls_x509_trust_list_add_named_crt: ADDED
+gnutls_x509_trust_list_verify_named_crt: ADDED
+gnutls_x509_privkey_verify_data: REMOVED
 gnutls_crypto_bigint_register: REMOVED
 gnutls_crypto_cipher_register: REMOVED
 gnutls_crypto_digest_register: REMOVED
@@ -21,7 +43,7 @@ gnutls_crypto_single_cipher_register: REMOVED
 gnutls_crypto_single_digest_register: REMOVED
 gnutls_crypto_single_mac_register: REMOVED
 GNUTLS_KX_ECDHE_PSK: New key exchange method
-
+GNUTLS_VERIFY_DISABLE_CRL_CHECKS: New certificate verification flag.
 
 * Version 2.99.2 (released 2011-05-26)
 
diff --git a/doc/cha-cert-auth.texi b/doc/cha-cert-auth.texi
index c64e61b..a913233 100644
--- a/doc/cha-cert-auth.texi
+++ b/doc/cha-cert-auth.texi
@@ -147,6 +147,10 @@ Deinitializes the list.
 @item @ref{gnutls_x509_trust_list_add_cas}:
 Adds certificate authorities to the list.
 
address@hidden @ref{gnutls_x509_trust_list_add_named_crt}:
+Adds trusted certificates for an entity identified
+by a name.
+
 @item @ref{gnutls_x509_trust_list_add_crls}:
 Adds certificate revocation lists.
 
@@ -155,15 +159,24 @@ Verifies a certificate chain using the previously setup 
trusted
 list. A callback can be specified that will provide information
 about the verification procedure (and detailed reasons of failure).
 
address@hidden @ref{gnutls_x509_trust_list_verify_named_crt}:
+Does verification of the certificate by looking for a matching one
+in the named certificates. A callback can be specified that will provide 
information
+about the verification procedure (and detailed reasons of failure).
+
 @end table
 
 The verification function will verify a given certificate chain against a list 
of certificate
 authorities and certificate revocation lists, and output
 a bitwise OR of elements of the @code{gnutls_certificate_status_t} 
-enumeration.  A detailed description of these elements can be found 
-in figure below.  An example of these functions in use can be found
+enumeration. It is also possible to have a set of certificates that
+are trusted for a particular server but not to authorize other certificates.
+This purpose is served by the functions 
@ref{gnutls_x509_trust_list_add_named_crt} and 
@ref{gnutls_x509_trust_list_verify_named_crt}.
+A detailed description of these elements can be found 
+in figure below. An example of these functions in use can be found
 in @ref{ex:verify2}.
 
+
 When operating in the context of a TLS session, the trusted certificate
 authority list has been set via the
 @ref{gnutls_certificate_set_x509_trust_file} and 
@ref{gnutls_certificate_set_x509_crl_file},
@@ -217,7 +230,11 @@ flag should normaly be disabled, unless you know what this 
means.
 Allow only trusted CA certificates that have version 1.  This is
 safer than GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT, and should be
 used instead. That way only signers in your trusted list will be
-allowed to have certificates of version 1.
+allowed to have certificates of version 1. This is the default.
+
address@hidden GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT:
+Do not allow trusted version 1 CA certificates.  This option is to be used
+in order consider all V1 certificates as deprecated.
 
 @item GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT:
 Allow CA certificates that have version 1 (both root and
@@ -234,6 +251,14 @@ Allow certificates to be signed using the old MD2 
algorithm.
 
 @item GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5:
 Allow certificates to be signed using the broken MD5 algorithm.
+
address@hidden GNUTLS_VERIFY_DISABLE_TIME_CHECKS:
+Disable checking of activation
+and expiration validity periods of certificate chains. Don't set
+this unless you understand the security implications.
+
address@hidden GNUTLS_VERIFY_DISABLE_CRL_CHECKS:
+Disables checking for validity using certificate revocation lists.
 @end table
 
 Although the verification of a certificate path indicates that the
diff --git a/doc/cha-intro-tls.texi b/doc/cha-intro-tls.texi
index 7646992..2f65e65 100644
--- a/doc/cha-intro-tls.texi
+++ b/doc/cha-intro-tls.texi
@@ -445,12 +445,20 @@ included as a fallback only.  The ciphers are sorted by 
security
 margin.
 
 @item SECURE128: 
-Means all "secure" ciphersuites with ciphers up to 128
-bits, sorted by security margin.
+Means all "secure" ciphersuites of security level 128-bit
+or more.
 
address@hidden SECURE256:
-Means all "secure" ciphersuites including the 256 bit
-ciphers, sorted by security margin.
address@hidden SECURE192:
+Means all "secure" ciphersuites of security level 192-bit
+or more.
+
address@hidden SUITEB128: 
+Means all the NSA Suite B cryptography (RFC5430) ciphersuites
+with an 128 bit security level.
+
address@hidden SUITEB192:
+Means all the NSA Suite B cryptography (RFC5430) ciphersuites
+with an 192 bit security level.
 
 @item EXPORT:
 Means all ciphersuites are enabled, including the
diff --git a/doc/examples/ex-verify.c b/doc/examples/ex-verify.c
index 1cc4f3c..5d34921 100644
--- a/doc/examples/ex-verify.c
+++ b/doc/examples/ex-verify.c
@@ -6,6 +6,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 
@@ -60,8 +61,16 @@ verify_certificate_chain (const char *hostname,
       gnutls_x509_crt_import (cert[i], &cert_chain[i], GNUTLS_X509_FMT_DER);
     }
 
-  gnutls_x509_trust_list_verify_crt(tlist, cert, cert_chain_length, 0, 
-    &output, print_details_func);
+  gnutls_x509_trust_list_verify_named_crt(tlist, cert[0], hostname, 
strlen(hostname), 
+    GNUTLS_VERIFY_DISABLE_CRL_CHECKS, &output, print_details_func);
+
+  /* if this certificate is not explicitly trusted verify against CAs 
+   */
+  if (output != 0)
+    {
+      gnutls_x509_trust_list_verify_crt(tlist, cert, cert_chain_length, 0, 
+        &output, print_details_func);
+    }
 
   if (output & GNUTLS_CERT_INVALID)
     {
diff --git a/lib/abstract_int.h b/lib/abstract_int.h
index 1060679..06318d3 100644
--- a/lib/abstract_int.h
+++ b/lib/abstract_int.h
@@ -14,4 +14,20 @@ int
 _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
                                  gnutls_pk_params_st * params);
 
+int pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk, 
+                       const gnutls_datum_t * hash,
+                       const gnutls_datum_t * signature,
+                       gnutls_pk_params_st * issuer_params);
+
+int pubkey_verify_data (gnutls_pk_algorithm_t pk,
+                        gnutls_digest_algorithm_t algo,
+                       const gnutls_datum_t * data,
+                       const gnutls_datum_t * signature,
+                       gnutls_pk_params_st * issuer_params);
+
+
+
+gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, 
+  const gnutls_pk_params_st* params, int* hash_len);
+
 #endif
diff --git a/lib/accelerated/intel/aes-gcm-x86.c 
b/lib/accelerated/intel/aes-gcm-x86.c
index 22bbac9..2d5329b 100644
--- a/lib/accelerated/intel/aes-gcm-x86.c
+++ b/lib/accelerated/intel/aes-gcm-x86.c
@@ -79,7 +79,8 @@ aes_gcm_cipher_init (gnutls_cipher_algorithm_t algorithm, 
void **_ctx)
   struct aes_gcm_ctx *ctx;
 
   /* we use key size to distinguish */
-  if (algorithm != GNUTLS_CIPHER_AES_128_GCM)
+  if (algorithm != GNUTLS_CIPHER_AES_128_GCM &&
+      algorithm != GNUTLS_CIPHER_AES_256_GCM)
     return GNUTLS_E_INVALID_REQUEST;
 
   *_ctx = gnutls_calloc (1, sizeof (struct aes_gcm_ctx));
diff --git a/lib/accelerated/intel/aes-x86.c b/lib/accelerated/intel/aes-x86.c
index 02c4549..a04ffd4 100644
--- a/lib/accelerated/intel/aes-x86.c
+++ b/lib/accelerated/intel/aes-x86.c
@@ -205,6 +205,14 @@ register_x86_crypto (void)
             {
               gnutls_assert ();
             }
+
+          ret =
+            gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM,
+                                                  80, &aes_gcm_struct);
+          if (ret < 0)
+            {
+              gnutls_assert ();
+            }
         }
     }
 
diff --git a/lib/algorithms/ciphersuites.c b/lib/algorithms/ciphersuites.c
index 773d30f..c371733 100644
--- a/lib/algorithms/ciphersuites.c
+++ b/lib/algorithms/ciphersuites.c
@@ -38,10 +38,8 @@ _gnutls_qsort (gnutls_session_t session, void *_base, size_t 
nmemb,
 /* Cipher SUITES */
 #define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, 
mac_algorithm, min_version, max_version, dtls ) \
        { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, 
min_version, max_version, dtls, GNUTLS_MAC_SHA256}
-#if 0
 #define GNUTLS_CIPHER_SUITE_ENTRY_PRF( name, block_algorithm, kx_algorithm, 
mac_algorithm, min_version, max_version, dtls, prf ) \
        { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, 
min_version, max_version, dtls, prf}
-#endif
 
 typedef struct
 {
@@ -220,6 +218,12 @@ typedef struct
 /* ECC with AES-GCM */
 #define GNUTLS_ECDHE_ECDSA_AES_128_GCM_SHA256   {0xC0,0x2B}
 #define GNUTLS_ECDHE_RSA_AES_128_GCM_SHA256     {0xC0,0x2F}
+#define GNUTLS_ECDHE_RSA_AES_256_GCM_SHA384     {0xC0,0x30}
+
+/* SuiteB */
+#define GNUTLS_ECDHE_ECDSA_AES_256_GCM_SHA384   {0xC0,0x2E}
+#define GNUTLS_ECDHE_ECDSA_AES_256_CBC_SHA384   {0xC0,0x24}
+
 
 /* ECC with PSK */
 #define GNUTLS_ECDHE_PSK_3DES_EDE_CBC_SHA { 0xC0, 0x34 }
@@ -612,18 +616,31 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = {
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ECDHE_PSK,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_0,
                              GNUTLS_VERSION_MAX, 1),
-  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_AES_256_CBC_SHA384,
+  GNUTLS_CIPHER_SUITE_ENTRY_PRF (GNUTLS_ECDHE_PSK_AES_256_CBC_SHA384,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ECDHE_PSK,
                              GNUTLS_MAC_SHA384, GNUTLS_TLS1_0,
-                             GNUTLS_VERSION_MAX, 1),
+                             GNUTLS_VERSION_MAX, 1, GNUTLS_MAC_SHA384),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_NULL_SHA256,
                              GNUTLS_CIPHER_NULL, GNUTLS_KX_ECDHE_PSK,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_0,
                              GNUTLS_VERSION_MAX, 1),
-  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_NULL_SHA384,
+  GNUTLS_CIPHER_SUITE_ENTRY_PRF (GNUTLS_ECDHE_PSK_NULL_SHA384,
                              GNUTLS_CIPHER_NULL, GNUTLS_KX_ECDHE_PSK,
                              GNUTLS_MAC_SHA384, GNUTLS_TLS1_0,
-                             GNUTLS_VERSION_MAX, 1),
+                             GNUTLS_VERSION_MAX, 1, GNUTLS_MAC_SHA384),
+  GNUTLS_CIPHER_SUITE_ENTRY_PRF(GNUTLS_ECDHE_ECDSA_AES_256_GCM_SHA384,
+                                GNUTLS_CIPHER_AES_256_GCM, 
GNUTLS_KX_ECDHE_ECDSA,
+                                GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+                                GNUTLS_VERSION_MAX, 1, GNUTLS_DIG_SHA384),
+  GNUTLS_CIPHER_SUITE_ENTRY_PRF(GNUTLS_ECDHE_RSA_AES_256_GCM_SHA384,
+                                GNUTLS_CIPHER_AES_256_GCM, GNUTLS_KX_ECDHE_RSA,
+                                GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+                                GNUTLS_VERSION_MAX, 1, GNUTLS_DIG_SHA384),
+  GNUTLS_CIPHER_SUITE_ENTRY_PRF(GNUTLS_ECDHE_ECDSA_AES_256_CBC_SHA384,
+                                GNUTLS_CIPHER_AES_256_CBC, 
GNUTLS_KX_ECDHE_ECDSA,
+                                GNUTLS_MAC_SHA384, GNUTLS_TLS1_2,
+                                GNUTLS_VERSION_MAX, 1, GNUTLS_DIG_SHA384),
+
   {0, {{0, 0}}, 0, 0, 0, 0, 0, 0}
 };
 
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 9cb6685..418d8d8 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -117,7 +117,7 @@ int
 gnutls_certificate_get_issuer (gnutls_certificate_credentials_t sc,
   gnutls_x509_crt_t cert, gnutls_x509_crt_t* issuer, unsigned int flags)
 {
-  return gnutls_trust_list_get_issuer(sc->tlist, cert, issuer, flags);
+  return gnutls_x509_trust_list_get_issuer(sc->tlist, cert, issuer, flags);
 }
 
 /**
diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h
index 5a06024..12af39c 100644
--- a/lib/gnutls_hash_int.h
+++ b/lib/gnutls_hash_int.h
@@ -173,4 +173,13 @@ int _gnutls_mac_deinit_ssl3_handshake (digest_hd_st * 
handle, void *digest,
 
 int _gnutls_hash_copy (digest_hd_st * dst_handle, digest_hd_st * src_handle);
 
+inline static int IS_SHA(gnutls_digest_algorithm_t algo)
+{
+  if (algo == GNUTLS_DIG_SHA1 || algo == GNUTLS_DIG_SHA224 ||
+      algo == GNUTLS_DIG_SHA256 || algo == GNUTLS_DIG_SHA384 ||
+      algo == GNUTLS_DIG_SHA512)
+      return 1;
+  return 0;
+}
+
 #endif /* GNUTLS_HASH_INT_H */
diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c
index 73138b1..fb04232 100644
--- a/lib/gnutls_priority.c
+++ b/lib/gnutls_priority.c
@@ -230,7 +230,17 @@ static const int supported_ecc_secure128[] = {
   0
 };
 
-static const int supported_ecc_secure256[] = {
+static const int supported_ecc_suiteb128[] = {
+  GNUTLS_ECC_CURVE_SECP256R1,
+  0
+};
+
+static const int supported_ecc_suiteb192[] = {
+  GNUTLS_ECC_CURVE_SECP384R1,
+  0
+};
+
+static const int supported_ecc_secure192[] = {
   GNUTLS_ECC_CURVE_SECP521R1,
   0
 };
@@ -244,15 +254,22 @@ static const int protocol_priority[] = {
   0
 };
 
+static const int protocol_priority_suiteb[] = {
+  GNUTLS_TLS1_2,
+  0
+};
+
 static const int kx_priority_performance[] = {
   GNUTLS_KX_RSA,
   GNUTLS_KX_ECDHE_ECDSA,
   GNUTLS_KX_ECDHE_RSA,
   GNUTLS_KX_DHE_RSA,
   GNUTLS_KX_DHE_DSS,
-  /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
-   * GNUTLS_KX_RSA_EXPORT: Deprecated, don't add!
-   */
+  0
+};
+
+static const int kx_priority_suiteb[] = {
+  GNUTLS_KX_ECDHE_ECDSA,
   0
 };
 
@@ -283,33 +300,34 @@ static const int kx_priority_secure[] = {
 
 static const int cipher_priority_performance[] = {
   GNUTLS_CIPHER_ARCFOUR_128,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_128_CBC,
-#endif
   GNUTLS_CIPHER_AES_128_CBC,
   GNUTLS_CIPHER_3DES_CBC,
   GNUTLS_CIPHER_AES_256_CBC,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_256_CBC,
-#endif
-#ifdef NETTLE_GCM
   GNUTLS_CIPHER_AES_128_GCM,
-#endif
+  GNUTLS_CIPHER_AES_256_GCM,
+  0
+};
+
+static const int cipher_priority_suiteb128[] = {
+  GNUTLS_CIPHER_AES_128_GCM,
+  GNUTLS_CIPHER_AES_128_CBC,
+  0
+};
+
+static const int cipher_priority_suiteb192[] = {
+  GNUTLS_CIPHER_AES_256_GCM,
+  GNUTLS_CIPHER_AES_256_CBC,
   0
 };
 
 static const int cipher_priority_normal[] = {
   GNUTLS_CIPHER_AES_128_CBC,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_128_CBC,
-#endif
   GNUTLS_CIPHER_AES_256_CBC,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_256_CBC,
-#endif
-#ifdef NETTLE_GCM
   GNUTLS_CIPHER_AES_128_GCM,
-#endif
   GNUTLS_CIPHER_3DES_CBC,
   GNUTLS_CIPHER_ARCFOUR_128,
   0
@@ -317,29 +335,20 @@ static const int cipher_priority_normal[] = {
 
 static const int cipher_priority_secure128[] = {
   GNUTLS_CIPHER_AES_128_CBC,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_128_CBC,
-#endif
-#ifdef NETTLE_GCM
   GNUTLS_CIPHER_AES_128_GCM,
-#endif
   GNUTLS_CIPHER_3DES_CBC,
   0
 };
 
 
-static const int cipher_priority_secure256[] = {
+static const int cipher_priority_secure192[] = {
   GNUTLS_CIPHER_AES_256_CBC,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_256_CBC,
-#endif
   GNUTLS_CIPHER_AES_128_CBC,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_128_CBC,
-#endif
-#ifdef NETTLE_GCM
   GNUTLS_CIPHER_AES_128_GCM,
-#endif
+  GNUTLS_CIPHER_AES_256_GCM,
   GNUTLS_CIPHER_3DES_CBC,
   0
 };
@@ -348,10 +357,8 @@ static const int cipher_priority_secure256[] = {
 static const int cipher_priority_export[] = {
   GNUTLS_CIPHER_AES_128_CBC,
   GNUTLS_CIPHER_AES_256_CBC,
-#ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_CAMELLIA_128_CBC,
   GNUTLS_CIPHER_CAMELLIA_256_CBC,
-#endif
   GNUTLS_CIPHER_AES_128_GCM,
   GNUTLS_CIPHER_3DES_CBC,
   GNUTLS_CIPHER_ARCFOUR_128,
@@ -386,14 +393,28 @@ static const int sign_priority_default[] = {
   0
 };
 
+static const int sign_priority_suiteb128[] = {
+  GNUTLS_SIGN_ECDSA_SHA256,
+  0
+};
+
+static const int sign_priority_suiteb192[] = {
+  GNUTLS_SIGN_ECDSA_SHA384,
+  0
+};
+
 static const int sign_priority_secure128[] = {
   GNUTLS_SIGN_RSA_SHA256,
   GNUTLS_SIGN_DSA_SHA256,
   GNUTLS_SIGN_ECDSA_SHA256,
+  GNUTLS_SIGN_RSA_SHA384,
+  GNUTLS_SIGN_ECDSA_SHA384,
+  GNUTLS_SIGN_RSA_SHA512,
+  GNUTLS_SIGN_ECDSA_SHA512,
   0
 };
 
-static const int sign_priority_secure256[] = {
+static const int sign_priority_secure192[] = {
   GNUTLS_SIGN_RSA_SHA512,
   GNUTLS_SIGN_ECDSA_SHA512,
   0
@@ -402,16 +423,35 @@ static const int sign_priority_secure256[] = {
 static const int mac_priority_normal[] = {
   GNUTLS_MAC_SHA1,
   GNUTLS_MAC_SHA256,
+  GNUTLS_MAC_SHA384,
   GNUTLS_MAC_AEAD,
   GNUTLS_MAC_MD5,
   0
 };
 
+static const int mac_priority_suiteb128[] = {
+  GNUTLS_MAC_SHA256,
+  GNUTLS_MAC_SHA384,
+  GNUTLS_MAC_AEAD,
+  0
+};
+
+static const int mac_priority_suiteb192[] = {
+  GNUTLS_MAC_SHA384,
+  GNUTLS_MAC_AEAD,
+  0
+};
 
-static const int mac_priority_secure[] = {
+static const int mac_priority_secure128[] = {
   GNUTLS_MAC_SHA256,
+  GNUTLS_MAC_SHA384,
+  GNUTLS_MAC_AEAD,
+  0
+};
+
+static const int mac_priority_secure192[] = {
+  GNUTLS_MAC_SHA384,
   GNUTLS_MAC_AEAD,
-  GNUTLS_MAC_SHA1,
   0
 };
 
@@ -526,11 +566,17 @@ gnutls_priority_set (gnutls_session_t session, 
gnutls_priority_t priority)
  * included as a fallback only.  The ciphers are sorted by security
  * margin.
  *
- * "SECURE128" means all "secure" ciphersuites with ciphers up to 128
- * bits, sorted by security margin.
+ * "SECURE128" means all "secure" ciphersuites of security level 128-bit
+ * or more.
+ *
+ * "SECURE192" means all "secure" ciphersuites of security level 192-bit
+ * or more.
  *
- * "SECURE256" means all "secure" ciphersuites including the 256 bit
- * ciphers, sorted by security margin.
+ * "SUITEB128" means all the NSA SuiteB ciphersuites with security level
+ * of 128.
+ *
+ * "SUITEB192" means all the NSA SuiteB ciphersuites with security level
+ * of 192.
  *
  * "EXPORT" means all ciphersuites are enabled, including the
  * low-security 40 bit ciphers.
@@ -638,31 +684,54 @@ gnutls_priority_init (gnutls_priority_t * priority_cache,
           _set_priority (&(*priority_cache)->supported_ecc, 
supported_ecc_normal);
         }
       else if (strcasecmp (broken_list[i], "SECURE256") == 0
-               || strcasecmp (broken_list[i], "SECURE") == 0)
+               || strcasecmp (broken_list[i], "SECURE192") == 0)
         {
           _set_priority (&(*priority_cache)->cipher,
-                         cipher_priority_secure256);
+                         cipher_priority_secure192);
           _set_priority (&(*priority_cache)->kx, kx_priority_secure);
-          _set_priority (&(*priority_cache)->mac, mac_priority_secure);
+          _set_priority (&(*priority_cache)->mac, mac_priority_secure192);
           _set_priority (&(*priority_cache)->sign_algo,
-                         sign_priority_secure256);
-          _set_priority (&(*priority_cache)->supported_ecc, 
supported_ecc_secure256);
+                         sign_priority_secure192);
+          _set_priority (&(*priority_cache)->supported_ecc, 
supported_ecc_secure192);
         }
-      else if (strcasecmp (broken_list[i], "SECURE128") == 0)
+      else if (strcasecmp (broken_list[i], "SECURE128") == 0
+               || strcasecmp (broken_list[i], "SECURE") == 0)
         {
           _set_priority (&(*priority_cache)->cipher,
                          cipher_priority_secure128);
           _set_priority (&(*priority_cache)->kx, kx_priority_secure);
-          _set_priority (&(*priority_cache)->mac, mac_priority_secure);
+          _set_priority (&(*priority_cache)->mac, mac_priority_secure128);
           _set_priority (&(*priority_cache)->sign_algo,
                          sign_priority_secure128);
           _set_priority (&(*priority_cache)->supported_ecc, 
supported_ecc_secure128);
         }
+      else if (strcasecmp (broken_list[i], "SUITEB128") == 0)
+        {
+          _set_priority (&(*priority_cache)->protocol, 
protocol_priority_suiteb);
+          _set_priority (&(*priority_cache)->cipher,
+                         cipher_priority_suiteb128);
+          _set_priority (&(*priority_cache)->kx, kx_priority_suiteb);
+          _set_priority (&(*priority_cache)->mac, mac_priority_suiteb128);
+          _set_priority (&(*priority_cache)->sign_algo,
+                         sign_priority_suiteb128);
+          _set_priority (&(*priority_cache)->supported_ecc, 
supported_ecc_suiteb128);
+        }
+      else if (strcasecmp (broken_list[i], "SUITEB192") == 0)
+        {
+          _set_priority (&(*priority_cache)->protocol, 
protocol_priority_suiteb);
+          _set_priority (&(*priority_cache)->cipher,
+                         cipher_priority_suiteb192);
+          _set_priority (&(*priority_cache)->kx, kx_priority_suiteb);
+          _set_priority (&(*priority_cache)->mac, mac_priority_suiteb192);
+          _set_priority (&(*priority_cache)->sign_algo,
+                         sign_priority_suiteb192);
+          _set_priority (&(*priority_cache)->supported_ecc, 
supported_ecc_suiteb192);
+        }
       else if (strcasecmp (broken_list[i], "EXPORT") == 0)
         {
           _set_priority (&(*priority_cache)->cipher, cipher_priority_export);
           _set_priority (&(*priority_cache)->kx, kx_priority_export);
-          _set_priority (&(*priority_cache)->mac, mac_priority_secure);
+          _set_priority (&(*priority_cache)->mac, mac_priority_secure128);
           _set_priority (&(*priority_cache)->sign_algo,
                          sign_priority_default);
           _set_priority (&(*priority_cache)->supported_ecc, 
supported_ecc_normal);
@@ -779,7 +848,7 @@ gnutls_priority_init (gnutls_priority_t * priority_cache,
           else if (strncasecmp (&broken_list[i][1], "MAC-ALL", 7) == 0)
             {
                   bulk_fn (&(*priority_cache)->mac,
-                                mac_priority_secure);
+                                mac_priority_secure128);
             }
           else if (strncasecmp (&broken_list[i][1], "CIPHER-ALL", 10) == 0)
             {
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index 5dddae2..6352bbb 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -30,6 +30,7 @@
 #include <gnutls_datum.h>
 #include <pkcs11_int.h>
 #include <gnutls/abstract.h>
+#include <gnutls_sig.h>
 #include <gnutls_pk.h>
 #include <x509_int.h>
 #include <openpgp/openpgp_int.h>
@@ -1119,7 +1120,49 @@ gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, 
unsigned int flags,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = pubkey_verify_sig( data, NULL, signature, pubkey->pk_algorithm, 
+  ret = pubkey_verify_data( pubkey->pk_algorithm, GNUTLS_DIG_UNKNOWN, data, 
signature,
+    &pubkey->params);
+  if (ret < 0)
+    {
+      gnutls_assert();
+    }
+
+  return ret;
+}
+
+/**
+ * gnutls_pubkey_verify_data2:
+ * @pubkey: Holds the public key
+ * @algo: The signature algorithm used
+ * @flags: should be 0 for now
+ * @data: holds the signed data
+ * @signature: contains the signature
+ *
+ * This function will verify the given signed data, using the
+ * parameters from the certificate.
+ *
+ * Returns: In case of a verification failure
+ *   %GNUTLS_E_PK_SIG_VERIFY_FAILED is returned, and a positive code
+ *   on success.
+ *
+ * Since: 2.12.0
+ **/
+int
+gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey, 
+                           gnutls_sign_algorithm_t algo,
+                           unsigned int flags,
+                          const gnutls_datum_t * data,
+                          const gnutls_datum_t * signature)
+{
+  int ret;
+
+  if (pubkey == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = pubkey_verify_data( pubkey->pk_algorithm, 
_gnutls_sign_get_hash_algorithm(algo), data, signature,
     &pubkey->params);
   if (ret < 0)
     {
@@ -1158,7 +1201,7 @@ gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned 
int flags,
     return _gnutls_rsa_verify (hash, signature, &key->params, 1);
   else
     {
-      return pubkey_verify_sig (NULL, hash, signature, key->pk_algorithm,
+      return pubkey_verify_hashed_data (key->pk_algorithm, hash, signature,
                        &key->params);
     }
 }
@@ -1250,3 +1293,266 @@ _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
 {
   return _gnutls_pk_params_copy(params, &key->params);
 }
+
+/* if hash==MD5 then we do RSA-MD5
+ * if hash==SHA then we do RSA-SHA
+ * params[0] is modulus
+ * params[1] is public key
+ */
+static int
+_pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
+                       const gnutls_datum_t * prehash,
+                       const gnutls_datum_t * signature, 
+                       gnutls_pk_params_st * params)
+{
+  gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
+  int ret;
+  opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE], *cmp;
+  int digest_size;
+  digest_hd_st hd;
+  gnutls_datum_t decrypted;
+
+  ret =
+    _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, 1);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  /* decrypted is a BER encoded data of type DigestInfo
+   */
+
+  digest_size = sizeof (digest);
+  if ((ret =
+       decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) != 0)
+    {
+      gnutls_assert ();
+      _gnutls_free_datum (&decrypted);
+      return ret;
+    }
+
+  _gnutls_free_datum (&decrypted);
+
+  if (digest_size != _gnutls_hash_get_algo_len (hash))
+    {
+      gnutls_assert ();
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
+
+  if (prehash && prehash->data && prehash->size == digest_size)
+    {
+      cmp = prehash->data;
+    }
+  else
+    {
+      if (!text)
+        {
+          gnutls_assert ();
+          return GNUTLS_E_INVALID_REQUEST;
+        }
+
+      ret = _gnutls_hash_init (&hd, hash);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+          return ret;
+        }
+
+      _gnutls_hash (&hd, text->data, text->size);
+      _gnutls_hash_deinit (&hd, md);
+
+      cmp = md;
+    }
+
+  if (memcmp (cmp, digest, digest_size) != 0)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+    }
+
+  return 0;
+}
+
+/* Hashes input data and verifies a signature.
+ */
+static int
+dsa_verify_hashed_data (const gnutls_datum_t * hash,
+                const gnutls_datum_t * signature,
+                gnutls_pk_algorithm_t pk,
+                gnutls_pk_params_st* params)
+{
+  gnutls_datum_t digest;
+  gnutls_digest_algorithm_t algo;
+  int hash_len;
+
+  algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len);
+
+  /* SHA1 or better allowed */
+  if (!hash->data || hash->size < hash_len)
+    {
+      gnutls_assert();
+      _gnutls_debug_log("Hash size (%d) does not correspond to hash %s(%d) or 
better.\n", (int)hash->size, gnutls_mac_get_name(algo), hash_len);
+          
+      if (hash->size != 20) /* SHA1 is allowed */
+        return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
+    }
+
+  digest.data = hash->data;
+  digest.size = hash->size;
+
+  return _gnutls_pk_verify (pk, &digest, signature, params);
+}
+
+static int
+dsa_verify_data (gnutls_pk_algorithm_t pk,
+                 gnutls_digest_algorithm_t algo,
+                 const gnutls_datum_t * data,
+                 const gnutls_datum_t * signature,
+                 gnutls_pk_params_st* params)
+{
+  int ret;
+  opaque _digest[MAX_HASH_SIZE];
+  gnutls_datum_t digest;
+  digest_hd_st hd;
+
+  if (algo == GNUTLS_DIG_UNKNOWN)
+    algo = _gnutls_dsa_q_to_hash (pk, params, NULL);
+
+  ret = _gnutls_hash_init (&hd, algo);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  _gnutls_hash (&hd, data->data, data->size);
+  _gnutls_hash_deinit (&hd, _digest);
+
+  digest.data = _digest;
+  digest.size = _gnutls_hash_get_algo_len(algo);
+
+  return _gnutls_pk_verify (pk, &digest, signature, params);
+}
+
+/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
+ * not verified, or 1 otherwise.
+ */
+int
+pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk,
+                   const gnutls_datum_t * hash,
+                   const gnutls_datum_t * signature,
+                   gnutls_pk_params_st * issuer_params)
+{
+
+  switch (pk)
+    {
+    case GNUTLS_PK_RSA:
+
+      if (_pkcs1_rsa_verify_sig
+          (NULL, hash, signature, issuer_params) != 0)
+        {
+          gnutls_assert ();
+          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+        }
+
+      return 1;
+      break;
+
+    case GNUTLS_PK_ECC:
+    case GNUTLS_PK_DSA:
+      if (dsa_verify_hashed_data(hash, signature, pk, issuer_params) != 0)
+        {
+          gnutls_assert ();
+          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+        }
+
+      return 1;
+      break;
+    default:
+      gnutls_assert ();
+      return GNUTLS_E_INTERNAL_ERROR;
+
+    }
+}
+
+/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
+ * not verified, or 1 otherwise.
+ */
+int
+pubkey_verify_data (gnutls_pk_algorithm_t pk,
+                    gnutls_digest_algorithm_t algo,
+                    const gnutls_datum_t * data,
+                    const gnutls_datum_t * signature,
+                    gnutls_pk_params_st * issuer_params)
+{
+
+  switch (pk)
+    {
+    case GNUTLS_PK_RSA:
+
+      if (_pkcs1_rsa_verify_sig
+          (data, NULL, signature, issuer_params) != 0)
+        {
+          gnutls_assert ();
+          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+        }
+
+      return 1;
+      break;
+
+    case GNUTLS_PK_ECC:
+    case GNUTLS_PK_DSA:
+      if (dsa_verify_data(pk, algo, data, signature, issuer_params) != 0)
+        {
+          gnutls_assert ();
+          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+        }
+
+      return 1;
+      break;
+    default:
+      gnutls_assert ();
+      return GNUTLS_E_INTERNAL_ERROR;
+
+    }
+}
+
+gnutls_digest_algorithm_t
+_gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* 
params, int* hash_len)
+{
+  int bits = 0;
+  
+  if (algo == GNUTLS_PK_DSA)
+    bits = _gnutls_mpi_get_nbits (params->params[1]);
+  else if (algo == GNUTLS_PK_ECC)
+    bits = gnutls_ecc_curve_get_size(params->flags)*8;
+
+  if (bits <= 160)
+    {
+      if (hash_len) *hash_len = 20;
+      return GNUTLS_DIG_SHA1;
+    }
+  else if (bits <= 192)
+    {
+      if (hash_len) *hash_len = 24;
+      return GNUTLS_DIG_SHA256;
+    }
+  else if (bits <= 224)
+    {
+      if (hash_len) *hash_len = 28;
+      return GNUTLS_DIG_SHA256;
+    }
+  else if (bits <= 256)
+    {
+      if (hash_len) *hash_len = 32;
+      return GNUTLS_DIG_SHA256;
+    }
+  else if (bits <= 384)
+    {
+      if (hash_len) *hash_len = 48;
+      return GNUTLS_DIG_SHA384;
+    }
+  else
+    {
+      if (hash_len) *hash_len = 64;
+      return GNUTLS_DIG_SHA512;
+    }
+}
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 17e8cb4..db8a071 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -48,6 +48,11 @@ sign_tls_hash (gnutls_session_t session, 
gnutls_digest_algorithm_t hash_algo,
                   const gnutls_datum_t * hash_concat,
                   gnutls_datum_t * signature);
 
+static int
+encode_ber_digest_info (gnutls_digest_algorithm_t hash,
+                        const gnutls_datum_t * digest,
+                        gnutls_datum_t * output);
+
 /* While this is currently equal to the length of RSA/SHA512
  * signature, it should also be sufficient for DSS signature and any
  * other RSA signatures including one with the old MD5/SHA1-combined
@@ -136,8 +141,7 @@ _gnutls_handshake_sign_data (gnutls_session_t session, 
gnutls_pcert_st* cert,
     case GNUTLS_PK_ECC:
       _gnutls_hash_deinit (&td_sha, concat);
 
-      if ((hash_algo != GNUTLS_DIG_SHA1) && (hash_algo != GNUTLS_DIG_SHA224)
-          && (hash_algo != GNUTLS_DIG_SHA256))
+      if (!IS_SHA(hash_algo))
         {
           gnutls_assert ();
           return GNUTLS_E_INTERNAL_ERROR;
@@ -733,6 +737,120 @@ cleanup:
   return ret;
 }
 
+
+/* 
+ * This function will do RSA PKCS #1 1.5 encoding
+ * on the given digest. The given digest must be allocated
+ * and will be freed if replacement is required.
+ */
+int
+pk_prepare_hash (gnutls_pk_algorithm_t pk,
+                 gnutls_digest_algorithm_t hash, gnutls_datum_t * digest)
+{
+  int ret;
+  gnutls_datum_t old_digest = { digest->data, digest->size };
+
+  switch (pk)
+    {
+    case GNUTLS_PK_RSA:
+      /* Encode the digest as a DigestInfo
+       */
+      if ((ret = encode_ber_digest_info (hash, &old_digest, digest)) != 0)
+        {
+          gnutls_assert ();
+          return ret;
+        }
+
+      _gnutls_free_datum (&old_digest);
+      break;
+    case GNUTLS_PK_DSA:
+    case GNUTLS_PK_ECC:
+      break;
+    default:
+      gnutls_assert ();
+      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+    }
+
+  return 0;
+}
+
+/* Reads the digest information.
+ * we use DER here, although we should use BER. It works fine
+ * anyway.
+ */
+int
+decode_ber_digest_info (const gnutls_datum_t * info,
+                        gnutls_mac_algorithm_t * hash,
+                        opaque * digest, int *digest_size)
+{
+  ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
+  int result;
+  char str[1024];
+  int len;
+
+  if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
+                                     "GNUTLS.DigestInfo",
+                                     &dinfo)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return _gnutls_asn2err (result);
+    }
+
+  len = sizeof (str) - 1;
+  result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return _gnutls_asn2err (result);
+    }
+
+  *hash = _gnutls_x509_oid2mac_algorithm (str);
+
+  if (*hash == GNUTLS_MAC_UNKNOWN)
+    {
+
+      _gnutls_debug_log ("verify.c: HASH OID: %s\n", str);
+
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return GNUTLS_E_UNKNOWN_ALGORITHM;
+    }
+
+  len = sizeof (str) - 1;
+  result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
+  /* To avoid permitting garbage in the parameters field, either the
+     parameters field is not present, or it contains 0x05 0x00. */
+  if (!(result == ASN1_ELEMENT_NOT_FOUND ||
+        (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
+         memcmp (str, ASN1_NULL, ASN1_NULL_SIZE) == 0)))
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
+
+  result = asn1_read_value (dinfo, "digest", digest, digest_size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return _gnutls_asn2err (result);
+    }
+
+  asn1_delete_structure (&dinfo);
+
+  return 0;
+}
+
 /* Writes the digest information and the digest in a DER encoded
  * structure. The digest info is allocated and stored into the info structure.
  */
@@ -819,39 +937,3 @@ encode_ber_digest_info (gnutls_digest_algorithm_t hash,
 
   return 0;
 }
-
-/* 
- * This function will do RSA PKCS #1 1.5 encoding
- * on the given digest. The given digest must be allocated
- * and will be freed if replacement is required.
- */
-int
-pk_prepare_hash (gnutls_pk_algorithm_t pk,
-                 gnutls_digest_algorithm_t hash, gnutls_datum_t * digest)
-{
-  int ret;
-  gnutls_datum_t old_digest = { digest->data, digest->size };
-
-  switch (pk)
-    {
-    case GNUTLS_PK_RSA:
-      /* Encode the digest as a DigestInfo
-       */
-      if ((ret = encode_ber_digest_info (hash, &old_digest, digest)) != 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-
-      _gnutls_free_datum (&old_digest);
-      break;
-    case GNUTLS_PK_DSA:
-    case GNUTLS_PK_ECC:
-      break;
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
-    }
-
-  return 0;
-}
diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h
index 3b6957a..e3865b9 100644
--- a/lib/gnutls_sig.h
+++ b/lib/gnutls_sig.h
@@ -67,4 +67,9 @@ _gnutls_privkey_sign_hash (gnutls_privkey_t key,
                            const gnutls_datum_t * hash,
                            gnutls_datum_t * signature);
 
+int
+decode_ber_digest_info (const gnutls_datum_t * info,
+                        gnutls_mac_algorithm_t * hash,
+                        opaque * digest, int *digest_size);
+
 #endif
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index 859ed14..3f664a3 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -815,7 +815,7 @@ _gnutls_cal_PRF_A (gnutls_mac_algorithm_t algorithm,
  * (used in the PRF function)
  */
 static int
-_gnutls_P_hash (gnutls_mac_algorithm_t algorithm,
+P_hash (gnutls_mac_algorithm_t algorithm,
                 const opaque * secret, int secret_size,
                 const opaque * seed, int seed_size,
                 int total_bytes, opaque * ret)
@@ -930,7 +930,8 @@ _gnutls_PRF (gnutls_session_t session,
   if (_gnutls_version_has_selectable_prf (ver))
     {
       result =
-        _gnutls_P_hash (GNUTLS_MAC_SHA256, secret, secret_size,
+        P_hash 
(_gnutls_cipher_suite_get_prf(&session->security_parameters.current_cipher_suite),
 
+                        secret, secret_size,
                         s_seed, s_seed_size, total_bytes, ret);
       if (result < 0)
         {
@@ -951,7 +952,7 @@ _gnutls_PRF (gnutls_session_t session,
         }
 
       result =
-        _gnutls_P_hash (GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size,
+        P_hash (GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size,
                         total_bytes, o1);
       if (result < 0)
         {
@@ -960,7 +961,7 @@ _gnutls_PRF (gnutls_session_t session,
         }
 
       result =
-        _gnutls_P_hash (GNUTLS_MAC_SHA1, s2, l_s, s_seed, s_seed_size,
+        P_hash (GNUTLS_MAC_SHA1, s2, l_s, s_seed, s_seed_size,
                         total_bytes, o2);
       if (result < 0)
         {
@@ -1387,3 +1388,18 @@ int total = 0, ret, iv_size;
   
   return total;
 }
+
+/**
+ * gnutls_ecc_curve_get:
+ * @session: is a #gnutls_session_t structure.
+ *
+ * Returns the currently used elliptic curve. Only valid
+ * when using an elliptic curve ciphersuite.
+ *
+ * Returns: the currently used curve, a #gnutls_ecc_curve_t
+ *   type.
+ **/
+gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session)
+{
+  return _gnutls_session_ecc_curve_get(session);
+}
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index eec013c..078ab60 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -95,6 +95,12 @@ int gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey,
                                    unsigned int flags,
                                    const gnutls_datum_t * data,
                                    const gnutls_datum_t * signature);
+int
+gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey, 
+                           gnutls_sign_algorithm_t algo,
+                           unsigned int flags,
+                          const gnutls_datum_t * data,
+                          const gnutls_datum_t * signature);
 
 /* Private key operations */
 
diff --git a/lib/includes/gnutls/compat.h b/lib/includes/gnutls/compat.h
index e6b9277..fb88179 100644
--- a/lib/includes/gnutls/compat.h
+++ b/lib/includes/gnutls/compat.h
@@ -202,16 +202,6 @@ gnutls_sign_callback_get (gnutls_session_t session, void 
**userdata)
                                        gnutls_datum_t * signature)
                                        _GNUTLS_GCC_ATTR_DEPRECATED;
 
-
-/* Deprecated because verify_* functions are moved to public
- * keys. Check abstract.h for similar functionality.
- */
-  int gnutls_x509_privkey_verify_data (gnutls_x509_privkey_t key,
-                                       unsigned int flags,
-                                       const gnutls_datum_t * data,
-                                       const gnutls_datum_t * signature)
-                                       _GNUTLS_GCC_ATTR_DEPRECATED;
-
 /* we support the gnutls_privkey_sign_data() instead.
  */
   int gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 9375f6a..9c4b690 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -81,6 +81,7 @@ extern "C"
    * @GNUTLS_CIPHER_RC2_40_CBC: RC2 in CBC mode with 40-bit keys.
    * @GNUTLS_CIPHER_DES_CBC: DES in CBC mode (56-bit keys).
    * @GNUTLS_CIPHER_AES_128_GCM: AES in GCM mode with 128-bit keys.
+   * @GNUTLS_CIPHER_AES_256_GCM: AES in GCM mode with 256-bit keys.
    * @GNUTLS_CIPHER_IDEA_PGP_CFB: IDEA in CFB mode.
    * @GNUTLS_CIPHER_3DES_PGP_CFB: 3DES in CFB mode.
    * @GNUTLS_CIPHER_CAST5_PGP_CFB: CAST5 in CFB mode.
@@ -108,6 +109,7 @@ extern "C"
     GNUTLS_CIPHER_DES_CBC = 91,
     GNUTLS_CIPHER_AES_192_CBC = 92,
     GNUTLS_CIPHER_AES_128_GCM = 93,
+    GNUTLS_CIPHER_AES_256_GCM = 94,
 
     /* used only for PGP internals. Ignored in TLS/SSL
      */
@@ -747,6 +749,7 @@ typedef enum
 /* Elliptic curves */
 const char * gnutls_ecc_curve_get_name (gnutls_ecc_curve_t curve);
 int gnutls_ecc_curve_get_size (gnutls_ecc_curve_t curve);
+gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
 
 /* get information on the current session */
   gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session);
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index 0ee2918..f6bfdd8 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -541,6 +541,8 @@ extern "C"
  * @GNUTLS_VERIFY_DISABLE_TIME_CHECKS: Disable checking of activation
  *   and expiration validity periods of certificate chains. Don't set
  *   this unless you understand the security implications.
+ * @GNUTLS_VERIFY_DISABLE_CRL_CHECKS: Disable checking for validity
+ *   using certificate revocation lists.
  *
  * Enumeration of different certificate verify flags.
  */
@@ -554,7 +556,8 @@ extern "C"
     GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5 = 32,
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS = 64,
     GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS = 128,
-    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT = 256
+    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT = 256,
+    GNUTLS_VERIFY_DISABLE_CRL_CHECKS = 512,
   } gnutls_certificate_verify_flags;
 
   int gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert,
@@ -847,13 +850,16 @@ extern "C"
   void
   gnutls_x509_trust_list_deinit (gnutls_x509_trust_list_t list, unsigned int 
all);
 
-  int gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
+  int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
     gnutls_x509_crt_t cert, gnutls_x509_crt_t* issuer, unsigned int flags);
 
   int
   gnutls_x509_trust_list_add_cas (gnutls_x509_trust_list_t list, 
     const gnutls_x509_crt_t * clist, int clist_size, unsigned int flags);
 
+  int gnutls_x509_trust_list_add_named_crt (gnutls_x509_trust_list_t list, 
+      gnutls_x509_crt_t cert, const void* name, size_t name_size, unsigned int 
flags);
+
 #define GNUTLS_TL_VERIFY_CRL 1
   int
   gnutls_x509_trust_list_add_crls (gnutls_x509_trust_list_t list, 
@@ -870,6 +876,14 @@ extern "C"
      */
     unsigned int verification_output);
 
+  int gnutls_x509_trust_list_verify_named_crt (
+      gnutls_x509_trust_list_t list,
+      gnutls_x509_crt_t cert,
+      const void * name, size_t name_size,
+      unsigned int flags,
+      unsigned int *verify,
+      gnutls_verify_output_function func);
+
   int
   gnutls_x509_trust_list_verify_crt (
     gnutls_x509_trust_list_t list,
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 042b2f9..bd3a4db 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -508,7 +508,6 @@ GNUTLS_1_4
     gnutls_x509_privkey_init;
     gnutls_x509_privkey_sign_data;
     gnutls_x509_privkey_sign_hash;
-    gnutls_x509_privkey_verify_data;
     gnutls_x509_rdn_get;
     gnutls_x509_rdn_get_by_oid;
     gnutls_x509_rdn_get_oid;
@@ -707,9 +706,13 @@ GNUTLS_3_0_0 {
        gnutls_global_set_audit_log_function;
        gnutls_ecc_curve_get_name;
        gnutls_ecc_curve_get_size;
+       gnutls_ecc_curve_get;
        gnutls_pubkey_get_pk_ecc_raw;
        gnutls_x509_privkey_export_ecc_raw;
        gnutls_x509_privkey_import_ecc_raw;
+       gnutls_pubkey_verify_data2;
+       gnutls_x509_trust_list_verify_named_crt;
+       gnutls_x509_trust_list_add_named_crt;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c
index 6e59461..9c8d126 100644
--- a/lib/nettle/cipher.c
+++ b/lib/nettle/cipher.c
@@ -183,6 +183,7 @@ wrap_nettle_cipher_init (gnutls_cipher_algorithm_t algo, 
void **_ctx)
     {
 #ifdef NETTLE_GCM
     case GNUTLS_CIPHER_AES_128_GCM:
+    case GNUTLS_CIPHER_AES_256_GCM:
       ctx->encrypt = _gcm_encrypt;
       ctx->decrypt = _gcm_decrypt;
       ctx->i_encrypt = (nettle_crypt_func*) aes_bidi_encrypt;
@@ -264,6 +265,7 @@ wrap_nettle_cipher_setkey (void *_ctx, const void *key, 
size_t keysize)
     {
 #ifdef NETTLE_GCM
     case GNUTLS_CIPHER_AES_128_GCM:
+    case GNUTLS_CIPHER_AES_256_GCM:
       gcm_aes_set_key(&ctx->ctx.aes_gcm, keysize, key);
       break;
 #endif
@@ -331,6 +333,7 @@ struct nettle_cipher_ctx *ctx = _ctx;
     {
 #ifdef NETTLE_GCM
     case GNUTLS_CIPHER_AES_128_GCM:
+    case GNUTLS_CIPHER_AES_256_GCM:
       if (ivsize != GCM_DEFAULT_NONCE_SIZE)
         {
           gnutls_assert ();
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 788b335..16cd3e4 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1344,6 +1344,43 @@ cleanup:
   return result;
 }
 
+/**
+ * gnutls_x509_crt_get_signature_algorithm:
+ * @cert: should contain a #gnutls_x509_crt_t structure
+ *
+ * This function will return a value of the #gnutls_sign_algorithm_t
+ * enumeration that is the signature algorithm that has been used to
+ * sign this certificate.
+ *
+ * Returns: a #gnutls_sign_algorithm_t value, or a negative value on
+ *   error.
+ **/
+int
+_gnutls_x509_get_signature_algorithm (ASN1_TYPE src, const char *src_name)
+{
+  int result;
+  gnutls_datum_t sa;
+
+  /* Read the signature algorithm. Note that parameters are not
+   * read. They will be read from the issuer's certificate if needed.
+   */
+  result =
+    _gnutls_x509_read_value (src, src_name, &sa, 0);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  result = _gnutls_x509_oid2sign_algorithm (sa.data);
+
+  _gnutls_free_datum (&sa);
+
+  return result;
+}
+
+
 /* Reads the DER signature from the certificate and allocates space and
  * returns them into signed_data.
  */
diff --git a/lib/x509/common.h b/lib/x509/common.h
index 0e96337..aebe338 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -128,6 +128,9 @@ int _gnutls_x509_decode_and_read_attribute (ASN1_TYPE 
asn1_struct,
 int _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
                                    unsigned int *bits);
 
+int
+_gnutls_x509_get_signature_algorithm (ASN1_TYPE src, const char *src_name);
+
 int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
                                              const char *dst_name,
                                              gnutls_pk_algorithm_t
@@ -140,8 +143,6 @@ int _gnutls_x509_get_signed_data (ASN1_TYPE src, const char 
*src_name,
 int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
                                 gnutls_datum_t * signature);
 
-gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, 
-  const gnutls_pk_params_st* params, int* hash_len);
 
 int _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
                           gnutls_pk_params_st * params);
@@ -153,12 +154,6 @@ int _gnutls_get_key_id (gnutls_pk_algorithm_t pk, 
gnutls_pk_params_st*,
 void _asnstr_append_name (char *name, size_t name_size, const char *part1,
                           const char *part2);
 
-int pubkey_verify_sig (const gnutls_datum_t * tbs,
-                       const gnutls_datum_t * hash,
-                       const gnutls_datum_t * signature,
-                       gnutls_pk_algorithm_t pk, 
-                       gnutls_pk_params_st * issuer_params);
-
 int
 check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2);
 
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index c61b3c4..27dee3e 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -2523,6 +2523,7 @@ gnutls_x509_crq_verify (gnutls_x509_crq_t crq,
 gnutls_datum data = { NULL, 0 };
 gnutls_datum signature = { NULL, 0 };
 gnutls_pk_params_st params;
+gnutls_digest_algorithm_t algo;
 int ret;
 
   gnutls_pk_params_init(&params);
@@ -2534,6 +2535,15 @@ int ret;
       gnutls_assert ();
       return ret;
     }
+    
+  ret = _gnutls_x509_get_signature_algorithm(crq->crq, 
"signatureAlgorithm.algorithm");
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+  
+  algo = _gnutls_sign_get_hash_algorithm(ret);
 
   ret = _gnutls_x509_get_signature (crq->crq, "signature", &signature);
   if (ret < 0)
@@ -2550,9 +2560,8 @@ int ret;
       goto cleanup;
     }
 
-  ret = pubkey_verify_sig(&data, NULL, &signature,
-                          gnutls_x509_crq_get_pk_algorithm (crq, NULL),
-                          &params);
+  ret = pubkey_verify_data(gnutls_x509_crq_get_pk_algorithm (crq, NULL), algo,
+                           &data, &signature, &params);
   if (ret < 0)
     {
       gnutls_assert ();
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index 08d89b5..99f626f 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -1641,45 +1641,6 @@ gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
 
 
 /**
- * gnutls_x509_privkey_verify_data:
- * @key: Holds the key
- * @flags: should be 0 for now
- * @data: holds the data to be signed
- * @signature: contains the signature
- *
- * This function will verify the given signed data, using the
- * parameters in the private key.
- *
- * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED 
- * is returned, and a positive code on success.
- *
- * Deprecated: Use gnutls_pubkey_verify_data().
- */
-int
-gnutls_x509_privkey_verify_data (gnutls_x509_privkey_t key,
-                                 unsigned int flags,
-                                 const gnutls_datum_t * data,
-                                 const gnutls_datum_t * signature)
-{
-  int result;
-
-  if (key == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  result = _gnutls_x509_privkey_verify_signature (data, signature, key);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-  return result;
-}
-
-/**
  * gnutls_x509_privkey_fix:
  * @key: Holds the key
  *
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 0b062df..c106ffe 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -37,10 +37,20 @@
 
 #define DEFAULT_SIZE 503
 #define INIT_HASH 0x33a1
+
+struct named_cert_st {
+  gnutls_x509_crt_t cert;
+  uint8_t name[MAX_NAME_SIZE];
+  unsigned int name_size;
+};
+
 struct node_st {
   /* The trusted certificates */
-  gnutls_x509_crt_t * trusted_crts;
-  unsigned int trusted_crt_size;
+  gnutls_x509_crt_t * trusted_cas;
+  unsigned int trusted_ca_size;
+
+  struct named_cert_st *named_certs;
+  unsigned int named_cert_size;
 
   /* The trusted CRLs */
   gnutls_x509_crl_t * crls;
@@ -105,11 +115,11 @@ int i, j;
     {
       for (i=0;i<list->size;i++)
         {
-          for (j=0;j<list->node[i].trusted_crt_size;j++)
+          for (j=0;j<list->node[i].trusted_ca_size;j++)
             {
-              gnutls_x509_crt_deinit(list->node[i].trusted_crts[j]);
+              gnutls_x509_crt_deinit(list->node[i].trusted_cas[j]);
             }
-          gnutls_free(list->node[i].trusted_crts);
+          gnutls_free(list->node[i].trusted_cas);
           for (j=0;j<list->node[i].crl_size;j++)
             {
               gnutls_x509_crl_deinit(list->node[i].crls[j]);
@@ -156,23 +166,83 @@ uint32_t hash;
         hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
         hash %= list->size;
 
-        list->node[hash].trusted_crts = gnutls_realloc_fast( 
list->node[hash].trusted_crts, 
(list->node[hash].trusted_crt_size+1)*sizeof(list->node[hash].trusted_crts[0]));
-        if (list->node[hash].trusted_crts == NULL)
+        _gnutls_free_datum(&dn);
+
+        list->node[hash].trusted_cas = gnutls_realloc_fast( 
list->node[hash].trusted_cas, 
(list->node[hash].trusted_ca_size+1)*sizeof(list->node[hash].trusted_cas[0]));
+        if (list->node[hash].trusted_cas == NULL)
           {
             gnutls_assert();
             return i;
           }
 
-        list->node[hash].trusted_crts[list->node[hash].trusted_crt_size] = 
clist[i];
-        list->node[hash].trusted_crt_size++;
-
-        _gnutls_free_datum(&dn);
+        list->node[hash].trusted_cas[list->node[hash].trusted_ca_size] = 
clist[i];
+        list->node[hash].trusted_ca_size++;
     }
 
   return i;
 }
 
 /**
+ * gnutls_x509_trust_list_add_named_crt:
+ * @list: The structure of the list
+ * @cert: A certificate
+ * @name: An identifier for the certificate
+ * @name_size: The size of the identifier
+ * @flags: should be 0.
+ *
+ * This function will add the given certificate to the trusted
+ * list and associate it with a name. The certificate will not be
+ * be used for verification with gnutls_x509_trust_list_verify_crt()
+ * but only with gnutls_x509_trust_list_verify_named_crt().
+ *
+ * In principle this function can be used to set individual "server"
+ * certificates that are trusted by the user for that specific server
+ * but for no other purposes.
+ *
+ * The certificate must not be deinitialized during the lifetime
+ * of the trusted list.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ *
+ **/
+int
+gnutls_x509_trust_list_add_named_crt (gnutls_x509_trust_list_t list, 
+  gnutls_x509_crt_t cert, const void* name, size_t name_size, unsigned int 
flags)
+{
+gnutls_datum_t dn;
+int ret;
+uint32_t hash;
+
+  if (name_size >= MAX_NAME_SIZE)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
+  hash %= list->size;
+
+  _gnutls_free_datum(&dn);
+
+  list->node[hash].named_certs = gnutls_realloc_fast( 
list->node[hash].named_certs, 
(list->node[hash].named_cert_size+1)*sizeof(list->node[hash].named_certs[0]));
+  if (list->node[hash].named_certs == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+  list->node[hash].named_certs[list->node[hash].named_cert_size].cert = cert;
+  memcpy(list->node[hash].named_certs[list->node[hash].named_cert_size].name, 
name, name_size);
+  list->node[hash].named_certs[list->node[hash].named_cert_size].name_size = 
name_size;
+
+  list->node[hash].named_cert_size++;
+
+  return 0;
+}
+
+/**
  * gnutls_x509_trust_list_add_crls:
  * @list: The structure of the list
  * @crl_list: A list of CRLs
@@ -225,13 +295,13 @@ uint32_t hash;
         if (flags & GNUTLS_TL_VERIFY_CRL)
           {
 
-            ret = gnutls_x509_crl_verify(crl_list[i], 
list->node[hash].trusted_crts,
-              list->node[hash].trusted_crt_size, verification_flags, &vret);
+            ret = gnutls_x509_crl_verify(crl_list[i], 
list->node[hash].trusted_cas,
+              list->node[hash].trusted_ca_size, verification_flags, &vret);
             if (ret < 0 || vret != 0)
               continue;
           }
 
-        list->node[hash].crls = gnutls_realloc_fast( list->node[hash].crls, 
(list->node[hash].crl_size+1)*sizeof(list->node[hash].trusted_crts[0]));
+        list->node[hash].crls = gnutls_realloc_fast( list->node[hash].crls, 
(list->node[hash].crl_size+1)*sizeof(list->node[hash].trusted_cas[0]));
         if (list->node[hash].crls == NULL)
           {
             gnutls_assert();
@@ -299,9 +369,9 @@ gnutls_datum_t dn;
 
       _gnutls_free_datum(&dn);
 
-      for (j = 0; j < list->node[hash].trusted_crt_size; j++)
+      for (j = 0; j < list->node[hash].trusted_ca_size; j++)
         {
-          if (check_if_same_cert (certificate_list[i], 
list->node[hash].trusted_crts[j]) == 0)
+          if (check_if_same_cert (certificate_list[i], 
list->node[hash].trusted_cas[j]) == 0)
             {
               /* cut the list at the point of first the trusted certificate */
               clist_size = i+1;
@@ -327,7 +397,7 @@ gnutls_datum_t dn;
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
+int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
   gnutls_x509_crt_t cert, gnutls_x509_crt_t* issuer, unsigned int flags)
 {
 gnutls_datum_t dn;
@@ -346,12 +416,12 @@ uint32_t hash;
 
   _gnutls_free_datum(&dn);
 
-  for (i=0;i<list->node[hash].trusted_crt_size;i++)
+  for (i=0;i<list->node[hash].trusted_ca_size;i++)
     {
-      ret = gnutls_x509_crt_check_issuer (cert, 
list->node[hash].trusted_crts[i]);
+      ret = gnutls_x509_crt_check_issuer (cert, 
list->node[hash].trusted_cas[i]);
       if (ret > 0)
         {
-          *issuer = list->node[hash].trusted_crts[i];
+          *issuer = list->node[hash].trusted_cas[i];
           return 0;
         }
     }
@@ -407,10 +477,10 @@ uint32_t hash;
   _gnutls_free_datum(&dn);
 
   *verify = _gnutls_x509_verify_certificate(cert_list, cert_list_size, 
-    list->node[hash].trusted_crts, list->node[hash].trusted_crt_size, 
+    list->node[hash].trusted_cas, list->node[hash].trusted_ca_size, 
     flags, func);
 
-  if (*verify != 0) return 0;
+  if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)) return 0;
 
   /* Check revocation of individual certificates.
    * start with the last one that we already have its hash
@@ -452,3 +522,79 @@ uint32_t hash;
 
   return 0;
 }
+
+/**
+ * gnutls_x509_trust_list_verify_named_crt:
+ * @list: The structure of the list
+ * @cert: is the certificate to be verified
+ * @name: is the certificate's name
+ * @name_size: is the certificate's name size
+ * @flags: Flags that may be used to change the verification algorithm. Use OR 
of the gnutls_certificate_verify_flags enumerations.
+ * @verify: will hold the certificate verification output.
+ * @func: If non-null will be called on each chain element verification with 
the output.
+ *
+ * This function will try to find a matching named certificate. If a
+ * match is found the certificate is considered valid. In addition to that
+ * this function will also check CRLs.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_x509_trust_list_verify_named_crt (
+  gnutls_x509_trust_list_t list,
+  gnutls_x509_crt_t cert,
+  const void * name,
+  size_t name_size,
+  unsigned int flags,
+  unsigned int *verify,
+  gnutls_verify_output_function func)
+{
+gnutls_datum_t dn;
+int ret, i;
+uint32_t hash;
+
+  ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
+  hash %= list->size;
+
+  _gnutls_free_datum(&dn);
+
+  *verify = GNUTLS_CERT_INVALID;
+
+  for (i=0;i<list->node[hash].named_cert_size;i++)
+    {
+      if (check_if_same_cert(cert, list->node[hash].named_certs[i].cert)==0)
+        { /* check if name matches */
+          if (list->node[hash].named_certs[i].name_size==name_size &&
+              memcmp(list->node[hash].named_certs[i].name, name, name_size) == 
0)
+              {
+                *verify = 0;
+                break;
+              }
+        }
+    }
+
+  if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)) return 0;
+
+  /* Check revocation of individual certificates.
+   * start with the last one that we already have its hash
+   */
+  ret = _gnutls_x509_crt_check_revocation (cert,
+                                        list->node[hash].crls, 
+                                        list->node[hash].crl_size, func);
+  if (ret == 1)
+    { /* revoked */
+      *verify |= GNUTLS_CERT_REVOKED;
+      *verify |= GNUTLS_CERT_INVALID;
+      return 0;
+    }
+
+  return 0;
+}
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 4ae9706..2adb3dd 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -369,7 +369,7 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
   gnutls_datum_t cert_signed_data = { NULL, 0 };
   gnutls_datum_t cert_signature = { NULL, 0 };
   gnutls_x509_crt_t issuer = NULL;
-  int issuer_version, result;
+  int issuer_version, result, hash_algo;
   unsigned int out = 0;
 
   if (output)
@@ -442,8 +442,17 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
       goto cleanup;
     }
 
+  result = _gnutls_x509_get_signature_algorithm(cert->cert, 
"signatureAlgorithm.algorithm");
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  hash_algo = _gnutls_sign_get_hash_algorithm(result);
+
   result =
-    _gnutls_x509_verify_signature (&cert_signed_data, NULL, &cert_signature,
+    _gnutls_x509_verify_data (hash_algo, &cert_signed_data, &cert_signature,
                                    issuer);
   if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED)
     {
@@ -666,301 +675,6 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t 
* certificate_list,
   return 0;
 }
 
-
-/* Reads the digest information.
- * we use DER here, although we should use BER. It works fine
- * anyway.
- */
-static int
-decode_ber_digest_info (const gnutls_datum_t * info,
-                        gnutls_mac_algorithm_t * hash,
-                        opaque * digest, int *digest_size)
-{
-  ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
-  int result;
-  char str[1024];
-  int len;
-
-  if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
-                                     "GNUTLS.DigestInfo",
-                                     &dinfo)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return _gnutls_asn2err (result);
-    }
-
-  len = sizeof (str) - 1;
-  result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return _gnutls_asn2err (result);
-    }
-
-  *hash = _gnutls_x509_oid2mac_algorithm (str);
-
-  if (*hash == GNUTLS_MAC_UNKNOWN)
-    {
-
-      _gnutls_debug_log ("verify.c: HASH OID: %s\n", str);
-
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return GNUTLS_E_UNKNOWN_ALGORITHM;
-    }
-
-  len = sizeof (str) - 1;
-  result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
-  /* To avoid permitting garbage in the parameters field, either the
-     parameters field is not present, or it contains 0x05 0x00. */
-  if (!(result == ASN1_ELEMENT_NOT_FOUND ||
-        (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
-         memcmp (str, ASN1_NULL, ASN1_NULL_SIZE) == 0)))
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return GNUTLS_E_ASN1_GENERIC_ERROR;
-    }
-
-  result = asn1_read_value (dinfo, "digest", digest, digest_size);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return _gnutls_asn2err (result);
-    }
-
-  asn1_delete_structure (&dinfo);
-
-  return 0;
-}
-
-/* if hash==MD5 then we do RSA-MD5
- * if hash==SHA then we do RSA-SHA
- * params[0] is modulus
- * params[1] is public key
- */
-static int
-_pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
-                       const gnutls_datum_t * prehash,
-                       const gnutls_datum_t * signature, 
-                       gnutls_pk_params_st * params)
-{
-  gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
-  int ret;
-  opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE], *cmp;
-  int digest_size;
-  digest_hd_st hd;
-  gnutls_datum_t decrypted;
-
-  ret =
-    _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, 1);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  /* decrypted is a BER encoded data of type DigestInfo
-   */
-
-  digest_size = sizeof (digest);
-  if ((ret =
-       decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) != 0)
-    {
-      gnutls_assert ();
-      _gnutls_free_datum (&decrypted);
-      return ret;
-    }
-
-  _gnutls_free_datum (&decrypted);
-
-  if (digest_size != _gnutls_hash_get_algo_len (hash))
-    {
-      gnutls_assert ();
-      return GNUTLS_E_ASN1_GENERIC_ERROR;
-    }
-
-  if (prehash && prehash->data && prehash->size == digest_size)
-    {
-      cmp = prehash->data;
-    }
-  else
-    {
-      if (!text)
-        {
-          gnutls_assert ();
-          return GNUTLS_E_INVALID_REQUEST;
-        }
-
-      ret = _gnutls_hash_init (&hd, hash);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-
-      _gnutls_hash (&hd, text->data, text->size);
-      _gnutls_hash_deinit (&hd, md);
-
-      cmp = md;
-    }
-
-  if (memcmp (cmp, digest, digest_size) != 0)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
-    }
-
-  return 0;
-}
-
-/* Hashes input data and verifies a signature.
- */
-static int
-dsa_verify_sig (const gnutls_datum_t * text,
-                const gnutls_datum_t * hash,
-                const gnutls_datum_t * signature,
-                gnutls_pk_algorithm_t pk,
-                gnutls_pk_params_st* params)
-{
-  int ret;
-  opaque _digest[MAX_HASH_SIZE];
-  gnutls_datum_t digest;
-  digest_hd_st hd;
-  gnutls_digest_algorithm_t algo;
-  int hash_len;
-
-  algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len);
-  if (hash)
-    {
-      /* SHA1 or better allowed */
-      if (!hash->data || hash->size < hash_len)
-        {
-          gnutls_assert();
-          _gnutls_debug_log("Hash size (%d) does not correspond to hash %s(%d) 
or better.\n", (int)hash->size, gnutls_mac_get_name(algo), hash_len);
-          
-          if (hash->size != 20) /* SHA1 is allowed */
-            return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
-        }
-
-      digest.data = hash->data;
-      digest.size = hash->size;
-    }
-  else
-    {
-      ret = _gnutls_hash_init (&hd, algo);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-
-      _gnutls_hash (&hd, text->data, text->size);
-      _gnutls_hash_deinit (&hd, _digest);
-
-      digest.data = _digest;
-      digest.size = _gnutls_hash_get_algo_len(algo);
-    }
-
-  ret = _gnutls_pk_verify (pk, &digest, signature, params);
-
-  return ret;
-}
-
-/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
- * not verified, or 1 otherwise.
- */
-int
-pubkey_verify_sig (const gnutls_datum_t * tbs,
-                   const gnutls_datum_t * hash,
-                   const gnutls_datum_t * signature,
-                   gnutls_pk_algorithm_t pk,
-                   gnutls_pk_params_st * issuer_params)
-{
-
-  switch (pk)
-    {
-    case GNUTLS_PK_RSA:
-
-      if (_pkcs1_rsa_verify_sig
-          (tbs, hash, signature, issuer_params) != 0)
-        {
-          gnutls_assert ();
-          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
-        }
-
-      return 1;
-      break;
-
-    case GNUTLS_PK_ECC:
-    case GNUTLS_PK_DSA:
-      if (dsa_verify_sig(tbs, hash, signature, pk, issuer_params) != 0)
-        {
-          gnutls_assert ();
-          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
-        }
-
-      return 1;
-      break;
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
-
-    }
-}
-
-gnutls_digest_algorithm_t
-_gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* 
params, int* hash_len)
-{
-  int bits = 0;
-  
-  if (algo == GNUTLS_PK_DSA)
-    bits = _gnutls_mpi_get_nbits (params->params[1]);
-  else if (algo == GNUTLS_PK_ECC)
-    bits = gnutls_ecc_curve_get_size(params->flags)*8;
-
-  if (bits <= 160)
-    {
-      if (hash_len) *hash_len = 20;
-      return GNUTLS_DIG_SHA1;
-    }
-  else if (bits <= 192)
-    {
-      if (hash_len) *hash_len = 24;
-      return GNUTLS_DIG_SHA256;
-    }
-  else if (bits <= 224)
-    {
-      if (hash_len) *hash_len = 28;
-      return GNUTLS_DIG_SHA256;
-    }
-  else if (bits <= 256)
-    {
-      if (hash_len) *hash_len = 32;
-      return GNUTLS_DIG_SHA256;
-    }
-  else if (bits <= 384)
-    {
-      if (hash_len) *hash_len = 48;
-      return GNUTLS_DIG_SHA384;
-    }
-  else
-    {
-      if (hash_len) *hash_len = 64;
-      return GNUTLS_DIG_SHA512;
-    }
-}
-
 /* This will return the appropriate hash to verify the given signature.
  * If signature is NULL it will return an (or the) appropriate hash for
  * the given parameters.
@@ -1040,14 +754,14 @@ cleanup:
 /* verifies if the certificate is properly signed.
  * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
  * 
- * 'tbs' is the signed data
+ * 'data' is the signed data
  * 'signature' is the signature!
  */
 int
-_gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
-                               const gnutls_datum_t * hash,
-                               const gnutls_datum_t * signature,
-                               gnutls_x509_crt_t issuer)
+_gnutls_x509_verify_data (gnutls_digest_algorithm_t algo,
+                          const gnutls_datum_t * data,
+                          const gnutls_datum_t * signature,
+                          gnutls_x509_crt_t issuer)
 {
   gnutls_pk_params_st issuer_params;
   int ret;
@@ -1063,9 +777,8 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
     }
 
   ret =
-    pubkey_verify_sig (tbs, hash, signature,
-                       gnutls_x509_crt_get_pk_algorithm (issuer, NULL),
-                       &issuer_params);
+    pubkey_verify_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL), algo,
+                        data, signature, &issuer_params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1078,26 +791,36 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * 
tbs,
   return ret;
 }
 
-/* verifies if the certificate is properly signed.
- * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
- * 
- * 'tbs' is the signed data
- * 'signature' is the signature!
- */
 int
-_gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
-                                       const gnutls_datum_t * signature,
-                                       gnutls_x509_privkey_t issuer)
+_gnutls_x509_verify_hashed_data (const gnutls_datum_t * hash,
+                                 const gnutls_datum_t * signature,
+                                 gnutls_x509_crt_t issuer)
 {
+  gnutls_pk_params_st issuer_params;
   int ret;
 
-  ret = pubkey_verify_sig (tbs, NULL, signature, issuer->pk_algorithm,
-                           &issuer->params);
+  /* Read the MPI parameters from the issuer's certificate.
+   */
+  ret =
+    _gnutls_x509_crt_get_mpis (issuer, &issuer_params);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret =
+    pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL),
+                               hash, signature, &issuer_params);
   if (ret < 0)
     {
       gnutls_assert ();
     }
 
+  /* release all allocated MPIs
+   */
+  gnutls_pk_params_release(&issuer_params);
+
   return ret;
 }
 
@@ -1329,7 +1052,7 @@ _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
   gnutls_datum_t crl_signed_data = { NULL, 0 };
   gnutls_datum_t crl_signature = { NULL, 0 };
   gnutls_x509_crt_t issuer;
-  int result;
+  int result, hash_algo;
 
   if (output)
     *output = 0;
@@ -1381,8 +1104,17 @@ _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
       goto cleanup;
     }
 
+  result = _gnutls_x509_get_signature_algorithm(crl->crl, 
"signatureAlgorithm.algorithm");
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  hash_algo = _gnutls_sign_get_hash_algorithm(result);
+
   result =
-    _gnutls_x509_verify_signature (&crl_signed_data, NULL, &crl_signature,
+    _gnutls_x509_verify_data (hash_algo, &crl_signed_data, &crl_signature,
                                    issuer);
   if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED)
     {
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 810057a..582968f 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -475,33 +475,7 @@ gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert,
 int
 gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert)
 {
-  int result;
-  gnutls_datum_t sa;
-
-  if (cert == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  /* Read the signature algorithm. Note that parameters are not
-   * read. They will be read from the issuer's certificate if needed.
-   */
-  result =
-    _gnutls_x509_read_value (cert->cert, "signatureAlgorithm.algorithm",
-                             &sa, 0);
-
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-  result = _gnutls_x509_oid2sign_algorithm (sa.data);
-
-  _gnutls_free_datum (&sa);
-
-  return result;
+  return _gnutls_x509_get_signature_algorithm(cert->cert, 
"signatureAlgorithm.algorithm");
 }
 
 /**
@@ -2613,7 +2587,7 @@ gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, 
unsigned int flags,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  result = _gnutls_x509_verify_signature (data, NULL, signature, crt);
+  result = _gnutls_x509_verify_data (GNUTLS_DIG_UNKNOWN, data, signature, crt);
   if (result < 0)
     {
       gnutls_assert ();
@@ -2651,7 +2625,7 @@ gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, 
unsigned int flags,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  result = _gnutls_x509_verify_signature (NULL, hash, signature, crt);
+  result = _gnutls_x509_verify_hashed_data (hash, signature, crt);
   if (result < 0)
     {
       gnutls_assert ();
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index 4df028b..41ed582 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -182,13 +182,14 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * 
hash,
                                gnutls_pk_algorithm_t pk,
                                gnutls_pk_params_st * issuer_params);
 
-int _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
-                                   const gnutls_datum_t * hash,
-                                   const gnutls_datum_t * signature,
-                                   gnutls_x509_crt_t issuer);
-int _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
-                                           const gnutls_datum_t * signature,
-                                           gnutls_x509_privkey_t issuer);
+int _gnutls_x509_verify_data (gnutls_digest_algorithm_t algo,
+                              const gnutls_datum_t * data,
+                              const gnutls_datum_t * signature,
+                              gnutls_x509_crt_t issuer);
+
+int _gnutls_x509_verify_hashed_data (const gnutls_datum_t * hash,
+                                     const gnutls_datum_t * signature,
+                                     gnutls_x509_crt_t issuer);
 
 /* privkey.h */
 ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t *
diff --git a/src/common.c b/src/common.c
index 3dfea1b..07687b8 100644
--- a/src/common.c
+++ b/src/common.c
@@ -393,6 +393,20 @@ print_dh_info (gnutls_session_t session, const char *str)
     }
 }
 
+static void
+print_ecdh_info (gnutls_session_t session, const char *str)
+{
+int curve;
+
+  printf ("- %sEC Diffie-Hellman parameters\n", str);
+  
+  curve = gnutls_ecc_curve_get(session);
+  
+  printf (" - Using curve: %s\n", gnutls_ecc_curve_get_name (curve));
+  printf (" - Curve size: %d bits\n", gnutls_ecc_curve_get_size(curve)*8);
+
+}
+
 int
 print_info (gnutls_session_t session, const char *hostname, int insecure)
 {
@@ -410,7 +424,9 @@ print_info (gnutls_session_t session, const char *hostname, 
int insecure)
     {
 #ifdef ENABLE_ANON
     case GNUTLS_CRD_ANON:
-      if (kx != GNUTLS_KX_ANON_ECDH)
+      if (kx == GNUTLS_KX_ANON_ECDH)
+        print_ecdh_info(session, "Anonymous ");
+      else
         print_dh_info (session, "Anonymous ");
       break;
 #endif
@@ -438,6 +454,8 @@ print_info (gnutls_session_t session, const char *hostname, 
int insecure)
                 gnutls_psk_server_get_username (session));
       if (kx == GNUTLS_KX_DHE_PSK)
         print_dh_info (session, "Ephemeral ");
+      if (kx == GNUTLS_KX_ECDHE_PSK)
+        print_ecdh_info(session, "Ephemeral ");
       break;
 #endif
     case GNUTLS_CRD_IA:
@@ -458,6 +476,8 @@ print_info (gnutls_session_t session, const char *hostname, 
int insecure)
 
       if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
         print_dh_info (session, "Ephemeral ");
+      else if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA)
+        print_ecdh_info(session, "Ephemeral ");
 
       print_cert_info (session, hostname, insecure);
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bd25931..efca9b2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -65,7 +65,7 @@ ctests = simple gc set_pkcs12_cred certder certuniqueid mpi   
                \
        crq_apis init_roundtrip pkcs12_s2k_pem dn2 mini-eagain          \
        nul-in-x509-names x509_altname pkcs12_encode mini-x509          \
        mini-x509-rehandshake rng-fork mini-eagain-dtls cipher-test     \
-       x509cert #gendh
+       x509cert x509cert-tl #gendh
 
 if ENABLE_OPENSSL
 ctests +=  openssl
diff --git a/tests/x509cert.c b/tests/x509cert-tl.c
similarity index 79%
copy from tests/x509cert.c
copy to tests/x509cert-tl.c
index 6007b95..b6ee2e6 100644
--- a/tests/x509cert.c
+++ b/tests/x509cert-tl.c
@@ -30,20 +30,13 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
-#if !defined(_WIN32)
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <arpa/inet.h>
-#endif
 #include <unistd.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 
 #include "utils.h"
 
-/* Test for gnutls_certificate_get_issuer() and implicitly for
- * gnutls_trust_list_get_issuer().
+/* gnutls_trust_list_*().
  */
 
 static void
@@ -142,48 +135,75 @@ const gnutls_datum_t server_key = { server_key_pem,
   sizeof (server_key_pem)
 };
 
+static time_t mytime (time_t * t)
+{
+  time_t then = 1207000800;
+
+  if (t)
+    *t = then;
+
+  return then;
+}
 
+#define NAME "localhost"
+#define NAME_SIZE (sizeof(NAME)-1)
 void
 doit (void)
 {
-  gnutls_certificate_credentials_t x509_cred;
   int ret;
-  gnutls_x509_crt_t crt, issuer;
-  char dn[128];
-  size_t dn_size;
+  gnutls_x509_crt_t server_crt, ca_crt;
+  gnutls_x509_trust_list_t tl;
+  unsigned int status;
 
   /* this must be called once in the program
    */
   gnutls_global_init ();
 
+  gnutls_global_set_time_function (mytime);
   gnutls_global_set_log_function (tls_log_func);
   if (debug)
     gnutls_global_set_log_level (6);
 
-  gnutls_certificate_allocate_credentials (&x509_cred);
-  gnutls_certificate_set_x509_trust_mem (x509_cred, &ca, GNUTLS_X509_FMT_PEM);
+  /* test for gnutls_certificate_get_issuer() */
+  gnutls_x509_trust_list_init(&tl, 0);
+  gnutls_x509_crt_init(&server_crt);
+  gnutls_x509_crt_init(&ca_crt);
 
-  gnutls_certificate_set_x509_key_mem (x509_cred, &server_cert, &server_key,
-                                       GNUTLS_X509_FMT_PEM);
+  ret = gnutls_x509_crt_import(server_crt, &cert, GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    fail("gnutls_x509_crt_import");
 
-  /* test for gnutls_certificate_get_issuer() */
-  gnutls_x509_crt_init(&crt);
-  ret = gnutls_x509_crt_import(crt, &cert, GNUTLS_X509_FMT_PEM);
+  ret = gnutls_x509_crt_import(ca_crt, &ca, GNUTLS_X509_FMT_PEM);
   if (ret < 0)
     fail("gnutls_x509_crt_import");
   
-  ret = gnutls_certificate_get_issuer(x509_cred, crt, &issuer, 0);
+  ret = gnutls_x509_trust_list_add_cas(tl, &ca_crt, 1, 0);
   if (ret < 0)
-    fail("gnutls_certificate_get_isser");
+    fail("gnutls_x509_trust_list_add_cas");
 
-  dn_size = sizeof(dn);
-  ret = gnutls_x509_crt_get_dn(issuer, dn, &dn_size);
+  ret = gnutls_x509_trust_list_add_named_crt(tl, server_crt, NAME, NAME_SIZE, 
0);
   if (ret < 0)
-    fail("gnutls_certificate_get_isser");
-  
-  fprintf(stderr, "Issuer's DN: %s\n", dn);
-  gnutls_x509_crt_deinit(crt);
-  gnutls_certificate_free_credentials(x509_cred);
+    fail("gnutls_x509_trust_list_add_named_crt");
+
+  ret = gnutls_x509_trust_list_verify_crt(tl, &server_crt, 1, 0, &status, 
NULL);
+  if (ret < 0 || status != 0)
+    fail("gnutls_x509_trust_list_verify_crt\n");
+
+  ret = gnutls_x509_trust_list_verify_named_crt(tl, server_crt, NAME, 
NAME_SIZE, 0, &status, NULL);
+  if (ret < 0 || status != 0)
+    fail("gnutls_x509_trust_list_verify_named_crt: %d\n", __LINE__);
+
+  ret = gnutls_x509_trust_list_verify_named_crt(tl, server_crt, NAME, 
NAME_SIZE-1, 0, &status, NULL);
+  if (ret < 0 || status == 0)
+    fail("gnutls_x509_trust_list_verify_named_crt: %d\n", __LINE__);
+
+  ret = gnutls_x509_trust_list_verify_named_crt(tl, server_crt, "other", 5, 0, 
&status, NULL);
+  if (ret < 0 || status == 0)
+    fail("gnutls_x509_trust_list_verify_named_crt: %d\n", __LINE__);
+
+  gnutls_x509_crt_deinit(ca_crt);
+  gnutls_x509_crt_deinit(server_crt);
+  gnutls_x509_trust_list_deinit(tl, 0);
   
   success("success");
 }


hooks/post-receive
-- 
GNU gnutls



reply via email to

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