diff options
-rw-r--r-- | lib/auth_srp.c | 2 | ||||
-rw-r--r-- | lib/auth_srp.h | 5 | ||||
-rw-r--r-- | lib/auth_srp_passwd.c | 39 | ||||
-rw-r--r-- | lib/auth_srp_passwd.h | 2 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 16 | ||||
-rw-r--r-- | lib/gnutls_int.h | 13 | ||||
-rw-r--r-- | lib/gnutls_srp.c | 85 | ||||
-rw-r--r-- | lib/gnutls_srp.h | 1 | ||||
-rw-r--r-- | lib/gnutls_ui.h | 12 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 2 |
10 files changed, 133 insertions, 44 deletions
diff --git a/lib/auth_srp.c b/lib/auth_srp.c index cf015dbc18..a47906941f 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -88,7 +88,7 @@ int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data) _gnutls_str_cpy( username, MAX_SRP_USERNAME, state->security_parameters.extensions.srp_username); - pwd_entry = _gnutls_srp_pwd_read_entry( state->gnutls_key, username, &err); + pwd_entry = _gnutls_srp_pwd_read_entry( state, username, &err); if (pwd_entry == NULL) { if (err==0) diff --git a/lib/auth_srp.h b/lib/auth_srp.h index 04bb48cc6f..f7d776f0cf 100644 --- a/lib/auth_srp.h +++ b/lib/auth_srp.h @@ -8,8 +8,9 @@ typedef struct { #define GNUTLS_SRP_CLIENT_CREDENTIALS SRP_CLIENT_CREDENTIALS_INT* typedef struct { - char* password_file; - char* password_conf_file; + char** password_file; + char** password_conf_file; + int password_files; } SRP_SERVER_CREDENTIALS_INT; #define GNUTLS_SRP_SERVER_CREDENTIALS SRP_SERVER_CREDENTIALS_INT* diff --git a/lib/auth_srp_passwd.c b/lib/auth_srp_passwd.c index 88e157b262..cfb414edfa 100644 --- a/lib/auth_srp_passwd.c +++ b/lib/auth_srp_passwd.c @@ -111,15 +111,21 @@ int indx; if (_gnutls_mpi_scan(&entry->v, verifier, &verifier_size) || entry->v == NULL) { gnutls_assert(); - gnutls_free(entry->salt); + gnutls_free( entry->salt); return GNUTLS_E_MPI_SCAN_FAILED; } + gnutls_free( verifier); /* now go for username */ *p='\0'; entry->username = gnutls_strdup(str); + if (entry->username==NULL) { + gnutls_free( entry->salt); + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } return indx; } @@ -195,7 +201,7 @@ int tmp_size; /* this function opens the tpasswd.conf file */ -static int pwd_read_conf( const GNUTLS_SRP_SERVER_CREDENTIALS cred, GNUTLS_SRP_PWD_ENTRY* entry, int index) { +static int pwd_read_conf( const char* pconf_file, GNUTLS_SRP_PWD_ENTRY* entry, int index) { FILE * fd; char line[2*1024]; int i; @@ -203,7 +209,7 @@ static int pwd_read_conf( const GNUTLS_SRP_SERVER_CREDENTIALS cred, GNUTLS_SRP_P sprintf( indexstr, "%d", index); /* Flawfinder: ignore */ - fd = fopen( cred->password_conf_file, "r"); + fd = fopen( pconf_file, "r"); if (fd==NULL) { gnutls_assert(); gnutls_free(entry); @@ -229,14 +235,15 @@ static int pwd_read_conf( const GNUTLS_SRP_SERVER_CREDENTIALS cred, GNUTLS_SRP_P } -GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username, int *err) { +GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_STATE state, char* username, int *err) { const GNUTLS_SRP_SERVER_CREDENTIALS cred; FILE * fd; char line[2*1024]; int i, len; GNUTLS_SRP_PWD_ENTRY * entry = gnutls_malloc(sizeof(GNUTLS_SRP_PWD_ENTRY)); int index; - + int pwd_index = 0; + if (entry==NULL) { gnutls_assert(); *err = 1; @@ -245,7 +252,7 @@ GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username *err = 0; /* normal exit */ - cred = _gnutls_get_cred( key, GNUTLS_CRD_SRP, NULL); + cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_CRD_SRP, NULL); if (cred==NULL) { *err = 1; gnutls_assert(); @@ -253,7 +260,23 @@ GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username return NULL; } - fd = fopen( cred->password_file, "r"); + if (cred->password_files<=0) { + gnutls_assert(); + return NULL; + } + + /* use the callback to select a password file */ + if (state->gnutls_internals.server_srp_callback!=NULL) { + pwd_index = state->gnutls_internals.server_srp_callback( + state, cred->password_file, cred->password_files); + + if (pwd_index < 0) { + gnutls_assert(); + return NULL; + } + } + + fd = fopen( cred->password_file[pwd_index], "r"); if (fd==NULL) { *err = 1; /* failed due to critical error */ gnutls_assert(); @@ -270,7 +293,7 @@ GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username len = strlen(username); if (strncmp( username, line, (i>len)?i:len) == 0) { if ((index = pwd_put_values( entry, line, strlen(line))) >= 0) - if (pwd_read_conf( cred, entry, index)==0) { + if (pwd_read_conf( cred->password_conf_file[pwd_index], entry, index)==0) { return entry; } else { gnutls_free(entry); diff --git a/lib/auth_srp_passwd.h b/lib/auth_srp_passwd.h index fec46265a4..d54846b2ac 100644 --- a/lib/auth_srp_passwd.h +++ b/lib/auth_srp_passwd.h @@ -11,7 +11,7 @@ typedef struct { } GNUTLS_SRP_PWD_ENTRY; /* this is localy alocated. It should be freed using the provided function */ -GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username, int* err); +GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_STATE state, char* username, int* err); void _gnutls_srp_clear_pwd_entry( GNUTLS_SRP_PWD_ENTRY * entry); GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry(void); int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result); diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index efdda83cf2..da35f9b207 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -105,26 +105,26 @@ void gnutls_certificate_free_sc(GNUTLS_CERTIFICATE_CREDENTIALS sc) for (j = 0; j < sc->cert_list_length[i]; j++) { gnutls_free_cert(sc->cert_list[i][j]); } - gnutls_free(sc->cert_list[i]); + gnutls_free( sc->cert_list[i]); } gnutls_free(sc->cert_list_length); gnutls_free(sc->cert_list); for (j = 0; j < sc->x509_ncas; j++) { - gnutls_free_cert(sc->x509_ca_list[j]); + gnutls_free_cert( sc->x509_ca_list[j]); } - gnutls_free(sc->x509_ca_list); + gnutls_free( sc->x509_ca_list); for (i = 0; i < sc->ncerts; i++) { _gnutls_free_private_key(sc->pkey[i]); } - gnutls_free(sc->pkey); - gnutls_free(sc->x509_rdn_sequence.data); + gnutls_free( sc->pkey); + gnutls_free( sc->x509_rdn_sequence.data); - gnutls_free(sc); + gnutls_free( sc); } @@ -258,7 +258,7 @@ void gnutls_certificate_server_set_request(GNUTLS_STATE state, * This function returns 0 on success. **/ void gnutls_certificate_client_set_select_func(GNUTLS_STATE state, - certificate_client_callback_func + certificate_client_select_func * func) { state->gnutls_internals.client_cert_callback = func; @@ -290,7 +290,7 @@ void gnutls_certificate_client_set_select_func(GNUTLS_STATE state, * **/ void gnutls_certificate_server_set_select_func(GNUTLS_STATE state, - certificate_server_callback_func + certificate_server_select_func * func) { state->gnutls_internals.server_cert_callback = func; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 6df7105bda..620384a928 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -388,8 +388,9 @@ typedef struct { #define Protocol_Priority GNUTLS_Priority #define CertType_Priority GNUTLS_Priority -typedef int certificate_client_callback_func(struct GNUTLS_STATE_INT*, const gnutls_datum *, int, const gnutls_datum *, int); -typedef int certificate_server_callback_func(struct GNUTLS_STATE_INT*, const gnutls_datum *, int); +typedef int certificate_client_select_func(struct GNUTLS_STATE_INT*, const gnutls_datum *, int, const gnutls_datum *, int); +typedef int certificate_server_select_func(struct GNUTLS_STATE_INT*, const gnutls_datum *, int); +typedef int srp_server_select_func(struct GNUTLS_STATE_INT*, const char**, int); typedef struct { opaque header[HANDSHAKE_HEADER_SIZE]; @@ -504,8 +505,12 @@ typedef struct { /* this is a callback function to call if no appropriate * client certificates were found. */ - certificate_client_callback_func* client_cert_callback; - certificate_server_callback_func* server_cert_callback; + certificate_client_select_func* client_cert_callback; + certificate_server_select_func* server_cert_callback; + + /* Callback to select the proper password file + */ + srp_server_select_func* server_srp_callback; /* bits to use for DHE and DHA * use _gnutls_dh_get_bits() and gnutls_dh_set_bits() diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c index 78de212de8..6b50177f70 100644 --- a/lib/gnutls_srp.c +++ b/lib/gnutls_srp.c @@ -317,20 +317,22 @@ MPI _gnutls_calc_srp_S2(MPI B, MPI g, MPI x, MPI a, MPI u, MPI n) * the structure. **/ void gnutls_srp_free_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS sc) { - gnutls_free(sc); + gnutls_free( sc->username); + gnutls_free( sc->password); + gnutls_free( sc); } /** - * gnutls_srp_allocate_server_sc - Used to allocate an GNUTLS_SRP_CLIENT_CREDENTIALS structure - * @sc: is a pointer to an &GNUTLS_SRP_CLIENT_CREDENTIALS structure. + * gnutls_srp_allocate_server_sc - Used to allocate an GNUTLS_SRP_SERVER_CREDENTIALS structure + * @sc: is a pointer to an &GNUTLS_SRP_SERVER_CREDENTIALS structure. * * This structure is complex enough to manipulate directly thus * this helper function is provided in order to allocate * the structure. **/ int gnutls_srp_allocate_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS *sc) { - *sc = gnutls_malloc( sizeof(SRP_CLIENT_CREDENTIALS_INT)); - + *sc = gnutls_calloc( 1, sizeof(SRP_CLIENT_CREDENTIALS_INT)); + if (*sc==NULL) return GNUTLS_E_MEMORY_ERROR; return 0; @@ -366,6 +368,14 @@ int gnutls_srp_set_client_cred( GNUTLS_SRP_CLIENT_CREDENTIALS res, char *usernam * the structure. **/ void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc) { +int i; + for (i=0;i<sc->password_files;i++) { + gnutls_free( sc->password_file[i]); + gnutls_free( sc->password_conf_file[i]); + } + gnutls_free(sc->password_file); + gnutls_free(sc->password_conf_file); + gnutls_free(sc); } @@ -377,9 +387,8 @@ void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc) { * this helper function is provided in order to allocate * the structure. **/ - int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc) { - *sc = gnutls_malloc( sizeof(SRP_SERVER_CREDENTIALS_INT)); + *sc = gnutls_calloc( 1, sizeof(SRP_SERVER_CREDENTIALS_INT)); if (*sc==NULL) return GNUTLS_E_MEMORY_ERROR; @@ -394,17 +403,67 @@ int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc) { * **/ int gnutls_srp_set_server_cred_file( GNUTLS_SRP_SERVER_CREDENTIALS res, char *password_file, char * password_conf_file) { +int i; + res->password_file = gnutls_realloc( res->password_file, + sizeof(char*)*(res->password_files+1)); + if (res->password_file==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } - res->password_file = gnutls_strdup( password_file); - if (res->password_file==NULL) return GNUTLS_E_MEMORY_ERROR; - - res->password_conf_file = gnutls_strdup( password_conf_file); + res->password_conf_file = gnutls_realloc( res->password_conf_file, + sizeof(char*)*(res->password_files+1)); if (res->password_conf_file==NULL) { - gnutls_free(res->password_file); + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + i = res->password_files++; + + res->password_file[i] = gnutls_strdup( password_file); + if (res->password_file[i]==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->password_conf_file[i] = gnutls_strdup( password_conf_file); + if (res->password_conf_file[i]==NULL) { + gnutls_assert(); + gnutls_free(res->password_file[i]); return GNUTLS_E_MEMORY_ERROR; } return 0; } - +/** + * gnutls_srp_server_set_select_func - Used to set a callback to assist in selecting the proper password file + * @state: is a &GNUTLS_STATE structure. + * @func: is the callback function + * + * The callback's function form is: + * int (*callback)(GNUTLS_STATE, const char** pfiles, int npfiles); + * + * 'pfiles' contains 'npfiles' char* structures which hold + * the password file name. + * + * This function specifies what we, in case of a server, are going + * to do when we have to use a password file. If this callback + * function is not provided then gnutls will automaticaly select the + * first password file + * + * In case the callback returned a negative number then gnutls will + * not attempt to choose the appropriate certificate and the caller function + * will fail. + * + * The callback function will only be called once per handshake. + * The callback function should return the index of the certificate + * choosen by the server. -1 indicates an error. + * + **/ +void gnutls_srp_server_set_select_func(GNUTLS_STATE state, + srp_server_select_func + * func) +{ + state->gnutls_internals.server_srp_callback = func; +} diff --git a/lib/gnutls_srp.h b/lib/gnutls_srp.h index 31bc66d2bc..7a9be24f28 100644 --- a/lib/gnutls_srp.h +++ b/lib/gnutls_srp.h @@ -11,5 +11,4 @@ int _gnutls_srp_gn( opaque** ret_g, opaque** ret_n, int bits); extern const uint8 diffie_hellman_group1_prime[130]; /* g is defined to be 2 */ -#define SRP_G 2 #define SRP_MAX_HASH_SIZE 24 diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h index fcaf330771..9337b0569d 100644 --- a/lib/gnutls_ui.h +++ b/lib/gnutls_ui.h @@ -49,8 +49,10 @@ typedef enum GNUTLS_X509_SUBJECT_ALT_NAME { # ifdef LIBGNUTLS_VERSION /* These are defined only in gnutls.h */ -typedef int gnutls_certificate_client_callback_func(GNUTLS_STATE, const gnutls_datum *, int, const gnutls_datum *, int); -typedef int gnutls_certificate_server_callback_func(GNUTLS_STATE, const gnutls_datum *, int); +typedef int gnutls_certificate_client_select_func(GNUTLS_STATE, const gnutls_datum *, int, const gnutls_datum *, int); +typedef int gnutls_certificate_server_select_func(GNUTLS_STATE, const gnutls_datum *, int); + +typedef int gnutls_srp_server_select_func(GNUTLS_STATE, const char **, int); /* Functions that allow AUTH_INFO structures handling */ @@ -61,6 +63,8 @@ GNUTLS_CredType gnutls_auth_get_type( GNUTLS_STATE state); const char* gnutls_srp_server_get_username( GNUTLS_STATE state); +void gnutls_srp_server_set_select_func( GNUTLS_SRP_SERVER_CREDENTIALS, gnutls_srp_server_select_func *); + /* ANON */ void gnutls_dh_set_bits( GNUTLS_STATE state, int bits); @@ -68,8 +72,8 @@ int gnutls_dh_get_bits( GNUTLS_STATE); /* X509PKI */ -void gnutls_certificate_client_set_select_func( GNUTLS_CERTIFICATE_CREDENTIALS, gnutls_certificate_client_callback_func *); -void gnutls_certificate_server_set_select_func( GNUTLS_CERTIFICATE_CREDENTIALS, gnutls_certificate_server_callback_func *); +void gnutls_certificate_client_set_select_func( GNUTLS_CERTIFICATE_CREDENTIALS, gnutls_certificate_client_select_func *); +void gnutls_certificate_server_set_select_func( GNUTLS_CERTIFICATE_CREDENTIALS, gnutls_certificate_server_select_func *); void gnutls_certificate_server_set_request( GNUTLS_STATE, GNUTLS_CertificateRequest); diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index 8e8a57bc07..d6059b4ed1 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -1084,8 +1084,6 @@ static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *ca, int c res->x509_ncas = i - 1; - - return 0; } |