summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-05-04 13:05:48 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-05-04 13:05:48 +0000
commit8f82a8e581e02a32aa97069052cdfccfc522b930 (patch)
tree06edca357d0f97648488fad490676d3b61b6553e
parentd93f1d1688a500a822d1d7793cc8e60563436db1 (diff)
downloadgnutls-8f82a8e581e02a32aa97069052cdfccfc522b930.tar.gz
More adds for SRP - SRPSHA1 and bcrypt
-rw-r--r--lib/Makefile.am5
-rw-r--r--lib/cert_b64.h6
-rw-r--r--lib/crypt.c20
-rw-r--r--lib/crypt_bcrypt.c253
-rw-r--r--lib/crypt_srpsha1.c126
-rw-r--r--lib/crypt_srpsha1.h2
-rw-r--r--lib/gnutls.h4
-rw-r--r--lib/gnutls_dh.c6
-rw-r--r--lib/gnutls_srp.c84
-rw-r--r--lib/gnutls_srp.h1
-rw-r--r--src/crypt.c24
-rw-r--r--src/crypt.gaa8
-rw-r--r--src/gaa.h4
-rw-r--r--src/gaaout.c58
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
diff --git a/src/gaa.h b/src/gaa.h
index 162e3ab3ab..bd74448d51 100644
--- a/src/gaa.h
+++ b/src/gaa.h
@@ -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;