diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-10-10 15:53:05 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-10-10 15:53:05 +0000 |
commit | 9743e150a3397826993ff28726af63cf20011cc9 (patch) | |
tree | 15c1c26ad1f7b57a25eb0118688c5d92b610ffbe | |
parent | 01f2ebc48ad96b8879ac101fe59e4374268a4567 (diff) | |
download | gnutls-9743e150a3397826993ff28726af63cf20011cc9.tar.gz |
updated name indication extension (dnsname)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | lib/auth_x509.c | 9 | ||||
-rw-r--r-- | lib/ext_dnsname.c | 126 | ||||
-rw-r--r-- | lib/ext_dnsname.h | 9 | ||||
-rw-r--r-- | lib/gnutls.h.in | 7 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 4 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 4 | ||||
-rw-r--r-- | lib/gnutls_extensions.c | 39 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 9 | ||||
-rw-r--r-- | lib/gnutls_int.h | 10 | ||||
-rw-r--r-- | src/cli.c | 5 | ||||
-rw-r--r-- | src/crypt.c | 2 | ||||
-rw-r--r-- | src/serv.c | 8 |
13 files changed, 151 insertions, 83 deletions
@@ -1,6 +1,8 @@ Version 0.2.4 - Better handling of X.509 certificate extensions - Added DHE_RSA ciphersuites +- Updated the Name Indication (dnsname) extension +- Improvements in Diffie Hellman primes handling Version 0.2.3 (19/09/2001) - Memory optimizations in gnutls_recv() diff --git a/lib/auth_x509.c b/lib/auth_x509.c index 07540d831c..86b818fed2 100644 --- a/lib/auth_x509.c +++ b/lib/auth_x509.c @@ -35,7 +35,7 @@ #include <gnutls_record.h> #include <x509_verify.h> #include <gnutls_sig.h> - +#include <ext_dnsname.h> /* Copies data from a internal certificate struct (gnutls_cert) to * exported certificate struct (X509PKI_CLIENT_AUTH_INFO) @@ -891,12 +891,13 @@ int _gnutls_find_apr_cert( GNUTLS_STATE state, gnutls_cert** apr_cert_list, int *apr_cert_list_length = 0; *apr_pkey = NULL; } else { + const char* dnsname = gnutls_ext_get_name_ind( state, GNUTLS_DNSNAME); + if (dnsname==NULL) dnsname=""; + ind = _gnutls_find_cert_list_index(cred->cert_list, cred->ncerts, - state-> - security_parameters. - extensions.dnsname); + dnsname); if (ind < 0) { *apr_cert_list = NULL; diff --git a/lib/ext_dnsname.c b/lib/ext_dnsname.c index e65106098a..3760fe29a4 100644 --- a/lib/ext_dnsname.c +++ b/lib/ext_dnsname.c @@ -24,21 +24,38 @@ #include "gnutls_errors.h" #include "gnutls_num.h" -int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) { +/* This file should have been called ext_name_ind.c + * + * In case of a server: if a DNSNAME extension type is received then it stores + * into the state the value of DNSNAME. The server may use gnutls_ext_get_name_ind(), + * in order to access it. + * + * In case of a client: If a proper DNSNAME extension type is found in the state then + * it sends the extension to the peer. + * + */ + +int _gnutls_name_ind_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) { uint16 len; if (state->security_parameters.entity == GNUTLS_SERVER) { if (data_size > 0) { - if (sizeof( state->security_parameters.extensions.dnsname) > data_size) { - len = READuint16( data); - if (len > data_size || len >= MAX_DNSNAME_SIZE) { - gnutls_assert(); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - /* note that dnsname is in UTF-8 - * format. - */ - memcpy( state->security_parameters.extensions.dnsname, &data[2], len); - state->security_parameters.extensions.dnsname[len]=0; /* null terminated */ + len = READuint16( data); + if (len > data_size || len >= MAX_DNSNAME_SIZE || len < 3) { + gnutls_assert(); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + + switch(data[2]) { + case 0: + if (sizeof( state->security_parameters.extensions.name.dnsname) > len-2) { + state->security_parameters.extensions.name.type = GNUTLS_DNSNAME; + /* note that dnsname is in UTF-8 + * format. + */ + memcpy( state->security_parameters.extensions.name.dnsname, &data[3], len-1); + state->security_parameters.extensions.name.dnsname[len-1]=0; /* null terminated */ + break; + } } } } @@ -48,17 +65,88 @@ int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int dat /* returns data_size or a negative number on failure * data is allocated localy */ -int _gnutls_dnsname_send_params( GNUTLS_STATE state, opaque** data) { +int _gnutls_name_ind_send_params( GNUTLS_STATE state, opaque** data) { uint16 len; /* this function sends the client extension data (dnsname) */ if (state->security_parameters.entity == GNUTLS_CLIENT) { - if ( (len = strlen(state->security_parameters.extensions.dnsname)) > 0) { /* send dnsname */ - (*data) = gnutls_malloc(len+2); /* hold the size also */ - WRITEuint16( len, *data); - memcpy( &(*data)[2], state->security_parameters.extensions.dnsname, len); - return len + 2; + switch (state->security_parameters.extensions.name.type) { + case GNUTLS_DNSNAME: + if ( (len = strlen(state->security_parameters.extensions.name.dnsname)) > 0) { /* send dnsname */ + (*data) = gnutls_malloc(len+3); /* hold the size and the type also */ + + WRITEuint16( len+1, *data); + (*data)[2] = 0; + memcpy( &(*data)[3], state->security_parameters.extensions.name.dnsname, len); + return len + 3; + } + return 0; + default: + return GNUTLS_E_UNIMPLEMENTED_FEATURE; } } - return 0; + return GNUTLS_E_UNKNOWN_ERROR; +} + +/** + * gnutls_ext_get_name_ind - Used to get the name indicator send by a client + * @state: is a &GNUTLS_STATE structure. + * @ind: is a name indicator type + * + * This function will allow you to get the name indication (if any), + * a client has sent. The name indication may be any of the enumeration + * GNUTLS_NAME_IND. + * + * If 'ind' is GNUTLS_DNSNAME, then this function is to be used by servers + * that support virtual hosting. + * The client may give the server the dnsname they connected to. + * + * The return value depends on the 'ind' type. In case of GNUTLS_DNSNAME, + * it is a null terminated string. If no name indication was given (maybe the client + * does not support this extension) this function returns NULL. + * + **/ +const void* gnutls_ext_get_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind) { + if (state->security_parameters.entity==GNUTLS_CLIENT) return NULL; + + switch( ind) { + case GNUTLS_DNSNAME: + if ( state->security_parameters.extensions.name.dnsname[0] == 0 || + state->security_parameters.extensions.name.type!=ind) return NULL; + return state->security_parameters.extensions.name.dnsname; + } + + return NULL; +} + +/** + * gnutls_ext_set_name_ind - Used to set a name indicator to be sent as an extension + * @state: is a &GNUTLS_STATE structure. + * @name: is a null terminated string that contains the dns name. + * @ind: specified the indicator type + * + * This function is to be used by clients that want to inform + * ( via a TLS extension mechanism) the server of the name they + * connected to. This should be used by clients that connect + * to servers that do virtual hosting. + * + * The value of 'name' depends on the 'ind' type. In case of GNUTLS_DNSNAME, + * a null terminated string is expected. + * + **/ +int gnutls_ext_set_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind, const void* name) { +const char* dnsname; + + if (state->security_parameters.entity==GNUTLS_SERVER) return GNUTLS_E_UNIMPLEMENTED_FEATURE; + state->security_parameters.extensions.name.type = ind; + + switch(ind) { + case GNUTLS_DNSNAME: + dnsname = name; + if (strlen( dnsname) >= MAX_DNSNAME_SIZE) return GNUTLS_E_MEMORY_ERROR; + strcpy( state->security_parameters.extensions.name.dnsname, dnsname); + return 0; + } + + return GNUTLS_E_UNIMPLEMENTED_FEATURE; } diff --git a/lib/ext_dnsname.h b/lib/ext_dnsname.h index 89ae8bcfcc..62ba86d5e3 100644 --- a/lib/ext_dnsname.h +++ b/lib/ext_dnsname.h @@ -1,2 +1,7 @@ -int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int data_size); -int _gnutls_dnsname_send_params( GNUTLS_STATE state, opaque** data); +int _gnutls_name_ind_recv_params( GNUTLS_STATE state, const opaque* data, int data_size); +int _gnutls_name_ind_send_params( GNUTLS_STATE state, opaque** data); + +const void* gnutls_ext_get_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind); +int gnutls_ext_set_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind, const void* name); + + diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in index e9ae8e184f..570cf9fce5 100644 --- a/lib/gnutls.h.in +++ b/lib/gnutls.h.in @@ -49,7 +49,7 @@ typedef enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=1 GNUTLS_NO_RENEGOTIATION=100 } AlertDescription; - +typedef enum GNUTLS_NAME_IND { GNUTLS_DNSNAME=1 } GNUTLS_NAME_IND; typedef enum CertificateStatus { GNUTLS_CERT_TRUSTED=1, GNUTLS_CERT_NOT_TRUSTED, GNUTLS_CERT_EXPIRED, GNUTLS_CERT_INVALID, GNUTLS_CERT_NONE } CertificateStatus; typedef enum CertificateRequest { GNUTLS_CERT_REQUEST=1, GNUTLS_CERT_REQUIRE } CertificateRequest; typedef enum CloseRequest { GNUTLS_SHUT_RDWR=0, GNUTLS_SHUT_WR=1 } CloseRequest; @@ -154,8 +154,8 @@ void* gnutls_get_auth_info( GNUTLS_STATE); * This will only exist if the client supports the dnsname * TLS extension. (draft-ietf-tls-extensions) */ -const char* gnutls_ext_get_dnsname( GNUTLS_STATE); -int gnutls_ext_set_dnsname( GNUTLS_STATE, const char* dnsname); +const void* gnutls_ext_get_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind); +int gnutls_ext_set_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind, const void* name); /* This will set the Common Name field in case of X509PKI * authentication. This will be used while verifying the @@ -175,7 +175,6 @@ typedef struct DSTRUCT* SRP_CLIENT_CREDENTIALS; typedef struct DSTRUCT* ANON_SERVER_CREDENTIALS; typedef struct DSTRUCT* ANON_CLIENT_CREDENTIALS; - void gnutls_free_srp_client_sc( SRP_CLIENT_CREDENTIALS sc); int gnutls_allocate_srp_client_sc( SRP_CLIENT_CREDENTIALS *sc); int gnutls_set_srp_client_cred( SRP_CLIENT_CREDENTIALS res, char *username, char* password); diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 50a24b238d..5382598b5f 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -994,7 +994,7 @@ int _gnutls_cert_supported_kx(gnutls_cert * cert, KXAlgorithm ** alg, * common_name (or subjectAltDNSName) field similar to name */ gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list, - int cert_list_length, char *name) + int cert_list_length, const char *name) { gnutls_cert *cert = NULL; int i; @@ -1019,7 +1019,7 @@ gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list, * common_name (or subjectAltDNSName) field similar to name */ int _gnutls_find_cert_list_index(gnutls_cert ** cert_list, - int cert_list_length, char *name) + int cert_list_length, const char *name) { int index = 0; int i; diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index 2765d11229..06e416c70a 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -50,9 +50,9 @@ typedef struct { int _gnutls_cert_supported_kx(gnutls_cert* cert, KXAlgorithm **alg, int *alg_size); PKAlgorithm _gnutls_map_pk_get_pk(KXAlgorithm kx_algorithm); int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert); -gnutls_cert* _gnutls_find_cert( gnutls_cert** cert_list, int cert_list_length, char* name); +gnutls_cert* _gnutls_find_cert( gnutls_cert** cert_list, int cert_list_length, const char* name); int _gnutls_find_cert_list_index(gnutls_cert ** cert_list, - int cert_list_length, char *name); + int cert_list_length, const char *name); #define MAX_INT_DIGITS 4 void _gnutls_int2str(int k, char* data); diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c index 78f263b5b6..636fbb8f0c 100644 --- a/lib/gnutls_extensions.c +++ b/lib/gnutls_extensions.c @@ -39,7 +39,7 @@ typedef struct { #define MAX_EXT 20 /* maximum supported extension */ static gnutls_extension_entry extensions[] = { GNUTLS_EXTENSION_ENTRY( GNUTLS_EXTENSION_SRP, _gnutls_srp_recv_params, _gnutls_srp_send_params), - GNUTLS_EXTENSION_ENTRY( GNUTLS_EXTENSION_DNSNAME, _gnutls_dnsname_recv_params, _gnutls_dnsname_send_params), + GNUTLS_EXTENSION_ENTRY( GNUTLS_EXTENSION_DNSNAME, _gnutls_name_ind_recv_params, _gnutls_name_ind_send_params), {0} }; @@ -164,40 +164,3 @@ int (*ext_func_send)( GNUTLS_STATE, opaque**); } -/** - * gnutls_ext_get_dnsname - Used to get the dnsname a client connected to - * @state: is a &GNUTLS_STATE structure. - * - * This function is to be used by servers that support virtual hosting. - * The client may give the server the dnsname they connected to. - * if no name was given this function returns NULL. - * - **/ -const char* gnutls_ext_get_dnsname( GNUTLS_STATE state) { - if (state->security_parameters.entity==GNUTLS_CLIENT) return NULL; - - if ( state->security_parameters.extensions.dnsname[0] == 0) return NULL; - - return state->security_parameters.extensions.dnsname; -} - -/** - * gnutls_ext_set_dnsname - Used to set the dnsname as an extension - * @state: is a &GNUTLS_STATE structure. - * @dnsname: is a null terminated string that contains the dns name. - * - * This function is to be used by clients that want to inform - * ( via a TLS extension mechanism) the server of the name they - * connected to. This should be used by clients that connect - * to servers that do virtual hosting. - **/ -int gnutls_ext_set_dnsname( GNUTLS_STATE state, const char* dnsname) { - - if (state->security_parameters.entity==GNUTLS_SERVER) return GNUTLS_E_UNIMPLEMENTED_FEATURE; - - if (strlen( dnsname) >= MAX_DNSNAME_SIZE) return GNUTLS_E_MEMORY_ERROR; - - strcpy( state->security_parameters.extensions.dnsname, dnsname); - - return 0; -} diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index bfbe5b505a..62fb2a76f1 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -38,6 +38,7 @@ #include "auth_x509.h" #include "gnutls_cert.h" #include "gnutls_constate.h" +#include <ext_dnsname.h> #ifdef HANDSHAKE_DEBUG #define ERR(x, y) _gnutls_log( "GNUTLS Error: %s (%d)\n", x,y) @@ -1738,6 +1739,7 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state, KXAlgorithm *alg; int alg_size; KXAlgorithm kx; + const char* dnsname; if (state->security_parameters.entity == GNUTLS_CLIENT) return 0; @@ -1758,12 +1760,13 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state, */ cert = NULL; - if (state->security_parameters.extensions.dnsname[0] != 0) { + dnsname = gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME); + + if (dnsname!=NULL && dnsname[0] != 0) { cert = (gnutls_cert *) _gnutls_find_cert(x509_cred->cert_list, x509_cred->ncerts, - state->security_parameters. - extensions.dnsname); + dnsname); } if (cert == NULL && x509_cred->cert_list != NULL) { /* if no such cert, use the first in the list */ diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 562e2ddd20..f23b832dbd 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -104,7 +104,6 @@ typedef enum HandshakeType { GNUTLS_HELLO_REQUEST, GNUTLS_CLIENT_HELLO, GNUTLS_S GNUTLS_CERTIFICATE_REQUEST, GNUTLS_SERVER_HELLO_DONE, GNUTLS_CERTIFICATE_VERIFY, GNUTLS_CLIENT_KEY_EXCHANGE, GNUTLS_FINISHED=20 } HandshakeType; - typedef struct { ChangeCipherSpecType type; @@ -209,9 +208,16 @@ typedef struct { * mechanism. (some extensions may hold parameters in AUTH_INFO * structures instead - see SRP). */ +typedef enum GNUTLS_NAME_IND { GNUTLS_DNSNAME=1 } GNUTLS_NAME_IND; + typedef struct { opaque dnsname[MAX_DNSNAME_SIZE]; - opaque srp_username[MAX_SRP_USERNAME]; + GNUTLS_NAME_IND type; +} name_ind; + +typedef struct { + name_ind name; + opaque srp_username[MAX_SRP_USERNAME]; } TLSExtensions; /* AUTH_INFO structures MUST NOT contain malloced @@ -227,9 +227,8 @@ int main(int argc, char** argv) gnutls_set_cred( state, GNUTLS_X509PKI, xcred); /* This TLS extension may break old implementations. - * - * gnutls_ext_set_dnsname( state, "localhost"); */ + gnutls_ext_set_name_ind( state, GNUTLS_DNSNAME, "localhost"); ret = gnutls_handshake(sd, state); @@ -280,7 +279,7 @@ int main(int argc, char** argv) gnutls_set_cred( state, GNUTLS_SRP, cred); gnutls_set_cred( state, GNUTLS_X509PKI, xcred); - gnutls_ext_set_dnsname( state, "hello.server.org"); + gnutls_ext_set_name_ind( state, GNUTLS_DNSNAME, "hello.server.org"); gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0); diff --git a/src/crypt.c b/src/crypt.c index a2f5ee7eb8..ee42fbc4ec 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -39,6 +39,8 @@ int crypt_int(char *username, char *passwd, int crypt, int salt, static int read_conf_values(MPI * g, MPI * n, char *str, int str_size); static int _verify_passwd_int(char* username, char* passwd, char* salt, MPI g, MPI n); +int _gnutls_srp_generate_prime(unsigned char ** ret_g, unsigned char ** ret_n, int bits); + int generate_create_conf(char *tpasswd_conf, int bits) { FILE *fd; diff --git a/src/serv.c b/src/serv.c index f7878e0737..6efb43021d 100644 --- a/src/serv.c +++ b/src/serv.c @@ -128,9 +128,9 @@ void print_info(GNUTLS_STATE state) printf("%.2X", sesid[i]); printf("\n"); - if ( gnutls_ext_get_dnsname(state) != NULL) { + if ( gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME) != NULL) { printf("- DNSNAME: "); - printf("%s\n", gnutls_ext_get_dnsname(state)); + printf("%s\n", (char*)gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME)); } /* print srp specific data */ @@ -231,9 +231,9 @@ void peer_print_info(int cd, GNUTLS_STATE state) /* if the client supports dnsname extension then * print the hostname he connected to. */ - if (gnutls_ext_get_dnsname(state)!=NULL) { + if (gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME)!=NULL) { sprintf(tmp2, "\n<p>DNSNAME: "); - sprintf(tmp2, "<b>%s</b></p>\n", gnutls_ext_get_dnsname(state)); + sprintf(tmp2, "<b>%s</b></p>\n", (char*)gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME)); } /* print srp specific data */ |