summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos <nmav@crystal.(none)>2008-03-16 11:17:55 +0200
committerNikos <nmav@crystal.(none)>2008-03-16 11:17:55 +0200
commita1cd6fe1a072717d2c33fd5a20306741c86399ae (patch)
treecda9b8f8412d1e14c1864c976add689f2d7def93
parentac6bc2abdd43c0becc60f89be11adc0bc42dab00 (diff)
downloadgnutls-a1cd6fe1a072717d2c33fd5a20306741c86399ae.tar.gz
Added functionality to override (register) a cipher. Initial functionality for MAC and digest algorithms.
-rw-r--r--NEWS7
-rw-r--r--includes/gnutls/crypto.h59
-rw-r--r--includes/gnutls/gnutls.h.in1
-rw-r--r--lib/Makefile.am5
-rw-r--r--lib/crypto.c135
-rw-r--r--lib/crypto.h3
-rw-r--r--lib/gnutls_cipher.c6
-rw-r--r--lib/gnutls_cipher_int.c86
-rw-r--r--lib/gnutls_cipher_int.h23
-rw-r--r--lib/gnutls_constate.c51
-rw-r--r--lib/gnutls_errors.c3
-rw-r--r--lib/gnutls_int.h4
-rw-r--r--lib/gnutls_state.c4
13 files changed, 319 insertions, 68 deletions
diff --git a/NEWS b/NEWS
index c2fc50eb95..15b10b5937 100644
--- a/NEWS
+++ b/NEWS
@@ -8,8 +8,13 @@ See the end for copying conditions.
** Finish renaming of gnutls_certificate_export_x509_cas etc.
They weren't renamed in the public header file.
+** Added functions to register a cipher/mac/digest. This allows to
+override the included ones.
+
** API and ABI modifications:
-No changes since last version.
+gnutls_crypto_cipher_register: ADDED
+gnutls_crypto_mac_register: ADDED
+gnutls_crypto_digest_register: ADDED
* Version 2.3.3 (released 2008-03-10)
diff --git a/includes/gnutls/crypto.h b/includes/gnutls/crypto.h
new file mode 100644
index 0000000000..b362b9d3ec
--- /dev/null
+++ b/includes/gnutls/crypto.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Free Software Foundation
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GNUTLS.
+ *
+ * The GNUTLS library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ *
+ */
+
+#ifndef GNUTLS_CRYPTO_H
+# define GNUTLS_CRYPTO_H
+
+typedef struct gnutls_crypto_cipher {
+ int (*init)( void** ctx);
+ int (*setkey)( void* ctx, const void * key, int keysize);
+ int (*setiv)(void* ctx, const void* iv, int ivsize);
+ int (*encrypt)(void* ctx, const void* plain, int plainsize, void* encr, int encrsize);
+ int (*decrypt)(void* ctx, const void* encr, int encrsize, void* plain, int plainsize);
+ void (*deinit)( void* ctx);
+} gnutls_crypto_cipher_st;
+
+typedef struct gnutls_crypto_mac {
+ int (*init)( void** ctx);
+ int (*mac)( void* ctx, const void * text, int textsize);
+ int (*copy)( void* src_ctx, void* dst_ctx);
+ int (*output) ( void* src_ctx, void* digest, int digestsize);
+ void (*deinit)( void* ctx);
+} gnutls_crypto_mac_st;
+
+typedef struct gnutls_crypto_digest {
+ int (*init)( void** ctx);
+ int (*digest)( void* ctx, const void * text, int textsize);
+ int (*copy)( void* src_ctx, void* dst_ctx);
+ int (*output) ( void* src_ctx, void* digest, int digestsize);
+ void (*deinit)( void* ctx);
+} gnutls_crypto_digest_st;
+
+/* priority: infinity for backend algorithms, 90 for kernel algorithms - lowest wins
+ */
+int gnutls_crypto_cipher_register( gnutls_cipher_algorithm_t algorithm, int priority, gnutls_crypto_cipher_st* s);
+int gnutls_crypto_mac_register( gnutls_mac_algorithm_t algorithm, int priority, gnutls_crypto_mac_st* s);
+int gnutls_crypto_digest_register( gnutls_digest_algorithm_t algorithm, int priority, gnutls_crypto_digest_st* s);
+
+#endif
diff --git a/includes/gnutls/gnutls.h.in b/includes/gnutls/gnutls.h.in
index 5ce8f35f93..0292ab7cc0 100644
--- a/includes/gnutls/gnutls.h.in
+++ b/includes/gnutls/gnutls.h.in
@@ -1301,6 +1301,7 @@ extern "C"
#define GNUTLS_E_OPENPGP_SUBKEY_ERROR -208
+#define GNUTLS_E_CRYPTO_ALREADY_REGISTERED -209
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
diff --git a/lib/Makefile.am b/lib/Makefile.am
index bf0d4a026d..96691bdbfb 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -85,7 +85,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c gnutls_cipher.c \
gnutls_x509.c ext_cert_type.c gnutls_rsa_export.c \
auth_rsa_export.c ext_server_name.c auth_dh_common.c \
gnutls_helper.c ext_inner_application.c \
- gnutls_supplemental.c
+ gnutls_supplemental.c crypto.c
if ENABLE_OPRFI
COBJECTS += $(OPRFI_COBJECTS)
@@ -105,7 +105,8 @@ HFILES = debug.h gnutls_compress.h defines.h gnutls_cipher.h \
gnutls_rsa_export.h ext_server_name.h auth_dh_common.h \
ext_srp.h gnutls_srp.h auth_srp.h auth_srp_passwd.h \
gnutls_helper.h auth_psk.h auth_psk_passwd.h \
- ext_inner_application.h gnutls_supplemental.h ext_oprfi.h
+ ext_inner_application.h gnutls_supplemental.h ext_oprfi.h \
+ crypto.h
# Separate so we can create the documentation
diff --git a/lib/crypto.c b/lib/crypto.c
new file mode 100644
index 0000000000..fda2263699
--- /dev/null
+++ b/lib/crypto.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008 Free Software Foundation
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GNUTLS.
+ *
+ * The GNUTLS library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ *
+ */
+
+#include <gnutls_errors.h>
+#include <gnutls_int.h>
+#include <gnutls/crypto.h>
+#include <crypto.h>
+
+typedef struct algo_list {
+ int algorithm;
+ int priority;
+ void* alg_data;
+ struct algo_list* next;
+} algo_list;
+
+#define cipher_list algo_list
+#define mac_list algo_list
+#define digest_list algo_list
+
+static int _algo_register( algo_list* al, int algorithm, int priority, void* s)
+{
+algo_list* cl;
+algo_list* last_cl;
+
+ /* look if there is any cipher with lowest priority. In that case do not add.
+ */
+ cl = al;
+ while( cl && cl->alg_data) {
+ if (cl->algorithm == algorithm) {
+ if (cl->priority < priority) {
+ gnutls_assert();
+ return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
+ } else {
+ /* the current has higher priority -> overwrite */
+ cl->algorithm = algorithm;
+ cl->priority = priority;
+ cl->alg_data = s;
+ return 0;
+ }
+ }
+ cl = cl->next;
+ if (cl) last_cl = cl;
+ }
+
+ cl = gnutls_malloc(sizeof(cipher_list));
+
+ if (cl == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ cl->algorithm = algorithm;
+ cl->priority = priority;
+ cl->alg_data = s;
+ cl->next = NULL;
+
+ last_cl->next = cl;
+
+ return 0;
+
+}
+
+static void *_get_algo( algo_list* al, int algo)
+{
+cipher_list* cl;
+
+ /* look if there is any cipher with lowest priority. In that case do not add.
+ */
+ cl = al;
+ while( cl && cl->alg_data) {
+ if (cl->algorithm == algo) {
+ return cl->alg_data;
+ }
+ cl = cl->next;
+ }
+
+ return NULL;
+}
+
+static cipher_list glob_cl = { GNUTLS_CIPHER_NULL, 0, NULL, NULL };
+static mac_list glob_ml = { GNUTLS_MAC_NULL, 0, NULL, NULL };
+static digest_list glob_dl = { GNUTLS_MAC_NULL, 0, NULL, NULL };
+
+
+int gnutls_crypto_cipher_register( gnutls_cipher_algorithm_t algorithm, int priority, gnutls_crypto_cipher_st* s)
+{
+ return _algo_register( &glob_cl, algorithm, priority, s);
+}
+
+gnutls_crypto_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t algo)
+{
+ return _get_algo( &glob_cl, algo);
+}
+
+int gnutls_crypto_mac_register( gnutls_mac_algorithm_t algorithm, int priority, gnutls_crypto_mac_st* s)
+{
+ return _algo_register( &glob_ml, algorithm, priority, s);
+}
+
+gnutls_crypto_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo)
+{
+ return _get_algo( &glob_ml, algo);
+}
+
+
+int gnutls_crypto_digest_register( gnutls_digest_algorithm_t algorithm, int priority, gnutls_crypto_digest_st* s)
+{
+ return _algo_register( &glob_dl, algorithm, priority, s);
+}
+
+gnutls_crypto_digest_st *_gnutls_get_crypto_digest( gnutls_digest_algorithm_t algo)
+{
+ return _get_algo( &glob_dl, algo);
+}
diff --git a/lib/crypto.h b/lib/crypto.h
new file mode 100644
index 0000000000..eb695a8757
--- /dev/null
+++ b/lib/crypto.h
@@ -0,0 +1,3 @@
+gnutls_crypto_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t algo);
+gnutls_crypto_digest_st *_gnutls_get_crypto_digest( gnutls_digest_algorithm_t algo);
+gnutls_crypto_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo);
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index e930c1de3f..c8bc72314b 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -400,7 +400,7 @@ _gnutls_compressed2ciphertext (gnutls_session_t session,
/* Actual encryption (inplace).
*/
- ret = _gnutls_cipher_encrypt (session->connection_state.
+ ret = _gnutls_cipher_encrypt (&session->connection_state.
write_cipher_state, cipher_data, length);
if (ret < 0)
{
@@ -460,7 +460,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
(session->security_parameters.read_bulk_cipher_algorithm))
{
case CIPHER_STREAM:
- if ((ret = _gnutls_cipher_decrypt (session->connection_state.
+ if ((ret = _gnutls_cipher_decrypt (&session->connection_state.
read_cipher_state,
ciphertext.data,
ciphertext.size)) < 0)
@@ -479,7 +479,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
return GNUTLS_E_DECRYPTION_FAILED;
}
- if ((ret = _gnutls_cipher_decrypt (session->connection_state.
+ if ((ret = _gnutls_cipher_decrypt (&session->connection_state.
read_cipher_state,
ciphertext.data,
ciphertext.size)) < 0)
diff --git a/lib/gnutls_cipher_int.c b/lib/gnutls_cipher_int.c
index 035bce6249..11b8488722 100644
--- a/lib/gnutls_cipher_int.c
+++ b/lib/gnutls_cipher_int.c
@@ -26,80 +26,116 @@
#include <gnutls_errors.h>
#include <gnutls_cipher_int.h>
#include <gnutls_datum.h>
+#include <gnutls/crypto.h>
+#include <crypto.h>
-cipher_hd_t
-_gnutls_cipher_init (gnutls_cipher_algorithm_t cipher,
+#define SR(x) if ( (x)<0 ) { \
+ gnutls_assert(); \
+ err = GNUTLS_E_INTERNAL_ERROR; \
+ goto cc_cleanup; \
+ }
+
+int
+_gnutls_cipher_init (cipher_hd_st* handle, gnutls_cipher_algorithm_t cipher,
const gnutls_datum_t * key, const gnutls_datum_t * iv)
{
- cipher_hd_t ret = NULL;
int err = GC_INVALID_CIPHER; /* doesn't matter */
-
+ gnutls_crypto_cipher_st * cc = NULL;
+
+ /* check if a cipher has been registered
+ */
+ cc = _gnutls_get_registered_cipher( cipher);
+ if (cc != NULL) {
+ handle->registered = 1;
+ handle->hd.rh.cc = cc;
+ SR( cc->init(&handle->hd.rh.ctx) );
+ SR(cc->setkey( handle->hd.rh.ctx, key->data, key->size));
+ if (iv->data && iv->size && cc->setiv)
+ SR(cc->setiv( handle->hd.rh.ctx, iv->data, iv->size));
+ return 0;
+ }
+
+ handle->registered = 0;
+ /* otherwise use included ciphers
+ */
switch (cipher)
{
case GNUTLS_CIPHER_AES_128_CBC:
- err = gc_cipher_open (GC_AES128, GC_CBC, &ret);
+ err = gc_cipher_open (GC_AES128, GC_CBC, &handle->hd.gc);
break;
case GNUTLS_CIPHER_AES_256_CBC:
- err = gc_cipher_open (GC_AES256, GC_CBC, &ret);
+ err = gc_cipher_open (GC_AES256, GC_CBC, &handle->hd.gc);
break;
case GNUTLS_CIPHER_3DES_CBC:
- err = gc_cipher_open (GC_3DES, GC_CBC, &ret);
+ err = gc_cipher_open (GC_3DES, GC_CBC, &handle->hd.gc);
break;
case GNUTLS_CIPHER_DES_CBC:
- err = gc_cipher_open (GC_DES, GC_CBC, &ret);
+ err = gc_cipher_open (GC_DES, GC_CBC, &handle->hd.gc);
break;
case GNUTLS_CIPHER_ARCFOUR_128:
- err = gc_cipher_open (GC_ARCFOUR128, GC_STREAM, &ret);
+ err = gc_cipher_open (GC_ARCFOUR128, GC_STREAM, &handle->hd.gc);
break;
case GNUTLS_CIPHER_ARCFOUR_40:
- err = gc_cipher_open (GC_ARCFOUR40, GC_STREAM, &ret);
+ err = gc_cipher_open (GC_ARCFOUR40, GC_STREAM, &handle->hd.gc);
break;
case GNUTLS_CIPHER_RC2_40_CBC:
- err = gc_cipher_open (GC_ARCTWO40, GC_CBC, &ret);
+ err = gc_cipher_open (GC_ARCTWO40, GC_CBC, &handle->hd.gc);
break;
#ifdef ENABLE_CAMELLIA
case GNUTLS_CIPHER_CAMELLIA_128_CBC:
- err = gc_cipher_open (GC_CAMELLIA128, GC_CBC, &ret);
+ err = gc_cipher_open (GC_CAMELLIA128, GC_CBC, &handle->hd.gc);
break;
case GNUTLS_CIPHER_CAMELLIA_256_CBC:
- err = gc_cipher_open (GC_CAMELLIA256, GC_CBC, &ret);
+ err = gc_cipher_open (GC_CAMELLIA256, GC_CBC, &handle->hd.gc);
break;
#endif
default:
- return NULL;
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
}
if (err == 0)
{
- gc_cipher_setkey (ret, key->size, key->data);
+ gc_cipher_setkey (handle->hd.gc, key->size, key->data);
if (iv->data != NULL && iv->size > 0)
- gc_cipher_setiv (ret, iv->size, iv->data);
+ gc_cipher_setiv (handle->hd.gc, iv->size, iv->data);
}
else if (cipher != GNUTLS_CIPHER_NULL)
{
gnutls_assert ();
_gnutls_x509_log ("Crypto cipher[%d] error: %d\n", cipher, err);
+ return GNUTLS_E_INTERNAL_ERROR;
/* FIXME: gc_strerror */
}
- return ret;
+ return 0;
+
+cc_cleanup:
+
+ if (handle->hd.rh.cc)
+ cc->deinit(handle->hd.rh.ctx);
+
+ return err;
}
int
-_gnutls_cipher_encrypt (cipher_hd_t handle, void *text, int textlen)
+_gnutls_cipher_encrypt (const cipher_hd_st* handle, void *text, int textlen)
{
if (handle != GNUTLS_CIPHER_FAILED)
{
- if (gc_cipher_encrypt_inline (handle, textlen, text) != 0)
+ if (handle->registered) {
+ return handle->hd.rh.cc->encrypt( handle->hd.rh.ctx, text, textlen, text, textlen);
+ }
+ if (gc_cipher_encrypt_inline (handle->hd.gc, textlen, text) != 0)
{
gnutls_assert ();
return GNUTLS_E_INTERNAL_ERROR;
@@ -109,12 +145,15 @@ _gnutls_cipher_encrypt (cipher_hd_t handle, void *text, int textlen)
}
int
-_gnutls_cipher_decrypt (cipher_hd_t handle, void *ciphertext,
+_gnutls_cipher_decrypt (const cipher_hd_st *handle, void *ciphertext,
int ciphertextlen)
{
if (handle != GNUTLS_CIPHER_FAILED)
{
- if (gc_cipher_decrypt_inline (handle, ciphertextlen, ciphertext) != 0)
+ if (handle->registered) {
+ return handle->hd.rh.cc->decrypt( handle->hd.rh.ctx, ciphertext, ciphertextlen, ciphertext, ciphertextlen);
+ }
+ if (gc_cipher_decrypt_inline (handle->hd.gc, ciphertextlen, ciphertext) != 0)
{
gnutls_assert ();
return GNUTLS_E_INTERNAL_ERROR;
@@ -124,10 +163,13 @@ _gnutls_cipher_decrypt (cipher_hd_t handle, void *ciphertext,
}
void
-_gnutls_cipher_deinit (cipher_hd_t handle)
+_gnutls_cipher_deinit (cipher_hd_st* handle)
{
if (handle != GNUTLS_CIPHER_FAILED)
{
+ if (handle->registered) {
+ return handle->hd.rh.cc->deinit( handle->hd.rh.ctx);
+ }
gc_cipher_close (handle);
}
}
diff --git a/lib/gnutls_cipher_int.h b/lib/gnutls_cipher_int.h
index bf62ed4882..b97a0c862f 100644
--- a/lib/gnutls_cipher_int.h
+++ b/lib/gnutls_cipher_int.h
@@ -25,15 +25,28 @@
#ifndef GNUTLS_CIPHER_INT
# define GNUTLS_CIPHER_INT
-#define cipher_hd_t gc_cipher_handle
+#include <gnutls/crypto.h>
+
+typedef struct {
+ gnutls_crypto_cipher_st* cc;
+ void* ctx;
+} reg_hd;
+
+typedef struct {
+ int registered; /* true or false(0) */
+ union {
+ gc_cipher_handle gc; /* when not registered */
+ reg_hd rh; /* when registered */
+ } hd;
+} cipher_hd_st;
#define GNUTLS_CIPHER_FAILED NULL
-cipher_hd_t _gnutls_cipher_init (gnutls_cipher_algorithm_t cipher,
+int _gnutls_cipher_init (cipher_hd_st*, gnutls_cipher_algorithm_t cipher,
const gnutls_datum_t * key,
const gnutls_datum_t * iv);
-int _gnutls_cipher_encrypt (cipher_hd_t handle, void *text, int textlen);
-int _gnutls_cipher_decrypt (cipher_hd_t handle, void *ciphertext,
+int _gnutls_cipher_encrypt (const cipher_hd_st *handle, void *text, int textlen);
+int _gnutls_cipher_decrypt (const cipher_hd_st *handle, void *ciphertext,
int ciphertextlen);
-void _gnutls_cipher_deinit (cipher_hd_t handle);
+void _gnutls_cipher_deinit (cipher_hd_st* handle);
#endif /* GNUTLS_CIPHER_INT */
diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c
index 56c9441229..e3e43ba13f 100644
--- a/lib/gnutls_constate.c
+++ b/lib/gnutls_constate.c
@@ -569,7 +569,7 @@ _gnutls_read_connection_state_init (gnutls_session_t session)
_gnutls_free_datum (&session->connection_state.read_mac_secret);
if (session->connection_state.read_cipher_state != NULL)
- _gnutls_cipher_deinit (session->connection_state.read_cipher_state);
+ _gnutls_cipher_deinit (&session->connection_state.read_cipher_state);
if (session->connection_state.read_compression_state != NULL)
_gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
@@ -587,19 +587,15 @@ _gnutls_read_connection_state_init (gnutls_session_t session)
case GNUTLS_SERVER:
/* initialize cipher session
*/
- session->connection_state.read_cipher_state =
- _gnutls_cipher_init (session->security_parameters.
- read_bulk_cipher_algorithm,
- &session->cipher_specs.
- client_write_key,
- &session->cipher_specs.client_write_IV);
- if (session->connection_state.read_cipher_state ==
- GNUTLS_CIPHER_FAILED
- && session->security_parameters.
+ rc = _gnutls_cipher_init (&session->connection_state.read_cipher_state,
+ session->security_parameters.read_bulk_cipher_algorithm,
+ &session->cipher_specs.client_write_key,
+ &session->cipher_specs.client_write_IV);
+ if (rc < 0) && session->security_parameters.
read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
{
gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
+ return rc;
}
/* copy mac secrets from cipherspecs, to connection
@@ -623,16 +619,12 @@ _gnutls_read_connection_state_init (gnutls_session_t session)
break;
case GNUTLS_CLIENT:
- session->connection_state.read_cipher_state =
- _gnutls_cipher_init (session->security_parameters.
- read_bulk_cipher_algorithm,
- &session->cipher_specs.
- server_write_key,
- &session->cipher_specs.server_write_IV);
+ rc = _gnutls_cipher_init (&session->connection_state.read_cipher_state,
+ session->security_parameters.read_bulk_cipher_algorithm,
+ &session->cipher_specs.server_write_key,
+ &session->cipher_specs.server_write_IV);
- if (session->connection_state.read_cipher_state ==
- GNUTLS_CIPHER_FAILED
- && session->security_parameters.
+ if (rc < 0 && session->security_parameters.
read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
{
gnutls_assert ();
@@ -760,7 +752,7 @@ _gnutls_write_connection_state_init (gnutls_session_t session)
_gnutls_free_datum (&session->connection_state.write_mac_secret);
if (session->connection_state.write_cipher_state != NULL)
- _gnutls_cipher_deinit (session->connection_state.write_cipher_state);
+ _gnutls_cipher_deinit (&session->connection_state.write_cipher_state);
if (session->connection_state.write_compression_state != NULL)
_gnutls_comp_deinit (session->connection_state.
@@ -778,16 +770,15 @@ _gnutls_write_connection_state_init (gnutls_session_t session)
case GNUTLS_SERVER:
/* initialize cipher session
*/
- session->connection_state.write_cipher_state =
- _gnutls_cipher_init (session->security_parameters.
+ rc = _gnutls_cipher_init (
+ &connection_state.write_cipher_state,
+ session->security_parameters.
write_bulk_cipher_algorithm,
&session->cipher_specs.
server_write_key,
&session->cipher_specs.server_write_IV);
- if (session->connection_state.write_cipher_state ==
- GNUTLS_CIPHER_FAILED
- && session->security_parameters.
+ if (rc < 0 && session->security_parameters.
write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
{
gnutls_assert ();
@@ -817,16 +808,14 @@ _gnutls_write_connection_state_init (gnutls_session_t session)
break;
case GNUTLS_CLIENT:
- session->connection_state.write_cipher_state =
- _gnutls_cipher_init (session->security_parameters.
+ rc = _gnutls_cipher_init (&connection_state.write_cipher_state,
+ session->security_parameters.
write_bulk_cipher_algorithm,
&session->cipher_specs.
client_write_key,
&session->cipher_specs.client_write_IV);
- if (session->connection_state.write_cipher_state ==
- GNUTLS_CIPHER_FAILED
- && session->security_parameters.
+ if (rc < 0 && session->security_parameters.
write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
{
gnutls_assert ();
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 465806f8f0..a0c1546876 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -89,6 +89,9 @@ static const gnutls_error_entry error_algorithms[] = {
ERROR_ENTRY (N_("The peer did not send any certificate."),
GNUTLS_E_NO_CERTIFICATE_FOUND, 1),
+ ERROR_ENTRY (N_("There is already a crypto algorithm with lower priority."),
+ GNUTLS_E_CRYPTO_ALREADY_REGISTERED, 0),
+
ERROR_ENTRY (N_("No temporary RSA parameters were found."),
GNUTLS_E_NO_TEMPORARY_RSA_PARAMS, 1),
ERROR_ENTRY (N_("No temporary DH parameters were found."),
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index dc8e399fed..b4dbdba26d 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -372,8 +372,8 @@ typedef struct
typedef struct
{
- cipher_hd_t write_cipher_state;
- cipher_hd_t read_cipher_state;
+ cipher_hd_st write_cipher_state;
+ cipher_hd_st read_cipher_state;
comp_hd_t read_compression_state;
comp_hd_t write_compression_state;
gnutls_datum_t read_mac_secret;
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index cd20eddffe..5524af8120 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -377,9 +377,9 @@ gnutls_deinit (gnutls_session_t session)
_gnutls_selected_certs_deinit (session);
if (session->connection_state.read_cipher_state != NULL)
- _gnutls_cipher_deinit (session->connection_state.read_cipher_state);
+ _gnutls_cipher_deinit (&session->connection_state.read_cipher_state);
if (session->connection_state.write_cipher_state != NULL)
- _gnutls_cipher_deinit (session->connection_state.write_cipher_state);
+ _gnutls_cipher_deinit (&session->connection_state.write_cipher_state);
if (session->connection_state.read_compression_state != NULL)
_gnutls_comp_deinit (session->connection_state.read_compression_state, 1);