diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-05-04 13:05:48 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-05-04 13:05:48 +0000 |
commit | 8f82a8e581e02a32aa97069052cdfccfc522b930 (patch) | |
tree | 06edca357d0f97648488fad490676d3b61b6553e | |
parent | d93f1d1688a500a822d1d7793cc8e60563436db1 (diff) | |
download | gnutls-8f82a8e581e02a32aa97069052cdfccfc522b930.tar.gz |
More adds for SRP - SRPSHA1 and bcrypt
-rw-r--r-- | lib/Makefile.am | 5 | ||||
-rw-r--r-- | lib/cert_b64.h | 6 | ||||
-rw-r--r-- | lib/crypt.c | 20 | ||||
-rw-r--r-- | lib/crypt_bcrypt.c | 253 | ||||
-rw-r--r-- | lib/crypt_srpsha1.c | 126 | ||||
-rw-r--r-- | lib/crypt_srpsha1.h | 2 | ||||
-rw-r--r-- | lib/gnutls.h | 4 | ||||
-rw-r--r-- | lib/gnutls_dh.c | 6 | ||||
-rw-r--r-- | lib/gnutls_srp.c | 84 | ||||
-rw-r--r-- | lib/gnutls_srp.h | 1 | ||||
-rw-r--r-- | src/crypt.c | 24 | ||||
-rw-r--r-- | src/crypt.gaa | 8 | ||||
-rw-r--r-- | src/gaa.h | 4 | ||||
-rw-r--r-- | src/gaaout.c | 58 |
14 files changed, 386 insertions, 215 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 16f6a20fe2..5051a76e3f 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -5,7 +5,8 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h \ gnutls_kx.h gnutls_hash_int.h gnutls_cipher_int.h gnutls_db.h \ 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 + gnutls_auth_int.h crypt_bcrypt.h gnutls_random.h crypt_srpsha1.h \ + cert_b64.h gnutls_srp.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 \ @@ -13,5 +14,5 @@ libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.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_bcrypt.c crypt.c gnutls_random.c crypt_srpsha1.c gnutls_srp.c libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) diff --git a/lib/cert_b64.h b/lib/cert_b64.h new file mode 100644 index 0000000000..58d4353044 --- /dev/null +++ b/lib/cert_b64.h @@ -0,0 +1,6 @@ +int _gnutls_base64_encode(uint8 * data, int data_size, uint8 ** result); +int _gnutls_fbase64_encode(char *msg, uint8 * data, int data_size, + uint8 ** result); +int _gnutls_base64_decode(uint8 * data, int data_size, uint8 ** result); +int _gnutls_fbase64_decode(char *msg, uint8 * data, int data_size, + uint8 ** result); diff --git a/lib/crypt.c b/lib/crypt.c index 054f8a56af..3f71923a33 100644 --- a/lib/crypt.c +++ b/lib/crypt.c @@ -20,19 +20,22 @@ #include "defines.h" #include "crypt_bcrypt.h" +#include "crypt_srpsha1.h" #include "gnutls_random.h" -enum crypt_algo { MD5_CRYPT, BLOWFISH_CRYPT }; +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) { +char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt) { switch(algo) { - case MD5_CRYPT: - break; case BLOWFISH_CRYPT: /* bcrypt */ - return crypt_bcrypt_wrapper(passwd, 6); - break; + /* salt in bcrypt is actually the cost */ + return crypt_bcrypt_wrapper(passwd, salt); + case SRPSHA1_CRYPT: /* bcrypt */ + /* salt in bcrypt is the salt size */ + return crypt_srpsha1_wrapper(username, passwd, salt); } return NULL; } @@ -46,6 +49,11 @@ int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt) { case '2': cr = crypt_bcrypt(passwd, salt); if (strncmp(cr, salt, strlen(cr))==0) return 0; + break; + case '4': + cr = crypt_srpsha1(username, passwd, salt); + if (strncmp(cr, salt, strlen(cr))==0) return 0; + break; } } return 1; diff --git a/lib/crypt_bcrypt.c b/lib/crypt_bcrypt.c index 1b666d1b53..ff2238b496 100644 --- a/lib/crypt_bcrypt.c +++ b/lib/crypt_bcrypt.c @@ -27,174 +27,12 @@ */ #include "defines.h" +#include "gnutls_int.h" #include "crypt_bcrypt.h" #include "gnutls_random.h" - -const static uint8 b64table[64] = - "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -const static uint8 asciitable[128] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, - 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, - 0x3c, 0x3d, 0x3e, 0x3f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, - 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, - 0x33, 0x34, 0x35, 0xff, 0xff, 0xff, - 0xff, 0xff -}; - -inline static int encode(uint8 * result, const uint8 * data, int left) -{ - - int data_len; - - if (left > 3) - data_len = 3; - else - data_len = left; - - switch (data_len) { - case 3: - result[0] = b64table[(data[0] >> 2)]; - result[1] = - b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) | - (data[1] >> 4))]; - result[2] = - b64table[((((data[1] & 0x0f) << 2) & 0xff) | - (data[2] >> 6))]; - result[3] = b64table[(((data[2] << 2) & 0xff) >> 2)]; - break; - case 2: - result[0] = b64table[(data[0] >> 2)]; - result[1] = - b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) | - (data[1] >> 4))]; - result[2] = b64table[(((data[1] << 4) & 0xff) >> 2)]; - result[3] = '\0'; - break; - case 1: - result[0] = b64table[(data[0] >> 2)]; - result[1] = - b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff))]; - result[2] = '\0'; - result[3] = '\0'; - break; - default: - return -1; - } - - return 4; - -} - -/* data must be 4 bytes - * result should be 3 bytes - */ -#define TOASCII(c) (c<127 ? asciitable[c] : 0xff) -inline static int decode(uint8 * result, const uint8 * data) -{ - uint8 a1, a2; - int ret = 3; - - a1 = TOASCII(data[0]); - a2 = TOASCII(data[1]); - if (a1 == 0xff || a2 == 0xff) - return -1; - result[0] = ((a1 << 2) & 0xff) | ((a2 >> 4) & 0xff); - - a1 = a2; - a2 = TOASCII(data[2]); - if (a2 == 0xff) - return -1; - result[1] = ((a1 << 4) & 0xff) | ((a2 >> 2) & 0xff); - - a1 = a2; - a2 = TOASCII(data[3]); - if (a2 == 0xff) - return -1; - result[2] = ((a1 << 6) & 0xff) | (a2 & 0xff); - - if (data[3] == '=') - ret--; - if (data[4] == '=') - ret--; - - return ret; -} - - -/* encodes data and puts the result into result (result should have 4/3 of the original size) - * The result_size is the return value - */ -static int _crypt_encode_base64(uint8 * result, const uint8 * data, - const uint16 data_size) -{ - int i, ret, tmp, j; - uint8 tmpres[4]; - - ret = data_size % 3; - if (ret != 0) - ret = 4; - else - ret = 0; - - ret += (data_size / 3) * 4; - - if ((result) == NULL) - return ret; - - for (i = j = 0; i < data_size; i += 3, j += 4) { - tmp = encode(tmpres, &data[i], data_size - i); - if (tmp == -1) - return -1; - memcpy(&result[j], tmpres, tmp); - } - - return ret; -} - - -/* decodes data and puts the result into result - * The result_size is the return value - */ -static int _crypt_decode_base64(uint8 * result, const uint16 result_size, - const uint8 * data) -{ - int i, ret, tmp, j; - uint8 tmpres[3]; - - ret = result_size; - - if (result == NULL) - return ret; - - for (i = j = 0; j < result_size; i += 4) { - tmp = decode(tmpres, &data[i]); - if (tmp < 0) - return tmp; - memcpy(&result[j], tmpres, tmp); - if (tmp < 3) - ret -= (3 - tmp); - j += 3; - } - return ret; -} - - +#include "cert_b64.h" +#include "gnutls_srp.h" +#include <gnutls_errors.h> #define rotl(x,n) (((x) << ((uint32)(n))) | ((x) >> (32 - (uint32)(n)))) #define rotr(x,n) (((x) >> ((uint32)(n))) | ((x) << (32 - (uint32)(n)))) @@ -667,7 +505,7 @@ static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes, cons { short i, j; int k; - uint32 data, *temp; + uint32 data, temp[2]; uint32 wsalt[4]; if (bsalt!=NULL) { @@ -683,7 +521,6 @@ static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes, cons } } - temp = malloc(8); temp[0] = temp[1] = 0x00000000; j = 0; @@ -753,22 +590,21 @@ static void _blf_deinit(blf_ctx *ctx) { free(ctx); } +static const char magic[] = "$2$"; char * crypt_bcrypt(const char *passwd, const char *salt) { unsigned char *sp, *tsp; - const char *magic = "$2a$"; blf_ctx *ctx; - const unsigned char text[24] = "OrpheanBeholderScryDoubt"; - uint8 csalt[16]; - uint8 rtext[120]; - int cost; + unsigned char text[24] = "OrpheanBeholderScryDoubt"; + uint8 *csalt; + uint8 *rtext; + int cost, vsize; int i, salt_size = strlen(salt); - unsigned char *local_salt; + unsigned char *local_salt, *v; int passwd_len; - char * password; - char tmp[200]; + char *tmp; passwd_len = strlen(passwd) + 1; /* we want the null also */ if (passwd_len > 56) @@ -785,47 +621,76 @@ char * cost = atoi((char *) sp); do { /* move to salt */ sp++; - } while (*sp != '$' && *sp != '\0'); + } while (*sp != '$'); sp++; + tsp = sp; - tsp += 22; + while((*tsp)!='$') tsp++; *tsp = '\0'; /* put a null after the end of salt */ - _crypt_decode_base64( csalt, 16, sp); + _gnutls_base64_decode( sp, strlen(sp), &csalt); ctx = _blf_init( csalt, passwd, passwd_len, cost); + gnutls_free(csalt); + for (i = 0; i < 64; i++) { _blf_encrypt(ctx, (uint8 *) text); _blf_encrypt(ctx, (uint8 *) &text[8]); _blf_encrypt(ctx, (uint8 *) &text[16]); } - _crypt_encode_base64(rtext, text, 23); + /* v = g^x mod n */ + vsize = _gnutls_srp_gx(text, 8*3, &v); + if (vsize==-1 || v==NULL) { + gnutls_assert(); + return NULL; + } - sprintf( tmp, "$2a$%.2u$%s%s", (unsigned int) cost, sp, rtext); - password = strdup(tmp); + _gnutls_base64_encode(v, vsize, &rtext); + gnutls_free(v); + + tmp = gnutls_calloc( 1, strlen(magic)+3+strlen(sp)+1+strlen(rtext)+1); + sprintf( tmp, "%s%.2u$%s$%s", magic, (unsigned int) cost, sp, rtext); + + gnutls_free(local_salt); + gnutls_free(rtext); + _blf_deinit(ctx); - return password; + return tmp; } char *crypt_bcrypt_wrapper(const char *pass_new, int cost) { - unsigned char result[40]; - char *cp = (char *) result; - unsigned char* tmp; + unsigned char *result; + char* tcp; + unsigned char* rand; char *e = NULL; - - tmp = _gnutls_get_random( 16, GNUTLS_WEAK_RANDOM); + int result_size; + + rand = _gnutls_get_random( 16, GNUTLS_WEAK_RANDOM); /* cost should be <32 and >6 */ - sprintf(cp, "$2a$%.2u$", cost); /* magic for the BCRYPT */ - cp += strlen(cp); - _crypt_encode_base64( cp, tmp, 16); + if (cost >=32) cost=31; + if (cost < 1) cost = 1; - _gnutls_free_rand(tmp); - /* no longer need cleartext */ - e = crypt_bcrypt(pass_new, (const char *) result); + result_size = _gnutls_base64_encode( rand, 16, &result); + if (result_size < 0) { + gnutls_assert(); + 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 */ + gnutls_free(result); + + _gnutls_free_rand(rand); + + /* no longer need cleartext */ + e = crypt_bcrypt(pass_new, (const char *) tcp); + gnutls_free(tcp); + return e; } diff --git a/lib/crypt_srpsha1.c b/lib/crypt_srpsha1.c new file mode 100644 index 0000000000..86b7f54ff3 --- /dev/null +++ b/lib/crypt_srpsha1.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GNUTLS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "defines.h" +#include "gnutls_int.h" +#include "gnutls_random.h" +#include "gnutls_hash_int.h" +#include "cert_b64.h" +#include "gnutls_srp.h" +#include <gnutls_errors.h> + +/* x = SHA(<salt> | SHA(<username> | ":" | <raw password>)) */ + +static const char magic[] = "$4$"; + +char * + crypt_srpsha1(const char* username, const char *passwd, const char *salt) +{ + unsigned char *sp, *tsp, *r1; + int salt_size = strlen(salt); + unsigned char *local_salt, *v; + int passwd_len; + GNUTLS_MAC_HANDLE h1; + int vsize, hash_len = gnutls_hash_get_algo_len(GNUTLS_MAC_SHA); + char *tmp; + uint8 *rtext, * csalt; + + passwd_len = strlen(passwd); /* we do not want the null */ + + h1 = gnutls_hash_init(GNUTLS_MAC_SHA); + gnutls_hash(h1, (char*)username, strlen(username)); + gnutls_hash(h1, ":", 1); + gnutls_hash(h1, (char*)passwd, passwd_len); + r1 = gnutls_hash_deinit(h1); + + local_salt = malloc(salt_size + 1); + strcpy((char *) local_salt, salt); + sp = local_salt; + + /* If it starts with the magic string, then skip that */ + if (!strncmp((char *) sp, magic, strlen(magic))) + sp += strlen(magic); + + tsp = sp; + while((*tsp)!='$') tsp++; + *tsp = '\0'; /* put a null after the end of salt */ + + _gnutls_base64_decode( sp, strlen(sp), &csalt); + + h1 = gnutls_hash_init(GNUTLS_MAC_SHA); + gnutls_hash(h1, csalt, 16); + gnutls_free(csalt); + + gnutls_hash(h1, r1, hash_len); + + gnutls_free(r1); + r1 = gnutls_hash_deinit(h1); + + /* v = g^x mod n */ + vsize = _gnutls_srp_gx(r1, hash_len, &v); + gnutls_free(r1); + if (vsize==-1 || v==NULL) { + gnutls_assert(); + return NULL; + } + + _gnutls_base64_encode(v, vsize, &rtext); + gnutls_free(v); + + tmp = gnutls_calloc( 1, strlen(sp)+strlen(rtext)+strlen(magic)+1+1 ); + + sprintf( tmp, "%s%s$%s", magic, sp, rtext); + + gnutls_free(rtext); + gnutls_free(local_salt); + + return tmp; +} +/* salt here is the salt size */ +char *crypt_srpsha1_wrapper(const char* username, const char *pass_new, int salt) +{ + unsigned char *result; + char *tcp; + unsigned char* rand; + char *e = NULL; + int result_size; + + if (salt > 50 || salt < 0) return NULL; /* wow that's pretty long salt */ + + rand = _gnutls_get_random( salt, GNUTLS_WEAK_RANDOM); + + result_size = _gnutls_base64_encode( rand, salt, &result); + if (result_size < 0) { + gnutls_assert(); + return NULL; + } + + tcp = gnutls_calloc( 1, result_size + strlen(magic)+1 +1 ); + sprintf(tcp, "%s%s$", magic, result); + + gnutls_free(result); + _gnutls_free_rand(rand); + /* no longer need cleartext */ + + e = crypt_srpsha1(username, pass_new, (const char *) tcp); + gnutls_free(tcp); + + return e; +} diff --git a/lib/crypt_srpsha1.h b/lib/crypt_srpsha1.h new file mode 100644 index 0000000000..36005ec3e0 --- /dev/null +++ b/lib/crypt_srpsha1.h @@ -0,0 +1,2 @@ +char * crypt_srpsha1(const char* username, const char *passwd, const char *salt); +char *crypt_srpsha1_wrapper(const char* username, const char *pass_new, int salt); diff --git a/lib/gnutls.h b/lib/gnutls.h index 41d117ec01..ce276c24a4 100644 --- a/lib/gnutls.h +++ b/lib/gnutls.h @@ -97,10 +97,10 @@ int gnutls_clean_db( GNUTLS_STATE state); /* crypt functions */ -enum crypt_algo { MD5_CRYPT, BLOWFISH_CRYPT }; +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); +char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt); int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt); /* these are deprecated must be replaced by gnutls_errors.h */ diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c index b04cc5f5ab..59a6b76822 100644 --- a/lib/gnutls_dh.c +++ b/lib/gnutls_dh.c @@ -25,6 +25,8 @@ /* Taken from gsti */ +#define DH_G 2 + static const uint8 diffie_hellman_group1_prime[130] = { 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, @@ -77,7 +79,7 @@ MPI gnutls_calc_dh_secret(MPI * ret_x) } /*_gnutls_dump_mpi(stderr, "prime=", prime ); */ - g = mpi_set_ui(NULL, 2); + g = mpi_set_ui(NULL, DH_G); x = 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 */ @@ -128,7 +130,7 @@ MPI gnutls_get_dh_params(MPI * ret_p) abort(); } - g = mpi_set_ui(NULL, 2); + g = mpi_set_ui(NULL, DH_G); if (ret_p) *ret_p = prime; diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c new file mode 100644 index 0000000000..c63fe7409c --- /dev/null +++ b/lib/gnutls_srp.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GNUTLS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#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 + */ + +/* Taken from gsti -- this is n + * g is defined to be 2 + */ + +#define SRP_G 2 + +static const uint8 diffie_hellman_group1_prime[130] = { 0x04, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +int _gnutls_srp_gx(opaque *text, int textsize, opaque** result) { + + MPI g, prime, x, e; + size_t n = sizeof diffie_hellman_group1_prime; + int result_size; + + if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, + diffie_hellman_group1_prime, &n)) { + gnutls_assert(); + return -1; + } + if (gcry_mpi_scan(&x, GCRYMPI_FMT_USG, + text, &textsize)) { + gnutls_assert(); + mpi_release(prime); + return -1; + } + + g = mpi_set_ui(NULL, SRP_G); + + /* e = g^x mod prime */ + e = gcry_mpi_alloc_like(prime); + + mpi_powm(e, g, x, prime); + + mpi_release(prime); + mpi_release(x); + + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e); + if (result!=NULL) { + *result = gnutls_malloc(result_size); + gcry_mpi_print(GCRYMPI_FMT_USG, *result, &result_size, e); + } + mpi_release(e); + return result_size; + +} diff --git a/lib/gnutls_srp.h b/lib/gnutls_srp.h new file mode 100644 index 0000000000..b60749144c --- /dev/null +++ b/lib/gnutls_srp.h @@ -0,0 +1 @@ +int _gnutls_srp_gx(opaque *text, int textsize, opaque** result); diff --git a/src/crypt.c b/src/crypt.c index d86752a8d3..e574d8551a 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -61,12 +61,31 @@ int main(int argc, char** argv) { gaainfo info; char* passwd; char* cr=NULL; +int crypt, salt; if ( gaa(argc, argv, &info) != -1) { fprintf(stderr, "Error in the arguments.\n"); return -1; } - + + salt = info.salt; + + if(info.crypt==NULL) crypt = SRPSHA1_CRYPT; + else { + if (strcasecmp( info.crypt, "bcrypt")==0) { + crypt = BLOWFISH_CRYPT; + if (salt==0) salt = 6; /* cost is 6 */ + } + else if (strcasecmp( info.crypt, "srpsha")==0) { + crypt = SRPSHA1_CRYPT; + if (salt==0) salt = 16; /* 16 bytes salt */ + } + else { + fprintf(stderr, "Unknown algorithm\n"); + return -1; + } + } + passwd = getpass("Enter password: "); if (info.passwd != NULL) { @@ -75,7 +94,8 @@ char* cr=NULL; return 0; } - cr = gnutls_crypt( info.username, passwd, BLOWFISH_CRYPT); + + cr = gnutls_crypt( info.username, passwd, crypt, salt); printf("%s:%s\n", info.username, cr); free(cr); return 0; diff --git a/src/crypt.gaa b/src/crypt.gaa index 157e8c719f..e37a1552bf 100644 --- a/src/crypt.gaa +++ b/src/crypt.gaa @@ -6,8 +6,14 @@ option (u,username) STR "username" { $username = $1 } "specify username." #char *passwd; option (p, passwd) STR "passwd" { $passwd = $1 } "specify a password file." +#char *crypt; +option (c, crypt) STR "crypt" { $crypt = $1 } "specify crypt algorithm (bcrypt/srpsha)." + +#int salt; +option (s, salt) INT "salt" { $salt = $1 } "specify salt/cost size for crypt algorithm." + option (h, help) { gaa_help(); exit(0); } "shows this help text" -init { $username=NULL; $passwd=NULL; } +init { $username=NULL; $passwd=NULL; $crypt=NULL; $salt=0; } OBLIGAT u @@ -8,6 +8,10 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { +#line 12 "crypt.gaa" + int salt; +#line 9 "crypt.gaa" + char *crypt; #line 6 "crypt.gaa" char *passwd; #line 3 "crypt.gaa" diff --git a/src/gaaout.c b/src/gaaout.c index 9f4e46a6bc..c6a764b7da 100644 --- a/src/gaaout.c +++ b/src/gaaout.c @@ -105,6 +105,8 @@ void gaa_help() printf("Crypt help\nUsage : crypt [-u user] [-p password file]""\n"); __gaa_helpsingle('u', "username", """username"" ", "specify username."); __gaa_helpsingle('p', "passwd", """passwd"" ", "specify a password file."); + __gaa_helpsingle('c', "crypt", """crypt"" ", "specify crypt algorithm (bcrypt/srpsha)."); + __gaa_helpsingle('s', "salt", """salt"" ", "specify salt/cost size for crypt algorithm."); __gaa_helpsingle('h', "help", "", "shows this help text"); #line 100 "gaa.skel" @@ -120,6 +122,10 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { +#line 12 "crypt.gaa" + int salt; +#line 9 "crypt.gaa" + char *crypt; #line 6 "crypt.gaa" char *passwd; #line 3 "crypt.gaa" @@ -178,10 +184,12 @@ int gaa_error = 0; #define GAA_MULTIPLE_OPTION 3 #define GAA_REST 0 -#define GAA_NB_OPTION 3 +#define GAA_NB_OPTION 5 #define GAAOPTID_help 1 -#define GAAOPTID_passwd 2 -#define GAAOPTID_username 3 +#define GAAOPTID_salt 2 +#define GAAOPTID_crypt 3 +#define GAAOPTID_passwd 4 +#define GAAOPTID_username 5 #line 168 "gaa.skel" @@ -364,6 +372,18 @@ float gaa_getfloat(char *arg) } /* option structures */ +struct GAAOPTION_salt +{ + int arg1; + int size1; +}; + +struct GAAOPTION_crypt +{ + char* arg1; + int size1; +}; + struct GAAOPTION_passwd { char* arg1; @@ -405,6 +425,8 @@ int gaa_get_option_num(char *str, int status) switch(status) { case GAA_LETTER_OPTION: + GAA_CHECK1STR("s", GAAOPTID_salt); + GAA_CHECK1STR("c", GAAOPTID_crypt); GAA_CHECK1STR("p", GAAOPTID_passwd); GAA_CHECK1STR("u", GAAOPTID_username); case GAA_MULTIPLE_OPTION: @@ -415,6 +437,8 @@ int gaa_get_option_num(char *str, int status) break; case GAA_WORD_OPTION: GAA_CHECKSTR("help", GAAOPTID_help); + GAA_CHECKSTR("salt", GAAOPTID_salt); + GAA_CHECKSTR("crypt", GAAOPTID_crypt); GAA_CHECKSTR("passwd", GAAOPTID_passwd); GAA_CHECKSTR("username", GAAOPTID_username); @@ -429,6 +453,8 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { int OK = 0; int gaa_last_non_option; + struct GAAOPTION_salt GAATMP_salt; + struct GAAOPTION_crypt GAATMP_crypt; struct GAAOPTION_passwd GAATMP_passwd; struct GAAOPTION_username GAATMP_username; @@ -453,11 +479,31 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { case GAAOPTID_help: OK = 0; -#line 9 "crypt.gaa" +#line 15 "crypt.gaa" { gaa_help(); exit(0); ;}; return GAA_OK; break; + case GAAOPTID_salt: + OK = 0; + GAA_TESTMOREARGS; + GAA_FILL(GAATMP_salt.arg1, gaa_getint, GAATMP_salt.size1); + gaa_index++; +#line 13 "crypt.gaa" +{ gaaval->salt = GAATMP_salt.arg1 ;}; + + return GAA_OK; + break; + case GAAOPTID_crypt: + OK = 0; + GAA_TESTMOREARGS; + GAA_FILL(GAATMP_crypt.arg1, gaa_getstr, GAATMP_crypt.size1); + gaa_index++; +#line 10 "crypt.gaa" +{ gaaval->crypt = GAATMP_crypt.arg1 ;}; + + return GAA_OK; + break; case GAAOPTID_passwd: OK = 0; GAA_TESTMOREARGS; @@ -501,8 +547,8 @@ int gaa(int argc, char **argv, gaainfo *gaaval) if(inited == 0) { -#line 11 "crypt.gaa" -{ gaaval->username=NULL; gaaval->passwd=NULL; ;}; +#line 17 "crypt.gaa" +{ gaaval->username=NULL; gaaval->passwd=NULL; gaaval->crypt=NULL; gaaval->salt=0; ;}; } inited = 1; |