summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/TODO3
-rw-r--r--lib/auth_anon.c5
-rw-r--r--lib/auth_rsa.c207
-rw-r--r--lib/auth_srp.c1
-rw-r--r--lib/auth_x509.h5
-rw-r--r--lib/gnutls.h.in12
-rw-r--r--lib/gnutls_algorithms.c156
-rw-r--r--lib/gnutls_algorithms.h15
-rw-r--r--lib/gnutls_auth.h1
-rw-r--r--lib/gnutls_handshake.c75
-rw-r--r--lib/gnutls_handshake.h1
-rw-r--r--lib/gnutls_int.h12
-rw-r--r--lib/gnutls_kx.c123
-rw-r--r--lib/gnutls_kx.h1
-rw-r--r--lib/gnutls_v2_compat.c2
-rw-r--r--src/cli.c15
-rw-r--r--src/serv.c37
17 files changed, 264 insertions, 407 deletions
diff --git a/doc/TODO b/doc/TODO
index b73be9d6eb..72b709b7c4 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -8,3 +8,6 @@
only one parse of the der structures.
* Create global variables that hold read/write and initialize
the ASN.1 parser's structures.
+* Create certificate verify function(s)
+* Add client side of RSA auth.
+
diff --git a/lib/auth_anon.c b/lib/auth_anon.c
index 1efd201d48..0f84020112 100644
--- a/lib/auth_anon.c
+++ b/lib/auth_anon.c
@@ -43,6 +43,7 @@ MOD_AUTH_STRUCT anon_auth_struct = {
gen_anon_client_kx,
NULL,
NULL,
+ NULL, /* certificate */
proc_anon_server_kx,
NULL,
NULL,
@@ -65,7 +66,7 @@ int _gnutls_generate_key(GNUTLS_KEY key) {
}
int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
- GNUTLS_MPI x, X, g, p;
+ MPI x, X, g, p;
int bits;
size_t n_X, n_g, n_p;
uint8 *data_p;
@@ -115,7 +116,7 @@ int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
}
int gen_anon_client_kx( GNUTLS_KEY key, opaque** data) {
-GNUTLS_MPI x, X;
+MPI x, X;
size_t n_X;
int ret;
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 5259359980..59a3219240 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -36,23 +36,26 @@
int gen_rsa_server_kx(GNUTLS_KEY, opaque **);
#endif
int gen_rsa_certificate(GNUTLS_KEY, opaque **);
+int gen_rsa_client_kx(GNUTLS_KEY, opaque **);
int proc_rsa_client_kx( GNUTLS_KEY, opaque*, int);
+int proc_rsa_certificate( GNUTLS_KEY, opaque*, int);
MOD_AUTH_STRUCT rsa_auth_struct = {
"RSA",
gen_rsa_certificate,
-/* not needed!!! gen_rsa_server_kx, */ NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- proc_rsa_client_kx,
- NULL,
- NULL
+ NULL, /* gen server kx */
+ NULL, /* gen server kx2 */
+ NULL, /* gen client kx0 */
+ gen_rsa_client_kx,
+ NULL, /* gen client cert vrfy */
+ NULL, /* gen server cert vrfy */
+ proc_rsa_certificate,
+ NULL, /* proc server kx */
+ NULL, /* proc server kx2 */
+ NULL, /* proc client kx0 */
+ proc_rsa_client_kx, /* proc client kx */
+ NULL, /* proc client cert vrfy */
+ NULL /* proc server cert vrfy */
};
typedef struct {
@@ -60,6 +63,7 @@ typedef struct {
gnutls_datum rsa_exponent;
} RSA_Params;
+#if 0
/* This function will calculate the SHA/MD5 signature in server kx.
* This is needed by the protocol.
*/
@@ -107,45 +111,47 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
return ret;
}
+#endif
-#if 0
-/* This function reads the RSA parameters from the given(?) certificate.
+/* This function extracts the RSA parameters from the given(?) certificate.
*/
-static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_datum cert)
+static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, MPI* mod, MPI* exp, gnutls_datum cert)
{
int ret = 0, result;
opaque str[5*1024];
int len = sizeof(str);
- if (create_structure("certificate2", "PKIX1Explicit88.Certificate")!=ASN_OK) {
+ if (create_structure("rsa_params", "PKIX1Explicit88.Certificate")!=ASN_OK) {
gnutls_assert();
return GNUTLS_E_PARSING_ERROR;
}
- result = get_der("certificate2", cert.data, cert.size);
+ result = get_der("rsa_params", cert.data, cert.size);
if (result != ASN_OK) {
+ /* couldn't decode DER */
gnutls_assert();
return GNUTLS_E_PARSING_ERROR;
}
- /* Verify sign */
+
result =
- read_value("certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm", str, &len);
+ read_value("rsa_params.tbsCertificate.subjectPublicKeyInfo.algorithm", str, &len);
if (result != ASN_OK) {
+fprintf(stderr, "resut: %d\n", result);
gnutls_assert();
- delete_structure("certificate2");
+ delete_structure("rsa_params");
return GNUTLS_E_PARSING_ERROR;
}
if (!strcmp(str, "1 2 840 113549 1 1 1")) { /* pkix-1 1 - RSA */
len = sizeof(str);
result =
- read_value("certificate2.tbsCertificate.subjectPublicKeyInfo.parameters", str, &len);
- delete_structure("certificate2");
+ read_value("rsa_params.tbsCertificate.subjectPublicKeyInfo.parameters", str, &len);
+ delete_structure("rsa_params");
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("certificate2");
+ delete_structure("rsa_params");
return GNUTLS_E_PARSING_ERROR;
}
@@ -169,17 +175,19 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
return GNUTLS_E_PARSING_ERROR;
}
- if (gcry_mpi_scan(&key->A,
+ if (gcry_mpi_scan(mod,
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
delete_structure("rsapublickey");
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (gnutls_set_datum(&params->rsa_modulus, str, len) < 0) {
- gnutls_assert();
- delete_structure("rsapublickey");
- return GNUTLS_E_MEMORY_ERROR;
- }
+
+ if (params!=NULL)
+ if (gnutls_set_datum(&params->rsa_modulus, str, len) < 0) {
+ gnutls_assert();
+ delete_structure("rsapublickey");
+ return GNUTLS_E_MEMORY_ERROR;
+ }
len = sizeof(str);
result =
@@ -187,22 +195,23 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
if (result != ASN_OK) {
gnutls_assert();
delete_structure("rsapublickey");
- gnutls_free_datum(&params->rsa_modulus);
- _gnutls_mpi_release(&key->A);
+ if (params!=NULL) gnutls_free_datum(&params->rsa_modulus);
+ _gnutls_mpi_release(mod);
return GNUTLS_E_PARSING_ERROR;
}
- if (gcry_mpi_scan(&key->B,
+ if (gcry_mpi_scan(exp,
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
- _gnutls_mpi_release(&key->A);
- gnutls_free_datum(&params->rsa_modulus);
+ _gnutls_mpi_release(mod);
+ if (params!=NULL) gnutls_free_datum(&params->rsa_modulus);
delete_structure("rsapublickey");
return GNUTLS_E_MPI_SCAN_FAILED;
}
if (gnutls_set_datum(&params->rsa_exponent, str, len) < 0) {
- _gnutls_mpi_release(&key->A);
- gnutls_free_datum(&params->rsa_modulus);
+ _gnutls_mpi_release(mod);
+ _gnutls_mpi_release(exp);
+ if (params!=NULL) gnutls_free_datum(&params->rsa_modulus);
delete_structure("rsapublickey");
return GNUTLS_E_MEMORY_ERROR;
}
@@ -211,11 +220,10 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
}
- delete_structure("certificate2");
+ delete_structure("rsa_params");
return ret;
}
-#endif
/* This function reads the RSA parameters from the given private key
* cert is not a certificate but a der structure containing the private
@@ -442,3 +450,126 @@ int proc_rsa_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
return 0;
}
+int proc_rsa_certificate( GNUTLS_KEY key, opaque* data, int data_size) {
+int size, len;
+opaque* p = data;
+X509PKI_AUTH_INFO* info;
+int dsize = data_size;
+int i, j;
+
+ key->auth_info = gnutls_calloc(1, sizeof(X509PKI_AUTH_INFO));
+ if (key->auth_info==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ key->auth_info_size = sizeof(X509PKI_AUTH_INFO);
+
+ DECR_LEN( dsize, 3);
+ size = READuint24( p);
+ p+=3;
+
+ if (size==0) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+
+ info = key->auth_info;
+ i = dsize;
+
+ len=READuint24(p); p+=3;
+
+ for(; i > 0; len=READuint24(p),p+=3) {
+ DECR_LEN(dsize, (len+3));
+ info->peer_certificate_list_size++;
+ p+=len;
+ i-=len+3;
+ }
+
+ if (info->peer_certificate_list_size==0) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+
+ dsize = data_size;
+ i = dsize;
+ info->peer_certificate_list = gnutls_malloc(sizeof(gnutls_datum)*(info->peer_certificate_list_size));
+ if (info->peer_certificate_list==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ p = data+3;
+ i = data_size - 3;
+ j = 0;
+
+ len=READuint24(p); p+=3;
+ for(; i > 0; len=READuint24(p), p+=3) {
+ if ( j >= info->peer_certificate_list_size) break;
+
+ info->peer_certificate_list[j].size = len;
+ info->peer_certificate_list[j].data = gnutls_malloc(len);
+ if (info->peer_certificate_list[j].data==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ memcpy( info->peer_certificate_list[j].data, p, len);
+ p+=len;
+ i-=len+3;
+ j++;
+ }
+
+
+#warning "WE DO NOT VERIFY RSA CERTIFICATES"
+ /* FIXME: Verify certificate
+ */
+ info->peer_certificate_status = GNUTLS_NOT_VERIFIED;
+
+ return 0;
+}
+
+/* return RSA(random) using the peers public key
+ */
+int gen_rsa_client_kx(GNUTLS_KEY key, opaque ** data)
+{
+ X509PKI_AUTH_INFO *auth = key->auth_info;
+ svoid *rand;
+ gnutls_datum sdata; /* data to send */
+ gnutls_datum edata; /* data to encrypt */
+ MPI pkey, n;
+ int ret;
+
+ if (auth == NULL) {
+ /* this shouldn't have happened. The proc_certificate
+ * function should have detected that.
+ */
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ rand = secure_malloc( TLS_MASTER_SIZE);
+ if (rand==NULL)
+ return GNUTLS_E_MEMORY_ERROR;
+
+ _gnutls_get_random( rand, TLS_MASTER_SIZE, GNUTLS_STRONG_RANDOM);
+
+ key->key.data = rand;
+ key->key.size = TLS_MASTER_SIZE;
+
+ edata.data = rand;
+ edata.size = TLS_MASTER_SIZE;
+
+ if ( (ret=_gnutls_get_rsa_params( key, NULL, &n, &pkey, auth->peer_certificate_list[0])) < 0 ) {
+ gnutls_assert();
+ return ret;
+ }
+
+ _gnutls_pkcs1_rsa_encrypt( &sdata, edata, pkey, n);
+
+ secure_free(rand);
+ _gnutls_mpi_release(&pkey);
+ _gnutls_mpi_release(&n);
+
+ *data = sdata.data;
+ return sdata.size;
+}
diff --git a/lib/auth_srp.c b/lib/auth_srp.c
index 5a15f7cec5..ee1ff3a8ff 100644
--- a/lib/auth_srp.c
+++ b/lib/auth_srp.c
@@ -45,6 +45,7 @@ MOD_AUTH_STRUCT srp_auth_struct = {
NULL,
NULL,
NULL,
+ NULL, /* certificate */
proc_srp_server_kx,
proc_srp_server_kx2,
proc_srp_client_kx0,
diff --git a/lib/auth_x509.h b/lib/auth_x509.h
index 7f68294067..981cc0348c 100644
--- a/lib/auth_x509.h
+++ b/lib/auth_x509.h
@@ -27,6 +27,9 @@ typedef struct {
int ne;
} X509PKI_CLIENT_CREDENTIALS;
+
typedef struct {
- int ne;
+ gnutls_datum *peer_certificate_list; /* In DER format */
+ int peer_certificate_list_size;
+ CertificateStatus peer_certificate_status;
} X509PKI_AUTH_INFO;
diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in
index 9283d26f0f..93b9a365d3 100644
--- a/lib/gnutls.h.in
+++ b/lib/gnutls.h.in
@@ -145,6 +145,18 @@ typedef struct {
int dh_bits;
} ANON_AUTH_INFO;
+typedef enum verified { GNUTLS_VERIFIED, GNUTLS_NOT_VERIFIED, GNUTLS_EXPIRED, GNUTLS_INVALID } CertificateStatus;
+
+typedef struct {
+ gnutls_datum *peer_certificate_list; /* In DER format */
+ int peer_certificate_list_size;
+ CertificateStatus peer_certificate_status;
+} X509PKI_AUTH_INFO;
+
+typedef struct {
+ int ne; /* nothing of interest here */
+} X509PKI_CLIENT_CREDENTIALS;
+
typedef struct {
gnutls_datum ** cert_list;
/* contains a list of a list of certificates.
diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c
index e9314f39ae..790d869743 100644
--- a/lib/gnutls_algorithms.c
+++ b/lib/gnutls_algorithms.c
@@ -174,30 +174,20 @@ static const gnutls_compression_entry compression_algorithms[] = {
/* Key Exchange Section */
-#define GNUTLS_KX_ALGO_ENTRY(name, server_cert, client_cert, RSA_premaster, DH_public_value, auth_struct) \
- { #name, name, server_cert, client_cert, RSA_premaster, DH_public_value, auth_struct }
+#define GNUTLS_KX_ALGO_ENTRY(name, auth_struct) \
+ { #name, name, auth_struct }
struct gnutls_kx_algo_entry {
char *name;
KXAlgorithm algorithm;
- int server_cert;
- int client_cert;
- int RSA_premaster;
- int DH_public_value;
MOD_AUTH_STRUCT *auth_struct;
};
typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
static const gnutls_kx_algo_entry kx_algorithms[] = {
- GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_ANON, 0, 0, 0, 1,
- &anon_auth_struct),
- GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, &rsa_auth_struct),
-/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_DSS, 1, 1, 0, 0,
- &dhe_dss_auth_struct),*/
-/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 0, 0, NULL),*/
-/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_DSS, 1, 1, 0, 0, NULL),*/
-/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_RSA, 1, 1, 0, 0, NULL),*/
- GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_SRP, 0, 0, 0, 0, &srp_auth_struct),
+ GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_ANON, &anon_auth_struct),
+ GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, &rsa_auth_struct),
+ GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_SRP, &srp_auth_struct),
{0}
};
@@ -688,14 +678,6 @@ int _gnutls_cipher_is_ok(BulkCipherAlgorithm algorithm)
/* Key EXCHANGE functions */
-int _gnutls_kx_server_certificate(KXAlgorithm algorithm)
-{
- size_t ret = 0;
- GNUTLS_KX_ALG_LOOP(ret = p->server_cert);
- return ret;
-
-}
-
MOD_AUTH_STRUCT *_gnutls_kx_auth_struct(KXAlgorithm algorithm)
{
MOD_AUTH_STRUCT *ret = NULL;
@@ -717,134 +699,6 @@ inline int _gnutls_kx_priority(GNUTLS_STATE state, KXAlgorithm algorithm)
return -1;
}
-int _gnutls_kx_server_key_exchange(KXAlgorithm algorithm)
-{
- size_t ret = 0;
- void *ret2 = NULL;
-
- /* if the auth algorithm does not have a null value
- * for the kx2 generation then it supports it!
- */
- GNUTLS_KX_ALG_LOOP(ret2 =
- p->auth_struct->gnutls_generate_server_kx);
- if (ret2 != NULL)
- ret = 1;
-
- return ret;
-
-}
-
-int _gnutls_kx_server_key_exchange2(KXAlgorithm algorithm)
-{
- size_t ret = 0;
- void *ret2 = NULL;
-
- /* if the auth algorithm does not have a null value
- * for the kx2 generation then it supports it!
- */
- GNUTLS_KX_ALG_LOOP(ret2 =
- p->auth_struct->gnutls_generate_server_kx2);
- if (ret2 != NULL)
- ret = 1;
-
- return ret;
-
-}
-
-int _gnutls_kx_client_key_exchange0(KXAlgorithm algorithm)
-{
- size_t ret = 0;
- void *ret2 = NULL;
-
- /* if the auth algorithm does not have a null value
- * for the kx0 generation then it supports it!
- */
- GNUTLS_KX_ALG_LOOP(ret2 =
- p->auth_struct->gnutls_process_client_kx0);
- if (ret2 != NULL)
- ret = 1;
-
- return ret;
-
-}
-
-int _gnutls_kx_client_key_exchange(KXAlgorithm algorithm)
-{
- size_t ret = 0;
- void *ret2 = NULL;
-
- /* if the auth algorithm does not have a null value
- * for the kx0 generation then it supports it!
- */
- GNUTLS_KX_ALG_LOOP(ret2 =
- p->auth_struct->gnutls_process_client_kx);
- if (ret2 != NULL)
- ret = 1;
- return ret;
-
-}
-
-
-int _gnutls_kx_client_cert_vrfy(KXAlgorithm algorithm)
-{
- size_t ret = 0;
- void *ret2 = NULL;
-
- /* if the auth algorithm does not have a null value
- * for the cert_vrfy function then it supports it!
- */
- GNUTLS_KX_ALG_LOOP(ret2 =
- p->auth_struct->
- gnutls_generate_client_cert_vrfy);
- if (ret2 != NULL)
- ret = 1;
-
- return ret;
-
-}
-
-int _gnutls_kx_server_cert_vrfy(KXAlgorithm algorithm)
-{
- size_t ret = 0;
- void *ret2 = NULL;
-
- /* if the auth algorithm does not have a null value
- * for the cert_vrfy function then it supports it!
- */
- GNUTLS_KX_ALG_LOOP(ret2 =
- p->auth_struct->
- gnutls_generate_server_cert_vrfy);
- if (ret2 != NULL)
- ret = 1;
-
- return ret;
-
-}
-
-int _gnutls_kx_client_certificate(KXAlgorithm algorithm)
-{ /* In bytes */
- size_t ret = 0;
- GNUTLS_KX_ALG_LOOP(ret = p->client_cert);
- return ret;
-
-}
-
-int _gnutls_kx_RSA_premaster(KXAlgorithm algorithm)
-{ /* In bytes */
- size_t ret = 0;
- GNUTLS_KX_ALG_LOOP(ret = p->RSA_premaster);
- return ret;
-
-}
-
-int _gnutls_kx_DH_public_value(KXAlgorithm algorithm)
-{ /* In bytes */
- size_t ret = 0;
- GNUTLS_KX_ALG_LOOP(ret = p->DH_public_value);
- return ret;
-
-}
-
/**
* gnutls_kx_get_name - Returns a string with the name of the specified key exchange algorithm
* @algorithm: is a key exchange algorithm
diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h
index a0186eb837..ec1014c099 100644
--- a/lib/gnutls_algorithms.h
+++ b/lib/gnutls_algorithms.h
@@ -58,21 +58,6 @@ char *gnutls_cipher_get_name(BulkCipherAlgorithm algorithm);
/* functions for key exchange */
int _gnutls_kx_priority(GNUTLS_STATE state, KXAlgorithm algorithm);
-int _gnutls_kx_server_certificate(KXAlgorithm algorithm);
-
-/* key exchange */
-int _gnutls_kx_server_key_exchange(KXAlgorithm algorithm);
-int _gnutls_kx_server_key_exchange2(KXAlgorithm algorithm);
-int _gnutls_kx_client_key_exchange(KXAlgorithm algorithm);
-int _gnutls_kx_client_key_exchange0(KXAlgorithm algorithm);
-/* client certificate */
-int _gnutls_kx_client_certificate(KXAlgorithm algorithm);
-int _gnutls_kx_RSA_premaster(KXAlgorithm algorithm);
-int _gnutls_kx_DH_public_value(KXAlgorithm algorithm);
-
-/* cert vrfy */
-int _gnutls_kx_client_cert_vrfy(KXAlgorithm algorithm);
-int _gnutls_kx_server_cert_vrfy(KXAlgorithm algorithm);
MOD_AUTH_STRUCT * _gnutls_kx_auth_struct(KXAlgorithm algorithm);
char *gnutls_kx_get_name(KXAlgorithm algorithm);
diff --git a/lib/gnutls_auth.h b/lib/gnutls_auth.h
index c673e2598b..bffd973ff5 100644
--- a/lib/gnutls_auth.h
+++ b/lib/gnutls_auth.h
@@ -10,6 +10,7 @@ typedef struct {
int (*gnutls_generate_client_cert_vrfy) ( GNUTLS_KEY, opaque**);
int (*gnutls_generate_server_cert_vrfy) ( GNUTLS_KEY, opaque**);
+ int (*gnutls_process_certificate)( GNUTLS_KEY, opaque*, int);
int (*gnutls_process_server_kx)( GNUTLS_KEY, opaque*, int);
int (*gnutls_process_server_kx2)( GNUTLS_KEY, opaque*, int);
int (*gnutls_process_client_kx0)( GNUTLS_KEY, opaque*, int);
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index f268270941..0c15b74a4a 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -227,8 +227,6 @@ int _gnutls_create_random(opaque * dst)
* since SSL version 2.0 is not supported).
*/
-#define DECR_LEN(len, x) len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;}
-
int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
int datalen)
{
@@ -600,23 +598,6 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
int handshake_headers = HANDSHAKE_HEADERS_SIZE;
HandshakeType recv_type;
- if (type == GNUTLS_CERTIFICATE) {
- /* If the ciphersuite does not support certificate just quit */
- if (state->security_parameters.entity == GNUTLS_CLIENT) {
- if (_gnutls_kx_server_certificate
- (_gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.
- current_cipher_suite)) == 0)
- return 0;
- } else { /* server */
- if (_gnutls_kx_client_certificate
- (_gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.
- current_cipher_suite)) == 0)
- return 0;
- }
- }
-
dataptr = gnutls_malloc(HANDSHAKE_HEADERS_SIZE);
ret =
@@ -728,11 +709,7 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
length32);
break;
case GNUTLS_CERTIFICATE:
- ret =
- _gnutls_recv_certificate(cd, state,
- &dataptr
- [HANDSHAKE_HEADERS_SIZE],
- length32);
+ ret = length32;
break;
case GNUTLS_SERVER_HELLO_DONE:
ret = 0;
@@ -929,7 +906,8 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
current_cipher_suite));
#endif
- /* check if the credentials (username, public key etc. are ok - actually check if they exist)
+ /* check if the credentials (username, public key etc. are ok).
+ * Actually checks if they exist.
*/
if (_gnutls_get_kx_cred
(state->gnutls_key,
@@ -1202,48 +1180,6 @@ int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data,
return ret;
}
-int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state, char *data,
- int datalen)
-{
- int pos = 0;
- char *certificate_list;
- int ret = 0;
- uint32 sizeOfCert;
-
- if (state->security_parameters.entity == GNUTLS_CLIENT) {
- if (datalen < 2) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
-
- sizeOfCert = READuint24(&data[pos]);
- pos += 3;
-
- if (sizeOfCert > MAX24) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
- certificate_list = gnutls_malloc(sizeOfCert);
-
- memcpy(certificate_list, &data[pos], sizeOfCert);
-
- /* Verify certificates !!! */
-
- gnutls_free(certificate_list); /* oooops! */
-
- } else { /* Server side reading a client certificate */
- /* actually this is not complete */
- if (datalen < 1) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
-
- ret = 0;
- }
-
- return ret;
-}
-
/**
* gnutls_handshake - This the main function in the handshake protocol.
@@ -1322,10 +1258,9 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
/* RECV CERTIFICATE */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_recv_handshake(cd, state, NULL, NULL,
- GNUTLS_CERTIFICATE);
+ ret = _gnutls_recv_certificate( cd, state);
if (ret < 0) {
+ gnutls_assert();
ERR("recv server certificate", ret);
gnutls_clearHashDataBuffer(state);
return ret;
diff --git a/lib/gnutls_handshake.h b/lib/gnutls_handshake.h
index cbdbf5def0..81c041d1ec 100644
--- a/lib/gnutls_handshake.h
+++ b/lib/gnutls_handshake.h
@@ -26,7 +26,6 @@ int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char* data, int datalen);
int gnutls_handshake(int cd, GNUTLS_STATE state);
int _gnutls_recv_handshake( int cd, GNUTLS_STATE state, uint8**, int*, HandshakeType);
int _gnutls_generate_session_id( char* session_id, uint8* len);
-int _gnutls_recv_certificate(int cd, GNUTLS_STATE state, char *data, int datalen);
int gnutls_handshake_begin(int cd, GNUTLS_STATE state);
int gnutls_handshake_finish(int cd, GNUTLS_STATE state);
void _gnutls_set_server_random( GNUTLS_STATE state, uint8* random);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 7c25b6d3cf..b1e24ac9ad 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -27,11 +27,11 @@
#define READ_DEBUG
#define WRITE_DEBUG
#define BUFFERS_DEBUG
-#define HANDSHAKE_DEBUG
#define RECORD_DEBUG
#define HARD_DEBUG
-#define DEBUG
+#define HANDSHAKE_DEBUG
*/
+#define DEBUG
#define SOCKET int
#define LIST ...
@@ -63,9 +63,6 @@
# include <gnutls_gcry.h>
#endif
-#define GNUTLS_MPI MPI
-#define gnutls_mpi_release mpi_release
-
#define svoid void /* for functions that allocate using secure_free */
#define secure_free gnutls_free
#define secure_malloc malloc
@@ -76,6 +73,8 @@
#define gnutls_calloc calloc
#define gnutls_free free
+#define DECR_LEN(len, x) len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;}
+
typedef unsigned char opaque;
typedef struct { opaque pint[3]; } uint24;
@@ -91,7 +90,8 @@ typedef enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=1
GNUTLS_INSUFFICIENT_SECURITY, GNUTLS_INTERNAL_ERROR=80, GNUTLS_USER_CANCELED=90,
GNUTLS_NO_RENEGOTIATION=100
} AlertDescription;
-
+typedef enum CertificateStatus { GNUTLS_VERIFIED, GNUTLS_NOT_VERIFIED, GNUTLS_EXPIRED, GNUTLS_INVALID } CertificateStatus;
+
typedef enum HandshakeType { GNUTLS_HELLO_REQUEST, GNUTLS_CLIENT_HELLO, GNUTLS_SERVER_HELLO,
GNUTLS_CERTIFICATE=11, GNUTLS_SERVER_KEY_EXCHANGE,
GNUTLS_CERTIFICATE_REQUEST, GNUTLS_SERVER_HELLO_DONE,
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index 261ece77d1..406075302f 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -30,7 +30,6 @@
#define MASTER_SECRET "master secret"
static int generate_normal_master( GNUTLS_STATE state);
-static int generate_resumed_master( GNUTLS_STATE state);
int _gnutls_generate_master( GNUTLS_STATE state) {
if (state->gnutls_internals.resumed==RESUME_FALSE)
@@ -85,50 +84,6 @@ char random[2*TLS_RANDOM_SIZE];
return ret;
}
-static int generate_resumed_master( GNUTLS_STATE state) {
-int premaster_size;
-#ifdef HARD_DEBUG
-int i;
-#endif
-opaque* premaster, *master;
-int ret = 0;
-char random[2*TLS_RANDOM_SIZE];
-
- memmove(random, state->security_parameters.client_random, TLS_RANDOM_SIZE);
- memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.server_random, TLS_RANDOM_SIZE);
-
- /* generate premaster */
- premaster_size = sizeof(state->security_parameters.master_secret);
- premaster = state->security_parameters.master_secret;
-
-#ifdef HARD_DEBUG
- fprintf(stderr, "RESUME...\n");
- fprintf(stderr, "PREMASTER SECRET[%d]: %s\n", premaster_size, _gnutls_bin2hex(premaster, premaster_size));
- fprintf(stderr, "CLIENT RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.client_random,32));
- fprintf(stderr, "SERVER RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.server_random,32));
-#endif
-
- if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
- master =
- gnutls_ssl3_generate_random( premaster, premaster_size,
- random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
-
- } else {
- master =
- gnutls_PRF( premaster, premaster_size,
- MASTER_SECRET, strlen(MASTER_SECRET),
- random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
- }
-
-#ifdef HARD_DEBUG
- fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, TLS_MASTER_SIZE));
-#endif
- if (master==NULL) return GNUTLS_E_MEMORY_ERROR;
-
- memmove(state->security_parameters.master_secret, master, TLS_MASTER_SIZE);
- secure_free(master);
- return ret;
-}
/* This is called when we want to receive the key exchange message of the
* server. It does nothing if this type of message is not required
@@ -171,12 +126,8 @@ int _gnutls_send_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
uint8 *data = NULL;
int data_size = 0;
int ret = 0;
- KXAlgorithm algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
-
- if (_gnutls_kx_server_key_exchange2(algorithm) != 0) {
+ if (state->gnutls_internals.auth_struct->gnutls_generate_server_kx2 != NULL) {
data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx2( state->gnutls_key, &data);
#ifdef HARD_DEBUG
@@ -207,11 +158,9 @@ int _gnutls_send_client_kx_message(SOCKET cd, GNUTLS_STATE state)
uint8 *data;
int data_size;
int ret = 0;
- KXAlgorithm algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
- if (_gnutls_kx_client_key_exchange(algorithm) == 0) return 0;
+ if (state->gnutls_internals.auth_struct->gnutls_generate_client_kx==NULL)
+ return 0;
#ifdef HARD_DEBUG
{
@@ -220,7 +169,6 @@ int _gnutls_send_client_kx_message(SOCKET cd, GNUTLS_STATE state)
}
#endif
-
data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_kx( state->gnutls_key, &data);
if (data_size < 0) {
gnutls_assert();
@@ -245,11 +193,9 @@ int _gnutls_send_client_kx_message0(SOCKET cd, GNUTLS_STATE state)
uint8 *data;
int data_size;
int ret = 0;
- KXAlgorithm algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
- if (_gnutls_kx_client_key_exchange0(algorithm) == 0) return 0;
+ if ( state->gnutls_internals.auth_struct->gnutls_generate_client_kx0 == NULL)
+ return 0;
#ifdef HARD_DEBUG
{
@@ -281,14 +227,11 @@ int _gnutls_send_client_certificate_verify(SOCKET cd, GNUTLS_STATE state)
uint8 *data;
int ret = 0;
int data_size;
- KXAlgorithm algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
/* if certificate verify is not needed just exit */
if (state->gnutls_internals.certificate_verify_needed==0) return 0;
- if (_gnutls_kx_client_cert_vrfy(algorithm)==0) {
+ if (state->gnutls_internals.auth_struct->gnutls_generate_client_cert_vrfy==NULL) {
return 0; /* this algorithm does not support cli_cert_vrfy */
}
@@ -310,7 +253,6 @@ int _gnutls_send_client_certificate_verify(SOCKET cd, GNUTLS_STATE state)
int _gnutls_recv_server_kx_message(SOCKET cd, GNUTLS_STATE state)
{
- KXAlgorithm algorithm;
uint8 *data;
int datasize;
int ret = 0;
@@ -318,11 +260,8 @@ int _gnutls_recv_server_kx_message(SOCKET cd, GNUTLS_STATE state)
#ifdef HARD_DEBUG
fprintf(stderr, "Receiving Server KX message\n");
#endif
- algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
- if (_gnutls_kx_server_key_exchange(algorithm) != 0) {
+ if (state->gnutls_internals.auth_struct->gnutls_process_server_kx!=NULL) {
ret =
_gnutls_recv_handshake(cd, state, &data,
&datasize,
@@ -342,7 +281,6 @@ int _gnutls_recv_server_kx_message(SOCKET cd, GNUTLS_STATE state)
int _gnutls_recv_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
{
- KXAlgorithm algorithm;
uint8 *data;
int datasize;
int ret = 0;
@@ -350,11 +288,8 @@ int _gnutls_recv_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
#ifdef HARD_DEBUG
fprintf(stderr, "Receiving Server KX message2\n");
#endif
- algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
- if (_gnutls_kx_server_key_exchange2(algorithm) != 0) {
+ if (state->gnutls_internals.auth_struct->gnutls_process_server_kx2 != NULL) {
ret =
_gnutls_recv_handshake(cd, state, &data,
&datasize,
@@ -374,7 +309,6 @@ int _gnutls_recv_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
int _gnutls_recv_client_kx_message(SOCKET cd, GNUTLS_STATE state)
{
- KXAlgorithm algorithm;
uint8 *data;
#ifdef HARD_DEBUG
int i;
@@ -386,12 +320,8 @@ int _gnutls_recv_client_kx_message(SOCKET cd, GNUTLS_STATE state)
fprintf(stderr, "Receiving client KX message\n");
#endif
- algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
-
/* Do key exchange only if the algorithm permits it */
- if (_gnutls_kx_client_key_exchange(algorithm) != 0) {
+ if (state->gnutls_internals.auth_struct->gnutls_process_client_kx != NULL) {
ret =
_gnutls_recv_handshake(cd, state, &data,
@@ -413,7 +343,6 @@ int _gnutls_recv_client_kx_message(SOCKET cd, GNUTLS_STATE state)
/* only used in SRP */
int _gnutls_recv_client_kx_message0(SOCKET cd, GNUTLS_STATE state)
{
- KXAlgorithm algorithm;
uint8 *data;
#ifdef HARD_DEBUG
int i;
@@ -425,12 +354,8 @@ int _gnutls_recv_client_kx_message0(SOCKET cd, GNUTLS_STATE state)
fprintf(stderr, "Receiving client KX message0\n");
#endif
- algorithm =
- _gnutls_cipher_suite_get_kx_algo
- (state->security_parameters.current_cipher_suite);
-
/* Do key exchange only if the algorithm permits it */
- if (_gnutls_kx_client_key_exchange0(algorithm) != 0) {
+ if (state->gnutls_internals.auth_struct->gnutls_process_client_kx0 != NULL) {
ret =
_gnutls_recv_handshake(cd, state, &data,
@@ -481,3 +406,31 @@ int _gnutls_send_certificate(SOCKET cd, GNUTLS_STATE state)
return data_size;
}
+
+int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state)
+{
+ int datasize;
+ opaque * data;
+ int ret = 0;
+
+ if (state->gnutls_internals.auth_struct->gnutls_process_certificate!=NULL) {
+
+ ret =
+ _gnutls_recv_handshake(cd, state, &data,
+ &datasize,
+ GNUTLS_CERTIFICATE);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ ret = state->gnutls_internals.auth_struct->gnutls_process_certificate( state->gnutls_key, data, datasize);
+ gnutls_free(data);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
+
+ return ret;
+}
diff --git a/lib/gnutls_kx.h b/lib/gnutls_kx.h
index 68ab4a3b9e..3a3b2e54b8 100644
--- a/lib/gnutls_kx.h
+++ b/lib/gnutls_kx.h
@@ -29,3 +29,4 @@ int _gnutls_recv_client_kx_message0(int cd, GNUTLS_STATE state);
int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state);
int _gnutls_send_certificate(int cd, GNUTLS_STATE state);
int _gnutls_generate_master( GNUTLS_STATE state);
+int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state);
diff --git a/lib/gnutls_v2_compat.c b/lib/gnutls_v2_compat.c
index f441baee8c..d4c4bfe098 100644
--- a/lib/gnutls_v2_compat.c
+++ b/lib/gnutls_v2_compat.c
@@ -94,8 +94,6 @@ static int SelectSuite_v2(GNUTLS_STATE state, opaque ret[2], char *data,
}
-#define DECR_LEN(len, x) len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;}
-
/* Read a v2 client hello. Some browsers still use that beast!
* However they set their version to 3.0 or 3.1.
*/
diff --git a/src/cli.c b/src/cli.c
index 11b22c4294..4a7249ee40 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -40,6 +40,8 @@
#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;
@@ -87,11 +89,14 @@ int main()
struct timeval tv;
int user_term = 0;
SRP_CLIENT_CREDENTIALS cred;
-
+ X509PKI_CLIENT_CREDENTIALS xcred;
+
+ PARSE();
+
cred.username = "test";
cred.password = "test";
-// signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
sd = socket(AF_INET, SOCK_STREAM, 0);
ERR(sd, "socket");
@@ -110,9 +115,10 @@ int main()
gnutls_set_cipher_priority( state, GNUTLS_3DES_CBC, GNUTLS_ARCFOUR, GNUTLS_RIJNDAEL_CBC, 0);
gnutls_set_compression_priority( state, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION, 0);
- gnutls_set_kx_priority( state, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0);
+ gnutls_set_kx_priority( state, GNUTLS_KX_RSA, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0);
gnutls_set_cred( state, GNUTLS_ANON, NULL);
gnutls_set_cred( state, GNUTLS_SRP, &cred);
+ gnutls_set_cred( state, GNUTLS_X509PKI, &xcred);
gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);
ret = gnutls_handshake(sd, state);
@@ -158,9 +164,10 @@ int main()
gnutls_set_cipher_priority( state, GNUTLS_3DES_CBC, GNUTLS_TWOFISH_CBC, GNUTLS_RIJNDAEL_CBC, GNUTLS_ARCFOUR, 0);
gnutls_set_compression_priority( state, GNUTLS_NULL_COMPRESSION, 0);
- gnutls_set_kx_priority( state, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0);
+ gnutls_set_kx_priority( state, GNUTLS_KX_RSA, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0);
gnutls_set_cred( state, GNUTLS_ANON, NULL);
gnutls_set_cred( state, GNUTLS_SRP, &cred);
+ gnutls_set_cred( state, GNUTLS_X509PKI, &xcred);
gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);
diff --git a/src/serv.c b/src/serv.c
index 24091ac960..8cfb019fe8 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -30,9 +30,8 @@
#include "../lib/gnutls.h"
#include <port.h>
#include <signal.h>
+#include "pk.h"
-#define PKIX "pkix.asn"
-#define PKCS "pkcs1.asn"
#define KEYFILE "key.pem"
#define CERTFILE "cert.pem"
@@ -46,32 +45,6 @@ static char http_buffer[16*1024];
* command line is present
*/
-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;
- }
-
-}
#define SA struct sockaddr
#define ERR(err,s) if(err==-1) {perror(s);return(1);}
@@ -114,12 +87,12 @@ GNUTLS_STATE initialize_state()
gnutls_init(&state, GNUTLS_SERVER);
if ((ret = gnutls_set_db_name(state, "gnutls-rsm.db")) < 0)
- fprintf(stderr, "*** DB error (%d)\n", ret);
+ fprintf(stderr, "*** DB error (%d)\n\n", ret);
/* null cipher is here only for debuging
* purposes.
*/
- gnutls_set_cipher_priority(state, GNUTLS_NULL_CIPHER, GNUTLS_ARCFOUR,
+ gnutls_set_cipher_priority(state, GNUTLS_NULL_CIPHER,
GNUTLS_RIJNDAEL_CBC, GNUTLS_3DES_CBC, 0);
gnutls_set_compression_priority(state, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION, 0);
gnutls_set_kx_priority(state, GNUTLS_KX_RSA, GNUTLS_KX_SRP,
@@ -349,7 +322,7 @@ int main(int argc, char **argv)
close(sd);
gnutls_deinit(state);
tmp = gnutls_strerror(ret);
- fprintf(stderr, "*** Handshake has failed (%s)\n",
+ fprintf(stderr, "*** Handshake has failed (%s)\n\n",
tmp);
free(tmp);
continue;
@@ -370,7 +343,7 @@ int main(int argc, char **argv)
break;
} else {
fprintf(stderr,
- "\n*** Received corrupted data(%d). Closing the connection.\n",
+ "\n*** Received corrupted data(%d). Closing the connection.\n\n",
ret);
break;
}