diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-03-11 20:14:29 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-03-11 20:14:29 +0000 |
commit | 20198610069ad076eecd831e8c370b3ad7d09c99 (patch) | |
tree | 5626f3fb06170cb1a33970180e92a2cb76cfd8dc | |
parent | c6f315f0adbc65ec325476b599eabe6c870df2a9 (diff) | |
download | gnutls-20198610069ad076eecd831e8c370b3ad7d09c99.tar.gz |
some improvements in the private key handling api. It is now used internally.
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/auth_cert.c | 14 | ||||
-rw-r--r-- | lib/auth_cert.h | 4 | ||||
-rw-r--r-- | lib/auth_dhe.c | 2 | ||||
-rw-r--r-- | lib/auth_rsa.c | 4 | ||||
-rw-r--r-- | lib/auth_rsa_export.c | 2 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 3 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 38 | ||||
-rw-r--r-- | lib/gnutls_int.h | 4 | ||||
-rw-r--r-- | lib/gnutls_privkey.c | 255 | ||||
-rw-r--r-- | lib/gnutls_privkey.h | 5 | ||||
-rw-r--r-- | lib/gnutls_sig.c | 9 | ||||
-rw-r--r-- | lib/gnutls_sig.h | 5 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 173 | ||||
-rw-r--r-- | lib/gnutls_x509.h | 1 | ||||
-rw-r--r-- | lib/x509/privkey.c | 254 | ||||
-rw-r--r-- | lib/x509/x509.h | 42 |
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; |