]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
* Added ability to generate RSA keys.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 12 Mar 2003 10:57:56 +0000 (10:57 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 12 Mar 2003 10:57:56 +0000 (10:57 +0000)
* Increased the maximum parameter size in order to read some large keys
  by some CAs. Patch by Ian Peters <itp@ximian.com>.
* Rolled back some of yesterdays changes. The gnutls_x509_privkey, was
  replaced (again) by the gnutls_privkey.

19 files changed:
NEWS
includes/gnutls/x509.h
lib/auth_cert.c
lib/auth_cert.h
lib/auth_dhe.c
lib/auth_rsa.c
lib/auth_rsa_export.c
lib/gnutls_cert.c
lib/gnutls_cert.h
lib/gnutls_mpi.h
lib/gnutls_sig.c
lib/gnutls_sig.h
lib/gnutls_x509.c
lib/x509/privkey.c
lib/x509/verify.c
lib/x509/x509.c
lib/x509/x509.h
libextra/auth_srp_rsa.c
libextra/gnutls_openpgp.c

diff --git a/NEWS b/NEWS
index 36bfb76ddd7d9418dfe38fc6d9ca54fe690ae8ba..e2d074ad9e353d82c6f3195749f9423dc076b8fc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ Version 0.9.1
 - Corrected a broken buffer check in _gnutls_io_read_buffered(),
   which caused some unexpected packet length errors. Report and patch
   by Ian Peters <itp@ximian.com>.
+- Added ability to generate RSA keys.
+- Increased the maximum parameter size in order to read some large keys
+  by some CAs. Patch by Ian Peters <itp@ximian.com>.
 
 Version 0.9.0 (03/03/2003)
 - This version is not binary compatible with the previous ones.
index ecc2cc625438ad17051de7c25de83c73c7d5925d..66b920e2cfc7a95bd82846056487c09713609806 100644 (file)
@@ -200,6 +200,12 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
        gnutls_x509_crt_fmt format);
 int gnutls_x509_privkey_get_pk_algorithm( gnutls_x509_privkey key);
 
+int gnutls_x509_privkey_generate( gnutls_x509_privkey key, gnutls_pk_algorithm algo,
+       int bits);
+
+int gnutls_x509_privkey_export( gnutls_x509_privkey key,
+       gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size);
+
 
 #ifdef __cplusplus
 }
index 2cc7804340f22ddd37d71768b3c8f099813a8760..c20be5aff9838715c3143b42df927a0637d743e4 100644 (file)
@@ -410,7 +410,7 @@ int _gnutls_gen_x509_crt(gnutls_session session, opaque ** data)
        int ret, i;
        opaque *pdata;
        gnutls_cert *apr_cert_list;
-       gnutls_x509_privkey apr_pkey;
+       gnutls_privkey *apr_pkey;
        int apr_cert_list_length;
 
        /* find the appropriate certificate */
@@ -462,7 +462,7 @@ int _gnutls_gen_openpgp_certificate(gnutls_session session, opaque ** data)
        int ret;
        opaque *pdata;
        gnutls_cert *apr_cert_list;
-       gnutls_x509_privkey apr_pkey;
+       gnutls_privkey* apr_pkey;
        int apr_cert_list_length;
 
        /* find the appropriate certificate */
