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_11_6-198-g258d52f


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-198-g258d52f
Date: Fri, 18 Feb 2011 22:59:39 +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=258d52ffb0112f457fa2503493b9f353d08bdf24

The branch, master has been updated
       via  258d52ffb0112f457fa2503493b9f353d08bdf24 (commit)
       via  09e0737359ca51974b427ad12bb5bec4ed031e8b (commit)
       via  ce2f60703c59df14fcd0b85e868a92ab01ff51bd (commit)
       via  91b08751670b65705d66aeed7aec53405e9e5d02 (commit)
       via  0023141108114890e71d328ce1648892bf5655cb (commit)
       via  ff715b55a4da5dd6e8fe9dd419c3982f7db22332 (commit)
       via  b46cd7664120a2b7aeb3d1e01df328ea1e730788 (commit)
      from  31c09710c06478dc6d3892e8a95864cf22d712f2 (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 258d52ffb0112f457fa2503493b9f353d08bdf24
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 18 23:59:36 2011 +0100

    Several updates for DTLS (client side only) to work.

commit 09e0737359ca51974b427ad12bb5bec4ed031e8b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 18 22:37:37 2011 +0100

    Increased level of opencdk debug messages.

commit ce2f60703c59df14fcd0b85e868a92ab01ff51bd
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 18 11:58:34 2011 +0100

    DSA keys in TLS 1.x, x<2 and SSL 3.0 use SHA-1 as hash. That is we reverted 
to previous gnutls behavior. That violates DSS but all implementations handle 
it like that.

commit 91b08751670b65705d66aeed7aec53405e9e5d02
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 18 11:41:11 2011 +0100

    use similar API when caching messages in DTLS or TLS.

commit 0023141108114890e71d328ce1648892bf5655cb
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 18 11:01:58 2011 +0100

    corrected is_version_supported().

commit ff715b55a4da5dd6e8fe9dd419c3982f7db22332
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 18 10:41:20 2011 +0100

    Simplified _gnutls_recv_handshake().

commit b46cd7664120a2b7aeb3d1e01df328ea1e730788
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 18 10:06:26 2011 +0100

    ciphersuites have a bit that indicates whether they are usable with DTLS or 
not.

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

Summary of changes:
 lib/auth_cert.c                 |    2 +-
 lib/debug.c                     |    3 +
 lib/gnutls_algorithms.c         |  156 ++++++++++++++++++------------------
 lib/gnutls_algorithms.h         |    4 -
 lib/gnutls_buffers.c            |  102 +++++++++++++++++------
 lib/gnutls_buffers.h            |    3 +-
 lib/gnutls_cipher.c             |   16 ++--
 lib/gnutls_cipher.h             |    2 +-
 lib/gnutls_dtls.c               |  108 +++++++++++++++----------
 lib/gnutls_dtls.h               |   11 +--
 lib/gnutls_errors.h             |    4 +-
 lib/gnutls_handshake.c          |  170 +++++++++++++++++++++++----------------
 lib/gnutls_handshake.h          |    4 +-
 lib/gnutls_int.h                |   61 ++++++--------
 lib/gnutls_kx.c                 |    2 +-
 lib/gnutls_mbuffers.h           |    6 +-
 lib/gnutls_num.c                |   59 +++-----------
 lib/gnutls_num.h                |    5 +-
 lib/gnutls_record.c             |   41 +++-------
 lib/gnutls_record.h             |    1 -
 lib/gnutls_sig.c                |   20 +++--
 lib/gnutls_state.c              |   18 ++++-
 lib/includes/gnutls/gnutls.h.in |    7 ++-
 lib/opencdk/main.h              |    2 +-
 lib/system.c                    |   16 ++++
 lib/system.h                    |    1 +
 src/cli-gaa.c                   |   16 ++--
 src/cli-gaa.h                   |    2 +-
 src/cli.c                       |    8 +-
 src/cli.gaa                     |    6 +-
 30 files changed, 467 insertions(+), 389 deletions(-)

diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 60bb989..9f644b1 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -2064,7 +2064,6 @@ _gnutls_server_select_cert (gnutls_session_t session,
 
   idx = -1;                     /* default is use no certificate */
 
-
   _gnutls_handshake_log("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s 
(%d)\n", session, 
     gnutls_pk_get_name(requested_algo), requested_algo, 
     gnutls_certificate_type_get_name(session->security_parameters.cert_type), 
session->security_parameters.cert_type);
@@ -2077,6 +2076,7 @@ _gnutls_server_select_cert (gnutls_session_t session,
         gnutls_pk_get_name(cred->cert_list[i][0].subject_pk_algorithm), 
cred->cert_list[i][0].subject_pk_algorithm,
         gnutls_certificate_type_get_name(cred->cert_list[i][0].cert_type), 
cred->cert_list[i][0].cert_type,
         gnutls_sign_get_name(cred->cert_list[i][0].sign_algo), 
cred->cert_list[i][0].sign_algo);
+
       if (requested_algo == GNUTLS_PK_ANY ||
           requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
         {
diff --git a/lib/debug.c b/lib/debug.c
index c9b367d..92b70d9 100644
--- a/lib/debug.c
+++ b/lib/debug.c
@@ -111,6 +111,9 @@ _gnutls_handshake2str (gnutls_handshake_description_t 
handshake)
     case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
       return "NEW SESSION TICKET";
       break;
+    case GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC:
+      return "CHANGE CIPHER SPEC";
+      break;
     default:
       return "Unknown Handshake packet";
 
diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c
index 2b2303f..84fb118 100644
--- a/lib/gnutls_algorithms.c
+++ b/lib/gnutls_algorithms.c
@@ -370,8 +370,8 @@ static const gnutls_kx_algorithm_t supported_kxs[] = {
 
 
 /* Cipher SUITES */
-#define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, 
mac_algorithm, min_version, max_version ) \
-       { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, 
min_version, max_version }
+#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}
 
 typedef struct
 {
@@ -384,6 +384,7 @@ typedef struct
                                          * from 'version' and above;
                                          */
   gnutls_protocol_t max_version;        /* this cipher suite is not supported 
after that */
+  int dtls:1; /* whether this ciphersuite is valid in DTLS */
 } gnutls_cipher_suite_entry;
 
 /* RSA with NULL cipher and MD5 MAC
@@ -537,292 +538,292 @@ static const gnutls_cipher_suite_entry cs_algorithms[] 
= {
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_ARCFOUR_MD5,
                              GNUTLS_CIPHER_ARCFOUR_128,
                              GNUTLS_KX_ANON_DH, GNUTLS_MAC_MD5,
-                             GNUTLS_SSL3, GNUTLS_VERSION_MAX),
+                             GNUTLS_SSL3, GNUTLS_VERSION_MAX, 0),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, ),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_128_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_128_CBC,
                              GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_256_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_256_CBC,
                              GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #endif
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA256,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA256,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   /* PSK */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_ARCFOUR_SHA1,
                              GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 0),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_AES_128_CBC_SHA256,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_PSK,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_AES_128_GCM_SHA256,
                              GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_PSK,
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_NULL_SHA256,
                              GNUTLS_CIPHER_NULL, GNUTLS_KX_PSK,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   /* DHE-PSK */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1,
                              GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_DHE_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 0),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_PSK,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_AES_128_CBC_SHA256,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_AES_128_GCM_SHA256,
                              GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_DHE_PSK,
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_NULL_SHA256,
                              GNUTLS_CIPHER_NULL, GNUTLS_KX_DHE_PSK,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   /* SRP */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   /* DHE_DSS */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_ARCFOUR_SHA1,
                              GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 0),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_128_CBC,
                              GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_256_CBC,
                              GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #endif
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_CBC_SHA256,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_256_CBC_SHA256,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   /* DHE_RSA */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_128_CBC,
                              GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_256_CBC,
                              GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #endif
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_CBC_SHA256,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_256_CBC_SHA256,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   /* RSA-NULL */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_MD5,
                              GNUTLS_CIPHER_NULL,
                              GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_SHA1,
                              GNUTLS_CIPHER_NULL,
                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_SHA256,
                              GNUTLS_CIPHER_NULL,
                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
   /* RSA-EXPORT */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5,
                              GNUTLS_CIPHER_ARCFOUR_40,
                              GNUTLS_KX_RSA_EXPORT, GNUTLS_MAC_MD5,
-                             GNUTLS_SSL3, GNUTLS_TLS1_0),
+                             GNUTLS_SSL3, GNUTLS_TLS1_0, 0),
 
   /* RSA */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_SHA1,
                              GNUTLS_CIPHER_ARCFOUR_128,
                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 0),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_MD5,
                              GNUTLS_CIPHER_ARCFOUR_128,
                              GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 0),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_3DES_EDE_CBC_SHA1,
                              GNUTLS_CIPHER_3DES_CBC,
                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA1,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA1,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #ifdef ENABLE_CAMELLIA
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_128_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_128_CBC, GNUTLS_KX_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_256_CBC_SHA1,
                              GNUTLS_CIPHER_CAMELLIA_256_CBC, GNUTLS_KX_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 #endif
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA256,
                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA256,
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA,
                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 /* GCM */
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_GCM_SHA256,
                              GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_RSA,
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_GCM_SHA256,
                              GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_DHE_RSA,
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_GCM_SHA256,
                              GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_DHE_DSS,
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DH_ANON_AES_128_GCM_SHA256,
                              GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_ANON_DH,
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
-                             GNUTLS_VERSION_MAX),
+                             GNUTLS_VERSION_MAX, 1),
 
-  {0, {{0, 0}}, 0, 0, 0, 0, 0}
+  {0, {{0, 0}}, 0, 0, 0, 0, 0, 0}
 };
 
 #define GNUTLS_CIPHER_SUITE_LOOP(b) \
