]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
several additions for RSA (mostly unstable)
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 17 Jun 2001 11:26:56 +0000 (11:26 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 17 Jun 2001 11:26:56 +0000 (11:26 +0000)
28 files changed:
lib/Makefile.am
lib/auth_rsa.c
lib/auth_srp.c
lib/auth_srp_passwd.c
lib/auth_x509.h
lib/cert_asn1.h
lib/cert_b64.c
lib/cert_b64.h
lib/crypt_bcrypt.c
lib/crypt_srpsha1.c
lib/gnutls.h.in
lib/gnutls_algorithms.c
lib/gnutls_cert.c [new file with mode: 0644]
lib/gnutls_cipher.c
lib/gnutls_errors.c
lib/gnutls_errors_int.h
lib/gnutls_handshake.c
lib/gnutls_handshake.h
lib/gnutls_int.h
lib/gnutls_kx.c
lib/gnutls_num.h
lib/gnutls_pk.c
lib/gnutls_pk.h
lib/gnutls_random.c
lib/gnutls_random.h
lib/gnutls_record.c [moved from lib/gnutls.c with 96% similarity]
lib/gnutls_srp.c
lib/gnutls_v2_compat.c

index ae4a52eeb3c8c85e02493428343c2640a958cddc..11432f7841e8eacb38ade59ea6af8d3a73053e32 100644 (file)
@@ -14,9 +14,9 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h \
        cert_b64.h gnutls_srp.h auth_srp.h auth_srp_passwd.h gnutls_v2_compat.h \
        crypt.h libgnutls-config.in libgnutls.m4 gnutls.h.in gnutls_errors_int.h \
        cert_asn1.h cert_der.h gnutls_datum.h auth_x509.h gnutls_gcry.h \
-       ext_dnsname.h
+       ext_dnsname.h gnutls_pk.h
 lib_LTLIBRARIES = libgnutls.la
-libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
+libgnutls_la_SOURCES = gnutls_record.c gnutls_compress.c debug.c gnutls_plaintext.c \
        gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \
        gnutls_errors.c gnutls_algorithms.c gnutls_dh.c gnutls_kx.c \
        gnutls_priority.c gnutls_hash_int.c gnutls_cipher_int.c \
@@ -25,6 +25,6 @@ libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
        crypt_bcrypt.c crypt.c gnutls_random.c crypt_srpsha1.c gnutls_srp.c \
        auth_srp.c auth_srp_passwd.c gnutls_v2_compat.c auth_srp_sb64.c \
        cert_ASN.y cert_asn1.c cert_der.c gnutls_datum.c auth_rsa.c \
-       gnutls_gcry.c ext_dnsname.c
+       gnutls_gcry.c ext_dnsname.c gnutls_pk.c gnutls_cert.c
 libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
 
index 9b72d9ceead2260f2f1e90013fe5fcb79edd692c..d92622f5147d920c34884ac3f509bd7413161c45 100644 (file)
@@ -28,6 +28,8 @@
 #include "cert_der.h"
 #include "gnutls_datum.h"
 #include "auth_x509.h"
+#include <gnutls_random.h>
+#include <gnutls_pk.h>
 
 #if 0
 int gen_rsa_server_kx(GNUTLS_KEY, opaque **);
@@ -114,7 +116,10 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
        opaque str[5*1024];
        int len = sizeof(str);
 
-       create_structure("certificate2", "PKIX1Explicit88.Certificate");
+       if (create_structure("certificate2", "PKIX1Explicit88.Certificate")!=ASN_OK) {
+               gnutls_assert();
+               return GNUTLS_E_PARSING_ERROR;
+       }
 
        result = get_der("certificate2", cert.data, cert.size);
        if (result != ASN_OK) {
@@ -143,7 +148,11 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
                        return GNUTLS_E_PARSING_ERROR;
                }
 
-               create_structure("rsapublickey", "PKIX1Explicit88.RSAPublicKey");
+               if (create_structure("rsapublickey", "PKIX1Explicit88.RSAPublicKey")!=ASN_OK) {
+                       gnutls_assert();
+                       return GNUTLS_E_PARSING_ERROR;
+               }
+               
                result = get_der("rsapublickey", str, len);
                if (result != ASN_OK) {
                        gnutls_assert();
@@ -217,35 +226,38 @@ static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert)
        opaque str[5*1024];
        int len = sizeof(str);
 
-       create_structure("rsa_key", "PKCS-1");
+       if (create_structure("rsakey", "PKCS-1.RSAPrivateKey")!=ASN_OK) {
+               gnutls_assert();
+               return GNUTLS_E_PARSING_ERROR;
+       }
 
-       result = get_der("rsa_key", cert.data, cert.size);
+       result = get_der("rsakey", cert.data, cert.size);
        if (result != ASN_OK) {
                gnutls_assert();
                return GNUTLS_E_PARSING_ERROR;
        }
 
        result =
-           read_value("rsa_key.RSAPrivateKey.privateExponent", str, &len);
+           read_value("rsakey.privateExponent", str, &len);
        if (result != ASN_OK) {
                gnutls_assert();
-               delete_structure("rsa_key");
+               delete_structure("rsakey");
                return GNUTLS_E_PARSING_ERROR;
        }
        if (gcry_mpi_scan(&key->u,
                  GCRYMPI_FMT_USG, str, &len) != 0) {
                gnutls_assert();
-               delete_structure("rsa_key");
+               delete_structure("rsakey");
                return GNUTLS_E_MPI_SCAN_FAILED;
        }
 
 
        len = sizeof(str);
        result =
-           read_value("rsa_key.modulus", str, &len);
+           read_value("rsakey.modulus", str, &len);
        if (result != ASN_OK) {
                gnutls_assert();
-               delete_structure("rsa_key");
+               delete_structure("rsakey");
                _gnutls_mpi_release(&key->u);
                return GNUTLS_E_PARSING_ERROR;
        }
@@ -253,12 +265,12 @@ static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert)
        if (gcry_mpi_scan(&key->A,
                  GCRYMPI_FMT_USG, str, &len) != 0) {
                gnutls_assert();
-               delete_structure("rsa_key");
+               delete_structure("rsakey");
                _gnutls_mpi_release(&key->u);
                return GNUTLS_E_MPI_SCAN_FAILED;
        }
 
-       delete_structure("rsa_key");
+       delete_structure("rsakey");
 
        return ret;
 }
@@ -315,7 +327,7 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
 int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
 {
        const X509PKI_SERVER_CREDENTIALS *cred;
-       int ret, i;
+       int ret, i, pdatasize;
        opaque* pdata;
        gnutls_datum* apr_cert_list;
        gnutls_datum apr_pkey;
@@ -359,7 +371,8 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
                WRITEdatum24( pdata, apr_cert_list[i]); 
                pdata += 3 + apr_cert_list[i].size;
        }
-
+       pdatasize = ret;
+       
        /* read the rsa parameters now, since later we will
         * now know which certificate we used!
         */
@@ -371,19 +384,44 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
                return ret;
        }
 
-       return ret;     
+       return pdatasize;
 }
 