@@ -512,7 +512,7 @@ int _gnutls_gen_openpgp_certificate_fpr(gnutls_session session,
        int ret, fpr_size, packet_size;
        opaque *pdata;
        gnutls_cert *apr_cert_list;
-       gnutls_x509_privkey apr_pkey;
+       gnutls_privkey* apr_pkey;
        int apr_cert_list_length;
 
        /* find the appropriate certificate */
@@ -1038,7 +1038,7 @@ int _gnutls_gen_cert_client_cert_vrfy(gnutls_session session,
 {
        int ret;
        gnutls_cert *apr_cert_list;
-       gnutls_x509_privkey apr_pkey;
+       gnutls_privkey* apr_pkey;
        int apr_cert_list_length, size;
        gnutls_datum signature;
 
@@ -1204,7 +1204,7 @@ int _gnutls_gen_cert_server_cert_req(gnutls_session session,
 int _gnutls_find_apr_cert(gnutls_session session,
                          gnutls_cert ** apr_cert_list,
                          int *apr_cert_list_length,
-                         gnutls_x509_privkey * apr_pkey)
+                         gnutls_privkey ** apr_pkey)
 {
        const gnutls_certificate_credentials cred;
        int ind;
@@ -1242,7 +1242,7 @@ int _gnutls_find_apr_cert(gnutls_session session,
                                *apr_cert_list = cred->cert_list[ind];
                                *apr_cert_list_length =
                                    cred->cert_list_length[ind];
-                               *apr_pkey = cred->pkey[ind];
+                               *apr_pkey = &cred->pkey[ind];
                        }
                }
        } else {                /* CLIENT SIDE */
@@ -1266,7 +1266,7 @@ int _gnutls_find_apr_cert(gnutls_session session,
                                *apr_cert_list = cred->cert_list[ind];
                                *apr_cert_list_length =
                                    cred->cert_list_length[ind];
-                               *apr_pkey = cred->pkey[ind];
+                               *apr_pkey = &cred->pkey[ind];
                        }
                }
 
index 8bee758041243a2fe20a29689fbab6839ba09bb7..a667aa394ed9941b255032222a66c1ea12f3f55b 100644 (file)
@@ -25,7 +25,7 @@ typedef struct {
                         * This is the same with the number of pkeys.
                         */
 
-       gnutls_x509_privkey * pkey; 
+       gnutls_privkey * pkey; 
                               /* private keys. It contains ncerts private
                                * keys. pkey[i] corresponds to certificate in
                                * cert_list[i][0].
@@ -89,7 +89,7 @@ int _gnutls_gen_cert_server_cert_req(gnutls_session, opaque **);
 int _gnutls_proc_cert_cert_req(gnutls_session, opaque *, size_t);
 int _gnutls_proc_cert_client_cert_vrfy(gnutls_session, opaque *, size_t);
 int _gnutls_proc_cert_server_certificate(gnutls_session, opaque *, size_t);
-int _gnutls_find_apr_cert( gnutls_session session, gnutls_cert** apr_cert_list, int *apr_cert_list_length, gnutls_x509_privkey* apr_pkey);
+int _gnutls_find_apr_cert( gnutls_session session, gnutls_cert** apr_cert_list, int *apr_cert_list_length, gnutls_privkey** apr_pkey);
 const gnutls_cert * _gnutls_server_find_cert( struct gnutls_session_int*, gnutls_pk_algorithm);
 
 #define _gnutls_proc_cert_client_certificate _gnutls_proc_cert_server_certificate
index 56dad83e107befa7cd0281431acbec14ca9d72da..4e7323297aa2d881992b2e40c0abffccb49bf410 100644 (file)
@@ -82,7 +82,7 @@ static int gen_dhe_server_kx(gnutls_session session, opaque ** data)
        int ret = 0, data_size;
        int bits;
        gnutls_cert *apr_cert_list;
-       gnutls_x509_privkey apr_pkey;
+       gnutls_privkey* apr_pkey;
        int apr_cert_list_length;
        gnutls_datum signature, ddata;
        CERTIFICATE_AUTH_INFO info;
index af93ee722b299513cf2bbaafe31343bfee13452b..1c1ec48a081507b6edd7b4152c72a7d43de61a78 100644 (file)
@@ -65,7 +65,8 @@ extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert;
 
 /* This function reads the RSA parameters from peer's certificate;
  */
-int _gnutls_get_public_rsa_params(gnutls_session session, GNUTLS_MPI params[MAX_PARAMS_SIZE], int* params_len)
+int _gnutls_get_public_rsa_params(gnutls_session session, 
+       GNUTLS_MPI params[MAX_PUBLIC_PARAMS_SIZE], int* params_len)
 {
 int ret;
 CERTIFICATE_AUTH_INFO info;
@@ -191,8 +192,8 @@ const gnutls_certificate_credentials cred;
 
        /* non export cipher suites. */ 
        
-       *params_size = cred->pkey[index]->params_size;
-       *params = cred->pkey[index]->params;
+       *params_size = cred->pkey[index].params_size;
+       *params = cred->pkey[index].params;
 
        return 0;
 }
@@ -277,8 +278,8 @@ int _gnutls_gen_rsa_client_kx(gnutls_session session, opaque ** data)
 {
        CERTIFICATE_AUTH_INFO auth = session->key->auth_info;
        gnutls_datum sdata;     /* data to send */
-       GNUTLS_MPI params[MAX_PARAMS_SIZE];
-       int params_len = MAX_PARAMS_SIZE;
+       GNUTLS_MPI params[MAX_PUBLIC_PARAMS_SIZE];
+       int params_len = MAX_PUBLIC_PARAMS_SIZE;
        int ret, i;
        gnutls_protocol_version ver;
 
index ef1ba7e35e8e2116bd39c36388860a0680e87933..3c49e72170fe8664249d49686d5692477a0fca29 100644 (file)
@@ -74,7 +74,7 @@ static int gen_rsa_export_server_kx(gnutls_session session, opaque ** data)
        uint8 *data_e, *data_m;
        int ret = 0, data_size;
        gnutls_cert *apr_cert_list;
-       gnutls_x509_privkey apr_pkey;
+       gnutls_privkey* apr_pkey;
        int apr_cert_list_length;
        gnutls_datum signature, ddata;
        CERTIFICATE_AUTH_INFO info;
index a12162e179335746208bda8431a545079f40aa60..8cf6167e79b938c161bc55b018e71c23e8fdc5ea 100644 (file)
@@ -81,7 +81,7 @@ void gnutls_certificate_free_credentials(gnutls_certificate_credentials sc)
        _gnutls_free_datum( &sc->keyring);
 
        for (i = 0; i < sc->ncerts; i++) {
-               gnutls_x509_privkey_deinit(sc->pkey[i]);
+               gnutls_privkey_deinit( &sc->pkey[i]);
        }
 
        gnutls_free( sc->pkey);
@@ -478,7 +478,7 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gcert, const gnutls_datum *derCe
        gcert->subject_pk_algorithm = gnutls_x509_crt_get_pk_algorithm( cert, NULL);
 
        if (flags & CERT_ONLY_PUBKEY || flags == 0) {
-               gcert->params_size = MAX_PARAMS_SIZE;
+               gcert->params_size = MAX_PUBLIC_PARAMS_SIZE;
                ret = _gnutls_x509_crt_get_mpis( cert, gcert->params, &gcert->params_size);
                if (ret < 0) {
                        gnutls_assert();
index c2a6c9cd03f2a20060f37edb20a9a46a49d0f3ba..44ac3ce0af89f59fceb7474a02457cc3bd26e1c1 100644 (file)
@@ -51,6 +51,28 @@ typedef struct gnutls_cert {
        
 } gnutls_cert;
 
+typedef struct gnutls_privkey_int {
+       MPI params[MAX_PRIV_PARAMS_SIZE];/* the size of params depends on the public 
+                                * key algorithm 
+                                */
+                               /*
+                                * RSA: [0] is modulus
+                                *      [1] is public exponent
+                                *      [2] is private exponent
+                                *      [3] is prime1 (p)
+                                *      [4] is prime2 (q)
+                                *      [5] is coefficient (u == inverse of p mod q)
+                                * DSA: [0] is p
+                                *      [1] is q
+                                *      [2] is g
+                                *      [3] is y (public key)
+                                *      [4] is x (private key)
+                                */
+       int params_size; /* holds the number of params */
+
+       gnutls_pk_algorithm pk_algorithm;
+} gnutls_privkey;
+
 struct gnutls_session_int; /* because gnutls_session is not defined when this file is included */
 
 typedef enum ConvFlags { 
@@ -64,6 +86,8 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gcert, const gnutls_datum *derCe
 void _gnutls_free_cert(gnutls_cert* cert);
 int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn);
 
+void _gnutls_privkey_deinit(gnutls_privkey *key);
+
 int _gnutls_cert_supported_kx( const gnutls_cert* cert, gnutls_kx_algorithm **alg, int *alg_size);
 
 #endif
index c92a9d8adad4b5b3610cfa247b307343f4b195c1..7ec3982d84dc7950b9dcdb64efe80f6a8334834e 100644 (file)
@@ -22,6 +22,7 @@
 #define _gnutls_mpi_mulm gcry_mpi_mulm
 #define _gnutls_mpi_mul gcry_mpi_mul
 #define _gnutls_mpi_add gcry_mpi_add
+#define _gnutls_mpi_add_ui gcry_mpi_add_ui
 #define _gnutls_mpi_mul_ui gcry_mpi_mul_ui
 
 # define _gnutls_mpi_alloc_like(x) _gnutls_mpi_new(_gnutls_mpi_get_nbits(x)) 
index 49283f00f0a76d23ed4737b87ef99984cd45cb72..a70d1fd2add9b969cf83466d6c4b6762a9225c5e 100644 (file)
 #include <gnutls_sig.h>
 
 
-int _gnutls_generate_sig( gnutls_cert* cert, gnutls_x509_privkey pkey, const gnutls_datum* hash_concat, gnutls_datum *signature);
+int _gnutls_generate_sig( gnutls_cert* cert, gnutls_privkey* pkey, const gnutls_datum* hash_concat, gnutls_datum *signature);
 
 
 /* Generates a signature of all the previous sent packets in the 
  * handshake procedure.
  */
-int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_x509_privkey pkey, gnutls_datum *signature) {
+int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum *signature) {
 gnutls_datum dconcat;
 int ret;
 opaque concat[36];
@@ -88,7 +88,7 @@ GNUTLS_MAC_HANDLE td_sha;
 /* Generates a signature of all the random data and the parameters.
  * Used in DHE_* ciphersuites.
  */
-int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_x509_privkey pkey, gnutls_datum* params, gnutls_datum *signature) 
+int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum* params, gnutls_datum *signature) 
 {
 gnutls_datum dconcat;
 int ret;
@@ -148,7 +148,7 @@ opaque concat[36];
  * Cert is the certificate of the corresponding private key. It is only checked if
  * it supports signing.
  */
-int _gnutls_generate_sig( gnutls_cert* cert, gnutls_x509_privkey pkey, const gnutls_datum* hash_concat, gnutls_datum *signature)
+int _gnutls_generate_sig( gnutls_cert* cert, gnutls_privkey* pkey, const gnutls_datum* hash_concat, gnutls_datum *signature)
 {
 int ret;
 gnutls_datum tmpdata;
index 8b6a1603f3eb96b75a1f5cd952f46dc86885a541..e839c38d8879851dd7eaf34e1ea73d3a3792abfd 100644 (file)
@@ -3,8 +3,8 @@
 # include <auth_cert.h>
 
 gnutls_certificate_status gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer);
-int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_x509_privkey pkey, gnutls_datum *signature);
-int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_x509_privkey pkey, gnutls_datum* params, gnutls_datum *signature);
+int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_privkey *pkey, gnutls_datum *signature);
+int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey *pkey, gnutls_datum* params, gnutls_datum *signature);
 int _gnutls_verify_sig_hdata( gnutls_session session, gnutls_cert *cert, gnutls_datum* signature);
 int _gnutls_verify_sig_params( gnutls_session session, gnutls_cert *cert, const gnutls_datum* params, gnutls_datum* signature);
 
index 5b028375b7fa52161263663fcb6757d63e80fc22..5865143fd3d8ca8011adcb02cbfb63ff4cf7f0e8 100644 (file)
@@ -152,9 +152,9 @@ int _gnutls_x509_cert_verify_peers(gnutls_session session)
  */
 static int _gnutls_check_key_cert_match( gnutls_certificate_credentials res) 
 {
-int pk = res->cert_list[res->ncerts-1][0].subject_pk_algorithm;
+uint pk = res->cert_list[res->ncerts-1][0].subject_pk_algorithm;
        
-       if (gnutls_x509_privkey_get_pk_algorithm(res->pkey[res->ncerts-1]) != pk) 
+       if (res->pkey[res->ncerts-1].pk_algorithm != pk) 
        {
                gnutls_assert();
                return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
@@ -430,6 +430,43 @@ int read_cert_mem(gnutls_certificate_credentials res, const char *cert, int cert
 }
 
 
+static int privkey_cpy( gnutls_privkey* dest, gnutls_x509_privkey src)
+{
+int i, ret;
+
+       memset( dest, 0, sizeof(gnutls_privkey));
+
+       for(i=0;i<src->params_size;i++) {
+               dest->params[i] = _gnutls_mpi_copy( src->params[i]);
+               if (dest->params[i] == NULL) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_MEMORY_ERROR;
+                       goto cleanup;
+               }
+       }
+
+       dest->pk_algorithm = src->pk_algorithm;
+       dest->params_size = src->params_size;
+
+       return 0;
+
+       cleanup:
+       
+       for (i=0;i<src->params_size;i++) {
+               _gnutls_mpi_release( &dest->params[i]);
+       }
+       return ret;
+}
+
+void _gnutls_privkey_deinit(gnutls_privkey *key)
+{
+int i;
+
+       for (i = 0; i < key->params_size; i++) {
+               _gnutls_mpi_release( &key->params[i]);
+       }
+}
+
 
 /* Reads a PEM encoded PKCS-1 RSA private key from memory
  * 2002-01-26: Added ability to read DSA keys.
@@ -440,16 +477,17 @@ static int read_key_mem(gnutls_certificate_credentials res, const char *key, int
 {
        int ret;
        gnutls_datum tmp;
+       gnutls_x509_privkey tmpkey;
 
        /* allocate space for the pkey list
         */
-       res->pkey = gnutls_realloc_fast( res->pkey, (res->ncerts+1)*sizeof(gnutls_x509_privkey));
+       res->pkey = gnutls_realloc_fast( res->pkey, (res->ncerts+1)*sizeof(gnutls_privkey));
        if (res->pkey==NULL) {
                gnutls_assert();
                return GNUTLS_E_MEMORY_ERROR;
        }
 
-       ret = gnutls_x509_privkey_init( &res->pkey[res->ncerts]);
+       ret = gnutls_x509_privkey_init( &tmpkey); //res->pkey[res->ncerts]);
        if (ret < 0) {
                gnutls_assert();
                return ret;
@@ -458,15 +496,18 @@ static int read_key_mem(gnutls_certificate_credentials res, const char *key, int
        tmp.data = (opaque*)key;
        tmp.size = key_size;
 
-       ret = gnutls_x509_privkey_import( res->pkey[res->ncerts], &tmp, type);
+       ret = gnutls_x509_privkey_import( tmpkey, &tmp, type);
        if (ret < 0) {
                gnutls_assert();
-               gnutls_x509_privkey_deinit( res->pkey[res->ncerts]);
-               res->pkey[res->ncerts] = NULL;
+               gnutls_x509_privkey_deinit( tmpkey);
 
                return ret;
        }
 
+       privkey_cpy( &res->pkey[res->ncerts], tmpkey);
+
+       gnutls_x509_privkey_deinit( tmpkey);
+
        return 0;
 }
 
@@ -608,7 +649,7 @@ void gnutls_certificate_free_keys(gnutls_certificate_credentials sc)
        sc->cert_list = NULL;
 
        for (i = 0; i < sc->ncerts; i++) {
-               gnutls_x509_privkey_deinit(sc->pkey[i]);
+               _gnutls_privkey_deinit( &sc->pkey[i]);
        }
 
        gnutls_free( sc->pkey);
index b55de979de9043fa75657d554e06802e4c7372af..1ce006cc80ec92619d7035700e93b9c85481bc58 100644 (file)
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
+#include <gnutls_rsa_export.h>
 #include <common.h>
 #include <gnutls_x509.h>
 #include <x509_b64.h>
 #include <x509.h>
 #include <dn.h>
 #include <extensions.h>
-#include <gnutls_privkey.h>
 
 /**
   * gnutls_x509_privkey_init - This function initializes a gnutls_crl structure
@@ -45,6 +45,7 @@ int gnutls_x509_privkey_init(gnutls_x509_privkey * key)
        *key = gnutls_calloc( 1, sizeof(gnutls_x509_privkey_int));
 
        if (*key) {
+               (*key)->key = ASN1_TYPE_EMPTY;
                (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN;
                return 0;               /* success */
        }
@@ -56,7 +57,7 @@ int gnutls_x509_privkey_init(gnutls_x509_privkey * key)
   * gnutls_x509_privkey_deinit - This function deinitializes memory used by a gnutls_x509_privkey structure
   * @key: The structure to be initialized
   *
-  * This function will deinitialize a CRL structure. 
+  * This function will deinitialize a private key structure. 
   *
   **/
 void gnutls_x509_privkey_deinit(gnutls_x509_privkey key)
@@ -67,6 +68,7 @@ int i;
                _gnutls_mpi_release( &key->params[i]);
        }
 
+       asn1_delete_structure(&key->key);
        gnutls_free(key);
 }
 