@@ -1397,6 +1398,7 @@ _gnutls_version_has_selectable_prf (gnutls_protocol_t 
version)
 {
   switch (version)
     {
+    case GNUTLS_DTLS1_0:
     case GNUTLS_TLS1_1:
     case GNUTLS_TLS1_0:
     case GNUTLS_SSL3:
@@ -1488,6 +1490,9 @@ _gnutls_map_kx_get_kx (gnutls_credentials_type_t type, 
int server)
   return ret;
 }
 
+/* Returns the credentials type required for this
+ * Key exchange method.
+ */
 gnutls_credentials_type_t
 _gnutls_map_kx_get_cred (gnutls_kx_algorithm_t algorithm, int server)
 {
@@ -1516,15 +1521,15 @@ _gnutls_cipher_suite_get_cipher_algo (const 
cipher_suite_st * suite)
   return ret;
 }
 
-gnutls_protocol_t
-_gnutls_cipher_suite_is_version_supported (const cipher_suite_st * suite,
-                                           gnutls_protocol_t version)
+static int
+_gnutls_cipher_suite_is_version_supported (gnutls_session_t session, const 
cipher_suite_st * suite)
 {
   int ret = 0;
-  GNUTLS_CIPHER_SUITE_ALG_LOOP ((version >= p->min_version
-                                 && version <= p->max_version) ? (ret =
-                                                                  1) : (ret =
-                                                                        0));
+  int version = gnutls_protocol_get_version( session);
+  
+  GNUTLS_CIPHER_SUITE_ALG_LOOP (if (version >= p->min_version
+                                 && version <= p->max_version) ret = 1;
+                                 if (IS_DTLS(session) && p->dtls==0) ret = 0;);
   return ret;
 }
 
@@ -1795,7 +1800,6 @@ _gnutls_supported_ciphersuites (gnutls_session_t session,
   unsigned int count = CIPHER_SUITES_COUNT;
   cipher_suite_st *tmp_ciphers;
   cipher_suite_st *ciphers;
-  gnutls_protocol_t version;
 
   if (count == 0)
     {
@@ -1813,8 +1817,6 @@ _gnutls_supported_ciphersuites (gnutls_session_t session,
       return GNUTLS_E_MEMORY_ERROR;
     }
 
-  version = gnutls_protocol_get_version (session);
-
   for (i = 0; i < count; i++)
     {
       memcpy (&tmp_ciphers[i], &cs_algorithms[i].id,
@@ -1832,7 +1834,7 @@ _gnutls_supported_ciphersuites (gnutls_session_t session,
       /* remove cipher suites which do not support the
        * protocol version used.
        */
-      if (_gnutls_cipher_suite_is_version_supported (&tmp_ciphers[i], version)
+      if (_gnutls_cipher_suite_is_version_supported (session, &tmp_ciphers[i])
           == 0)
         continue;
 
diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h
index 4e6b540..07cfd34 100644
--- a/lib/gnutls_algorithms.h
+++ b/lib/gnutls_algorithms.h
@@ -68,10 +68,6 @@ gnutls_kx_algorithm_t _gnutls_cipher_suite_get_kx_algo 
(const cipher_suite_st
 gnutls_mac_algorithm_t _gnutls_cipher_suite_get_mac_algo (const
                                                           cipher_suite_st *
                                                           algorithm);
-gnutls_protocol_t _gnutls_cipher_suite_is_version_supported (const
-                                                             cipher_suite_st *
-                                                             algorithm,
-                                                             
gnutls_protocol_t);
 cipher_suite_st _gnutls_cipher_suite_get_suite_name (cipher_suite_st *
                                                      algorithm);
 
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 692e61b..a57784f 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -55,6 +55,7 @@
 #include <gnutls_buffers.h>
 #include <gnutls_mbuffers.h>
 #include <gnutls_state.h>
+#include <gnutls_dtls.h>
 #include <system.h>
 
 #include <errno.h>
@@ -271,8 +272,8 @@ static ssize_t
 _gnutls_dgram_read (gnutls_session_t session, mbuffer_st **bufel,
                    gnutls_pull_func pull_func)
 {
-  ssize_t i;
-  char *ptr = alloca (MAX_RECV_SIZE);
+  ssize_t i, ret;
+  char *ptr;
   gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
 
   if (!bufel)
@@ -281,11 +282,15 @@ _gnutls_dgram_read (gnutls_session_t session, mbuffer_st 
**bufel,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
+  ptr = gnutls_malloc(MAX_RECV_SIZE(session));
+  if (ptr == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
   session->internals.direction = 0;
 
   reset_errno (session);
 
-  i = pull_func (fd, ptr, MAX_RECV_SIZE);
+  i = pull_func (fd, ptr, MAX_RECV_SIZE(session));
 
   if (i < 0)
     {
@@ -295,13 +300,20 @@ _gnutls_dgram_read (gnutls_session_t session, mbuffer_st 
**bufel,
                        (int) i, fd, errno, session->internals.errnum);
 
       if (err == EAGAIN)
-       return GNUTLS_E_AGAIN;
+        {
+         ret = GNUTLS_E_AGAIN;
+         goto cleanup;
+        }
       else if (err == EINTR)
-       return GNUTLS_E_INTERRUPTED;
+        {
+         ret = GNUTLS_E_INTERRUPTED;
+         goto cleanup;
+        }
       else
        {
          gnutls_assert ();
-         return GNUTLS_E_PULL_ERROR;
+         ret = GNUTLS_E_PULL_ERROR;
+         goto cleanup;
        }
     }
   else
@@ -311,23 +323,28 @@ _gnutls_dgram_read (gnutls_session_t session, mbuffer_st 
**bufel,
        /* If we get here, we likely have a stream socket.
         * FIXME: this probably breaks DCCP. */
        gnutls_assert ();
-       return GNUTLS_E_INTERNAL_ERROR;
+       ret = GNUTLS_E_INTERNAL_ERROR;
+       goto cleanup;
       }
 
       *bufel = _mbuffer_alloc (0, i);
       if (!*bufel)
        {
          gnutls_assert ();
-         return GNUTLS_E_MEMORY_ERROR;
+         ret = GNUTLS_E_MEMORY_ERROR;
+         goto cleanup;
        }
 
       _mbuffer_append_data (*bufel, ptr, i);
     }
 
-  if (_gnutls_log_level >= 7)
-    _gnutls_read_log ("READ: read %d bytes from %p\n", (int) i, fd);
-
-  return i;
+  _gnutls_read_log ("READ: read %d bytes from %p\n", (int) i, fd);
+  
+  ret = i;
+  
+cleanup:
+  gnutls_free(ptr);
+  return ret;
 }
 
 static ssize_t
@@ -405,13 +422,9 @@ _gnutls_stream_read (gnutls_session_t session, mbuffer_st 
**bufel,
 
 finish:
 
-  if (_gnutls_log_level >= 7)
-    {
-      _gnutls_read_log ("READ: read %d bytes from %p\n",
+  _gnutls_read_log ("READ: read %d bytes from %p\n",
                         (int) (size - left), fd);
 
-    }
-
   return (size - left);
 }
 
@@ -549,7 +562,7 @@ _gnutls_io_read_buffered (gnutls_session_t session, size_t 
total,
   mbuffer_st *bufel = NULL;
   size_t recvlowat, recvdata, readsize;
 
-  if (total > MAX_RECV_SIZE || total == 0)
+  if (total > MAX_RECV_SIZE(session) || total == 0)
     {
       gnutls_assert ();         /* internal error */
       return GNUTLS_E_INVALID_REQUEST;
@@ -610,7 +623,7 @@ _gnutls_io_read_buffered (gnutls_session_t session, size_t 
total,
    * receive are longer than the maximum receive buffer size.
    */
   if ((session->internals.record_recv_buffer.byte_length + recvdata) >
-      MAX_RECV_SIZE)
+      MAX_RECV_SIZE(session))
     {
       gnutls_assert ();         /* internal error */
       return GNUTLS_E_INVALID_REQUEST;
@@ -823,6 +836,29 @@ _gnutls_io_write_flush (gnutls_session_t session)
   return sent;
 }
 
+#include "debug.h"
+/* Checks whether there are received data within
+ * a timeframe.
+ *
+ * Returns 0 if data were received, GNUTLS_E_TIMEDOUT
+ * on timeout and a negative value on error.
+ */
+int
+_gnutls_io_check_recv (gnutls_session_t session, int ms)
+{
+  gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;
+  int ret;
+  
+  
+  ret = system_recv_timeout(fd, ms);
+  if (ret == -1)
+    return gnutls_assert_val(GNUTLS_E_PULL_ERROR);
+  
+  if (ret > 0)
+    return 0;
+  else return GNUTLS_E_TIMEDOUT;
+}
+
 /* This function writes the data that are left in the
  * Handshake write buffer (ie. because the previous write was
  * interrupted.
@@ -841,13 +877,17 @@ _gnutls_handshake_io_write_flush (gnutls_session_t 
session)
   _gnutls_write_log ("HWRITE FLUSH: %d bytes in buffer.\n",
                      (int) send_buffer->byte_length);
 
+  if (IS_DTLS(session))
+    return _gnutls_dtls_transmit(session);
+
+
   for (cur = _mbuffer_get_first (send_buffer, &msg);
        cur != NULL; cur = _mbuffer_get_first (send_buffer, &msg))
     {
-      ret = _gnutls_send_int (session, GNUTLS_HANDSHAKE,
-                              session->internals.handshake_send_buffer_htype,
+      ret = _gnutls_send_int (session, cur->type,
+                              cur->htype,
                               EPOCH_WRITE_CURRENT,
-                              msg.data, msg.size, 0 /* do not flush */ );
+                              msg.data, msg.size, 0);
 
       if (ret >= 0)
         {
@@ -877,22 +917,32 @@ _gnutls_handshake_io_write_flush (gnutls_session_t 
session)
  * protocol. Just makes sure that all data have been sent.
  *
  */
-void
+int
 _gnutls_handshake_io_cache_int (gnutls_session_t session,
                                 gnutls_handshake_description_t htype,
                                 mbuffer_st * bufel)
 {
-  mbuffer_head_st *const send_buffer =
+  mbuffer_head_st * send_buffer;
+  
+  if (IS_DTLS(session))
+    return _gnutls_dtls_handshake_enqueue(session, bufel, htype, 
session->internals.dtls.hsk_write_seq-1);
+  
+  send_buffer =
     &session->internals.handshake_send_buffer;
 
+  bufel->htype = htype;
+  if (bufel->htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC)
+    bufel->type = GNUTLS_CHANGE_CIPHER_SPEC;
+  else
+    bufel->type = GNUTLS_HANDSHAKE;
+
   _mbuffer_enqueue (send_buffer, bufel);
-  session->internals.handshake_send_buffer_htype = htype;
 
   _gnutls_write_log
     ("HWRITE: enqueued %d. Total %d bytes.\n",
      (int) bufel->msg.size, (int) send_buffer->byte_length);
 
-  return;
+  return 0;
 }
 
 /* This is a receive function for the gnutls handshake 
diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h
index 3dfad55..8028f73 100644
--- a/lib/gnutls_buffers.h
+++ b/lib/gnutls_buffers.h
@@ -56,10 +56,11 @@ int _gnutls_handshake_buffer_get_ptr (gnutls_session_t 
session,
 ssize_t _gnutls_handshake_io_recv_int (gnutls_session_t, content_type_t,
                                        gnutls_handshake_description_t, void *,
                                        size_t);
-void _gnutls_handshake_io_cache_int (gnutls_session_t,
+int _gnutls_handshake_io_cache_int (gnutls_session_t,
                                      gnutls_handshake_description_t,
                                      mbuffer_st * bufel);
 ssize_t _gnutls_io_write_flush (gnutls_session_t session);
+int _gnutls_io_check_recv (gnutls_session_t session, int ms);
 ssize_t _gnutls_handshake_io_write_flush (gnutls_session_t session);
 
 #endif
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index eeee430..0f569c3 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -46,7 +46,7 @@
 static int _gnutls_compressed2ciphertext (gnutls_session_t session,
                                    opaque * cipher_data, int cipher_size,
                                    gnutls_datum_t compressed,
-                                   content_type_t _type, int random_pad,
+                                   content_type_t _type, 
                                    record_parameters_st * params);
 static int _gnutls_ciphertext2compressed (gnutls_session_t session,
                                    opaque * compress_data,
@@ -82,7 +82,7 @@ int
 _gnutls_encrypt (gnutls_session_t session, const opaque * headers,
                  size_t headers_size, const opaque * data,
                  size_t data_size, opaque * ciphertext,
-                 size_t ciphertext_size, content_type_t type, int random_pad,
+                 size_t ciphertext_size, content_type_t type, 
                  record_parameters_st * params)
 {
   gnutls_datum_t plain;
@@ -115,7 +115,7 @@ _gnutls_encrypt (gnutls_session_t session, const opaque * 
headers,
 
   ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size],
                                        ciphertext_size - headers_size,
-                                       comp, type, random_pad, params);
+                                       comp, type, params);
 
   if (free_comp)
     _gnutls_free_datum (&comp);
@@ -310,7 +310,7 @@ static int
 _gnutls_compressed2ciphertext (gnutls_session_t session,
                                opaque * cipher_data, int cipher_size,
                                gnutls_datum_t compressed,
-                               content_type_t type, int random_pad,
+                               content_type_t type, 
                                record_parameters_st * params)
 {
   uint8_t * tag_ptr = NULL;
@@ -326,8 +326,11 @@ _gnutls_compressed2ciphertext (gnutls_session_t session,
   int ver = gnutls_protocol_get_version (session);
   int explicit_iv = _gnutls_version_has_explicit_iv 
(session->security_parameters.version);
   int auth_cipher = _gnutls_auth_cipher_is_aead(&params->write.cipher_state);
+  int random_pad = (session->internals.priorities.no_padding == 0) ? 1 : 0;
   
-
+  _gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n",
+    session, gnutls_cipher_get_name(params->cipher_algorithm), 
gnutls_mac_get_name(params->mac_algorithm),
+    (unsigned int)params->epoch);
   preamble_size =
     make_preamble (UINT64DATA
                    (params->write.sequence_number),
@@ -572,8 +575,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
        * MAC.
        */
       preamble_size =
-        make_preamble (UINT64DATA
-                       (params->read.sequence_number), type,
+        make_preamble (UINT64DATA(*sequence), type,
                        length, ver, preamble);
       _gnutls_auth_cipher_add_auth (&params->read.cipher_state, preamble, 
preamble_size);
       _gnutls_auth_cipher_add_auth (&params->read.cipher_state, 
ciphertext.data, length);
diff --git a/lib/gnutls_cipher.h b/lib/gnutls_cipher.h
index 19667de..0af1935 100644
--- a/lib/gnutls_cipher.h
+++ b/lib/gnutls_cipher.h
@@ -27,7 +27,7 @@ int _gnutls_encrypt (gnutls_session_t session, const opaque * 
headers,
                      size_t headers_size, const opaque * data,
                      size_t data_size, opaque * ciphertext,
                      size_t ciphertext_size, content_type_t type,
-                     int random_pad, record_parameters_st * params);
+                     record_parameters_st * params);
 
 int _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
                      size_t ciphertext_size, uint8_t * data, size_t data_size,
diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c
index d0934a5..b01f92a 100644
--- a/lib/gnutls_dtls.c
+++ b/lib/gnutls_dtls.c
@@ -30,6 +30,9 @@
 #include "debug.h"
 #include "gnutls_dtls.h"
 #include "gnutls_record.h"
+#include <gnutls_mbuffers.h>
+#include <gnutls_buffers.h>
+#include <gnutls_constate.h>
 
 /* This function is called once a handshake message is ready to be
  * queued in the next outgoing flight. The actual transmission occurs
@@ -39,12 +42,17 @@
  */
 int
 _gnutls_dtls_handshake_enqueue (gnutls_session_t session,
-                               opaque *data,
-                               uint32_t datasize,
+                               mbuffer_st* bufel,
                                gnutls_handshake_description_t type,
                                uint16_t sequence)
 {
   dtls_hsk_retransmit_buffer *msg;
+  record_parameters_st * params;
+  int ret;
+
+  ret = _gnutls_epoch_get( session, EPOCH_WRITE_CURRENT, &params);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
   msg = gnutls_malloc (sizeof(dtls_hsk_retransmit_buffer));
   if (msg == NULL)
@@ -53,27 +61,17 @@ _gnutls_dtls_handshake_enqueue (gnutls_session_t session,
       return GNUTLS_E_MEMORY_ERROR;
     }
 
-  msg->msg.size = datasize - DTLS_HANDSHAKE_HEADER_SIZE;
-
-  msg->msg.data = gnutls_malloc (msg->msg.size);
-  if (msg->msg.data == NULL)
-    {
-      gnutls_free (msg);
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  memcpy (msg->msg.data, data + DTLS_HANDSHAKE_HEADER_SIZE, msg->msg.size);
+  msg->bufel = bufel;
 
   msg->next = NULL;
-  /* FIXME: dummy epoch */
-  msg->epoch = 0;
+
+  msg->epoch = params->epoch;
   msg->type = type;
   msg->sequence = sequence;
 
   _gnutls_dtls_log ("DTLS[%p]: Enqueued Packet[%u] %s(%d) with length: %u\n",
                    session, (uint)sequence, _gnutls_handshake2str (type),
-                   type, msg->msg.size);
+                   type, msg->bufel->msg.size);
 
   *(session->internals.dtls.retransmit_end) = msg;
   session->internals.dtls.retransmit_end = &msg->next;
@@ -87,61 +85,74 @@ static inline int
 transmit_message (gnutls_session_t session,
                  dtls_hsk_retransmit_buffer *msg)
 {
-  opaque *data;
-  uint offset, frag_len;
+  opaque *data, *mtu_data;
+  int ret = 0;
+  unsigned int offset, frag_len, data_size;
   const uint mtu = session->internals.dtls.hsk_mtu;
 
-  data = gnutls_malloc (DTLS_HANDSHAKE_HEADER_SIZE + mtu);
-  if (data == NULL)
+  if (msg->type == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC)
     {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
+      return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1,
+        msg->epoch, 
+        _mbuffer_get_uhead_ptr(msg->bufel), 
+        _mbuffer_get_uhead_size(msg->bufel), 0);
     }
 
+  mtu_data = gnutls_malloc(mtu + DTLS_HANDSHAKE_HEADER_SIZE);
+  if (mtu_data == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+  data = _mbuffer_get_udata_ptr( msg->bufel);
+  data_size = _mbuffer_get_udata_size(msg->bufel);
+
   /* Write fixed headers
    */
 
   /* Handshake type */
-  data[0] = (uint8_t) msg->type;
+  mtu_data[0] = (uint8_t) msg->type;
 
   /* Total length */
-  _gnutls_write_uint24 (msg->msg.size, &data[1]);
+  _gnutls_write_uint24 (data_size, &mtu_data[1]);
 
   /* Handshake sequence */
-  _gnutls_write_uint16 (msg->sequence, &data[4]);
+  _gnutls_write_uint16 (msg->sequence, &mtu_data[4]);
 
   /* Chop up and send handshake message into mtu-size pieces. */
-  for (offset=0; offset < msg->msg.size; offset += mtu)
+  for (offset=0; offset < data_size; offset += mtu)
     {
       /* Calculate fragment length */
-      if(offset + mtu > msg->msg.size)
-       frag_len = msg->msg.size - offset;
+      if(offset + mtu > data_size)
+        frag_len = data_size - offset;
       else
-       frag_len = mtu;
+        frag_len = mtu;
 
       /* Fragment offset */
-      _gnutls_write_uint24 (offset, &data[6]);
+      _gnutls_write_uint24 (offset, &mtu_data[6]);
 
       /* Fragment length */
-      _gnutls_write_uint24 (frag_len, &data[9]);
+      _gnutls_write_uint24 (frag_len, &mtu_data[9]);
 
-      memcpy (&data[12], msg->msg.data + offset, frag_len);
+      
+      memcpy (&mtu_data[12], data+offset, frag_len);
 
       _gnutls_dtls_log ("DTLS[%p]: Sending Packet[%u] fragment %s(%d) with "
                        "length: %u, offset: %u, fragment length: %u\n",
                        session, msg->sequence,
                        _gnutls_handshake2str (msg->type),
-                       msg->type, msg->msg.size, offset, frag_len);
+                       msg->type, data_size, offset, frag_len);
 
       /* FIXME: We should collaborate with the record layer to pack as
-        many records possible into a single datagram. We should also
-        tell the record layer which epoch to use for encryption. */
-      _gnutls_send_int (session, GNUTLS_HANDSHAKE, msg->type, 
EPOCH_WRITE_CURRENT,
-                       data, DTLS_HANDSHAKE_HEADER_SIZE + frag_len, 0);
+       * many records possible into a single datagram. We should also
+       * tell the record layer which epoch to use for encryption. 
+       */
+      ret = _gnutls_send_int (session, GNUTLS_HANDSHAKE, msg->type, msg->epoch,
+        mtu_data, DTLS_HANDSHAKE_HEADER_SIZE + frag_len, 0);
+      if (ret < 0)
+        break;
    }
 
-  gnutls_free (data);
-  return 0;
+  gnutls_free (mtu_data);
+  return ret;
 }
 
 /* This function transmits the flight that has been previously
@@ -153,15 +164,26 @@ transmit_message (gnutls_session_t session,
 int
 _gnutls_dtls_transmit (gnutls_session_t session)
 {
+int ret;
+
   /* PREPARING -> SENDING state transition */
   dtls_hsk_retransmit_buffer *msg;
 
+restart:
   _gnutls_dtls_log ("DTLS[%p]: Start of flight transmission.\n", session);
 
   for (msg = session->internals.dtls.retransmit; msg != NULL; msg = msg->next)
     transmit_message (session, msg);
-  _gnutls_io_write_flush (session);
 
+  ret = _gnutls_io_write_flush (session);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  ret = _gnutls_io_check_recv(session, 100);
+  if (ret == GNUTLS_E_TIMEDOUT)
+    goto restart;
+  else if (ret < 0)
+    return gnutls_assert_val(ret);
 
   _gnutls_dtls_log ("DTLS[%p]: End of flight transmission.\n", session);
 
@@ -183,7 +205,7 @@ _gnutls_dtls_clear_outgoing_buffer (gnutls_session_t 
session)
     {
       next = msg->next;
 
-      gnutls_free (msg->msg.data);
+      _mbuffer_xfree(&msg->bufel);
       gnutls_free (msg);
 
       msg = next;
@@ -193,6 +215,7 @@ _gnutls_dtls_clear_outgoing_buffer (gnutls_session_t 
session)
   session->internals.dtls.retransmit = NULL;
 }
 
+#if 0
 void
 _gnutls_dtls_split_sequence (const uint64 *input,
                             uint16_t *epoch, uint64_t *sequence)
@@ -200,5 +223,6 @@ _gnutls_dtls_split_sequence (const uint64 *input,
   *epoch = _gnutls_read_uint16 (UINT64DATA(*input));
   *sequence = _gnutls_read_uint48 (&UINT64DATA(*input)[2]);
 
-  fprintf(stderr, "%04x:%012lx\n", *epoch, *sequence);
+//  fprintf(stderr, "%04x:%012lx\n", *epoch, *sequence);
 }
+#endif
diff --git a/lib/gnutls_dtls.h b/lib/gnutls_dtls.h
index f870c1b..80958dd 100644
--- a/lib/gnutls_dtls.h
+++ b/lib/gnutls_dtls.h
@@ -27,14 +27,13 @@
 
 #include "gnutls_int.h"
 
-int _gnutls_dtls_handshake_enqueue(gnutls_session_t session,
-                                  opaque *data,
-                                  uint32_t datasize,
-                                  gnutls_handshake_description_t type,
-                                  uint16_t sequence);
+int
+_gnutls_dtls_handshake_enqueue (gnutls_session_t session,
+                               mbuffer_st* bufel,
+                               gnutls_handshake_description_t type,
+                               uint16_t sequence);
 
 int _gnutls_dtls_transmit(gnutls_session_t session);
 void _gnutls_dtls_clear_outgoing_buffer(gnutls_session_t session);
-void _gnutls_dtls_split_sequence(const uint64 *input, uint16_t *epoch, 
uint64_t *sequence);
 
 #endif
diff --git a/lib/gnutls_errors.h b/lib/gnutls_errors.h
index 5444042..1af2517 100644
--- a/lib/gnutls_errors.h
+++ b/lib/gnutls_errors.h
@@ -65,7 +65,7 @@ _gnutls_log (int, const char *fmt, ...)
 #define _gnutls_buffers_log(...) LEVEL_EQ(6, __VA_ARGS__)
 #define _gnutls_hard_log(...) LEVEL(9, __VA_ARGS__)
 #define _gnutls_record_log(...) LEVEL(4, __VA_ARGS__)
-# define _gnutls_dtls_log(...) LEVEL(6, __VA_ARGS__)
+#define _gnutls_dtls_log(...) LEVEL(6, __VA_ARGS__)
 #define _gnutls_read_log(...) LEVEL_EQ(7, __VA_ARGS__)
 #define _gnutls_write_log(...) LEVEL_EQ(7, __VA_ARGS__)
 #define _gnutls_x509_log(...) LEVEL(1, __VA_ARGS__)
@@ -76,7 +76,7 @@ _gnutls_log (int, const char *fmt, ...)
 #define _gnutls_buffers_log _gnutls_null_log
 #define _gnutls_hard_log _gnutls_null_log
 #define _gnutls_record_log _gnutls_null_log
-# define _gnutls_dtls_log _gnutls_null_log
+#define _gnutls_dtls_log _gnutls_null_log
 #define _gnutls_read_log _gnutls_null_log
 #define _gnutls_write_log _gnutls_null_log
 #define _gnutls_x509_log _gnutls_null_log
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 81bb263..9889c3b 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- * 2009, 2010 Free Software Foundation, Inc.
+ * 2009, 2010, 2011 Free Software Foundation, Inc.
  *
  * Author: Nikos Mavrogiannopoulos
  *
@@ -33,7 +33,6 @@
 #include "gnutls_algorithms.h"
 #include "gnutls_compress.h"
 #include "gnutls_cipher.h"
-#include "gnutls_dtls.h"
 #include "gnutls_buffers.h"
 #include "gnutls_mbuffers.h"
 #include "gnutls_kx.h"
@@ -840,7 +839,7 @@ _gnutls_recv_finished (gnutls_session_t session)
  * RSA algorithms, PK_DSA if DSS, and PK_ANY for both or PK_NONE for none.
  */
 static int
-_gnutls_server_find_pk_algos_in_ciphersuites (const opaque *
+server_find_pk_algos_in_ciphersuites (const opaque *
                                               data, unsigned int datalen)
 {
   unsigned int j;
@@ -911,7 +910,7 @@ _gnutls_server_select_suite (gnutls_session_t session, 
opaque * data,
         }
     }
 
-  pk_algo = _gnutls_server_find_pk_algos_in_ciphersuites (data, datalen);
+  pk_algo = server_find_pk_algos_in_ciphersuites (data, datalen);
 
   x = _gnutls_supported_ciphersuites (session, &ciphers);
   if (x < 0)
@@ -1241,17 +1240,19 @@ _gnutls_send_handshake (gnutls_session_t session, 
mbuffer_st * bufel,
          _gnutls_handshake_hash_add_sent (session, type, data, datasize)) < 0)
       {
         gnutls_assert ();
-        gnutls_free (bufel);
+      _mbuffer_xfree(&bufel);
         return ret;
       }
 
   session->internals.last_handshake_out = type;
 
-  if (_gnutls_is_dtls(session))
-    _gnutls_dtls_handshake_enqueue (session, data, datasize, type,
-                                   session->internals.dtls.hsk_write_seq-1);
-  else
-    _gnutls_handshake_io_cache_int (session, type, bufel);
+  ret = _gnutls_handshake_io_cache_int (session, type, bufel);
+  if (ret < 0)
+    {
+      _mbuffer_xfree(&bufel);
+      gnutls_assert();
+      return ret;
+    }
 
   switch (type)
     {
@@ -1294,7 +1295,7 @@ _gnutls_recv_handshake_header (gnutls_session_t session,
   int ret;
   uint32_t length32 = 0;
   uint8_t *dataptr = NULL;      /* for realloc */
-  size_t handshake_header_size = HANDSHAKE_HEADER_SIZE;
+  size_t handshake_header_size = HANDSHAKE_HEADER_SIZE(session);
 
   /* if we have data into the buffer then return them, do not read the next 
packet.
    * In order to return we need a full TLS handshake header, or in case of a 
version 2
@@ -1357,7 +1358,7 @@ _gnutls_recv_handshake_header (gnutls_session_t session,
                                        [session->
                                         internals.handshake_header_buffer.
                                         header_size],
-                                       HANDSHAKE_HEADER_SIZE -
+                                       HANDSHAKE_HEADER_SIZE(session) -
                                        session->
                                        internals.handshake_header_buffer.
                                        header_size);
@@ -1367,7 +1368,7 @@ _gnutls_recv_handshake_header (gnutls_session_t session,
           return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
         }
       if ((size_t) ret !=
-          HANDSHAKE_HEADER_SIZE -
+          HANDSHAKE_HEADER_SIZE(session) -
           session->internals.handshake_header_buffer.header_size)
         {
           gnutls_assert ();
@@ -1379,11 +1380,11 @@ _gnutls_recv_handshake_header (gnutls_session_t session,
        * that the packet has enough data.
        */
       length32 = _gnutls_read_uint24 (&dataptr[1]);
-      handshake_header_size = HANDSHAKE_HEADER_SIZE;
+      handshake_header_size = HANDSHAKE_HEADER_SIZE(session);
 
       _gnutls_handshake_log ("HSK[%p]: %s was received [%ld bytes]\n",
                              session, _gnutls_handshake2str (dataptr[0]),
-                             (long int) (length32 + HANDSHAKE_HEADER_SIZE));
+                             (long int) (length32 + 
HANDSHAKE_HEADER_SIZE(session)));
 
     }
   else
@@ -1488,7 +1489,7 @@ _gnutls_handshake_hash_add_recvd (gnutls_session_t 
session,
 int
 _gnutls_recv_handshake (gnutls_session_t session, uint8_t ** data,
                         int *datalen, gnutls_handshake_description_t type,
-                        Optional optional)
+                        optional_t optional)
 {
   int ret;
   uint32_t length32 = 0;
@@ -1541,8 +1542,9 @@ _gnutls_recv_handshake (gnutls_session_t session, uint8_t 
** data,
       if (ret <= 0)
         {
           gnutls_assert ();
-          gnutls_free (dataptr);
-          return (ret == 0) ? GNUTLS_E_UNEXPECTED_PACKET_LENGTH : ret;
+          if (ret == 0) 
+            ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+          goto cleanup;
         }
     }
 
@@ -1557,12 +1559,6 @@ _gnutls_recv_handshake (gnutls_session_t session, 
uint8_t ** data,
                                           session->
                                           internals.handshake_header_buffer.
                                           header_size, dataptr, length32);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      _gnutls_handshake_header_buffer_clear (session);
-      return ret;
-    }
 
   /* If we fail before this then we will reuse the handshake header
    * have have received above. if we get here the we clear the handshake
@@ -1570,47 +1566,57 @@ _gnutls_recv_handshake (gnutls_session_t session, 
uint8_t ** data,
    */
   _gnutls_handshake_header_buffer_clear (session);
 
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
   switch (recv_type)
     {
     case GNUTLS_HANDSHAKE_CLIENT_HELLO:
     case GNUTLS_HANDSHAKE_SERVER_HELLO:
       ret = _gnutls_recv_hello (session, dataptr, length32);
-
-      /* dataptr is freed because the caller does not
-       * need it */
-      gnutls_free (dataptr);
-      if (data != NULL)
-        *data = NULL;
-
       if (ret < 0)
-        break;
+        {
+          gnutls_assert();
+          goto cleanup;
+        }
 
       /* initialize the hashes for both - (client will know server's version
        * and server as well at this point) */
       if ((ret = _gnutls_handshake_hash_init (session)) < 0)
         {
           gnutls_assert ();
-          return ret;
+          goto cleanup;
         }
 
+      goto cleanup; /* caller doesn't need dataptr */
+
       break;
     case GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST:
       ret = _gnutls_recv_hello_verify_request (session, dataptr, length32);
-      gnutls_free (dataptr);
-
       if (ret < 0)
-       break;
+        {
+          gnutls_assert();
+          goto cleanup;
+        }
       else
        /* Signal our caller we have received a verification cookie
           and ClientHello needs to be sent again. */
        ret = 1;
+       
+      goto cleanup; /* caller doesn't need dataptr */
 
       break;
     case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
       if (length32 == 0)
         ret = 0;
       else
-        ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+        {
+          ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+          goto cleanup;
+        }
       break;
     case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
     case GNUTLS_HANDSHAKE_FINISHED:
@@ -1624,13 +1630,17 @@ _gnutls_recv_handshake (gnutls_session_t session, 
uint8_t ** data,
       break;
     default:
       gnutls_assert ();
-      gnutls_free (dataptr);
-      if (data != NULL)
-        *data = NULL;
       ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
+      goto cleanup;
     }
 
   return ret;
+
+cleanup:
+  gnutls_free (dataptr);
+  if (data != NULL)
+    *data = NULL;
+  return ret;
 }
 
 /* This function checks if the given cipher suite is supported, and sets it
@@ -2858,8 +2868,6 @@ _gnutls_handshake_client (gnutls_session_t session)
       STATE = STATE1;
       IMED_RET ("send hello", ret, 1);
 
-      _gnutls_dtls_transmit(session);
-
     case STATE11:
       if (_gnutls_is_dtls (session))
        {
@@ -2955,7 +2963,6 @@ _gnutls_handshake_client (gnutls_session_t session)
           _gnutls_send_client_certificate_verify (session, AGAIN (STATE9));
       STATE = STATE9;
       IMED_RET ("send client certificate verify", ret, 1);
-      _gnutls_dtls_transmit(session);
 
       STATE = STATE0;
     default:
@@ -2966,6 +2973,51 @@ _gnutls_handshake_client (gnutls_session_t session)
   return 0;
 }
 
+
+
+/* This function is to be called if the handshake was successfully 
+ * completed. This sends a Change Cipher Spec packet to the peer.
+ */
+static ssize_t
+send_change_cipher_spec (gnutls_session_t session, int again)
+{
+  opaque* data;
+  mbuffer_st * bufel;
+  int ret;
+  
+  if (again == 0)
+    {
+      bufel = _gnutls_handshake_alloc (session, 1, 1);
+      if (bufel == NULL)
+        return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+      _mbuffer_set_uhead_size(bufel, 1);
+      _mbuffer_set_udata_size(bufel, 0);
+
+      data = _mbuffer_get_uhead_ptr (bufel);
+      
+      data[0] = 1;
+
+      ret = _gnutls_handshake_io_cache_int (session, 
GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC, bufel);
+      if (ret < 0)
+        {
+          _mbuffer_xfree(&bufel);
+          return gnutls_assert_val(ret);
+        }
+
+      if (!IS_DTLS(session)) /* remove once combined */
+        {
+          ret = _gnutls_handshake_io_write_flush (session);
+          if (ret < 0)
+            return gnutls_assert_val(ret);
+        }
+
+      _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session);
+    }
+
+    return 0;
+}
+
 /* This function sends the final handshake packets and initializes connection 
  */
 static int
@@ -2979,19 +3031,8 @@ _gnutls_send_handshake_final (gnutls_session_t session, 
int init)
     {
     case STATE0:
     case STATE20:
-
-      STATE = STATE20;
-
-      ret = _gnutls_handshake_io_write_flush (session);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-
-    case STATE21:
-      ret = _gnutls_send_change_cipher_spec (session, AGAIN (STATE21));
-      STATE = STATE21;
+      ret = send_change_cipher_spec (session, AGAIN (STATE20));
+      STATE = STATE0;
 
       if (ret < 0)
         {
@@ -3018,10 +3059,10 @@ _gnutls_send_handshake_final (gnutls_session_t session, 
int init)
           return ret;
         }
 
-    case STATE22:
+    case STATE21:
       /* send the finished message */
-      ret = _gnutls_send_finished (session, AGAIN (STATE22));
-      STATE = STATE22;
+      ret = _gnutls_send_finished (session, AGAIN (STATE21));
+      STATE = STATE21;
       if (ret < 0)
         {
           ERR ("send Finished", ret);
@@ -3029,7 +3070,6 @@ _gnutls_send_handshake_final (gnutls_session_t session, 
int init)
           return ret;
         }
 
-      _gnutls_dtls_transmit(session);
       STATE = STATE0;
     default:
       break;
@@ -3448,7 +3488,6 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t 
session,
   int newSuiteSize = 0, i;
   gnutls_certificate_credentials_t cert_cred;
   gnutls_kx_algorithm_t kx;
-  gnutls_cipher_algorithm_t cid;
   int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
   gnutls_kx_algorithm_t *alg = NULL;
   int alg_size = 0;
@@ -3533,15 +3572,6 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t 
session,
             delete = 1;
         }
 
-      /* if dtls and not appropriate for dtls */
-      if(_gnutls_is_dtls(session))
-       {
-         cid = _gnutls_cipher_suite_get_cipher_algo (&(*cipherSuites)[i]);
-
-         if(cid == GNUTLS_CIPHER_ARCFOUR_128 || cid == 
GNUTLS_CIPHER_ARCFOUR_40)
-           delete = 1;
-       }
-
       memcpy (&cs.suite, &(*cipherSuites)[i].suite, 2);
 
       if (delete == 0)
diff --git a/lib/gnutls_handshake.h b/lib/gnutls_handshake.h
index 0af8e12..e320044 100644
--- a/lib/gnutls_handshake.h
+++ b/lib/gnutls_handshake.h
@@ -24,7 +24,7 @@
  */
 
 typedef enum Optional
-{ OPTIONAL_PACKET, MANDATORY_PACKET } Optional;
+{ OPTIONAL_PACKET, MANDATORY_PACKET } optional_t;
 
 int _gnutls_send_handshake (gnutls_session_t session, mbuffer_st * bufel,
                             gnutls_handshake_description_t type);
@@ -34,7 +34,7 @@ int _gnutls_send_hello (gnutls_session_t session, int again);
 int _gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen);
 int _gnutls_recv_handshake (gnutls_session_t session, uint8_t **, int *,
                             gnutls_handshake_description_t,
-                            Optional optional);
+                            optional_t optional);
 int _gnutls_generate_session_id (opaque * session_id, uint8_t * len);
 int _gnutls_handshake_common (gnutls_session_t session);
 int _gnutls_handshake_client (gnutls_session_t session);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 90efdb5..20d7422 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -57,11 +57,6 @@ typedef struct
   unsigned char i[8];
 } uint64;
 
-typedef struct
-{
-  unsigned char i[6];
-} uint48;
-
 #include <gnutls/gnutls.h>
 
 /*
@@ -151,12 +146,12 @@ typedef enum transport_t
 } transport_t;
 
 /* the maximum size of encrypted packets */
-#define IS_DTLS (session->internals.transport == GNUTLS_DGRAM)
+#define IS_DTLS(session) (session->internals.transport == GNUTLS_DGRAM)
 
 #define DEFAULT_MAX_RECORD_SIZE 16384
 #define TLS_RECORD_HEADER_SIZE 5
 #define DTLS_RECORD_HEADER_SIZE (TLS_RECORD_HEADER_SIZE+8)
-#define RECORD_HEADER_SIZE (IS_DTLS ? DTLS_RECORD_HEADER_SIZE : 
TLS_RECORD_HEADER_SIZE)
+#define RECORD_HEADER_SIZE(session) (IS_DTLS(session) ? 
DTLS_RECORD_HEADER_SIZE : TLS_RECORD_HEADER_SIZE)
 #define MAX_RECORD_HEADER_SIZE DTLS_RECORD_HEADER_SIZE
 
 #define MAX_RECORD_SEND_SIZE 
(size_t)session->security_parameters.max_record_send_size
@@ -164,11 +159,11 @@ typedef enum transport_t
 #define MAX_PAD_SIZE 255
 #define EXTRA_COMP_SIZE 2048
 #define MAX_RECORD_OVERHEAD 
(MAX_CIPHER_BLOCK_SIZE/*iv*/+MAX_PAD_SIZE+EXTRA_COMP_SIZE)
-#define MAX_RECV_SIZE 
(MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE+RECORD_HEADER_SIZE)
+#define MAX_RECV_SIZE(session) 
(MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE+RECORD_HEADER_SIZE(session))
 
 #define TLS_HANDSHAKE_HEADER_SIZE 4
 #define DTLS_HANDSHAKE_HEADER_SIZE (TLS_HANDSHAKE_HEADER_SIZE+8)
-#define HANDSHAKE_HEADER_SIZE (IS_DTLS ? DTLS_HANDSHAKE_HEADER_SIZE : 
TLS_HANDSHAKE_HEADER_SIZE)
+#define HANDSHAKE_HEADER_SIZE(session) (IS_DTLS(session) ? 
DTLS_HANDSHAKE_HEADER_SIZE : TLS_HANDSHAKE_HEADER_SIZE)
 #define MAX_HANDSHAKE_HEADER_SIZE DTLS_HANDSHAKE_HEADER_SIZE
 
 /* This is the maximum handshake message size we send without
@@ -208,10 +203,6 @@ typedef struct
 
 #include <gnutls_mpi.h>
 
-typedef enum change_cipher_spec_t
-{ GNUTLS_TYPE_CHANGE_CIPHER_SPEC = 1
-} change_cipher_spec_t;
-
 typedef enum handshake_state_t
 { STATE0 = 0, STATE1, STATE2,
   STATE3, STATE4, STATE5,
@@ -273,6 +264,9 @@ typedef struct mbuffer_st
   size_t mark;
   unsigned int user_mark;       /* only used during fill in */
   size_t maximum_size;
+  
+  gnutls_handshake_description_t htype;
+  content_type_t type;
 } mbuffer_st;
 
 typedef struct mbuffer_head_st
@@ -284,6 +278,25 @@ typedef struct mbuffer_head_st
   size_t byte_length;
 } mbuffer_head_st;
 
+/* This is a linked list used to buffer the next flight of outgoing
+   handshake messages. Messages are queued whole; they are fragmented
+   dynamically on transmit. */
+typedef struct dtls_hsk_retransmit_buffer
+{
+  struct dtls_hsk_retransmit_buffer *next;
+
+  /* The actual handshake message */
+  mbuffer_st* bufel;
+
+  /* Record layer epoch of message */
+  uint16_t epoch;
+
+  /* Handshake layer type and sequence of message */
+  gnutls_handshake_description_t type;
+  uint16_t sequence;
+} dtls_hsk_retransmit_buffer;
+
+
 typedef enum
 {
   HANDSHAKE_MAC_TYPE_10 = 1,    /* TLS 1.0 style */
@@ -531,27 +544,6 @@ typedef struct
   int free_rsa_params;
 } internal_params_st;
 
-struct dtls_hsk_retransmit_buffer;
-typedef struct dtls_hsk_retransmit_buffer dtls_hsk_retransmit_buffer;
-
-/* This is a linked list used to buffer the next flight of outgoing
-   handshake messages. Messages are queued whole; they are fragmented
-   dynamically on transmit. */
-struct dtls_hsk_retransmit_buffer
-{
-  dtls_hsk_retransmit_buffer *next;
-
-  /* The actual handshake message */
-  gnutls_datum_t msg;
-
-  /* Record layer epoch of message */
-  uint16_t epoch;
-
-  /* Handshake layer type and sequence of message */
-  gnutls_handshake_description_t type;
-  uint16_t sequence;
-};
-
 /* DTLS session state
  */
 typedef struct
@@ -653,7 +645,6 @@ typedef struct
    * protocol only. freed using _gnutls_handshake_io_buffer_clear();
    */
   mbuffer_head_st handshake_send_buffer;
-  gnutls_handshake_description_t handshake_send_buffer_htype;
   content_type_t handshake_recv_buffer_type;
   gnutls_handshake_description_t handshake_recv_buffer_htype;
   gnutls_buffer_st handshake_recv_buffer;
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index d105c16..7c390f0 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -452,7 +452,7 @@ _gnutls_recv_server_kx_message (gnutls_session_t session)
   uint8_t *data = NULL;
   int datasize;
   int ret = 0;
-  Optional optflag = MANDATORY_PACKET;
+  optional_t optflag = MANDATORY_PACKET;
 
   if (session->internals.auth_struct->gnutls_process_server_kx != NULL)
     {
diff --git a/lib/gnutls_mbuffers.h b/lib/gnutls_mbuffers.h
index 6b3f424..571e467 100644
--- a/lib/gnutls_mbuffers.h
+++ b/lib/gnutls_mbuffers.h
@@ -95,13 +95,13 @@ _mbuffer_set_uhead_size (mbuffer_st * bufel, size_t size)
 inline static mbuffer_st *
 _gnutls_handshake_alloc (gnutls_session_t session, size_t size, size_t maximum)
 {
-  mbuffer_st *ret = _mbuffer_alloc (HANDSHAKE_HEADER_SIZE + size,
-                                    HANDSHAKE_HEADER_SIZE + maximum);
+  mbuffer_st *ret = _mbuffer_alloc (HANDSHAKE_HEADER_SIZE(session) + size,
+                                    HANDSHAKE_HEADER_SIZE(session) + maximum);
 
   if (!ret)
     return NULL;
 
-  _mbuffer_set_uhead_size (ret, HANDSHAKE_HEADER_SIZE);
+  _mbuffer_set_uhead_size (ret, HANDSHAKE_HEADER_SIZE(session));
 
   return ret;
 }
diff --git a/lib/gnutls_num.c b/lib/gnutls_num.c
index 786cf4d..2528447 100644
--- a/lib/gnutls_num.c
+++ b/lib/gnutls_num.c
@@ -67,27 +67,17 @@ _gnutls_uint64pp (uint64 * x)
  * has been reached.
  */
 int
-_gnutls_uint48pp (uint48 * x)
+_gnutls_uint48pp (uint64 * x)
 {
-  register int i, y = 0;
-
-  for (i = 5; i >= 0; i--)
-    {
-      y = 0;
-      if (x->i[i] == 0xff)
-       {
-         x->i[i] = 0;
-         y = 1;
-       }
-      else
-       x->i[i]++;
-
-      if (y == 0)
-       break;
-    }
-  if (y != 0)
-    return -1;                 /* over 48 bits! meh... */
-
+  int ret;
+  
+  ret = _gnutls_uint64pp(x);
+  if (ret != 0)
+    return ret;
+  
+  if (x->i[6] != 0)
+    return -1;
+    
   return 0;
 }
 
@@ -114,20 +104,6 @@ _gnutls_uint32touint24 (uint32_t num)
 
 }
 
-uint64_t
-_gnutls_uint48touint64 (uint48 num)
-{
-  uint64_t ret=0;
-
-  ((uint8_t *) & ret)[2] = num.i[0];
-  ((uint8_t *) & ret)[3] = num.i[1];
-  ((uint8_t *) & ret)[4] = num.i[2];
-  ((uint8_t *) & ret)[5] = num.i[3];
-  ((uint8_t *) & ret)[6] = num.i[4];
-  ((uint8_t *) & ret)[7] = num.i[5];
-  return ret;
-}
-
 /* data should be at least 3 bytes */
 uint32_t
 _gnutls_read_uint24 (const opaque * data)
@@ -237,18 +213,3 @@ _gnutls_uint64touint32 (const uint64 * num)
   return ret;
 }
 
