]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
more rsa stuff -- and cleanups
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 15 Jun 2001 22:05:32 +0000 (22:05 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 15 Jun 2001 22:05:32 +0000 (22:05 +0000)
12 files changed:
lib/auth_anon.c
lib/auth_rsa.c
lib/auth_srp.c
lib/auth_x509.h
lib/gnutls.h.in
lib/gnutls_algorithms.c
lib/gnutls_auth.h
lib/gnutls_datum.c
lib/gnutls_datum.h
lib/gnutls_handshake.c
lib/gnutls_int.h
src/serv.c

index 315fc9980ba92057da113c98038619b4609060da..43dd30d7f896c1da3b592593dbb9e5a647b5eb04 100644 (file)
@@ -35,6 +35,7 @@ int proc_anon_client_kx( GNUTLS_KEY, opaque*, int);
 
 MOD_AUTH_STRUCT anon_auth_struct = {
        "ANON",
+       NULL,
        gen_anon_server_kx,
        NULL,
        NULL,
index 932c7b2c7b154f808a9ef02317e7493649ae2744..7d4c3aa3b59480a1ed6985270d2ffc16c9c816a8 100644 (file)
 #include "gnutls_datum.h"
 #include "auth_x509.h"
 
+#if 0
 int gen_rsa_server_kx(GNUTLS_KEY, opaque **);
+#endif
+int gen_rsa_certificate(GNUTLS_KEY, opaque **);
+int proc_rsa_client_kx( GNUTLS_KEY, opaque*, int);
 
 MOD_AUTH_STRUCT rsa_auth_struct = {
        "RSA",
-       gen_rsa_server_kx,
-       NULL,
+       gen_rsa_certificate,
+/*     not needed!!! gen_rsa_server_kx, */ NULL,
        NULL,
        NULL,
        NULL,
@@ -44,6 +48,7 @@ MOD_AUTH_STRUCT rsa_auth_struct = {
        NULL,
        NULL,
        NULL,
+       proc_rsa_client_kx,
        NULL,
        NULL
 };
@@ -102,10 +107,6 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
 }
 
 
-#define dat_set( d,s,len) d.data=gnutls_malloc(len); \
-               if (d.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
-               memcpy(d.data, s, len); d.size = len;
-
 /* This function reads the RSA parameters from the given(?) certificate.
  */
 static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_datum cert)
@@ -131,7 +132,7 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
                return GNUTLS_E_PARSING_ERROR;
        }
 
-       if (!strcmp(str, "111")) {      /* pkix-1 1 - RSA */
+       if (!strcmp(str, "1 2 840 113549 1 1 1")) { /* pkix-1 1 - RSA */
                len = sizeof(str);
                result =
                    read_value("certificate2.tbsCertificate.subjectPublicKeyInfo.parameters", str, &len);
@@ -165,7 +166,11 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
                        delete_structure("rsapublickey");
                        return GNUTLS_E_MPI_SCAN_FAILED;
                }
-               dat_set(params->rsa_modulus, str, len);
+               if (gnutls_set_datum(&params->rsa_modulus, str, len) < 0) {
+                       gnutls_assert();
+                       delete_structure("rsapublickey");
+                       return GNUTLS_E_MEMORY_ERROR;
+               }
 
                len = sizeof(str);
                result =
@@ -173,7 +178,7 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
                if (result != ASN_OK) {
                        gnutls_assert();
                        delete_structure("rsapublickey");
-                       gnutls_free(params->rsa_modulus.data);
+                       gnutls_free_datum(&params->rsa_modulus);
                        gcry_mpi_release(key->A);
                        return GNUTLS_E_PARSING_ERROR;
                }
@@ -182,11 +187,16 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
                          GCRYMPI_FMT_USG, str, &len) != 0) {
                        gnutls_assert();
                        gcry_mpi_release(key->A);
-                       gnutls_free(params->rsa_modulus.data);
+                       gnutls_free_datum(&params->rsa_modulus);
                        delete_structure("rsapublickey");
                        return GNUTLS_E_MPI_SCAN_FAILED;
                }
-               dat_set(params->rsa_exponent, str, len);
+               if (gnutls_set_datum(&params->rsa_exponent, str, len) < 0) {
+                       gcry_mpi_release(key->A);
+                       gnutls_free_datum(&params->rsa_modulus);
+                       delete_structure("rsapublickey");
+                       return GNUTLS_E_MEMORY_ERROR;   
+               }
 
                delete_structure("rsapublickey");
 
@@ -197,6 +207,63 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
        return ret;
 }
 
