+## Process this file with automake to produce Makefile.in
-SUBDIRS = lib src
-
+SUBDIRS = src
+
\ No newline at end of file
-/* acconfig.h - used by autoheader to make config.h.in
- */
-#ifndef GPA_CONFIG_H
-#define GPA_CONFIG_H
+/* and the real names of the random devices */
+#undef NAME_OF_DEV_RANDOM
+#undef NAME_OF_DEV_URANDOM
+#undef HAVE_DEV_RANDOM
-/* Need this, because some autoconf tests rely on this (e.g. stpcpy)
- * and it should be used for new programs anyway. */
-#define _GNU_SOURCE 1
+#undef PACKAGE
+#undef VERSION
-@TOP@
+#undef T_CPU
+#undef T_VENDOR
+#undef T_OS
-#undef HAVE_BYTE_TYPEDEF
-
-
-@BOTTOM@
-
-
-#endif /*GPA_CONFIG_H*/
+LT_CURRENT
+LT_REVISION
+LT_AGE
+
\ No newline at end of file
#! /bin/sh
aclocal && \
-libtoolize -c --force --ltdl && \
+libtoolize -c --force && \
autoheader && \
automake -a -c || automake -a -c
autoconf
-dnl
-dnl Configure script source for GNUTLS
-dnl
-dnl (Process this file with autoconf to produce a configure script.)
-AC_REVISION($Revision$)dnl
-AC_PREREQ(2.13)
-
-AC_INIT(src/gnutls.c)
-AM_CONFIG_HEADER(config.h)
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT()
+dnl AC_CONFIG_HEADER(config.h)
-dnl
-dnl The version number goes here
-dnl
-AM_INIT_AUTOMAKE(gnutls,0.0.0)
+AC_PREFIX_DEFAULT(/usr/local)
-dnl
-dnl Setup some stuff depending on host/target.
-dnl
-case "${target}" in
- *-*-mingw32)
- # special stuff for Windoze NT
- # Do we need to set cross_compiling here or is it sufficient
- # to rely on AC_PROG_CC which is called later?
- CC="${target}-gcc"
- CPP="${target}-gcc -E"
- RANLIB="${target}-ranlib"
- ;;
- *)
- ;;
-esac
+AC_CANONICAL_SYSTEM
+AC_DEFINE_UNQUOTED(T_CPU, "$target_cpu")
+AC_DEFINE_UNQUOTED(T_VENDOR, "$target_vendor")
+AC_DEFINE_UNQUOTED(T_OS, "$target_os")
+GNUTLS_MAJOR_VERSION=0
+GNUTLS_MINOR_VERSION=0
+GNUTLS_MICRO_VERSION=1
+GNUTLS_VERSION=$GNUTLS_MAJOR_VERSION.$GNUTLS_MINOR_VERSION.$GNUTLS_MICRO_VERSION
-AM_MAINTAINER_MODE
-dnl
-dnl Checks for programs
-dnl
-AC_PROG_CC
-AC_STDC_HEADERS
-AC_ARG_PROGRAM
-AC_PROG_RANLIB
+AM_INIT_AUTOMAKE(gnutls, $GNUTLS_VERSION)
+AM_CONFIG_HEADER(config.h)
-dnl
-dnl Checks for libraries
-dnl
+GNUTLS_MOST_RECENT_INTERFACE=$GNUTLS_MINOR_VERSION
+GNUTLS_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER=$GNUTLS_MICRO_VERSION
+GNUTLS_OLDEST_INTERFACE=0
+AC_SUBST(GNUTLS_MAJOR_VERSION)
+AC_SUBST(GNUTLS_MINOR_VERSION)
+AC_SUBST(GNUTLS_MICRO_VERSION)
+AC_SUBST(GNUTLS_VERSION)
-dnl
-dnl Checks for header files
-dnl
+AC_SUBST(GNUTLS_MOST_RECENT_INTERFACE)
+AC_SUBST(GNUTLS_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER)
+AC_SUBST(GNUTLS_OLDEST_INTERFACE)
+LT_CURRENT=$GNUTLS_MOST_RECENT_INTERFACE
+LT_REVISION=$GNUTLS_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER
+LT_AGE=`expr $GNUTLS_MOST_RECENT_INTERFACE - $GNUTLS_OLDEST_INTERFACE`
+AC_SUBST(LT_CURRENT)
+AC_SUBST(LT_REVISION)
+AC_SUBST(LT_AGE)
-dnl
-dnl Checks for typedefs and structures
-dnl
-dnl
-dnl Checks for compiler features
-dnl
+AC_PROG_CC
+
-dnl
-dnl Checks for library functions
-dnl
+AC_C_CONST
+dnl Checks for programs.
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PATH_PROG(RM,rm)
+AC_PATH_PROG(MAKEINFO,makeinfo)
+dnl AC_PATH_PROG(AR,ar)
+dnl AC_PATH_PROG(RANLIB,ranlib)
-dnl
-dnl Checks for system services
-dnl
+dnl AC_PROG_MAKE_SET
+dnl From GNUPG
+AC_MSG_CHECKING([whether use of /dev/random is requested])
+AC_ARG_ENABLE(dev-random,
+[ --disable-dev-random disable the use of dev random],
+ try_dev_random=$enableval, try_dev_random=yes)
+AC_MSG_RESULT($try_dev_random)
-AC_OUTPUT([
-Makefile
-lib/Makefile
-src/Makefile
-])
+opt_maintainer_mode=no
+AC_MSG_CHECKING([whether in maintanance mode])
+AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable maintainer mode],
+opt_maintainer_mode=$enableval)
+AC_MSG_RESULT($opt_maintainer_mode)
+case "${target}" in
+ *-openbsd*)
+ NAME_OF_DEV_RANDOM="/dev/srandom"
+ NAME_OF_DEV_URANDOM="/dev/urandom"
+ ;;
+ *)
+ NAME_OF_DEV_RANDOM="/dev/random"
+ NAME_OF_DEV_URANDOM="/dev/urandom"
+ ;;
+esac
-dnl *-*wedit:notab*-* Please keep this as the last line.
+AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM")
+AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM")
+
+dnl check whether we have a random device
+if test "$try_dev_random" = yes ; then
+AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
+[if test -c "/dev/random" && test -c "$NAME_OF_DEV_URANDOM" ; then
+ ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi])
+if test "$ac_cv_have_dev_random" = yes; then
+ AC_DEFINE(HAVE_DEV_RANDOM)
+else
+ AC_MSG_WARN(No random device found. No real random data can be used.)
+fi
+else
+ AC_MSG_CHECKING(for random device)
+ ac_cv_have_dev_random=no
+ AC_MSG_RESULT(has been disabled)
+ AC_MSG_WARN(Support for random device was disabled. No real random data can be used.)
+fi
+
+
+if test $ac_cv_prog_gcc = yes; then
+ CFLAGS="${CFLAGS} -ffast-math"
+
+ if test $opt_maintainer_mode = yes; then
+ CFLAGS="${CFLAGS} -Wall -Wpointer-arith -pedantic"
+ fi
+fi
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h pwd.h locale.h strings.h mcrypt.h)
+AC_CHECK_HEADERS(sys/stat.h sys/types.h fcntl.h sys/wait.h)
+AC_CHECK_HEADERS(utime.h signal.h)
+AC_CHECK_HEADERS(termios.h termio.h sgtty.h)
+AC_CHECK_FUNCS(bzero signal sigaction memset fcntl fsync siglongjmp,,)
+AC_CHECK_FUNCS(lstat stat umask utime memmove bcopy getpwuid waitpid,,)
+
+dnl Checks for libraries.
+AC_C_BIGENDIAN
+AC_TYPE_SIGNAL
+AC_CHECK_SIZEOF(unsigned long long, 8)
+AC_CHECK_SIZEOF(unsigned long int, 4)
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned short int, 2)
+AC_CHECK_SIZEOF(unsigned char, 1)
+
+AM_PROG_LIBTOOL
+
+AC_OUTPUT([Makefile src/Makefile])
-## Process this file with automake to produce Makefile.in
-
-bin_PROGRAMS = foo
-
-
-foo_SOURCES = foo.c foo.h
-
+include_HEADERS = gnutls.h
+EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h gnutls_cipher.h
+lib_LTLIBRARIES = libgnutls.la
+libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c gnutls_cipher.c
+libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+bin_PROGRAMS = test
+test_SOURCES = test.c
+test_LDADD = libgnutls.la -lgcrypt -lmhash
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <defines.h>
+#include "gnutls.h"
+
+
+static char hexconvtab[] = "0123456789abcdef";
+
+char * bin2hex(const unsigned char *old, const size_t oldlen)
+{
+ unsigned char *new = NULL;
+ int i, j;
+
+ new = malloc(oldlen * 2 * sizeof(char) + 1);
+ if (!new)
+ return (new);
+
+ for (i = j = 0; i < oldlen; i++) {
+ new[j++] = hexconvtab[old[i] >> 4];
+ new[j++] = hexconvtab[old[i] & 15];
+ }
+ new[j] = '\0';
+
+ return (new);
+}
+
+
+void _print_state(GNUTLS_STATE state)
+{
+
+ fprintf(stderr, "GNUTLS State:\n");
+ fprintf(stderr, "Connection End: %d\n",
+ state->security_parameters.entity);
+ fprintf(stderr, "Cipher Algorithm: %d\n",
+ state->security_parameters.bulk_cipher_algorithm);
+ fprintf(stderr, "Cipher Type: %d\n",
+ state->security_parameters.cipher_type);
+ fprintf(stderr, "Key Size: %d\n",
+ state->security_parameters.key_size);
+ fprintf(stderr, "Key Material: %d\n",
+ state->security_parameters.key_material_length);
+ fprintf(stderr, "Exportable: %d\n",
+ state->security_parameters.is_exportable);
+ fprintf(stderr, "MAC algorithm: %d\n",
+ state->security_parameters.mac_algorithm);
+ fprintf(stderr, "Hash size: %d\n",
+ state->security_parameters.hash_size);
+ fprintf(stderr, "Compression Algorithm: %d\n",
+ state->security_parameters.compression_algorithm);
+ fprintf(stderr, "\n");
+
+}
+
+void _print_TLSCompressed(GNUTLSCompressed * compressed)
+{
+ fprintf(stderr, "TLSCompressed packet:\n");
+ fprintf(stderr, "type: %d\n", compressed->type);
+ fprintf(stderr, "version: %d,%d\n", compressed->version.major,
+ compressed->version.minor);
+ fprintf(stderr, "length: %d\n", compressed->length);
+ fprintf(stderr, "fragment: %s\n", bin2hex(compressed->fragment, compressed->length));
+ fprintf(stderr, "\n");
+}
+
+
+void _print_TLSPlaintext(GNUTLSPlaintext * plaintext)
+{
+ fprintf(stderr, "TLSPlaintext packet:\n");
+ fprintf(stderr, "type: %d\n", plaintext->type);
+ fprintf(stderr, "version: %d,%d\n", plaintext->version.major,
+ plaintext->version.minor);
+ fprintf(stderr, "length: %d\n", plaintext->length);
+ fprintf(stderr, "fragment: %s\n", bin2hex(plaintext->fragment, plaintext->length));
+ fprintf(stderr, "\n");
+}
+
+
+void _print_TLSCiphertext( GNUTLSCiphertext * ciphertext)
+{
+
+ fprintf(stderr, "TLSCiphertext packet:\n");
+ fprintf(stderr, "type: %d\n", ciphertext->type);
+ fprintf(stderr, "version: %d,%d\n", ciphertext->version.major,
+ ciphertext->version.minor);
+ fprintf(stderr, "length: %d\n", ciphertext->length);
+
+ fprintf(stderr, "fragment: %s\n", bin2hex(ciphertext->fragment, ciphertext->length));
+ fprintf(stderr, "\n");
+}
--- /dev/null
+void _print_state(GNUTLS_STATE state);
+void _print_TLSCompressed(GNUTLSCompressed * compressed);
+void _print_TLSPlaintext(GNUTLSPlaintext * plaintext);
+void _print_TLSCiphertext( GNUTLSCiphertext *);
+char * bin2hex(const unsigned char *old, const size_t oldlen);
--- /dev/null
+#include <config.h>
+
+
+
+#ifdef STDC_HEADERS
+# include <string.h>
+# include <stdlib.h>
+# include <stdio.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <time.h>
+
+
+/* for open */
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <gcrypt.h>
+
+#if SIZEOF_UNSIGNED_LONG_INT == 8
+ typedef unsigned long int uint64;
+ typedef signed long int sint64;
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+ typedef unsigned long long uint64;
+ typedef signed long long sint64;
+#else
+# error "Cannot find a 64 bit integer in your system, sorry."
+#endif
+
+
+#if SIZEOF_UNSIGNED_LONG_INT == 4
+ typedef unsigned long int uint32;
+ typedef signed long int sint32;
+#elif SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int uint32;
+ typedef signed int sint32;
+#else
+# error "Cannot find a 32 bit integer in your system, sorry."
+#endif
+
+#if SIZEOF_UNSIGNED_INT == 2
+ typedef unsigned int uint16;
+ typedef signed int sint16;
+#elif SIZEOF_UNSIGNED_SHORT_INT == 2
+ typedef unsigned short int uint16;
+ typedef signed short int sint16;
+#else
+# error "Cannot find a 16 bit integer in your system, sorry."
+#endif
+
+#if SIZEOF_UNSIGNED_CHAR == 1
+ typedef unsigned char uint8;
+ typedef signed char int8;
+#else
+# error "Cannot find an 8 bit char in your system, sorry."
+#endif
+
+#ifndef HAVE_MEMMOVE
+# ifdef HAVE_BCOPY
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# else
+# error "Neither memmove nor bcopy exists on your system."
+# endif
+#endif
--- /dev/null
+#include <defines.h>
+#include "gnutls.h"
+#include "debug.h"
+#include "gnutls_compress.h"
+#include "gnutls_plaintext.h"
+#include "gnutls_cipher.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <mhash.h>
+
+int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end)
+{
+ *state = gnutls_calloc(1, sizeof(GNUTLS_STATE_INT));
+ memset(*state, 0, sizeof(GNUTLS_STATE));
+ (*state)->security_parameters.entity = con_end;
+
+/* Set the defaults (only to remind me that they should be allocated ) */
+ (*state)->security_parameters.bulk_cipher_algorithm = CIPHER_NULL;
+ (*state)->security_parameters.mac_algorithm = MAC_NULL;
+ (*state)->security_parameters.compression_algorithm = COMPRESSION_NULL;
+
+ (*state)->connection_state.compression_state = NULL;
+ (*state)->connection_state.mac_secret = NULL;
+
+ (*state)->cipher_specs.server_write_mac_secret = NULL;
+ (*state)->cipher_specs.client_write_mac_secret = NULL;
+ (*state)->cipher_specs.server_write_IV = NULL;
+ (*state)->cipher_specs.client_write_IV = NULL;
+ (*state)->cipher_specs.server_write_key = NULL;
+ (*state)->cipher_specs.client_write_key = NULL;
+
+}
+
+int gnutls_deinit(GNUTLS_STATE * state)
+{
+ gnutls_free((*state)->connection_state.compression_state);
+ gnutls_free((*state)->connection_state.mac_secret);
+
+ secure_free((*state)->cipher_specs.server_write_mac_secret);
+ secure_free((*state)->cipher_specs.client_write_mac_secret);
+ secure_free((*state)->cipher_specs.server_write_IV);
+ secure_free((*state)->cipher_specs.client_write_IV);
+ secure_free((*state)->cipher_specs.server_write_key);
+ secure_free((*state)->cipher_specs.client_write_key);
+
+
+ gnutls_free(*state);
+}
+
+/* Produces "total_bytes" bytes using the hash algorithm specified.
+ * (used in the PRF function)
+ */
+svoid* gnutls_P_hash( hashid algorithm, opaque* secret, int secret_size,
+ opaque* seed, int seed_size, int total_bytes) {
+
+ MHASH td1, td2;
+ char* ret=secure_malloc(total_bytes);
+ void* A;
+ int i=0, times, copy_bytes=0, how;
+ void *final;
+
+ do {
+ i += mhash_get_block_size(algorithm);
+ } while( i < total_bytes);
+
+ A = seed;
+ times = i / mhash_get_block_size(algorithm);
+
+ for (i=0;i<times;i++) {
+ td2 = hmac_mhash_init( algorithm, secret, secret_size, mhash_get_hash_pblock(algorithm));
+
+ td1 = hmac_mhash_init( algorithm, secret, secret_size, mhash_get_hash_pblock(algorithm));
+ mhash( td1, A, seed_size);
+
+ A=hmac_mhash_end( td1);
+
+ mhash( td2, A, mhash_get_block_size(algorithm));
+ mhash( td2, seed, seed_size);
+ final = hmac_mhash_end( td2);
+
+ copy_bytes=mhash_get_block_size(algorithm);
+ if ((i+1)*copy_bytes < total_bytes) {
+ how = mhash_get_block_size(algorithm);
+ } else {
+ how = total_bytes - (i)*copy_bytes;
+ }
+
+ if ( how>0) {
+ memmove( &ret[i*copy_bytes], final, how);
+ }
+ free(final);
+ if (i>0) free(A);
+ }
+
+ return ret;
+}
+
+
+/* The PRF function expands a given secret */
+svoid *gnutls_PRF( opaque* secret, int secret_size, uint8* label, int label_size,
+ opaque* seed, int seed_size, int total_bytes)
+{
+ int l_s1, l_s2, i, s_seed_size;
+ char* o1, *o2;
+ char* s1, *s2;
+ char* ret;
+ char* s_seed;
+
+ /* label+seed = s_seed */
+ s_seed_size = seed_size+label_size;
+ s_seed=gnutls_malloc(s_seed_size);
+ memmove( s_seed, label, label_size);
+ memmove( &s_seed[label_size], seed, seed_size);
+
+
+ if (secret_size%2 == 0) {
+ l_s1 = l_s2 = secret_size/2;
+ s1 = &secret[0];
+ s2 = &secret[l_s1+1];
+ } else {
+ l_s1 = l_s2 = (secret_size/2) + 1;
+ s1 = &secret[0];
+ s2 = &secret[l_s1];
+ }
+
+ o1 = gnutls_P_hash( MHASH_MD5, s1, l_s1, s_seed, s_seed_size, total_bytes);
+ o2 = gnutls_P_hash( MHASH_SHA1, s2, l_s2, s_seed, s_seed_size, total_bytes);
+
+ ret = secure_malloc( total_bytes);
+ gnutls_free( s_seed);
+ for (i=0;i<total_bytes;i++) {
+ ret[i] = o1[i] ^ o2[i];
+ }
+
+ secure_free(o1);
+ secure_free(o2);
+
+ return ret;
+
+}
+
+/* if master_secret, client_random and server_random have been initialized,
+ * this functions creates the keys and stores them into state->cipher_specs
+ */
+int _gnutls_set_keys( GNUTLS_STATE state) {
+ char* key_block;
+ char keyexp[]="key expansion";
+ char* random = gnutls_malloc(64);
+ int hash_size;
+ int IV_size;
+ int key_size;
+
+ hash_size = state->security_parameters.hash_size;
+ IV_size = state->security_parameters.IV_size;
+ key_size = state->security_parameters.key_material_length;
+
+ memmove(random, state->security_parameters.server_random, 32);
+ memmove(&random[32], state->security_parameters.client_random, 32);
+
+ key_block = gnutls_PRF( state->security_parameters.master_secret, 48,
+ keyexp, strlen(keyexp),
+ random, 64,
+ 2*hash_size +
+ 2*key_size +
+ 2*IV_size);
+
+ state->cipher_specs.client_write_mac_secret = secure_malloc( hash_size);
+ memmove( state->cipher_specs.client_write_mac_secret, &key_block[0], hash_size);
+
+ state->cipher_specs.server_write_mac_secret = secure_malloc( hash_size);
+ memmove( state->cipher_specs.server_write_mac_secret, &key_block[hash_size], hash_size);
+
+ state->cipher_specs.client_write_key = secure_malloc( key_size);
+ memmove( state->cipher_specs.client_write_key, &key_block[2*hash_size], key_size);
+
+ state->cipher_specs.server_write_key = secure_malloc( key_size);
+ memmove( state->cipher_specs.server_write_key, &key_block[2*hash_size+key_size], key_size);
+
+ state->cipher_specs.client_write_IV = secure_malloc( IV_size);
+ memmove( state->cipher_specs.client_write_IV, &key_block[2*key_size+2*hash_size], IV_size);
+
+ state->cipher_specs.server_write_IV = secure_malloc( IV_size);
+ memmove( state->cipher_specs.server_write_IV, &key_block[2*hash_size+2*key_size+IV_size], IV_size);
+
+ secure_free( key_block);
+ return 0;
+}
+
+int gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, int sizeofdata) {
+ GNUTLSPlaintext *gtxt;
+ GNUTLSCompressed *gcomp;
+ GNUTLSCiphertext *gcipher;
+ int iterations, i, err;
+ uint16 length;
+ int ret=0, Size;
+
+ if (sizeofdata==0) return 0;
+
+ if (sizeofdata<16384) {
+ iterations=1;
+ Size=sizeofdata;
+ } else {
+ iterations = sizeofdata/16384;
+ Size = 16384;
+ }
+ for (i=0;i<iterations;i++) {
+ err = _gnutls_text2TLSPlaintext(type, >xt, &data[i*Size], Size);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ _gnutls_freeTLSPlaintext(gtxt);
+
+ err = _gnutls_TLSCompressed2TLSCiphertext( state, &gcipher, gcomp);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ _gnutls_freeTLSCompressed(gcomp);
+
+ write( cd, &gcipher->type, sizeof(ContentType));
+ write( cd, &gcipher->version.major, 1);
+ write( cd, &gcipher->version.minor, 1);
+#ifdef WORDS_BIGENDIAN
+ length=gcipher->length;
+#else
+ length=byteswap16(gcipher->length);
+#endif
+ write( cd, &length, sizeof(uint16));
+ _print_TLSCiphertext( gcipher);
+ write( cd, gcipher->fragment, gcipher->length);
+ state->connection_state.write_sequence_number++;
+ ret += Size;
+
+ _gnutls_freeTLSCiphertext(gcipher);
+ }
+ /* rest data */
+ if (iterations>1) {
+ Size=sizeofdata%16384;
+ err = _gnutls_text2TLSPlaintext(type, >xt, &data[ret], Size);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ _gnutls_freeTLSPlaintext(gtxt);
+
+ err = _gnutls_TLSCompressed2TLSCiphertext( state, &gcipher, gcomp);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+ _gnutls_freeTLSCompressed(gcomp);
+#ifdef WORDS_BIGENDIAN
+ length=gcipher->length;
+#else
+ length=byteswap16(gcipher->length);
+#endif
+ write( cd, &gcipher->type, sizeof(ContentType));
+ write( cd, &gcipher->version.major, 1);
+ write( cd, &gcipher->version.minor, 1);
+ write( cd, &length, sizeof(uint16));
+ write( cd, gcipher->fragment, gcipher->length);
+ state->connection_state.write_sequence_number++;
+ ret += Size;
+
+ _gnutls_freeTLSCiphertext(gcipher);
+ }
+
+ return ret;
+}
+
+
+#if 0
+int gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, int sizeofdata) {
+ GNUTLSPlaintext *gtxt;
+ GNUTLSCompressed *gcomp;
+ GNUTLSCiphertext *gcipher;
+ int iterations, i, err;
+ uint16 length;
+ int ret=0, Size;
+
+ if (sizeofdata==0) return 0;
+
+ if (sizeofdata<16384) {
+ iterations=1;
+ Size=sizeofdata;
+ } else {
+ iterations = sizeofdata/16384;
+ Size = 16384;
+ }
+ for (i=0;i<iterations;i++) {
+ err = _gnutls_text2TLSPlaintext(type, >xt, &data[i*Size], Size);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ _gnutls_freeTLSPlaintext(gtxt);
+
+ err = _gnutls_TLSCompressed2TLSCiphertext( state, &gcipher, gcomp);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ _gnutls_freeTLSCompressed(gcomp);
+
+ write( cd, &gcipher->type, sizeof(ContentType));
+ write( cd, &gcipher->version.major, 1);
+ write( cd, &gcipher->version.minor, 1);
+#ifdef WORDS_BIGENDIAN
+ length=gcipher->length;
+#else
+ length=byteswap16(gcipher->length);
+#endif
+ write( cd, &length, sizeof(uint16));
+ _print_TLSCiphertext( gcipher);
+ write( cd, gcipher->fragment, gcipher->length);
+ state->connection_state.write_sequence_number++;
+ ret += Size;
+
+ _gnutls_freeTLSCiphertext(gcipher);
+ }
+ /* rest data */
+ if (iterations>1) {
+ Size=sizeofdata%16384;
+ err = _gnutls_text2TLSPlaintext(type, >xt, &data[ret], Size);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+
+ _gnutls_freeTLSPlaintext(gtxt);
+
+ err = _gnutls_TLSCompressed2TLSCiphertext( state, &gcipher, gcomp);
+ if (err<0) {
+ /*gnutls_perror(err);*/
+ return err;
+ }
+ _gnutls_freeTLSCompressed(gcomp);
+#ifdef WORDS_BIGENDIAN
+ length=gcipher->length;
+#else
+ length=byteswap16(gcipher->length);
+#endif
+ write( cd, &gcipher->type, sizeof(ContentType));
+ write( cd, &gcipher->version.major, 1);
+ write( cd, &gcipher->version.minor, 1);
+ write( cd, &length, sizeof(uint16));
+ write( cd, gcipher->fragment, gcipher->length);
+ state->connection_state.write_sequence_number++;
+ ret += Size;
+
+ _gnutls_freeTLSCiphertext(gcipher);
+ }
+
+ return ret;
+}
+#endif
--- /dev/null
+#define svoid void /* for functions that allocate using secure_free */
+#define secure_free free
+#define secure_malloc malloc
+#define secure_realloc realloc
+#define secure_calloc calloc
+#define gnutls_malloc malloc
+#define gnutls_realloc realloc
+#define gnutls_calloc calloc
+#define gnutls_free free
+
+#define rotl64(x,n) (((x) << ((uint16)(n))) | ((x) >> (64 - (uint16)(n))))
+#define rotr64(x,n) (((x) >> ((uint16)(n))) | ((x) << (64 - (uint16)(n))))
+#define rotl32(x,n) (((x) << ((uint16)(n))) | ((x) >> (32 - (uint16)(n))))
+#define rotr32(x,n) (((x) >> ((uint16)(n))) | ((x) << (32 - (uint16)(n))))
+#define rotl16(x,n) (((x) << ((uint16)(n))) | ((x) >> (16 - (uint16)(n))))
+#define rotr16(x,n) (((x) >> ((uint16)(n))) | ((x) << (16 - (uint16)(n))))
+
+#define byteswap16(x) ((rotl16(x, 8) & 0x00ff) | (rotr16(x, 8) & 0xff00))
+#define byteswap32(x) ((rotl32(x, 8) & 0x00ff00ff) | (rotr32(x, 8) & 0xff00ff00))
+#define byteswap64(x) ((rotl64(x, 8) & 0x00ff00ff00ff00ff) | (rotr64(x, 8) & 0xff00ff00ff00ff00))
+
+typedef unsigned char opaque;
+
+/* STATE */
+enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT };
+enum BulkCipherAlgorithm { CIPHER_NULL, CIPHER_3DES = 4 };
+enum CipherType { CIPHER_STREAM, CIPHER_BLOCK };
+enum IsExportable { EXPORTABLE_TRUE, EXPORTABLE_FALSE };
+enum MACAlgorithm { MAC_NULL, MAC_MD5, MAC_SHA };
+enum CompressionMethod { COMPRESSION_NULL };
+
+
+typedef enum ConnectionEnd ConnectionEnd;
+typedef enum BulkCipherAlgorithm BulkCipherAlgorithm;
+typedef enum CipherType CipherType;
+typedef enum IsExportable IsExportable;
+typedef enum MACAlgorithm MACAlgorithm;
+typedef enum CompressionMethod CompressionMethod;
+
+typedef struct {
+ ConnectionEnd entity;
+ BulkCipherAlgorithm bulk_cipher_algorithm;
+ CipherType cipher_type;
+ uint8 IV_size; /* not specified in the protocol, but later it
+ * uses it */
+ uint8 key_size;
+ uint8 key_material_length;
+ IsExportable is_exportable;
+ MACAlgorithm mac_algorithm;
+ uint8 hash_size;
+ CompressionMethod compression_algorithm;
+ opaque master_secret[48];
+ opaque client_random[32];
+ opaque server_random[32];
+} SecurityParameters;
+
+typedef struct {
+ opaque* server_write_mac_secret;
+ opaque* client_write_mac_secret;
+ opaque* server_write_IV;
+ opaque* client_write_IV;
+ opaque* server_write_key;
+ opaque* client_write_key;
+} CipherSpecs;
+
+typedef struct {
+ opaque* compression_state;
+ GCRY_CIPHER_HD cipher_state;
+ opaque* mac_secret;
+ uint8 mac_secret_size;
+ uint64 read_sequence_number;
+ uint64 write_sequence_number;
+} ConnectionState;
+
+typedef struct {
+ SecurityParameters security_parameters;
+ CipherSpecs cipher_specs;
+ ConnectionState connection_state;
+} GNUTLS_STATE_INT;
+
+typedef GNUTLS_STATE_INT *GNUTLS_STATE;
+
+
+/* Record Protocol */
+enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HANDSHAKE,
+ GNUTLS_APPLICATION_DATA };
+typedef enum ContentType ContentType;
+
+#define GNUTLS_VERSION_MAJOR 3
+#define GNUTLS_VERSION_MINOR 1
+
+typedef struct {
+ uint8 major;
+ uint8 minor;
+} ProtocolVersion;
+
+typedef struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ opaque* fragment;
+} GNUTLSPlaintext;
+
+typedef struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ opaque* fragment;
+} GNUTLSCompressed;
+
+/* This is used for both block ciphers and stream ciphers. In stream ciphers
+ * the padding is just ignored.
+ */
+typedef struct {
+ opaque* content;
+ opaque* MAC;
+ uint8* padding;
+ uint8 padding_length;
+} GNUTLS_GenericBlockCipher;
+
+typedef struct {
+ opaque* content;
+ opaque* MAC;
+} GNUTLS_GenericStreamCipher;
+
+typedef struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ void* fragment; /* points GenericStreamCipher
+ * or GenericBlockCipher
+ */
+} GNUTLSCiphertext;
+
+
+int gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, int sizeofdata);
+#define gnutls_send( x, y, z, w) gnutls_send_int( x, y, GNUTLS_APPLICATION_DATA, z, w)
+
+#define GNUTLS_E_MAC_FAILED -1
+#define GNUTLS_E_UNKNOWN_CIPHER -2
+#define GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM -3
+#define GNUTLS_E_UNKNOWN_MAC_ALGORITHM -4
+#define GNUTLS_E_UNKNOWN_ERROR -5
+#define GNUTLS_E_UNKNOWN_CIPHER_TYPE -6
+#define GNUTLS_E_LARGE_PACKET -7
+
--- /dev/null
+#include <defines.h>
+#include "gnutls.h"
+#include "gnutls_compress.h"
+#include "gnutls_cipher.h"
+#include <mhash.h>
+
+#define TDES_BLOCKLEN 8
+#define TDES_KEYLEN 24
+#define MD5_DIGEST 16
+#define SHA_DIGEST 20
+
+/* Sets the specified cipher into the state */
+int _gnutls_set_cipher( GNUTLS_STATE state, BulkCipherAlgorithm algo) {
+
+ switch (algo) {
+ case CIPHER_NULL:
+ state->security_parameters.bulk_cipher_algorithm=CIPHER_NULL;
+ state->security_parameters.cipher_type=CIPHER_STREAM;
+ state->security_parameters.is_exportable=EXPORTABLE_TRUE;
+ state->security_parameters.key_material_length =
+ state->security_parameters.key_size = 0;
+ break;
+
+ case CIPHER_3DES:
+ state->security_parameters.bulk_cipher_algorithm=CIPHER_3DES;
+ state->security_parameters.cipher_type=CIPHER_BLOCK;
+ state->security_parameters.is_exportable=EXPORTABLE_FALSE;
+ state->security_parameters.key_material_length =
+ state->security_parameters.key_size = TDES_KEYLEN;
+ state->security_parameters.IV_size = TDES_BLOCKLEN;
+ break;
+ default:
+ return GNUTLS_E_UNKNOWN_CIPHER;
+ }
+
+
+ return 0;
+
+}
+
+/* Sets the specified algorithm into compression state */
+int _gnutls_set_compression( GNUTLS_STATE state, CompressionMethod algo) {
+
+ switch (algo) {
+ case COMPRESSION_NULL:
+ break;
+
+ default:
+ return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
+ }
+ return 0;
+
+}
+
+
+int _gnutls_set_mac( GNUTLS_STATE state, MACAlgorithm algo) {
+
+ switch (algo) {
+ case MAC_NULL:
+ state->security_parameters.mac_algorithm=MAC_NULL;
+ state->security_parameters.hash_size=0;
+ break;
+
+ case MAC_MD5:
+ state->security_parameters.mac_algorithm=MAC_MD5;
+ state->security_parameters.hash_size=MD5_DIGEST;
+ break;
+
+ case MAC_SHA:
+ state->security_parameters.mac_algorithm=MAC_SHA;
+ state->security_parameters.hash_size=SHA_DIGEST;
+ break;
+
+ default:
+ return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
+ }
+
+ return 0;
+
+}
+
+/* Sets the current connection state to conform with the
+ * Security parameters, and initializes encryption.
+ */
+int _gnutls_connection_state_init(GNUTLS_STATE state) {
+ int rc;
+
+ gnutls_free( state->connection_state.mac_secret);
+ if ( state->connection_state.cipher_state != NULL)
+ gcry_cipher_close( state->connection_state.cipher_state);
+ gnutls_free( state->connection_state.compression_state);
+
+ switch ( state->security_parameters.compression_algorithm) {
+ case COMPRESSION_NULL:
+ state->connection_state.compression_state=NULL;
+ break;
+ default:
+ return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
+ }
+
+ switch ( state->security_parameters.mac_algorithm) {
+ case MAC_NULL:
+ state->connection_state.mac_secret = NULL;
+ state->connection_state.mac_secret_size = 0;
+ break;
+ case MAC_MD5:
+ state->connection_state.mac_secret = gnutls_malloc(MD5_DIGEST);
+ state->connection_state.mac_secret_size = MD5_DIGEST;
+ break;
+ case MAC_SHA:
+ state->connection_state.mac_secret = gnutls_malloc(SHA_DIGEST);
+ state->connection_state.mac_secret_size = SHA_DIGEST;
+ break;
+ default:
+ return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
+ }
+
+ switch ( state->security_parameters.bulk_cipher_algorithm) {
+ case CIPHER_NULL:
+ state->connection_state.cipher_state = NULL;
+ break;
+ case CIPHER_3DES:
+ state->connection_state.cipher_state = gcry_cipher_open(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
+ break;
+ default:
+ return GNUTLS_E_UNKNOWN_CIPHER;
+ }
+
+
+ switch (state->security_parameters.entity) {
+ case GNUTLS_SERVER:
+ if (state->connection_state.cipher_state!=NULL) {
+ rc = gcry_cipher_setkey( state->connection_state.cipher_state, state->cipher_specs.server_write_key, state->security_parameters.key_size);
+ gcry_cipher_setiv( state->connection_state.cipher_state, state->cipher_specs.server_write_IV, state->security_parameters.IV_size);
+ }
+ if (state->connection_state.mac_secret_size>0)
+ memmove( state->connection_state.mac_secret, state->cipher_specs.server_write_mac_secret, state->connection_state.mac_secret_size);
+ break;
+ case GNUTLS_CLIENT:
+ if (state->connection_state.cipher_state!=NULL) {
+ gcry_cipher_setiv( state->connection_state.cipher_state, state->cipher_specs.client_write_IV, state->security_parameters.IV_size);
+ rc = gcry_cipher_setkey( state->connection_state.cipher_state, state->cipher_specs.client_write_key, state->security_parameters.key_size);
+ }
+ if (state->connection_state.mac_secret_size>0)
+ memmove( state->connection_state.mac_secret, state->cipher_specs.client_write_mac_secret, state->connection_state.mac_secret_size);
+ break;
+ default:
+ return GNUTLS_E_UNKNOWN_ERROR;
+ }
+
+ return 0;
+}
+
+int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state,
+ GNUTLSCiphertext**
+ cipher,
+ GNUTLSCompressed *
+ compressed)
+{
+ GNUTLSCiphertext *ciphertext;
+ uint8 *padding, *content, *MAC;
+ uint8 padding_length;
+ uint16 c_length;
+ int rc;
+ uint8* data;
+ uint8 *macpointer;
+ uint8 pad;
+ uint8 *rand;
+ uint64 seq_num;
+ int length;
+ int td;
+
+
+ content =
+ gnutls_malloc(compressed->length);
+ memmove(content, compressed->fragment, compressed->length);
+
+/* if (state->connection_state.mac_secret_size>0) {
+ MAC = gnutls_malloc(state->connection_state.mac_secret_size);
+ }*/
+
+ *cipher = gnutls_malloc(sizeof(GNUTLSCiphertext));
+ ciphertext = *cipher;
+
+ switch (state->security_parameters.mac_algorithm) {
+ case MAC_NULL:
+ td = -1;
+ break;
+ case MAC_SHA:
+ td = hmac_mhash_init( MHASH_SHA1, state->connection_state.mac_secret, state->connection_state.mac_secret_size, mhash_get_hash_pblock(MHASH_SHA1));
+ break;
+ case MAC_MD5:
+ td = hmac_mhash_init( MHASH_MD5, state->connection_state.mac_secret, state->connection_state.mac_secret_size, mhash_get_hash_pblock(MHASH_MD5));
+ break;
+ default:
+ gnutls_free(*cipher);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
+ }
+
+#ifdef WORDS_BIGENDIAN
+ seq_num = state->connection_state.write_sequence_number;
+ c_length = compressed->length;
+#else
+ seq_num = byteswap64(state->connection_state.write_sequence_number);
+ c_length = byteswap16(compressed->length);
+#endif
+ if (td>=0) {
+ mhash( td, &seq_num, 8);
+ mhash( td, &compressed->type, 1);
+ mhash( td, &compressed->version.major, 1);
+ mhash( td, &compressed->version.minor, 1);
+ mhash( td, &c_length, 2);
+ mhash( td, &compressed->fragment, compressed->length);
+ MAC = hmac_mhash_end( td);
+ }
+ switch (state->security_parameters.cipher_type) {
+ case CIPHER_STREAM:
+ switch (state->security_parameters.bulk_cipher_algorithm) {
+ case CIPHER_NULL:
+ length = compressed->length+state->connection_state.mac_secret_size;
+ data = gnutls_malloc( length);
+ memmove( data, content, compressed->length);
+ memmove( &data[compressed->length], MAC, state->connection_state.mac_secret_size);
+ ciphertext->fragment = data;
+ ciphertext->length = length;
+ ciphertext->type = compressed->type;
+ ciphertext->version.major =
+ compressed->version.major;
+ ciphertext->version.minor =
+ compressed->version.minor;
+ break;
+ default:
+ gnutls_free(*cipher);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_CIPHER;
+
+ }
+ break;
+ case CIPHER_BLOCK:
+ switch (state->security_parameters.bulk_cipher_algorithm) {
+ case CIPHER_3DES:
+
+ rand = gcry_random_bytes(1, GCRY_STRONG_RANDOM);
+ length = compressed->length + state->connection_state.mac_secret_size
+ + rand[0] + 1;
+ length = (length / TDES_BLOCKLEN) * TDES_BLOCKLEN;
+ pad = length - compressed->length - state->connection_state.mac_secret_size - 1;
+
+ /* set pad bytes pad */
+ padding = gnutls_malloc( pad);
+ memset(padding, pad, pad);
+ padding_length=pad;
+
+ data = gnutls_malloc( length);
+ memmove( data, content, compressed->length);
+ memmove( &data[compressed->length], MAC, state->connection_state.mac_secret_size);
+ memmove( &data[state->connection_state.mac_secret_size+compressed->length], padding, pad);
+ memmove( &data[pad+state->connection_state.mac_secret_size+compressed->length], &padding_length, 1);
+
+ gnutls_free( padding);
+
+ gcry_cipher_encrypt( state->connection_state.cipher_state,
+ data, length,
+ data, length);
+
+ ciphertext->fragment = data;
+ ciphertext->length = length;
+ ciphertext->type = compressed->type;
+ ciphertext->version.major =
+ compressed->version.major;
+ ciphertext->version.minor =
+ compressed->version.minor;
+
+ gcry_free(rand);
+ break;
+ default:
+ gnutls_free(*cipher);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_CIPHER;
+ }
+ break;
+ default:
+ gnutls_free(*cipher);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
+ }
+
+// gnutls_free( MAC);
+ if (td>=0) free( MAC);
+ gnutls_free( content);
+
+ return 0;
+}
+
+int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state,
+ GNUTLSCompressed**
+ compress,
+ GNUTLSCiphertext *
+ ciphertext)
+{
+ GNUTLSCompressed *compressed;
+ uint8 *content, *MAC;
+ uint16 c_length;
+ int rc;
+ uint8* data;
+ uint8 *macpointer;
+ uint8 pad;
+ uint64 seq_num;
+ int length;
+ int td;
+
+
+ content =
+ gnutls_malloc(ciphertext->length);
+ memmove(content, ciphertext->fragment, ciphertext->length);
+
+/* if (state->connection_state.mac_secret_size>0) {
+ MAC = gnutls_malloc(state->connection_state.mac_secret_size);
+ }*/
+
+ *compress = gnutls_malloc(sizeof(GNUTLSCompressed));
+ compressed = *compress;
+
+
+ switch (state->security_parameters.mac_algorithm) {
+ case MAC_NULL:
+ td = -1;
+ break;
+ case MAC_SHA:
+ td = hmac_mhash_init( MHASH_SHA1, state->connection_state.mac_secret, state->connection_state.mac_secret_size, mhash_get_hash_pblock(MHASH_SHA1));
+ break;
+ case MAC_MD5:
+ td = hmac_mhash_init( MHASH_MD5, state->connection_state.mac_secret, state->connection_state.mac_secret_size, mhash_get_hash_pblock(MHASH_MD5));
+ break;
+ default:
+ gnutls_free(*compress);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
+ }
+
+#ifdef WORDS_BIGENDIAN
+ seq_num = state->connection_state.read_sequence_number;
+ c_length = ciphertext->length;
+#else
+ seq_num = byteswap64(state->connection_state.read_sequence_number);
+ c_length = byteswap16(ciphertext->length);
+#endif
+ if (td>=0) {
+ mhash( td, &seq_num, 8);
+ mhash( td, &ciphertext->type, 1);
+ mhash( td, &ciphertext->version.major, 1);
+ mhash( td, &ciphertext->version.minor, 1);
+ mhash( td, &c_length, 2);
+ mhash( td, &ciphertext->fragment, ciphertext->length);
+ MAC = hmac_mhash_end( td);
+ }
+ switch (state->security_parameters.cipher_type) {
+ case CIPHER_STREAM:
+ switch (state->security_parameters.bulk_cipher_algorithm) {
+ case CIPHER_NULL:
+ length = ciphertext->length-state->connection_state.mac_secret_size;
+ data = gnutls_malloc( length);
+ memmove( data, content, length);
+
+ /* HMAC was not the same. */
+ if (memcmp(MAC, &data[length], state->connection_state.mac_secret_size)!=0) return GNUTLS_E_MAC_FAILED;
+
+ compressed->fragment = data;
+ compressed->length = length;
+ compressed->type = ciphertext->type;
+ compressed->version.major =
+ ciphertext->version.major;
+ compressed->version.minor =
+ ciphertext->version.minor;
+ break;
+ default:
+ gnutls_free(*compress);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_CIPHER;
+
+ }
+ break;
+ case CIPHER_BLOCK:
+ switch (state->security_parameters.bulk_cipher_algorithm) {
+ case CIPHER_3DES:
+
+ gcry_cipher_decrypt( state->connection_state.cipher_state,
+ content, ciphertext->length,
+ content, ciphertext->length);
+
+ pad = content[ciphertext->length-1]; /* pad */
+ length = ciphertext->length - state->connection_state.mac_secret_size
+ - pad - 1;
+
+ /* HMAC was not the same. */
+ if (memcmp(MAC, &data[length], state->connection_state.mac_secret_size)!=0) return GNUTLS_E_MAC_FAILED;
+
+ data = gnutls_malloc( length);
+ memmove( data, content, length);
+
+ compressed->fragment = data;
+ compressed->length = length;
+ compressed->type = ciphertext->type;
+ compressed->version.major =
+ ciphertext->version.major;
+ compressed->version.minor =
+ ciphertext->version.minor;
+
+ break;
+ default:
+ gnutls_free(*compress);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_CIPHER;
+ }
+ break;
+ default:
+ gnutls_free(*compress);
+ gnutls_free(content);
+ return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
+ }
+
+// gnutls_free( MAC);
+ free( MAC);
+ gnutls_free( content);
+
+ return 0;
+}
+
+
+
+
+int _gnutls_freeTLSCiphertext(GNUTLSCiphertext * ciphertext)
+{
+ if (ciphertext == NULL)
+ return 0;
+
+ gnutls_free(ciphertext->fragment);
+ gnutls_free(ciphertext);
+
+ return 0;
+}
--- /dev/null
+int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state,
+ GNUTLSCiphertext**
+ cipher,
+ GNUTLSCompressed *
+ compressed);
+int _gnutls_freeTLSCiphertext(GNUTLSCiphertext * ciphertext);
+int _gnutls_set_cipher( GNUTLS_STATE state, BulkCipherAlgorithm algo);
+int _gnutls_set_mac( GNUTLS_STATE state, MACAlgorithm algo);
+int _gnutls_set_compression( GNUTLS_STATE state, CompressionMethod algo);
+int _gnutls_connection_state_init(GNUTLS_STATE state);
+int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state,
+ GNUTLSCompressed**
+ compress,
+ GNUTLSCiphertext *
+ ciphertext);
--- /dev/null
+#include <defines.h>
+#include "gnutls.h"
+#include "gnutls_compress.h"
+
+int _gnutls_TLSPlaintext2TLSCompressed(GNUTLS_STATE state,
+ GNUTLSCompressed **
+ compress,
+ GNUTLSPlaintext *
+ plaintext)
+{
+ GNUTLSCompressed *compressed;
+
+ *compress = gnutls_malloc(sizeof(GNUTLSCompressed));
+ compressed = *compress;
+
+ switch (state->security_parameters.compression_algorithm) {
+ case COMPRESSION_NULL:
+
+ compressed->fragment = gnutls_malloc(plaintext->length);
+
+ memmove(compressed->fragment, plaintext->fragment,
+ plaintext->length);
+ compressed->length = plaintext->length;
+ compressed->type = plaintext->type;
+ compressed->version.major = plaintext->version.major;
+ compressed->version.minor = plaintext->version.minor;
+ break;
+ default:
+ gnutls_free(*compress);
+ return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
+ }
+
+ return 0;
+}
+
+int _gnutls_TLSCompressed2TLSPlaintext(GNUTLS_STATE state,
+ GNUTLSPlaintext**
+ plain,
+ GNUTLSCompressed *
+ compressed)
+{
+ GNUTLSPlaintext *plaintext;
+
+ *plain = gnutls_malloc(sizeof(GNUTLSPlaintext));
+ plaintext = *plain;
+
+ switch (state->security_parameters.compression_algorithm) {
+ case COMPRESSION_NULL:
+ plaintext->fragment = gnutls_malloc(compressed->length);
+ memmove(plaintext->fragment, compressed->fragment,
+ compressed->length);
+ plaintext->length = compressed->length;
+ plaintext->type = compressed->type;
+ plaintext->version.major = compressed->version.major;
+ plaintext->version.minor = compressed->version.minor;
+ break;
+ default:
+ gnutls_free(*plain);
+ return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
+ }
+
+ return 0;
+}
+
+
+
+
+int _gnutls_freeTLSCompressed(GNUTLSCompressed * compressed)
+{
+ if (compressed == NULL)
+ return 0;
+
+ gnutls_free(compressed->fragment);
+ gnutls_free(compressed);
+
+ return 0;
+}
--- /dev/null
+int _gnutls_freeTLSCompressed(GNUTLSCompressed * compressed);
+int _gnutls_TLSPlaintext2TLSCompressed(GNUTLS_STATE state,
+ GNUTLSCompressed **
+ compress,
+ GNUTLSPlaintext *
+ plaintext);
+int _gnutls_TLSCompressed2TLSPlaintext(GNUTLS_STATE state,
+ GNUTLSPlaintext**
+ plain,
+ GNUTLSCompressed *
+ compressed);
--- /dev/null
+#include <defines.h>
+#include "gnutls.h"
+
+
+
+/* Plaintext Handling */
+int _gnutls_text2TLSPlaintext(ContentType type, GNUTLSPlaintext** plain, char *text, uint16 length)
+{
+ GNUTLSPlaintext *plaintext;
+
+ if (length > 16384)
+ return GNUTLS_E_LARGE_PACKET;
+
+ *plain = gnutls_malloc(sizeof(GNUTLSPlaintext));
+ plaintext = *plain;
+
+ plaintext->fragment = gnutls_malloc(length);
+ memmove(plaintext->fragment, text, length);
+ plaintext->length = length;
+ plaintext->type = type;
+ plaintext->version.major = GNUTLS_VERSION_MAJOR;
+ plaintext->version.minor = GNUTLS_VERSION_MINOR;
+
+ return 0;
+}
+
+int _gnutls_TLSPlaintext2text( char** txt, GNUTLSPlaintext* plaintext)
+{
+ char *text;
+
+ if (plaintext->length > 16384)
+ return GNUTLS_E_LARGE_PACKET;
+
+ *txt = gnutls_malloc(plaintext->length);
+ text = *txt;
+
+ memmove(text, plaintext->fragment, plaintext->length);
+
+ return 0;
+}
+
+int _gnutls_freeTLSPlaintext(GNUTLSPlaintext * plaintext)
+{
+ if (plaintext == NULL)
+ return 0;
+
+ gnutls_free(plaintext->fragment);
+ gnutls_free(plaintext);
+
+ return 0;
+}
--- /dev/null
+int _gnutls_text2TLSPlaintext(ContentType type, GNUTLSPlaintext**, char *text, uint16 length);
+int _gnutls_freeTLSPlaintext(GNUTLSPlaintext* plaintext);
+int _gnutls_TLSPlaintext2text( char**, GNUTLSPlaintext* plaintext);
--- /dev/null
+#include <defines.h>
+#include <gnutls.h>
+#include "gnutls_compress.h"
+#include "gnutls_plaintext.h"
+#include "gnutls_cipher.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+int main()
+{
+ GNUTLS_STATE state;
+ char text[] = "ena xelidoni sto bouno\n";
+ GNUTLSPlaintext *gtxt;
+ GNUTLSCompressed *gcomp;
+ GNUTLSCiphertext *gcipher;
+ int cd;
+
+
+ gnutls_init(&state, GNUTLS_CLIENT);
+ _gnutls_set_cipher(state, CIPHER_3DES);
+ _gnutls_set_compression( state, COMPRESSION_NULL);
+ _gnutls_set_mac(state, MAC_NULL);
+ _print_state(state);
+
+ _gnutls_set_keys( state);
+ _gnutls_connection_state_init( state);
+
+ remove("ciphertext");
+ cd = open( "ciphertext", O_WRONLY|O_CREAT, S_IRWXU);
+
+ gnutls_send( cd, state, text, strlen(text));
+
+ close(cd);
+ gnutls_deinit(&state);
+ return 0;
+}