summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/auth_srp.c2
-rw-r--r--lib/auth_srp.h5
-rw-r--r--lib/auth_srp_passwd.c39
-rw-r--r--lib/auth_srp_passwd.h2
-rw-r--r--lib/gnutls_cert.c16
-rw-r--r--lib/gnutls_int.h13
-rw-r--r--lib/gnutls_srp.c85
-rw-r--r--lib/gnutls_srp.h1
-rw-r--r--lib/gnutls_ui.h12
-rw-r--r--lib/gnutls_x509.c2
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;
}