+/* This function reads the RSA parameters from the given private key
+ * cert is not a certificate but a der structure containing the private
+ * key(s).
+ */
+static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert)
+{
+       int ret = 0, result;
+       opaque str[5*1024];
+       int len = sizeof(str);
+
+       create_structure("rsa_key", "PKCS-1");
+
+       result = get_der("rsa_key", cert.data, cert.size);
+       if (result != ASN_OK) {
+               gnutls_assert();
+               return GNUTLS_E_PARSING_ERROR;
+       }
+
+       result =
+           read_value("rsa_key.RSAPrivateKey.privateExponent", str, &len);
+       if (result != ASN_OK) {
+               gnutls_assert();
+               delete_structure("rsa_key");
+               return GNUTLS_E_PARSING_ERROR;
+       }
+       if (gcry_mpi_scan(&key->u,
+                 GCRYMPI_FMT_USG, str, &len) != 0) {
+               gnutls_assert();
+               delete_structure("rsa_key");
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+
+       len = sizeof(str);
+       result =
+           read_value("rsa_key.modulus", str, &len);
+       if (result != ASN_OK) {
+               gnutls_assert();
+               delete_structure("rsa_key");
+               gcry_mpi_release(key->u);
+               return GNUTLS_E_PARSING_ERROR;
+       }
+
+       if (gcry_mpi_scan(&key->A,
+                 GCRYMPI_FMT_USG, str, &len) != 0) {
+               gnutls_assert();
+               delete_structure("rsa_key");
+               gcry_mpi_release(key->u);
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       delete_structure("rsa_key");
+
+       return ret;
+}
+
+#if 0 /* wow ... this was not needed ! */
 int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
 {
        RSA_Params params;
@@ -211,7 +278,7 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
        }
 
        ret =
-           _gnutls_get_rsa_params(key, &params, cred->cert_list[0]);
+           _gnutls_get_rsa_params(key, &params, cred->pkey);
 
        if (ret < 0) {
                gnutls_assert();
@@ -231,6 +298,9 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
        WRITEdatum16(pdata, params.rsa_exponent);
        pdata += params.rsa_exponent.size;
 
+       gnutls_free_datum(&params.rsa_modulus);
+       gnutls_free_datum(&params.rsa_modulus);
+
        ret = _gnutls_calc_rsa_signature( key, (*data), ret-20-16, pdata);
        if (ret< 0) {
                gnutls_free((*data));
@@ -240,4 +310,96 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
 
        return ret;     
 }
+#endif
+
+int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
+{
+       RSA_Params params;
+       const X509PKI_SERVER_CREDENTIALS *cred;
+       int ret, i;
+       opaque* pdata;
+
+       cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+       if (cred == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INSUFICIENT_CRED;
+       }
+
+       ret = 3;
+       for (i=0;i<cred->cert_list_size;i++) {
+               ret += cred->cert_list[i].size + 3; 
+                                       /* hold size
+                                        * for uint24 */
+       }
+
+       (*data) = gnutls_malloc(ret);
+       pdata = (*data);
+       
+       if (pdata == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+       
+       WRITEuint24( ret-3, pdata);
+       pdata+=3;
+       for (i=0;i<cred->cert_list_size;i++) {
+               WRITEdatum24( pdata, cred->cert_list[i]); 
+               pdata += 3 + cred->cert_list[i].size;
+       }
+
+       return ret;     
+}
+
+
+int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
+       uint16 n_Y;
+       size_t _n_Y;
+       MPI g, p;
+       int bits;
+       const RSA_SERVER_CREDENTIALS * cred;
+
+       cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+       if (cred == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INSUFICIENT_CRED;
+       }
+
+       ret =
+           _gnutls_get_rsa_params(key, &params, cred->cert_list[0]);
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+#if 0 /* removed. I do not know why - maybe I didn't get the protocol,
+       * but openssl does not use that byte
+       */
+       if (data[0] != 1) {
+               gnutls_assert();
+               return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+       }
+#endif
+
+       n_Y = READuint16( &data[0]);
+
+       _n_Y = n_Y;
+       if (gcry_mpi_scan(&key->client_Y,
+                     GCRYMPI_FMT_USG, &data[2], &_n_Y)) {
+               gnutls_assert();
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       g = gnutls_get_dh_params(&p, bits);
+       key->KEY = gnutls_calc_dh_key( key->client_Y, key->dh_secret, p);
+
+       gnutls_mpi_release(key->client_Y);
+       gnutls_mpi_release(key->dh_secret);
+       gnutls_mpi_release(p);
+       gnutls_mpi_release(g);
+       key->client_Y = NULL;
+       key->dh_secret = NULL;
+
+       return 0;
+}
 
index fe3e03fe16dc287e4def106bfcd41ba77e431487..c8fd2cef6b2a6c63eb39c9d6e3f6b62a50ae71ce 100644 (file)
@@ -38,6 +38,7 @@ int proc_srp_client_kx0(GNUTLS_KEY, opaque *, int);
 
 MOD_AUTH_STRUCT srp_auth_struct = {
        "SRP",
+       NULL,
        gen_srp_server_kx,
        gen_srp_server_kx2,
        gen_srp_client_kx0,
index d7dcd2d3a0aa02d11ddc70a48e0374a5f671f84e..a6f55501117eb41d78e94913bbe81a6b1f04dd2d 100644 (file)
@@ -4,6 +4,7 @@ extern MOD_AUTH_STRUCT x509pki_auth_struct;
 typedef struct {
        gnutls_datum * cert_list;
        int cert_list_size;
+       gnutls_datum pkey; /* private key */
 } X509PKI_SERVER_CREDENTIALS;
 
 typedef struct {
index 174a602928d19e24c43f9d03f1c923d01b0b4d15..1e26a502823f2279a3c5abb7fad905f2d42b7699 100644 (file)
@@ -144,6 +144,7 @@ typedef struct {
 typedef struct {
        gnutls_datum * cert_list;
        int cert_list_size;
+       gnutls_datum pkey; /* private key */
 } X509PKI_SERVER_CREDENTIALS;
 
 /* error codes appended here */
index e7c60fcf5793b70acb947fc9362581449d244a90..e1542bc323002e75e673ab3a31163f1e216755f3 100644 (file)
@@ -27,6 +27,7 @@
 #include "auth_anon.h"
 /* #include "auth_dhe_dss.h" */
 #include "auth_srp.h"
+#include "auth_x509.h"
 
 #define MAX_CIPHER 256
 #define MAX_MAC 256
@@ -190,12 +191,12 @@ typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
 static const gnutls_kx_algo_entry kx_algorithms[] = {
        GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_ANON, 0, 0, 0, 1,
                             &anon_auth_struct),
-       GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, NULL),
+       GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, &x509pki_auth_struct),
 /*     GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_DSS, 1, 1, 0, 0,
                             &dhe_dss_auth_struct),*/
-       GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 0, 0, NULL),
-       GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_DSS, 1, 1, 0, 0, NULL),
-       GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_RSA, 1, 1, 0, 0, NULL),
+/*     GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 0, 0, NULL),*/
+/*     GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_DSS, 1, 1, 0, 0, NULL),*/
+/*     GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_RSA, 1, 1, 0, 0, NULL),*/
        GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_SRP, 0, 0, 0, 0, &srp_auth_struct),
        {0}
 };
