]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
More adds for SRP - SRPSHA1 and bcrypt
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 4 May 2001 13:05:48 +0000 (13:05 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 4 May 2001 13:05:48 +0000 (13:05 +0000)
14 files changed:
lib/Makefile.am
lib/cert_b64.h [new file with mode: 0644]
lib/crypt.c
lib/crypt_bcrypt.c
lib/crypt_srpsha1.c [new file with mode: 0644]
lib/crypt_srpsha1.h [new file with mode: 0644]
lib/gnutls.h
lib/gnutls_dh.c
lib/gnutls_srp.c [new file with mode: 0644]
lib/gnutls_srp.h [new file with mode: 0644]
src/crypt.c
src/crypt.gaa
src/gaa.h
src/gaaout.c

index 16f6a20fe24194cb0f738160952d9aa5adb55ab4..5051a76e3fa8e3b5e50730bbf1b9e157898c0cfd 100644 (file)
@@ -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 (file)
index 0000000..58d4353
--- /dev/null
@@ -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);
index 054f8a56af2371468e67a8e2f0de185ed787e9ff..3f71923a334f684c4e6b7b3a8253cbcc1a5a3d1f 100644 (file)
 
 #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;
index 1b666d1b532e0e0b81d615c83e5aa70e42bd24f6..ff2238b496073e0800417d023b5d6b8a5dd5cadb 100644 (file)
  */
 
 #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 (file)
index 0000000..86b7f54
--- /dev/null
@@ -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 (file)
index 0000000..36005ec
--- /dev/null
@@ -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);
index 41d117ec014070756b87ff844841589cf1f35e89..ce276c24a4f6659efe2d7c6e86a6c2b8df7b6ec5 100644 (file)
@@ -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 */
index b04cc5f5ab5e9d65e9fd84c27bda842e174a3e01..59a6b768220cc6c794c691e303ad84d1603e83f0 100644 (file)
@@ -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 (file)
index 0000000..c63fe74
--- /dev/null
@@ -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 (file)
index 0000000..b607491
--- /dev/null
@@ -0,0 +1 @@
+int _gnutls_srp_gx(opaque *text, int textsize, opaque** result);
index d86752a8d33d41d4361ea2ce2c975f9f5e49ca7c..e574d8551a829d102610adaa76502da0756a25eb 100644 (file)
@@ -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;
index 157e8c719f16e84d6ec70433244c4221f5f1292a..e37a1552bf1826270f2c1b4bcc4e38819964295f 100644 (file)
@@ -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
index 162e3ab3abfdc7082f9ca764ccaff6591241ba3b..bd74448d51c79b207512e579832aa840f0e01d02 100644 (file)
--- 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"
index 9f4e46a6bc228cb361cc3fe75492ddf06e92393a..c6a764b7da1da5451d47815adafc3e0faf65b429 100644 (file)
@@ -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,9 +479,29 @@ 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:
@@ -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;