summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-03-12 10:57:56 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-03-12 10:57:56 +0000
commitf2b8289f8cc87c07b54714859fee9c6e053717bf (patch)
tree69a0cdb436b0f4303dd7b93be27073f677d7bd6e
parentedb61853219e078ae2d478d998a8ed06315c68f5 (diff)
downloadgnutls-f2b8289f8cc87c07b54714859fee9c6e053717bf.tar.gz
* 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>. * Rolled back some of yesterdays changes. The gnutls_x509_privkey, was replaced (again) by the gnutls_privkey.
-rw-r--r--NEWS3
-rw-r--r--includes/gnutls/x509.h6
-rw-r--r--lib/auth_cert.c14
-rw-r--r--lib/auth_cert.h4
-rw-r--r--lib/auth_dhe.c2
-rw-r--r--lib/auth_rsa.c11
-rw-r--r--lib/auth_rsa_export.c2
-rw-r--r--lib/gnutls_cert.c4
-rw-r--r--lib/gnutls_cert.h24
-rw-r--r--lib/gnutls_mpi.h1
-rw-r--r--lib/gnutls_sig.c8
-rw-r--r--lib/gnutls_sig.h4
-rw-r--r--lib/gnutls_x509.c57
-rw-r--r--lib/x509/privkey.c349
-rw-r--r--lib/x509/verify.c4
-rw-r--r--lib/x509/x509.c2
-rw-r--r--lib/x509/x509.h14
-rw-r--r--libextra/auth_srp_rsa.c2
-rw-r--r--libextra/gnutls_openpgp.c12
19 files changed, 471 insertions, 52 deletions
diff --git a/NEWS b/NEWS
index 36bfb76ddd..e2d074ad9e 100644
--- 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.
diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h
index ecc2cc6254..66b920e2cf 100644
--- a/includes/gnutls/x509.h
+++ b/includes/gnutls/x509.h
@@ -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
}
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 2cc7804340..c20be5aff9 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -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];
}
}
diff --git a/lib/auth_cert.h b/lib/auth_cert.h
index 8bee758041..a667aa394e 100644
--- a/lib/auth_cert.h
+++ b/lib/auth_cert.h
@@ -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
diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c
index 56dad83e10..4e7323297a 100644
--- a/lib/auth_dhe.c
+++ b/lib/auth_dhe.c
@@ -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;
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index af93ee722b..1c1ec48a08 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -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;
diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c
index ef1ba7e35e..3c49e72170 100644
--- a/lib/auth_rsa_export.c
+++ b/lib/auth_rsa_export.c
@@ -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;
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index a12162e179..8cf6167e79 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -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();
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index c2a6c9cd03..44ac3ce0af 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -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
diff --git a/lib/gnutls_mpi.h b/lib/gnutls_mpi.h
index c92a9d8ada..7ec3982d84 100644
--- a/lib/gnutls_mpi.h
+++ b/lib/gnutls_mpi.h
@@ -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))
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 49283f00f0..a70d1fd2ad 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -34,13 +34,13 @@
#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;
diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h
index 8b6a1603f3..e839c38d88 100644
--- a/lib/gnutls_sig.h
+++ b/lib/gnutls_sig.h
@@ -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);
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 5b028375b7..5865143fd3 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -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);
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index b55de979de..1ce006cc80 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -23,13 +23,13 @@
#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;
+}
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index e0cfaedf0b..536025abdc 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -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) {
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index c3241331c1..4c71a4cc68 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -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 =
diff --git a/lib/x509/x509.h b/lib/x509/x509.h
index 1d4772d4e9..2aa3601355 100644
--- a/lib/x509/x509.h
+++ b/lib/x509/x509.h
@@ -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
*/
/*
diff --git a/libextra/auth_srp_rsa.c b/libextra/auth_srp_rsa.c
index ecabeb4437..750e5cfd45 100644
--- a/libextra/auth_srp_rsa.c
+++ b/libextra/auth_srp_rsa.c
@@ -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);
diff --git a/libextra/gnutls_openpgp.c b/libextra/gnutls_openpgp.c
index fb8f447140..bd7341bd51 100644
--- a/libextra/gnutls_openpgp.c
+++ b/libextra/gnutls_openpgp.c
@@ -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;