summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-03-11 20:14:29 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-03-11 20:14:29 +0000
commit20198610069ad076eecd831e8c370b3ad7d09c99 (patch)
tree5626f3fb06170cb1a33970180e92a2cb76cfd8dc
parentc6f315f0adbc65ec325476b599eabe6c870df2a9 (diff)
downloadgnutls-20198610069ad076eecd831e8c370b3ad7d09c99.tar.gz
some improvements in the private key handling api. It is now used internally.
-rw-r--r--lib/Makefile.am4
-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.c4
-rw-r--r--lib/auth_rsa_export.c2
-rw-r--r--lib/gnutls_cert.c3
-rw-r--r--lib/gnutls_cert.h38
-rw-r--r--lib/gnutls_int.h4
-rw-r--r--lib/gnutls_privkey.c255
-rw-r--r--lib/gnutls_privkey.h5
-rw-r--r--lib/gnutls_sig.c9
-rw-r--r--lib/gnutls_sig.h5
-rw-r--r--lib/gnutls_x509.c173
-rw-r--r--lib/gnutls_x509.h1
-rw-r--r--lib/x509/privkey.c254
-rw-r--r--lib/x509/x509.h42
17 files changed, 313 insertions, 506 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 1ba2cdf525..d354c22409 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -17,7 +17,7 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls.asn pkix.asn \
libgnutls-config.in libgnutls.m4 gnutls.h.in.in gnutls_errors_int.h \
gnutls-api.tex gnutls_datum.h auth_cert.h gnutls_mpi.h \
gnutls_pk.h gnutls_record.h gnutls_cert.h \
- gnutls_privkey.h gnutls_constate.h gnutls_global.h \
+ gnutls_constate.h gnutls_global.h \
gnutls_sig.h gnutls_mem.h gnutls_ui.h \
io_debug.h ext_max_record.h gnutls_session_pack.h \
gnutls_alert.h gnutls_str.h gnutls_state.h gnutls_x509.h \
@@ -34,7 +34,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c \
auth_anon.c gnutls_extensions.c gnutls_auth.c gnutls_random.c \
gnutls_v2_compat.c gnutls_datum.c auth_rsa.c gnutls_session_pack.c \
gnutls_mpi.c gnutls_pk.c gnutls_cert.c \
- gnutls_global.c gnutls_privkey.c gnutls_constate.c gnutls_anon_cred.c \
+ gnutls_global.c gnutls_constate.c gnutls_anon_cred.c \
pkix_asn1_tab.c gnutls_asn1_tab.c gnutls_mem.c \
auth_cert.c gnutls_ui.c gnutls_sig.c auth_dhe.c \
gnutls_dh_primes.c ext_max_record.c gnutls_alert.c gnutls_int_compat.c \
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 1c60942ffc..2cc7804340 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_private_key *apr_pkey;
+ gnutls_x509_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_private_key *apr_pkey;
+ gnutls_x509_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_private_key *apr_pkey;
+ gnutls_x509_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_private_key *apr_pkey;
+ gnutls_x509_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_private_key ** apr_pkey)
+ gnutls_x509_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 05165ebc4e..8bee758041 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_private_key * pkey;
+ gnutls_x509_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_private_key** apr_pkey);
+int _gnutls_find_apr_cert( gnutls_session session, gnutls_cert** apr_cert_list, int *apr_cert_list_length, gnutls_x509_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 887cf27fe9..56dad83e10 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_private_key *apr_pkey;
+ gnutls_x509_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 999154cfeb..af93ee722b 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -191,8 +191,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;
}
diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c
index 2d54662b55..ef1ba7e35e 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_private_key *apr_pkey;
+ gnutls_x509_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 11b044246c..a12162e179 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -31,7 +31,6 @@
#include <gnutls_datum.h>
#include <gnutls_mpi.h>
#include <gnutls_global.h>
-#include <gnutls_privkey.h>
#include <gnutls_algorithms.h>
#include <gnutls_dh.h>
#include <gnutls_str.h>
@@ -82,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_free_private_key(sc->pkey[i]);
+ gnutls_x509_privkey_deinit(sc->pkey[i]);
}
gnutls_free( sc->pkey);
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index b792c4b7ef..c2a6c9cd03 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -6,23 +6,12 @@
#include <gnutls_ui.h>
#include "x509/x509.h"
-#define MAX_PARAMS_SIZE 6 /* ok for RSA and DSA */
+#define MAX_PUBLIC_PARAMS_SIZE 4 /* ok for RSA and DSA */
/* parameters should not be larger than this limit */
-#define MAX_PARAMETER_SIZE 1200
-#define DSA_PRIVATE_PARAMS 5
#define DSA_PUBLIC_PARAMS 4
-#define RSA_PRIVATE_PARAMS 6
#define RSA_PUBLIC_PARAMS 2
-#if MAX_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
-# error INCREASE MAX_PARAMS
-#endif
-
-#if MAX_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0
-# error INCREASE MAX_PARAMS
-#endif
-
/* For key Usage, test as:
* if (st.keyUsage & KEY_DIGITAL_SIGNATURE) ...
*/
@@ -37,7 +26,7 @@
#define KEY_DECIPHER_ONLY 1
typedef struct gnutls_cert {
- MPI params[MAX_PARAMS_SIZE]; /* the size of params depends on the public
+ MPI params[MAX_PUBLIC_PARAMS_SIZE]; /* the size of params depends on the public
* key algorithm
* RSA: [0] is modulus
* [1] is public exponent
@@ -62,29 +51,6 @@ typedef struct gnutls_cert {
} gnutls_cert;
-typedef struct {
- MPI params[MAX_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_private_key;
-
struct gnutls_session_int; /* because gnutls_session is not defined when this file is included */
typedef enum ConvFlags {
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 1d568dcd9b..25d57303fc 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -34,9 +34,9 @@
#define HANDSHAKE_DEBUG // Prints some information on handshake
#define X509_DEBUG
#define RECORD_DEBUG
-#define COMPRESSION_DEBUG
+#define COMPRESSION_DEBUG*/
#define DEBUG
-*/
+
/* It might be a good idea to replace int with void*
* here.
diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c
deleted file mode 100644
index a99596529f..0000000000
--- a/lib/gnutls_privkey.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2001 Nikos Mavroyanopoulos
- *
- * This file is part of GNUTLS.
- *
- * The GNUTLS library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* This file contains functions needed to read DSA or RSA private keys
- * from files, or memory.
- */
-
-#include <gnutls_int.h>
-#include <gnutls_errors.h>
-#include <x509_b64.h>
-#include <auth_cert.h>
-#include <gnutls_cert.h>
-#include <libtasn1.h>
-#include <gnutls_datum.h>
-#include <gnutls_mpi.h>
-#include <gnutls_global.h>
-#include <gnutls_privkey.h>
-
-/* Converts an RSA PKCS#1 key to
- * an internal structure (gnutls_private_key)
- */
-int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key * pkey,
- gnutls_datum raw_key)
-{
- int result;
- opaque str[MAX_PARAMETER_SIZE];
- ASN1_TYPE pkey_asn;
-
- pkey->pk_algorithm = GNUTLS_PK_RSA;
-
- if ((result =
- asn1_create_element(_gnutls_get_gnutls_asn(),
- "GNUTLS.RSAPrivateKey", &pkey_asn
- )) != ASN1_SUCCESS) {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- if ((sizeof(pkey->params) / sizeof(GNUTLS_MPI)) < RSA_PRIVATE_PARAMS) {
- gnutls_assert();
- /* internal error. Increase the GNUTLS_MPIs in params */
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- result = asn1_der_decoding(&pkey_asn, raw_key.data, raw_key.size, NULL);
- if (result != ASN1_SUCCESS) {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- if ((result = _gnutls_x509_read_int(pkey_asn, "modulus",
- str, sizeof(str) - 1,
- &pkey->params[0])) < 0) {
- gnutls_assert();
- asn1_delete_structure(&pkey_asn);
- return result;
- }
-
- if ((result =
- _gnutls_x509_read_int(pkey_asn, "publicExponent", str,
- sizeof(str) - 1,
- &pkey->params[1])) < 0) {
- gnutls_assert();
- asn1_delete_structure(&pkey_asn);
- _gnutls_mpi_release(&pkey->params[0]);
- return result;
- }
-
- if ((result =
- _gnutls_x509_read_int(pkey_asn, "privateExponent", str,
- sizeof(str) - 1,
- &pkey->params[2])) < 0) {
- gnutls_assert();
- _gnutls_mpi_release(&pkey->params[0]);
- _gnutls_mpi_release(&pkey->params[1]);
- asn1_delete_structure(&pkey_asn);
- return result;
- }
-
- if ((result = _gnutls_x509_read_int(pkey_asn, "prime1",
- str, sizeof(str) - 1,
- &pkey->params[3])) < 0) {
- gnutls_assert();
- _gnutls_mpi_release(&pkey->params[0]);
- _gnutls_mpi_release(&pkey->params[1]);
- _gnutls_mpi_release(&pkey->params[2]);
- asn1_delete_structure(&pkey_asn);
- return result;
- }
-
- if ((result = _gnutls_x509_read_int(pkey_asn, "prime2",
- str, sizeof(str) - 1,
- &pkey->params[4])) < 0) {
- gnutls_assert();
- _gnutls_mpi_release(&pkey->params[0]);
- _gnutls_mpi_release(&pkey->params[1]);
- _gnutls_mpi_release(&pkey->params[2]);
- _gnutls_mpi_release(&pkey->params[3]);
- asn1_delete_structure(&pkey_asn);
- return result;
- }
-
-#if 1
- /* Calculate the coefficient. This is because the gcrypt
- * library is uses the p,q in the reverse order.
- */
- pkey->params[5] =
- _gnutls_mpi_snew(_gnutls_mpi_get_nbits(pkey->params[0]));
-
- if (pkey->params[5] == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- _gnutls_mpi_invm(pkey->params[5], pkey->params[3], pkey->params[4]);
- /* p, q */
-#else
- if ( (result=_gnutls_x509_read_int( pkey_asn, "coefficient",
- str, sizeof(str)-1, &pkey->params[5])) < 0) {
- gnutls_assert();
- _gnutls_mpi_release( &pkey->params[0]);
- _gnutls_mpi_release( &pkey->params[1]);
- _gnutls_mpi_release( &pkey->params[2]);
- _gnutls_mpi_release( &pkey->params[3]);
- _gnutls_mpi_release( &pkey->params[4]);
- asn1_delete_structure(&pkey_asn);
- return result;
- }
-#endif
-
- pkey->params_size = RSA_PRIVATE_PARAMS;
-
- asn1_delete_structure(&pkey_asn);
-
- return 0;
-
-
-}
-
-int _gnutls_DSAkey2gnutlsKey(gnutls_private_key * pkey,
- gnutls_datum raw_key)
-{
- int result;
- opaque str[MAX_PARAMETER_SIZE];
- ASN1_TYPE dsa_asn;
-
- pkey->pk_algorithm = GNUTLS_PK_DSA;
-
- if ((result =
- asn1_create_element(_gnutls_get_gnutls_asn(),
- "GNUTLS.DSAPrivateKey", &dsa_asn
- )) != ASN1_SUCCESS) {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- if ((sizeof(pkey->params) / sizeof(GNUTLS_MPI)) < DSA_PRIVATE_PARAMS) {
- gnutls_assert();
- /* internal error. Increase the GNUTLS_MPIs in params */
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- result = asn1_der_decoding(&dsa_asn, raw_key.data, raw_key.size, NULL);
- if (result != ASN1_SUCCESS) {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- if ((result = _gnutls_x509_read_int(dsa_asn, "p",
- str, sizeof(str) - 1,
- &pkey->params[0])) < 0) {
- gnutls_assert();
- asn1_delete_structure(&dsa_asn);
- return result;
- }
-
- if ((result = _gnutls_x509_read_int(dsa_asn, "q",
- str, sizeof(str) - 1,
- &pkey->params[1])) < 0) {
- gnutls_assert();
- asn1_delete_structure(&dsa_asn);
- _gnutls_mpi_release(&pkey->params[0]);
- return result;
- }
-
- if ((result = _gnutls_x509_read_int(dsa_asn, "g",
- str, sizeof(str) - 1,
- &pkey->params[2])) < 0) {
- gnutls_assert();
- asn1_delete_structure(&dsa_asn);
- _gnutls_mpi_release(&pkey->params[0]);
- _gnutls_mpi_release(&pkey->params[1]);
- return result;
- }
-
- if ((result = _gnutls_x509_read_int(dsa_asn, "Y",
- str, sizeof(str) - 1,
- &pkey->params[3])) < 0) {
- gnutls_assert();
- asn1_delete_structure(&dsa_asn);
- _gnutls_mpi_release(&pkey->params[0]);
- _gnutls_mpi_release(&pkey->params[1]);
- _gnutls_mpi_release(&pkey->params[2]);
- return result;
- }
-
- if ((result = _gnutls_x509_read_int(dsa_asn, "priv",
- str, sizeof(str) - 1,
- &pkey->params[4])) < 0) {
- gnutls_assert();
- asn1_delete_structure(&dsa_asn);
- _gnutls_mpi_release(&pkey->params[0]);
- _gnutls_mpi_release(&pkey->params[1]);
- _gnutls_mpi_release(&pkey->params[2]);
- _gnutls_mpi_release(&pkey->params[3]);
- return result;
- }
- pkey->params_size = DSA_PRIVATE_PARAMS;
-
- asn1_delete_structure(&dsa_asn);
-
- return 0;
-
-
-}
-
-void _gnutls_free_private_key(gnutls_private_key pkey)
-{
- int i;
-
- for (i = 0; i < pkey.params_size; i++) {
- _gnutls_mpi_release(&pkey.params[i]);
- }
-
- return;
-}
-
diff --git a/lib/gnutls_privkey.h b/lib/gnutls_privkey.h
deleted file mode 100644
index 78b18a0724..0000000000
--- a/lib/gnutls_privkey.h
+++ /dev/null
@@ -1,5 +0,0 @@
-int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key);
-int _gnutls_DSAkey2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key);
-void _gnutls_free_private_key( gnutls_private_key pkey);
-int _gnutls_der_check_if_rsa_key(const gnutls_datum * key_struct);
-int _gnutls_der_check_if_dsa_key(const gnutls_datum * key_struct);
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index dd460fb2ef..49283f00f0 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -27,7 +27,6 @@
#include <libtasn1.h>
#include <gnutls_datum.h>
#include <gnutls_mpi.h>
-#include <gnutls_privkey.h>
#include <gnutls_global.h>
#include <gnutls_pk.h>
#include <debug.h>
@@ -35,13 +34,13 @@
#include <gnutls_sig.h>
-int _gnutls_generate_sig( gnutls_cert* cert, gnutls_private_key *pkey, const gnutls_datum* hash_concat, gnutls_datum *signature);
+int _gnutls_generate_sig( gnutls_cert* cert, gnutls_x509_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_private_key *pkey, gnutls_datum *signature) {
+int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_x509_privkey pkey, gnutls_datum *signature) {
gnutls_datum dconcat;
int ret;
opaque concat[36];
@@ -89,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_private_key *pkey, gnutls_datum* params, gnutls_datum *signature)
+int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_x509_privkey pkey, gnutls_datum* params, gnutls_datum *signature)
{
gnutls_datum dconcat;
int ret;
@@ -149,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_private_key *pkey, const gnutls_datum* hash_concat, gnutls_datum *signature)
+int _gnutls_generate_sig( gnutls_cert* cert, gnutls_x509_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 7026c4a778..8b6a1603f3 100644
--- a/lib/gnutls_sig.h
+++ b/lib/gnutls_sig.h
@@ -3,9 +3,8 @@
# include <auth_cert.h>
gnutls_certificate_status gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer);
-int _gnutls_pkcs1_rsa_generate_sig( gnutls_cert* cert, gnutls_private_key *pkey, const gnutls_datum* hash_concat, gnutls_datum *signature);
-int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum *signature);
-int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature);
+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_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 5e970a7acc..5b028375b7 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -39,7 +39,6 @@
#include <gnutls_str.h>
#include <debug.h>
#include <x509_b64.h>
-#include <gnutls_privkey.h>
#include <gnutls_x509.h>
#include "x509/common.h"
#include "x509/x509.h"
@@ -155,7 +154,8 @@ static int _gnutls_check_key_cert_match( gnutls_certificate_credentials res)
{
int pk = res->cert_list[res->ncerts-1][0].subject_pk_algorithm;
- if (res->pkey[res->ncerts-1].pk_algorithm != (unsigned int)pk) {
+ if (gnutls_x509_privkey_get_pk_algorithm(res->pkey[res->ncerts-1]) != pk)
+ {
gnutls_assert();
return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
}
@@ -431,77 +431,6 @@ int read_cert_mem(gnutls_certificate_credentials res, const char *cert, int cert
-/* This will check if the given DER key is a PKCS-1 RSA key.
- * Returns 0 if the key is an RSA one.
- */
-int _gnutls_der_check_if_rsa_key(const gnutls_datum * key_struct)
-{
- ASN1_TYPE c2;
- int result;
-
- if (key_struct->size == 0 || key_struct->data == NULL) {
- gnutls_assert();
- return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
- }
-
- if ((result=asn1_create_element
- (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", &c2
- )) != ASN1_SUCCESS)
- {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- result = asn1_der_decoding(&c2, key_struct->data, key_struct->size, NULL);
- asn1_delete_structure(&c2);
-
- if (result != ASN1_SUCCESS) {
- /* couldn't decode DER */
-
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- return 0;
-}
-
-/* This will check if the given DER key is an openssl formated DSA key.
- * Returns 0 if the key is a DSA one.
- */
-int _gnutls_der_check_if_dsa_key(const gnutls_datum * key_struct)
-{
- ASN1_TYPE c2;
- int result;
-
- if (key_struct->size == 0 || key_struct->data == NULL) {
- gnutls_assert();
- return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
- }
-
- if ((result=asn1_create_element
- (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", &c2
- )) != ASN1_SUCCESS)
- {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- result = asn1_der_decoding(&c2, key_struct->data, key_struct->size, NULL);
- asn1_delete_structure(&c2);
-
- if (result != ASN1_SUCCESS) {
- /* couldn't decode DER */
-
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- return 0;
-}
-
-
-
-
/* Reads a PEM encoded PKCS-1 RSA private key from memory
* 2002-01-26: Added ability to read DSA keys.
* type indicates the certificate format.
@@ -510,102 +439,34 @@ static int read_key_mem(gnutls_certificate_credentials res, const char *key, int
gnutls_x509_crt_fmt type)
{
int ret;
- opaque *b64 = NULL;
gnutls_datum tmp;
- gnutls_pk_algorithm pk;
/* allocate space for the pkey list
*/
- res->pkey = gnutls_realloc_fast( res->pkey, (res->ncerts+1)*sizeof(gnutls_private_key));
+ res->pkey = gnutls_realloc_fast( res->pkey, (res->ncerts+1)*sizeof(gnutls_x509_privkey));
if (res->pkey==NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- /* read PKCS-1 private key */
-
- if (type==GNUTLS_X509_FMT_DER) { /* DER */
- int cv;
-
- tmp.data = (opaque*)key;
- tmp.size = key_size;
-
- /* The only way to distinguish the keys
- * is to count the sequence of integers.
- */
- pk = GNUTLS_PK_UNKNOWN;
- cv = _gnutls_der_check_if_rsa_key( &tmp);
- if (cv==0)
- pk = GNUTLS_PK_RSA;
- else {
- cv = _gnutls_der_check_if_dsa_key( &tmp);
- if (cv == 0) pk = GNUTLS_PK_DSA;
- }
-
- } else { /* PEM */
-
- /* If we find the "DSA PRIVATE" string in the
- * pem encoded certificate then it's a DSA key.
- */
- if (strstr( key, "DSA PRIVATE")!=NULL) {
- pk = GNUTLS_PK_DSA;
- key = strstr( key, PEM_KEY_DSA_SEP);
- if (key == NULL) {
- gnutls_assert();
- return GNUTLS_E_BASE64_DECODING_ERROR;
- } key_size = strlen( key);
- } else {
- pk = GNUTLS_PK_RSA;
- key = strstr( key, PEM_KEY_RSA_SEP);
- if (key == NULL) {
- gnutls_assert();
- return GNUTLS_E_BASE64_DECODING_ERROR;
- }
- key_size = strlen( key);
- }
-
+ ret = gnutls_x509_privkey_init( &res->pkey[res->ncerts]);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
- ret = _gnutls_fbase64_decode( NULL, key, key_size, &b64);
+ tmp.data = (opaque*)key;
+ tmp.size = key_size;
- if (ret < 0) {
- gnutls_assert();
- return GNUTLS_E_BASE64_DECODING_ERROR;
- }
-
- tmp.data = b64;
- tmp.size = ret;
- }
+ ret = gnutls_x509_privkey_import( res->pkey[res->ncerts], &tmp, type);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_x509_privkey_deinit( res->pkey[res->ncerts]);
+ res->pkey[res->ncerts] = NULL;
- switch (pk) { /* decode the key */
- case GNUTLS_PK_RSA:
- if ((ret =
- _gnutls_PKCS1key2gnutlsKey(&res->pkey[res->ncerts],
- tmp)) < 0) {
- gnutls_assert();
- gnutls_free(b64);
- return ret;
- }
- break;
- case GNUTLS_PK_DSA:
- if ((ret =
- _gnutls_DSAkey2gnutlsKey(&res->pkey[res->ncerts],
- tmp)) < 0) {
- gnutls_assert();
- gnutls_free(b64);
- return ret;
- }
- break;
- default:
- gnutls_assert();
- gnutls_free(b64);
- return GNUTLS_E_INTERNAL_ERROR;
+ return ret;
}
- /* this doesn't hurt in the DER case, since
- * b64 is NULL
- */
- gnutls_free(b64);
-
return 0;
}
@@ -747,7 +608,7 @@ void gnutls_certificate_free_keys(gnutls_certificate_credentials sc)
sc->cert_list = NULL;
for (i = 0; i < sc->ncerts; i++) {
- _gnutls_free_private_key(sc->pkey[i]);
+ gnutls_x509_privkey_deinit(sc->pkey[i]);
}
gnutls_free( sc->pkey);
diff --git a/lib/gnutls_x509.h b/lib/gnutls_x509.h
index d5ac72c05a..b48c2e1038 100644
--- a/lib/gnutls_x509.h
+++ b/lib/gnutls_x509.h
@@ -15,3 +15,4 @@ int _gnutls_check_key_usage( const gnutls_cert* cert, gnutls_kx_algorithm alg);
int _gnutls_x509_read_rsa_params(opaque * der, int dersize, GNUTLS_MPI * params);
int _gnutls_x509_read_dsa_pubkey(opaque * der, int dersize, GNUTLS_MPI * params);
+
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index 2e5f0a6ad9..b55de979de 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -45,8 +45,10 @@ int gnutls_x509_privkey_init(gnutls_x509_privkey * key)
*key = gnutls_calloc( 1, sizeof(gnutls_x509_privkey_int));
if (*key) {
+ (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN;
return 0; /* success */
}
+
return GNUTLS_E_MEMORY_ERROR;
}
@@ -59,11 +61,196 @@ int gnutls_x509_privkey_init(gnutls_x509_privkey * key)
**/
void gnutls_x509_privkey_deinit(gnutls_x509_privkey key)
{
- _gnutls_free_datum(&key->raw);
+int i;
+
+ for (i = 0; i < key->params_size; i++) {
+ _gnutls_mpi_release( &key->params[i]);
+ }
gnutls_free(key);
}
+/* Converts an RSA PKCS#1 key to
+ * an internal structure (gnutls_private_key)
+ */
+static ASN1_TYPE decode_pkcs1_rsa_key( const gnutls_datum *raw_key,
+ gnutls_x509_privkey pkey)
+{
+ int result;
+ opaque str[MAX_PARAMETER_SIZE];
+ ASN1_TYPE pkey_asn;
+
+ if ((result =
+ asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.RSAPrivateKey", &pkey_asn
+ )) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return NULL;
+ }
+
+ if ((sizeof(pkey->params) / sizeof(GNUTLS_MPI)) < RSA_PRIVATE_PARAMS) {
+ gnutls_assert();
+ /* internal error. Increase the GNUTLS_MPIs in params */
+ return NULL;
+ }
+
+ result = asn1_der_decoding(&pkey_asn, raw_key->data, raw_key->size, NULL);
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(pkey_asn, "modulus",
+ str, sizeof(str) - 1,
+ &pkey->params[0])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result =
+ _gnutls_x509_read_int(pkey_asn, "publicExponent", str,
+ sizeof(str) - 1,
+ &pkey->params[1])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result =
+ _gnutls_x509_read_int(pkey_asn, "privateExponent", str,
+ sizeof(str) - 1,
+ &pkey->params[2])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(pkey_asn, "prime1",
+ str, sizeof(str) - 1,
+ &pkey->params[3])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(pkey_asn, "prime2",
+ str, sizeof(str) - 1,
+ &pkey->params[4])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+#if 1
+ /* Calculate the coefficient. This is because the gcrypt
+ * library is uses the p,q in the reverse order.
+ */
+ pkey->params[5] =
+ _gnutls_mpi_snew(_gnutls_mpi_get_nbits(pkey->params[0]));
+
+ if (pkey->params[5] == NULL) {
+ gnutls_assert();
+ goto error;
+ }
+
+ _gnutls_mpi_invm(pkey->params[5], pkey->params[3], pkey->params[4]);
+ /* p, q */
+#else
+ if ( (result=_gnutls_x509_read_int( pkey_asn, "coefficient",
+ str, sizeof(str)-1, &pkey->params[5])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+#endif
+ pkey->params_size = 6;
+
+ return pkey_asn;
+
+ error:
+ asn1_delete_structure(&pkey_asn);
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
+ _gnutls_mpi_release(&pkey->params[2]);
+ _gnutls_mpi_release(&pkey->params[3]);
+ _gnutls_mpi_release(&pkey->params[4]);
+ _gnutls_mpi_release(&pkey->params[5]);
+ return NULL;
+
+}
+
+static ASN1_TYPE decode_dsa_key( const gnutls_datum* raw_key,
+ gnutls_x509_privkey pkey)
+{
+ int result;
+ opaque str[MAX_PARAMETER_SIZE];
+ ASN1_TYPE dsa_asn;
+
+ if ((result =
+ asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.DSAPrivateKey", &dsa_asn
+ )) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return NULL;
+ }
+
+ if ((sizeof(pkey->params) / sizeof(GNUTLS_MPI)) < DSA_PRIVATE_PARAMS) {
+ gnutls_assert();
+ /* internal error. Increase the GNUTLS_MPIs in params */
+ return NULL;
+ }
+
+ result = asn1_der_decoding(&dsa_asn, raw_key->data, raw_key->size, NULL);
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(dsa_asn, "p",
+ str, sizeof(str) - 1,
+ &pkey->params[0])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(dsa_asn, "q",
+ str, sizeof(str) - 1,
+ &pkey->params[1])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(dsa_asn, "g",
+ str, sizeof(str) - 1,
+ &pkey->params[2])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(dsa_asn, "Y",
+ str, sizeof(str) - 1,
+ &pkey->params[3])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ if ((result = _gnutls_x509_read_int(dsa_asn, "priv",
+ str, sizeof(str) - 1,
+ &pkey->params[4])) < 0) {
+ gnutls_assert();
+ goto error;
+ }
+ pkey->params_size = 5;
+
+ return dsa_asn;
+
+ error:
+ asn1_delete_structure(&dsa_asn);
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
+ _gnutls_mpi_release(&pkey->params[2]);
+ _gnutls_mpi_release(&pkey->params[3]);
+ _gnutls_mpi_release(&pkey->params[4]);
+ return NULL;
+
+}
+
+
#define PEM_KEY_DSA "DSA PRIVATE"
#define PEM_KEY_RSA "RSA PRIVATE"
@@ -88,6 +275,8 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
int result = 0, need_free = 0;
gnutls_datum _data = { data->data, data->size };
+ key->pk_algorithm = GNUTLS_PK_UNKNOWN;
+
/* If the Certificate is in PEM format then decode it
*/
if (format == GNUTLS_X509_FMT_PEM) {
@@ -96,11 +285,13 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
/* Try the first header */
result = _gnutls_fbase64_decode(PEM_KEY_RSA, data->data, data->size,
&out);
+ key->pk_algorithm = GNUTLS_PK_RSA;
if (result <= 0) {
/* try for the second header */
result = _gnutls_fbase64_decode(PEM_KEY_DSA, data->data, data->size,
&out);
+ key->pk_algorithm = GNUTLS_PK_DSA;
if (result <= 0) {
if (result==0) result = GNUTLS_E_INTERNAL_ERROR;
@@ -115,19 +306,47 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
need_free = 1;
}
- result =
- _gnutls_set_datum(&key->raw, _data.data, _data.size);
- if (result < 0) {
- gnutls_assert();
- goto cleanup;
+ if (key->pk_algorithm == GNUTLS_PK_RSA) {
+ key->key = decode_pkcs1_rsa_key( &_data, key);
+ if (key->key == NULL) {
+ gnutls_assert();
+ result = GNUTLS_E_ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ } else if (key->pk_algorithm == GNUTLS_PK_DSA) {
+ key->key = decode_dsa_key( &_data, key);
+ if (key->key == NULL) {
+ gnutls_assert();
+ result = GNUTLS_E_ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ } else {
+ /* Try decoding with both, and accept the one that
+ * succeeds.
+ */
+ key->pk_algorithm = GNUTLS_PK_DSA;
+ key->key = decode_dsa_key( &_data, key);
+
+ if (key->key == NULL) {
+ key->pk_algorithm = GNUTLS_PK_RSA;
+ key->key = decode_pkcs1_rsa_key( &_data, key);
+ if (key->key == NULL) {
+ gnutls_assert();
+ result = GNUTLS_E_ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
}
-
+
if (need_free) _gnutls_free_datum( &_data);
+ /* The key has now been decoded.
+ */
+
return 0;
cleanup:
- _gnutls_free_datum(&key->raw);
+ key->pk_algorithm = GNUTLS_PK_UNKNOWN;
if (need_free) _gnutls_free_datum( &_data);
return result;
}
@@ -147,22 +366,5 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
**/
int gnutls_x509_privkey_get_pk_algorithm( gnutls_x509_privkey key)
{
-int cv, pk;
-
- pk = GNUTLS_PK_UNKNOWN;
-
- /* The only way to distinguish the keys
- * is to count the sequence of integers.
- */
- cv = _gnutls_der_check_if_rsa_key( &key->raw);
- if (cv==0)
- pk = GNUTLS_PK_RSA;
- else {
- cv = _gnutls_der_check_if_dsa_key( &key->raw);
- if (cv==0)
- pk = GNUTLS_PK_DSA;
- }
-
- return pk;
-
+ return key->pk_algorithm;
}
diff --git a/lib/x509/x509.h b/lib/x509/x509.h
index f096dcc06f..1d4772d4e9 100644
--- a/lib/x509/x509.h
+++ b/lib/x509/x509.h
@@ -17,8 +17,48 @@ typedef struct gnutls_x509_crt_int {
gnutls_pk_algorithm signature_algorithm;
} gnutls_x509_crt_int;
+/* Raw encoded parameter.
+ */
+#define MAX_PARAMETER_SIZE 1200
+
+#define MAX_PARAMS_SIZE 6 /* ok for RSA and DSA */
+
+/* parameters should not be larger than this limit */
+#define DSA_PRIVATE_PARAMS 5
+#define DSA_PUBLIC_PARAMS 4
+#define RSA_PRIVATE_PARAMS 6
+#define RSA_PUBLIC_PARAMS 2
+
+#if MAX_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
+# error INCREASE MAX_PARAMS
+#endif
+
+#if MAX_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0
+# error INCREASE MAX_PARAMS
+#endif
+
typedef struct gnutls_x509_privkey_int {
- gnutls_datum raw; /* we only keep raw data for the moment */
+ MPI params[MAX_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;
+
+ ASN1_TYPE key;
} gnutls_x509_privkey_int;
typedef struct gnutls_x509_crt_int *gnutls_x509_crt;