summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-15 22:05:32 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-15 22:05:32 +0000
commit780c45c9fcc8719cb13f6ff5abcc73b7725de5df (patch)
treea4223c147853208bda0450ca2209ba71bc6d2798
parent2a881f41279b151a28506d35ab63304e0f6dc1b2 (diff)
downloadgnutls-780c45c9fcc8719cb13f6ff5abcc73b7725de5df.tar.gz
more rsa stuff -- and cleanups
-rw-r--r--lib/auth_anon.c1
-rw-r--r--lib/auth_rsa.c186
-rw-r--r--lib/auth_srp.c1
-rw-r--r--lib/auth_x509.h1
-rw-r--r--lib/gnutls.h.in1
-rw-r--r--lib/gnutls_algorithms.c9
-rw-r--r--lib/gnutls_auth.h1
-rw-r--r--lib/gnutls_datum.c18
-rw-r--r--lib/gnutls_datum.h3
-rw-r--r--lib/gnutls_handshake.c31
-rw-r--r--lib/gnutls_int.h1
-rw-r--r--src/serv.c1
12 files changed, 231 insertions, 23 deletions
diff --git a/lib/auth_anon.c b/lib/auth_anon.c
index 315fc9980b..43dd30d7f8 100644
--- a/lib/auth_anon.c
+++ b/lib/auth_anon.c
@@ -35,6 +35,7 @@ int proc_anon_client_kx( GNUTLS_KEY, opaque*, int);
MOD_AUTH_STRUCT anon_auth_struct = {
"ANON",
+ NULL,
gen_anon_server_kx,
NULL,
NULL,
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 932c7b2c7b..7d4c3aa3b5 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -30,12 +30,16 @@
#include "gnutls_datum.h"
#include "auth_x509.h"
+#if 0
int gen_rsa_server_kx(GNUTLS_KEY, opaque **);
+#endif
+int gen_rsa_certificate(GNUTLS_KEY, opaque **);
+int proc_rsa_client_kx( GNUTLS_KEY, opaque*, int);
MOD_AUTH_STRUCT rsa_auth_struct = {
"RSA",
- gen_rsa_server_kx,
- NULL,
+ gen_rsa_certificate,
+/* not needed!!! gen_rsa_server_kx, */ NULL,
NULL,
NULL,
NULL,
@@ -44,6 +48,7 @@ MOD_AUTH_STRUCT rsa_auth_struct = {
NULL,
NULL,
NULL,
+ proc_rsa_client_kx,
NULL,
NULL
};
@@ -102,10 +107,6 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
}
-#define dat_set( d,s,len) d.data=gnutls_malloc(len); \
- if (d.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
- memcpy(d.data, s, len); d.size = len;
-
/* This function reads the RSA parameters from the given(?) certificate.
*/
static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_datum cert)
@@ -131,7 +132,7 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
return GNUTLS_E_PARSING_ERROR;
}
- if (!strcmp(str, "111")) { /* pkix-1 1 - RSA */
+ 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);
@@ -165,7 +166,11 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
delete_structure("rsapublickey");
return GNUTLS_E_MPI_SCAN_FAILED;
}
- dat_set(params->rsa_modulus, str, len);
+ if (gnutls_set_datum(&params->rsa_modulus, str, len) < 0) {
+ gnutls_assert();
+ delete_structure("rsapublickey");
+ return GNUTLS_E_MEMORY_ERROR;
+ }
len = sizeof(str);
result =
@@ -173,7 +178,7 @@ 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(params->rsa_modulus.data);
+ gnutls_free_datum(&params->rsa_modulus);
gcry_mpi_release(key->A);
return GNUTLS_E_PARSING_ERROR;
}
@@ -182,11 +187,16 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
gcry_mpi_release(key->A);
- gnutls_free(params->rsa_modulus.data);
+ gnutls_free_datum(&params->rsa_modulus);
delete_structure("rsapublickey");
return GNUTLS_E_MPI_SCAN_FAILED;
}
- dat_set(params->rsa_exponent, str, len);
+ if (gnutls_set_datum(&params->rsa_exponent, str, len) < 0) {
+ gcry_mpi_release(key->A);
+ gnutls_free_datum(&params->rsa_modulus);
+ delete_structure("rsapublickey");
+ return GNUTLS_E_MEMORY_ERROR;
+ }
delete_structure("rsapublickey");
@@ -197,6 +207,63 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
return ret;
}
+/* This function reads the RSA parameters from the given private key
+ * cert is not a certificate but a der structure containing the private
+ * key(s).
+ */
+static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert)
+{
+ int ret = 0, result;
+ opaque str[5*1024];
+ int len = sizeof(str);
+
+ create_structure("rsa_key", "PKCS-1");
+
+ result = get_der("rsa_key", cert.data, cert.size);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ result =
+ read_value("rsa_key.RSAPrivateKey.privateExponent", str, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ return GNUTLS_E_PARSING_ERROR;
+ }
+ if (gcry_mpi_scan(&key->u,
+ GCRYMPI_FMT_USG, str, &len) != 0) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+
+ len = sizeof(str);
+ result =
+ read_value("rsa_key.modulus", str, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ gcry_mpi_release(key->u);
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ if (gcry_mpi_scan(&key->A,
+ GCRYMPI_FMT_USG, str, &len) != 0) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ gcry_mpi_release(key->u);
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ delete_structure("rsa_key");
+
+ return ret;
+}
+
+#if 0 /* wow ... this was not needed ! */
int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
{
RSA_Params params;
@@ -211,7 +278,7 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
}
ret =
- _gnutls_get_rsa_params(key, &params, cred->cert_list[0]);
+ _gnutls_get_rsa_params(key, &params, cred->pkey);
if (ret < 0) {
gnutls_assert();
@@ -231,6 +298,9 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
WRITEdatum16(pdata, params.rsa_exponent);
pdata += params.rsa_exponent.size;
+ gnutls_free_datum(&params.rsa_modulus);
+ gnutls_free_datum(&params.rsa_modulus);
+
ret = _gnutls_calc_rsa_signature( key, (*data), ret-20-16, pdata);
if (ret< 0) {
gnutls_free((*data));
@@ -240,4 +310,96 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
return ret;
}
+#endif
+
+int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
+{
+ RSA_Params params;
+ const X509PKI_SERVER_CREDENTIALS *cred;
+ int ret, i;
+ opaque* pdata;
+
+ cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ if (cred == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ ret = 3;
+ for (i=0;i<cred->cert_list_size;i++) {
+ ret += cred->cert_list[i].size + 3;
+ /* hold size
+ * for uint24 */
+ }
+
+ (*data) = gnutls_malloc(ret);
+ pdata = (*data);
+
+ if (pdata == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ WRITEuint24( ret-3, pdata);
+ pdata+=3;
+ for (i=0;i<cred->cert_list_size;i++) {
+ WRITEdatum24( pdata, cred->cert_list[i]);
+ pdata += 3 + cred->cert_list[i].size;
+ }
+
+ return ret;
+}
+
+
+int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
+ uint16 n_Y;
+ size_t _n_Y;
+ MPI g, p;
+ int bits;
+ const RSA_SERVER_CREDENTIALS * cred;
+
+ cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ if (cred == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ ret =
+ _gnutls_get_rsa_params(key, &params, cred->cert_list[0]);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+#if 0 /* removed. I do not know why - maybe I didn't get the protocol,
+ * but openssl does not use that byte
+ */
+ if (data[0] != 1) {
+ gnutls_assert();
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ }
+#endif
+
+ n_Y = READuint16( &data[0]);
+
+ _n_Y = n_Y;
+ if (gcry_mpi_scan(&key->client_Y,
+ GCRYMPI_FMT_USG, &data[2], &_n_Y)) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ g = gnutls_get_dh_params(&p, bits);
+ key->KEY = gnutls_calc_dh_key( key->client_Y, key->dh_secret, p);
+
+ gnutls_mpi_release(key->client_Y);
+ gnutls_mpi_release(key->dh_secret);
+ gnutls_mpi_release(p);
+ gnutls_mpi_release(g);
+ key->client_Y = NULL;
+ key->dh_secret = NULL;
+
+ return 0;
+}
diff --git a/lib/auth_srp.c b/lib/auth_srp.c
index fe3e03fe16..c8fd2cef6b 100644
--- a/lib/auth_srp.c
+++ b/lib/auth_srp.c
@@ -38,6 +38,7 @@ int proc_srp_client_kx0(GNUTLS_KEY, opaque *, int);
MOD_AUTH_STRUCT srp_auth_struct = {
"SRP",
+ NULL,
gen_srp_server_kx,
gen_srp_server_kx2,
gen_srp_client_kx0,
diff --git a/lib/auth_x509.h b/lib/auth_x509.h
index d7dcd2d3a0..a6f5550111 100644
--- a/lib/auth_x509.h
+++ b/lib/auth_x509.h
@@ -4,6 +4,7 @@ extern MOD_AUTH_STRUCT x509pki_auth_struct;
typedef struct {
gnutls_datum * cert_list;
int cert_list_size;
+ gnutls_datum pkey; /* private key */
} X509PKI_SERVER_CREDENTIALS;
typedef struct {
diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in
index 174a602928..1e26a50282 100644
--- a/lib/gnutls.h.in
+++ b/lib/gnutls.h.in
@@ -144,6 +144,7 @@ typedef struct {
typedef struct {
gnutls_datum * cert_list;
int cert_list_size;
+ gnutls_datum pkey; /* private key */
} X509PKI_SERVER_CREDENTIALS;
/* error codes appended here */
diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c
index e7c60fcf57..e1542bc323 100644
--- a/lib/gnutls_algorithms.c
+++ b/lib/gnutls_algorithms.c
@@ -27,6 +27,7 @@
#include "auth_anon.h"
/* #include "auth_dhe_dss.h" */
#include "auth_srp.h"
+#include "auth_x509.h"
#define MAX_CIPHER 256
#define MAX_MAC 256
@@ -190,12 +191,12 @@ 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, NULL),
+ GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, &x509pki_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_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),
{0}
};
diff --git a/lib/gnutls_auth.h b/lib/gnutls_auth.h
index b183b7ba49..c673e2598b 100644
--- a/lib/gnutls_auth.h
+++ b/lib/gnutls_auth.h
@@ -2,6 +2,7 @@
#define GNUTLS_AUTH_H
typedef struct {
char* name; /* null terminated */
+ int (*gnutls_generate_certificate)( GNUTLS_KEY, opaque**);
int (*gnutls_generate_server_kx)( GNUTLS_KEY, opaque**);
int (*gnutls_generate_server_kx2)( GNUTLS_KEY, opaque**); /* used in SRP */
int (*gnutls_generate_client_kx0)( GNUTLS_KEY, opaque**);
diff --git a/lib/gnutls_datum.c b/lib/gnutls_datum.c
index 8e137dcb18..b152c19c40 100644
--- a/lib/gnutls_datum.c
+++ b/lib/gnutls_datum.c
@@ -40,3 +40,21 @@ void WRITEdatum8( opaque* dest, gnutls_datum dat) {
dest[0] = (uint8) dat.size;
memcpy( &dest[1], dat.data, dat.size);
}
+
+int gnutls_set_datum( gnutls_datum* dat, const void* data, int data_size) {
+ dat->data = gnutls_malloc(data_size);
+ if (dat->data==NULL) return GNUTLS_E_MEMORY_ERROR;
+
+ dat->size = data_size;
+ memcpy( dat->data, data, data_size);
+
+ return 0;
+}
+
+void gnutls_free_datum( gnutls_datum* dat) {
+ if (dat->data!=NULL && dat->size!=0)
+ gnutls_free( dat->data);
+
+ dat->data = NULL;
+ dat->size = 0;
+}
diff --git a/lib/gnutls_datum.h b/lib/gnutls_datum.h
index 2462acd648..0fa057dd20 100644
--- a/lib/gnutls_datum.h
+++ b/lib/gnutls_datum.h
@@ -2,3 +2,6 @@ void WRITEdatum16( opaque* dest, gnutls_datum dat);
void WRITEdatum24( opaque* dest, gnutls_datum dat);
void WRITEdatum32( opaque* dest, gnutls_datum dat);
void WRITEdatum8( opaque* dest, gnutls_datum dat);
+
+int gnutls_set_datum( gnutls_datum* dat, const void* data, int data_size);
+void gnutls_free_datum( gnutls_datum* dat);
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 97ab9a015f..a05c6a9179 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -1150,11 +1150,15 @@ int gnutls_handshake(int cd, GNUTLS_STATE state)
return ret;
}
-/**
+ /*
* gnutls_handshake_begin - This function does a partial handshake of the TLS/SSL protocol.
* @cd: is a connection descriptor, as returned by socket().
* @state: is a a &GNUTLS_STATE structure.
*
+ * NOTE: I intend to make this function obsolete. If a certificate
+ * cannot be verified then this information will be available in the auth_info
+ * structure. Thus not need for these functions.
+ *
* This function initiates the handshake of the TLS/SSL protocol.
* Here we will receive - if requested and supported by the ciphersuite -
* the peer's certificate.
@@ -1163,7 +1167,7 @@ int gnutls_handshake(int cd, GNUTLS_STATE state)
* However this failure will not be fatal. However you may choose to
* continue the handshake - eg. even if the certificate cannot
* be verified- by calling gnutls_handshake_finish().
- **/
+ */
int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
{
int ret;
@@ -1230,11 +1234,20 @@ int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
return ret;
}
- /* FIXME: send our certificate - if required */
/* NOTE: these should not be send if we are resuming */
/* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
+ if (state->gnutls_internals.resumed == RESUME_FALSE)
+ ret = _gnutls_send_certificate(cd, state);
+ if (ret < 0) {
+ ERR("send server certificate", ret);
+ gnutls_assert();
+ gnutls_clearHashDataBuffer(state);
+ return ret;
+ }
+
+
/* send server key exchange (A) */
if (state->gnutls_internals.resumed == RESUME_FALSE)
ret = _gnutls_send_server_kx_message(cd, state);
@@ -1245,6 +1258,8 @@ int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
return ret;
}
+ /* FIXME: Send certificate request */
+
/* Added for SRP which uses a different handshake */
/* receive the client key exchange message */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
@@ -1269,7 +1284,8 @@ int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
}
}
-/* This function sends the final handshake packets and initializes connection */
+/* This function sends the final handshake packets and initializes connection
+ */
static int _gnutls_send_handshake_final(int cd, GNUTLS_STATE state,
int init)
{
@@ -1303,7 +1319,8 @@ static int _gnutls_send_handshake_final(int cd, GNUTLS_STATE state,
return ret;
}
-/* This function receives the final handshake packets */
+/* This function receives the final handshake packets
+ */
static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state,
int init)
{
@@ -1337,7 +1354,7 @@ static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state,
return ret;
}
-/**
+ /*
* gnutls_handshake_finish - This function finished a partial handshake of the TLS/SSL protocol.
* @cd: is a connection descriptor, as returned by socket().
* @state: is a a &GNUTLS_STATE structure.
@@ -1346,7 +1363,7 @@ static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state,
* You should call it only if you used gnutls_handshake_begin() and
* you have somehow verified the identity of the peer.
* This function will fail if any problem is encountered.
- **/
+ */
int gnutls_handshake_finish(int cd, GNUTLS_STATE state)
{
int ret = 0;
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 58b682e461..403cc1c208 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -142,6 +142,7 @@ typedef struct {
/* RSA:
* modulus is A
* exponent is B
+ * private key is u;
*/
/* this is used to hold the peers authentication data
diff --git a/src/serv.c b/src/serv.c
index ab57e94110..126c57fd4c 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -82,6 +82,7 @@ int main()
gnutls_init(&state, GNUTLS_SERVER);
if ((ret = gnutls_set_db_name(state, "gnutls-rsm.db")) < 0)
fprintf(stderr, "*** DB error (%d)\n", ret);
+
gnutls_set_cipher_priority(state, GNUTLS_TWOFISH,
GNUTLS_RIJNDAEL, GNUTLS_3DES,
GNUTLS_ARCFOUR, 0);