diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-06-15 22:05:32 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-06-15 22:05:32 +0000 |
commit | 780c45c9fcc8719cb13f6ff5abcc73b7725de5df (patch) | |
tree | a4223c147853208bda0450ca2209ba71bc6d2798 | |
parent | 2a881f41279b151a28506d35ab63304e0f6dc1b2 (diff) | |
download | gnutls-780c45c9fcc8719cb13f6ff5abcc73b7725de5df.tar.gz |
more rsa stuff -- and cleanups
-rw-r--r-- | lib/auth_anon.c | 1 | ||||
-rw-r--r-- | lib/auth_rsa.c | 186 | ||||
-rw-r--r-- | lib/auth_srp.c | 1 | ||||
-rw-r--r-- | lib/auth_x509.h | 1 | ||||
-rw-r--r-- | lib/gnutls.h.in | 1 | ||||
-rw-r--r-- | lib/gnutls_algorithms.c | 9 | ||||
-rw-r--r-- | lib/gnutls_auth.h | 1 | ||||
-rw-r--r-- | lib/gnutls_datum.c | 18 | ||||
-rw-r--r-- | lib/gnutls_datum.h | 3 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 31 | ||||
-rw-r--r-- | lib/gnutls_int.h | 1 | ||||
-rw-r--r-- | src/serv.c | 1 |
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(¶ms->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(¶ms->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(¶ms->rsa_modulus); delete_structure("rsapublickey"); return GNUTLS_E_MPI_SCAN_FAILED; } - dat_set(params->rsa_exponent, str, len); + if (gnutls_set_datum(¶ms->rsa_exponent, str, len) < 0) { + gcry_mpi_release(key->A); + gnutls_free_datum(¶ms->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, ¶ms, cred->cert_list[0]); + _gnutls_get_rsa_params(key, ¶ms, 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(¶ms.rsa_modulus); + gnutls_free_datum(¶ms.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, ¶ms, 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); |