+#define RANDOMIZE_X(x) x.size=48; x.data=gnutls_malloc(x.size); \
+               if (x.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
+               if (_gnutls_get_random( key->key.data, key->key.size, GNUTLS_WEAK_RANDOM) < 0) { \
+                       return GNUTLS_E_MEMORY_ERROR; \
+               } 
 
 int proc_rsa_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
-       const X509PKI_SERVER_CREDENTIALS * cred;
-
-       cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
-       if (cred == NULL) {
+       gnutls_datum plaintext;
+       gnutls_datum ciphertext;
+       int ret, dsize;
+
+       ciphertext.data = &data[2];
+       dsize = READuint16(data);
+       ciphertext.size = GMIN(dsize, data_size);
+
+       ret = _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, key->u, key->A);
+       if ( ret < 0) {
+               /* in case decryption fails then don't inform
+                * the peer. Just use a random key. (in order to avoid
+                * attack against pkcs-1 formating).
+                */
                gnutls_assert();
-               return GNUTLS_E_INSUFICIENT_CRED;
+               RANDOMIZE_X(key->key);
+       } else {
+               if (plaintext.size != 48) { /* WOW */
+                       RANDOMIZE_X(key->key);
+               } else {
+                       key->key.data = plaintext.data;
+                       key->key.size = plaintext.size;
+               }
        }
 
+       _gnutls_mpi_release( &key->A);
+       _gnutls_mpi_release( &key->B);
+       _gnutls_mpi_release( &key->u);
        return 0;
 }
 
index 08d1d3b697f9becdceeaa2263efcf658f6dce04f..5a15f7cec5ac3ef1763dba859fbde86f96406ca0 100644 (file)
@@ -103,9 +103,9 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
        N = gcry_mpi_alloc_like(pwd_entry->n);
        V = gcry_mpi_alloc_like(pwd_entry->v);
 
-       mpi_set(G, pwd_entry->g);
-       mpi_set(N, pwd_entry->n);
-       mpi_set(V, pwd_entry->v);
+       gcry_mpi_set(G, pwd_entry->g);
+       gcry_mpi_set(N, pwd_entry->n);
+       gcry_mpi_set(V, pwd_entry->v);
 
        (*data) = gnutls_malloc(n_n + n_g + pwd_entry->salt_size + 6 + 1);
 
