LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - tls-sig.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 264 301 87.7 %
Date: 2020-10-30 04:50:48 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2001-2012 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2017 Red Hat, Inc.
       4             :  *
       5             :  * Author: Nikos Mavrogiannopoulos
       6             :  *
       7             :  * This file is part of GnuTLS.
       8             :  *
       9             :  * The GnuTLS is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public License
      11             :  * as published by the Free Software Foundation; either version 2.1 of
      12             :  * the License, or (at your option) any later version.
      13             :  *
      14             :  * This library is distributed in the hope that it will be useful, but
      15             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public License
      20             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      21             :  *
      22             :  */
      23             : 
      24             : #include "gnutls_int.h"
      25             : #include "errors.h"
      26             : #include <x509_b64.h>
      27             : #include <auth/cert.h>
      28             : #include <algorithms.h>
      29             : #include <datum.h>
      30             : #include <mpi.h>
      31             : #include <global.h>
      32             : #include <pk.h>
      33             : #include <debug.h>
      34             : #include <buffers.h>
      35             : #include <tls-sig.h>
      36             : #include <kx.h>
      37             : #include <libtasn1.h>
      38             : #include <ext/signature.h>
      39             : #include <state.h>
      40             : #include <x509/common.h>
      41             : #include <abstract_int.h>
      42             : 
      43        9730 : int _gnutls_check_key_usage_for_sig(gnutls_session_t session, unsigned key_usage, unsigned our_cert)
      44             : {
      45        9730 :         const char *lstr;
      46        9730 :         unsigned allow_key_usage_violation;
      47             : 
      48        9730 :         if (our_cert) {
      49        7858 :                 lstr = "Local";
      50        7858 :                 allow_key_usage_violation = session->internals.priorities->allow_server_key_usage_violation;
      51             :         } else {
      52        1872 :                 lstr = "Peer's";
      53        1872 :                 allow_key_usage_violation = session->internals.allow_key_usage_violation;
      54             :         }
      55             : 
      56        9730 :         if (key_usage != 0) {
      57        3951 :                 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
      58          40 :                         gnutls_assert();
      59          40 :                         if (likely(allow_key_usage_violation == 0)) {
      60          37 :                                 _gnutls_audit_log(session,
      61             :                                           "%s certificate does not allow digital signatures. Key usage violation detected.\n", lstr);
      62          37 :                                 return GNUTLS_E_KEY_USAGE_VIOLATION;
      63             :                         } else {
      64           3 :                                 _gnutls_audit_log(session,
      65             :                                           "%s certificate does not allow digital signatures. Key usage violation detected (ignored).\n", lstr);
      66             :                         }
      67             :                 }
      68             :         }
      69             :         return 0;
      70             : }
      71             : 
      72             : /* Generates a signature of all the random data and the parameters.
      73             :  * Used in *DHE_* ciphersuites for TLS 1.2.
      74             :  */
      75             : static int
      76        2155 : _gnutls_handshake_sign_data12(gnutls_session_t session,
      77             :                             gnutls_pcert_st * cert, gnutls_privkey_t pkey,
      78             :                             gnutls_datum_t * params,
      79             :                             gnutls_datum_t * signature,
      80             :                             gnutls_sign_algorithm_t sign_algo)
      81             : {
      82        2155 :         gnutls_datum_t dconcat;
      83        2155 :         int ret;
      84             : 
      85        2155 :         _gnutls_handshake_log
      86             :             ("HSK[%p]: signing TLS 1.2 handshake data: using %s\n", session,
      87             :              gnutls_sign_algorithm_get_name(sign_algo));
      88             : 
      89        2155 :         if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pkey->pk_algorithm) == 0))
      90           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
      91             : 
      92        2155 :         dconcat.size = GNUTLS_RANDOM_SIZE*2 + params->size;
      93        2155 :         dconcat.data = gnutls_malloc(dconcat.size);
      94        2155 :         if (dconcat.data == NULL)
      95           0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
      96             : 
      97        2155 :         memcpy(dconcat.data, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
      98        2155 :         memcpy(dconcat.data+GNUTLS_RANDOM_SIZE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
      99        2155 :         memcpy(dconcat.data+GNUTLS_RANDOM_SIZE*2, params->data, params->size);
     100             : 
     101        2155 :         ret = gnutls_privkey_sign_data2(pkey, sign_algo,
     102             :                                         0, &dconcat, signature);
     103        2155 :         if (ret < 0) {
     104           0 :                 gnutls_assert();
     105             :         }
     106        2155 :         gnutls_free(dconcat.data);
     107             : 
     108        2155 :         return ret;
     109             : 
     110             : }
     111             : 
     112             : static int
     113        1452 : _gnutls_handshake_sign_data10(gnutls_session_t session,
     114             :                             gnutls_pcert_st * cert, gnutls_privkey_t pkey,
     115             :                             gnutls_datum_t * params,
     116             :                             gnutls_datum_t * signature,
     117             :                             gnutls_sign_algorithm_t sign_algo)
     118             : {
     119        1452 :         gnutls_datum_t dconcat;
     120        1452 :         int ret;
     121        1452 :         digest_hd_st td_sha;
     122        1452 :         uint8_t concat[MAX_SIG_SIZE];
     123        1452 :         const mac_entry_st *me;
     124        1452 :         gnutls_pk_algorithm_t pk_algo;
     125             : 
     126        1452 :         pk_algo = gnutls_privkey_get_pk_algorithm(pkey, NULL);
     127        1452 :         if (pk_algo == GNUTLS_PK_RSA)
     128        1362 :                 me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
     129             :         else
     130          90 :                 me = hash_to_entry(
     131             :                                 gnutls_sign_get_hash_algorithm(sign_algo));
     132        1452 :         if (me == NULL)
     133           0 :                 return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
     134             : 
     135        1452 :         if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pk_algo) == 0))
     136           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     137             : 
     138        1452 :         pk_algo = gnutls_sign_get_pk_algorithm(sign_algo);
     139        1452 :         if (pk_algo == GNUTLS_PK_UNKNOWN)
     140           0 :                 return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM);
     141             : 
     142        1452 :         _gnutls_handshake_log
     143             :             ("HSK[%p]: signing handshake data: using %s\n", session,
     144             :              gnutls_sign_algorithm_get_name(sign_algo));
     145             : 
     146        1452 :         ret = _gnutls_hash_init(&td_sha, me);
     147        1452 :         if (ret < 0) {
     148           0 :                 gnutls_assert();
     149           0 :                 return ret;
     150             :         }
     151             : 
     152        1452 :         _gnutls_hash(&td_sha, session->security_parameters.client_random,
     153             :                      GNUTLS_RANDOM_SIZE);
     154        1452 :         _gnutls_hash(&td_sha, session->security_parameters.server_random,
     155             :                      GNUTLS_RANDOM_SIZE);
     156        1452 :         _gnutls_hash(&td_sha, params->data, params->size);
     157             : 
     158        1452 :         _gnutls_hash_deinit(&td_sha, concat);
     159             : 
     160        1452 :         dconcat.data = concat;
     161        1452 :         dconcat.size = _gnutls_hash_get_algo_len(me);
     162             : 
     163        1452 :         ret = gnutls_privkey_sign_hash(pkey, MAC_TO_DIG(me->id), GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
     164             :                                        &dconcat, signature);
     165        1452 :         if (ret < 0) {
     166           0 :                 gnutls_assert();
     167             :         }
     168             : 
     169             :         return ret;
     170             : }
     171             : 
     172             : /* Generates a signature of all the random data and the parameters.
     173             :  * Used in DHE_* ciphersuites.
     174             :  */
     175             : int
     176        3608 : _gnutls_handshake_sign_data(gnutls_session_t session,
     177             :                             gnutls_pcert_st * cert, gnutls_privkey_t pkey,
     178             :                             gnutls_datum_t * params,
     179             :                             gnutls_datum_t * signature,
     180             :                             gnutls_sign_algorithm_t * sign_algo)
     181             : {
     182        3608 :         const version_entry_st *ver = get_version(session);
     183        3608 :         unsigned key_usage = 0;
     184        3608 :         int ret;
     185             : 
     186        3608 :         *sign_algo = session->security_parameters.server_sign_algo;
     187        3608 :         if (*sign_algo == GNUTLS_SIGN_UNKNOWN) {
     188           1 :                 gnutls_assert();
     189           1 :                 return GNUTLS_E_UNWANTED_ALGORITHM;
     190             :         }
     191             : 
     192        3607 :         gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
     193             : 
     194        3607 :         ret = _gnutls_check_key_usage_for_sig(session, key_usage, 1);
     195        3607 :         if (ret < 0)
     196           0 :                 return gnutls_assert_val(ret);
     197             : 
     198        3607 :         if (_gnutls_version_has_selectable_sighash(ver))
     199        2155 :                 return _gnutls_handshake_sign_data12(session, cert, pkey, params, signature, *sign_algo);
     200             :         else
     201        1452 :                 return _gnutls_handshake_sign_data10(session, cert, pkey, params, signature, *sign_algo);
     202             : }
     203             : 
     204             : /* Generates a signature of all the random data and the parameters.
     205             :  * Used in DHE_* ciphersuites.
     206             :  */
     207             : static int
     208         133 : _gnutls_handshake_verify_data10(gnutls_session_t session,
     209             :                               unsigned verify_flags,
     210             :                               gnutls_pcert_st * cert,
     211             :                               const gnutls_datum_t * params,
     212             :                               gnutls_datum_t * signature,
     213             :                               gnutls_sign_algorithm_t sign_algo)
     214             : {
     215         133 :         gnutls_datum_t dconcat;
     216         133 :         int ret;
     217         133 :         digest_hd_st td_sha;
     218         133 :         uint8_t concat[MAX_SIG_SIZE];
     219         133 :         gnutls_digest_algorithm_t hash_algo;
     220         133 :         const mac_entry_st *me;
     221         133 :         gnutls_pk_algorithm_t pk_algo;
     222             : 
     223         133 :         pk_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
     224         133 :         if (pk_algo == GNUTLS_PK_RSA) {
     225          74 :                 hash_algo = GNUTLS_DIG_MD5_SHA1;
     226          74 :                 verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
     227             :         } else {
     228          59 :                 hash_algo = GNUTLS_DIG_SHA1;
     229          59 :                 if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
     230          59 :                         sign_algo = gnutls_pk_to_sign(pk_algo, hash_algo);
     231             :                 }
     232             :         }
     233             : 
     234         133 :         me = hash_to_entry(hash_algo);
     235             : 
     236         133 :         ret = _gnutls_hash_init(&td_sha, me);
     237         133 :         if (ret < 0) {
     238           0 :                 gnutls_assert();
     239           0 :                 return ret;
     240             :         }
     241             : 
     242         133 :         _gnutls_hash(&td_sha, session->security_parameters.client_random,
     243             :                      GNUTLS_RANDOM_SIZE);
     244         133 :         _gnutls_hash(&td_sha, session->security_parameters.server_random,
     245             :                      GNUTLS_RANDOM_SIZE);
     246         133 :         _gnutls_hash(&td_sha, params->data, params->size);
     247             : 
     248         133 :         _gnutls_hash_deinit(&td_sha, concat);
     249             : 
     250         133 :         dconcat.data = concat;
     251         133 :         dconcat.size = _gnutls_hash_get_algo_len(me);
     252             : 
     253         133 :         ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo,
     254             :                                          GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
     255             :                                          &dconcat, signature);
     256         133 :         if (ret < 0)
     257           5 :                 return gnutls_assert_val(ret);
     258             : 
     259             :         return ret;
     260             : }
     261             : 
     262             : static int
     263         703 : _gnutls_handshake_verify_data12(gnutls_session_t session,
     264             :                               unsigned verify_flags,
     265             :                               gnutls_pcert_st * cert,
     266             :                               const gnutls_datum_t * params,
     267             :                               gnutls_datum_t * signature,
     268             :                               gnutls_sign_algorithm_t sign_algo)
     269             : {
     270         703 :         gnutls_datum_t dconcat;
     271         703 :         int ret;
     272         703 :         const version_entry_st *ver = get_version(session);
     273         703 :         const gnutls_sign_entry_st *se = _gnutls_sign_to_entry(sign_algo);
     274             : 
     275         703 :         _gnutls_handshake_log
     276             :             ("HSK[%p]: verify TLS 1.2 handshake data: using %s\n", session,
     277             :              se->name);
     278             : 
     279         703 :         ret =
     280         703 :             _gnutls_pubkey_compatible_with_sig(session,
     281             :                                                cert->pubkey, ver,
     282             :                                                sign_algo);
     283         703 :         if (ret < 0)
     284           3 :                 return gnutls_assert_val(ret);
     285             : 
     286        1400 :         if (unlikely(sign_supports_cert_pk_algorithm(se, cert->pubkey->params.algo) == 0)) {
     287           0 :                 _gnutls_handshake_log("HSK[%p]: certificate of %s cannot be combined with %s sig\n",
     288             :                                       session, gnutls_pk_get_name(cert->pubkey->params.algo), se->name);
     289           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     290             :         }
     291             : 
     292         700 :         ret =
     293         700 :             _gnutls_session_sign_algo_enabled(session, sign_algo);
     294         700 :         if (ret < 0)
     295           0 :                 return gnutls_assert_val(ret);
     296             : 
     297         700 :         dconcat.size = GNUTLS_RANDOM_SIZE*2+params->size;
     298         700 :         dconcat.data = gnutls_malloc(dconcat.size);
     299         700 :         if (dconcat.data == NULL)
     300           0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     301             : 
     302         700 :         memcpy(dconcat.data, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
     303         700 :         memcpy(dconcat.data+GNUTLS_RANDOM_SIZE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
     304         700 :         memcpy(dconcat.data+GNUTLS_RANDOM_SIZE*2, params->data, params->size);
     305             : 
     306             :         /* Here we intentionally enable flag GNUTLS_VERIFY_ALLOW_BROKEN
     307             :          * because we have checked whether the currently used signature
     308             :          * algorithm is allowed in the session. */
     309         700 :         ret = gnutls_pubkey_verify_data2(cert->pubkey, sign_algo, verify_flags|GNUTLS_VERIFY_ALLOW_BROKEN,
     310             :                                          &dconcat, signature);
     311         700 :         if (ret < 0)
     312          19 :                 gnutls_assert();
     313             : 
     314         700 :         gnutls_free(dconcat.data);
     315             : 
     316         700 :         return ret;
     317             : }
     318             : 
     319             : int
     320         840 : _gnutls_handshake_verify_data(gnutls_session_t session,
     321             :                               unsigned verify_flags,
     322             :                               gnutls_pcert_st * cert,
     323             :                               const gnutls_datum_t * params,
     324             :                               gnutls_datum_t * signature,
     325             :                               gnutls_sign_algorithm_t sign_algo)
     326             : {
     327         840 :         unsigned key_usage;
     328         840 :         int ret;
     329         840 :         const version_entry_st *ver = get_version(session);
     330             : 
     331         840 :         if (cert == NULL) {
     332           0 :                 gnutls_assert();
     333           0 :                 return GNUTLS_E_CERTIFICATE_ERROR;
     334             :         }
     335             : 
     336         840 :         gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
     337             : 
     338         840 :         ret = _gnutls_check_key_usage_for_sig(session, key_usage, 0);
     339         840 :         if (ret < 0)
     340           4 :                 return gnutls_assert_val(ret);
     341             : 
     342         836 :         gnutls_sign_algorithm_set_server(session, sign_algo);
     343             : 
     344         836 :         if (_gnutls_version_has_selectable_sighash(ver))
     345         703 :                 return _gnutls_handshake_verify_data12(session, verify_flags, cert, params, signature, sign_algo);
     346             :         else
     347         133 :                 return _gnutls_handshake_verify_data10(session, verify_flags, cert, params, signature, sign_algo);
     348             : }
     349             : 
     350             : 
     351             : /* Client certificate verify calculations
     352             :  */
     353             : 
     354             : static void
     355           3 : _gnutls_reverse_datum(gnutls_datum_t * d)
     356             : {
     357           3 :         unsigned i;
     358             : 
     359         131 :         for (i = 0; i < d->size / 2; i ++) {
     360         128 :                 uint8_t t = d->data[i];
     361         128 :                 d->data[i] = d->data[d->size - 1 - i];
     362         128 :                 d->data[d->size - 1 - i] = t;
     363             :         }
     364           3 : }
     365             : 
     366             : static int
     367           3 : _gnutls_create_reverse(const gnutls_datum_t *src, gnutls_datum_t *dst)
     368             : {
     369           3 :         unsigned int i;
     370             : 
     371           3 :         dst->size = src->size;
     372           3 :         dst->data = gnutls_malloc(dst->size);
     373           3 :         if (!dst->data)
     374           0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     375             : 
     376         259 :         for (i = 0; i < dst->size; i++)
     377         256 :                 dst->data[i] = src->data[dst->size - 1 - i];
     378             : 
     379             :         return 0;
     380             : }
     381             : 
     382             : /* this is _gnutls_handshake_verify_crt_vrfy for TLS 1.2
     383             :  */
     384             : static int
     385         407 : _gnutls_handshake_verify_crt_vrfy12(gnutls_session_t session,
     386             :                                     unsigned verify_flags,
     387             :                                     gnutls_pcert_st * cert,
     388             :                                     gnutls_datum_t * signature,
     389             :                                     gnutls_sign_algorithm_t sign_algo)
     390             : {
     391         407 :         int ret;
     392         407 :         gnutls_datum_t dconcat;
     393         407 :         const gnutls_sign_entry_st *se = _gnutls_sign_to_entry(sign_algo);
     394         407 :         gnutls_datum_t sig_rev = {NULL, 0};
     395             : 
     396         407 :         ret = _gnutls_session_sign_algo_enabled(session, sign_algo);
     397         407 :         if (ret < 0)
     398           0 :                 return gnutls_assert_val(ret);
     399             : 
     400         814 :         if (unlikely(sign_supports_cert_pk_algorithm(se, cert->pubkey->params.algo) == 0)) {
     401           8 :                 _gnutls_handshake_log("HSK[%p]: certificate of %s cannot be combined with %s sig\n",
     402             :                                       session, gnutls_pk_get_name(cert->pubkey->params.algo), se->name);
     403          16 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     404             :         }
     405             : 
     406         399 :         if (se->flags & GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE) {
     407           3 :                 ret = _gnutls_create_reverse(signature, &sig_rev);
     408           3 :                 if (ret < 0)
     409           0 :                         return gnutls_assert_val(ret);
     410             :         }
     411             : 
     412         399 :         dconcat.data = session->internals.handshake_hash_buffer.data;
     413         399 :         dconcat.size = session->internals.handshake_hash_buffer_prev_len;
     414             : 
     415             :         /* Here we intentionally enable flag GNUTLS_VERIFY_ALLOW_BROKEN
     416             :          * because we have checked whether the currently used signature
     417             :          * algorithm is allowed in the session. */
     418         399 :         ret = gnutls_pubkey_verify_data2(cert->pubkey, sign_algo, verify_flags|GNUTLS_VERIFY_ALLOW_BROKEN,
     419             :                                          &dconcat,
     420         399 :                                          sig_rev.data ? &sig_rev : signature);
     421         399 :         _gnutls_free_datum(&sig_rev);
     422         399 :         if (ret < 0)
     423         226 :                 gnutls_assert();
     424             : 
     425             :         return ret;
     426             : 
     427             : }
     428             : 
     429             : /* Verifies a SSL 3.0 signature (like the one in the client certificate
     430             :  * verify message).
     431             :  */
     432             : #ifdef ENABLE_SSL3
     433             : static int
     434             : _gnutls_handshake_verify_crt_vrfy3(gnutls_session_t session,
     435             :                                    unsigned verify_flags,
     436             :                                    gnutls_pcert_st * cert,
     437             :                                    gnutls_datum_t * signature,
     438             :                                    gnutls_sign_algorithm_t sign_algo)
     439             : {
     440             :         int ret;
     441             :         uint8_t concat[MAX_SIG_SIZE];
     442             :         digest_hd_st td_sha;
     443             :         gnutls_datum_t dconcat;
     444             :         gnutls_pk_algorithm_t pk =
     445             :             gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
     446             : 
     447             :         ret = _gnutls_generate_master(session, 1);
     448             :         if (ret < 0) {
     449             :                 return gnutls_assert_val(ret);
     450             :         }
     451             : 
     452             :         dconcat.data = concat;
     453             :         dconcat.size = 0;
     454             : 
     455             :         if (pk == GNUTLS_PK_RSA) {
     456             :                 digest_hd_st td_md5;
     457             : 
     458             :                 ret = _gnutls_hash_init(&td_md5,
     459             :                                         hash_to_entry(GNUTLS_DIG_MD5));
     460             :                 if (ret < 0)
     461             :                         return gnutls_assert_val(ret);
     462             : 
     463             :                 _gnutls_hash(&td_md5,
     464             :                                 session->internals.handshake_hash_buffer.data,
     465             :                                 session->internals.handshake_hash_buffer_prev_len);
     466             : 
     467             :                 ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5, concat,
     468             :                                                 session->security_parameters.
     469             :                                                 master_secret,
     470             :                                                 GNUTLS_MASTER_SIZE);
     471             :                 if (ret < 0)
     472             :                         return gnutls_assert_val(ret);
     473             : 
     474             :                 verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
     475             :                 dconcat.size = 16;
     476             :         }
     477             : 
     478             :         ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1));
     479             :         if (ret < 0) {
     480             :                 gnutls_assert();
     481             :                 return GNUTLS_E_HASH_FAILED;
     482             :         }
     483             : 
     484             :         _gnutls_hash(&td_sha,
     485             :                      session->internals.handshake_hash_buffer.data,
     486             :                      session->internals.handshake_hash_buffer_prev_len);
     487             : 
     488             :         ret =
     489             :             _gnutls_mac_deinit_ssl3_handshake(&td_sha,
     490             :                                               dconcat.data + dconcat.size,
     491             :                                               session->security_parameters.
     492             :                                               master_secret,
     493             :                                               GNUTLS_MASTER_SIZE);
     494             :         if (ret < 0) {
     495             :                 return gnutls_assert_val(ret);
     496             :         }
     497             : 
     498             :         dconcat.size += 20;
     499             : 
     500             :         ret = gnutls_pubkey_verify_hash2(cert->pubkey, GNUTLS_SIGN_UNKNOWN,
     501             :                                          GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
     502             :                                          &dconcat, signature);
     503             :         if (ret < 0)
     504             :                 return gnutls_assert_val(ret);
     505             : 
     506             :         return ret;
     507             : }
     508             : #endif
     509             : 
     510             : static int
     511          80 : _gnutls_handshake_verify_crt_vrfy10(gnutls_session_t session,
     512             :                                     unsigned verify_flags,
     513             :                                     gnutls_pcert_st * cert,
     514             :                                     gnutls_datum_t * signature,
     515             :                                     gnutls_sign_algorithm_t sign_algo)
     516             : {
     517          80 :         int ret;
     518          80 :         uint8_t concat[MAX_SIG_SIZE];
     519          80 :         digest_hd_st td_sha;
     520          80 :         gnutls_datum_t dconcat;
     521          80 :         gnutls_pk_algorithm_t pk_algo;
     522          80 :         const mac_entry_st *me;
     523             : 
     524             :         /* TLS 1.0 and TLS 1.1 */
     525          80 :         pk_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
     526          80 :         if (pk_algo == GNUTLS_PK_RSA) {
     527          58 :                 me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
     528          58 :                 verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
     529          58 :                 sign_algo = GNUTLS_SIGN_UNKNOWN;
     530             :         } else {
     531          22 :                 me = hash_to_entry(GNUTLS_DIG_SHA1);
     532          22 :                 sign_algo = gnutls_pk_to_sign(pk_algo, GNUTLS_DIG_SHA1);
     533             :         }
     534          80 :         ret = _gnutls_hash_init(&td_sha, me);
     535          80 :         if (ret < 0) {
     536           0 :                 gnutls_assert();
     537           0 :                 return ret;
     538             :         }
     539             : 
     540         160 :         _gnutls_hash(&td_sha,
     541          80 :                      session->internals.handshake_hash_buffer.data,
     542          80 :                      session->internals.handshake_hash_buffer_prev_len);
     543             : 
     544          80 :         _gnutls_hash_deinit(&td_sha, concat);
     545             : 
     546          80 :         dconcat.data = concat;
     547          80 :         dconcat.size = _gnutls_hash_get_algo_len(me);
     548             : 
     549          80 :         ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo,
     550             :                                          GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
     551             :                                          &dconcat, signature);
     552          80 :         if (ret < 0)
     553           0 :                 gnutls_assert();
     554             : 
     555             :         return ret;
     556             : }
     557             : 
     558             : /* Verifies a TLS signature (like the one in the client certificate
     559             :  * verify message). 
     560             :  */
     561             : int
     562         488 : _gnutls_handshake_verify_crt_vrfy(gnutls_session_t session,
     563             :                                   unsigned verify_flags,
     564             :                                   gnutls_pcert_st * cert,
     565             :                                   gnutls_datum_t * signature,
     566             :                                   gnutls_sign_algorithm_t sign_algo)
     567             : {
     568         488 :         int ret;
     569         488 :         const version_entry_st *ver = get_version(session);
     570         488 :         unsigned key_usage;
     571             : 
     572         488 :         if (cert == NULL) {
     573           0 :                 gnutls_assert();
     574           0 :                 return GNUTLS_E_CERTIFICATE_ERROR;
     575             :         }
     576             : 
     577         488 :         gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
     578             : 
     579         488 :         ret = _gnutls_check_key_usage_for_sig(session, key_usage, 0);
     580         488 :         if (ret < 0)
     581           1 :                 return gnutls_assert_val(ret);
     582             : 
     583         487 :         _gnutls_handshake_log("HSK[%p]: verify cert vrfy: using %s\n",
     584             :                               session,
     585             :                               gnutls_sign_algorithm_get_name(sign_algo));
     586             : 
     587         487 :         if (unlikely(ver == NULL))
     588           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     589             : 
     590         487 :         gnutls_sign_algorithm_set_client(session, sign_algo);
     591             : 
     592             :         /* TLS 1.2 */
     593         487 :         if (_gnutls_version_has_selectable_sighash(ver))
     594         407 :                 return _gnutls_handshake_verify_crt_vrfy12(session, 
     595             :                                                            verify_flags,
     596             :                                                            cert,
     597             :                                                            signature,
     598             :                                                            sign_algo);
     599             : #ifdef ENABLE_SSL3
     600             :         if (ver->id == GNUTLS_SSL3)
     601             :                 return _gnutls_handshake_verify_crt_vrfy3(session,
     602             :                                                           verify_flags,
     603             :                                                           cert,
     604             :                                                           signature,
     605             :                                                           sign_algo);
     606             : #endif
     607             : 
     608             :         /* TLS 1.0 and TLS 1.1 */
     609          80 :         return _gnutls_handshake_verify_crt_vrfy10(session,
     610             :                                                    verify_flags,
     611             :                                                    cert,
     612             :                                                    signature,
     613             :                                                    sign_algo);
     614             : }
     615             : 
     616             : /* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2.
     617             :  * Returns the used signature algorithm, or a negative error code.
     618             :  */
     619             : static int
     620          73 : _gnutls_handshake_sign_crt_vrfy12(gnutls_session_t session,
     621             :                                   gnutls_pcert_st * cert,
     622             :                                   gnutls_privkey_t pkey,
     623             :                                   gnutls_datum_t * signature)
     624             : {
     625          73 :         gnutls_datum_t dconcat;
     626          73 :         gnutls_sign_algorithm_t sign_algo;
     627          73 :         const gnutls_sign_entry_st *se;
     628          73 :         int ret;
     629             : 
     630          73 :         sign_algo = _gnutls_session_get_sign_algo(session, cert, pkey, 1, GNUTLS_KX_UNKNOWN);
     631          73 :         if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
     632           1 :                 gnutls_assert();
     633           1 :                 return GNUTLS_E_UNWANTED_ALGORITHM;
     634             :         }
     635             : 
     636          72 :         se = _gnutls_sign_to_entry(sign_algo);
     637          72 :         if (se == NULL)
     638           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     639             : 
     640          72 :         gnutls_sign_algorithm_set_client(session, sign_algo);
     641             : 
     642          72 :         if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pkey->pk_algorithm) == 0))
     643           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     644             : 
     645          72 :         _gnutls_debug_log("sign handshake cert vrfy: picked %s\n",
     646             :                           gnutls_sign_algorithm_get_name(sign_algo));
     647             : 
     648          72 :         dconcat.data = session->internals.handshake_hash_buffer.data;
     649          72 :         dconcat.size = session->internals.handshake_hash_buffer.length;
     650             : 
     651          72 :         ret = gnutls_privkey_sign_data2(pkey, sign_algo,
     652             :                                         0, &dconcat, signature);
     653          72 :         if (ret < 0) {
     654           0 :                 gnutls_assert();
     655           0 :                 return ret;
     656             :         }
     657             : 
     658          72 :         if (se->flags & GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE)
     659           3 :                 _gnutls_reverse_datum(signature);
     660             : 
     661          72 :         return sign_algo;
     662             : }
     663             : 
     664             : #ifdef ENABLE_SSL3
     665             : static int
     666             : _gnutls_handshake_sign_crt_vrfy3(gnutls_session_t session,
     667             :                                  gnutls_pcert_st * cert,
     668             :                                  const version_entry_st *ver,
     669             :                                  gnutls_privkey_t pkey,
     670             :                                  gnutls_datum_t * signature)
     671             : {
     672             :         gnutls_datum_t dconcat;
     673             :         int ret;
     674             :         uint8_t concat[MAX_SIG_SIZE];
     675             :         digest_hd_st td_sha;
     676             :         gnutls_pk_algorithm_t pk =
     677             :             gnutls_privkey_get_pk_algorithm(pkey, NULL);
     678             : 
     679             :         /* ensure 1024 bit DSA keys are used */
     680             :         ret =
     681             :             _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver,
     682             :                                                GNUTLS_SIGN_UNKNOWN);
     683             :         if (ret < 0)
     684             :                 return gnutls_assert_val(ret);
     685             : 
     686             :         ret = _gnutls_generate_master(session, 1);
     687             :         if (ret < 0) {
     688             :                 gnutls_assert();
     689             :                 return ret;
     690             :         }
     691             : 
     692             :         dconcat.data = concat;
     693             :         dconcat.size = 0;
     694             : 
     695             :         if (pk == GNUTLS_PK_RSA) {
     696             :                 digest_hd_st td_md5;
     697             :                 ret =
     698             :                     _gnutls_hash_init(&td_md5,
     699             :                                       hash_to_entry(GNUTLS_DIG_MD5));
     700             :                 if (ret < 0)
     701             :                         return gnutls_assert_val(ret);
     702             : 
     703             :                 _gnutls_hash(&td_md5,
     704             :                              session->internals.handshake_hash_buffer.data,
     705             :                              session->internals.handshake_hash_buffer.
     706             :                              length);
     707             : 
     708             :                 ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5,
     709             :                                                         dconcat.data,
     710             :                                                         session->security_parameters.
     711             :                                                         master_secret,
     712             :                                                         GNUTLS_MASTER_SIZE);
     713             :                 if (ret < 0)
     714             :                         return gnutls_assert_val(ret);
     715             : 
     716             :                 dconcat.size = 16;
     717             :         }
     718             : 
     719             :         ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1));
     720             :         if (ret < 0) {
     721             :                 gnutls_assert();
     722             :                 return ret;
     723             :         }
     724             : 
     725             :         _gnutls_hash(&td_sha,
     726             :                      session->internals.handshake_hash_buffer.data,
     727             :                      session->internals.handshake_hash_buffer.length);
     728             :         ret =
     729             :                 _gnutls_mac_deinit_ssl3_handshake(&td_sha,
     730             :                                 dconcat.data + dconcat.size,
     731             :                                 session->security_parameters.
     732             :                                 master_secret,
     733             :                                 GNUTLS_MASTER_SIZE);
     734             :         if (ret < 0)
     735             :                 return gnutls_assert_val(ret);
     736             : 
     737             :         dconcat.size += 20;
     738             : 
     739             :         ret = gnutls_privkey_sign_hash(pkey, GNUTLS_DIG_SHA1,
     740             :                                        GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
     741             :                                        &dconcat, signature);
     742             :         if (ret < 0)
     743             :                 return gnutls_assert_val(ret);
     744             : 
     745             :         return GNUTLS_SIGN_UNKNOWN;
     746             : }
     747             : #endif
     748             : 
     749             : static int
     750          58 : _gnutls_handshake_sign_crt_vrfy10(gnutls_session_t session,
     751             :                                   gnutls_pcert_st * cert,
     752             :                                   const version_entry_st *ver,
     753             :                                   gnutls_privkey_t pkey,
     754             :                                   gnutls_datum_t * signature)
     755             : {
     756          58 :         gnutls_datum_t dconcat;
     757          58 :         int ret;
     758          58 :         uint8_t concat[MAX_SIG_SIZE];
     759          58 :         digest_hd_st td_sha;
     760         116 :         gnutls_pk_algorithm_t pk =
     761          58 :             gnutls_privkey_get_pk_algorithm(pkey, NULL);
     762          58 :         const mac_entry_st *me;
     763             : 
     764             :         /* ensure 1024 bit DSA keys are used */
     765          58 :         ret =
     766          58 :             _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver,
     767             :                                                GNUTLS_SIGN_UNKNOWN);
     768          58 :         if (ret < 0)
     769           2 :                 return gnutls_assert_val(ret);
     770             : 
     771          56 :         if (pk == GNUTLS_PK_RSA)
     772          49 :                 me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
     773             :         else
     774           7 :                 me = hash_to_entry(GNUTLS_DIG_SHA1);
     775             : 
     776          56 :         ret = _gnutls_hash_init(&td_sha, me);
     777          56 :         if (ret < 0) {
     778           0 :                 gnutls_assert();
     779           0 :                 return ret;
     780             :         }
     781             : 
     782         112 :         _gnutls_hash(&td_sha,
     783          56 :                      session->internals.handshake_hash_buffer.data,
     784             :                      session->internals.handshake_hash_buffer.length);
     785             : 
     786          56 :         _gnutls_hash_deinit(&td_sha, concat);
     787             : 
     788          56 :         dconcat.data = concat;
     789          56 :         dconcat.size = _gnutls_hash_get_algo_len(me);
     790             : 
     791          56 :         ret = gnutls_privkey_sign_hash(pkey, MAC_TO_DIG(me->id), GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
     792             :                                        &dconcat, signature);
     793          56 :         if (ret < 0) {
     794           0 :                 gnutls_assert();
     795           0 :                 return ret;
     796             :         }
     797             : 
     798             :         return GNUTLS_SIGN_UNKNOWN;
     799             : }
     800             : 
     801             : /* Generates a signature of all the previous sent packets in the
     802             :  * handshake procedure.
     803             :  * 20040227: now it works for SSL 3.0 as well
     804             :  * 20091031: works for TLS 1.2 too!
     805             :  *
     806             :  * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
     807             :  * For TLS1.2 returns the signature algorithm used on success, or a negative error code;
     808             :  *
     809             :  * Returns the used signature algorithm, or a negative error code.
     810             :  */
     811             : int
     812         131 : _gnutls_handshake_sign_crt_vrfy(gnutls_session_t session,
     813             :                                 gnutls_pcert_st * cert,
     814             :                                 gnutls_privkey_t pkey,
     815             :                                 gnutls_datum_t * signature)
     816             : {
     817         131 :         int ret;
     818         131 :         const version_entry_st *ver = get_version(session);
     819         131 :         unsigned key_usage = 0;
     820             : 
     821         131 :         if (unlikely(ver == NULL))
     822           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     823             : 
     824         131 :         gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
     825             : 
     826         131 :         ret = _gnutls_check_key_usage_for_sig(session, key_usage, 1);
     827         131 :         if (ret < 0)
     828           0 :                 return gnutls_assert_val(ret);
     829             : 
     830             :         /* TLS 1.2 */
     831         131 :         if (_gnutls_version_has_selectable_sighash(ver))
     832          73 :                 return _gnutls_handshake_sign_crt_vrfy12(session, cert,
     833             :                                                          pkey, signature);
     834             : 
     835             :         /* TLS 1.1 or earlier */
     836             : #ifdef ENABLE_SSL3
     837             :         if (ver->id == GNUTLS_SSL3)
     838             :                 return _gnutls_handshake_sign_crt_vrfy3(session, cert, ver,
     839             :                                                         pkey, signature);
     840             : #endif
     841             : 
     842          58 :         return _gnutls_handshake_sign_crt_vrfy10(session, cert, ver,
     843             :                                                  pkey, signature);
     844             : }

Generated by: LCOV version 1.14