summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-05-05 22:24:00 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-05-05 22:24:00 +0000
commitc2fd5ac55082c85394c5d37c2a59fb1fb503a205 (patch)
tree0b1948f5d08577d70253267ff272dd39eef89553
parent24b938de479d51c8568c61ce6f26c147bf8ae2fe (diff)
downloadgnutls-c2fd5ac55082c85394c5d37c2a59fb1fb503a205.tar.gz
some hacks in order to exchange the algorithm used to hash
the password...
-rw-r--r--lib/auth_srp.c26
-rw-r--r--lib/crypt.c5
-rw-r--r--lib/crypt_bcrypt.c46
-rw-r--r--lib/crypt_bcrypt.h1
-rw-r--r--lib/crypt_srpsha1.c2
-rw-r--r--lib/gnutls.h2
-rw-r--r--lib/gnutls_dh.c36
-rw-r--r--lib/gnutls_errors.c1
-rw-r--r--lib/gnutls_errors.h1
-rw-r--r--lib/gnutls_int.h4
-rw-r--r--lib/gnutls_srp.c76
-rw-r--r--lib/gnutls_srp.h2
12 files changed, 126 insertions, 76 deletions
diff --git a/lib/auth_srp.c b/lib/auth_srp.c
index a4b6e40c17..12429eb9b7 100644
--- a/lib/auth_srp.c
+++ b/lib/auth_srp.c
@@ -60,14 +60,15 @@ MOD_AUTH_STRUCT srp_auth_struct = {
#define V key->x
#define S key->KEY
-/* Send the first key exchange message ( g, n, s) */
+/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number */
int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
{
- size_t n_g, n_n;
+ size_t n_g, n_n, n_s;
uint16 _n_n, _n_g, _n_s;
size_t ret;
uint8 *data_n, *data_s;
uint8 *data_g;
+ uint8 pwd_algo;
GNUTLS_SRP_PWD_ENTRY *pwd_entry;
if (key->username == NULL) {
@@ -80,6 +81,8 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
return GNUTLS_E_PWD_ERROR;
}
+ pwd_algo = (uint8) pwd_entry->algorithm;
+
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_g, pwd_entry->g);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_n, pwd_entry->n);
@@ -92,7 +95,7 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
mpi_set(N, pwd_entry->n);
mpi_set(V, pwd_entry->v);
- (*data) = gnutls_malloc(n_n + n_g + pwd_entry->salt_size + 6);
+ (*data) = gnutls_malloc(n_n + n_g + pwd_entry->salt_size + 6 + 1);
/* copy G (generator) to data */
data_g = (*data);
@@ -121,6 +124,7 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
_n_s = pwd_entry->salt_size;
memcpy(&data_s[2], pwd_entry->salt, _n_s);
+ n_s = _n_s;
#ifndef WORDS_BIGENDIAN
_n_s = byteswap16(_n_s);
memcpy(data_s, &_n_s, 2);
@@ -128,8 +132,10 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
memcpy(data_s, &_n_s, 2);
#endif
+ /* copy the algorithm used to generate the verifier */
+ memcpy( &data_s[2+n_s], &pwd_algo, 1);
- ret = n_g + n_n + pwd_entry->salt_size + 6;
+ ret = n_g + n_n + pwd_entry->salt_size + 6 + 1;
gnutls_free(pwd_entry);
return ret;
@@ -225,7 +231,7 @@ int proc_srp_server_kx(GNUTLS_KEY key, opaque * data, int data_size)
size_t _n_s, _n_g, _n_n;
uint8 *data_n;
uint8 *data_g;
- uint8 *data_s;
+ uint8 *data_s, pwd_algo;
int i;
opaque *hd;
char *username;
@@ -292,9 +298,17 @@ int proc_srp_server_kx(GNUTLS_KEY key, opaque * data, int data_size)
return GNUTLS_E_MPI_SCAN_FAILED;
}
+/* read the algorithm used to generate V */
+ memcpy( &pwd_algo, &data_s[n_s], 1);
+
/* generate x = SHA(s | SHA(U | ":" | p))
+ * (or the equivalent using bcrypt)
*/
- hd = _gnutls_calc_srp_sha( username, password, data_s, n_s);
+ hd = _gnutls_calc_srp_x( username, password, data_s, n_s, pwd_algo);
+ if (hd==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_HASH_FAILED;
+ }
_n_g = 20;
if (gcry_mpi_scan(&key->x, GCRYMPI_FMT_USG, hd, &_n_g) != 0) {
gnutls_assert();
diff --git a/lib/crypt.c b/lib/crypt.c
index 3f71923a33..c14b0c54c9 100644
--- a/lib/crypt.c
+++ b/lib/crypt.c
@@ -19,14 +19,11 @@
*/
#include "defines.h"
+#include "gnutls_int.h"
#include "crypt_bcrypt.h"
#include "crypt_srpsha1.h"
#include "gnutls_random.h"
-enum crypt_algo { BLOWFISH_CRYPT, SRPSHA1_CRYPT };
-
-typedef enum crypt_algo crypt_algo;
-
char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt) {
switch(algo) {
diff --git a/lib/crypt_bcrypt.c b/lib/crypt_bcrypt.c
index cabfb54182..bf50bdd0f6 100644
--- a/lib/crypt_bcrypt.c
+++ b/lib/crypt_bcrypt.c
@@ -600,10 +600,10 @@ char *
unsigned char text[24] = "OrpheanBeholderScryDoubt";
uint8 *csalt;
uint8 *rtext;
- int cost, vsize;
+ uint8 cost;
int i, salt_size = strlen(salt);
unsigned char *local_salt, *v;
- int passwd_len;
+ int passwd_len, vsize;
char *tmp, *g, *n;
passwd_len = strlen(passwd) + 1; /* we want the null also */
@@ -618,19 +618,14 @@ char *
if (!strncmp((char *) sp, magic, strlen(magic)))
sp += strlen(magic);
- cost = atoi((char *) sp);
- do { /* move to salt */
- sp++;
- } while (*sp != '$');
- sp++;
-
tsp = sp;
while((*tsp)!='$') tsp++;
*tsp = '\0'; /* put a null after the end of salt */
_gnutls_base64_decode( sp, strlen(sp), &csalt);
- ctx = _blf_init( csalt, passwd, passwd_len, cost);
+ cost = (uint8) csalt[0];
+ ctx = _blf_init( &csalt[1], passwd, passwd_len, cost);
gnutls_free(csalt);
for (i = 0; i < 64; i++) {
@@ -670,19 +665,20 @@ char *crypt_bcrypt_wrapper(const char *pass_new, int cost)
char *e = NULL;
int result_size;
- rand = _gnutls_get_random( 16, GNUTLS_WEAK_RANDOM);
+ rand = _gnutls_get_random( 17, GNUTLS_WEAK_RANDOM);
/* cost should be <32 and >6 */
if (cost >=32) cost=31;
if (cost < 1) cost = 1;
- result_size = _gnutls_base64_encode( rand, 16, &result);
+ rand[0] = (uint8) cost;
+ result_size = _gnutls_base64_encode( rand, 17, &result);
if (result_size < 0) {
gnutls_assert();
return NULL;
}
tcp = gnutls_calloc( 1, strlen(magic)+ 3 + result_size +1+1);
- sprintf(tcp, "%s%.2u$%s$", magic, cost, result);
+ sprintf(tcp, "%s$%s$", magic, result);
gnutls_free(result);
@@ -694,3 +690,29 @@ char *crypt_bcrypt_wrapper(const char *pass_new, int cost)
return e;
}
+void *
+ _gnutls_calc_srp_bcrypt( char *passwd, opaque *salt, int salt_size)
+{
+ blf_ctx *ctx;
+ opaque text[24] = "OrpheanBeholderScryDoubt";
+ int passwd_len, i;
+ opaque *tmp;
+
+ passwd_len = strlen(passwd) + 1; /* we want the null also */
+ if (passwd_len > 56)
+ passwd_len = 56;
+
+ ctx = _blf_init( &salt[1], passwd, passwd_len, salt[0]);
+
+ tmp = malloc(sizeof(text));
+ memcpy( tmp, text, sizeof(text));
+
+ for (i = 0; i < 64; i++) {
+ _blf_encrypt(ctx, (uint8 *) tmp);
+ _blf_encrypt(ctx, (uint8 *) &tmp[8]);
+ _blf_encrypt(ctx, (uint8 *) &tmp[16]);
+ }
+
+ _blf_deinit(ctx);
+ return tmp;
+}
diff --git a/lib/crypt_bcrypt.h b/lib/crypt_bcrypt.h
index 2a97aff184..aedb3c6aa2 100644
--- a/lib/crypt_bcrypt.h
+++ b/lib/crypt_bcrypt.h
@@ -1,2 +1,3 @@
char * crypt_bcrypt (const char *passwd, const char *salt);
char *crypt_bcrypt_wrapper(const char *pass_new, int cost);
+void * _gnutls_calc_srp_bcrypt( char *passwd, opaque *salt, int salt_size);
diff --git a/lib/crypt_srpsha1.c b/lib/crypt_srpsha1.c
index 6d3ccc8583..c5d22c073f 100644
--- a/lib/crypt_srpsha1.c
+++ b/lib/crypt_srpsha1.c
@@ -28,7 +28,7 @@
/* x = SHA(<salt> | SHA(<username> | ":" | <raw password>)) */
-static const char magic[] = "$4$";
+static const char magic[] = "$0$";
char *
crypt_srpsha1(const char* username, const char *passwd, const char *salt)
diff --git a/lib/gnutls.h b/lib/gnutls.h
index 59e63ff8d9..bc4658cff8 100644
--- a/lib/gnutls.h
+++ b/lib/gnutls.h
@@ -97,7 +97,7 @@ int gnutls_clean_db( GNUTLS_STATE state);
/* crypt functions */
-enum crypt_algo { BLOWFISH_CRYPT, SRPSHA1_CRYPT };
+enum crypt_algo { SRPSHA1_CRYPT, BLOWFISH_CRYPT=2 };
typedef enum crypt_algo crypt_algo;
char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt);
diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c
index 1a8570bb34..eda6795ecc 100644
--- a/lib/gnutls_dh.c
+++ b/lib/gnutls_dh.c
@@ -77,23 +77,23 @@ MPI gnutls_calc_dh_secret(MPI * ret_x)
}
/*_gnutls_dump_mpi(stderr, "prime=", prime ); */
- g = mpi_set_ui(NULL, DH_G);
- x = mpi_new(X_SIZE); /* FIXME: allocate in secure memory */
+ g = gcry_mpi_set_ui(NULL, DH_G);
+ x = gcry_mpi_new(X_SIZE); /* FIXME: allocate in secure memory */
gcry_mpi_randomize(x, X_SIZE, GCRY_STRONG_RANDOM);
/* fixme: set high bit of x and select a larger one */
-/* e = mpi_new(E_SIZE); */
+/* e = gcry_mpi_new(E_SIZE); */
e = gcry_mpi_alloc_like(prime);
/* e = g^x mod prime */
- mpi_powm(e, g, x, prime);
+ gcry_mpi_powm(e, g, x, prime);
if (ret_x)
*ret_x = x;
else
- mpi_release(x);
- mpi_release(g);
- mpi_release(prime);
+ gcry_mpi_release(x);
+ gcry_mpi_release(g);
+ gcry_mpi_release(prime);
return e;
}
@@ -101,18 +101,18 @@ MPI _gnutls_calc_dh_secret(MPI * ret_x, MPI g, MPI prime)
{
MPI e, x;
- x = mpi_new(X_SIZE); /* FIXME: allocate in secure memory */
+ x = gcry_mpi_new(X_SIZE); /* FIXME: allocate in secure memory */
gcry_mpi_randomize(x, X_SIZE, GCRY_STRONG_RANDOM);
/* fixme: set high bit of x and select a larger one */
e = gcry_mpi_alloc_like(prime);
-/* e = mpi_new(E_SIZE); */
- mpi_powm(e, g, x, prime);
+/* e = gcry_mpi_new(E_SIZE); */
+ gcry_mpi_powm(e, g, x, prime);
if (ret_x)
*ret_x = x;
else
- mpi_release(x);
+ gcry_mpi_release(x);
return e;
}
@@ -128,12 +128,12 @@ MPI gnutls_get_dh_params(MPI * ret_p)
abort();
}
- g = mpi_set_ui(NULL, DH_G);
+ g = gcry_mpi_set_ui(NULL, DH_G);
if (ret_p)
*ret_p = prime;
else
- mpi_release(prime);
+ gcry_mpi_release(prime);
return g;
}
@@ -151,9 +151,9 @@ MPI gnutls_calc_dh_key(MPI f, MPI x)
/*_gnutls_dump_mpi(stderr, "prime=", prime ); */
k = gcry_mpi_alloc_like(prime);
-/* k = mpi_new(E_SIZE); FIXME: allocate in secure memory */
- mpi_powm(k, f, x, prime);
- mpi_release(prime);
+/* k = gcry_mpi_new(E_SIZE); FIXME: allocate in secure memory */
+ gcry_mpi_powm(k, f, x, prime);
+ gcry_mpi_release(prime);
return k;
}
@@ -161,8 +161,8 @@ MPI _gnutls_calc_dh_key(MPI f, MPI x, MPI prime)
{
MPI k;
-/* k = mpi_new(E_SIZE); FIXME: allocate in secure memory */
+/* k = gcry_mpi_new(E_SIZE); FIXME: allocate in secure memory */
k = gcry_mpi_alloc_like(prime);
- mpi_powm(k, f, x, prime);
+ gcry_mpi_powm(k, f, x, prime);
return k;
}
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 6b34a55602..5eaaa41bd2 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -65,6 +65,7 @@ static gnutls_error_entry error_algorithms[] = {
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_HASH_FAILED, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0),
GNUTLS_ERROR_ENTRY( GNUTLS_E_DB_ERROR, 1),
{0}
diff --git a/lib/gnutls_errors.h b/lib/gnutls_errors.h
index 74c0880611..4d0daf19bf 100644
--- a/lib/gnutls_errors.h
+++ b/lib/gnutls_errors.h
@@ -52,6 +52,7 @@
#define GNUTLS_E_DB_ERROR -30
#define GNUTLS_E_PWD_ERROR -31
#define GNUTLS_E_INSUFICIENT_CRED -32
+#define GNUTLS_E_HASH_FAILED -33
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -50
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 7776f7e9ce..b4b6ad5de5 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -73,7 +73,7 @@ typedef struct {
typedef unsigned char opaque;
-
+enum crypt_algo { SRPSHA1_CRYPT, BLOWFISH_CRYPT=2 };
enum ChangeCipherSpecType { GNUTLS_TYPE_CHANGE_CIPHER_SPEC=1 };
enum AlertLevel { GNUTLS_WARNING=1, GNUTLS_FATAL };
enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=10, GNUTLS_BAD_RECORD_MAC=20,
@@ -89,6 +89,7 @@ enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=10, GNUTL
typedef enum AlertDescription AlertDescription;
typedef enum AlertLevel AlertLevel;
typedef enum ChangeCipherSpecType ChangeCipherSpecType;
+typedef enum crypt_algo crypt_algo;
enum HandshakeType { GNUTLS_HELLO_REQUEST, GNUTLS_CLIENT_HELLO, GNUTLS_SERVER_HELLO,
GNUTLS_CERTIFICATE=11, GNUTLS_SERVER_KEY_EXCHANGE,
@@ -160,6 +161,7 @@ typedef struct {
* to hold the requested user - currently only in srp
*/
char* username;
+ uint8 crypt_algo;
AUTH_CRED* cred; /* used in srp, etc */
} GNUTLS_KEY_A;
diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c
index 06b870f146..5b4634e49d 100644
--- a/lib/gnutls_srp.c
+++ b/lib/gnutls_srp.c
@@ -21,6 +21,7 @@
#include <defines.h>
#include <gnutls_int.h>
#include <gnutls_errors.h>
+#include <crypt_bcrypt.h>
/* Here functions for SRP (like g^x mod n) are defined
*/
@@ -59,18 +60,18 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, ch
if (gcry_mpi_scan(&x, GCRYMPI_FMT_USG,
text, &textsize)) {
gnutls_assert();
- mpi_release(prime);
+ gcry_mpi_release(prime);
return -1;
}
- g = mpi_set_ui(NULL, SRP_G);
+ g = gcry_mpi_set_ui(NULL, SRP_G);
e = gcry_mpi_alloc_like(prime);
/* e = g^x mod prime (n) */
- mpi_powm(e, g, x, prime);
+ gcry_mpi_powm(e, g, x, prime);
- mpi_release(x);
+ gcry_mpi_release(x);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e);
if (result!=NULL) {
@@ -94,9 +95,9 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, ch
(*ret_n)[siz] = 0;
}
- mpi_release(e);
- mpi_release(g);
- mpi_release(prime);
+ gcry_mpi_release(e);
+ gcry_mpi_release(g);
+ gcry_mpi_release(prime);
return result_size;
@@ -115,20 +116,20 @@ MPI _gnutls_calc_srp_B(MPI * ret_b, MPI g, MPI n, MPI v)
/* calculate: B = (v + g^b) % N */
bits = gcry_mpi_get_nbits(n);
- b = mpi_new(bits); /* FIXME: allocate in secure memory */
+ b = gcry_mpi_new(bits); /* FIXME: allocate in secure memory */
gcry_mpi_randomize(b, bits, GCRY_STRONG_RANDOM);
- tmpB = mpi_new(bits); /* FIXME: allocate in secure memory */
- B = mpi_new(bits); /* FIXME: allocate in secure memory */
- mpi_powm(tmpB, g, b, n);
- mpi_addm(B, v, tmpB, n);
+ tmpB = gcry_mpi_new(bits); /* FIXME: allocate in secure memory */
+ B = gcry_mpi_new(bits); /* FIXME: allocate in secure memory */
+ gcry_mpi_powm(tmpB, g, b, n);
+ gcry_mpi_addm(B, v, tmpB, n);
- mpi_release(tmpB);
+ gcry_mpi_release(tmpB);
if (ret_b)
*ret_b = b;
else
- mpi_release(b);
+ gcry_mpi_release(b);
return B;
}
@@ -153,7 +154,7 @@ MPI ret;
gnutls_free(hd);
gnutls_free(b_holder);
- ret = mpi_set_ui(NULL, u);
+ ret = gcry_mpi_set_ui(NULL, u);
return ret;
}
@@ -170,12 +171,12 @@ S = gcry_mpi_alloc_like(n);
tmp1 = gcry_mpi_alloc_like(n);
tmp2 = gcry_mpi_alloc_like(n);
-mpi_pow(tmp1, v, u);
-mpi_mul(tmp2, A, tmp1);
-mpi_release(tmp1);
+gcry_mpi_pow(tmp1, v, u);
+gcry_mpi_mul(tmp2, A, tmp1);
+gcry_mpi_release(tmp1);
-mpi_powm(S, tmp2, b, n);
-mpi_release(tmp2);
+gcry_mpi_powm(S, tmp2, b, n);
+gcry_mpi_release(tmp2);
return S;
}
@@ -190,16 +191,16 @@ MPI A;
int bits;
bits = gcry_mpi_get_nbits(n);
- tmpa = mpi_new(bits); /* FIXME: allocate in secure memory */
+ tmpa = gcry_mpi_new(bits); /* FIXME: allocate in secure memory */
gcry_mpi_randomize(tmpa, bits, GCRY_STRONG_RANDOM);
- A = mpi_new(bits); /* FIXME: allocate in secure memory */
- mpi_powm(A, g, tmpa, n);
+ A = gcry_mpi_new(bits); /* FIXME: allocate in secure memory */
+ gcry_mpi_powm(A, g, tmpa, n);
if (a!=NULL)
*a = tmpa;
else
- mpi_release(tmpa);
+ gcry_mpi_release(tmpa);
return A;
}
@@ -227,6 +228,17 @@ opaque* hd;
return hd;
}
+void* _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, uint8 crypt_algo) {
+
+ switch(crypt_algo) {
+ case SRPSHA1_CRYPT:
+ return _gnutls_calc_srp_sha( username, password, salt, salt_size);
+ case BLOWFISH_CRYPT:
+ return _gnutls_calc_srp_bcrypt( password, salt, salt_size);
+ }
+ return NULL;
+}
+
/* S = (B - g^x) ^ (a + u * x) % N
* this is our shared key
@@ -239,18 +251,18 @@ MPI S, tmp1, tmp2, tmp4;
tmp1 = gcry_mpi_alloc_like(n);
tmp2 = gcry_mpi_alloc_like(n);
- mpi_pow(tmp1, g, x);
- mpi_sub(tmp2, B, tmp1);
+ gcry_mpi_pow(tmp1, g, x);
+ gcry_mpi_sub(tmp2, B, tmp1);
tmp4 = gcry_mpi_alloc_like(n);
- mpi_add(tmp1, u, x);
- mpi_add(tmp4, a, tmp1);
- mpi_release(tmp1);
+ gcry_mpi_add(tmp1, u, x);
+ gcry_mpi_add(tmp4, a, tmp1);
+ gcry_mpi_release(tmp1);
- mpi_powm(S, tmp2, tmp4, n);
- mpi_release(tmp2);
- mpi_release(tmp4);
+ gcry_mpi_powm(S, tmp2, tmp4, n);
+ gcry_mpi_release(tmp2);
+ gcry_mpi_release(tmp4);
return S;
}
diff --git a/lib/gnutls_srp.h b/lib/gnutls_srp.h
index fdb6e7f6fe..03ea949d30 100644
--- a/lib/gnutls_srp.h
+++ b/lib/gnutls_srp.h
@@ -3,5 +3,5 @@ MPI _gnutls_calc_srp_B(MPI * ret_b, MPI g, MPI n, MPI v);
MPI _gnutls_calc_srp_u( MPI B);
MPI _gnutls_calc_srp_S1(MPI A, MPI b, MPI u, MPI v, MPI n);
MPI _gnutls_calc_srp_A(MPI *a, MPI g, MPI n);
-void* _gnutls_calc_srp_sha( char* username, char* password, opaque* salt, int salt_size);
+void* _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, int crypt_algo);
MPI _gnutls_calc_srp_S2(MPI B, MPI g, MPI x, MPI a, MPI u, MPI n);