-uint64_t
-_gnutls_read_uint48 (const opaque * data)
-{
-  uint64_t ret;
-  uint48 num;
-
-  memcpy(num.i, data, 6);
-
-  ret = _gnutls_uint48touint64 (num);
-#ifndef WORDS_BIGENDIAN
-  ret = bswap_64 (ret);
-#endif
-
-  return ret;
-}
diff --git a/lib/gnutls_num.h b/lib/gnutls_num.h
index 8e8aaea..456e34e 100644
--- a/lib/gnutls_num.h
+++ b/lib/gnutls_num.h
@@ -32,7 +32,6 @@
 
 uint32_t _gnutls_uint24touint32 (uint24 num);
 uint24 _gnutls_uint32touint24 (uint32_t num);
-uint64_t _gnutls_uint48touint64 (uint48 num);
 uint64_t _gnutls_read_uint48 (const opaque * data);
 uint32_t _gnutls_read_uint32 (const opaque * data);
 uint16_t _gnutls_read_uint16 (const opaque * data);
@@ -45,8 +44,8 @@ void _gnutls_write_uint16 (uint16_t num, opaque * data);
 uint32_t _gnutls_uint64touint32 (const uint64 *);
 
 int _gnutls_uint64pp (uint64 *);
-int _gnutls_uint48pp (uint48 *);
-# define _gnutls_uint64zero(x) x.i[0] = x.i[1] = x.i[2] = x.i[3] = x.i[4] = 
x.i[5] = x.i[6] = x.i[7] = 0
+int _gnutls_uint48pp (uint64 *);
+
 # define UINT64DATA(x) ((x).i)
 
 #endif /* GNUTLS_NUM_H */
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index a543b23..d1ba96a 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- * 2009, 2010 Free Software Foundation, Inc.
+ * 2009, 2010, 2011 Free Software Foundation, Inc.
  *
  * Author: Nikos Mavrogiannopoulos
  *
