- 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.
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
}
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 */
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 */
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 */
{
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;
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;
*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 */
*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];
}
}
* 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].
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
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;
/* 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;
/* 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;
}
{
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;
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;
_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);
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();
} 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 {
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
#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))
#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];
/* 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;
* 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;
# 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);
*/
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;
}
+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.
{
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;
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;
}
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);
#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
*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 */
}
* 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)
_gnutls_mpi_release( &key->params[i]);
}
+ asn1_delete_structure(&key->key);
gnutls_free(key);
}
/**
* 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.
{
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;
+}
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) {
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 =
/* 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
#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
*/
/*
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);
* 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;
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;
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;
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 ) {
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();
#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;