From fe1b1d18fa42e2162cc58da5bcc262d07dfb9b9b Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 19 Nov 2002 12:01:54 +0000 Subject: Added certificate authenticated SRP cipher suites. --- lib/auth_cert.c | 2 +- lib/gnutls.h.in.in | 2 +- lib/gnutls_algorithms.c | 47 +++++++++++++++++++++++++++++++++-------------- lib/gnutls_algorithms.h | 4 ++-- lib/gnutls_auth.c | 17 +++++++++++++---- lib/gnutls_auth_int.h | 2 +- lib/gnutls_cert.c | 1 + lib/gnutls_handshake.c | 24 +++++++++++------------- lib/gnutls_int.h | 2 +- lib/gnutls_v2_compat.c | 2 +- lib/gnutls_x509.c | 9 +++++++-- 11 files changed, 72 insertions(+), 40 deletions(-) (limited to 'lib') diff --git a/lib/auth_cert.c b/lib/auth_cert.c index f7c57aa7f3..5c5774336f 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -1255,7 +1255,7 @@ int _gnutls_find_apr_cert(gnutls_session session, gnutls_cert ** apr_cert_list, int ind; cred = - _gnutls_get_kx_cred(session->key, GNUTLS_CRD_CERTIFICATE, + _gnutls_get_kx_cred(session, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in index 8f759dbd74..97e7b5644f 100644 --- a/lib/gnutls.h.in.in +++ b/lib/gnutls.h.in.in @@ -44,7 +44,7 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_NULL=1, typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP, - GNUTLS_KX_RSA_EXPORT + GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA } gnutls_kx_algorithm; typedef enum gnutls_credentials_type { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } gnutls_credentials_type; diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index ca05423d02..f05a3cb4c2 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -28,25 +28,31 @@ /* Cred type mappings to KX algorithms */ typedef struct { gnutls_kx_algorithm algorithm; - gnutls_credentials_type type; + gnutls_credentials_type client_type; + gnutls_credentials_type server_type; /* The type of credentials a server + * needs to set */ } gnutls_cred_map; static const gnutls_cred_map cred_mappings[] = { - { GNUTLS_KX_ANON_DH, GNUTLS_CRD_ANON }, - { GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE }, - { GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE }, - { GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE }, - { GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE }, - { GNUTLS_KX_SRP, GNUTLS_CRD_SRP }, + { GNUTLS_KX_ANON_DH, GNUTLS_CRD_ANON, GNUTLS_CRD_ANON }, + { GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE }, + { GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE }, + { GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE }, + { GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE }, + { GNUTLS_KX_SRP, GNUTLS_CRD_SRP, GNUTLS_CRD_SRP }, + { GNUTLS_KX_SRP_RSA, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE }, { 0 } }; #define GNUTLS_KX_MAP_LOOP(b) \ const gnutls_cred_map *p; \ - for(p = cred_mappings; p->type != 0; p++) { b ; } + for(p = cred_mappings; p->algorithm != 0; p++) { b ; } -#define GNUTLS_KX_MAP_ALG_LOOP(a) \ - GNUTLS_KX_MAP_LOOP( if(p->type == type) { a; break; }) +#define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \ + GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; }) + +#define GNUTLS_KX_MAP_ALG_LOOP_CLIENT(a) \ + GNUTLS_KX_MAP_LOOP( if(p->client_type == type) { a; break; }) /* TLS Versions */ @@ -234,6 +240,7 @@ typedef struct { #define GNUTLS_SRP_SHA_RIJNDAEL_128_CBC_SHA { 0x00, 0x53 } #define GNUTLS_SRP_SHA_RIJNDAEL_256_CBC_SHA { 0x00, 0x56 } +#define GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA { 0x00, 0x51 } /** RSA **/ @@ -316,6 +323,10 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = { GNUTLS_CIPHER_RIJNDAEL_256_CBC, GNUTLS_KX_SRP, GNUTLS_MAC_SHA, GNUTLS_TLS1), + GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA, + GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_RSA, + GNUTLS_MAC_SHA, GNUTLS_TLS1), + /* DHE_DSS */ GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_DHE_DSS_ARCFOUR_SHA, GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_KX_DHE_DSS, @@ -805,18 +816,26 @@ int ret=0; } /* Type to KX mappings */ -gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type) +gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type, int server) { gnutls_kx_algorithm ret = -1; - GNUTLS_KX_MAP_ALG_LOOP(ret = p->algorithm); + if (server) { + GNUTLS_KX_MAP_ALG_LOOP_SERVER(ret = p->algorithm); + } else { + GNUTLS_KX_MAP_ALG_LOOP_SERVER(ret = p->algorithm); + } return ret; } -gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm) +gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm, int server) { gnutls_credentials_type ret = -1; - GNUTLS_KX_MAP_LOOP(if (p->algorithm==algorithm) ret = p->type); + if (server) { + GNUTLS_KX_MAP_LOOP(if (p->algorithm==algorithm) ret = p->server_type); + } else { + GNUTLS_KX_MAP_LOOP(if (p->algorithm==algorithm) ret = p->client_type); + } return ret; } diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h index 944996ae57..b3b041802e 100644 --- a/lib/gnutls_algorithms.h +++ b/lib/gnutls_algorithms.h @@ -77,8 +77,8 @@ int _gnutls_compression_get_comp_level(gnutls_compression_method algorithm); int _gnutls_compression_get_wbits(gnutls_compression_method algorithm); /* Type to KX mappings */ -gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type); -gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm); +gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type, int server); +gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm, int server); struct gnutls_kx_algo_entry { const char *name; diff --git a/lib/gnutls_auth.c b/lib/gnutls_auth.c index c23b6fc1c3..5bed7f9c52 100644 --- a/lib/gnutls_auth.c +++ b/lib/gnutls_auth.c @@ -137,20 +137,29 @@ int gnutls_credentials_set( gnutls_session session, gnutls_credentials_type type * Eg. for CERTIFICATE ciphersuites (key exchange algorithms: KX_RSA, KX_DHE_RSA), * the same function are to be used to access the authentication data. **/ -gnutls_credentials_type gnutls_auth_get_type( gnutls_session session) { +gnutls_credentials_type gnutls_auth_get_type( gnutls_session session) +{ +/* This is not the credentials we must set, but the authentication data + * we get by the peer, so it should be reversed. + */ +int server = session->security_parameters.entity==GNUTLS_SERVER?0:1; return _gnutls_map_kx_get_cred( _gnutls_cipher_suite_get_kx_algo - (session->security_parameters.current_cipher_suite)); + (session->security_parameters.current_cipher_suite), server); } /* * This returns an pointer to the linked list. Don't * free that!!! */ -const void *_gnutls_get_kx_cred( GNUTLS_KEY key, gnutls_kx_algorithm algo, int *err) { - return _gnutls_get_cred( key, _gnutls_map_kx_get_cred(algo), err); +const void *_gnutls_get_kx_cred( gnutls_session session, gnutls_kx_algorithm algo, int *err) +{ +int server = session->security_parameters.entity==GNUTLS_SERVER?1:0; + + return _gnutls_get_cred( session->key, _gnutls_map_kx_get_cred(algo, server), err); } + const void *_gnutls_get_cred( GNUTLS_KEY key, gnutls_credentials_type type, int *err) { AUTH_CRED * ccred; diff --git a/lib/gnutls_auth_int.h b/lib/gnutls_auth_int.h index a91d03d226..a62de07565 100644 --- a/lib/gnutls_auth_int.h +++ b/lib/gnutls_auth_int.h @@ -1,7 +1,7 @@ int gnutls_clear_creds( gnutls_session session); int gnutls_credentials_set( gnutls_session session, gnutls_credentials_type type, void* cred); const void *_gnutls_get_cred( GNUTLS_KEY key, gnutls_credentials_type kx, int* err); -const void *_gnutls_get_kx_cred( GNUTLS_KEY key, gnutls_kx_algorithm algo, int *err); +const void *_gnutls_get_kx_cred( gnutls_session session, gnutls_kx_algorithm algo, int *err); int _gnutls_generate_key(GNUTLS_KEY key); gnutls_credentials_type gnutls_auth_get_type( gnutls_session session); void* _gnutls_get_auth_info( gnutls_session session); diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 4deab906a9..2ddf17b937 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -57,6 +57,7 @@ static const gnutls_pk_map pk_mappings[] = { {GNUTLS_KX_RSA, GNUTLS_PK_RSA}, {GNUTLS_KX_RSA_EXPORT, GNUTLS_PK_RSA}, {GNUTLS_KX_DHE_RSA, GNUTLS_PK_RSA}, + {GNUTLS_KX_SRP_RSA, GNUTLS_PK_RSA}, {GNUTLS_KX_DHE_DSS, GNUTLS_PK_DSA}, {0} }; diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 8c484e8d17..6771fcb8a7 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -505,7 +505,7 @@ int _gnutls_recv_finished(gnutls_session session) /* returns PK_RSA if the given cipher suite list only supports, * RSA algorithms, PK_DSA if DSS, and -1 if both or none. */ -int _gnutls_find_pk_algos_in_ciphersuites( opaque* data, int datalen) { +int _gnutls_server_find_pk_algos_in_ciphersuites( opaque* data, int datalen) { int j; gnutls_pk_algorithm algo=-1, prev_algo = 0; gnutls_kx_algorithm kx; @@ -513,7 +513,7 @@ gnutls_kx_algorithm kx; for (j = 0; j < datalen; j += 2) { kx = _gnutls_cipher_suite_get_kx_algo(*((GNUTLS_CipherSuite *) & data[j])); - if ( _gnutls_map_kx_get_cred( kx) == GNUTLS_CRD_CERTIFICATE) { + if ( _gnutls_map_kx_get_cred( kx, 1) == GNUTLS_CRD_CERTIFICATE) { algo = _gnutls_map_pk_get_pk( kx); if (algo!=prev_algo && prev_algo!=0) return -1; @@ -537,7 +537,7 @@ int _gnutls_server_select_suite(gnutls_session session, opaque *data, int datale * supported by the peer. */ - pk_algo = _gnutls_find_pk_algos_in_ciphersuites( data, datalen); + pk_algo = _gnutls_server_find_pk_algos_in_ciphersuites( data, datalen); x = _gnutls_supported_ciphersuites(session, &ciphers); if (x < 0) { /* the case x==0 is handled within the function. */ @@ -597,8 +597,7 @@ int _gnutls_server_select_suite(gnutls_session session, opaque *data, int datale /* check if the credentials (username, public key etc. are ok) */ if (_gnutls_get_kx_cred - (session->key, - _gnutls_cipher_suite_get_kx_algo(session->security_parameters. + (session, _gnutls_cipher_suite_get_kx_algo(session->security_parameters. current_cipher_suite), &err) == NULL && err != 0) { gnutls_assert(); @@ -1108,8 +1107,7 @@ static int _gnutls_client_set_ciphersuite(gnutls_session session, * Actually checks if they exist. */ if (_gnutls_get_kx_cred - (session->key, - _gnutls_cipher_suite_get_kx_algo(session-> + (session, _gnutls_cipher_suite_get_kx_algo(session-> security_parameters. current_cipher_suite), &err) == NULL && err != 0) { @@ -2335,7 +2333,7 @@ int _gnutls_remove_unwanted_ciphersuites(gnutls_session session, gnutls_kx_algorithm *alg; int alg_size; gnutls_kx_algorithm kx; - + int server = session->security_parameters.entity==GNUTLS_SERVER?1:0; /* if we should use a specific certificate, * we should remove all algorithms that are not supported @@ -2390,22 +2388,22 @@ int _gnutls_remove_unwanted_ciphersuites(gnutls_session session, /* if it is defined but had no credentials */ - if (_gnutls_get_kx_cred - (session->key, kx, NULL) == NULL) { + if (_gnutls_get_kx_cred(session, kx, NULL) == NULL) { keep = 1; } else /* If there was no credentials to use with the specified * key exchange method, then just remove it. */ - if (_gnutls_map_kx_get_cred(kx) == GNUTLS_CRD_CERTIFICATE) { + if (_gnutls_map_kx_get_cred(kx, server) == GNUTLS_CRD_CERTIFICATE) { keep = 1; /* do not keep */ if (x509_cred != NULL) { - if (session->security_parameters.entity == - GNUTLS_SERVER) { + if (server) { /* here we check if the KX algorithm * is compatible with the certificate. */ +fprintf(stderr, "KX: %d\n", kx); for (j = 0; j < alg_size; j++) { +fprintf(stderr, "ALG: %d\n", alg[j]); if (alg[j] == kx) { keep = 0; break; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 260f6d318b..281ba655c8 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -159,7 +159,7 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_NULL=1, typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP, - GNUTLS_KX_RSA_EXPORT + GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA } gnutls_kx_algorithm; typedef enum gnutls_mac_algorithm { GNUTLS_MAC_NULL=1, GNUTLS_MAC_MD5, GNUTLS_MAC_SHA } gnutls_mac_algorithm; diff --git a/lib/gnutls_v2_compat.c b/lib/gnutls_v2_compat.c index 8271672719..01225468f1 100644 --- a/lib/gnutls_v2_compat.c +++ b/lib/gnutls_v2_compat.c @@ -156,7 +156,7 @@ int _gnutls_read_client_hello_v2(gnutls_session session, opaque * data, /* check if the credentials (username, public key etc. are ok) */ - if (_gnutls_get_kx_cred( session->key, _gnutls_cipher_suite_get_kx_algo(session->security_parameters.current_cipher_suite), &err) == NULL && err != 0) { + if (_gnutls_get_kx_cred( session, _gnutls_cipher_suite_get_kx_algo(session->security_parameters.current_cipher_suite), &err) == NULL && err != 0) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CREDENTIALS; } diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index 5b8a285fd9..59f46a47ee 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -2212,10 +2212,14 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert, /* Returns 0 if it's ok to use the gnutls_kx_algorithm with this * certificate (uses the KeyUsage field). */ -int _gnutls_check_x509_key_usage(const gnutls_cert * cert, +int _gnutls_check_x509_key_usage( const gnutls_cert * cert, gnutls_kx_algorithm alg) { - if (_gnutls_map_kx_get_cred(alg) == GNUTLS_CRD_CERTIFICATE) { + + /* FIXME: check here */ + if (_gnutls_map_kx_get_cred(alg, 1) == GNUTLS_CRD_CERTIFICATE || + _gnutls_map_kx_get_cred(alg, 0) == GNUTLS_CRD_CERTIFICATE) + { switch (alg) { case GNUTLS_KX_RSA: if (cert->keyUsage != 0) { @@ -2228,6 +2232,7 @@ int _gnutls_check_x509_key_usage(const gnutls_cert * cert, return 0; } return 0; + case GNUTLS_KX_SRP_RSA: case GNUTLS_KX_DHE_RSA: case GNUTLS_KX_DHE_DSS: case GNUTLS_KX_RSA_EXPORT: -- cgit v1.2.1