From: Nikos Mavrogiannopoulos Date: Sat, 8 Apr 2000 21:48:49 +0000 (+0000) Subject: Added some basics for key exchange. X-Git-Tag: gnutls0-0-4~93 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8dc58a2fa217b7bcb2962e998fa98af14e610489;p=thirdparty%2Fgnutls.git Added some basics for key exchange. --- diff --git a/src/gnutls.c b/src/gnutls.c index 33289f0ff8..6ca396b680 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -606,7 +606,7 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, if (type == GNUTLS_HANDSHAKE) { ret = - _gnutls_recv_handshake + _gnutls_recv_handshake_int (cd, state, tmpdata, tmplen, data, sizeofdata); gnutls_free(tmpdata); diff --git a/src/gnutls_algorithms.c b/src/gnutls_algorithms.c index f4aeacafce..d3de151836 100644 --- a/src/gnutls_algorithms.c +++ b/src/gnutls_algorithms.c @@ -14,7 +14,7 @@ void tolow(char *str, int size) } -int _gnutls_get_block_size(BulkCipherAlgorithm algorithm) +int _gnutls_cipher_get_block_size(BulkCipherAlgorithm algorithm) { size_t ret = 0; GNUTLS_ALG_LOOP(ret = p->blocksize); @@ -22,7 +22,7 @@ int _gnutls_get_block_size(BulkCipherAlgorithm algorithm) } -int _gnutls_is_block_algorithm(BulkCipherAlgorithm algorithm) +int _gnutls_cipher_is_block(BulkCipherAlgorithm algorithm) { size_t ret = 0; @@ -31,7 +31,7 @@ int _gnutls_is_block_algorithm(BulkCipherAlgorithm algorithm) } -int _gnutls_get_key_size(BulkCipherAlgorithm algorithm) +int _gnutls_cipher_get_key_size(BulkCipherAlgorithm algorithm) { /* In bytes */ size_t ret = 0; GNUTLS_ALG_LOOP(ret = p->keysize); @@ -39,7 +39,7 @@ int _gnutls_get_key_size(BulkCipherAlgorithm algorithm) } -int _gnutls_get_iv_size(BulkCipherAlgorithm algorithm) +int _gnutls_cipher_get_iv_size(BulkCipherAlgorithm algorithm) { /* In bytes */ size_t ret = 0; GNUTLS_ALG_LOOP(ret = p->iv); @@ -47,7 +47,7 @@ int _gnutls_get_iv_size(BulkCipherAlgorithm algorithm) } -char *_gnutls_get_algorithms_name(BulkCipherAlgorithm algorithm) +char *_gnutls_cipher_get_name(BulkCipherAlgorithm algorithm) { char *ret = NULL; char *pointerTo_; @@ -69,9 +69,87 @@ char *_gnutls_get_algorithms_name(BulkCipherAlgorithm algorithm) } -int _gnutls_is_algorithm(BulkCipherAlgorithm algorithm) +int _gnutls_cipher_is_ok(BulkCipherAlgorithm algorithm) { - char *y = _gnutls_get_algorithms_name(algorithm); + char *y = _gnutls_cipher_get_name(algorithm); + + if (y != NULL) { + free(y); + return 0; + } else { + return 1; + } + +} + + + +int _gnutls_kx_algo_server_certificate(KX_Algorithm algorithm) +{ + size_t ret = 0; + GNUTLS_KX_ALG_LOOP(ret = p->server_cert); + return ret; + +} + +int _gnutls_kx_algo_server_key_exchange(KX_Algorithm algorithm) +{ + size_t ret = 0; + + GNUTLS_KX_ALG_LOOP(ret = p->server_kx); + return ret; + +} + +int _gnutls_kx_algo_client_certificate(KX_Algorithm algorithm) +{ /* In bytes */ + size_t ret = 0; + GNUTLS_KX_ALG_LOOP(ret = p->client_cert); + return ret; + +} + +int _gnutls_kx_algo_RSA_premaster(KX_Algorithm algorithm) +{ /* In bytes */ + size_t ret = 0; + GNUTLS_KX_ALG_LOOP(ret = p->RSA_premaster); + return ret; + +} + +int _gnutls_kx_algo_DH_public_value(KX_Algorithm algorithm) +{ /* In bytes */ + size_t ret = 0; + GNUTLS_KX_ALG_LOOP(ret = p->DH_public_value); + return ret; + +} + +char *_gnutls_kx_algo_get_name(KX_Algorithm algorithm) +{ + char *ret = NULL; + char *pointerTo_; + + /* avoid prefix */ + GNUTLS_KX_ALG_LOOP(ret = strdup(p->name + sizeof("KX_") - 1)); + + + if (ret != NULL) { + tolow(ret, strlen(ret)); + pointerTo_ = strchr(ret, '_'); + + while (pointerTo_ != NULL) { + *pointerTo_ = '-'; + pointerTo_ = strchr(ret, '_'); + } + } + return ret; +} + + +int _gnutls_kx_algo_is_ok(KX_Algorithm algorithm) +{ + char *y = _gnutls_kx_algo_get_name(algorithm); if (y != NULL) { free(y); diff --git a/src/gnutls_algorithms.h b/src/gnutls_algorithms.h index 55172aaf55..7bc613ad16 100644 --- a/src/gnutls_algorithms.h +++ b/src/gnutls_algorithms.h @@ -25,8 +25,52 @@ static gnutls_cipher_entry algorithms[] = { GNUTLS_LOOP( if(p->id == algorithm) { a; break; } ) -int _gnutls_get_block_size(BulkCipherAlgorithm algorithm); -int _gnutls_is_block_algorithm(BulkCipherAlgorithm algorithm); -int _gnutls_get_key_size(BulkCipherAlgorithm algorithm); -int _gnutls_get_iv_size(BulkCipherAlgorithm algorithm); -char *_gnutls_get_algorithms_name(BulkCipherAlgorithm algorithm); + + +#define GNUTLS_KX_ALGO_ENTRY(name, server_cert, server_kx, client_cert, RSA_premaster, DH_public_value) \ + { #name, name, server_cert, server_kx, client_cert, RSA_premaster, DH_public_value } + +struct gnutls_kx_algo_entry { + char *name; + KX_Algorithm algorithm; + int server_cert; + int server_kx; + int client_cert; + int RSA_premaster; + int DH_public_value; +}; +typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry; + +static gnutls_kx_algo_entry kx_algorithms[] = { + GNUTLS_KX_ALGO_ENTRY( KX_ANON_DH, 0, 1, 0, 0, 1), + GNUTLS_KX_ALGO_ENTRY( KX_RSA , 1, 0, 1, 1, 0), + GNUTLS_KX_ALGO_ENTRY( KX_DHE_DSS, 1, 1, 1, 0, 0), + GNUTLS_KX_ALGO_ENTRY( KX_DHE_RSA, 1, 1, 1, 0, 0), + GNUTLS_KX_ALGO_ENTRY( KX_DH_DSS , 1, 0, 1, 0, 0), + GNUTLS_KX_ALGO_ENTRY( KX_DH_RSA , 1, 0, 1, 0, 0), + {0} +}; + +#define GNUTLS_KX_LOOP(b) \ + gnutls_kx_algo_entry *p; \ + for(p = kx_algorithms; p->name != NULL; p++) { b ; } + +#define GNUTLS_KX_ALG_LOOP(a) \ + GNUTLS_KX_LOOP( if(p->algorithm == algorithm) { a; break; } ) + + +int _gnutls_cipher_get_block_size(BulkCipherAlgorithm algorithm); +int _gnutls_cipher_is_block(BulkCipherAlgorithm algorithm); +int _gnutls_cipher_is_ok(BulkCipherAlgorithm algorithm); +int _gnutls_cipher_get_key_size(BulkCipherAlgorithm algorithm); +int _gnutls_cipher_get_iv_size(BulkCipherAlgorithm algorithm); +char *_gnutls_cipher_get_name(BulkCipherAlgorithm algorithm); + + +int _gnutls_kx_get_block_size(KX_Algorithm algorithm); +int _gnutls_kx_is_block(KX_Algorithm algorithm); +int _gnutls_kx_is_ok(KX_Algorithm algorithm); +int _gnutls_kx_get_key_size(KX_Algorithm algorithm); +int _gnutls_kx_get_iv_size(KX_Algorithm algorithm); +char *_gnutls_kx_get_name(KX_Algorithm algorithm); + diff --git a/src/gnutls_cipher.c b/src/gnutls_cipher.c index 2d8ee74514..855ab27647 100644 --- a/src/gnutls_cipher.c +++ b/src/gnutls_cipher.c @@ -13,9 +13,9 @@ int _gnutls_set_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo) { - if (_gnutls_is_algorithm(algo) == 0) { + if (_gnutls_cipher_is_ok(algo) == 0) { state->security_parameters.bulk_cipher_algorithm = algo; - if (_gnutls_is_block_algorithm(algo) == 0) { + if (_gnutls_cipher_is_block(algo) == 0) { state->security_parameters.cipher_type = CIPHER_BLOCK; } else { @@ -26,9 +26,9 @@ int _gnutls_set_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo) EXPORTABLE_FALSE; state->security_parameters.key_material_length = state->security_parameters.key_size = - _gnutls_get_key_size(algo); + _gnutls_cipher_get_key_size(algo); state->security_parameters.IV_size = - _gnutls_get_iv_size(algo); + _gnutls_cipher_get_iv_size(algo); } else { return GNUTLS_E_UNKNOWN_CIPHER; } @@ -359,8 +359,8 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, rand[0] + 1; length = (length / - _gnutls_get_block_size(CIPHER_3DES)) * - _gnutls_get_block_size(CIPHER_3DES); + _gnutls_cipher_get_block_size(CIPHER_3DES)) * + _gnutls_cipher_get_block_size(CIPHER_3DES); pad = length - compressed->length - state->connection_state.mac_secret_size - 1; diff --git a/src/gnutls_handshake.c b/src/gnutls_handshake.c index 3e13252298..a10f2ea970 100644 --- a/src/gnutls_handshake.c +++ b/src/gnutls_handshake.c @@ -49,6 +49,15 @@ int ret; return ret; } +int _gnutls_recv_handshake( int cd, GNUTLS_STATE state, void* data, uint32 datalen, HandshakeType type) { +int ret; + state->gnutls_internals.next_handshake_type = type; + ret = gnutls_recv_int( cd, state, GNUTLS_HANDSHAKE, data, datalen); + state->gnutls_internals.next_handshake_type = GNUTLS_NONE; + + return ret; +} + _gnutls_recv_finished( int cd, GNUTLS_STATE state) { uint8* data, vrfy[12]; uint8 concat[36]; /* md5+sha1 */ @@ -59,8 +68,7 @@ int ret=0; memmove( concat, state->gnutls_internals.md_md5, 16); memmove( &concat[16], state->gnutls_internals.md_sha1, 20); - state->gnutls_internals.next_handshake_type = GNUTLS_FINISHED; - ret = gnutls_recv_int( cd, state, GNUTLS_HANDSHAKE, vrfy, 12); + ret = _gnutls_recv_handshake( cd, state, vrfy, 12, GNUTLS_FINISHED); if (ret<0) { ERR("recv finished int", ret); return ret; @@ -202,7 +210,7 @@ int _gnutls_send_handshake(int cd, GNUTLS_STATE state, void* i_data, uint32 i_da return ret; } -int _gnutls_recv_handshake( int cd, GNUTLS_STATE state, void* data, uint32 datasize, void* output_data, uint32 output_datasize) { +int _gnutls_recv_handshake_int( int cd, GNUTLS_STATE state, void* data, uint32 datasize, void* output_data, uint32 output_datasize) { int ret; uint32 length32=0; int pos=0; @@ -371,7 +379,7 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state, opaque* SessionID, uint8 Sess } -/* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake only if a +/* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a * hello message is expected. It uses the gnutls_internals.current_cipher_suite * and gnutls_internals.compression_method. */ @@ -493,8 +501,7 @@ uint8 session_id_size; } /* receive the server hello */ - state->gnutls_internals.next_handshake_type = GNUTLS_SERVER_HELLO; - ret = gnutls_recv_int( cd, state, GNUTLS_HANDSHAKE, NULL, 0); + ret = _gnutls_recv_handshake( cd, state, NULL, 0, GNUTLS_SERVER_HELLO); if (ret<0) { ERR("recv hello", ret); return ret; @@ -503,8 +510,7 @@ uint8 session_id_size; /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */ /* receive the server hello done */ - state->gnutls_internals.next_handshake_type = GNUTLS_SERVER_HELLO_DONE; - ret = gnutls_recv_int( cd, state, GNUTLS_HANDSHAKE, NULL, 0); + ret = _gnutls_recv_handshake( cd, state, NULL, 0, GNUTLS_SERVER_HELLO_DONE); if (ret<0) { ERR("recv server hello done", ret); return ret; @@ -549,8 +555,7 @@ uint8 session_id_size; } else { /* SERVER */ - state->gnutls_internals.next_handshake_type = GNUTLS_CLIENT_HELLO; - ret = gnutls_recv_int( cd, state, GNUTLS_HANDSHAKE, NULL, 0); + ret = _gnutls_recv_handshake( cd, state, NULL, 0, GNUTLS_CLIENT_HELLO); if (ret<0) { ERR("recv hello", ret); return ret; diff --git a/src/gnutls_handshake.h b/src/gnutls_handshake.h index c39ed90706..b610642c60 100644 --- a/src/gnutls_handshake.h +++ b/src/gnutls_handshake.h @@ -5,5 +5,5 @@ int _gnutls_send_hello_request(int cd, GNUTLS_STATE state); int _gnutls_send_hello(int cd, GNUTLS_STATE state, opaque* SessionID, uint8 SessionIDLen); int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char* data, int datalen, opaque** SessionID, int SessionIDnum); int gnutls_handshake(int cd, GNUTLS_STATE state); -int _gnutls_recv_handshake( int cd, GNUTLS_STATE state, void*, uint32, void*, uint32); +int _gnutls_recv_handshake_int( int cd, GNUTLS_STATE state, void*, uint32, void*, uint32); int _gnutls_generate_session_id( char** session_id, uint8* len); diff --git a/src/gnutls_int.h b/src/gnutls_int.h index 300b5d64b3..8e6fa16f02 100644 --- a/src/gnutls_int.h +++ b/src/gnutls_int.h @@ -48,7 +48,7 @@ enum HandshakeType { GNUTLS_HELLO_REQUEST, GNUTLS_CLIENT_HELLO, GNUTLS_SERVER_HE GNUTLS_CERTIFICATE=11, GNUTLS_SERVER_KEY_EXCHANGE, GNUTLS_CERTIFICATE_REQUEST, GNUTLS_SERVER_HELLO_DONE, GNUTLS_CERTIFICATE_VERIFY, GNUTLS_CLIENT_KEY_EXCHANGE, - GNUTLS_FINISHED=20 }; + GNUTLS_FINISHED=20, GNUTLS_NONE=255 }; typedef enum HandshakeType HandshakeType; @@ -66,6 +66,7 @@ typedef struct { /* STATE */ enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT }; enum BulkCipherAlgorithm { CIPHER_NULL, CIPHER_3DES = 4 }; +enum KX_Algorithm { KX_RSA, KX_DHE_DSS, KX_DHE_RSA, KX_DH_DSS, KX_DH_RSA, KX_ANON_DH }; enum CipherType { CIPHER_STREAM, CIPHER_BLOCK }; enum IsExportable { EXPORTABLE_TRUE, EXPORTABLE_FALSE }; enum MACAlgorithm { MAC_NULL, MAC_MD5, MAC_SHA }; @@ -74,6 +75,7 @@ enum CompressionMethod { COMPRESSION_NULL }; enum ValidSession { VALID_TRUE, VALID_FALSE }; enum ResumableSession { RESUME_TRUE, RESUME_FALSE }; +typedef enum KX_Algorithm KX_Algorithm; typedef enum ValidSession ValidSession; typedef enum ResumableSession ResumableSession; typedef enum ConnectionEnd ConnectionEnd;