index b183b7ba499d01d9b6ea85b4a02a145eb86c12d0..c673e2598bd859f4279b2d9fe629630a6319c9b3 100644 (file)
@@ -2,6 +2,7 @@
  #define GNUTLS_AUTH_H
 typedef struct {
        char* name; /* null terminated */
+       int (*gnutls_generate_certificate)( GNUTLS_KEY, opaque**);
        int (*gnutls_generate_server_kx)( GNUTLS_KEY, opaque**);
        int (*gnutls_generate_server_kx2)( GNUTLS_KEY, opaque**); /* used in SRP */
        int (*gnutls_generate_client_kx0)( GNUTLS_KEY, opaque**);
index 8e137dcb18aa75ba5b0c3c19984d8805fc37400e..b152c19c407ec5fdd0260372bae751f4741d3f8a 100644 (file)
@@ -40,3 +40,21 @@ void WRITEdatum8( opaque* dest, gnutls_datum dat) {
        dest[0] = (uint8) dat.size;
        memcpy( &dest[1], dat.data, dat.size);
 }
+
+int gnutls_set_datum( gnutls_datum* dat, const void* data, int data_size) {
+       dat->data = gnutls_malloc(data_size);
+       if (dat->data==NULL) return GNUTLS_E_MEMORY_ERROR;
+       
+       dat->size = data_size;
+       memcpy( dat->data, data, data_size);
+       
+       return 0;
+}
+
+void gnutls_free_datum( gnutls_datum* dat) {
+       if (dat->data!=NULL && dat->size!=0)
+               gnutls_free( dat->data);
+
+       dat->data = NULL;
+       dat->size = 0;
+}
index 2462acd6488e9ad0ec4e29e1fd4e714ac29af3f2..0fa057dd20d3bcb32380206d37e6ec1df1d195d6 100644 (file)
@@ -2,3 +2,6 @@ void WRITEdatum16( opaque* dest, gnutls_datum dat);
 void WRITEdatum24( opaque* dest, gnutls_datum dat);
 void WRITEdatum32( opaque* dest, gnutls_datum dat);
 void WRITEdatum8( opaque* dest, gnutls_datum dat);
+
+int gnutls_set_datum( gnutls_datum* dat, const void* data, int data_size);
+void gnutls_free_datum( gnutls_datum* dat);
index 97ab9a015fd77d247f827e39675c9c1567212ef8..a05c6a91793805aa3889e79963db4a02b44d2375 100644 (file)
@@ -1150,11 +1150,15 @@ int gnutls_handshake(int cd, GNUTLS_STATE state)
        return ret;
 }
 