@@ -327,7 +327,7 @@ sequence_increment (gnutls_session_t session,
 {
   if (_gnutls_is_dtls(session))
     {
-      return _gnutls_uint48pp((uint48*)&value->i[2]);
+      return _gnutls_uint48pp(value);
     }
   else
     {
@@ -422,7 +422,7 @@ _gnutls_send_int (gnutls_session_t session, content_type_t 
type,
    */
   copy_record_version (session, htype, &headers[1]);
 
-  header_size = RECORD_HEADER_SIZE;
+  header_size = RECORD_HEADER_SIZE(session);
   /* Adjust header length and add sequence for DTLS */
     sequence_write(&record_state->sequence_number, &headers[3]);
 
@@ -465,9 +465,7 @@ _gnutls_send_int (gnutls_session_t session, content_type_t 
type,
       cipher_size =
         _gnutls_encrypt (session, headers, header_size, data,
                          data2send_size, _mbuffer_get_udata_ptr (bufel),
-                         cipher_size, type,
-                         (session->internals.priorities.no_padding ==
-                          0) ? 1 : 0, record_params);
+                         cipher_size, type, record_params);
       if (cipher_size <= 0)
         {
           gnutls_assert ();
@@ -528,25 +526,6 @@ _gnutls_send_int (gnutls_session_t session, content_type_t 
type,
   return retval;
 }
 
-/* This function is to be called if the handshake was successfully 
- * completed. This sends a Change Cipher Spec packet to the peer.
- */
-ssize_t
-_gnutls_send_change_cipher_spec (gnutls_session_t session, int again)
-{
-  static const opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
-
-  _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session);
-
-  if (again == 0)
-    return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1,
-                             EPOCH_WRITE_CURRENT, data, 1, MBUFFER_FLUSH);
-  else
-    {
-      return _gnutls_io_write_flush (session);
-    }
-}
-
 inline static int
 check_recv_type (content_type_t recv_type)
 {
@@ -685,7 +664,7 @@ record_check_version (gnutls_session_t session,
     {
       /* Reject hello packets with major version higher than 3.
        */
-      if (version[0] > 3)
+      if (!(IS_DTLS(session)) && version[0] > 3)
         {
           gnutls_assert ();
           _gnutls_record_log
@@ -968,7 +947,7 @@ begin:
 
 /* default headers for TLS 1.0
  */
-  header_size = RECORD_HEADER_SIZE;
+  header_size = RECORD_HEADER_SIZE(session);
 
   if ((ret =
        _gnutls_io_read_buffered (session, header_size, -1)) != header_size)
@@ -1047,7 +1026,7 @@ begin:
                       _gnutls_uint64touint32 (&record_state->sequence_number),
                       _gnutls_packet2str (recv_type), recv_type, length);
 
-  if (length > MAX_RECV_SIZE)
+  if (length > MAX_RECV_SIZE(session))
     {
       _gnutls_record_log
         ("REC[%p]: FATAL ERROR: Received packet with length: %d\n",
@@ -1094,8 +1073,10 @@ begin:
       return ret;
     }
 
-  decrypt_sequence =
-    _gnutls_is_dtls(session) ? &dtls_sequence : &record_state->sequence_number;
+  if (IS_DTLS(session))
+    decrypt_sequence = &dtls_sequence;
+  else
+    decrypt_sequence = &record_state->sequence_number;
 
 /* decrypt the data we got. 
  */
diff --git a/lib/gnutls_record.h b/lib/gnutls_record.h
index 3277314..b24b390 100644
--- a/lib/gnutls_record.h
+++ b/lib/gnutls_record.h
@@ -36,6 +36,5 @@ ssize_t _gnutls_send_int (gnutls_session_t session, 
content_type_t type,
 ssize_t _gnutls_recv_int (gnutls_session_t session, content_type_t type,
                           gnutls_handshake_description_t, opaque * data,
                           size_t sizeofdata);
-ssize_t _gnutls_send_change_cipher_spec (gnutls_session_t session, int again);
 
 #endif
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 2719c57..7aa02a3 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -56,7 +56,8 @@ sign_tls_hash (gnutls_session_t session, 
gnutls_digest_algorithm_t hash_algo,
 #define MAX_SIG_SIZE 19 + MAX_HASH_SIZE
 
 static int 
-get_hash_algo(gnutls_session_t session, gnutls_cert* cert, 
+get_hash_algo(gnutls_session_t session, int version,
+  gnutls_cert* cert, 
   gnutls_sign_algorithm_t sign_algo,
   gnutls_digest_algorithm_t *hash_algo)
 {
@@ -64,11 +65,16 @@ int ret;
 
   if (cert->subject_pk_algorithm == GNUTLS_PK_DSA)
     { /* override */
-      *hash_algo = _gnutls_dsa_q_to_hash (cert->params[1]);
+      if (!_gnutls_version_has_selectable_sighash (version))
+        *hash_algo = GNUTLS_DIG_SHA1;
+      else
+        {
+          *hash_algo = _gnutls_dsa_q_to_hash (cert->params[1]);
 
-      ret = _gnutls_session_sign_algo_requested(session, 
_gnutls_x509_pk_to_sign (GNUTLS_PK_DSA, *hash_algo));
-      if (ret < 0)
-        return gnutls_assert_val(ret);
+          ret = _gnutls_session_sign_algo_requested(session, 
_gnutls_x509_pk_to_sign (GNUTLS_PK_DSA, *hash_algo));
+          if (ret < 0)
+            return gnutls_assert_val(ret);
+        }
     }
   else
     {
@@ -105,7 +111,7 @@ _gnutls_handshake_sign_data (gnutls_session_t session, 
gnutls_cert * cert,
       return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
     }
 
-  ret = get_hash_algo(session, cert, *sign_algo, &hash_algo);
+  ret = get_hash_algo(session, ver, cert, *sign_algo, &hash_algo);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
@@ -387,7 +393,7 @@ _gnutls_handshake_verify_data (gnutls_session_t session, 
gnutls_cert * cert,
       _gnutls_hash (&td_md5, params->data, params->size);
     }
 
-  ret = get_hash_algo(session, cert, algo, &hash_algo);
+  ret = get_hash_algo(session, ver, cert, algo, &hash_algo);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index afdbb02..d1f0742 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -77,7 +77,11 @@ gnutls_cipher_algorithm_t
 gnutls_cipher_get (gnutls_session_t session)
 {
   record_parameters_st *record_params;
-  _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
+  int ret;
+  
+  ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
+  if (ret < 0)
+    return gnutls_assert_val(GNUTLS_CIPHER_NULL);
 
   return record_params->cipher_algorithm;
 }
@@ -126,7 +130,11 @@ gnutls_mac_algorithm_t
 gnutls_mac_get (gnutls_session_t session)
 {
   record_parameters_st *record_params;
-  _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
+  int ret;
+  
+  ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
+  if (ret < 0)
+    return gnutls_assert_val(GNUTLS_MAC_NULL);
 
   return record_params->mac_algorithm;
 }
@@ -144,7 +152,11 @@ gnutls_compression_method_t
 gnutls_compression_get (gnutls_session_t session)
 {
   record_parameters_st *record_params;
-  _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
+  int ret;
+  
+  ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
+  if (ret < 0)
+    return gnutls_assert_val(GNUTLS_COMP_NULL);
 
   return record_params->compression_algorithm;
 }
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 581acf3..7518c24 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -385,6 +385,7 @@ extern "C"
   /**
    * gnutls_handshake_description_t:
    * @GNUTLS_HANDSHAKE_HELLO_REQUEST: Hello request.
+   * @GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST: DTLS Hello verify request.
    * @GNUTLS_HANDSHAKE_CLIENT_HELLO: Client hello.
    * @GNUTLS_HANDSHAKE_SERVER_HELLO: Server hello.
    * @GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: New session ticket.
@@ -396,6 +397,7 @@ extern "C"
    * @GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE: Client key exchange.
    * @GNUTLS_HANDSHAKE_FINISHED: Finished.
    * @GNUTLS_HANDSHAKE_SUPPLEMENTAL: Supplemental.
+   * @GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC: Change Cipher Spec
    *
    * Enumeration of different TLS handshake packets.
    */
@@ -413,7 +415,8 @@ extern "C"
     GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY = 15,
     GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE = 16,
     GNUTLS_HANDSHAKE_FINISHED = 20,
-    GNUTLS_HANDSHAKE_SUPPLEMENTAL = 23
+    GNUTLS_HANDSHAKE_SUPPLEMENTAL = 23,
+    GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC = 254
   } gnutls_handshake_description_t;
 
   /**
@@ -1738,6 +1741,8 @@ extern "C"
 
 #define GNUTLS_E_CRYPTO_INIT_FAILED -318
 
+#define GNUTLS_E_TIMEDOUT -319
+
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
 
 
diff --git a/lib/opencdk/main.h b/lib/opencdk/main.h
index bc7d523..271b9d7 100644
--- a/lib/opencdk/main.h
+++ b/lib/opencdk/main.h
@@ -27,7 +27,7 @@
 
 #include "types.h"
 
-#define _cdk_log_debug _gnutls_debug_log
+#define _cdk_log_debug _gnutls_hard_log
 #define _cdk_log_info _gnutls_x509_log
 #define _cdk_get_log_level() _gnutls_log_level
 
diff --git a/lib/system.c b/lib/system.c
index f3bed5f..d89c283 100644
--- a/lib/system.c
+++ b/lib/system.c
@@ -105,6 +105,22 @@ system_read_peek (gnutls_transport_ptr ptr, void *data, 
size_t data_size)
   return recv (GNUTLS_POINTER_TO_INT (ptr), data, data_size, MSG_PEEK);
 }
 
+/* Wait for data to be received within a timeout period in milliseconds
+ */
+int system_recv_timeout(gnutls_transport_ptr ptr, size_t ms)
+{
+fd_set rfds;
+struct timeval tv;
+
+  FD_ZERO(&rfds);
+  FD_SET(GNUTLS_POINTER_TO_INT(ptr), &rfds);
+  
+  tv.tv_sec = 0;
+  tv.tv_usec = ms * 1000;
+  
+  return select(GNUTLS_POINTER_TO_INT(ptr)+1, &rfds, NULL, NULL, &tv);
+}
+
 /* Thread stuff */
 
 #ifdef HAVE_WIN32_LOCKS
diff --git a/lib/system.h b/lib/system.h
index 860bca8..6ec4e83 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -8,6 +8,7 @@
 #endif
 
 int system_errno (gnutls_transport_ptr);
+int system_recv_timeout(gnutls_transport_ptr ptr, size_t ms);
 
 #ifdef _WIN32
 ssize_t system_write (gnutls_transport_ptr ptr, const void *data,
diff --git a/src/cli-gaa.c b/src/cli-gaa.c
index aab764e..fd9e0e4 100644
--- a/src/cli-gaa.c
+++ b/src/cli-gaa.c
@@ -132,7 +132,7 @@ void gaa_help(void)
        __gaa_helpsingle('e', "rehandshake", "", "Connect, establish a session 
and rehandshake immediately.");
        __gaa_helpsingle(0, "noticket", "", "Doesn't accept session tickets.");
        __gaa_helpsingle('s', "starttls", "", "Connect, establish a plain 
session and start TLS when EOF or a SIGALRM is received.");
-       __gaa_helpsingle('u', "dtls", "", "Use DTLS (datagram TLS).");
+       __gaa_helpsingle('u', "udp", "", "Use DTLS (datagram TLS).");
        __gaa_helpsingle(0, "crlf", "", "Send CR LF instead of LF.");
        __gaa_helpsingle(0, "x509fmtder", "", "Use DER format for certificates 
to read from.");
        __gaa_helpsingle('f', "fingerprint", "", "Send the openpgp fingerprint, 
instead of the key.");
@@ -219,7 +219,7 @@ struct _gaainfo
 #line 32 "cli.gaa"
        int crlf;
 #line 29 "cli.gaa"
-       int dtls;
+       int udp;
 #line 26 "cli.gaa"
        int starttls;
 #line 23 "cli.gaa"
@@ -310,7 +310,7 @@ static int gaa_error = 0;
 #define GAAOPTID_fingerprint   23
 #define GAAOPTID_x509fmtder    24
 #define GAAOPTID_crlf  25
-#define GAAOPTID_dtls  26
+#define GAAOPTID_udp   26
 #define GAAOPTID_starttls      27
 #define GAAOPTID_noticket      28
 #define GAAOPTID_rehandshake   29
@@ -662,7 +662,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECK1STR("f", GAAOPTID_fingerprint);
                        GAA_CHECK1STR("", GAAOPTID_x509fmtder);
                        GAA_CHECK1STR("", GAAOPTID_crlf);
-                       GAA_CHECK1STR("u", GAAOPTID_dtls);
+                       GAA_CHECK1STR("u", GAAOPTID_udp);
                        GAA_CHECK1STR("s", GAAOPTID_starttls);
                        GAA_CHECK1STR("", GAAOPTID_noticket);
                        GAA_CHECK1STR("e", GAAOPTID_rehandshake);
@@ -696,7 +696,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECKSTR("fingerprint", GAAOPTID_fingerprint);
                        GAA_CHECKSTR("x509fmtder", GAAOPTID_x509fmtder);
                        GAA_CHECKSTR("crlf", GAAOPTID_crlf);
-                       GAA_CHECKSTR("dtls", GAAOPTID_dtls);
+                       GAA_CHECKSTR("udp", GAAOPTID_udp);
                        GAA_CHECKSTR("starttls", GAAOPTID_starttls);
                        GAA_CHECKSTR("noticket", GAAOPTID_noticket);
                        GAA_CHECKSTR("rehandshake", GAAOPTID_rehandshake);
@@ -970,10 +970,10 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo 
*gaaval, char *opt_list)
 
                return GAA_OK;
                break;
-       case GAAOPTID_dtls:
+       case GAAOPTID_udp:
        OK = 0;
 #line 30 "cli.gaa"
-{ gaaval->dtls = 1 ;};
+{ gaaval->udp = 1 ;};
 
                return GAA_OK;
                break;
@@ -1057,7 +1057,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
        gaaval->srp_username=NULL; gaaval->srp_passwd=NULL; gaaval->fmtder = 0; 
gaaval->starttls =0; 
        gaaval->debug = 0; gaaval->print_cert = 0; gaaval->verbose = 0; 
gaaval->psk_key = NULL; 
        gaaval->psk_username = NULL; gaaval->priorities = NULL;
-       gaaval->pgp_subkey = NULL; gaaval->rehandshake = 0; gaaval->dtls = 0; 
;};
+       gaaval->pgp_subkey = NULL; gaaval->rehandshake = 0; gaaval->udp = 0; ;};
 
     }
     inited = 1;
diff --git a/src/cli-gaa.h b/src/cli-gaa.h
index 07f409b..aba523e 100644
--- a/src/cli-gaa.h
+++ b/src/cli-gaa.h
@@ -55,7 +55,7 @@ struct _gaainfo
 #line 32 "cli.gaa"
        int crlf;
 #line 29 "cli.gaa"
-       int dtls;
+       int udp;
 #line 26 "cli.gaa"
        int starttls;
 #line 23 "cli.gaa"
diff --git a/src/cli.c b/src/cli.c
index 762146c..6f8339b 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -53,7 +53,7 @@
 #define MAX_BUF 4096
 
 /* global stuff here */
-int resume, starttls, insecure, rehandshake, dtls;
+int resume, starttls, insecure, rehandshake, udp;
 const char *hostname = NULL;
 char *service;
 int record_max_size;
@@ -551,7 +551,7 @@ init_tls_session (const char *hostname)
 
   gnutls_session_t session;
 
-  if (dtls)
+  if (udp)
     gnutls_init_dtls (&session, GNUTLS_CLIENT, 0);
   else
     gnutls_init (&session, GNUTLS_CLIENT);
@@ -977,7 +977,7 @@ gaa_parser (int argc, char **argv)
   resume = info.resume;
   rehandshake = info.rehandshake;
   insecure = info.insecure;
-  dtls = info.dtls;
+  udp = info.udp;
   service = info.port;
   record_max_size = info.record_size;
   fingerprint = info.fingerprint;
@@ -1396,7 +1396,7 @@ socket_open (socket_st * hd, const char *hostname, const 
char *service)
   printf ("Resolving '%s'...\n", hostname);
   /* get server name */
   memset (&hints, 0, sizeof (hints));
-  hints.ai_socktype = dtls ? SOCK_DGRAM : SOCK_STREAM;
+  hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
   if ((err = getaddrinfo (hostname, service, &hints, &res)))
     {
       fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
diff --git a/src/cli.gaa b/src/cli.gaa
index c7de095..9b3aa78 100644
--- a/src/cli.gaa
+++ b/src/cli.gaa
@@ -26,8 +26,8 @@ option (noticket) { $noticket = 1 } "Doesn't accept session 
tickets."
 #int starttls;
 option (s, starttls) { $starttls = 1 } "Connect, establish a plain session and 
start TLS when EOF or a SIGALRM is received."
 
-#int dtls;
-option (u, dtls) { $dtls = 1 } "Use DTLS (datagram TLS)."
+#int udp;
+option (u, udp) { $udp = 1 } "Use DTLS (datagram TLS)."
 
 #int crlf;
 option (crlf) { $crlf = 1 } "Send CR LF instead of LF."
@@ -111,4 +111,4 @@ init { $resume=0; $noticket=0; $port="443"; $rest_args=NULL;
        $srp_username=NULL; $srp_passwd=NULL; $fmtder = 0; $starttls =0; 
        $debug = 0; $print_cert = 0; $verbose = 0; $psk_key = NULL; 
        $psk_username = NULL; $priorities = NULL;
-       $pgp_subkey = NULL; $rehandshake = 0; $dtls = 0; }
+       $pgp_subkey = NULL; $rehandshake = 0; $udp = 0; }


hooks/post-receive
-- 
GNU gnutls



reply via email to

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