]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added certificate authenticated SRP cipher suites.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 19 Nov 2002 12:01:54 +0000 (12:01 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 19 Nov 2002 12:01:54 +0000 (12:01 +0000)
22 files changed:
NEWS
lib/auth_cert.c
lib/gnutls.h.in.in
lib/gnutls_algorithms.c
lib/gnutls_algorithms.h
lib/gnutls_auth.c
lib/gnutls_auth_int.h
lib/gnutls_cert.c
lib/gnutls_handshake.c
lib/gnutls_int.h
lib/gnutls_v2_compat.c
lib/gnutls_x509.c
libextra/Makefile.am
libextra/auth_srp.c
libextra/auth_srp.h
libextra/auth_srp_rsa.c [new file with mode: 0644]
libextra/ext_srp.c
libextra/gnutls_extra.c
libextra/gnutls_extra.h
src/cli.c
src/common.c
src/serv.c

diff --git a/NEWS b/NEWS
index d20de755c0a3df1a4d3d2c0dea752534a250ae3f..1ad473bdf60eb0aa51d1e9c0049c2c5a9530f2c1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ Version 0.?.?
 - Added "gnutls/compat.h" header which must be included if the obsolete 
   0.4.x API is to be used.
 - Example programs are now stored in doc/examples/
+- Added certificate authenticated SRP cipher suites.
 
 Version 0.5.11 (5/11/2002)
 - Some fixes in 'gnutls-cli' client program to prevent some segmentation 
index f7c57aa7f3df80d6ef1e71634b9a3364fd04a803..5c5774336f90e4b12765adb708e65a8880a64313 100644 (file)
@@ -1255,7 +1255,7 @@ int _gnutls_find_apr_cert(gnutls_session session, gnutls_cert ** apr_cert_list,
        int ind;
 
        cred =
-           _gnutls_get_kx_cred(session->key, GNUTLS_CRD_CERTIFICATE,
+           _gnutls_get_kx_cred(session, GNUTLS_CRD_CERTIFICATE,
                                NULL);
 
        if (cred == NULL) {
index 8f759dbd7494fc13b700b806c3901fe5b48d0dab..97e7b5644f7b2c92eeb3bf75cb8e9c5352b57774 100644 (file)
@@ -44,7 +44,7 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_NULL=1,
 
 typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, 
        GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP,
-       GNUTLS_KX_RSA_EXPORT
+       GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA
 } gnutls_kx_algorithm;
 
 typedef enum gnutls_credentials_type { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } gnutls_credentials_type;
index ca05423d02891170f8c2984768d35fb1291b2b43..f05a3cb4c290c73c4238a4b19bf2f61400a7f77c 100644 (file)
 /* Cred type mappings to KX algorithms */
 typedef struct {
        gnutls_kx_algorithm algorithm;
-       gnutls_credentials_type type;
+       gnutls_credentials_type client_type;
+       gnutls_credentials_type server_type; /* The type of credentials a server
+                                             * needs to set */
 } gnutls_cred_map;
 
 static const gnutls_cred_map cred_mappings[] = {
-       { GNUTLS_KX_ANON_DH, GNUTLS_CRD_ANON    },
-       { GNUTLS_KX_RSA,     GNUTLS_CRD_CERTIFICATE },
-       { GNUTLS_KX_RSA_EXPORT,     GNUTLS_CRD_CERTIFICATE },
-       { GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE },
-       { GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE },
-       { GNUTLS_KX_SRP,     GNUTLS_CRD_SRP     },
+       { GNUTLS_KX_ANON_DH,    GNUTLS_CRD_ANON,        GNUTLS_CRD_ANON    },
+       { GNUTLS_KX_RSA,        GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE },
+       { GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE },
+       { GNUTLS_KX_DHE_DSS,    GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE },
+       { GNUTLS_KX_DHE_RSA,    GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE },
+       { GNUTLS_KX_SRP,        GNUTLS_CRD_SRP,         GNUTLS_CRD_SRP     },
+       { GNUTLS_KX_SRP_RSA,    GNUTLS_CRD_SRP,         GNUTLS_CRD_CERTIFICATE     },
        { 0 }
 };
 
 #define GNUTLS_KX_MAP_LOOP(b) \
         const gnutls_cred_map *p; \
-                for(p = cred_mappings; p->type != 0; p++) { b ; }
+                for(p = cred_mappings; p->algorithm != 0; p++) { b ; }
 
-#define GNUTLS_KX_MAP_ALG_LOOP(a) \
-                        GNUTLS_KX_MAP_LOOP( if(p->type == type) { a; break; })
+#define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \
+                        GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; })
+
+#define GNUTLS_KX_MAP_ALG_LOOP_CLIENT(a) \
+                        GNUTLS_KX_MAP_LOOP( if(p->client_type == type) { a; break; })
 
 
 /* TLS Versions */
@@ -234,6 +240,7 @@ typedef struct {
 #define GNUTLS_SRP_SHA_RIJNDAEL_128_CBC_SHA { 0x00, 0x53 }
 #define GNUTLS_SRP_SHA_RIJNDAEL_256_CBC_SHA { 0x00, 0x56 }
 
+#define GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA { 0x00, 0x51 }
 
 /** RSA 
  **/
@@ -316,6 +323,10 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = {
                                  GNUTLS_CIPHER_RIJNDAEL_256_CBC, GNUTLS_KX_SRP,
                                  GNUTLS_MAC_SHA, GNUTLS_TLS1),
 
+       GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA,
+                                 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_RSA,
+                                 GNUTLS_MAC_SHA, GNUTLS_TLS1),
+
        /* DHE_DSS */
        GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_DHE_DSS_ARCFOUR_SHA,
                                  GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_KX_DHE_DSS,
@@ -805,18 +816,26 @@ int ret=0;
 }
 
 /* Type to KX mappings */
-gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type)
+gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type, int server)
 {
        gnutls_kx_algorithm ret = -1;
 
-       GNUTLS_KX_MAP_ALG_LOOP(ret = p->algorithm);
+       if (server) {
+               GNUTLS_KX_MAP_ALG_LOOP_SERVER(ret = p->algorithm);
+       } else {
+               GNUTLS_KX_MAP_ALG_LOOP_SERVER(ret = p->algorithm);
+       }
        return ret;
 }
 
-gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm)
+gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm, int server)
 {
        gnutls_credentials_type ret = -1;
-       GNUTLS_KX_MAP_LOOP(if (p->algorithm==algorithm) ret = p->type);
+       if (server) {
+               GNUTLS_KX_MAP_LOOP(if (p->algorithm==algorithm) ret = p->server_type);
+       } else {
+               GNUTLS_KX_MAP_LOOP(if (p->algorithm==algorithm) ret = p->client_type);
+       }
 
        return ret;
 }
index 944996ae5702ca74d0402a3aa15c402d1cb49ec1..b3b041802e5506febd2d053542d4b3c82298a14f 100644 (file)
@@ -77,8 +77,8 @@ int _gnutls_compression_get_comp_level(gnutls_compression_method algorithm);
 int _gnutls_compression_get_wbits(gnutls_compression_method algorithm);
 
 /* Type to KX mappings */
-gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type);
-gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm);
+gnutls_kx_algorithm _gnutls_map_kx_get_kx(gnutls_credentials_type type, int server);
+gnutls_credentials_type _gnutls_map_kx_get_cred(gnutls_kx_algorithm algorithm, int server);
 
 struct gnutls_kx_algo_entry {
        const char *name;
index c23b6fc1c3efb0437aca38a53241f068a2db4952..5bed7f9c52de92c04826dbd68ee5a519347e9666 100644 (file)
@@ -137,20 +137,29 @@ int gnutls_credentials_set( gnutls_session session, gnutls_credentials_type type
   * Eg. for CERTIFICATE ciphersuites (key exchange algorithms: KX_RSA, KX_DHE_RSA),
   * the same function are to be used to access the authentication data.
   **/
-gnutls_credentials_type gnutls_auth_get_type( gnutls_session session) {
+gnutls_credentials_type gnutls_auth_get_type( gnutls_session session) 
+{
+/* This is not the credentials we must set, but the authentication data
+ * we get by the peer, so it should be reversed.
+ */
+int server = session->security_parameters.entity==GNUTLS_SERVER?0:1;
 
        return _gnutls_map_kx_get_cred(
                 _gnutls_cipher_suite_get_kx_algo
-                         (session->security_parameters.current_cipher_suite));
+                         (session->security_parameters.current_cipher_suite), server);
 }
 
 /* 
  * This returns an pointer to the linked list. Don't
  * free that!!!
  */
-const void *_gnutls_get_kx_cred( GNUTLS_KEY key, gnutls_kx_algorithm algo, int *err) {
-       return _gnutls_get_cred( key, _gnutls_map_kx_get_cred(algo), err);
+const void *_gnutls_get_kx_cred( gnutls_session session, gnutls_kx_algorithm algo, int *err) 
+{
+int server = session->security_parameters.entity==GNUTLS_SERVER?1:0;
+
+       return _gnutls_get_cred( session->key, _gnutls_map_kx_get_cred(algo, server), err);
 }
+
 const void *_gnutls_get_cred( GNUTLS_KEY key, gnutls_credentials_type type, int *err) {
        AUTH_CRED * ccred;
 
index a91d03d226c3e37ffd3c4be59f67cdd39b802e97..a62de075659f9b8e7a7bc7b2b23c17c5a11e53d3 100644 (file)
@@ -1,7 +1,7 @@
 int gnutls_clear_creds( gnutls_session session);
 int gnutls_credentials_set( gnutls_session session, gnutls_credentials_type type, void* cred);
 const void *_gnutls_get_cred( GNUTLS_KEY key, gnutls_credentials_type kx, int* err);
-const void *_gnutls_get_kx_cred( GNUTLS_KEY key, gnutls_kx_algorithm algo, int *err);
+const void *_gnutls_get_kx_cred( gnutls_session session, gnutls_kx_algorithm algo, int *err);
 int _gnutls_generate_key(GNUTLS_KEY key);
 gnutls_credentials_type gnutls_auth_get_type( gnutls_session session);
 void* _gnutls_get_auth_info( gnutls_session session);
index 4deab906a9847d67c4eb5d62d62a85e961d0be8b..2ddf17b937c0a27e7850eba57de4050edbae65c2 100644 (file)
@@ -57,6 +57,7 @@ static const gnutls_pk_map pk_mappings[] = {
        {GNUTLS_KX_RSA, GNUTLS_PK_RSA},
        {GNUTLS_KX_RSA_EXPORT, GNUTLS_PK_RSA},
        {GNUTLS_KX_DHE_RSA, GNUTLS_PK_RSA},
+       {GNUTLS_KX_SRP_RSA, GNUTLS_PK_RSA},
        {GNUTLS_KX_DHE_DSS, GNUTLS_PK_DSA},
        {0}
 };
index 8c484e8d17883c366afb97cb1676b519ab4d91f4..6771fcb8a74e96d797ececc9a7e6388d8beb1b87 100644 (file)
@@ -505,7 +505,7 @@ int _gnutls_recv_finished(gnutls_session session)
 /* returns PK_RSA if the given cipher suite list only supports,
  * RSA algorithms, PK_DSA if DSS, and -1 if both or none.
  */
-int _gnutls_find_pk_algos_in_ciphersuites( opaque* data, int datalen) {
+int _gnutls_server_find_pk_algos_in_ciphersuites( opaque* data, int datalen) {
 int j;
 gnutls_pk_algorithm algo=-1, prev_algo = 0;
 gnutls_kx_algorithm kx;
@@ -513,7 +513,7 @@ gnutls_kx_algorithm kx;
        for (j = 0; j < datalen; j += 2) {
                kx = _gnutls_cipher_suite_get_kx_algo(*((GNUTLS_CipherSuite *) & data[j]));
                
-               if ( _gnutls_map_kx_get_cred( kx) == GNUTLS_CRD_CERTIFICATE) {
+               if ( _gnutls_map_kx_get_cred( kx, 1) == GNUTLS_CRD_CERTIFICATE) {
                        algo = _gnutls_map_pk_get_pk( kx);
        
                        if (algo!=prev_algo && prev_algo!=0) return -1;
@@ -537,7 +537,7 @@ int _gnutls_server_select_suite(gnutls_session session, opaque *data, int datale
                              * supported by the peer.
                              */
 
-       pk_algo = _gnutls_find_pk_algos_in_ciphersuites( data, datalen);
+       pk_algo = _gnutls_server_find_pk_algos_in_ciphersuites( data, datalen);
 
        x = _gnutls_supported_ciphersuites(session, &ciphers);
        if (x < 0) { /* the case x==0 is handled within the function. */
@@ -597,8 +597,7 @@ int _gnutls_server_select_suite(gnutls_session session, opaque *data, int datale
        /* check if the credentials (username, public key etc. are ok)
         */
        if (_gnutls_get_kx_cred
-           (session->key,
-            _gnutls_cipher_suite_get_kx_algo(session->security_parameters.
+           (session, _gnutls_cipher_suite_get_kx_algo(session->security_parameters.
                                              current_cipher_suite),
             &err) == NULL && err != 0) {
                gnutls_assert();
@@ -1108,8 +1107,7 @@ static int _gnutls_client_set_ciphersuite(gnutls_session session,
         * Actually checks if they exist.
         */
        if (_gnutls_get_kx_cred
-           (session->key,
-            _gnutls_cipher_suite_get_kx_algo(session->
+           (session, _gnutls_cipher_suite_get_kx_algo(session->
                                              security_parameters.
                                              current_cipher_suite),
             &err) == NULL && err != 0) {
@@ -2335,7 +2333,7 @@ int _gnutls_remove_unwanted_ciphersuites(gnutls_session session,
        gnutls_kx_algorithm *alg;
        int alg_size;
        gnutls_kx_algorithm kx;
-
+       int server = session->security_parameters.entity==GNUTLS_SERVER?1:0;
 
        /* if we should use a specific certificate, 
         * we should remove all algorithms that are not supported
@@ -2390,22 +2388,22 @@ int _gnutls_remove_unwanted_ciphersuites(gnutls_session session,
 
                /* if it is defined but had no credentials 
                 */
-               if (_gnutls_get_kx_cred
-                   (session->key, kx, NULL) == NULL) {
+               if (_gnutls_get_kx_cred(session, kx, NULL) == NULL) {
                        keep = 1;
                } else
                /* If there was no credentials to use with the specified
                 * key exchange method, then just remove it.
                 */
-               if (_gnutls_map_kx_get_cred(kx) == GNUTLS_CRD_CERTIFICATE) {
+               if (_gnutls_map_kx_get_cred(kx, server) == GNUTLS_CRD_CERTIFICATE) {
                        keep = 1;       /* do not keep */
                        if (x509_cred != NULL) {
-                               if (session->security_parameters.entity ==
-                                   GNUTLS_SERVER) {
+                               if (server) {
                                        /* here we check if the KX algorithm 
                                         * is compatible with the certificate.
                                         */
+fprintf(stderr, "KX: %d\n", kx);
                                        for (j = 0; j < alg_size; j++) {
+fprintf(stderr, "ALG: %d\n", alg[j]);
                                                if (alg[j] == kx) {
                                                        keep = 0;
                                                        break;
index 260f6d318b2a24b14a26cda9e7755ef7e5cd4fa8..281ba655c859eb8e0ff0b031b4165c72412c6489 100644 (file)
@@ -159,7 +159,7 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_NULL=1,
 
 typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, 
        GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP,
-       GNUTLS_KX_RSA_EXPORT
+       GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA
 } gnutls_kx_algorithm;
 
 typedef enum gnutls_mac_algorithm { GNUTLS_MAC_NULL=1, GNUTLS_MAC_MD5, GNUTLS_MAC_SHA } gnutls_mac_algorithm;
index 82716727194c5259104d3447cfe5fb4c78bd9377..01225468f10f735530a587983c1fdfba76600d27 100644 (file)
@@ -156,7 +156,7 @@ int _gnutls_read_client_hello_v2(gnutls_session session, opaque * data,
 
        /* check if the credentials (username, public key etc. are ok)
         */
-       if (_gnutls_get_kx_cred( session->key, _gnutls_cipher_suite_get_kx_algo(session->security_parameters.current_cipher_suite), &err) == NULL && err != 0) {
+       if (_gnutls_get_kx_cred( session, _gnutls_cipher_suite_get_kx_algo(session->security_parameters.current_cipher_suite), &err) == NULL && err != 0) {
                gnutls_assert();
                return GNUTLS_E_INSUFICIENT_CREDENTIALS;
        }
index 5b8a285fd9743440c0046dc6e769279c6a29376e..59f46a47eeb94acf76ddae9b5c1c7a52d43925f4 100644 (file)
@@ -2212,10 +2212,14 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert,
 /* Returns 0 if it's ok to use the gnutls_kx_algorithm with this 
  * certificate (uses the KeyUsage field). 
  */
-int _gnutls_check_x509_key_usage(const gnutls_cert * cert,
+int _gnutls_check_x509_key_usage( const gnutls_cert * cert,
                                    gnutls_kx_algorithm alg)
 {
-       if (_gnutls_map_kx_get_cred(alg) == GNUTLS_CRD_CERTIFICATE) {
+
+       /* FIXME: check here */
+       if (_gnutls_map_kx_get_cred(alg, 1) == GNUTLS_CRD_CERTIFICATE ||
+               _gnutls_map_kx_get_cred(alg, 0) == GNUTLS_CRD_CERTIFICATE) 
+       {
                switch (alg) {
                case GNUTLS_KX_RSA:
                        if (cert->keyUsage != 0) {
@@ -2228,6 +2232,7 @@ int _gnutls_check_x509_key_usage(const gnutls_cert * cert,
                                        return 0;
                        }
                        return 0;
+               case GNUTLS_KX_SRP_RSA:
                case GNUTLS_KX_DHE_RSA:
                case GNUTLS_KX_DHE_DSS:
                case GNUTLS_KX_RSA_EXPORT:
index 4825a71985b95eb02aff545b1b28be392e49aba3..6caf8869f42aee5b77cfed34e438e52506d2e6e8 100644 (file)
@@ -15,7 +15,8 @@ lib_LTLIBRARIES = libgnutls-extra.la
 
 COBJECTS_EXTRA = crypt.c crypt_srpsha1.c ext_srp.c \
        gnutls_srp.c auth_srp.c auth_srp_passwd.c auth_srp_sb64.c \
-       gnutls_openpgp.c gnutls_extra.c gnutls_openssl.c minilzo.c
+       gnutls_openpgp.c gnutls_extra.c gnutls_openssl.c minilzo.c \
+       auth_srp_rsa.c
 
 libgnutls_extra_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
        $(LIBOPENCDK_LIBS)
index 7333b6942eb33682462997e2bbe03537f47731ce..7d01073222d4f64cb4301cf1358de124113598e5 100644 (file)
 #include "auth_srp.h"
 #include <gnutls_str.h>
 
-int gen_srp_server_kx2(gnutls_session, opaque **);
-int gen_srp_client_kx0(gnutls_session, opaque **);
+int _gnutls_gen_srp_server_kx2(gnutls_session, opaque **);
+int _gnutls_gen_srp_client_kx0(gnutls_session, opaque **);
 
-int proc_srp_server_kx2(gnutls_session, opaque *, size_t);
-int proc_srp_client_kx0(gnutls_session, opaque *, size_t);
+int _gnutls_proc_srp_server_kx2(gnutls_session, opaque *, size_t);
+int _gnutls_proc_srp_client_kx0(gnutls_session, opaque *, size_t);
 
 const MOD_AUTH_STRUCT srp_auth_struct = {
        "SRP",
        NULL,
        NULL,
        NULL,
-       gen_srp_server_kx2,
-       gen_srp_client_kx0,
+       _gnutls_gen_srp_server_kx2,
+       _gnutls_gen_srp_client_kx0,
        NULL,
        NULL,
        NULL,
@@ -52,8 +52,8 @@ const MOD_AUTH_STRUCT srp_auth_struct = {
        NULL,
        NULL, /* certificate */
        NULL,
-       proc_srp_server_kx2,
-       proc_srp_client_kx0,
+       _gnutls_proc_srp_server_kx2,
+       _gnutls_proc_srp_client_kx0,
        NULL,
        NULL,
        NULL
@@ -72,7 +72,7 @@ const MOD_AUTH_STRUCT srp_auth_struct = {
 /* Send the first key exchange message ( g, n, s) and append the verifier algorithm number 
  * Data is allocated by the caller, and should have data_size size.
  */
-int gen_srp_server_hello(gnutls_session state, opaque * data, size_t _data_size)
+int _gnutls_gen_srp_server_hello(gnutls_session state, opaque * data, size_t _data_size)
 {
        size_t n_g, n_n, n_s;
        int ret;
@@ -170,7 +170,7 @@ int gen_srp_server_hello(gnutls_session state, opaque * data, size_t _data_size)
 }
 
 /* send the second key exchange message  */
-int gen_srp_server_kx2(gnutls_session state, opaque ** data)
+int _gnutls_gen_srp_server_kx2(gnutls_session state, opaque ** data)
 {
        int ret;
        size_t n_b;
@@ -232,7 +232,7 @@ int gen_srp_server_kx2(gnutls_session state, opaque ** data)
 
 
 /* return A = g^a % N */
-int gen_srp_client_kx0(gnutls_session state, opaque ** data)
+int _gnutls_gen_srp_client_kx0(gnutls_session state, opaque ** data)
 {
        size_t n_a;
        uint8 *data_a;
@@ -249,10 +249,13 @@ int gen_srp_client_kx0(gnutls_session state, opaque ** data)
        username = cred->username;
        password = cred->password;
 
-       if (username == NULL || password == NULL)
+       if (username == NULL || password == NULL) {
+               gnutls_assert();
                return GNUTLS_E_INSUFICIENT_CRED;
+       }
 
-       /* calc A = g^a % N */
+       /* calc A = g^a % N 
+        */
        if (G == NULL || N == NULL) {
                gnutls_assert();
                return GNUTLS_E_INSUFICIENT_CRED;
@@ -264,8 +267,10 @@ int gen_srp_client_kx0(gnutls_session state, opaque ** data)
                return GNUTLS_E_MEMORY_ERROR;
        }
 
-       if (_gnutls_mpi_print( NULL, &n_a, A)!=0)
+       if (_gnutls_mpi_print( NULL, &n_a, A)!=0) {
+               gnutls_assert();
                return GNUTLS_E_MPI_PRINT_FAILED;
+       }
 
        (*data) = gnutls_malloc(n_a + 2);
        if ( (*data) == NULL) {
@@ -286,7 +291,7 @@ int gen_srp_client_kx0(gnutls_session state, opaque ** data)
 }
 
 /* receive the first key exchange message ( g, n, s) */
-int proc_srp_server_hello(gnutls_session state, const opaque * data, size_t _data_size)
+int _gnutls_proc_srp_server_hello(gnutls_session state, const opaque * data, size_t _data_size)
 {
        uint8 n_s;
        uint16 n_g, n_n;
@@ -372,7 +377,7 @@ int proc_srp_server_hello(gnutls_session state, const opaque * data, size_t _dat
 }
 
 /* just read A and put it to state */
-int proc_srp_client_kx0(gnutls_session state, opaque * data, size_t _data_size)
+int _gnutls_proc_srp_client_kx0(gnutls_session state, opaque * data, size_t _data_size)
 {
        size_t _n_A;
        ssize_t data_size = _data_size;
@@ -390,7 +395,7 @@ int proc_srp_client_kx0(gnutls_session state, opaque * data, size_t _data_size)
 }
 
 
-int proc_srp_server_kx2(gnutls_session state, opaque * data, size_t _data_size)
+int _gnutls_proc_srp_server_kx2(gnutls_session state, opaque * data, size_t _data_size)
 {
        size_t _n_B;
        ssize_t data_size = _data_size;
@@ -432,7 +437,9 @@ int proc_srp_server_kx2(gnutls_session state, opaque * data, size_t _data_size)
        if (ret < 0)
                return ret;
 
-       return 0;
+       return _data_size - data_size; /* return the remaining data 
+                                       * needed in auth_srp_rsa.
+                                       */
 }
 
 #endif /* ENABLE_SRP */
index 988e24f5ef40ece3830a84f2277afd1ba3d24b7d..463ce943406061dcebe5cbdad083ba8bd2d5f7ae 100644 (file)
@@ -1,5 +1,7 @@
-#include <gnutls_auth.h>
+#ifndef AUTH_SRP_H
+# define AUTH_SRP_H
 
+#include <gnutls_auth.h>
 
 typedef struct {
        char* username;
@@ -23,9 +25,17 @@ typedef struct SRP_SERVER_AUTH_INFO_INT {
 
 #ifdef ENABLE_SRP
 
-int proc_srp_server_hello(gnutls_session state, const opaque * data, size_t data_size);
-int gen_srp_server_hello(gnutls_session state, opaque * data, size_t data_size);
+int _gnutls_proc_srp_server_hello(gnutls_session state, const opaque * data, size_t data_size);
+int _gnutls_gen_srp_server_hello(gnutls_session state, opaque * data, size_t data_size);
+
+int _gnutls_gen_srp_server_kx2(gnutls_session, opaque **);
+int _gnutls_gen_srp_client_kx0(gnutls_session, opaque **);
+
+int _gnutls_proc_srp_server_kx2(gnutls_session, opaque *, size_t);
+int _gnutls_proc_srp_client_kx0(gnutls_session, opaque *, size_t);
 
 typedef struct  SRP_SERVER_AUTH_INFO_INT  SRP_SERVER_AUTH_INFO_INT;
 
 #endif /* ENABLE_SRP */
+
+#endif
diff --git a/libextra/auth_srp_rsa.c b/libextra/auth_srp_rsa.c
new file mode 100644 (file)
index 0000000..466482a
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ *      Copyright (C) 2001,2002 Nikos Mavroyanopoulos
+ *
+ * This file is part of GNUTLS.
+ *
+ * GNUTLS-EXTRA 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-EXTRA 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 "gnutls_int.h"
+
+#ifdef ENABLE_SRP
+
+#include "gnutls_errors.h"
+#include "auth_srp_passwd.h"
+#include "gnutls_auth.h"
+#include "gnutls_auth_int.h"
+#include "gnutls_srp.h"
+#include "debug.h"
+#include "gnutls_num.h"
+#include "auth_srp.h"
+#include <gnutls_str.h>
+#include <auth_cert.h>
+#include <x509_verify.h>
+#include <gnutls_datum.h>
+#include <gnutls_sig.h>
+#include <auth_srp.h>
+#include <gnutls_x509.h>
+#include <gnutls_extra.h>
+
+static int gen_srp_rsa_server_kx2(gnutls_session, opaque **);
+static int proc_srp_rsa_server_kx2(gnutls_session, opaque *, size_t);
+
+const MOD_AUTH_STRUCT srp_rsa_auth_struct = {
+       "SRP",
+       _gnutls_gen_cert_server_certificate,
+       NULL,
+       NULL,
+       gen_srp_rsa_server_kx2,
+       _gnutls_gen_srp_client_kx0,
+       NULL,
+       NULL,
+       NULL,
+
+       _gnutls_proc_cert_server_certificate,
+       NULL, /* certificate */
+       NULL,
+       proc_srp_rsa_server_kx2,
+       _gnutls_proc_srp_client_kx0,
+       NULL,
+       NULL,
+       NULL
+};
+
+
+static int gen_srp_rsa_server_kx2(gnutls_session session, opaque ** data)
+{
+ssize_t ret, data_size;
+gnutls_datum signature, ddata;
+const gnutls_certificate_credentials cred;
+gnutls_cert *apr_cert_list;
+gnutls_private_key *apr_pkey;
+int apr_cert_list_length;
+
+       ret = _gnutls_gen_srp_server_kx2( session, data);
+
+       if (ret < 0) return ret;
+       
+       data_size = ret;
+       ddata.data = *data;
+       ddata.size = data_size;
+
+       cred = _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL);
+       if (cred == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INSUFICIENT_CREDENTIALS;
+       }
+
+       /* find the appropriate certificate */
+       if ((ret =
+            _gnutls_find_apr_cert(session, &apr_cert_list,
+                                  &apr_cert_list_length,
+                                  &apr_pkey)) < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       if ((ret =
+            _gnutls_generate_sig_params(session, &apr_cert_list[0],
+                        apr_pkey, &ddata, &signature)) < 0) 
+       {
+               gnutls_assert();
+               gnutls_free(*data);
+               return ret;
+       }
+
+       *data = gnutls_realloc_fast(*data, data_size + signature.size + 2);
+       if (*data == NULL) {
+               gnutls_free_datum(&signature);
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       _gnutls_write_datum16(&(*data)[data_size], signature);
+       data_size += signature.size + 2;
+
+       gnutls_free_datum(&signature);
+
+       return data_size;
+
+}
+
+extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert;
+
+static int proc_srp_rsa_server_kx2(gnutls_session session, opaque * data, size_t _data_size)
+{
+ssize_t ret;
+int i, sigsize;
+gnutls_datum vparams, signature;
+ssize_t data_size;
+CERTIFICATE_AUTH_INFO info;
+gnutls_cert peer_cert;
+opaque* p;
+
+       ret = _gnutls_proc_srp_server_kx2( session, data, _data_size);
+       if (ret < 0) return ret;
+       
+       data_size = _data_size - ret;
+
+       info = _gnutls_get_auth_info( session);
+       if (info == NULL || info->ncerts==0) {
+               gnutls_assert();
+               /* we need this in order to get peer's certificate */
+               return GNUTLS_E_INTERNAL_ERROR;
+       }
+
+       /* VERIFY SIGNATURE */
+
+       vparams.size = ret; /* all the data minus the signature */
+       vparams.data = data;
+
+       p = &data[vparams.size];
+
+       DECR_LEN( data_size, 2);
+       sigsize = _gnutls_read_uint16( p);
+
+       DECR_LEN( data_size, sigsize);
+       signature.data = &p[2];
+       signature.size = sigsize;
+
+       switch( session->security_parameters.cert_type) {
+               case GNUTLS_CRT_X509:
+                       if ((ret =
+                            _gnutls_x509_cert2gnutls_cert( &peer_cert,
+                                            info->raw_certificate_list[0], CERT_NO_COPY)) < 0) {
+                               gnutls_assert();
+                               return ret;
+                       }
+                       break;
+
+               case GNUTLS_CRT_OPENPGP:
+                       if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) {
+                               gnutls_assert();
+                               return GNUTLS_E_INIT_LIBEXTRA;
+                       }
+                       if ((ret =
+                            _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert,
+                                            info->raw_certificate_list[0])) < 0) {
+                               gnutls_assert();
+                               return ret;
+                       }
+                       break;
+
+               default:
+                       gnutls_assert();
+                       return GNUTLS_E_INTERNAL_ERROR;
+       }
+
+       ret =
+           _gnutls_verify_sig_params(session,
+                                     &peer_cert,
+                                     &vparams, &signature);
+       
+       _gnutls_free_cert( peer_cert);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       return 0;
+}
+
+
+#endif /* ENABLE_SRP */
index 3ebd31cf1669062564539684ec639c9e7c751073..957ec92529a79f007fac0ac7732490c18b3d3142 100644 (file)
@@ -32,8 +32,9 @@ int _gnutls_srp_recv_params( gnutls_session state, const opaque* data, size_t _d
        uint8 len;
        ssize_t data_size = _data_size;
 
-       if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0) {
-               /* algorithm was not allowed in this state
+       if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0 && 
+               _gnutls_kx_priority( state, GNUTLS_KX_SRP_RSA) < 0) {
+               /* algorithm was not allowed in this session
                 */
                return 0;
        }
@@ -52,7 +53,7 @@ int _gnutls_srp_recv_params( gnutls_session state, const opaque* data, size_t _d
                }
        } else { /* client side reading server hello extensions */
                if (state->internals.resumed==RESUME_FALSE)
-                       return proc_srp_server_hello( state, data, data_size);
+                       return _gnutls_proc_srp_server_hello( state, data, data_size);
                else /* we do not need to process this if
                      * we are resuming.
                      */
@@ -61,14 +62,25 @@ int _gnutls_srp_recv_params( gnutls_session state, const opaque* data, size_t _d
        return 0;
 }
 
+/* Checks if the given cipher suite is an SRP one
+ */
+inline static int is_srp( GNUTLS_CipherSuite suite) {
+       int kx = _gnutls_cipher_suite_get_kx_algo( suite);
+       
+       if (kx == GNUTLS_KX_SRP || (kx == GNUTLS_KX_SRP_RSA)) return 1;
+       
+       return 0;
+}
+
 /* returns data_size or a negative number on failure
  * data is allocated localy
  */
 int _gnutls_srp_send_params( gnutls_session state, opaque* data, size_t data_size) {
        uint len;
 
-       if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0) {
-               /* algorithm was not allowed in this state
+       if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0 && 
+               _gnutls_kx_priority( state, GNUTLS_KX_SRP_RSA) < 0) {
+               /* algorithm was not allowed in this session
                 */
                return 0;
        }
@@ -97,11 +109,12 @@ int _gnutls_srp_send_params( gnutls_session state, opaque* data, size_t data_siz
                
                /* note that security parameters are not fully established
                 */
-               if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) != GNUTLS_KX_SRP)
+
+               if ( !is_srp(state->security_parameters.current_cipher_suite))
                        return 0; /* no data to send */
                
                if (state->internals.resumed==RESUME_FALSE)
-                       return gen_srp_server_hello( state, data, data_size);
+                       return _gnutls_gen_srp_server_hello( state, data, data_size);
                else
                        return 0;
        }
index 2dab1b5d0901c3b1fef23148d08261d430d49bd9..608266ac32ec3a987c5731d08354f06322be1454 100644 (file)
@@ -57,6 +57,7 @@ int i;
 extern const int _gnutls_kx_algorithms_size;
 extern gnutls_kx_algo_entry _gnutls_kx_algorithms[];
 extern MOD_AUTH_STRUCT srp_auth_struct;
+extern MOD_AUTH_STRUCT srp_rsa_auth_struct;
 
 static int _gnutls_add_srp_auth_struct(void) {
 int i;
@@ -73,6 +74,16 @@ int i;
 
                _gnutls_kx_algorithms[i+1].name = 0;
        
+       }
+       i++;
+
+       if (_gnutls_kx_algorithms[i].name==NULL && (i < _gnutls_kx_algorithms_size-1)) {
+               _gnutls_kx_algorithms[i].name = "SRP_RSA";
+               _gnutls_kx_algorithms[i].algorithm = GNUTLS_KX_SRP_RSA;
+               _gnutls_kx_algorithms[i].auth_struct = &srp_rsa_auth_struct;
+
+               _gnutls_kx_algorithms[i+1].name = 0;
+       
                return 0; /* ok */
        }
 
index 37933630015884757b75093573b766ecb60041bb..e1f6d67bdcb4671050e9f4842fc2204a15784b98 100644 (file)
@@ -5,5 +5,5 @@ typedef int (*OPENPGP_VERIFY_KEY_FUNC)( const char *,
 typedef time_t (*OPENPGP_KEY_CREATION_TIME_FUNC)( const gnutls_datum*);
 typedef time_t (*OPENPGP_KEY_EXPIRATION_TIME_FUNC)( const gnutls_datum*);
 typedef int (*OPENPGP_KEY_REQUEST)(gnutls_datum*, const gnutls_certificate_credentials, opaque*,int);
-typedef int (*OPENPGP_FINGERPRINT)(const gnutls_datum*, char*, size_t*);
+typedef int (*OPENPGP_FINGERPRINT)(const gnutls_datum*, unsigned char*, size_t*);
 typedef int (*OPENPGP_CERT2GNUTLS_CERT)(gnutls_cert*, gnutls_datum);
index f5b166f45d8e2635a1c6902b00ac4a23a1d1e32e..027c47fd305dbf9f014621473708ce7cce15971c 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -506,8 +506,10 @@ void gaa_parser(int argc, char **argv)
 
    if (info.kx != NULL && info.nkx > 0) {
       for (j = i = 0; i < info.nkx; i++) {
-        if (strncasecmp(info.kx[i], "SRP", 3) == 0)
+        if (strcasecmp(info.kx[i], "SRP") == 0)
            kx_priority[j++] = GNUTLS_KX_SRP;
+        if (strcasecmp(info.kx[i], "SRP-RSA") == 0)
+           kx_priority[j++] = GNUTLS_KX_SRP_RSA;
         if (strcasecmp(info.kx[i], "RSA") == 0)
            kx_priority[j++] = GNUTLS_KX_RSA;
         if (strcasecmp(info.kx[i], "RSA-EXPORT") == 0)
index bb0febbd3308789804d3af48e54179020d2e309b..9038bcb811824cd69fd4d5af10430a2dcef020f7 100644 (file)
@@ -373,6 +373,7 @@ void print_list(void)
        printf(", DHE-DSS");
        printf(", DHE-RSA");
        printf(", SRP");
+       printf(", SRP-RSA");
        printf(", ANON-DH\n");
 
        printf("Compression methods:");
index 48828ae4a0dcf475d0eb3306443b5667175cd8fc..f0a508f68bb634e222847bc9ba73404500e7b1bc 100644 (file)
@@ -986,8 +986,10 @@ void gaa_parser(int argc, char **argv)
 
    if (info.kx != NULL && info.nkx > 0) {
       for (j = i = 0; i < info.nkx; i++) {
-        if (strncasecmp(info.kx[i], "SRP", 3) == 0)
+        if (strcasecmp(info.kx[i], "SRP") == 0)
            kx_priority[j++] = GNUTLS_KX_SRP;
+        if (strcasecmp(info.kx[i], "SRP-RSA") == 0)
+           kx_priority[j++] = GNUTLS_KX_SRP_RSA;
         if (strcasecmp(info.kx[i], "RSA") == 0)
            kx_priority[j++] = GNUTLS_KX_RSA;
         if (strcasecmp(info.kx[i], "RSA-EXPORT") == 0)