-/**
+ /*
   * gnutls_handshake_begin - This function does a partial handshake of the TLS/SSL protocol.
   * @cd: is a connection descriptor, as returned by socket().
   * @state: is a a &GNUTLS_STATE structure.
   *
+  * NOTE: I intend to make this function obsolete. If a certificate
+  * cannot be verified then this information will be available in the auth_info
+  * structure. Thus not need for these functions.
+  *
   * This function initiates the handshake of the TLS/SSL protocol.
   * Here we will receive - if requested and supported by the ciphersuite -
   * the peer's certificate. 
@@ -1163,7 +1167,7 @@ int gnutls_handshake(int cd, GNUTLS_STATE state)
   * However this failure will not be fatal. However you may choose to
   * continue the handshake - eg. even if the certificate cannot
   * be verified- by calling gnutls_handshake_finish().
-  **/
+  */
 int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
 {
        int ret;
@@ -1230,11 +1234,20 @@ int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
                        return ret;
                }
 
-               /* FIXME: send our certificate - if required */
                /* NOTE: these should not be send if we are resuming */
 
                /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
 
+               if (state->gnutls_internals.resumed == RESUME_FALSE)
+                       ret = _gnutls_send_certificate(cd, state);
+               if (ret < 0) {
+                       ERR("send server certificate", ret);
+                       gnutls_assert();
+                       gnutls_clearHashDataBuffer(state);
+                       return ret;
+               }
+
+
                /* send server key exchange (A) */
                if (state->gnutls_internals.resumed == RESUME_FALSE)
                        ret = _gnutls_send_server_kx_message(cd, state);
@@ -1245,6 +1258,8 @@ int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
                        return ret;
                }
 
+               /* FIXME: Send certificate request */
+
 /* Added for SRP which uses a different handshake */
                /* receive the client key exchange message */
                if (state->gnutls_internals.resumed == RESUME_FALSE)    /* if we are not resuming */
@@ -1269,7 +1284,8 @@ int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
        }
 }
 
-/* This function sends the final handshake packets and initializes connection */
+/* This function sends the final handshake packets and initializes connection 
+ */
 static int _gnutls_send_handshake_final(int cd, GNUTLS_STATE state,
                                        int init)
 {
@@ -1303,7 +1319,8 @@ static int _gnutls_send_handshake_final(int cd, GNUTLS_STATE state,
        return ret;
 }
 
-/* This function receives the final handshake packets */
+/* This function receives the final handshake packets 
+ */
 static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state,
                                        int init)
 {
@@ -1337,7 +1354,7 @@ static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state,
        return ret;
 }
 
-/**
+ /*
   * gnutls_handshake_finish - This function finished a partial handshake of the TLS/SSL protocol.
   * @cd: is a connection descriptor, as returned by socket().
   * @state: is a a &GNUTLS_STATE structure.
@@ -1346,7 +1363,7 @@ static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state,
   * You should call it only if you used gnutls_handshake_begin() and
   * you have somehow verified the identity of the peer.
   * This function will fail if any problem is encountered.
-  **/
+  */
 int gnutls_handshake_finish(int cd, GNUTLS_STATE state)
 {
        int ret = 0;
index 58b682e461a165c63afe67957684fbeccc7de56a..403cc1c208c08260c2395890d390c226d79e868e 100644 (file)
@@ -142,6 +142,7 @@ typedef struct {
        /* RSA: 
         * modulus is A
         * exponent is B
+        * private key is u;
         */
        
        /* this is used to hold the peers authentication data 
index ab57e9411005ce78aaa45d660a567d3925807978..126c57fd4c669a2200e6863150ba636f50ed7ee2 100644 (file)
@@ -82,6 +82,7 @@ int main()
                gnutls_init(&state, GNUTLS_SERVER);
                if ((ret = gnutls_set_db_name(state, "gnutls-rsm.db")) < 0)
                        fprintf(stderr, "*** DB error (%d)\n", ret);
+               
                gnutls_set_cipher_priority(state, GNUTLS_TWOFISH,
                                           GNUTLS_RIJNDAEL, GNUTLS_3DES,
                                           GNUTLS_ARCFOUR, 0);