gnutls_compress_int.h gnutls_session.h gnutls_priority.h gnutls_auth.h \
auth_anon.h auth_dhe_dss.h gnutls_extensions.h ext_srp.h \
gnutls_auth_int.h crypt_bcrypt.h gnutls_random.h crypt_srpsha1.h \
- cert_b64.h gnutls_srp.h
+ cert_b64.h gnutls_srp.h auth_srp.h auth_srp_passwd.h
lib_LTLIBRARIES = libgnutls.la
libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \
gnutls_priority.c gnutls_hash_int.c gnutls_cipher_int.c \
gnutls_compress_int.c gnutls_session.c gnutls_db.c cert_b64.c \
auth_anon.c auth_dhe_dss.c gnutls_extensions.c ext_srp.c gnutls_auth.c \
- crypt_bcrypt.c crypt.c gnutls_random.c crypt_srpsha1.c gnutls_srp.c
+ crypt_bcrypt.c crypt.c gnutls_random.c crypt_srpsha1.c gnutls_srp.c \
+ auth_srp.c auth_srp_passwd.c
libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
int i, salt_size = strlen(salt);
unsigned char *local_salt, *v;
int passwd_len;
- char *tmp;
+ char *tmp, *g, *n;
passwd_len = strlen(passwd) + 1; /* we want the null also */
if (passwd_len > 56)
}
/* v = g^x mod n */
- vsize = _gnutls_srp_gx(text, 8*3, &v);
+ vsize = _gnutls_srp_gx(text, 8*3, &v, &g, &n);
if (vsize==-1 || v==NULL) {
gnutls_assert();
return NULL;
_gnutls_base64_encode(v, vsize, &rtext);
gnutls_free(v);
- tmp = gnutls_calloc( 1, strlen(magic)+3+strlen(sp)+1+strlen(rtext)+1);
+ tmp = gnutls_malloc( strlen(magic)+3+strlen(sp)+1+strlen(rtext)+strlen(g)+2+strlen(n)+1);
- sprintf( tmp, "%s%.2u$%s$%s", magic, (unsigned int) cost, sp, rtext);
+ sprintf( tmp, "%s%.2u$%s$%s$%s$%s", magic, (unsigned int) cost, sp, rtext, g, n);
+ gnutls_free(g);
+ gnutls_free(n);
gnutls_free(local_salt);
gnutls_free(rtext);
return NULL;
}
- /* base64 encoded text is 4/3 times larger than orignal */
tcp = gnutls_calloc( 1, strlen(magic)+ 3 + result_size +1+1);
- sprintf(tcp, "%s%.2u$%s$", magic, cost, result); /* magic for the BCRYPT */
+ sprintf(tcp, "%s%.2u$%s$", magic, cost, result);
gnutls_free(result);
_gnutls_free_rand(rand);
- /* no longer need cleartext */
e = crypt_bcrypt(pass_new, (const char *) tcp);
gnutls_free(tcp);
int passwd_len;
GNUTLS_MAC_HANDLE h1;
int vsize, hash_len = gnutls_hash_get_algo_len(GNUTLS_MAC_SHA);
- char *tmp;
+ char *tmp, *g, *n;
uint8 *rtext, * csalt;
passwd_len = strlen(passwd); /* we do not want the null */
r1 = gnutls_hash_deinit(h1);
/* v = g^x mod n */
- vsize = _gnutls_srp_gx(r1, hash_len, &v);
+ vsize = _gnutls_srp_gx(r1, hash_len, &v, &g, &n);
gnutls_free(r1);
if (vsize==-1 || v==NULL) {
gnutls_assert();
_gnutls_base64_encode(v, vsize, &rtext);
gnutls_free(v);
- tmp = gnutls_calloc( 1, strlen(sp)+strlen(rtext)+strlen(magic)+1+1 );
+ tmp = gnutls_malloc( strlen(sp)+strlen(rtext)+strlen(magic)+strlen(g)+2+strlen(n)+1+1 );
- sprintf( tmp, "%s%s$%s", magic, sp, rtext);
+ sprintf( tmp, "%s%s$%s$%s$%s", magic, sp, rtext,g ,n);
+ gnutls_free(g);
+ gnutls_free(n);
gnutls_free(rtext);
gnutls_free(local_salt);
char *e = NULL;
int result_size;
- if (salt > 50 || salt < 0) return NULL; /* wow that's pretty long salt */
+ if (salt > 50 || salt <= 0) return NULL; /* wow that's pretty long salt */
rand = _gnutls_get_random( salt, GNUTLS_WEAK_RANDOM);
#include "gnutls_int.h"
int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) {
- /* actually this reads username from data */
+ if (data_size > 0) {
+ state->gnutls_key->username = gnutls_malloc(data_size+1);
+ memcpy(state->gnutls_key->username, data, data_size);
+ state->gnutls_key->username[data_size]=0; /* null terminated */
+ }
return 0;
}
int _gnutls_srp_send_params( GNUTLS_STATE state, opaque** data) {
/* this functions sends the server extension data */
(*data) = NULL;
+ if (state->gnutls_key->username!=NULL) { /* send username */
+ (*data) = strdup( state->gnutls_key->username);
+ return strlen(state->gnutls_key->username);
+ }
return 0;
}
(*state)->gnutls_internals.buffer_handshake = NULL;
(*state)->gnutls_internals.resumable = RESUME_TRUE;
- (*state)->gnutls_internals.cred = NULL; /* no credentials by default */
+ (*state)->gnutls_key->cred = NULL; /* no credentials by default */
+ (*state)->gnutls_key->username = NULL; /* no default username */
gnutls_set_current_version ( (*state), GNUTLS_TLS1); /* default */
(*state)->gnutls_key->client_p = NULL;
(*state)->gnutls_key->client_g = NULL;
(*state)->gnutls_key->dh_secret = NULL;
-
+
+ (*state)->gnutls_key->A = NULL;
+ (*state)->gnutls_key->a = NULL;
+ (*state)->gnutls_key->x = NULL;
+ (*state)->gnutls_key->u = NULL;
+ (*state)->gnutls_key->B = NULL;
+ (*state)->gnutls_key->b = NULL;
+
(*state)->gnutls_internals.certificate_requested = 0;
(*state)->gnutls_internals.certificate_verify_needed = 0;
/* Set default priorities */
gnutls_set_cipher_priority( (*state), 2, GNUTLS_RIJNDAEL, GNUTLS_3DES);
gnutls_set_compression_priority( (*state), 1, GNUTLS_NULL_COMPRESSION);
- gnutls_set_kx_priority( (*state), 2, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA);
+ gnutls_set_kx_priority( (*state), 1, GNUTLS_KX_ANON_DH);
gnutls_set_mac_priority( (*state), 2, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5);
(*state)->security_parameters.session_id_size = 0;
mpi_release((*state)->gnutls_key->client_Y);
mpi_release((*state)->gnutls_key->client_p);
mpi_release((*state)->gnutls_key->client_g);
+
+ mpi_release((*state)->gnutls_key->u);
+ mpi_release((*state)->gnutls_key->a);
+ mpi_release((*state)->gnutls_key->x);
+ mpi_release((*state)->gnutls_key->A);
+ mpi_release((*state)->gnutls_key->B);
+ mpi_release((*state)->gnutls_key->b);
+
mpi_release((*state)->gnutls_key->dh_secret);
gnutls_free((*state)->gnutls_key);
+ gnutls_free((*state)->gnutls_key->username);
+
/* free priorities */
if ((*state)->gnutls_internals.MACAlgorithmPriority.algorithm_priority!=NULL)
gnutls_free((*state)->gnutls_internals.MACAlgorithmPriority.algorithm_priority);
enum BulkCipherAlgorithm { GNUTLS_NULL_CIPHER, GNUTLS_ARCFOUR=1, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL, GNUTLS_TWOFISH, GNUTLS_RIJNDAEL256 };
typedef enum BulkCipherAlgorithm BulkCipherAlgorithm;
-enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH };
+enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP };
typedef enum KXAlgorithm KXAlgorithm;
enum MACAlgorithm { GNUTLS_NULL_MAC, GNUTLS_MAC_MD5, GNUTLS_MAC_SHA };
typedef enum MACAlgorithm MACAlgorithm;
/* include all the kx handler's definitions */
#include "auth_anon.h"
#include "auth_dhe_dss.h"
+#include "auth_srp.h"
#define MAX_CIPHER 256
#define MAX_MAC 256
GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 0, 0, NULL),
GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_DSS, 1, 1, 0, 0, NULL),
GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_RSA, 1, 1, 0, 0, NULL),
-// GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_SRP, 0, 0, 0, 0, &srp_auth_struct),
+ GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_SRP, 0, 0, 0, 0, &srp_auth_struct),
{0}
};
int gnutls_clear_creds( GNUTLS_STATE state) {
AUTH_CRED * ccred, *ncred;
- if (state->gnutls_internals.cred!=NULL) { /* begining of the list */
- ccred = state->gnutls_internals.cred;
+ if (state->gnutls_key->cred!=NULL) { /* begining of the list */
+ ccred = state->gnutls_key->cred;
while(ccred!=NULL) {
ncred = ccred->next;
if (ccred!=NULL) gnutls_free(ccred);
ccred = ncred;
}
- state->gnutls_internals.cred = NULL;
+ state->gnutls_key->cred = NULL;
}
return 0;
AUTH_CRED * ccred, *pcred;
int exists=0;
- if (state->gnutls_internals.cred==NULL) { /* begining of the list */
+ if (state->gnutls_key->cred==NULL) { /* begining of the list */
- state->gnutls_internals.cred = gnutls_malloc(sizeof(AUTH_CRED));
- if (state->gnutls_internals.cred == NULL) return GNUTLS_E_MEMORY_ERROR;
+ state->gnutls_key->cred = gnutls_malloc(sizeof(AUTH_CRED));
+ if (state->gnutls_key->cred == NULL) return GNUTLS_E_MEMORY_ERROR;
- state->gnutls_internals.cred->credentials = cred;
- state->gnutls_internals.cred->next = NULL;
- state->gnutls_internals.cred->algorithm = kx;
+ state->gnutls_key->cred->credentials = cred;
+ state->gnutls_key->cred->next = NULL;
+ state->gnutls_key->cred->algorithm = kx;
} else {
- ccred = state->gnutls_internals.cred;
+ ccred = state->gnutls_key->cred;
while(ccred!=NULL) {
if (ccred->algorithm==kx) {
exists=1;
}
/*
- * This returns an item from the linked list
+ * This returns an pointer to the linked list. Don't
+ * free that!!!
*/
-AUTH_CRED *gnutls_get_kx_cred( GNUTLS_STATE state, int kx) {
+void *_gnutls_get_kx_cred( GNUTLS_KEY key, int kx) {
AUTH_CRED * ccred;
- ccred = state->gnutls_internals.cred;
+ ccred = key->cred;
while(ccred!=NULL) {
if (ccred->algorithm==kx) {
break;
int (*gnutls_process_server_cert_vrfy) ( GNUTLS_KEY, opaque*, int);
} MOD_AUTH_STRUCT;
-typedef struct {
- KXAlgorithm algorithm;
- void* credentials;
- void* next;
-} AUTH_CRED;
#endif
int gnutls_clear_creds( GNUTLS_STATE state);
int gnutls_set_kx_cred( GNUTLS_STATE state, int kx, AUTH_CRED* cred);
-AUTH_CRED *gnutls_get_kx_cred( GNUTLS_STATE state, int kx);
+void *_gnutls_get_kx_cred( GNUTLS_KEY key, int kx);
/* #define E_SIZE 1024 */
#define X_SIZE 512
-#define gcry_mpi_alloc_like(x) gcry_mpi_new(gcry_mpi_get_nbits(x))
-
/****************
* Choose a random value x and calculate e = g^x mod p.
* Return: e and if ret_x is not NULL x.
GNUTLS_ERROR_ENTRY( GNUTLS_E_COMPRESSION_FAILED, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_MEMORY_ERROR, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_UNIMPLEMENTED_FEATURE, 1),
+ GNUTLS_ERROR_ENTRY( GNUTLS_E_INSUFICIENT_CRED, 1),
+ GNUTLS_ERROR_ENTRY( GNUTLS_E_PWD_ERROR, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_EXPIRED, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0),
GNUTLS_ERROR_ENTRY( GNUTLS_E_DB_ERROR, 1),
#define GNUTLS_E_AGAIN -28
#define GNUTLS_E_EXPIRED -29
#define GNUTLS_E_DB_ERROR -30
+#define GNUTLS_E_PWD_ERROR -31
+#define GNUTLS_E_INSUFICIENT_CRED -32
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -50
AlertDescription description;
} Alert;
-typedef struct {
- /* For DH KX */
- MPI KEY;
- MPI client_Y;
- MPI client_g;
- MPI client_p;
- MPI dh_secret;
-} GNUTLS_KEY_A;
-typedef GNUTLS_KEY_A* GNUTLS_KEY;
-
/* STATE */
enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT };
enum BulkCipherAlgorithm { GNUTLS_NULL_CIPHER, GNUTLS_ARCFOUR=1, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL, GNUTLS_TWOFISH, GNUTLS_RIJNDAEL256 };
enum Extensions { GNUTLS_EXTENSION_SRP=7 };
-enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH };
+enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP };
enum KeyExchangeAlgorithm { GNUTLS_RSA, GNUTLS_DIFFIE_HELLMAN };
enum CipherType { CIPHER_STREAM, CIPHER_BLOCK };
enum MACAlgorithm { GNUTLS_NULL_MAC, GNUTLS_MAC_MD5, GNUTLS_MAC_SHA };
typedef enum CompressionMethod CompressionMethod;
typedef enum Extensions Extensions;
+/* STATE (stop) */
+
+typedef struct {
+ KXAlgorithm algorithm;
+ void* credentials;
+ void* next;
+} AUTH_CRED;
+
+typedef struct {
+ /* For DH KX */
+ MPI KEY;
+ MPI client_Y;
+ MPI client_g;
+ MPI client_p;
+ MPI dh_secret;
+ /* for SRP */
+ MPI A;
+ MPI B;
+ MPI u;
+ MPI b;
+ MPI a;
+ MPI x;
+
+ char* username; /* user in srp */
+ AUTH_CRED* cred; /* used in srp, etc */
+} GNUTLS_KEY_A;
+typedef GNUTLS_KEY_A* GNUTLS_KEY;
+
+
+/* STATE (cont) */
+
#include <gnutls_hash_int.h>
#include <gnutls_cipher_int.h>
#include <gnutls_auth.h>
+
typedef struct {
ConnectionEnd entity;
BulkCipherAlgorithm bulk_cipher_algorithm;
char* db_name;
int expire_time;
MOD_AUTH_STRUCT* auth_struct; /* used in handshake packets and KX algorithms */
- AUTH_CRED* cred;
+
} GNUTLS_INTERNALS;
typedef struct {
int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2);
#define _gnutls_version_ssl3(x) _gnutls_version_cmp(x, GNUTLS_SSL3)
+#define gcry_mpi_alloc_like(x) gcry_mpi_new(gcry_mpi_get_nbits(x))
+
#endif /* GNUTLS_INT_H */
#endif
if (_gnutls_kx_server_key_exchange2(algorithm) != 0) {
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx2( state->gnutls_key, &data);
if (data_size<0) {
gnutls_assert();
return data_size;
}
- ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_CLIENT_KEY_EXCHANGE);
+ ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_CLIENT_KEY_EXCHANGE);
gnutls_free(data);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &premaster_size, state->gnutls_key->KEY);
memmove(random, state->security_parameters.client_random, 32);
memmove(&random[32], state->security_parameters.server_random, 32);
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_kx( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_kx0( state->gnutls_key, &data);
if (data_size < 0) {
gnutls_assert();
return data_size;
}
- ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_CLIENT_KEY_EXCHANGE);
+ ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_CLIENT_KEY_EXCHANGE);
gnutls_free(data);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &premaster_size, state->gnutls_key->KEY);
return ret;
- ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx( state->gnutls_key, data, datasize);
+ ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx2( state->gnutls_key, data, datasize);
gnutls_free(data);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
- ret = state->gnutls_internals.auth_struct->gnutls_process_client_kx( state->gnutls_key, data, datasize);
+ ret = state->gnutls_internals.auth_struct->gnutls_process_client_kx0( state->gnutls_key, data, datasize);
gnutls_free(data);
if (ret < 0)
return ret;
#include <defines.h>
#include <gnutls_int.h>
#include <gnutls_errors.h>
-#define gcry_mpi_alloc_like(x) gcry_mpi_new(gcry_mpi_get_nbits(x))
+
/* Here functions for SRP (like g^x mod n) are defined
*/
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
-int _gnutls_srp_gx(opaque *text, int textsize, opaque** result) {
+int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, char** ret_n) {
MPI g, prime, x, e;
size_t n = sizeof diffie_hellman_group1_prime;
- int result_size;
+ int result_size, siz;
if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG,
diffie_hellman_group1_prime, &n)) {
g = mpi_set_ui(NULL, SRP_G);
- /* e = g^x mod prime */
e = gcry_mpi_alloc_like(prime);
+ /* e = g^x mod prime (n) */
mpi_powm(e, g, x, prime);
- mpi_release(prime);
mpi_release(x);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e);
*result = gnutls_malloc(result_size);
gcry_mpi_print(GCRYMPI_FMT_USG, *result, &result_size, e);
}
+
+ siz = 0;
+ gcry_mpi_print(GCRYMPI_FMT_HEX, NULL, &siz, g);
+ if (ret_g!=NULL) {
+ *ret_g = gnutls_malloc(siz+1);
+ gcry_mpi_print(GCRYMPI_FMT_HEX, *ret_g, &siz, g);
+ (*ret_g)[siz] = 0;
+ }
+
+ siz = 0;
+ gcry_mpi_print(GCRYMPI_FMT_HEX, NULL, &siz, prime);
+ if (ret_n!=NULL) {
+ *ret_n = gnutls_malloc(siz+1);
+ gcry_mpi_print(GCRYMPI_FMT_HEX, *ret_n, &siz, prime);
+ (*ret_n)[siz] = 0;
+ }
+
mpi_release(e);
+ mpi_release(g);
+ mpi_release(prime);
+
return result_size;
}
-int _gnutls_srp_gx(opaque *text, int textsize, opaque** result);
+int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, char** ret_n);
if (info.passwd != NULL) {
verify_passwd( info.passwd, info.username, passwd);
- free(cr);
return 0;
}
cr = gnutls_crypt( info.username, passwd, crypt, salt);
+ if (cr==NULL) {
+ fprintf(stderr, "Cannot gnutls_crypt()...\n");
+ return -1;
+ }
+
printf("%s:%s\n", info.username, cr);
free(cr);
return 0;