diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-05-05 22:24:00 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-05-05 22:24:00 +0000 |
commit | c2fd5ac55082c85394c5d37c2a59fb1fb503a205 (patch) | |
tree | 0b1948f5d08577d70253267ff272dd39eef89553 | |
parent | 24b938de479d51c8568c61ce6f26c147bf8ae2fe (diff) | |
download | gnutls-c2fd5ac55082c85394c5d37c2a59fb1fb503a205.tar.gz |
some hacks in order to exchange the algorithm used to hash
the password...
-rw-r--r-- | lib/auth_srp.c | 26 | ||||
-rw-r--r-- | lib/crypt.c | 5 | ||||
-rw-r--r-- | lib/crypt_bcrypt.c | 46 | ||||
-rw-r--r-- | lib/crypt_bcrypt.h | 1 | ||||
-rw-r--r-- | lib/crypt_srpsha1.c | 2 | ||||
-rw-r--r-- | lib/gnutls.h | 2 | ||||
-rw-r--r-- | lib/gnutls_dh.c | 36 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 1 | ||||
-rw-r--r-- | lib/gnutls_errors.h | 1 | ||||
-rw-r--r-- | lib/gnutls_int.h | 4 | ||||
-rw-r--r-- | lib/gnutls_srp.c | 76 | ||||
-rw-r--r-- | lib/gnutls_srp.h | 2 |
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); |