diff options
-rw-r--r-- | doc/tex/asn1.tex | 2 | ||||
-rw-r--r-- | lib/auth_dhe_rsa.c | 2 | ||||
-rw-r--r-- | lib/auth_rsa.c | 14 | ||||
-rw-r--r-- | lib/auth_x509.c | 14 | ||||
-rw-r--r-- | lib/gnutls.asn | 5 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 23 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 11 | ||||
-rw-r--r-- | lib/gnutls_gcry.c | 24 | ||||
-rw-r--r-- | lib/gnutls_gcry.h | 3 | ||||
-rw-r--r-- | lib/gnutls_pk.c | 256 | ||||
-rw-r--r-- | lib/gnutls_pk.h | 14 | ||||
-rw-r--r-- | lib/gnutls_privkey.c | 169 | ||||
-rw-r--r-- | lib/gnutls_sig.c | 90 | ||||
-rw-r--r-- | lib/x509_sig_check.c | 151 | ||||
-rw-r--r-- | src/cli.c | 12 |
15 files changed, 397 insertions, 393 deletions
diff --git a/doc/tex/asn1.tex b/doc/tex/asn1.tex index d0014dbce0..71c6301eb8 100644 --- a/doc/tex/asn1.tex +++ b/doc/tex/asn1.tex @@ -3,7 +3,7 @@ \section{Introduction} This file describes the forth version of ASN.1 parser I -developed\footnote{ASN.1 Structure handling in \gnutls is developed by Fabio +developed\footnote{ASN.1 Structure handling in \gnutls{} is developed by Fabio Fiorina}. The main difference from the first version is the use of pointers and the possibility to save/get ASN1 definitions in/from a C vector. diff --git a/lib/auth_dhe_rsa.c b/lib/auth_dhe_rsa.c index 697fe408a6..67363a49b9 100644 --- a/lib/auth_dhe_rsa.c +++ b/lib/auth_dhe_rsa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000,2001 Nikos Mavroyanopoulos + * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos * * This file is part of GNUTLS. * diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index 31a8c3ebd1..8ac3e5064c 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -79,6 +79,7 @@ int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size) gnutls_sdatum plaintext; gnutls_datum ciphertext; int ret, dsize; + MPI params[2]; if ( gnutls_protocol_get_version(state) == GNUTLS_SSL3) { /* SSL 3.0 */ @@ -95,9 +96,10 @@ int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size) ciphertext.size = dsize; } + params[0] = state->gnutls_key->A; + params[1] = state->gnutls_key->u; ret = - _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, state->gnutls_key->u, - state->gnutls_key->A, 2); /* btype==2 */ + _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, params, 2); /* btype==2 */ if (ret < 0) { /* in case decryption fails then don't inform @@ -146,7 +148,7 @@ int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data) { X509PKI_AUTH_INFO auth = state->gnutls_key->auth_info; gnutls_datum sdata; /* data to send */ - MPI pkey, n; + MPI params[RSA_PARAMS]; int ret; GNUTLS_Version ver; @@ -164,11 +166,11 @@ int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data) state->gnutls_key->key.data[0] = _gnutls_version_get_major(ver); state->gnutls_key->key.data[1] = _gnutls_version_get_minor(ver); + params[0] = state->gnutls_key->a; + params[1] = state->gnutls_key->x; if ((ret = - _gnutls_pkcs1_rsa_encrypt(&sdata, state->gnutls_key->key, state->gnutls_key->x, state->gnutls_key->a, 2)) < 0) { + _gnutls_pkcs1_rsa_encrypt(&sdata, state->gnutls_key->key, params, 2)) < 0) { gnutls_assert(); - _gnutls_mpi_release(&pkey); - _gnutls_mpi_release(&n); return ret; } _gnutls_mpi_release(&state->gnutls_key->a); diff --git a/lib/auth_x509.c b/lib/auth_x509.c index fafed43535..8b5dc4931f 100644 --- a/lib/auth_x509.c +++ b/lib/auth_x509.c @@ -89,17 +89,19 @@ int _gnutls_copy_x509_auth_info(X509PKI_AUTH_INFO info, gnutls_cert * cert, } /* This function reads the RSA parameters from the given private key - * cert is not a certificate but a der structure containing the private - * key(s). - * Ok this is no longer the case. We now precompile the pkcs1 key - * to the gnutls_private_key structure. */ static int _gnutls_get_private_rsa_params(GNUTLS_KEY key, gnutls_private_key * pkey) { - key->u = gcry_mpi_copy(pkey->params[0]); - key->A = gcry_mpi_copy(pkey->params[1]); + key->u = gcry_mpi_copy(pkey->params[2]); + if (key->u==NULL) return GNUTLS_E_MEMORY_ERROR; + + key->A = gcry_mpi_copy(pkey->params[0]); + if (key->A==NULL) { + _gnutls_mpi_release( &key->u); + return GNUTLS_E_MEMORY_ERROR; + } return 0; } diff --git a/lib/gnutls.asn b/lib/gnutls.asn index da195bfec6..010b8117a3 100644 --- a/lib/gnutls.asn +++ b/lib/gnutls.asn @@ -68,6 +68,11 @@ DSAParameters ::= SEQUENCE { g INTEGER } +DSASignatureValue ::= SEQUENCE { + r INTEGER, + s INTEGER +} + DSAPrivateKey ::= SEQUENCE { version INTEGER, -- should be zero p INTEGER, diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index f4e4fef452..9f27f46448 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -71,29 +71,6 @@ PKAlgorithm _gnutls_map_pk_get_pk(KXAlgorithm kx_algorithm) return ret; } -/* this function reads an integer - * from asn1 structs. Combines the read and mpi_scan - * steps. - */ -static -int _gnutls_x509_read_int( node_asn* node, char* value, char* tmpstr, int tmpstr_size, MPI* ret_mpi) { -int len, result; - - len = tmpstr_size - 1; - result = asn1_read_value(node, value, tmpstr, &len); - if (result != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if (_gnutls_mpi_scan( ret_mpi, tmpstr, &len) != 0) { - gnutls_assert(); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - return 0; -} - void gnutls_free_cert(gnutls_cert cert) { int n, i; diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index a94854caf0..f9c49c711d 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -10,7 +10,7 @@ /* parameters should not be larger than this limit */ #define MAX_PARAMETER_SIZE 1200 #define DSA_PARAMS 5 -#define RSA_PARAMS 2 +#define RSA_PARAMS 3 #if MAX_PARAMS_SIZE - RSA_PARAMS < 0 # error INCREASE RSA_PARAMS @@ -28,7 +28,7 @@ typedef struct gnutls_cert { * DSA: [0] is p * [1] is q * [2] is g - * [3] is pub + * [3] is public key */ PKAlgorithm subject_pk_algorithm; @@ -58,11 +58,14 @@ typedef struct { * key algorithm */ /* + * RSA: [0] is modulus + * [1] is public exponent + * [2] is private exponent * DSA: [0] is p * [1] is q * [2] is g - * [3] is Y (public) - * [4] is priv + * [3] is y (public key) + * [4] is x (private key) */ PKAlgorithm pk_algorithm; diff --git a/lib/gnutls_gcry.c b/lib/gnutls_gcry.c index 7ea3abcca0..31e8b3f6be 100644 --- a/lib/gnutls_gcry.c +++ b/lib/gnutls_gcry.c @@ -19,6 +19,8 @@ */ #include <gnutls_int.h> +#include <x509_asn1.h> +#include <gnutls_errors.h> /* Functions that refer to the libgcrypt library. */ @@ -42,3 +44,25 @@ int _gnutls_mpi_print( opaque *buffer, size_t *nbytes, const GCRY_MPI a ) { return gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, a); } + +/* this function reads an integer + * from asn1 structs. Combines the read and mpi_scan + * steps. + */ +int _gnutls_x509_read_int( node_asn* node, char* value, char* tmpstr, int tmpstr_size, MPI* ret_mpi) { +int len, result; + + len = tmpstr_size - 1; + result = asn1_read_value(node, value, tmpstr, &len); + if (result != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + if (_gnutls_mpi_scan( ret_mpi, tmpstr, &len) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + return 0; +} diff --git a/lib/gnutls_gcry.h b/lib/gnutls_gcry.h index df42a09d66..1423f4c04a 100644 --- a/lib/gnutls_gcry.h +++ b/lib/gnutls_gcry.h @@ -2,6 +2,7 @@ # define GNUTLS_GCRY_H # include <gcrypt.h> +# include <x509_asn1.h> MPI _gnutls_mpi_new( int); @@ -13,4 +14,6 @@ int _gnutls_mpi_scan( GCRY_MPI *ret_mpi, const opaque *buffer, size_t *nbytes ); int _gnutls_mpi_print( opaque *buffer, size_t *nbytes, const GCRY_MPI a ); +int _gnutls_x509_read_int( node_asn* node, char* value, char* tmpstr, int tmpstr_size, MPI* ret_mpi); + #endif diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c index a7a27cb80f..cd999e9f9c 100644 --- a/lib/gnutls_pk.c +++ b/lib/gnutls_pk.c @@ -27,26 +27,27 @@ #include <gnutls_errors.h> #include <gnutls_random.h> #include <gnutls_datum.h> +#include <gnutls_global.h> +#include <x509_der.h> #include "debug.h" -static int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI ** pkey); -static int _gnutls_pk_verify(int algo, MPI hash, MPI** data, MPI **pkey); +static int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI * pkey); +static int _gnutls_pk_verify(int algo, MPI hash, MPI* data, MPI *pkey); /* Do PKCS-1 RSA encryption. - * pkey is the public key and n the modulus. + * params is modulus, public exp. */ - int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, - gnutls_datum plaintext, MPI pkey, MPI n, + gnutls_datum plaintext, MPI* params, int btype) { int k, psize, i, ret; MPI m, res; opaque *edata, *ps; - MPI *_pkey[2]; + MPI tmp_params[RSA_PARAMS]; - k = gcry_mpi_get_nbits(n) / 8; + k = gcry_mpi_get_nbits(params[0]) / 8; if (plaintext.size > k - 11) { gnutls_assert(); @@ -70,6 +71,10 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, ps = &edata[2]; switch (btype) { case 2: + /* using public key */ + tmp_params[0] = params[0]; + tmp_params[1] = params[1]; + _gnutls_get_random(ps, psize, GNUTLS_WEAK_RANDOM); for (i = 0; i < psize; i++) { if (ps[i] == 0) @@ -77,6 +82,10 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, } break; case 1: + /* using private key */ + tmp_params[0] = params[0]; + tmp_params[1] = params[2]; + for (i = 0; i < psize; i++) ps[i] = 0xff; break; @@ -102,9 +111,7 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, } gnutls_free(edata); - _pkey[0] = &n; - _pkey[1] = &pkey; - ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, m, _pkey); + ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, m, tmp_params); _gnutls_mpi_release(&m); if (ret < 0) { @@ -130,19 +137,18 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, /* Do PKCS-1 RSA decryption. - * pkey is the private key and n the modulus. + * params is modulus, public exp. * Can decrypt block type 1 and type packets. */ int _gnutls_pkcs1_rsa_decrypt(gnutls_sdatum * plaintext, - gnutls_datum ciphertext, MPI pkey, MPI n, + gnutls_datum ciphertext, MPI* params, int btype) { int k, esize, i, ret; MPI c, res; opaque *edata; - MPI *_pkey[2]; - k = gcry_mpi_get_nbits(n) / 8; + k = gcry_mpi_get_nbits(params[0]) / 8; esize = ciphertext.size; if (esize != k) { @@ -155,11 +161,7 @@ int _gnutls_pkcs1_rsa_decrypt(gnutls_sdatum * plaintext, return GNUTLS_E_MPI_SCAN_FAILED; } - - _pkey[0] = &n; - _pkey[1] = &pkey; - - ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, c, _pkey); + ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, c, params); _gnutls_mpi_release(&c); if (ret < 0) { @@ -239,13 +241,13 @@ int _gnutls_pkcs1_rsa_decrypt(gnutls_sdatum * plaintext, int _gnutls_rsa_verify( const gnutls_datum* vdata, const gnutls_datum *ciphertext, - MPI pkey, MPI n, int btype) { + MPI *params, int btype) { gnutls_datum plain; int ret; /* decrypt signature */ - if ( (ret=_gnutls_pkcs1_rsa_decrypt( &plain, *ciphertext, pkey, n, btype)) < 0) { + if ( (ret=_gnutls_pkcs1_rsa_decrypt( &plain, *ciphertext, params, btype)) < 0) { gnutls_assert(); return ret; } @@ -267,28 +269,92 @@ int _gnutls_rsa_verify( const gnutls_datum* vdata, const gnutls_datum *ciphertex return 0; /* ok */ } +/* encodes the Dss-Sig-Value structure + */ +static int encode_ber_rs( gnutls_datum* sig_value, MPI r, MPI s) { +node_asn* sig; +int result; +opaque str[MAX_PARAMETER_SIZE]; +int len = sizeof(str); +int tot_len = 0; + + if (asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.DSASignatureValue", + &sig, "sig")!=ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_ERROR; + } + + if ( _gnutls_mpi_print( str, &len, r) < 0) { + gnutls_assert(); + asn1_delete_structure(sig); + return GNUTLS_E_MPI_PRINT_FAILED; + } + tot_len += len; + + result = asn1_write_value( sig, "sig.r", str, len); + + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(sig); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + len = sizeof(str) - 1; + if ( _gnutls_mpi_print( str, &len, s) < 0) { + gnutls_assert(); + asn1_delete_structure(sig); + return GNUTLS_E_MPI_PRINT_FAILED; + } + tot_len += len; + + result = asn1_write_value( sig, "sig.s", str, len); + + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(sig); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + sig_value->size = tot_len + 100; + sig_value->data = gnutls_malloc( sig_value->size); + if (sig_value->data==NULL) { + gnutls_assert(); + asn1_delete_structure(sig); + } + + result = asn1_create_der( sig, "sig", sig_value->data, &sig_value->size); + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(sig); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + asn1_delete_structure(sig); + + return 0; +} + -/* Do DSA signature calculation +/* Do DSA signature calculation. params is p, q, g, y, x in that order. */ -int _gnutls_dsa_sign(gnutls_datum * signature, gnutls_datum plaintext, - MPI p, MPI q, MPI g, MPI y) +int _gnutls_dsa_sign(gnutls_datum * signature, const gnutls_datum *hash, + MPI * params) { - MPI res[2], mdata; - int sig_size; - MPI *_pkey[DSA_PARAMS]; - int k, ret, psize; + MPI rs[2], mdata; + int k, ret; + + k = hash->size; + if (k!=20) { /* SHA only */ + gnutls_assert(); + return GNUTLS_E_PK_SIGNATURE_FAILED; + } - k = plaintext.size; - if (_gnutls_mpi_scan(&mdata, plaintext.data, &k) != 0) { + if (_gnutls_mpi_scan(&mdata, hash->data, &k) != 0) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } - _pkey[0] = &p; - _pkey[1] = &q; - _pkey[2] = &g; - _pkey[3] = &y; - ret = _gnutls_pk_sign(GCRY_PK_DSA, res, mdata, _pkey); + ret = _gnutls_pk_sign(GCRY_PK_DSA, rs, mdata, params); /* res now holds r,s */ _gnutls_mpi_release(&mdata); @@ -297,34 +363,80 @@ int _gnutls_dsa_sign(gnutls_datum * signature, gnutls_datum plaintext, return ret; } -#error FIX r,s + if (encode_ber_rs( signature, rs[0], rs[1])!=0) { + gnutls_assert(); + _gnutls_mpi_release(&rs[0]); + _gnutls_mpi_release(&rs[1]); + return GNUTLS_E_MEMORY_ERROR; + } + + /* free r,s */ + _gnutls_mpi_release(&rs[0]); + _gnutls_mpi_release(&rs[1]); + + return 0; +} + +/* decodes the Dss-Sig-Value structure + */ +static int decode_ber_rs( const gnutls_datum* sig_value, MPI* r, MPI* s) { +node_asn* sig; +int result; +opaque str[MAX_PARAMETER_SIZE]; - _gnutls_mpi_print(NULL, &sig_size, res[0]); - signature->data = gnutls_malloc(sig_size); - if (signature->data == NULL) { + if (asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.DSASignatureValue", &sig, "sig")!=ASN_OK) { gnutls_assert(); - _gnutls_mpi_release(&res[0]); - return GNUTLS_E_MEMORY_ERROR; + return GNUTLS_E_ASN1_ERROR; + } + + result = asn1_get_der( sig, sig_value->data, sig_value->size); + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(sig); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + result = + _gnutls_x509_read_int( sig, "sig.r", str, sizeof(str)-1, r); + if (result < 0) { + gnutls_assert(); + asn1_delete_structure(sig); + return result; } - _gnutls_mpi_print(signature->data, &psize, res[0]); - signature->size = psize; - _gnutls_mpi_release(&res[0]); + result = + _gnutls_x509_read_int( sig, "sig.s", str, sizeof(str)-1, s); + if (result < 0) { + gnutls_assert(); + _gnutls_mpi_release( s); + asn1_delete_structure(sig); + return result; + } + asn1_delete_structure(sig); + return 0; } -int _gnutls_dsa_verify( const gnutls_datum* vdata, const gnutls_datum *ciphertext, - MPI p, MPI q, MPI g, MPI y) { +/* params is p, q, g, y in that order + */ +int _gnutls_dsa_verify( const gnutls_datum* vdata, const gnutls_datum *sig_value, + MPI * params) { MPI mdata; int ret, k; - MPI *_pkey[DSA_PARAMS]; - MPI *_data[2]; - MPI r, s; - - #error FIX r,s + MPI rs[2]; + + if (vdata->size != 20) { /* sha-1 only */ + gnutls_assert(); + return GNUTLS_E_INTERNAL; + } + + if (decode_ber_rs( sig_value, &rs[0], &rs[1])!=0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } k = vdata->size; if (_gnutls_mpi_scan(&mdata, vdata->data, &k) != 0) { @@ -333,14 +445,7 @@ int _gnutls_dsa_verify( const gnutls_datum* vdata, const gnutls_datum *ciphertex } /* decrypt signature */ - _pkey[0] = &p; - _pkey[1] = &q; - _pkey[2] = &g; - _pkey[3] = &y; - - _data[0] = &r; - _data[1] = &s; - if ( (ret=_gnutls_pk_verify( GCRY_PK_DSA, mdata, _data, _pkey)) < 0) { + if ( (ret=_gnutls_pk_verify( GCRY_PK_DSA, mdata, rs, params)) < 0) { _gnutls_mpi_release(&mdata); gnutls_assert(); return ret; @@ -358,7 +463,7 @@ int _gnutls_dsa_verify( const gnutls_datum* vdata, const gnutls_datum *ciphertex * Emulate our old PK interface here - sometime in the future we might * change the internal design to directly fit to libgcrypt. */ -int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI ** pkey) +int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI * pkey) { GCRY_SEXP s_ciph, s_data, s_pkey; int rc; @@ -368,7 +473,7 @@ int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI ** pkey) case GCRY_PK_RSA: rc = gcry_sexp_build(&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", - *pkey[0], *pkey[1]); + pkey[0], pkey[1]); break; default: @@ -384,6 +489,7 @@ int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI ** pkey) /* put the data into a simple list */ if (gcry_sexp_build(&s_data, NULL, "%m", data)) { gnutls_assert(); + gcry_sexp_release(s_pkey); return GNUTLS_E_UNKNOWN_ERROR; } @@ -410,7 +516,7 @@ int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI ** pkey) if (resarr[0] == NULL) { gnutls_assert(); gcry_sexp_release(s_ciph); - return GNUTLS_E_UNKNOWN_ERROR; + return GNUTLS_E_INTERNAL; } } @@ -421,7 +527,7 @@ int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI ** pkey) /* in case of DSA puts into data, r,s */ static -int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI ** pkey) +int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI * pkey) { GCRY_SEXP s_hash, s_key, s_sig; int rc; @@ -430,9 +536,9 @@ int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI ** pkey) switch (algo) { case GCRY_PK_DSA: rc = gcry_sexp_build(&s_key, NULL, - "(public-key(rsa(p%m)(q%m)(g%m)(y%m)(x%m)))", - *pkey[0], *pkey[1], *pkey[2], - *pkey[3], *pkey[4]); + "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", + pkey[0], pkey[1], pkey[2], + pkey[3], pkey[4]); break; default: @@ -458,7 +564,7 @@ int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI ** pkey) if (rc != 0) { gnutls_assert(); - return GNUTLS_E_PK_ENCRYPTION_FAILED; + return GNUTLS_E_PK_SIGNATURE_FAILED; } else { GCRY_SEXP list = gcry_sexp_find_token( s_sig, "r" , 0); @@ -488,7 +594,7 @@ int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI ** pkey) } -static int _gnutls_pk_verify(int algo, MPI hash, MPI** data, MPI **pkey) +static int _gnutls_pk_verify(int algo, MPI hash, MPI* data, MPI *pkey) { GCRY_SEXP s_sig, s_hash, s_pkey; int rc; @@ -498,18 +604,16 @@ static int _gnutls_pk_verify(int algo, MPI hash, MPI** data, MPI **pkey) case GCRY_PK_DSA: rc = gcry_sexp_build(&s_pkey, NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2], - pkey[3]); + pkey[0], pkey[1], pkey[2], pkey[3]); break; default: gnutls_assert(); - return GNUTLS_E_UNKNOWN_KX_ALGORITHM; + return GNUTLS_E_INTERNAL; } if (rc != 0) { gnutls_assert(); - gcry_sexp_release(s_pkey); return GNUTLS_E_INTERNAL; } @@ -524,20 +628,20 @@ static int _gnutls_pk_verify(int algo, MPI hash, MPI** data, MPI **pkey) case GCRY_PK_DSA: rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r%m)(s%m)))", - *data[0], *data[1]); + data[0], data[1]); break; default: gnutls_assert(); gcry_sexp_release(s_pkey); - gcry_sexp_release(s_sig); - return GNUTLS_E_UNKNOWN_KX_ALGORITHM; + gcry_sexp_release(s_hash); + return GNUTLS_E_INTERNAL; } if (rc != 0) { gnutls_assert(); gcry_sexp_release(s_pkey); - gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); return GNUTLS_E_INTERNAL; } diff --git a/lib/gnutls_pk.h b/lib/gnutls_pk.h index 95a54f4ee3..125e6dbb45 100644 --- a/lib/gnutls_pk.h +++ b/lib/gnutls_pk.h @@ -5,14 +5,16 @@ typedef enum PKAlgorithm { GNUTLS_PK_RSA = 1, GNUTLS_PK_DSA, /* sign only */ GNUTLS_PK_DH, GNUTLS_PK_UNKNOWN } PKAlgorithm; -int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI ** pkey); +int _gnutls_pk_encrypt(int algo, MPI * resarr, MPI data, MPI * pkey); int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, gnutls_datum plaintext, - MPI pkey, MPI n, int btype); -int _gnutls_dsa_sign(gnutls_datum * signature, gnutls_datum plaintext, - MPI p, MPI q, MPI g, MPI Y); + MPI * params, int btype); +int _gnutls_dsa_sign(gnutls_datum * signature, const gnutls_datum *plaintext, + MPI *params); int _gnutls_pkcs1_rsa_decrypt(gnutls_datum * plaintext, gnutls_datum ciphertext, - MPI pkey, MPI n, int btype); + MPI * params, int btype); int _gnutls_rsa_verify( const gnutls_datum* vdata, const gnutls_datum *ciphertext, - MPI pkey, MPI n, int btype); + MPI* params, int btype); +int _gnutls_dsa_verify( const gnutls_datum* vdata, const gnutls_datum *sig_value, + MPI * params); #endif /* GNUTLS_PK_H */ diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index ac749ed47b..360f4236ab 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -37,12 +37,11 @@ int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key) { int result; opaque str[MAX_PARAMETER_SIZE]; - int len = sizeof(str); - node_asn *pkcs_asn; + node_asn *pkey_asn; pkey->pk_algorithm = GNUTLS_PK_RSA; - if (asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", &pkcs_asn, "rsakey")!=ASN_OK) { + if (asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", &pkey_asn, "rsakey")!=ASN_OK) { gnutls_assert(); return GNUTLS_E_ASN1_ERROR; } @@ -53,51 +52,43 @@ int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key) return GNUTLS_E_INTERNAL; } - result = asn1_get_der( pkcs_asn, raw_key.data, raw_key.size); + result = asn1_get_der( pkey_asn, raw_key.data, raw_key.size); if (result != ASN_OK) { gnutls_assert(); return GNUTLS_E_ASN1_PARSING_ERROR; } - len = sizeof(str) - 1; - result = - asn1_read_value( pkcs_asn, "rsakey.privateExponent", str, &len); - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(pkcs_asn); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - if (_gnutls_mpi_scan( &pkey->params[0], /* u */ - str, &len) != 0 || pkey->params[0]==NULL) { + if ( (result=_gnutls_x509_read_int( pkey_asn, "rsakey.modulus", + str, sizeof(str)-1, &pkey->params[0])) < 0) { gnutls_assert(); - asn1_delete_structure(pkcs_asn); - return GNUTLS_E_MPI_SCAN_FAILED; + asn1_delete_structure(pkey_asn); + return result; } - - len = sizeof(str) - 1; - result = - asn1_read_value( pkcs_asn, "rsakey.modulus", str, &len); - if (result != ASN_OK) { + if ( (result=_gnutls_x509_read_int( pkey_asn, "rsakey.publicExponent", + str, sizeof(str)-1, &pkey->params[1])) < 0) { gnutls_assert(); - asn1_delete_structure(pkcs_asn); + asn1_delete_structure(pkey_asn); _gnutls_mpi_release( &pkey->params[0]); - return GNUTLS_E_ASN1_PARSING_ERROR; + return result; } - if (_gnutls_mpi_scan( &pkey->params[1], /* A */ - str, &len) != 0 || pkey->params[1] == NULL) { + if ( (result=_gnutls_x509_read_int( pkey_asn, "rsakey.privateExponent", + str, sizeof(str)-1, &pkey->params[2])) < 0) { gnutls_assert(); - asn1_delete_structure(pkcs_asn); _gnutls_mpi_release( &pkey->params[0]); - return GNUTLS_E_MPI_SCAN_FAILED; + _gnutls_mpi_release( &pkey->params[1]); + asn1_delete_structure(pkey_asn); + return result; } - asn1_delete_structure(pkcs_asn); + + asn1_delete_structure(pkey_asn); if (gnutls_set_datum( &pkey->raw, raw_key.data, raw_key.size) < 0) { _gnutls_mpi_release(&pkey->params[0]); _gnutls_mpi_release(&pkey->params[1]); + _gnutls_mpi_release(&pkey->params[2]); gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } @@ -110,12 +101,11 @@ int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key) int _gnutls_DSAkey2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key) { int result; opaque str[MAX_PARAMETER_SIZE]; - int len = sizeof(str); - node_asn *pkix_asn; + node_asn *dsa_asn; pkey->pk_algorithm = GNUTLS_PK_DSA; - if (asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", &pkix_asn, "dsakey")!=ASN_OK) { + if (asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", &dsa_asn, "dsakey")!=ASN_OK) { gnutls_assert(); return GNUTLS_E_ASN1_ERROR; } @@ -126,111 +116,58 @@ int _gnutls_DSAkey2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key) { return GNUTLS_E_INTERNAL; } - result = asn1_get_der( pkix_asn, raw_key.data, raw_key.size); + result = asn1_get_der( dsa_asn, raw_key.data, raw_key.size); if (result != ASN_OK) { gnutls_assert(); return GNUTLS_E_ASN1_PARSING_ERROR; } - len = sizeof(str) - 1; - result = - asn1_read_value( pkix_asn, "dsakey.p", str, &len); - if (result != ASN_OK) { + if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.p", + str, sizeof(str)-1, &pkey->params[0])) < 0) { gnutls_assert(); - asn1_delete_structure(pkix_asn); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if (_gnutls_mpi_scan( &pkey->params[0], /* p */ - str, &len) != 0) { - gnutls_assert(); - asn1_delete_structure(pkix_asn); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - len = sizeof(str) - 1; - result = - asn1_read_value( pkix_asn, "dsakey.q", str, &len); - if (result != ASN_OK) { - gnutls_assert(); - _gnutls_mpi_release(&pkey->params[0]); - asn1_delete_structure(pkix_asn); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if (_gnutls_mpi_scan( &pkey->params[1], /* q */ str, &len) != 0) { - gnutls_assert(); - _gnutls_mpi_release(&pkey->params[0]); - asn1_delete_structure(pkix_asn); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - len = sizeof(str) - 1; - result = - asn1_read_value( pkix_asn, "dsakey.g", str, &len); - if (result != ASN_OK) { - gnutls_assert(); - _gnutls_mpi_release(&pkey->params[0]); - _gnutls_mpi_release(&pkey->params[1]); - asn1_delete_structure(pkix_asn); - return GNUTLS_E_ASN1_PARSING_ERROR; + asn1_delete_structure(dsa_asn); + return result; } - if (_gnutls_mpi_scan( &pkey->params[2], /* g */ str, &len) != 0) { + if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.q", + str, sizeof(str)-1, &pkey->params[1])) < 0) { gnutls_assert(); - _gnutls_mpi_release(&pkey->params[0]); - _gnutls_mpi_release(&pkey->params[1]); - asn1_delete_structure(pkix_asn); - return GNUTLS_E_MPI_SCAN_FAILED; + asn1_delete_structure(dsa_asn); + _gnutls_mpi_release( &pkey->params[0]); + return result; } - len = sizeof(str) - 1; - result = - asn1_read_value( pkix_asn, "dsakey.Y", str, &len); - if (result != ASN_OK) { + if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.g", + str, sizeof(str)-1, &pkey->params[2])) < 0) { gnutls_assert(); - _gnutls_mpi_release(&pkey->params[0]); - _gnutls_mpi_release(&pkey->params[1]); - _gnutls_mpi_release(&pkey->params[2]); - asn1_delete_structure(pkix_asn); - return GNUTLS_E_ASN1_PARSING_ERROR; + asn1_delete_structure(dsa_asn); + _gnutls_mpi_release( &pkey->params[0]); + _gnutls_mpi_release( &pkey->params[1]); + return result; } - if (_gnutls_mpi_scan( &pkey->params[3], /* priv key */ - str, &len) != 0) { + if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.Y", + 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(pkix_asn); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - len = sizeof(str) - 1; - result = - asn1_read_value( pkix_asn, "dsakey.priv", str, &len); - if (result != ASN_OK) { - 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(pkix_asn); - return GNUTLS_E_ASN1_PARSING_ERROR; + 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 (_gnutls_mpi_scan( &pkey->params[4], /* priv key */ - str, &len) != 0) { + if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.priv", + 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(pkix_asn); - return GNUTLS_E_MPI_SCAN_FAILED; + 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; } - asn1_delete_structure(pkix_asn); + asn1_delete_structure(dsa_asn); if (gnutls_set_datum( &pkey->raw, raw_key.data, raw_key.size) < 0) { _gnutls_mpi_release(&pkey->params[0]); diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c index a2502705f6..8b6009a634 100644 --- a/lib/gnutls_sig.c +++ b/lib/gnutls_sig.c @@ -35,6 +35,8 @@ #include <gnutls_sig.h> +int _gnutls_generate_sig( gnutls_cert* cert, gnutls_private_key *pkey, const gnutls_datum* hash_concat, gnutls_datum *signature); + /* Generates a signature of all the previous sent packets in the * handshake procedure. @@ -46,25 +48,36 @@ opaque concat[36]; GNUTLS_MAC_HANDLE td_md5; GNUTLS_MAC_HANDLE td_sha; - td_md5 = gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_md5); - if (td_md5 == NULL) { - gnutls_assert(); - return GNUTLS_E_HASH_FAILED; - } td_sha = gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_sha); if (td_sha == NULL) { gnutls_assert(); - gnutls_hash_deinit( td_md5, NULL); return GNUTLS_E_HASH_FAILED; } - gnutls_hash_deinit(td_md5, concat); gnutls_hash_deinit(td_sha, &concat[16]); - dconcat.data = concat; - dconcat.size = 36; + switch (cert->subject_pk_algorithm) { + case GNUTLS_PK_RSA: + td_md5 = gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_md5); + if (td_md5 == NULL) { + gnutls_assert(); + return GNUTLS_E_HASH_FAILED; + } + gnutls_hash_deinit(td_md5, concat); + dconcat.data = concat; + dconcat.size = 36; + break; + case GNUTLS_PK_DSA: + dconcat.data = &concat[16]; + dconcat.size = 20; + break; + + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL; + } ret = _gnutls_generate_sig( cert, pkey, &dconcat, signature); if (ret < 0) gnutls_assert(); @@ -84,33 +97,46 @@ GNUTLS_MAC_HANDLE td_md5; GNUTLS_MAC_HANDLE td_sha; opaque concat[36]; - td_md5 = gnutls_hash_init( GNUTLS_MAC_MD5); - if (td_md5 == NULL) { - gnutls_assert(); - return GNUTLS_E_HASH_FAILED; - } td_sha = gnutls_hash_init( GNUTLS_MAC_SHA); if (td_sha == NULL) { gnutls_assert(); - gnutls_hash_deinit( td_md5, NULL); return GNUTLS_E_HASH_FAILED; } - gnutls_hash( td_md5, state->security_parameters.client_random, TLS_RANDOM_SIZE); - gnutls_hash( td_md5, state->security_parameters.server_random, TLS_RANDOM_SIZE); - gnutls_hash( td_md5, params->data, params->size); - gnutls_hash( td_sha, state->security_parameters.client_random, TLS_RANDOM_SIZE); gnutls_hash( td_sha, state->security_parameters.server_random, TLS_RANDOM_SIZE); gnutls_hash( td_sha, params->data, params->size); - gnutls_hash_deinit(td_md5, concat); gnutls_hash_deinit(td_sha, &concat[16]); - dconcat.data = concat; - dconcat.size = 36; + switch (cert->subject_pk_algorithm) { + case GNUTLS_PK_RSA: + td_md5 = gnutls_hash_init( GNUTLS_MAC_MD5); + if (td_md5 == NULL) { + gnutls_assert(); + return GNUTLS_E_HASH_FAILED; + } + + gnutls_hash( td_md5, state->security_parameters.client_random, TLS_RANDOM_SIZE); + gnutls_hash( td_md5, state->security_parameters.server_random, TLS_RANDOM_SIZE); + gnutls_hash( td_md5, params->data, params->size); + + gnutls_hash_deinit(td_md5, concat); + + dconcat.data = concat; + dconcat.size = 36; + break; + case GNUTLS_PK_DSA: + dconcat.data = &concat[16]; + dconcat.size = 20; + break; + + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL; + } ret = _gnutls_generate_sig( cert, pkey, &dconcat, signature); if (ret < 0) gnutls_assert(); @@ -139,27 +165,23 @@ gnutls_datum tmpdata; return GNUTLS_E_X509_KEY_USAGE_VIOLATION; } + tmpdata.data = hash_concat->data; + tmpdata.size = hash_concat->size; + switch(pkey->pk_algorithm) { case GNUTLS_PK_RSA: - tmpdata.data = hash_concat->data; - tmpdata.size = hash_concat->size; /* md5 + sha */ /* encrypt */ - if ((ret=_gnutls_pkcs1_rsa_encrypt( signature, tmpdata, pkey->params[0], pkey->params[1], 1)) < 0) { + if ((ret=_gnutls_pkcs1_rsa_encrypt( signature, tmpdata, pkey->params, 1)) < 0) { gnutls_assert(); return ret; } break; case GNUTLS_PK_DSA: - /* Ok this is silly. We have calculated - * md5 also! - */ - tmpdata.data = &hash_concat->data[16]; - tmpdata.size = 20; /* sha */ /* sign */ - if ((ret=_gnutls_dsa_sign( signature, tmpdata, pkey->params[0], pkey->params[1], pkey->params[2], pkey->params[3])) < 0) { + if ((ret=_gnutls_dsa_sign( signature, &tmpdata, pkey->params)) < 0) { gnutls_assert(); return ret; } @@ -204,7 +226,7 @@ int _gnutls_pkcs1_rsa_verify_sig( gnutls_cert *cert, const gnutls_datum *hash_co vdata.size = hash_concat->size; /* verify signature */ - if ( (ret=_gnutls_rsa_verify( &vdata, signature, cert->params[1], cert->params[0], 1)) < 0) { + if ( (ret=_gnutls_rsa_verify( &vdata, signature, cert->params, 1)) < 0) { gnutls_assert(); return ret; } @@ -216,13 +238,13 @@ int _gnutls_pkcs1_rsa_verify_sig( gnutls_cert *cert, const gnutls_datum *hash_co vdata.size = 20; /* sha1 */ /* decrypt signature */ - if ( (ret=_gnutls_dsa_verify( &vdata, *signature, cert->params[0], - cert->params[1], cert->params[2], cert->params[3])) < 0) { + if ( (ret=_gnutls_dsa_verify( &vdata, signature, cert->params)) < 0) { gnutls_assert(); return ret; } break; + default: gnutls_assert(); return GNUTLS_E_UNIMPLEMENTED_FEATURE; diff --git a/lib/x509_sig_check.c b/lib/x509_sig_check.c index 1556ed1114..c1afde5b7c 100644 --- a/lib/x509_sig_check.c +++ b/lib/x509_sig_check.c @@ -33,6 +33,8 @@ #include <debug.h> #include <gnutls_str.h> +/* returns DER tbsCertificate + */ static gnutls_datum _gnutls_get_tbs( gnutls_cert* cert) { node_asn *c2; gnutls_datum ret = {NULL, 0}; @@ -137,8 +139,8 @@ int len; * m is modulus * e is public key */ -int -_pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI e, MPI m) +static int +_pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI *params) { MACAlgorithm hash; int ret; @@ -148,7 +150,7 @@ _pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI e, MPI m gnutls_datum decrypted; - if ( (ret=_gnutls_pkcs1_rsa_decrypt( &decrypted, *signature, e, m, 1)) < 0) { + if ( (ret=_gnutls_pkcs1_rsa_decrypt( &decrypted, *signature, params, 1)) < 0) { gnutls_assert(); return ret; } @@ -182,136 +184,53 @@ _pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI e, MPI m return 0; } -#ifdef DEBUG -/* This is for CA DSS params - can wait */ -# warning CHECK HERE FOR DSS -#endif - /* verifies if the certificate is properly signed. */ CertificateStatus gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer) { gnutls_datum signature; gnutls_datum tbs; - if ( issuer->subject_pk_algorithm == GNUTLS_PK_RSA) { - signature.data = cert->signature; - signature.size = cert->signature_size; - - tbs = _gnutls_get_tbs( cert); - if (tbs.data==NULL) { - gnutls_assert(); - return GNUTLS_CERT_INVALID; - } + signature.data = cert->signature; + signature.size = cert->signature_size; - if (_pkcs1_rsa_verify_sig( &signature, &tbs, issuer->params[1], issuer->params[0])!=0) { - gnutls_assert(); - gnutls_free_datum( &tbs); - return GNUTLS_CERT_NOT_TRUSTED; - } - gnutls_free_datum(&tbs); - return GNUTLS_CERT_TRUSTED; + tbs = _gnutls_get_tbs( cert); + if (tbs.data==NULL) { + gnutls_assert(); + return GNUTLS_CERT_INVALID; } - _gnutls_log( "X509_sig: PK: %d\n", issuer->subject_pk_algorithm); + switch( issuer->subject_pk_algorithm) { + case GNUTLS_PK_RSA: + + if (_pkcs1_rsa_verify_sig( &signature, &tbs, issuer->params)!=0) { + gnutls_assert(); + gnutls_free_datum( &tbs); + return GNUTLS_CERT_NOT_TRUSTED; + } - gnutls_assert(); - return GNUTLS_CERT_INVALID; -} + gnutls_free_datum(&tbs); + return GNUTLS_CERT_TRUSTED; + break; + case GNUTLS_PK_DSA: + if (_gnutls_dsa_verify( &tbs, &signature, issuer->params)!=0) { + gnutls_assert(); + gnutls_free_datum( &tbs); + return GNUTLS_CERT_NOT_TRUSTED; + } -#if 0 -/* Signature generation - not tested */ -static int _gnutls_digestinfo_encode( opaque* data, int data_size, char* OID, gnutls_datum* der) { -node_asn *di; -int result; + gnutls_free_datum(&tbs); + return GNUTLS_CERT_TRUSTED; + break; - if (asn1_create_structure( _gnutls_get_gnutls_asn(), - "GNUTLS.DigestInfo", &di, "di") != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - - result = asn1_write_value( di, "di.digestAlgorithm.algorithm", OID, 1); - if (result!=ASN_OK) { - gnutls_assert(); - asn1_delete_structure( di); - return GNUTLS_E_ASN1_ERROR; - } - - result = asn1_write_value( di, "di.digestAlgorithm.parameters", NULL, 0); - if (result!=ASN_OK) { - gnutls_assert(); - asn1_delete_structure( di); - return GNUTLS_E_ASN1_ERROR; } - result = asn1_write_value( di, "di.digest", data, data_size); - if (result!=ASN_OK) { - gnutls_assert(); - asn1_delete_structure( di); - return GNUTLS_E_ASN1_ERROR; - } + gnutls_free_datum(&tbs); - der->size = data_size + 200; - der->data = gnutls_malloc( der->size); - if (der->data==NULL) { - gnutls_assert(); - asn1_delete_structure( di); - return GNUTLS_E_MEMORY_ERROR; - } - - result = asn1_create_der( di, "di", der->data, &der->size); - if (result!=ASN_OK) { - gnutls_assert(); - asn1_delete_structure( di); - gnutls_free_datum( der); - return GNUTLS_E_ASN1_ERROR; - } - asn1_delete_structure( di); + _gnutls_log( "X509_sig: PK: %d\n", issuer->subject_pk_algorithm); - return 0; + gnutls_assert(); + return GNUTLS_CERT_INVALID; } -int _pkcs1_rsa_generate_sig( MACAlgorithm hash_algo, gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature) { - int ret; - GNUTLS_HASH_HANDLE hd; - opaque digest[MAX_HASH_SIZE]; - char OID[64]; - int digest_size = gnutls_hash_get_algo_len( hash_algo); - gnutls_datum der; - - if (hash_algo==GNUTLS_MAC_MD5) - _gnutls_str_cpy(OID, sizeof(OID), "1 2 840 113549 2 5"); - else if (hash_algo==GNUTLS_MAC_SHA) - _gnutls_str_cpy(OID, sizeof(OID), "1 3 14 3 2 26"); - else { - gnutls_assert(); - return GNUTLS_E_UNKNOWN_MAC_ALGORITHM; - } - - /* hash data */ - hd = gnutls_hash_init( hash_algo); - if (hd==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - gnutls_hash( hd, data->data, data->size); - gnutls_hash_deinit( hd, digest); - - /* encode digest to DigestInfo (der) */ - if ( (ret=_gnutls_digestinfo_encode( digest, digest_size, OID, &der)) < 0) { - gnutls_assert(); - return ret; - } - - der.data = digest; - der.size = digest_size; - /* encrypt der */ - if ( (ret=_gnutls_pkcs1_rsa_encrypt( signature, der, pkey->params[0], pkey->params[1], 1)) < 0) { - gnutls_assert(); - return ret; - } - return 0; -} -#endif @@ -50,8 +50,11 @@ #define MAX(X,Y) (X >= Y ? X : Y); #define CAFILE "x509/ca.pem" #define CRLFILE NULL -#define CLIKEYFILE "x509/clikey.pem" -#define CLICERTFILE "x509/clicert.pem" +#define CLIKEYFILE1 "x509/clikey-dsa.pem" +#define CLICERTFILE1 "x509/clicert-dsa.pem" + +#define CLIKEYFILE2 "x509/clikey.pem" +#define CLICERTFILE2 "x509/clicert.pem" static int cert_callback( GNUTLS_STATE state, const gnutls_datum *client_certs, int ncerts, const gnutls_datum* req_ca_cert, int nreqs) { @@ -130,12 +133,13 @@ int main(int argc, char** argv) } /* X509 stuff */ - if (gnutls_x509pki_allocate_client_sc( &xcred, 1) < 0) { /* space for 1 certificate */ + if (gnutls_x509pki_allocate_client_sc( &xcred, 2) < 0) { /* space for 2 certificates */ fprintf(stderr, "memory error\n"); exit(1); } gnutls_x509pki_set_client_trust_file( xcred, CAFILE, CRLFILE); - gnutls_x509pki_set_client_key_file( xcred, CLICERTFILE, CLIKEYFILE); + gnutls_x509pki_set_client_key_file( xcred, CLICERTFILE1, CLIKEYFILE1); + gnutls_x509pki_set_client_key_file( xcred, CLICERTFILE2, CLIKEYFILE2); gnutls_x509pki_set_client_cert_callback( xcred, cert_callback); /* SRP stuff */ |