]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
added global state.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 22 Jun 2001 11:43:39 +0000 (11:43 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 22 Jun 2001 11:43:39 +0000 (11:43 +0000)
15 files changed:
NEWS
README
configure.in
doc/Makefile.am
doc/TODO
lib/Makefile.am
lib/gnutls.h.in
lib/gnutls_buffers.c
lib/gnutls_buffers.h
lib/gnutls_cert.c
lib/gnutls_global.c [new file with mode: 0644]
lib/gnutls_record.c
src/cli.c
src/pk.h [deleted file]
src/serv.c

diff --git a/NEWS b/NEWS
index b6faafb68f39cf86e1fcbc21683987e7961be239..26ba20682d5502975d3046e5ccbc53cf428d692e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Version 0.1.4
+Version 0.1.4 (22/06/2001)
 - Corrected (srp) base64 encoding.
 - Changed bcrypt algorithm to include username.
 - Added RSA Ciphersuites (no certificate checking).
@@ -7,6 +7,7 @@ Version 0.1.4
 - Bugfixes in session resuming
 - Updated Ciphersuite selection algorithm
 - Added internal representation of x509 structures.
+- Added global state
 
 Version 0.1.3 (01/06/2001)
 - Updated API (and the way it is documented - we use inline documentation)
diff --git a/README b/README
index 950df1b50422e9c34ecedafa21d972984f98f2e6..d3d39a5f4821a0579dd21166b5cdffa89732d240 100644 (file)
--- a/README
+++ b/README
@@ -10,6 +10,9 @@ real world programs)
 * Run the buildconf script before doing anything. This will create
 the needed configure, makefiles etc. using Automake, Autoconf, and libtool.
 
+* Documentation:
+ view the doc/ directory and the examples in the src/ directory.
+
 BUGS:
 
 There should be plenty, but if you think you found any 
index 500bd32e42e41d2734285cc1c2b40b476f42c182..e3b1cee557d0e29f4de4172f9cb08fb62b6d0414 100644 (file)
@@ -10,8 +10,8 @@ AC_DEFINE_UNQUOTED(T_VENDOR, "$target_vendor")
 AC_DEFINE_UNQUOTED(T_OS, "$target_os")
 
 GNUTLS_MAJOR_VERSION=0
-GNUTLS_MINOR_VERSION=2
-GNUTLS_MICRO_VERSION=0
+GNUTLS_MINOR_VERSION=1
+GNUTLS_MICRO_VERSION=4
 GNUTLS_VERSION=$GNUTLS_MAJOR_VERSION.$GNUTLS_MINOR_VERSION.$GNUTLS_MICRO_VERSION
 
 AC_DEFINE_UNQUOTED(GNUTLS_VERSION, "$GNUTLS_VERSION")
index fed12235a5efa6f24b00b4e0292f96bff2fc8306..fe89ab971d13e73004888929fc3ed858125e10f0 100644 (file)
@@ -1,4 +1,4 @@
-EXTRA_DIST = TODO gnutls-api.txt gnutls-api.html
+EXTRA_DIST = TODO gnutls-api.txt gnutls-api.html ASN1.readme.txt
 
 gnutls-api: gnutls-api.html gnutls-api.txt
 gnutls-api.html: 
index e97430782d9871e95ba4337388ab9ff033da2f75..148973a963b6b9e188ac8f48687a96aac90e8891 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -3,10 +3,7 @@
 * Add Kerberos support (who wants that?)
 * Audit the code (volunteers?)
 * Fix renegotiate
-* Add certificate verification in order for clients to work
-* Optimize X509PKI_SERVER_CREDENTIALS so that there should be
-  only one parse of the der structures.
-* Create global variables that hold read/write and initialize
-  the ASN.1 parser's structures.
 * Create certificate verification function(s)
 * Modify SRP to conform the newest draft
+* make gnutls_allocate_x509_sc() work with certificate lists
+  ( now works with a single certificate)
index 776efdf4ce59a5fb42a9afa894e4e10d8df4f894..033beb9c6887c3421ef6cc1f4c0e9e97dcd768e1 100644 (file)
@@ -25,6 +25,7 @@ libgnutls_la_SOURCES = gnutls_record.c gnutls_compress.c debug.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_pk.c gnutls_cert.c
+       gnutls_gcry.c ext_dnsname.c gnutls_pk.c gnutls_cert.c \
+       gnutls_global.c
 libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
 