@@ -355,7 +357,7 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
 
 /**
   * gnutls_x509_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm
-  * @cert: should contain a gnutls_x509_privkey structure
+  * @key: should contain a gnutls_x509_privkey structure
   *
   * This function will return the public key algorithm of a private
   * key.
@@ -368,3 +370,344 @@ int gnutls_x509_privkey_get_pk_algorithm( gnutls_x509_privkey key)
 {
         return key->pk_algorithm;
 }
+
+
+/**
+  * gnutls_x509_privkey_export - This function will export the private key
+  * @key: Holds the key
+  * @format: the format of output params. One of PEM or DER.
+  * @output_data: will contain a private key PEM or DER encoded
+  * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
+  *
+  * This function will export the private key to a PKCS1 structure for RSA keys,
+  * or an integer sequence for DSA keys. The DSA keys are in the same format
+  * with the parameters used by openssl.
+  *
+  * If the buffer provided is not long enough to hold the output, then
+  * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
+  *
+  * If the structure is PEM encoded, it will have a header
+  * of "BEGIN RSA PRIVATE KEY".
+  *
+  * In case of failure a negative value will be returned, and
+  * 0 on success.
+  *
+  **/
+int gnutls_x509_privkey_export( gnutls_x509_privkey key,
+       gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size)
+{
+       int result;
+       
+       if (format == GNUTLS_X509_FMT_DER) {
+               if ((result=asn1_der_coding( key->key, "", output_data, output_data_size, NULL)) != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       
+                       if (result == ASN1_MEM_ERROR)
+                               return GNUTLS_E_SHORT_MEMORY_BUFFER;
+
+                       return _gnutls_asn2err(result);
+               }
+
+       } else { /* PEM */
+               opaque tmp[5*1024];
+               opaque *out;
+               int len;
+               char * msg;
+               
+               len = sizeof(tmp) - 1;
+               if ((result=asn1_der_coding( key->key, "", tmp, &len, NULL)) != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       return _gnutls_asn2err(result);
+               }
+
+               if (key->pk_algorithm == GNUTLS_PK_RSA)
+                       msg = "RSA PRIVATE KEY";
+               else if (key->pk_algorithm == GNUTLS_PK_DSA)
+                       msg = "DSA PRIVATE KEY";
+               else msg = NULL;
+
+               result = _gnutls_fbase64_encode( msg,
+                                               tmp, len, &out);
+
+               if (result < 0) {
+                       gnutls_assert();
+                       return result;
+               }
+
+               if (result == 0) {      /* oooops */
+                       gnutls_assert();
+                       return GNUTLS_E_INTERNAL_ERROR;
+               }
+
+               if (result + 1 > *output_data_size) {
+                       gnutls_assert();
+                       gnutls_free(out);
+                       *output_data_size = result;
+                       return GNUTLS_E_SHORT_MEMORY_BUFFER;
+               }
+
+               *output_data_size = result;
+               
+               if (output_data) {
+                       memcpy( output_data, out, result);
+                       output_data[result] = 0;
+               }
+               gnutls_free( out);
+               
+       }
+
+       return 0;
+}
+
+static int _encode_rsa( ASN1_TYPE* c2, MPI* params)
+{
+       int result, i;
+       size_t size[8], total, tmp_size;
+       opaque * m_data, *pube_data, *prie_data;
+       opaque* p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
+       opaque * all_data = NULL;
+       GNUTLS_MPI exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL;
+       opaque null = '\0';
+
+       /* Read all the sizes */
+       total = 0;
+       for (i=0;i<6;i++) {
+               _gnutls_mpi_print( NULL, &size[i], params[i]);
+               total += size[i];
+       }
+
+       /* Now generate exp1 and exp2
+        */
+       exp1 = _gnutls_mpi_alloc_like( params[0]); /* like modulus */
+       if (exp1 == NULL) {
+               gnutls_assert();
+               result = GNUTLS_E_MEMORY_ERROR;
+               goto cleanup;
+       }
+
+       exp2 = _gnutls_mpi_alloc_like( params[0]);
+       if (exp2 == NULL) {
+               gnutls_assert();
+               result = GNUTLS_E_MEMORY_ERROR;
+               goto cleanup;
+       }
+
+       q1 = _gnutls_mpi_alloc_like( params[4]);
+       if (q1 == NULL) {
+               gnutls_assert();
+               result = GNUTLS_E_MEMORY_ERROR;
+               goto cleanup;
+       }
+
+       p1 = _gnutls_mpi_alloc_like( params[3]);
+       if (p1 == NULL) {
+               gnutls_assert();
+               result = GNUTLS_E_MEMORY_ERROR;
+               goto cleanup;
+       }
+       
+       _gnutls_mpi_add_ui( p1, params[3], -1);
+       _gnutls_mpi_add_ui( q1, params[4], -1);
+
+       _gnutls_mpi_mod( exp1, params[2], p1);
+       _gnutls_mpi_mod( exp2, params[2], q1);
+
+
+       /* calculate exp's size */
+       _gnutls_mpi_print( NULL, &size[6], exp1);
+       total += size[6];
+
+       _gnutls_mpi_print( NULL, &size[7], exp2);
+       total += size[7];
+
+       /* Encoding phase.
+        * allocate data enough to hold everything
+        */
+       all_data = gnutls_alloca( total);
+       if (all_data == NULL) {
+               gnutls_assert();
+               result = GNUTLS_E_MEMORY_ERROR;
+               goto cleanup;
+       }
+       
+       m_data = &all_data[0];
+       pube_data = &all_data[size[0]];
+       prie_data = &all_data[size[1]];
+       p1_data = &all_data[size[2]];
+       p2_data = &all_data[size[3]];
+       u_data = &all_data[size[4]];
+       exp1_data = &all_data[size[5]];
+       exp2_data = &all_data[size[6]];
+
+       _gnutls_mpi_print( m_data, &tmp_size, params[0]);
+       _gnutls_mpi_print( pube_data, &tmp_size, params[1]);
+       _gnutls_mpi_print( prie_data, &tmp_size, params[2]);
+       _gnutls_mpi_print( p1_data, &tmp_size, params[3]);
+       _gnutls_mpi_print( p2_data, &tmp_size, params[4]);
+       _gnutls_mpi_print( u_data, &tmp_size, params[5]);
+       _gnutls_mpi_print( exp1_data, &tmp_size, exp1);
+       _gnutls_mpi_print( exp2_data, &tmp_size, exp2);
+
+       /* Ok. Now we have the data. Create the asn1 structures
+        */     
+
+       if ((result = asn1_create_element
+            (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", c2))
+           != ASN1_SUCCESS) {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       /* Write PRIME 
+        */
+       if ((result = asn1_write_value(*c2, "modulus",
+                                           m_data, size[0])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "publicExponent",
+                                           pube_data, size[1])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "privateExponent",
+                                           prie_data, size[2])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "prime1",
+                                           p1_data, size[3])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "prime2",
+                                           p2_data, size[4])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "exponent1",
+                                           exp1_data, size[6])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "exponent2",
+                                           exp2_data, size[7])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "coefficient",
+                                           u_data, size[5])) != ASN1_SUCCESS) 
+       {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       gnutls_afree(all_data);
+
+       if ((result = asn1_write_value(*c2, "otherPrimeInfos",
+                                           NULL, 0)) != ASN1_SUCCESS) {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       if ((result = asn1_write_value(*c2, "version",
+                                           &null, 1)) != ASN1_SUCCESS) {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       return 0;
+       
+       cleanup:
+               _gnutls_mpi_release( &exp1);
+               _gnutls_mpi_release( &exp2);
+               _gnutls_mpi_release( &q1);
+               _gnutls_mpi_release( &p1);
+               asn1_delete_structure(c2);
+               gnutls_afree( all_data);
+               
+               return result;
+}
+
+
+/**
+  * gnutls_x509_privkey_generate - This function will generate a private key
+  * @key: should contain a gnutls_x509_privkey structure
+  * @algo: is one of RSA or DSA.
+  * @bits: the size of the modulus
+  *
+  * This function will generate a random private key. Note that
+  * this function must be called on an empty private key.
+  *
+  * Returns 0 on success or a negative value on error.
+  *
+  **/
+int gnutls_x509_privkey_generate( gnutls_x509_privkey key, gnutls_pk_algorithm algo,
+       int bits)
+{
+int ret;
+
+       switch( algo) {
+               case GNUTLS_PK_DSA:
+                       return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+               case GNUTLS_PK_RSA:
+                       ret = _gnutls_rsa_generate_params( key->params, bits);
+                       
+                       if (ret < 0) {
+                               gnutls_assert();
+                               return ret;
+                       }
+                       
+                       ret = _encode_rsa( &key->key, key->params);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto cleanup;
+                       }
+                       key->params_size = 6;
+                       key->pk_algorithm = GNUTLS_PK_RSA;
+                       
+                       break;
+               default:
+                       gnutls_assert();
+                       return GNUTLS_E_INVALID_REQUEST;
+       }
+       
+       return 0;
+
+       cleanup:
+               key->pk_algorithm = GNUTLS_PK_UNKNOWN;
+               key->params_size = 0;
+               _gnutls_mpi_release(&key->params[0]);
+               _gnutls_mpi_release(&key->params[1]);
+               _gnutls_mpi_release(&key->params[2]);
+               _gnutls_mpi_release(&key->params[3]);
+               _gnutls_mpi_release(&key->params[4]);
+               _gnutls_mpi_release(&key->params[5]);
+
+               return ret;
+}
index e0cfaedf0beda6b9e462d2f4bf2944e7a9020475..536025abdc85a40c892c66932cc7873f6b2adc04 100644 (file)
@@ -487,12 +487,12 @@ static
 int _gnutls_x509_verify_signature( const gnutls_datum* tbs,
        const gnutls_datum* signature, gnutls_x509_crt issuer) 
 {
-GNUTLS_MPI issuer_params[MAX_PARAMS_SIZE];
+GNUTLS_MPI issuer_params[MAX_PUBLIC_PARAMS_SIZE];
 int ret, issuer_params_size, i;
 
        /* Read the MPI parameters from the issuer's certificate.
         */
-       issuer_params_size = MAX_PARAMS_SIZE;
+       issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
        ret = _gnutls_x509_crt_get_mpis(issuer, issuer_params, &issuer_params_size);
 
        if ( ret < 0) {
index c3241331c11aef96be3b76e459a9804041d26bd7..4c71a4cc687319f3f7ddf05dd1560f7a3a025736 100644 (file)
@@ -460,7 +460,7 @@ int gnutls_x509_crt_get_pk_algorithm( gnutls_x509_crt cert, int* bits)
        opaque str[MAX_X509_CERT_SIZE];
        int algo;
        int len = sizeof(str);
-       GNUTLS_MPI params[MAX_PARAMS_SIZE];
+       GNUTLS_MPI params[MAX_PUBLIC_PARAMS_SIZE];
 
        len = sizeof(str) - 1;
        result =
index 1d4772d4e920f02ab8998be51af10ddc6cea17c3..2aa3601355192775e9fb3acf5480514ee9450e97 100644 (file)
@@ -19,9 +19,9 @@ typedef struct gnutls_x509_crt_int {
 
 /* Raw encoded parameter.
  */
-#define MAX_PARAMETER_SIZE 1200
+#define MAX_PARAMETER_SIZE 2400
 
-#define MAX_PARAMS_SIZE 6 /* ok for RSA and DSA */
+#define MAX_PRIV_PARAMS_SIZE 6 /* ok for RSA and DSA */
 
 /* parameters should not be larger than this limit */
 #define DSA_PRIVATE_PARAMS 5
@@ -29,16 +29,16 @@ typedef struct gnutls_x509_crt_int {
 #define RSA_PRIVATE_PARAMS 6
 #define RSA_PUBLIC_PARAMS 2
 
-#if MAX_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
-# error INCREASE MAX_PARAMS
+#if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
+# error INCREASE MAX_PRIV_PARAMS
 #endif
 
-#if MAX_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0
-# error INCREASE MAX_PARAMS
+#if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0
+# error INCREASE MAX_PRIV_PARAMS
 #endif
 
 typedef struct gnutls_x509_privkey_int {
-       MPI params[MAX_PARAMS_SIZE];/* the size of params depends on the public 
+       MPI params[MAX_PRIV_PARAMS_SIZE];/* the size of params depends on the public 
                                 * key algorithm 
                                 */
                                /*
index ecabeb443782c15b3a3361e0e48906bcfeb2b158..750e5cfd453ea11ff3b742ba02205bbfa91d8f9d 100644 (file)
@@ -81,7 +81,7 @@ ssize_t ret, data_size;
 gnutls_datum signature, ddata;
 const gnutls_certificate_credentials cred;
 gnutls_cert *apr_cert_list;
-gnutls_private_key *apr_pkey;
+gnutls_privkey *apr_pkey;
 int apr_cert_list_length;
 
        ret = _gnutls_gen_srp_server_kx( session, data);
index fb8f44714029a69349e95595bf0122b5e6e6a1b8..bd7341bd514152bd5d55138666f879f5bd648e31 100644 (file)
@@ -335,7 +335,7 @@ openpgp_pk_to_gnutls_cert( gnutls_cert *cert, cdkPKT_public_key *pk )
  * GnuTLS specific data which is need to perform secret key operations.
  -*/
 int
-_gnutls_openpgp_key2gnutls_key( gnutls_private_key *pkey,
+_gnutls_openpgp_key2gnutls_key( gnutls_privkey *pkey,
                                 gnutls_datum *raw_key )
 {
     CDK_KBNODE snode;
@@ -568,7 +568,7 @@ gnutls_certificate_set_openpgp_key_mem( gnutls_certificate_credentials res,
     i = 1;
     while( (p = cdk_kbnode_walk( knode, &ctx, 0 )) ) {
         pkt = cdk_kbnode_get_packet( p );
-        if( i > MAX_PARAMS_SIZE )
+        if( i > MAX_PUBLIC_PARAMS_SIZE )
             break;
         if( pkt->pkttype == CDK_PKT_PUBLIC_KEY ) {
             int n = res->ncerts;
@@ -586,7 +586,7 @@ gnutls_certificate_set_openpgp_key_mem( gnutls_certificate_credentials res,
   
     res->ncerts++;
     res->pkey = gnutls_realloc_fast(res->pkey,
-                               (res->ncerts)*sizeof(gnutls_private_key));
+                               (res->ncerts)*sizeof(gnutls_privkey));
     if( !res->pkey ) {
         gnutls_assert();
         return GNUTLS_E_MEMORY_ERROR;   
@@ -673,7 +673,7 @@ gnutls_certificate_set_openpgp_key_file( gnutls_certificate_credentials res,
         i = 1;
         rc = cdk_keydb_get_keyblock( inp, &knode );
         while( knode && (p = cdk_kbnode_walk( knode, &ctx, 0 )) ) {
-            if( i > MAX_PARAMS_SIZE )
+            if( i > MAX_PUBLIC_PARAMS_SIZE )
                 break;
             pkt = cdk_kbnode_get_packet( p );
             if( pkt->pkttype == CDK_PKT_PUBLIC_KEY ) {
@@ -710,7 +710,7 @@ gnutls_certificate_set_openpgp_key_file( gnutls_certificate_credentials res,
     stream_to_datum( inp, &raw );
     cdk_stream_close( inp );
 
-    n = (res->ncerts + 1) * sizeof (gnutls_private_key);
+    n = (res->ncerts + 1) * sizeof (gnutls_privkey);
     res->pkey = gnutls_realloc_fast( res->pkey, n );
     if( !res->pkey ) {
         gnutls_assert();
@@ -1942,7 +1942,7 @@ void gnutls_openpgp_set_recv_key_function( gnutls_session session,
 
 #else /*!HAVE_LIBOPENCDK*/
 int
-_gnutls_openpgp_key2gnutls_key( gnutls_private_key *pkey,
+_gnutls_openpgp_key2gnutls_key( gnutls_privkey *pkey,
                                 gnutls_datum raw_key )
 {
     return GNUTLS_E_UNIMPLEMENTED_FEATURE;