index 78483043ff4c9a6adbbaada94c3dc43afa7b4214..d63a76f1e21b6b7b3561a6770d91b412a254899b 100644 (file)
@@ -283,7 +283,6 @@ GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username
 GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry() {
        GNUTLS_SRP_PWD_ENTRY * pwd_entry = gnutls_malloc(sizeof(GNUTLS_SRP_PWD_ENTRY));
        size_t n = sizeof diffie_hellman_group1_prime;
-       opaque * rand;
        
        pwd_entry->username = gnutls_malloc(strlen(RNDUSER)+1);
        strcpy( pwd_entry->username, RNDUSER);
@@ -299,10 +298,12 @@ GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry() {
        }
 
        pwd_entry->salt_size = RND_SALT_SIZE;
-       rand = _gnutls_get_random(RND_SALT_SIZE, GNUTLS_WEAK_RANDOM);
+       
        pwd_entry->salt = gnutls_malloc(RND_SALT_SIZE);
-       memcpy( pwd_entry->salt, rand, RND_SALT_SIZE);
-       _gnutls_free_rand( rand);
+       if (_gnutls_get_random(pwd_entry->salt, RND_SALT_SIZE, GNUTLS_WEAK_RANDOM) < 0) {
+               gnutls_assert();
+               return NULL;
+       }
        
        pwd_entry->algorithm = 0;
 
index 8cfd1aed8904e14ed9b62c0badf233eb9dc578ef..a0c477cbaf3155c99bcf3069a18651c293abbe80 100644 (file)
@@ -1,5 +1,5 @@
 /* this is not to be included by gnutls_anon.c */
-extern MOD_AUTH_STRUCT x509pki_auth_struct;
+extern MOD_AUTH_STRUCT rsa_auth_struct;
 
 /* This structure may be complex but, it's the only way to
  * support a server that has multiple certificates
@@ -12,7 +12,7 @@ typedef struct {
                         *       [1] certificate2, certificate22, ...
                         */
        int * cert_list_length;
-                       /* contains the number of the certificates in one
+                       /* contains the number of the certificates in a
                         * row.
                         */
        int ncerts;     /* contains the number of columns in cert_list.
index a1d8354294762db63ef21d182054f4c0b99a7678..6d8be13f2e3ef23f3084eeedee74101c054f9e26 100755 (executable)
@@ -173,5 +173,7 @@ create_structure(char *dest_name,char *source_name);
 int
 delete_structure(char *root_name);
 
+int parser_asn1(char *file_name);
+
 #endif
 
index 9e05b65ee0ed1678ecf6fb860db15e56f615e147..d593f256be91feed7947e39db05256285dbeeb1e 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "defines.h"
 #include "gnutls_int.h"
+#include "gnutls_errors.h"
 
 const static uint8 b64table[64] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -296,12 +297,13 @@ inline static int cpydata(uint8 * data, int data_size, uint8 ** result)
 
 /* decodes data and puts the result into result (localy alocated)
  * The result_size is the return value
+ * FIXME: This function is a mess
  */
-int _gnutls_fbase64_decode(char *msg, uint8 * data, int data_size,
+#define ENDSTR "-----\n"
+int _gnutls_fbase64_decode( uint8 * data, int data_size,
                           uint8 ** result)
 {
-       int i, ret, tmp, j;
-       uint8 tmpres[3];
+       int i, ret;
        char top[80];
        char bottom[80];
        uint8 *rdata;
@@ -310,59 +312,52 @@ int _gnutls_fbase64_decode(char *msg, uint8 * data, int data_size,
        int kdata_size;
 
        strcpy(top, "-----BEGIN ");
-       strcat(top, msg);
-       strcat(top, "-----");
 
        strcpy(bottom, "\n-----END ");
-       strcat(bottom, msg);
-       strcat(bottom, "-----");
 
        i = 0;
        do {
                rdata = &data[i];
-               data_size -= i;
+               data_size --;
                i++;
        } while (data_size > 0 && strncmp(rdata, top, strlen(top)) != 0);
 
-       if (data_size < 4 + strlen(bottom))
+       if (data_size < 4 + strlen(bottom)) {
+               gnutls_assert();
                return -1;
-       data_size -= strlen(top);
-       rdata += strlen(top);
+       }
+       
+       do {
+               data_size--;
+               rdata++;
+       } while( ( strncmp( rdata, ENDSTR, strlen(ENDSTR)) != 0) && data_size > 0) ;
+
+       data_size -= strlen(ENDSTR);
+       rdata += strlen(ENDSTR);
 
        rdata_size = 0;
        do {
                rdata_size++;
        } while (rdata_size < data_size
-                && strncmp(&rdata[rdata_size], bottom,
-                           strlen(bottom)) != 0);
+                && strncmp(&rdata[rdata_size], bottom, strlen(bottom)) != 0);
 
-       if (rdata_size < 4)
+       if (rdata_size < 4) {
+               gnutls_assert();
                return -1;
+       }
 
        kdata_size = cpydata(rdata, rdata_size, &kdata);
 
-       if (kdata_size < 4)
+       if (kdata_size < 4) {
+               gnutls_assert();
                return -1;
-
-       kdata_size /= 4;
-       kdata_size *= 4;
-
-       ret = (kdata_size / 4) * 3;
-       (*result) = gnutls_malloc(ret);
-       if ((*result) == NULL)
-               return -1;
-
-       for (i = j = 0; i < kdata_size; i += 4) {
-               tmp = decode(tmpres, &kdata[i]);
-               if (tmp < 0) {
-                       gnutls_free( *result);
-                       return tmp;
-               }
-               memcpy(&(*result)[j], tmpres, tmp);
-               if (tmp < 3)
-                       ret -= (3 - tmp);
-               j += 3;
        }
+
+       if ((ret = _gnutls_base64_decode( kdata, kdata_size, result)) < 0) {
+               gnutls_assert();
+               gnutls_free(kdata);
+               return GNUTLS_E_PARSING_ERROR;
+       } 
        gnutls_free(kdata);
        return ret;
 }
index 58d4353044d2f5f489f66824dd8dd87c16ada48c..94a546c2f19814df9eaca4e51768ba962439c4cb 100644 (file)
@@ -2,5 +2,5 @@ int _gnutls_base64_encode(uint8 * data, int data_size, uint8 ** result);
 int _gnutls_fbase64_encode(char *msg, uint8 * data, int data_size,
                           uint8 ** result);
 int _gnutls_base64_decode(uint8 * data, int data_size, uint8 ** result);
-int _gnutls_fbase64_decode(char *msg, uint8 * data, int data_size,
+int _gnutls_fbase64_decode( uint8 * data, int data_size,
                           uint8 ** result);
index 029fa8526aa6a9ec532d3bc6b26784e266062aee..b472c8993d612554e66a9970d123e38c99e743c1 100644 (file)
@@ -686,11 +686,14 @@ char *crypt_bcrypt_wrapper(const char* username, const char *pass_new, int cost,
 {
        opaque *result;
        char *tcp;
-       uint8 *rand;
+       uint8 rand[17];
        char *e = NULL;
        int result_size;
 
-       rand = _gnutls_get_random(17, GNUTLS_WEAK_RANDOM);
+       if (_gnutls_get_random(&rand[1], 17, GNUTLS_WEAK_RANDOM) < 0 ) {
+               gnutls_assert();
+               return NULL;
+       }
        /* cost should be <32 and >6 */
        if (cost >= 32)
                cost = 31;
@@ -698,11 +701,7 @@ char *crypt_bcrypt_wrapper(const char* username, const char *pass_new, int cost,
                cost = 1;
 
        rand[0] = (uint8) cost;
-       result_size = _gnutls_sbase64_encode( &rand[0], 17, &result);
-
-       _gnutls_free_rand(rand);
-
-       _gnutls_sbase64_decode( result, strlen(result), &rand);
+       result_size = _gnutls_sbase64_encode( rand, 17, &result);
 
        if (result_size < 0) {
                gnutls_assert();
index 46cade81eddb3a49872c9d693433c2087cecc78a..91ea1704a2045a508a12432efca386c51f686a76 100644 (file)
@@ -116,18 +116,22 @@ char *crypt_srpsha1_wrapper(const char *username, const char *pass_new,
 {
        unsigned char *result;
        char *tcp;
-       unsigned char *rand;
+       opaque *rand;
        char *e = NULL;
        int result_size;
 
        if (salt > 50 || salt <= 0)
                return NULL;    /* wow that's pretty long salt */
 
-       rand = _gnutls_get_random(salt, GNUTLS_WEAK_RANDOM);
+       rand = gnutls_malloc(salt);
+       if (rand==NULL || _gnutls_get_random(rand, salt, GNUTLS_WEAK_RANDOM) < 0) {
+               gnutls_assert();
+               return NULL;
+       }
 
        result_size = _gnutls_sbase64_encode(rand, salt, &result);
        if (result_size < 0) {
-               _gnutls_free_rand(rand);
+               gnutls_free(rand);
                gnutls_assert();
                return NULL;
        }
@@ -136,7 +140,7 @@ char *crypt_srpsha1_wrapper(const char *username, const char *pass_new,
        sprintf(tcp, ":%s", result);
 
        gnutls_free(result);
-       _gnutls_free_rand(rand);
+       gnutls_free(rand);
        /* no longer need cleartext */
 
        e = crypt_srpsha1(username, pass_new, (const char *) tcp, g, n);
index 90406998d1e5da09fa838426caa2fdf77b411217..98bc6acd548efd4ccaa634c9d7b402b1a21fb127 100644 (file)
@@ -159,4 +159,10 @@ typedef struct {
                                */
 } X509PKI_SERVER_CREDENTIALS;
 
+/* CERTFILE is an x509 certificate in PEM form.
+ * KEYFILE is a pkcs-1 private key in PEM form.
+ */
+int gnutls_read_certs(X509PKI_SERVER_CREDENTIALS * res, char *CERTFILE,
+                     char *KEYFILE);
+
 /* error codes appended here */
index e1542bc323002e75e673ab3a31163f1e216755f3..d132c723ec2a61750f6e0f8297bcb7a4bbf9e520 100644 (file)
@@ -191,7 +191,7 @@ typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
 static const gnutls_kx_algo_entry kx_algorithms[] = {
        GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_ANON, 0, 0, 0, 1,
                             &anon_auth_struct),
-       GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, &x509pki_auth_struct),
+       GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, &rsa_auth_struct),
 /*     GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_DSS, 1, 1, 0, 0,
                             &dhe_dss_auth_struct),*/
 /*     GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 0, 0, NULL),*/
@@ -1093,6 +1093,7 @@ _gnutls_qsort(GNUTLS_STATE state, void *_base, size_t nmemb, size_t size,
 #ifdef DEBUG
        if (size > MAX_ELEM_SIZE) {
                gnutls_assert();
+               fprintf(stderr, "QSORT BUG\n");
                exit(1);
        }
 #endif
@@ -1232,6 +1233,7 @@ _gnutls_supported_ciphersuites_sorted(GNUTLS_STATE state,
        for (i = 0; i < j; i++)
                fprintf(stderr, "\t%d: %s\n", i,
                        _gnutls_cipher_suite_get_name((*ciphers)[i]));
+       fprintf(stderr, "SORT BUG\n");
        exit(0);
 #endif
 
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
new file mode 100644 (file)
index 0000000..9d7b39d
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *      Copyright (C) 2001 Nikos Mavroyanopoulos
+ *
+ * This file is part of GNUTLS.
+ *
+ * GNUTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <defines.h>
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <cert_b64.h>
+#include <auth_x509.h>
+
+/* FIXME: this function is a mess 
+ */
+int gnutls_read_certs(X509PKI_SERVER_CREDENTIALS * res, char *CERTFILE,
+                     char *KEYFILE)
+{
+       FILE *fd1, *fd2;
+       char x[100 * 1024];
+       int siz;
+       opaque *b64;
+
+       fd1 = fopen(CERTFILE, "r");
+       if (fd1 == NULL)
+               return GNUTLS_E_UNKNOWN_ERROR;
+
+       fd2 = fopen(KEYFILE, "r");
+       if (fd2 == NULL) {
+               fclose(fd1);
+               return GNUTLS_E_UNKNOWN_ERROR;
+       }
+
+       siz = fread(x, 1, sizeof(x), fd1);
+       siz = _gnutls_fbase64_decode(x, siz, &b64);
+
+       if (siz < 0) {
+               gnutls_assert();
+               return GNUTLS_E_PARSING_ERROR;
+       }
+
+       res->cert_list = (gnutls_datum**) gnutls_malloc(1*sizeof(gnutls_datum*));
+       if (res->cert_list == NULL)
+               return GNUTLS_E_MEMORY_ERROR;
+
+       res->cert_list[0] = (gnutls_datum*) gnutls_malloc(1*sizeof(gnutls_datum));
+       if (res->cert_list[0] == NULL)
+               return GNUTLS_E_MEMORY_ERROR;
+
+       res->cert_list_length = (int*) gnutls_malloc(1*sizeof(int*));
+       if (res->cert_list_length == NULL)
+               return GNUTLS_E_MEMORY_ERROR;
+
+       res->ncerts = 1;
+
+       res->cert_list_length[0] = 1;
+
+       res->cert_list[0][0].data = b64;
+       res->cert_list[0][0].size = siz;
+
+       fclose(fd1);
+
+
+
+
+/* second file */
+
+       siz = fread(x, 1, sizeof(x), fd2);
+       siz = _gnutls_fbase64_decode(x, siz, &b64);
+
+       if (siz < 0) {
+               gnutls_assert();
+               return GNUTLS_E_PARSING_ERROR;
+       }
+
+       res->pkey = gnutls_malloc(1*sizeof(gnutls_datum));
+       if (res->pkey == NULL)
+               return GNUTLS_E_MEMORY_ERROR;
+
+       res->pkey[0].data = b64;
+       res->pkey[0].size = siz;
+
+       fclose(fd2);
+
+       return 0;
+}
index f250b8fbe98576a3aa84be5ef8ebd7d1b0ab615f..2c9b24eeb50495020e321d42daac5afc151d396d 100644 (file)
@@ -435,7 +435,7 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state,
        uint16 c_length;
        uint8 *data;
        uint8 pad;
-       uint8 *rand;
+       uint8 rand;
        uint64 seq_num;
        int length;
        GNUTLS_MAC_HANDLE td;
@@ -515,24 +515,27 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state,
 
                break;
        case CIPHER_BLOCK:
-               rand = _gnutls_get_random(1, GNUTLS_WEAK_RANDOM);
+               if (_gnutls_get_random(&rand, 1, GNUTLS_WEAK_RANDOM) < 0) {
+                       gnutls_assert();
+                       return GNUTLS_E_MEMORY_ERROR;
+               }
 
                /* make rand a multiple of blocksize */
                if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
-                       rand[0] = 0;
+                       rand = 0;
                } else {
-                       rand[0] = (rand[0] / blocksize) * blocksize;
+                       rand = (rand / blocksize) * blocksize;
                        /* added to avoid the case of pad calculated 0
                         * seen below for pad calculation.
                         */
-                       if (rand[0] > blocksize) rand[0]-=blocksize;
+                       if (rand > blocksize) rand-=blocksize;
                }
 
                length =
                    compressed->length +
                    state->security_parameters.hash_size;
 
-               pad = (uint8) (blocksize - (length % blocksize)) + rand[0];
+               pad = (uint8) (blocksize - (length % blocksize)) + rand;
 
                length += pad;
                data = gnutls_malloc(length);
@@ -551,7 +554,6 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state,
                ciphertext->version.major = compressed->version.major;
                ciphertext->version.minor = compressed->version.minor;
 
-               _gnutls_free_rand(rand);
                break;
        default:
                gnutls_free(*cipher);
index c2657ca75b84ae76946e787b7f72ddb35fe90d71..7f92b2c45aa702724c78684f62c9eccf83256960 100644 (file)
@@ -59,6 +59,7 @@ static gnutls_error_entry error_algorithms[] = {
        GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_SCAN_FAILED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_PRINT_FAILED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_DECRYPTION_FAILED, 1),
+       GNUTLS_ERROR_ENTRY( GNUTLS_E_ENCRYPTION_FAILED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_DECOMPRESSION_FAILED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_COMPRESSION_FAILED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_MEMORY_ERROR, 1),
index 4b97c7c58ac6371243c5ba1bb7ff39472793ae35..ed98646485cb4319d862e5eb6765226c56e9584b 100644 (file)
@@ -37,4 +37,5 @@
 #define GNUTLS_E_GOT_HELLO_REQUEST -37
 #define GNUTLS_E_GOT_APPLICATION_DATA -38
 #define GNUTLS_E_RECORD_LIMIT_REACHED -39
+#define GNUTLS_E_ENCRYPTION_FAILED -40
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -50
index 46cf3e663d2332df5fe4adbb951dfa6ebf85aee3..83f8a3cb5eb87ea3684afa7ebda2af8a9d3f6ef9 100644 (file)
 static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data, int datalen);
 static int SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret, opaque * data, int datalen);
 
-static void set_server_random( GNUTLS_STATE state, uint8* random) {
+void _gnutls_set_server_random( GNUTLS_STATE state, uint8* random) {
        memcpy( state->security_parameters.server_random, random, 32);
-       memcpy( state->gnutls_key->server_random, random, 32);
+       if (state->gnutls_key!=NULL)
+               memcpy( state->gnutls_key->server_random, random, 32);
 }
-static void set_client_random( GNUTLS_STATE state, uint8* random) {
+void _gnutls_set_client_random( GNUTLS_STATE state, uint8* random) {
        memcpy( state->security_parameters.client_random, random, 32);
-       memcpy( state->gnutls_key->client_random, random, 32);
+       if (state->gnutls_key!=NULL)
+               memcpy( state->gnutls_key->client_random, random, 32);
 }
 
 /* Calculate The SSL3 Finished message */
@@ -156,19 +158,20 @@ void *_gnutls_finished(GNUTLS_STATE state, int type, int skip)
 /* this function will produce 32 bytes of random data
  * and put it to dst.
  */
-static int create_random( opaque* dst) {
+int _gnutls_create_random( opaque* dst) {
 uint32 tim;
-opaque* rand;
+opaque rand[28];
 
        tim = time(NULL);
        /* generate server random value */
        WRITEuint32( tim, dst);
 
-       rand = _gnutls_get_random(28, GNUTLS_STRONG_RANDOM);
+       if (_gnutls_get_random(rand, 28, GNUTLS_STRONG_RANDOM) < 0) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
        memcpy( &dst[4], rand, 28);
 
-       _gnutls_free_rand(rand);
-
        return 0;
 }
 
@@ -216,11 +219,11 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
        pos += 2;
 
        DECR_LEN(len, 32);
-       set_client_random( state, &data[pos]);
+       _gnutls_set_client_random( state, &data[pos]);
        pos += 32;
 
-       create_random( random);
-       set_server_random( state, random);
+       _gnutls_create_random( random);
+       _gnutls_set_server_random( state, random);
 
        state->security_parameters.timestamp = time(NULL);
 
@@ -228,9 +231,11 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
        memcpy(&session_id_len, &data[pos++], 1);
 
        /* RESUME SESSION */
-       if (session_id_len > 32)
+       if (session_id_len > 32) {
+               gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
-
+       }
+       
        DECR_LEN(len, session_id_len);
        ret =
            _gnutls_server_restore_session(state, &data[pos],
@@ -253,9 +258,9 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
                                            session_id,
                                            &state->security_parameters.
                                            session_id_size);
+
                state->gnutls_internals.resumed = RESUME_FALSE;
        }
-
        /* Select a ciphersuite */
        DECR_LEN(len, 2);
        sizeOfSuites = READuint16( &data[pos]);
@@ -267,8 +272,10 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
                          sizeOfSuites);
 
        pos += sizeOfSuites;
-       if (ret < 0)
+       if (ret < 0) {
+               gnutls_assert();
                return ret;
+       }
 
 
        /* check if the credentials (username, public key etc. are ok)
@@ -282,6 +289,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
                return GNUTLS_E_INSUFICIENT_CRED;
        }
 
+
        /* set the MOD_AUTH_STRUCT to the appropriate struct
         * according to the KX algorithm. This is needed since all the
         * handshake functions are read from there;
@@ -372,6 +380,7 @@ int _gnutls_recv_finished(int cd, GNUTLS_STATE state)
                                   GNUTLS_FINISHED);
        if (ret < 0) {
                ERR("recv finished int", ret);
+               gnutls_assert();
                return ret;
        }
 
@@ -439,7 +448,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
 
        for (j = 0; j < datalen; j += 2) {
                for (i = 0; i < x; i++) {
-                       if (memcmp(&ciphers[i].CipherSuite, &data[j], 2) ==
+                       if (memcmp(ciphers[i].CipherSuite, &data[j], 2) ==
                            0) {
 #ifdef HARD_DEBUG
                                fprintf(stderr, "Selected cipher suite: ");
@@ -447,7 +456,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
                                        _gnutls_cipher_suite_get_name(*
                                                                      ((GNUTLS_CipherSuite *) & data[j])));
 #endif
-                               memcpy(ret, &ciphers[i].CipherSuite, 2);
+                               memcpy(ret, ciphers[i].CipherSuite, 2);
                                gnutls_free(ciphers);
 
                                return 0;
@@ -785,7 +794,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
        pos += 2;
 
        DECR_LEN(len, 32);
-       set_server_random( state, &data[pos]);
+       _gnutls_set_server_random( state, &data[pos]);
        pos += 32;
 
        DECR_LEN(len, 1);
@@ -955,8 +964,8 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state)
                    _gnutls_version_get_minor(state->connection_state.
                                              version);
 
-               create_random( random);
-               set_client_random( state, random);
+               _gnutls_create_random( random);
+               _gnutls_set_client_random( state, random);
                
                state->security_parameters.timestamp = time(0);
 
@@ -1551,15 +1560,17 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state)
 
 int _gnutls_generate_session_id(char *session_id, uint8 * len)
 {
-       char *rand;
-       rand = _gnutls_get_random(32, GNUTLS_WEAK_RANDOM);
+       opaque rand[32];
+       if (_gnutls_get_random(rand, 32, GNUTLS_WEAK_RANDOM) < 0) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
 
        memcpy(session_id, rand, 32);
-       _gnutls_free_rand(rand);
        *len = 32;
 
 #ifdef HARD_DEBUG
-       fprintf(stderr, "SessionID: %s\n",
+       fprintf(stderr, "Generated SessionID: %s\n",
                _gnutls_bin2hex(session_id, 32));
 #endif
        return 0;
index 625b80fef2138d8608a42a1a31991fe66ca7eb12..cbdbf5def0ee7a62925b027a902385dfffa42319 100644 (file)
@@ -29,3 +29,6 @@ int _gnutls_generate_session_id( char* session_id, uint8* len);
 int _gnutls_recv_certificate(int cd, GNUTLS_STATE state, char *data, int datalen);
 int gnutls_handshake_begin(int cd, GNUTLS_STATE state);
 int gnutls_handshake_finish(int cd, GNUTLS_STATE state);
+void _gnutls_set_server_random( GNUTLS_STATE state, uint8* random);
+void _gnutls_set_client_random( GNUTLS_STATE state, uint8* random);
+int _gnutls_create_random( opaque* dst);
index 8fac4a42e851ed16806102f2e9c1cd75f0efa8f2..b581b6126c6c9eebced7feb8edf5a8509d676c05 100644 (file)
@@ -27,9 +27,9 @@
 #define WRITE_DEBUG
 #define BUFFERS_DEBUG
 #define HANDSHAKE_DEBUG
+*/
 #define HARD_DEBUG
 #define DEBUG
-*/
 
 #define LIST ...
 
index fa5b7e1708ecb675291c1b251d1b9f2cb953b8bb..6108926c8bdd8f6f44171f729f4513df5d139600 100644 (file)
@@ -104,7 +104,11 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state)
 
        ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_SERVER_KEY_EXCHANGE);
        gnutls_free(data);
-       
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
        return data_size;
 }
 
@@ -118,13 +122,14 @@ int _gnutls_send_server_kx_message2(int cd, GNUTLS_STATE state)
            _gnutls_cipher_suite_get_kx_algo
            (state->gnutls_internals.current_cipher_suite);
 
-#ifdef HARD_DEBUG
-       fprintf(stderr, "Sending server KX message2\n");
-#endif
 
        if (_gnutls_kx_server_key_exchange2(algorithm) != 0) {
                data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx2( state->gnutls_key, &data);
 
+#ifdef HARD_DEBUG
+               fprintf(stderr, "Sending server KX message2\n");
+#endif
+
                if (data_size<0) {
                        gnutls_assert();
                        return data_size;
@@ -177,6 +182,11 @@ int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state)
        ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_CLIENT_KEY_EXCHANGE);
        gnutls_free(data);
 
+       if (ret<0) {
+               gnutls_assert();
+               return ret;
+       }
+
        ret = generate_master( state);
        if (ret<0) {
                gnutls_assert();
@@ -432,5 +442,10 @@ int _gnutls_send_certificate(int cd, GNUTLS_STATE state)
        ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_CERTIFICATE);
        gnutls_free(data);
        
+       if (ret<0) {
+               gnutls_assert();
+               return ret;
+       }
+
        return data_size;
 }
index eaa1519979292d596773992fdfe66e7530882c1d..125ac949d8cde6ea2dda68e8577fff6ddad371f6 100644 (file)
@@ -20,6 +20,9 @@
 
 #include <gnutls_int.h>
 
+#define GMIN(x,y) (x<y)?x:y
+#define GMAX(x,y) (x>y)?x:y
+
 uint32 uint24touint32( uint24 num);
 uint24 uint32touint24( uint32 num);
 uint32 READuint32( const opaque* data);
index 716139890bc63be317be806c7ac4b702cd5e466d..7cd01ab86f5e1777d4c011b8021ba5d79808b7a9 100644 (file)
 #include <gnutls_gcry.h>
 #include <gnutls_pk.h>
 #include <gnutls_errors.h>
+#include <gnutls_random.h>
+#include <gnutls_datum.h>
+
+/* Do PKCS-1 RSA encryption. 
+ * pkey is the public key and n the modulus.
+ */
+
+int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, gnutls_datum plaintext,
+                     MPI pkey, MPI n)
+{
+       int k, psize, i, ret;
+       MPI m, res;
+       opaque *edata, *ps;
+       MPI *_pkey[2];
+
+       k = gcry_mpi_get_nbits(n) / 8;
+
+       if (plaintext.size > k - 11) {
+               gnutls_assert();
+               return GNUTLS_E_ENCRYPTION_FAILED;
+       }
+
+       edata = gnutls_malloc(k);
+       if (edata == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       /* EB = 00||BT||PS||00||D 
+        * (use block type 2)
+        */
+
+       edata[0] = 0;
+       edata[1] = 2;
+       psize = k - 3 - plaintext.size;
+
+       ps = &edata[2];
+       _gnutls_get_random(ps, psize, GNUTLS_WEAK_RANDOM);
+       for (i = 0; i < psize; i++) {
+               if (ps[i] == 0)
+                       ps[i] = 0xff;
+       }
+       ps[psize] = 0;
+       memcpy(&ps[psize + 1], plaintext.data, plaintext.size);
+
+       if (gcry_mpi_scan(&m, GCRYMPI_FMT_USG, edata, &k) != 0) {
+               gnutls_assert();
+               gnutls_free(edata);
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+       gnutls_free(edata);
+
+       _pkey[0] = &n;
+       _pkey[1] = &pkey;
+       ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, m, _pkey);
+       gcry_mpi_release(m);
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &psize, res);
+       ciphertext->data = gnutls_malloc(psize);
+       if (ciphertext->data == NULL) {
+               gnutls_assert();
+               gcry_mpi_release(res);
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+       gcry_mpi_print(GCRYMPI_FMT_USG, ciphertext->data, &psize, res);
+       ciphertext->size = psize;
+
+       gcry_mpi_release(res);
+
+       return 0;
+}
+
+
+/* Do PKCS-1 RSA decryption. 
+ * pkey is the private key and n the modulus.
+ */
+
+int _gnutls_pkcs1_rsa_decrypt(gnutls_datum * plaintext, gnutls_datum ciphertext,
+                     MPI pkey, MPI n)
+{
+       int k, esize, i, ret;
+       MPI c, res;
+       opaque *edata;
+       MPI *_pkey[2];
+
+       k = gcry_mpi_get_nbits(n) / 8;
+       
+       esize = ciphertext.size;
+
+       if (esize!=k) {
+               gnutls_assert();
+               return GNUTLS_E_DECRYPTION_FAILED;
+       }
+       
+       if (gcry_mpi_scan(&c, GCRYMPI_FMT_USG, ciphertext.data, &esize) != 0) {
+               gnutls_assert();
+               gnutls_free(edata);
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       _pkey[0] = &n;
+       _pkey[1] = &pkey;
+
+       ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, c, _pkey);
+       gcry_mpi_release(c);
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &esize, res);
+       edata = gnutls_malloc(esize);
+       if (edata == NULL) {
+               gnutls_assert();
+               gcry_mpi_release(res);
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+       gcry_mpi_print(GCRYMPI_FMT_USG, edata, &esize, res);
+
+       gcry_mpi_release(res);
+
+       /* EB = 00||BT||PS||00||D 
+        * (use block type 2)
+        */
+
+       if (edata[0] != 0 || edata[1] != 2) {
+               gnutls_assert();
+               gnutls_free(edata);
+               return GNUTLS_E_DECRYPTION_FAILED;
+       }
+
+       ret = GNUTLS_E_DECRYPTION_FAILED;
+       for (i=2;i<esize;i++) {
+               if (edata[i]==0) { 
+                       ret = 0;
+                       break;
+               }
+       }
+       i++;
+       
+       if (ret < 0) {
+               gnutls_assert();
+               gnutls_free(edata);
+               return GNUTLS_E_DECRYPTION_FAILED;
+       }
+       
+       if (gnutls_set_datum( plaintext, &edata[i], esize - i) < 0) {
+               gnutls_assert();
+               gnutls_free(edata);
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+       
+       gnutls_free(edata);
+
+       return 0;
+}
 
 /* this is taken from gnupg 
  */
+
 /****************
  * Emulate our old PK interface here - sometime in the future we might
  * change the internal design to directly fit to libgcrypt.
  */
-int _gnutls_pk_encrypt(enum gcry_pk_algos algo, MPI * resarr, MPI data, MPI * pkey)
+int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI **pkey)
 {
        GCRY_SEXP s_ciph, s_data, s_pkey;
        int rc;
@@ -39,14 +201,14 @@ int _gnutls_pk_encrypt(enum gcry_pk_algos algo, MPI * resarr, MPI data, MPI * pk
        /* make a sexp from pkey */
        if (algo == GCRY_PK_RSA) {
                rc = gcry_sexp_build(&s_pkey, NULL,
-                                    "(public-key(rsa(p%m)(e%m)))", 
-                                    pkey[0], pkey[1] );
+                                    "(public-key(rsa(p%m)(e%m)))",
+                                    *pkey[0], *pkey[1]);
        } else {
                gnutls_assert();
                return GNUTLS_E_UNKNOWN_KX_ALGORITHM;
        }
 
-       if (rc!=0) {
+       if (rc != 0) {
                gnutls_assert();
                return GNUTLS_E_UNKNOWN_ERROR;
        }
@@ -62,14 +224,26 @@ int _gnutls_pk_encrypt(enum gcry_pk_algos algo, MPI * resarr, MPI data, MPI * pk
        gcry_sexp_release(s_data);
        gcry_sexp_release(s_pkey);
 
-       if (rc);
-       else {                  /* add better error handling or make gnupg use S-Exp directly */
+       if (rc != 0) {
+               gnutls_assert();
+               return GNUTLS_E_UNKNOWN_ERROR;
+               
+       } else {                /* add better error handling or make gnupg use S-Exp directly */
                GCRY_SEXP list = gcry_sexp_find_token(s_ciph, "a", 0);
-               /* assert(list); */
+               if (list == NULL) {
+                       gnutls_assert();
+                       gcry_sexp_release(s_ciph);
+                       return GNUTLS_E_UNKNOWN_ERROR;
+               }
+
                resarr[0] = gcry_sexp_nth_mpi(list, 1, 0);
-               /* assert(resarr[0]); */
                gcry_sexp_release(list);
 
+               if (resarr[0] == NULL) {
+                       gnutls_assert();
+                       gcry_sexp_release(s_ciph);
+                       return GNUTLS_E_UNKNOWN_ERROR;
+               }
        }
 
        gcry_sexp_release(s_ciph);
index bcb0c5243ad4db23d2c4d3548cd9d32ab7ae697b..f6eb0328c771f6eeb09233d7b3f74764cbd5f336 100644 (file)
@@ -1,2 +1,5 @@
-int _gnutls_pk_encrypt(enum gcry_pk_algos algo, MPI * resarr, MPI data, MPI * pkey);
-
+int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI ** pkey);
+int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, gnutls_datum plaintext,
+                     MPI pkey, MPI n);
+int _gnutls_pkcs1_rsa_decrypt(gnutls_datum * plaintext, gnutls_datum ciphertext,
+                     MPI pkey, MPI n);
index b7e3839a460d647d3f11a04ff782b7f0537b915d..20b83ddeb8ca99544188c41751faa99cac2a0f7a 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
-#include "defines.h"
-#include "gnutls_int.h"
-#include "gnutls_random.h"
+#include <defines.h>
+#include <gnutls_int.h>
+#include <gnutls_random.h>
+#include <gnutls_errors.h>
 #ifndef USE_GCRYPT
 # include <unistd.h>
 # include <sys/types.h>
 # include <sys/time.h>
 #endif
 
-char *_gnutls_get_random(int bytes, int dev)
+int _gnutls_get_random(opaque * res, int bytes, int dev)
 {
 #ifndef USE_GCRYPT
     int fd;
     struct timeval tv;
     char prand[16];
-    char * buf = gnutls_malloc(bytes);
     char *device;
-    
+        
     switch(dev) {
        case 1:
                device = "/dev/random";
@@ -54,25 +54,28 @@ char *_gnutls_get_random(int bytes, int dev)
        memcpy(&prand[8], &fd, sizeof(fd));
        fd = clock();
        memcpy(&prand[12], &fd, sizeof(fd));
-       memset(buf, 0, bytes);
+       memset(res, 0, bytes);
        if (bytes > 16)
            bytes = 16;
-       memcpy(buf, prand, bytes);
+       memcpy(res, prand, bytes);
     } else {
-       read(fd, buf, bytes);
+       read(fd, res, bytes);
        close(fd);
     }
-    return buf;
+    return 0;
 #else                          /* using gcrypt */
-    return gcry_random_bytes(bytes, dev);
+    char* buf;
+    buf = gcry_random_bytes(bytes, dev);
+    if (buf==NULL) {
+       gnutls_assert();
+       return GNUTLS_E_MEMORY_ERROR;
+    }
+
+    memcpy( res, buf, bytes);
+    gnutls_free(buf);
+    
+    return 0;
 #endif
 
 }
 
-void _gnutls_free_rand(void* rand) {
-#ifndef USE_GCRYPT
-       gnutls_free(rand);
-#else
-       gcry_free(rand);
-#endif
-}
\ No newline at end of file
index b226900e93cf61998def018bb1292bed684a1b29..7d55822e562a5aeb2c1821fb939ec320b3550b0a 100644 (file)
@@ -8,5 +8,4 @@
 # define GNUTLS_STRONG_RANDOM GCRY_STRONG_RANDOM
 #endif
 
-char *_gnutls_get_random(int bytes, int);
-void _gnutls_free_rand(void* rand);
+int _gnutls_get_random(opaque* res, int bytes, int);
similarity index 96%
rename from lib/gnutls.c
rename to lib/gnutls_record.c
index 71dd379ef3c7ed9c1b354abb8a826f8506adcb96..08da041031946248d3bf00fecaada107fd7f837e 100644 (file)
@@ -50,8 +50,10 @@ GNUTLS_Version ver;
 
 void gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version) {
        state->connection_state.version = version;
-       state->gnutls_key->version.major = _gnutls_version_get_major(version);
-       state->gnutls_key->version.minor = _gnutls_version_get_minor(version);
+       if (state->gnutls_key!=NULL) {
+               state->gnutls_key->version.major = _gnutls_version_get_major(version);
+               state->gnutls_key->version.minor = _gnutls_version_get_minor(version);
+       }
 }
 
 int gnutls_is_secure_memory(const void* mem) {
@@ -426,6 +428,19 @@ int gnutls_bye(int cd, GNUTLS_STATE state)
        return ret;
 }
 
+/* This function will check the input buffer for 
+ * any pending alert.
+ */
+int _gnutls_check_for_pending_alert(int cd, GNUTLS_STATE state)
+{
+       int ret;
+
+       /* receive the closure alert */
+       ret = gnutls_recv_int(cd, state, GNUTLS_ALERT, NULL, 0, 0|MSG_DONTWAIT); 
+
+       return ret;
+}
+
 int gnutls_close_nowait(int cd, GNUTLS_STATE state)
 {
        int ret;
@@ -457,7 +472,12 @@ ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, const void
        if (state->gnutls_internals.valid_connection == VALID_FALSE) {
                return GNUTLS_E_INVALID_SESSION;
        }
-
+       
+       if (type==GNUTLS_HANDSHAKE) {
+               if ((ret = _gnutls_check_for_pending_alert(cd, state)) < 0)
+                       return ret;
+       }
+       
        if (sizeofdata < MAX_ENC_LEN) {
                iterations = 1;
                Size = sizeofdata;
@@ -637,6 +657,14 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data
         * must be set to non blocking mode
         */
        if ( _gnutls_Read(cd, headers, HEADER_SIZE, MSG_PEEK|flags) != HEADER_SIZE) {
+               if (type==GNUTLS_ALERT && flags==MSG_DONTWAIT) 
+                       return 0;                 /* we expected an alert
+                                                  * but nothing came thus success.
+                                                  * we only wait for an alert
+                                                  * in check_pending_alert().
+                                                  */
+               /* How do we handle errno in a multithread environment? 
+                */
                if (errno==EAGAIN) return GNUTLS_E_AGAIN;
                state->gnutls_internals.valid_connection = VALID_FALSE;
                if (type==GNUTLS_ALERT) return 0; /* we were expecting close notify */
@@ -653,10 +681,11 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data
        /* if msb set and expecting handshake message
         * it should be SSL 2 hello 
         */
-               version = GNUTLS_SSL3; /* assume ssl 3.0 */
+               version = GNUTLS_SSL3; /* assume ssl 3.0 - not really needed */
                length = (((headers[0] & 0x7f) << 8)) | headers[1];
                header_size = 2;
-               recv_type = GNUTLS_HANDSHAKE; /* only v2 client hello we accept */
+               recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
+                                              */
                state->gnutls_internals.v2_hello = length;
 #ifdef DEBUG
                fprintf(stderr, "Record: V2 packet received. Length: %d\n", length);
@@ -671,7 +700,7 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data
                length = READuint16( &headers[3]);
        }
        
-       if ( gnutls_get_current_version(state) != version) {
+       if ( gnutls_get_current_version(state) != version && recv_type != GNUTLS_HANDSHAKE) {
 #ifdef DEBUG
                fprintf(stderr, "Record: INVALID VERSION PACKET: (%d) %d.%d\n", headers[0], headers[1], headers[2]);
 #endif
index 8577c4926259fe1a0b2950e2e732ab341749d4dc..d3f022662ce3dbd3e053a8296cbcc6c865152628 100644 (file)
@@ -90,6 +90,8 @@ int _gnutls_srp_gn(opaque ** ret_g, opaque ** ret_n, int bits)
        gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &siz, g);
        if (ret_g != NULL) {
                tmp = gnutls_malloc(siz);
+               if (tmp==NULL) return GNUTLS_E_MEMORY_ERROR;
+               
                gcry_mpi_print(GCRYMPI_FMT_USG, tmp, &siz, g);
 
                if (_gnutls_sbase64_encode(tmp, siz, ret_g) < 0) {
@@ -103,6 +105,8 @@ int _gnutls_srp_gn(opaque ** ret_g, opaque ** ret_n, int bits)
        gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &siz, prime);
        if (ret_n != NULL) {
                tmp = gnutls_malloc(siz);
+               if (tmp==NULL) return GNUTLS_E_MEMORY_ERROR;
+
                gcry_mpi_print(GCRYMPI_FMT_USG, tmp, &siz, prime);
                if (_gnutls_sbase64_encode(tmp, siz, ret_n) < 0) {
                        gnutls_free(tmp);
@@ -141,6 +145,8 @@ int _gnutls_srp_gx(opaque * text, int textsize, opaque ** result, MPI g,
        gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e);
        if (result != NULL) {
                *result = gnutls_malloc(result_size);
+               if ((*result)==NULL) return GNUTLS_E_MEMORY_ERROR;
+
                gcry_mpi_print(GCRYMPI_FMT_USG, *result, &result_size, e);
        }
 
@@ -191,11 +197,17 @@ MPI _gnutls_calc_srp_u(MPI B)
 
        gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &b_size, B);
        b_holder = gnutls_malloc(b_size);
+       if (b_holder==NULL) return NULL;
 
        gcry_mpi_print(GCRYMPI_FMT_USG, b_holder, &b_size, B);
 
 
        td = gnutls_hash_init(GNUTLS_MAC_SHA);
+       if (td==NULL) {
+               gnutls_free(b_holder);
+               gnutls_assert();
+               return NULL;
+       }
        gnutls_hash(td, b_holder, b_size);
        hd = gnutls_hash_deinit(td);
        memcpy(&u, hd, sizeof(u));
index ac678ffd1bd189282235d87ad8d37b644eb82970..ce4e2b59216ba1831355791c9c27bf77193631db 100644 (file)
@@ -48,12 +48,11 @@ static int SelectSuite_v2(GNUTLS_STATE state, opaque ret[2], char *data,
        x = _gnutls_supported_ciphersuites(state, &ciphers);
 #ifdef HARD_DEBUG
        fprintf(stderr, "Requested cipher suites: \n");
-       for (j = 0; j < datalen; j += 2) {
+       for (j = 0; j < datalen; j += 3) {
                if (data[j] == 0) {     /* only print if in v2 compat mode */
-                       j++;
                        fprintf(stderr, "\t%s\n",
                                _gnutls_cipher_suite_get_name(*
-                                                             ((GNUTLS_CipherSuite *) & data[j])));
+                                                             ((GNUTLS_CipherSuite *) & data[j+1])));
                }
        }
        fprintf(stderr, "Supported cipher suites: \n");
@@ -61,13 +60,12 @@ static int SelectSuite_v2(GNUTLS_STATE state, opaque ret[2], char *data,
                fprintf(stderr, "\t%s\n",
                        _gnutls_cipher_suite_get_name(ciphers[j]));
 #endif
-       memset(ret, '\0', sizeof(GNUTLS_CipherSuite));
+       memset(ret, '\0', 2);
 
-       for (j = 0; j < datalen; j += 2) {
+       for (j = 0; j < datalen; j += 3) {
                for (i = 0; i < x; i++) {
-                       if (data[j++] == 0)
-                               if (memcmp
-                                   (&ciphers[i].CipherSuite, &data[j],
+                       if (data[j] == 0)
+                               if ( memcmp(ciphers[i].CipherSuite, &data[j+1],
                                     2) == 0) {
 #ifdef HARD_DEBUG
                                        fprintf(stderr,
@@ -76,10 +74,10 @@ static int SelectSuite_v2(GNUTLS_STATE state, opaque ret[2], char *data,
                                                _gnutls_cipher_suite_get_name
                                                (*
                                                 ((GNUTLS_CipherSuite *) &
-                                                 data[j])));
+                                                 data[j+1])));
 #endif
                                        memmove(ret,
-                                               &ciphers[i].CipherSuite,
+                                               ciphers[i].CipherSuite,
                                                2);
                                        gnutls_free(ciphers);
 
@@ -109,7 +107,7 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data,
        int ret = 0;
        uint16 sizeOfSuites;
        GNUTLS_Version version;
-       char *rand;
+       opaque random[32];
        int len = datalen;
        int err;
        uint16 challenge;
@@ -149,9 +147,10 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data,
        session_id_len = READuint16( &data[pos]);
        pos += 2;
 
-       if (session_id_len > 32)
+       if (session_id_len > 32) {
+               gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
-
+       }
 
        /* read challenge length */
        DECR_LEN(len, 2);
@@ -172,9 +171,10 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data,
                                  &data[pos], sizeOfSuites);
 
        pos += sizeOfSuites;
-       if (ret < 0)
+       if (ret < 0) {
+               gnutls_assert();
                return ret;
-
+       }
 
        /* check if the credentials (username, public key etc. are ok)
         */
@@ -207,17 +207,17 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data,
        pos+=session_id_len;
        
        DECR_LEN(len, challenge);
-       memset( state->security_parameters.client_random, 0, 32);
+       memset( random, 0, 32);
+       memcpy( random, &data[challenge > 32 ? (pos+challenge-32) : pos], challenge < 32 ? challenge : 32);
 
        /* read the last 32 bytes */
-       memcpy( state->security_parameters.client_random, &data[challenge > 32 ? (pos+challenge-32) : pos], challenge < 32 ? challenge : 32);
+       _gnutls_set_client_random( state, random);
 
        /* generate server random value */
-       WRITEuint32( time(NULL), state->security_parameters.server_random);
 
-       rand = _gnutls_get_random(28, GNUTLS_STRONG_RANDOM);
-       memmove(&state->security_parameters.server_random[4], rand, 28);
-       _gnutls_free_rand(rand);
+       _gnutls_create_random( random);
+       _gnutls_set_server_random( state, random);
+       
        state->security_parameters.timestamp = time(NULL);
 
 
@@ -249,5 +249,5 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data,
                state->gnutls_internals.resumed = RESUME_FALSE;
        }
 
-       return ret;
+       return 0;
 }