summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-11-29 15:29:54 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-11-29 15:29:54 +0000
commitc89ee7ef6caff8f6929702db1859c22c1ec4adc3 (patch)
treed54067c4bc4ef3e6b8c5e9d1ba72f55ed225ab74 /lib
parent47580d3bd319cbacab763a9bb0f293e9a79ebed6 (diff)
downloadgnutls-c89ee7ef6caff8f6929702db1859c22c1ec4adc3.tar.gz
introduced gnutls_x509pki_get_certificate(). This function returns the
peer's certificate DER encoded. This certificate is also stored in the resume db.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/auth_anon.c13
-rw-r--r--lib/auth_dhe_rsa.c9
-rw-r--r--lib/auth_rsa.c1
-rw-r--r--lib/auth_srp.c8
-rw-r--r--lib/auth_x509.c30
-rw-r--r--lib/auth_x509.h9
-rw-r--r--lib/gnutls_algorithms.c2
-rw-r--r--lib/gnutls_auth.c45
-rw-r--r--lib/gnutls_db.c22
-rw-r--r--lib/gnutls_int.h11
-rw-r--r--lib/gnutls_record.c31
-rw-r--r--lib/gnutls_session.c57
-rw-r--r--lib/gnutls_session_pack.c344
-rw-r--r--lib/gnutls_session_pack.h3
-rw-r--r--lib/gnutls_ui.c21
-rw-r--r--lib/gnutls_ui.h3
17 files changed, 529 insertions, 84 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f65d5c3cd7..42ace9e549 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -17,7 +17,7 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h pkcs1.asn pkix.asn \
ext_dnsname.h gnutls_pk.h gnutls_record.h gnutls_cert.h \
gnutls_privkey.h gnutls_constate.h gnutls_global.h x509_verify.h \
gnutls_sig.h gnutls_mem.h x509_extensions.h gnutls_ui.h \
- gnutls-api.tex io_debug.h ext_max_record.h
+ gnutls-api.tex io_debug.h ext_max_record.h gnutls_session_pack.h
lib_LTLIBRARIES = libgnutls.la
@@ -30,7 +30,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c \
auth_anon.c auth_dhe_dss.c gnutls_extensions.c ext_srp.c gnutls_auth.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 \
- gnutls_datum.c auth_rsa.c \
+ gnutls_datum.c auth_rsa.c gnutls_session_pack.c \
gnutls_gcry.c ext_dnsname.c gnutls_pk.c gnutls_cert.c x509_verify.c\
gnutls_global.c gnutls_privkey.c gnutls_constate.c gnutls_anon_cred.c \
x509_sig_check.c pkix_asn1_tab.c pkcs1_asn1_tab.c gnutls_mem.c \
diff --git a/lib/auth_anon.c b/lib/auth_anon.c
index 17284e6a7d..ba2341e881 100644
--- a/lib/auth_anon.c
+++ b/lib/auth_anon.c
@@ -87,11 +87,18 @@ int gen_anon_server_kx( GNUTLS_STATE state, opaque** data) {
return GNUTLS_E_MEMORY_ERROR;
}
- state->gnutls_key->auth_info = gnutls_malloc(sizeof(ANON_SERVER_AUTH_INFO));
- if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
+ if ( state->gnutls_key->auth_info == NULL) {
+ state->gnutls_key->auth_info = gnutls_malloc(sizeof(ANON_SERVER_AUTH_INFO));
+ if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
+ state->gnutls_key->auth_info_type = GNUTLS_ANON;
+ state->gnutls_key->auth_info_size = sizeof(ANON_SERVER_AUTH_INFO_INT);
+ } else
+ if (gnutls_get_auth_type( state) != state->gnutls_key->auth_info_type) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
((ANON_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->dh_bits = gcry_mpi_get_nbits(p);
- state->gnutls_key->auth_info_size = sizeof(ANON_SERVER_AUTH_INFO_INT);
X = gnutls_calc_dh_secret(&x, g, p);
if (X==NULL || x==NULL) {
diff --git a/lib/auth_dhe_rsa.c b/lib/auth_dhe_rsa.c
index bec7454fcc..d6f7b8291c 100644
--- a/lib/auth_dhe_rsa.c
+++ b/lib/auth_dhe_rsa.c
@@ -102,7 +102,14 @@ static int gen_dhe_rsa_server_kx(GNUTLS_STATE state, opaque ** data)
info = state->gnutls_key->auth_info;
info->dh_bits = gcry_mpi_get_nbits(p);
info->peer_certificate_status = GNUTLS_CERT_NONE;
- }
+ state->gnutls_key->auth_info_type = GNUTLS_X509PKI;
+
+ } else
+ if (gnutls_get_auth_type( state) != state->gnutls_key->auth_info_type) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
info = state->gnutls_key->auth_info;
X = gnutls_calc_dh_secret(&x, g, p);
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index ee4c838750..1073fe7c9b 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -70,6 +70,7 @@ MOD_AUTH_STRUCT rsa_auth_struct =
#define RANDOMIZE_KEY(x, galloc) x.size=TLS_MASTER_SIZE; x.data=galloc(x.size); \
if (x.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
if (_gnutls_get_random( x.data, x.size, GNUTLS_WEAK_RANDOM) < 0) { \
+ gnutls_assert(); \
return GNUTLS_E_MEMORY_ERROR; \
}
diff --git a/lib/auth_srp.c b/lib/auth_srp.c
index 7d36b4344d..e017f53835 100644
--- a/lib/auth_srp.c
+++ b/lib/auth_srp.c
@@ -76,8 +76,14 @@ int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data)
GNUTLS_SRP_PWD_ENTRY *pwd_entry;
int err;
- if ( state->gnutls_key->auth_info == NULL)
+ if ( state->gnutls_key->auth_info == NULL) {
state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(SRP_SERVER_AUTH_INFO_INT));
+ state->gnutls_key->auth_info_type = GNUTLS_SRP;
+ } else
+ if (gnutls_get_auth_type( state) != state->gnutls_key->auth_info_type) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
if (state->gnutls_key->auth_info == NULL) {
gnutls_assert();
diff --git a/lib/auth_x509.c b/lib/auth_x509.c
index 41b739531a..be6b67377a 100644
--- a/lib/auth_x509.c
+++ b/lib/auth_x509.c
@@ -40,9 +40,11 @@
/* Copies data from a internal certificate struct (gnutls_cert) to
* exported certificate struct (X509PKI_AUTH_INFO)
*/
-void _gnutls_copy_x509_client_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, CertificateStatus verify) {
+int _gnutls_copy_x509_client_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, CertificateStatus verify) {
/* Copy peer's information to AUTH_INFO
*/
+int ret;
+
memcpy( &info->peer_dn, &cert->cert_info, sizeof(gnutls_DN));
memcpy( &info->issuer_dn, &cert->issuer_info, sizeof(gnutls_DN));
@@ -59,7 +61,15 @@ void _gnutls_copy_x509_client_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* ce
info->peer_certificate_expiration_time = cert->expiration_time;
info->peer_certificate_activation_time = cert->activation_time;
- return;
+ if (cert->raw.size > 0) {
+ ret = gnutls_set_datum( &info->raw_certificate, cert->raw.data, cert->raw.size);
+ if ( ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
+
+ return 0;
}
typedef struct {
@@ -536,6 +546,8 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
gnutls_assert();
return GNUTLS_E_INSUFICIENT_CRED;
}
+
+
if (state->gnutls_key->auth_info == NULL) {
state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(X509PKI_AUTH_INFO_INT));
if (state->gnutls_key->auth_info == NULL) {
@@ -546,7 +558,14 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
info = state->gnutls_key->auth_info;
info->peer_certificate_status = GNUTLS_CERT_NONE;
- }
+
+ state->gnutls_key->auth_info_type = GNUTLS_X509PKI;
+ } else
+ if (gnutls_get_auth_type( state) != state->gnutls_key->auth_info_type) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
info = state->gnutls_key->auth_info;
DECR_LEN(dsize, 3);
@@ -647,7 +666,10 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
/* keep the PK algorithm */
state->gnutls_internals.peer_pk_algorithm = peer_certificate_list[0].subject_pk_algorithm;
- _gnutls_copy_x509_client_auth_info(info, &peer_certificate_list[0], verify);
+ if ( (ret = _gnutls_copy_x509_client_auth_info(info, &peer_certificate_list[0], verify)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
if ( (ret=_gnutls_check_x509_key_usage( &peer_certificate_list[0], gnutls_get_current_kx( state))) < 0) {
gnutls_assert();
diff --git a/lib/auth_x509.h b/lib/auth_x509.h
index e4e61a076b..9d7d8b0faa 100644
--- a/lib/auth_x509.h
+++ b/lib/auth_x509.h
@@ -46,13 +46,18 @@ typedef struct X509PKI_AUTH_INFO_INT {
time_t peer_certificate_expiration_time;
char subjectAltDNSName[X509_CN_SIZE];
unsigned char keyUsage;
- int certificate_requested;
+ int certificate_requested; /* if the peer requested certificate
+ * this is non zero;
+ */
int dh_bits; /* bits of the DH (if DHE_RSA is used) */
+ gnutls_datum raw_certificate; /* holds the raw certificate of the
+ * peer.
+ */
} *X509PKI_AUTH_INFO;
typedef struct X509PKI_AUTH_INFO_INT X509PKI_AUTH_INFO_INT;
-void _gnutls_copy_x509_client_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, CertificateStatus verify);
+int _gnutls_copy_x509_client_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, CertificateStatus verify);
/* AUTH X509 functions */
int _gnutls_gen_x509_server_certificate(GNUTLS_STATE, opaque **);
diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c
index 40d78dec0a..e5072e12fd 100644
--- a/lib/gnutls_algorithms.c
+++ b/lib/gnutls_algorithms.c
@@ -675,7 +675,7 @@ const char *gnutls_kx_get_name(KXAlgorithm algorithm)
char *ret = NULL;
/* avoid prefix */
- GNUTLS_KX_ALG_LOOP(ret = p->name + sizeof("GNUTLS_") - 1);
+ GNUTLS_KX_ALG_LOOP(ret = p->name + sizeof("GNUTLS_KX_") - 1);
return ret;
}
diff --git a/lib/gnutls_auth.c b/lib/gnutls_auth.c
index ce9ca1cc27..8af9a04696 100644
--- a/lib/gnutls_auth.c
+++ b/lib/gnutls_auth.c
@@ -23,6 +23,7 @@
#include "gnutls_auth.h"
#include "gnutls_auth_int.h"
#include "gnutls_algorithms.h"
+#include "auth_x509.h"
#include "auth_anon.h"
/* The functions here are used in order for authentication algorithms
@@ -135,8 +136,10 @@ int gnutls_set_cred( GNUTLS_STATE state, CredType type, void* cred) {
**/
CredType gnutls_get_auth_type( GNUTLS_STATE state) {
+
return _gnutls_map_kx_get_cred(
- state->security_parameters.kx_algorithm);
+ _gnutls_cipher_suite_get_kx_algo
+ (state->security_parameters.current_cipher_suite));
}
/*
@@ -182,3 +185,43 @@ void* _gnutls_get_auth_info( GNUTLS_STATE state) {
return state->gnutls_key->auth_info;
}
+/*-
+ * _gnutls_free_auth_info - Frees the auth info structure
+ * @state: is a &GNUTLS_STATE structure.
+ *
+ * this function frees the auth info structure and sets it to
+ * null. It must be called since some structures contain malloced
+ * elements.
+ -*/
+void _gnutls_free_auth_info( GNUTLS_STATE state) {
+ if (state==NULL || state->gnutls_key==NULL) {
+ gnutls_assert();
+ return;
+ }
+
+ switch ( state->gnutls_key->auth_info_type) {
+ case GNUTLS_SRP:
+ case GNUTLS_ANON:
+
+ break;
+ case GNUTLS_X509PKI: {
+ X509PKI_AUTH_INFO info =
+ _gnutls_get_auth_info(state);
+
+ if (info==NULL) break;
+ gnutls_free( info->raw_certificate.data);
+
+ }
+ break;
+ default:
+ return;
+
+ }
+
+ gnutls_free( state->gnutls_key->auth_info);
+ state->gnutls_key->auth_info = NULL;
+ state->gnutls_key->auth_info_size = 0;
+ state->gnutls_key->auth_info_type = 0;
+
+}
+
diff --git a/lib/gnutls_db.c b/lib/gnutls_db.c
index 88ebc989e9..7e68afd101 100644
--- a/lib/gnutls_db.c
+++ b/lib/gnutls_db.c
@@ -26,6 +26,7 @@
#include "gnutls_session.h"
#include <gnutls_db.h>
#include "debug.h"
+#include <gnutls_session_pack.h>
#define GNUTLS_DBNAME state->gnutls_internals.db_name
@@ -242,13 +243,13 @@ gnutls_datum _key;
}
/* The format of storing data is:
- * SECURITY_PARAMETERS + AUTH_INFO_SIZE + AUTH_INFO
+ * (forget it). Check gnutls_session_pack.c
*/
int _gnutls_server_register_current_session( GNUTLS_STATE state)
{
gnutls_datum key = { state->security_parameters.session_id, state->security_parameters.session_id_size };
gnutls_datum content;
-int ret = 0, pos;
+int ret = 0;
if (state->gnutls_internals.resumable==RESUME_FALSE)
return GNUTLS_E_INVALID_SESSION;
@@ -257,20 +258,17 @@ int ret = 0, pos;
return GNUTLS_E_INVALID_SESSION;
/* allocate space for data */
- content.size = sizeof(SecurityParameters) + state->gnutls_key->auth_info_size
- + sizeof(state->gnutls_key->auth_info_size);
+ content.size = _gnutls_session_size( state);
content.data = gnutls_malloc( content.size);
if (content.data==NULL) return GNUTLS_E_MEMORY_ERROR;
/* copy data */
- pos = 0;
- memcpy( &content.data[0], (void*)&state->security_parameters, sizeof(SecurityParameters));
- pos+=sizeof(SecurityParameters);
-
- memcpy( &content.data[pos], &state->gnutls_key->auth_info_size, sizeof(state->gnutls_key->auth_info_size));
- pos+=sizeof(state->gnutls_key->auth_info_size);
-
- memcpy( &content.data[pos], state->gnutls_key->auth_info, state->gnutls_key->auth_info_size);
+ ret = _gnutls_session_pack( state, &content);
+ if (ret < 0) {
+ gnutls_free( content.data);
+ gnutls_assert();
+ return ret;
+ }
ret = _gnutls_store_session( state, key, content);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 3264bf1599..caf6c5bbba 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -31,9 +31,9 @@
#define WRITE_DEBUG
#define READ_DEBUG
#define HANDSHAKE_DEBUG // Prints some information on handshake
-#define RECORD_DEBUG
+#define RECORD_DEBUG*/
#define DEBUG
-*/
+
/* It might be a good idea to replace int with void*
* here.
@@ -201,10 +201,12 @@ struct GNUTLS_KEY_INT {
/* this is used to hold the peers authentication data
*/
- /* AUTH_INFO structures MUST NOT contain malloced
- * elements.
+ /* AUTH_INFO structures MAY contain malloced
+ * elements. Check gnutls_session_pack.c, and gnutls_auth.c.
+ * Rememember that this should be calloced!
*/
void* auth_info;
+ CredType auth_info_type;
int auth_info_size; /* needed in order to store to db for restoring
*/
uint8 crypt_algo;
@@ -494,6 +496,7 @@ svoid *gnutls_PRF( opaque * secret, int secret_size, uint8 * label,
int total_bytes);
void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version);
GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state);
+void _gnutls_free_auth_info( GNUTLS_STATE state);
/* These two macros return the advertized TLS version of
* the peer.
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index 3f26919ac5..1875e5d322 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -157,7 +157,7 @@ int gnutls_deinit(GNUTLS_STATE state)
}
/* remove auth info firstly */
- _gnutls_free(state->gnutls_key->auth_info);
+ _gnutls_free_auth_info(state );
#ifdef HAVE_LIBGDBM
/* close the database - resuming sessions */
@@ -190,21 +190,24 @@ int gnutls_deinit(GNUTLS_STATE state)
gnutls_sfree_datum( &state->cipher_specs.server_write_key);
gnutls_sfree_datum( &state->cipher_specs.client_write_key);
- _gnutls_mpi_release(&state->gnutls_key->KEY);
- _gnutls_mpi_release(&state->gnutls_key->client_Y);
- _gnutls_mpi_release(&state->gnutls_key->client_p);
- _gnutls_mpi_release(&state->gnutls_key->client_g);
+ if (state->gnutls_key != NULL) {
+ _gnutls_mpi_release(&state->gnutls_key->KEY);
+ _gnutls_mpi_release(&state->gnutls_key->client_Y);
+ _gnutls_mpi_release(&state->gnutls_key->client_p);
+ _gnutls_mpi_release(&state->gnutls_key->client_g);
- _gnutls_mpi_release(&state->gnutls_key->u);
- _gnutls_mpi_release(&state->gnutls_key->a);
- _gnutls_mpi_release(&state->gnutls_key->x);
- _gnutls_mpi_release(&state->gnutls_key->A);
- _gnutls_mpi_release(&state->gnutls_key->B);
- _gnutls_mpi_release(&state->gnutls_key->b);
+ _gnutls_mpi_release(&state->gnutls_key->u);
+ _gnutls_mpi_release(&state->gnutls_key->a);
+ _gnutls_mpi_release(&state->gnutls_key->x);
+ _gnutls_mpi_release(&state->gnutls_key->A);
+ _gnutls_mpi_release(&state->gnutls_key->B);
+ _gnutls_mpi_release(&state->gnutls_key->b);
- _gnutls_mpi_release(&state->gnutls_key->dh_secret);
- _gnutls_free(state->gnutls_key);
+ _gnutls_mpi_release(&state->gnutls_key->dh_secret);
+ _gnutls_free(state->gnutls_key);
+ state->gnutls_key = NULL;
+ }
/* free priorities */
_gnutls_free(state->gnutls_internals.MACAlgorithmPriority.algorithm_priority);
@@ -246,7 +249,7 @@ static svoid *gnutls_P_hash( MACAlgorithm algorithm, opaque * secret, int secret
int i = 0, times, how, blocksize, A_size;
opaque final[20], Atmp[MAX_SEED_SIZE];
- if (seed_size > MAX_SEED_SIZE) {
+ if (seed_size > MAX_SEED_SIZE || total_bytes<=0) {
gnutls_assert();
return NULL;
}
diff --git a/lib/gnutls_session.c b/lib/gnutls_session.c
index 8474d59c3d..8e98641e60 100644
--- a/lib/gnutls_session.c
+++ b/lib/gnutls_session.c
@@ -20,8 +20,9 @@
#include "gnutls_int.h"
#include "gnutls_errors.h"
#include "debug.h"
+#include <gnutls_session_pack.h>
-#define SESSION_SIZE sizeof(SecurityParameters) + sizeof(state->gnutls_key->auth_info_size) + state->gnutls_key->auth_info_size
+#define SESSION_SIZE _gnutls_session_size( state)
/**
* gnutls_get_current_session - Returns all session parameters.
@@ -38,6 +39,9 @@
**/
int gnutls_get_current_session( GNUTLS_STATE state, opaque* session, int *session_size) {
+ gnutls_datum psession;
+ int ret;
+
if (*session_size < SESSION_SIZE || session==NULL) {
*session_size = SESSION_SIZE;
session = NULL; /* return with the new session_size value */
@@ -48,10 +52,15 @@ int gnutls_get_current_session( GNUTLS_STATE state, opaque* session, int *sessio
if (session==NULL) {
return 0;
}
- memcpy( session, &state->security_parameters, sizeof(SecurityParameters));
- memcpy( &session[sizeof(SecurityParameters)], &state->gnutls_key->auth_info_size, sizeof(state->gnutls_key->auth_info_size));
- memcpy( &session[sizeof(state->gnutls_key->auth_info_size)+sizeof(SecurityParameters)],
- state->gnutls_key->auth_info, state->gnutls_key->auth_info_size);
+
+ psession.data = session;
+
+ ret = _gnutls_session_pack( state, &psession);
+ if (ret< 0) {
+ gnutls_assert();
+ return ret;
+ }
+ *session_size = psession.size;
return 0;
}
@@ -97,43 +106,15 @@ int gnutls_get_current_session_id( GNUTLS_STATE state, void* session, int *sessi
* performed.
**/
int gnutls_set_current_session( GNUTLS_STATE state, opaque* session, int session_size) {
- int auth_info_size;
- int timestamp = time(0);
- SecurityParameters sp;
+ int ret;
+ gnutls_datum psession = { session, session_size };
- if ( (session_size - sizeof(SecurityParameters))
- >= sizeof(state->gnutls_key->auth_info_size)) { /* have more data */
- auth_info_size = *((int*)&session[sizeof(SecurityParameters)]);
- } else {
- auth_info_size = 0;
- gnutls_assert();
- return GNUTLS_E_DB_ERROR;
- }
- if (session_size < sizeof(SecurityParameters)) {
+ ret = _gnutls_session_unpack( state, &psession);
+ if (ret < 0) {
gnutls_assert();
- return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ return ret;
}
- memcpy( &sp, session, sizeof(SecurityParameters));
- if ( timestamp - sp.timestamp <= state->gnutls_internals.expire_time
- && sp.timestamp <= timestamp) {
-
- memcpy( &state->gnutls_internals.resumed_security_parameters, &sp, sizeof(SecurityParameters));
- if (auth_info_size > 0) {
- state->gnutls_key->auth_info = gnutls_malloc(auth_info_size);
- if (state->gnutls_key->auth_info==NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
- state->gnutls_key->auth_info_size = auth_info_size;
- memcpy( state->gnutls_key->auth_info, &session[sizeof(SecurityParameters)+sizeof(state->gnutls_key->auth_info_size)], auth_info_size);
- } else { /* set to null */
- state->gnutls_key->auth_info_size = 0;
- state->gnutls_key->auth_info = NULL;
- }
- } else {
- return GNUTLS_E_EXPIRED;
- }
return 0;
}
diff --git a/lib/gnutls_session_pack.c b/lib/gnutls_session_pack.c
new file mode 100644
index 0000000000..38396d14de
--- /dev/null
+++ b/lib/gnutls_session_pack.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2000 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 <gnutls_int.h>
+#include <auth_srp.h>
+#include <auth_anon.h>
+#include <auth_x509.h>
+#include <gnutls_errors.h>
+#include <gnutls_auth_int.h>
+#include <gnutls_session_pack.h>
+#include <gnutls_datum.h>
+#include <gnutls_num.h>
+
+#define PACK_HEADER_SIZE 1
+int _gnutls_pack_x509pki_auth_info(X509PKI_AUTH_INFO info,
+ gnutls_datum * packed_session);
+int _gnutls_unpack_x509pki_auth_info(X509PKI_AUTH_INFO info,
+ const gnutls_datum * packed_session);
+static int _gnutls_pack_x509pki_auth_info_size();
+
+
+/* Since auth_info structures contain malloced data, this function
+ * is required in order to pack these structures in a vector in
+ * order to store them to the DB.
+ */
+int _gnutls_session_pack(GNUTLS_STATE state, gnutls_datum * packed_session)
+{
+ uint32 pack_size;
+ int ret;
+
+ if (packed_session==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ }
+
+ switch (gnutls_get_auth_type(state)) {
+ case GNUTLS_SRP:{
+ SRP_SERVER_AUTH_INFO info =
+ _gnutls_get_auth_info(state);
+ if (info == NULL || info->username[0] == 0)
+ return GNUTLS_E_INVALID_PARAMETERS;
+
+ pack_size = sizeof(SRP_SERVER_AUTH_INFO_INT);
+ packed_session->size =
+ PACK_HEADER_SIZE + pack_size + sizeof(uint32);
+
+ packed_session->data[0] = GNUTLS_SRP;
+ WRITEuint32(pack_size,
+ &packed_session->
+ data[PACK_HEADER_SIZE]);
+ memcpy(&packed_session->
+ data[PACK_HEADER_SIZE + sizeof(uint32)],
+ info, sizeof(SRP_SERVER_AUTH_INFO_INT));
+
+ }
+ break;
+ case GNUTLS_ANON:{
+ ANON_CLIENT_AUTH_INFO info =
+ _gnutls_get_auth_info(state);
+ if (info == NULL)
+ return GNUTLS_E_INVALID_PARAMETERS;
+
+ pack_size = sizeof(ANON_CLIENT_AUTH_INFO_INT);
+ packed_session->size =
+ PACK_HEADER_SIZE + pack_size + sizeof(uint32);
+
+ packed_session->data[0] = GNUTLS_ANON;
+ WRITEuint32(pack_size,
+ &packed_session->
+ data[PACK_HEADER_SIZE]);
+ memcpy(&packed_session->
+ data[PACK_HEADER_SIZE + sizeof(uint32)],
+ info, sizeof(ANON_CLIENT_AUTH_INFO_INT));
+
+ }
+ break;
+ case GNUTLS_X509PKI:{
+ X509PKI_AUTH_INFO info =
+ _gnutls_get_auth_info(state);
+ if (info == NULL)
+ return GNUTLS_E_INVALID_PARAMETERS;
+
+ ret =
+ _gnutls_pack_x509pki_auth_info(info,
+ packed_session);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
+ break;
+ default:
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+
+ }
+
+ /* Auth_info structures copied. Now copy SecurityParameters.
+ */
+ packed_session->size += sizeof(SecurityParameters)+sizeof(uint32);
+
+ WRITEuint32( sizeof(SecurityParameters), &packed_session->data[packed_session->size - sizeof(SecurityParameters) - sizeof(uint32)]);
+ memcpy(&packed_session->
+ data[packed_session->size - sizeof(SecurityParameters)],
+ &state->security_parameters, sizeof(SecurityParameters));
+
+ return 0;
+}
+
+/* Returns the size needed to hold the current session.
+ */
+int _gnutls_session_size( GNUTLS_STATE state)
+{
+ uint32 pack_size;
+
+ pack_size = PACK_HEADER_SIZE + sizeof(uint32);
+
+ switch ( gnutls_get_auth_type(state)) {
+ case GNUTLS_SRP:
+ case GNUTLS_ANON:
+ pack_size += state->gnutls_key->auth_info_size;
+ case GNUTLS_X509PKI:
+ pack_size += _gnutls_pack_x509pki_auth_info_size( state);
+ }
+
+ /* Auth_info structures copied. Now copy SecurityParameters.
+ */
+ pack_size += sizeof(SecurityParameters) + sizeof(uint32);
+
+ return pack_size;
+}
+
+int _gnutls_session_unpack(GNUTLS_STATE state,
+ const gnutls_datum * packed_session)
+{
+ uint32 pack_size;
+ int ret;
+ uint32 timestamp = time(0);
+ SecurityParameters sp;
+
+ if (packed_session==NULL || packed_session->size == 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ }
+
+ if (state->gnutls_key->auth_info != NULL) {
+ _gnutls_free_auth_info( state);
+ }
+
+ switch (packed_session->data[0]) {
+ case GNUTLS_SRP:{
+
+ pack_size =
+ READuint32(&packed_session->
+ data[PACK_HEADER_SIZE]);
+
+
+ if (pack_size == 0) break;
+ if (pack_size != sizeof(SRP_SERVER_AUTH_INFO_INT)) {
+ gnutls_assert();
+ return GNUTLS_E_DB_ERROR;
+ }
+
+ state->gnutls_key->auth_info =
+ gnutls_calloc(1,
+ sizeof
+ (SRP_SERVER_AUTH_INFO_INT));
+ if (state->gnutls_key->auth_info == NULL)
+ return GNUTLS_E_MEMORY_ERROR;
+ state->gnutls_key->auth_info_size =
+ sizeof(SRP_SERVER_AUTH_INFO_INT);
+
+
+ memcpy(state->gnutls_key->auth_info,
+ &packed_session->data[PACK_HEADER_SIZE +
+ sizeof(uint32)],
+ sizeof(SRP_SERVER_AUTH_INFO_INT));
+ }
+ break;
+ case GNUTLS_ANON:{
+ pack_size =
+ READuint32(&packed_session->
+ data[PACK_HEADER_SIZE]);
+
+ if (pack_size == 0) break;
+
+ if (pack_size != sizeof(ANON_CLIENT_AUTH_INFO_INT)) {
+ gnutls_assert();
+ return GNUTLS_E_DB_ERROR;
+ }
+
+ state->gnutls_key->auth_info =
+ gnutls_calloc(1,
+ sizeof
+ (ANON_CLIENT_AUTH_INFO_INT));
+ if (state->gnutls_key->auth_info == NULL)
+ return GNUTLS_E_MEMORY_ERROR;
+ state->gnutls_key->auth_info_size =
+ sizeof(ANON_CLIENT_AUTH_INFO_INT);
+
+ memcpy(state->gnutls_key->auth_info,
+ &packed_session->data[PACK_HEADER_SIZE],
+ sizeof(ANON_CLIENT_AUTH_INFO_INT));
+ }
+ break;
+ case GNUTLS_X509PKI:{
+ pack_size =
+ READuint32(&packed_session->
+ data[PACK_HEADER_SIZE]);
+
+ if (pack_size == 0) break;
+
+ if (pack_size < sizeof(X509PKI_AUTH_INFO_INT)) {
+ gnutls_assert();
+ return GNUTLS_E_DB_ERROR;
+ }
+
+ state->gnutls_key->auth_info =
+ gnutls_calloc(1,
+ sizeof(X509PKI_AUTH_INFO_INT));
+ if (state->gnutls_key->auth_info == NULL)
+ return GNUTLS_E_MEMORY_ERROR;
+ state->gnutls_key->auth_info_size =
+ sizeof(X509PKI_AUTH_INFO_INT);
+
+ ret =
+ _gnutls_unpack_x509pki_auth_info(state->
+ gnutls_key->
+ auth_info,
+ packed_session);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ pack_size += ret;
+
+ }
+ break;
+ default:
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+
+ }
+
+ state->gnutls_key->auth_info_type = packed_session->data[0];
+
+ /* Auth_info structures copied. Now copy SecurityParameters.
+ */
+ ret =
+ READuint32(&packed_session->
+ data[PACK_HEADER_SIZE + sizeof(uint32) +
+ pack_size]);
+
+ if (ret != sizeof(SecurityParameters)) {
+ gnutls_assert();
+ return GNUTLS_E_DB_ERROR;
+ }
+ memcpy(&sp, &packed_session->data[PACK_HEADER_SIZE +
+ 2 * sizeof(uint32) + pack_size],
+ sizeof(SecurityParameters));
+
+ if ( timestamp - sp.timestamp <= state->gnutls_internals.expire_time
+ && sp.timestamp <= timestamp) {
+
+ memcpy( &state->gnutls_internals.resumed_security_parameters, &sp, sizeof(SecurityParameters));
+ } else {
+ _gnutls_free_auth_info( state);
+
+ return GNUTLS_E_EXPIRED;
+ }
+
+
+ return 0;
+}
+
+int _gnutls_pack_x509pki_auth_info(X509PKI_AUTH_INFO info,
+ gnutls_datum * packed_session)
+{
+ uint32 pack_size = sizeof(X509PKI_AUTH_INFO_INT) + info->raw_certificate.size;
+ packed_session->size =
+ pack_size + PACK_HEADER_SIZE + sizeof(uint32);
+
+ packed_session->data[0] = GNUTLS_X509PKI;
+ WRITEuint32(pack_size, &packed_session->data[PACK_HEADER_SIZE]);
+ memcpy(&packed_session->data[PACK_HEADER_SIZE + sizeof(uint32)],
+ info, sizeof(X509PKI_AUTH_INFO_INT));
+
+ if (info->raw_certificate.size > 0)
+ memcpy(&packed_session->data[PACK_HEADER_SIZE + sizeof(uint32) +
+ sizeof(X509PKI_AUTH_INFO_INT)], info->raw_certificate.data,
+ info->raw_certificate.size);
+
+ return 0;
+}
+
+static int _gnutls_pack_x509pki_auth_info_size( GNUTLS_STATE state)
+{
+ X509PKI_AUTH_INFO info =
+ _gnutls_get_auth_info(state);
+ uint32 pack_size = sizeof(X509PKI_AUTH_INFO_INT);
+
+ if (info == NULL)
+ return 0;
+
+ return pack_size + PACK_HEADER_SIZE + sizeof(uint32) + info->raw_certificate.size;
+}
+
+
+int _gnutls_unpack_x509pki_auth_info(X509PKI_AUTH_INFO info,
+ const gnutls_datum * packed_session)
+{
+int ret;
+
+ memcpy(info,
+ &packed_session->data[PACK_HEADER_SIZE + sizeof(uint32)],
+ sizeof(X509PKI_AUTH_INFO_INT));
+
+ if (info->raw_certificate.size > 0) {
+ ret = gnutls_set_datum( &info->raw_certificate,
+ &packed_session->data[PACK_HEADER_SIZE + sizeof(uint32) + sizeof(X509PKI_AUTH_INFO_INT)],
+ info->raw_certificate.size);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
+ return 0;
+}
diff --git a/lib/gnutls_session_pack.h b/lib/gnutls_session_pack.h
new file mode 100644
index 0000000000..580ace5cdb
--- /dev/null
+++ b/lib/gnutls_session_pack.h
@@ -0,0 +1,3 @@
+int _gnutls_session_pack( GNUTLS_STATE state, gnutls_datum* packed_session);
+int _gnutls_session_unpack( GNUTLS_STATE state, const gnutls_datum* packed_session);
+int _gnutls_session_size(GNUTLS_STATE state);
diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c
index 046d028e9c..7bb796b275 100644
--- a/lib/gnutls_ui.c
+++ b/lib/gnutls_ui.c
@@ -145,7 +145,7 @@ X509PKI_AUTH_INFO info;
CertificateStatus gnutls_x509pki_get_peer_certificate_status( GNUTLS_STATE state) {
X509PKI_AUTH_INFO info;
- CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_E_INVALID_REQUEST);
+ CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_CERT_NONE);
info = _gnutls_get_auth_info(state);
if (info==NULL) return GNUTLS_CERT_NONE;
@@ -153,6 +153,25 @@ X509PKI_AUTH_INFO info;
}
/**
+ * gnutls_x509pki_get_peer_certificate - This function returns the peer's raw (DER encoded) certificate
+ * @state: is a gnutls state
+ *
+ * This function will return the peer's raw certificate as sent by the peer.
+ * This certificate is DER encoded.
+ * Returns NULL in case of an error, or if no certificate was sent.
+ *
+ **/
+const gnutls_datum * gnutls_x509pki_get_peer_certificate( GNUTLS_STATE state) {
+X509PKI_AUTH_INFO info;
+
+ CHECK_AUTH(GNUTLS_X509PKI, NULL);
+
+ info = _gnutls_get_auth_info(state);
+ if (info==NULL) return NULL;
+ return &info->raw_certificate;
+}
+
+/**
* gnutls_x509pki_get_peer_certificate_version - This function returns the peer's certificate version
* @state: is a gnutls state
*
diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h
index e8d71fb178..27784f24d4 100644
--- a/lib/gnutls_ui.h
+++ b/lib/gnutls_ui.h
@@ -61,6 +61,7 @@ int gnutls_x509pki_set_cert_request( GNUTLS_STATE, CertificateRequest);
int gnutls_x509pki_get_certificate_request_status( GNUTLS_STATE);
const gnutls_DN* gnutls_x509pki_get_peer_dn( GNUTLS_STATE);
+const gnutls_datum* gnutls_x509pki_get_peer_certificate( GNUTLS_STATE);
const gnutls_DN* gnutls_x509pki_get_issuer_dn( GNUTLS_STATE);
CertificateStatus gnutls_x509pki_get_peer_certificate_status( GNUTLS_STATE);
int gnutls_x509pki_get_peer_certificate_version( GNUTLS_STATE);
@@ -76,6 +77,7 @@ int gnutls_x509pki_get_dh_bits( GNUTLS_STATE);
#define gnutls_x509pki_server_get_peer_dn gnutls_x509pki_get_peer_dn
#define gnutls_x509pki_server_get_issuer_dn gnutls_x509pki_get_issuer_dn
#define gnutls_x509pki_server_get_peer_certificate_status gnutls_x509pki_get_peer_certificate_status
+#define gnutls_x509pki_server_get_peer_certificate gnutls_x509pki_get_peer_certificate
#define gnutls_x509pki_server_get_peer_certificate_version gnutls_x509pki_get_peer_certificate_version
#define gnutls_x509pki_server_get_peer_certificate_activation_time gnutls_x509pki_get_peer_certificate_activation_time
#define gnutls_x509pki_server_get_peer_certificate_expiration_time gnutls_x509pki_get_peer_certificate_expiration_time
@@ -85,6 +87,7 @@ int gnutls_x509pki_get_dh_bits( GNUTLS_STATE);
#define gnutls_x509pki_client_get_peer_dn gnutls_x509pki_get_peer_dn
#define gnutls_x509pki_client_get_issuer_dn gnutls_x509pki_get_issuer_dn
#define gnutls_x509pki_client_get_peer_certificate_status gnutls_x509pki_get_peer_certificate_status
+#define gnutls_x509pki_client_get_peer_certificate gnutls_x509pki_get_peer_certificate
#define gnutls_x509pki_client_get_peer_certificate_version gnutls_x509pki_get_peer_certificate_version
#define gnutls_x509pki_client_get_peer_certificate_activation_time gnutls_x509pki_get_peer_certificate_activation_time
#define gnutls_x509pki_client_get_peer_certificate_expiration_time gnutls_x509pki_get_peer_certificate_expiration_time