index da26d159993126f3d84b1000a4b81be1d9c585d4..07cd7becaf58f5bf123c12f9ee268410fa2bf5ca 100644 (file)
@@ -190,4 +190,14 @@ typedef struct {
 void gnutls_free_x509_sc( X509PKI_SERVER_CREDENTIALS sc);
 int gnutls_allocate_x509_sc(X509PKI_SERVER_CREDENTIALS * res, char *CERTFILE, char *KEYFILE);
 
+/* global state functions 
+ */
+/* In this version global_init accepts two files (pkix.asn, pkcs1.asn).
+ * This will not be the case in the final version. These files 
+ * are located in the src/ directory of gnutls distribution.
+ */
+int gnutls_global_init(char* PKIX, char* PKCS1);
+void gnutls_global_deinit();
+
+
 /* error codes appended here */
index 69240d174c4375e175696697c17e63faa0849801..33eb935d60d0eb1fcca175ccef1cda52bb0806bc 100644 (file)
  # include <errno.h>
 #endif
 
+extern ssize_t (*recv_func)( SOCKET, void*, size_t, int);
+extern ssize_t (*send_func)( SOCKET,const void*, size_t, int);
+
+
 int gnutls_insertDataBuffer(ContentType type, GNUTLS_STATE state, char *data, int length)
 {
        int old_buffer;
@@ -142,7 +146,7 @@ ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag)
 
        left = sizeOfPtr;
        while (left > 0) {
-               i = recv(fd, &ptr[i], left, flag);
+               i = recv_func(fd, &ptr[i], left, flag);
                if (i < 0) {
                        return (0-errno);
                } else {
@@ -176,7 +180,7 @@ ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag)
 /* This function is like write. But it does not return -1 on error.
  * It does return -errno instead.
  */
-ssize_t _gnutls_Write(int fd, const void *iptr, size_t n)
+ssize_t _gnutls_Write(int fd, const void *iptr, size_t n, int flags)
 {
        size_t left;
 #ifdef WRITE_DEBUG
@@ -200,7 +204,7 @@ ssize_t _gnutls_Write(int fd, const void *iptr, size_t n)
 #endif
        left = n;
        while (left > 0) {
-               i = write(fd, &ptr[i], left);
+               i = send(fd, &ptr[i], left, flags);
                if (i == -1) {
                        return (0-errno);
                }
index 1cd8ca611723fd68da3a1caa1456c9169a413db6..6b23f60397f33ecd14d0cd7a72de587c8fe0713c 100644 (file)
@@ -21,8 +21,8 @@
 int gnutls_insertDataBuffer(ContentType type, GNUTLS_STATE state, char *data, int length);
 int gnutls_getDataBufferSize(ContentType type, GNUTLS_STATE state);
 int gnutls_getDataFromBuffer(ContentType type, GNUTLS_STATE state, char *data, int length);
-ssize_t _gnutls_Read(int fd, void *iptr, size_t n, int flag);
-ssize_t _gnutls_Write(int fd, const void *iptr, size_t n);
+ssize_t _gnutls_Read(int fd, void *iptr, size_t n, int);
+ssize_t _gnutls_Write(int fd, const void *iptr, size_t n, int );
 
 /* used in SSL3 */
 int gnutls_getHashDataFromBuffer( GNUTLS_STATE state, char *data, int length);
index c532c5b8b16f7bdc41a33ee98bf0c4a13edf0a57..5f7437844e8cbcb1011e2496bc8f21060369da61 100644 (file)
@@ -233,7 +233,7 @@ static int _read_rsa_params(opaque * der, int dersize, MPI ** params)
        }
 
        /* allocate size for the parameters (2) */
-       *params = gnutls_malloc(2 * sizeof(MPI));
+       *params = gnutls_calloc(1, 2 * sizeof(MPI));
 
        if (gcry_mpi_scan(&(*params)[0], GCRYMPI_FMT_USG, str, &len) != 0) {
                gnutls_assert();
@@ -270,30 +270,37 @@ static int _read_rsa_params(opaque * der, int dersize, MPI ** params)
 
 
 #define _READ( str, OID, NAME, res) \
-       if(!strcmp(str, OID)){ \
+       if(strcmp(str, OID)==0){ \
          strcpy( str, "PKIX1Explicit88.X520"); \
          strcat( str, NAME); \
-         if (create_structure( NAME, str) != ASN_OK) \
+         strcpy( name2, "temp-structure-"); \
+         strcat( name2, NAME); \
+         if ( (result = create_structure( name2, str)) != ASN_OK) { \
+               gnutls_assert(); \
                return GNUTLS_E_ASN1_ERROR; \
+         } \
          if (read_value(name3,str,&len) != ASN_OK) { \
-               delete_structure( NAME); \
-               return GNUTLS_E_ASN1_PARSING_ERROR; \
+               delete_structure( name2); \
+               continue; \
+         } \
+         if (get_der( name2, str, len) != ASN_OK) { \
+               delete_structure( name2); \
+               continue; \
          } \
-         if (get_der( NAME, str, len) != ASN_OK) { \
-               delete_structure( NAME); \
-               return GNUTLS_E_ASN1_PARSING_ERROR; \
+         strcpy( name3,name2); \
+         if (read_value( name3, str, &len) != ASN_OK) {  /* CHOICE */ \
+               delete_structure( name2); \
+               continue; \
          } \
-         strcpy( name3,NAME); \
-         read_value( name3, str, &len);  /* CHOICE */ \
-         strcat( name3, "."); \
+         strcat( name3, "."); \
          strcat( name3, str); \
          if (read_value(name3,str,&len) != ASN_OK) { \
-               delete_structure( NAME); \
-               return GNUTLS_E_ASN1_PARSING_ERROR; \
+               delete_structure( name2); \
+               continue; \
          } \
          str[len]=0; \
          res = strdup(str); \
-         delete_structure(NAME); \
+         delete_structure(name2); \
        }
 
 /* This function will attempt to read a Name
@@ -311,6 +318,7 @@ static int _get_Name_type(char *root, gnutls_cert * gCert)
                strcat(name, ".rdnSequence.?");
                ltostr(k, counter);
                strcat(name, counter);
+
                result = read_value(name, str, &len);
                if (result == ASN_ELEMENT_NOT_FOUND)
                        break;
@@ -326,16 +334,20 @@ static int _get_Name_type(char *root, gnutls_cert * gCert)
                        strcpy(name3, name2);
                        strcat(name3, ".type");
                        result = read_value(name3, str, &len);
+
                        if (result != ASN_OK) {
                                gnutls_assert();
                                return GNUTLS_E_ASN1_PARSING_ERROR;
                        }
                        strcpy(name3, name2);
                        strcat(name3, ".value");
+
                        if (result == ASN_OK) {
-                               _READ(str, "2 5 4 6", "Country",
-                                     gCert->country);
-                               _READ(str, "2 5 4 10", "Organization",
+/*                             _READ(str, "2 5 4 6", "countryName",
+ *                                   gCert->country);
+ * This one fails (with SIGSEGV).
+ */
+                               _READ(str, "2 5 4 10", "OrganizationName",
                                      gCert->organization);
                                _READ(str, "2 5 4 11",
                                      "OrganizationalUnitName",
@@ -399,7 +411,6 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert)
                    read_value
                    ("certificate3.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
                     str, &len);
-               delete_structure("certificate3");
 
                if (result != ASN_OK) {
                        gnutls_assert();
@@ -471,7 +482,7 @@ int _gnutls_cert_supported_kx(gnutls_cert * cert, KXAlgorithm ** alg,
                }
        }
 
-       *alg = gnutls_malloc(sizeof(KXAlgorithm) * i);
+       *alg = gnutls_calloc(1, sizeof(KXAlgorithm) * i);
        if (*alg == NULL)
                return GNUTLS_E_MEMORY_ERROR;
 
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
new file mode 100644 (file)
index 0000000..e0c6e4f
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *      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_asn1.h>
+#include <signal.h>
+
+static void* old_sig_handler;
+ssize_t (*recv_func)( SOCKET, void*, size_t, int);
+ssize_t (*send_func)( SOCKET,const void*, size_t, int);
+
+int gnutls_is_secure_memory(const void* mem) {
+       return 0;
+}
+
+/**
+  * gnutls_global_init - This function initializes the global state to defaults.
+  *
+  * This function initializes the global state to defaults.
+  * Every gnutls application has a global state which holds common parameters
+  * shared by gnutls state structures.
+  * You must call gnutls_global_deinit() when gnutls usage is no longer needed
+  * Returns zero on success.
+  **/
+int gnutls_global_init(char* PKIX, char* PKCS1)
+{
+       int result;
+
+       /* for gcrypt in order to be able to allocate memory */
+       gcry_set_allocation_handler(gnutls_malloc, secure_malloc, gnutls_is_secure_memory, gnutls_realloc, free);
+
+       /* we need this */
+       old_sig_handler = signal( SIGPIPE, SIG_IGN);
+
+       /* set default recv/send functions
+        */
+       recv_func = recv;
+       send_func = send;
+
+       /* initialize parser 
+        * This should not deal with files in the final
+        * version.
+        */
+       
+       result = parser_asn1(PKIX);
+
+       if (result != ASN_OK) {
+               return GNUTLS_E_ASN1_PARSING_ERROR;
+       }
+       
+       result = parser_asn1(PKCS1);
+
+       if (result != ASN_OK) {
+               return GNUTLS_E_PARSING_ERROR;
+       }
+       
+       return 0;
+}
+
+/**
+  * gnutls_global_deinit - This function deinitializes the global state 
+  *
+  * This function deinitializes the global state.
+  **/
+
+void gnutls_global_deinit() {
+
+       /* restore signal handler  */
+       signal( SIGPIPE, old_sig_handler);
+
+
+
+}
index 91e0b02d89b1d72c83a3a53754caa247c590325d..6a5250c3d8d9304e96d207a45447756001dbb253 100644 (file)
@@ -57,10 +57,6 @@ void gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version) {
        }
 }
 
-int gnutls_is_secure_memory(const void* mem) {
-       return 0;
-}
-
 /**
   * gnutls_set_lowat - Used to set the lowat value in order for select to check for pending data.
   * @state: is a &GNUTLS_STATE structure.
@@ -89,8 +85,6 @@ int gnutls_set_lowat(GNUTLS_STATE state, int num) {
   **/
 int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end)
 {
-       /* for gcrypt in order to be able to allocate memory */
-       gcry_set_allocation_handler(gnutls_malloc, secure_malloc, gnutls_is_secure_memory, gnutls_realloc, free);
 
        *state = gnutls_calloc(1, sizeof(GNUTLS_STATE_INT));
        
@@ -122,7 +116,7 @@ int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end)
 
 #define GNUTLS_FREE(x) if(x!=NULL) gnutls_free(x)
 /**
-  * gnutls_init - This function clears all buffers associated with the &state
+  * gnutls_deinit - This function clears all buffers associated with the &state
   * @state: is a &GNUTLS_STATE structure.
   *
   * This function clears all buffers associated with the &state.
@@ -541,14 +535,14 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const v
                
                WRITEuint16( cipher_size, &headers[3]);
                
-               if (_gnutls_Write(cd, headers, HEADER_SIZE) != HEADER_SIZE) {
+               if (_gnutls_Write(cd, headers, HEADER_SIZE, flags) != HEADER_SIZE) {
                        state->gnutls_internals.valid_connection = VALID_FALSE;
                        state->gnutls_internals.resumable = RESUME_FALSE;
                        gnutls_assert();
                        return GNUTLS_E_UNABLE_SEND_DATA;
                }
 
-               if (_gnutls_Write(cd, cipher, cipher_size) != cipher_size) {
+               if (_gnutls_Write(cd, cipher, cipher_size, flags) != cipher_size) {
                        state->gnutls_internals.valid_connection = VALID_FALSE;
                        state->gnutls_internals.resumable = RESUME_FALSE;
                        gnutls_assert();
@@ -580,7 +574,7 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const v
                memmove( cipher, headers, HEADER_SIZE);
 
                cipher_size += HEADER_SIZE;
-               if (_gnutls_Write(cd, cipher, cipher_size) != cipher_size) {
+               if (_gnutls_Write(cd, cipher, cipher_size, flags) != cipher_size) {
                        state->gnutls_internals.valid_connection = VALID_FALSE;
                        state->gnutls_internals.resumable = RESUME_FALSE;
                        gnutls_assert();
@@ -628,14 +622,14 @@ ssize_t _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state)
 
        WRITEuint16( 1, &headers[3]);
        
-       if (_gnutls_Write(cd, headers, 5) != 5) {
+       if (_gnutls_Write(cd, headers, 5, 0) != 5) {
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
                return GNUTLS_E_UNABLE_SEND_DATA;
        }
 
-       if (_gnutls_Write(cd, &data, 1) != 1) {
+       if (_gnutls_Write(cd, &data, 1, 0) != 1) {
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
index 88f9550912b5a7819eb3d8399d90867f1388debf..35fd9496e4767442e463aada84e6f0128eeb728c 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -28,7 +28,6 @@
 #include <string.h>
 #include <unistd.h>
 #include "../lib/gnutls.h"
-#include <signal.h>
 #include <sys/time.h>
 
 #define SA struct sockaddr
@@ -39,8 +38,6 @@
 
 #define MAX(X,Y) (X >= Y ? X : Y);
 
-#include "pk.h"
-
 static int print_info( GNUTLS_STATE state) {
 char *tmp;
 const ANON_AUTH_INFO *dh_info;
@@ -60,17 +57,19 @@ const X509PKI_AUTH_INFO *x509_info;
                if (x509_info != NULL) {
                        switch( x509_info->peer_certificate_status) {
                        case GNUTLS_NOT_VERIFIED:
-                               printf("- Peer's Certificate was NOT verified\n");
+                               printf("- Peer's X509 Certificate was NOT verified\n");
                                break;
                        case GNUTLS_EXPIRED:
-                               printf("- Peer's Certificate was verified but is expired\n");
-                               break;
-                       case GNUTLS_INVALID:
-                               printf("- Peer's Certificate was invalid\n");
+                               printf("- Peer's X509 Certificate was verified but is expired\n");
                                break;
                        case GNUTLS_VERIFIED:
-                               printf("- Peer's Certificate was verified\n");
+                               printf("- Peer's X509 Certificate was verified\n");
                                break;
+                       case GNUTLS_INVALID:
+                       default:
+                               printf("- Peer's X509 Certificate was invalid\n");
+                               break;
+
                        }
                }
        }
@@ -115,13 +114,15 @@ int main(int argc, char** argv)
                fprintf(stderr, "Usage: cli [host] [port]\n");
                exit(1);
        }
-       PARSE();
+       
+       if (gnutls_global_init("pkix.asn", "pkcs1.asn") < 0) {
+               fprintf(stderr, "global state initialization error\n");
+               exit(1);
+       }
                
        cred.username = "test";
        cred.password = "test";
        
-       signal(SIGPIPE, SIG_IGN);
-
        sd = socket(AF_INET, SOCK_STREAM, 0);
        ERR(sd, "socket");
 
@@ -286,5 +287,8 @@ int main(int argc, char** argv)
        close(sd);
        
        gnutls_deinit( state);
+
+       gnutls_global_deinit();
+       
        return 0;
 }
diff --git a/src/pk.h b/src/pk.h
deleted file mode 100644 (file)
index 9615747..0000000
--- a/src/pk.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#define PKIX "pkix.asn"
-#define PKCS "pkcs1.asn"
-void PARSE()
-{
-       /* this is to be moved to gnutls */
-       int result = parser_asn1(PKIX);
-
-       signal( SIGPIPE, SIG_IGN);
-
-       if (result == ASN_SYNTAX_ERROR) {
-               printf("%s: PARSE ERROR\n", PKIX);
-               return;
-       } else if (result == ASN_IDENTIFIER_NOT_FOUND) {
-               printf("%s: IDENTIFIER NOT FOUND\n", PKIX);
-               return;
-       }
-
-       result = parser_asn1(PKCS);
-
-       if (result == ASN_SYNTAX_ERROR) {
-               printf("%s: PARSE ERROR\n", PKCS);
-               return;
-       } else if (result == ASN_IDENTIFIER_NOT_FOUND) {
-               printf("%s: IDENTIFIER NOT FOUND\n", PKCS);
-               return;
-       }
-
-}
index 5ffcc8b1da1d94bae0ff35aa2f17d8eeeb39b507..1d1c00dde74378fe1cf10bf0c84154f48bad483c 100644 (file)
@@ -29,8 +29,6 @@
 #include <unistd.h>
 #include "../lib/gnutls.h"
 #include <port.h>
-#include <signal.h>
-#include "pk.h"
 
 #define KEYFILE "key.pem"
 #define CERTFILE "cert.pem"
@@ -72,10 +70,6 @@ GNUTLS_STATE initialize_state()
        GNUTLS_STATE state;
        int ret;
 
-       if (gnutls_allocate_x509_sc(&x509_cred, CERTFILE, KEYFILE) < 0) {
-               fprintf(stderr, "X509 PARSE ERROR\n");
-               exit(1);
-       }
 
        /* this is a password file (created with the included crypt utility) 
         * Read README.crypt prior to using SRP.
@@ -287,7 +281,16 @@ int main(int argc, char **argv)
                }
        }
        
-       PARSE();
+       if (gnutls_global_init("pkix.asn", "pkcs1.asn") < 0) {
+               fprintf(stderr, "global state initialization error\n");
+               exit(1);
+       }
+
+       if (gnutls_allocate_x509_sc(&x509_cred, CERTFILE, KEYFILE) < 0) {
+               fprintf(stderr, "X509 PARSE ERROR\n");
+               exit(1);
+       }
+
 
        listen_sd = socket(AF_INET, SOCK_STREAM, 0);
        ERR(listen_sd, "socket");
@@ -389,6 +392,11 @@ int main(int argc, char **argv)
                gnutls_deinit(state);
        }
        close(listen_sd);
+
+       gnutls_free_x509_sc(x509_cred);
+
+       gnutls_global_deinit();
+       
        return 0;
 
 }