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

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2017-2019 Red Hat, Inc.
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : #include "gnutls_int.h"
      24             : #include "errors.h"
      25             : #include <auth/cert.h>
      26             : #include <algorithms.h>
      27             : #include <ext/signature.h>
      28             : #include <abstract_int.h>
      29             : #include "tls13-sig.h"
      30             : #include "tls-sig.h"
      31             : #include "hash_int.h"
      32             : 
      33             : #undef PREFIX_SIZE
      34             : #define PREFIX_SIZE 64
      35             : #if PREFIX_SIZE < MAX_HASH_SIZE
      36             : /* we assume later that prefix is sufficient to store hash output */
      37             : # error Need to modify code
      38             : #endif
      39             : 
      40             : int
      41         568 : _gnutls13_handshake_verify_data(gnutls_session_t session,
      42             :                               unsigned verify_flags,
      43             :                               gnutls_pcert_st *cert,
      44             :                               const gnutls_datum_t *context,
      45             :                               const gnutls_datum_t *signature,
      46             :                               const gnutls_sign_entry_st *se)
      47             : {
      48         568 :         int ret;
      49         568 :         const version_entry_st *ver = get_version(session);
      50         568 :         gnutls_buffer_st buf;
      51         568 :         uint8_t prefix[PREFIX_SIZE];
      52         568 :         unsigned key_usage = 0;
      53         568 :         gnutls_datum_t p;
      54             : 
      55         568 :         _gnutls_handshake_log
      56             :             ("HSK[%p]: verifying TLS 1.3 handshake data using %s\n", session,
      57             :              se->name);
      58             : 
      59         568 :         ret =
      60         568 :             _gnutls_pubkey_compatible_with_sig(session,
      61             :                                                cert->pubkey, ver,
      62             :                                                se->id);
      63         568 :         if (ret < 0)
      64           0 :                 return gnutls_assert_val(ret);
      65             : 
      66        1136 :         if (unlikely(sign_supports_cert_pk_algorithm(se, cert->pubkey->params.algo) == 0)) {
      67           0 :                 _gnutls_handshake_log("HSK[%p]: certificate of %s cannot be combined with %s sig\n",
      68             :                                       session, gnutls_pk_get_name(cert->pubkey->params.algo), se->name);
      69           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
      70             :         }
      71             : 
      72         568 :         ret =
      73         568 :             _gnutls_session_sign_algo_enabled(session, se->id);
      74         568 :         if (ret < 0)
      75           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
      76             : 
      77         568 :         if ((se->flags & GNUTLS_SIGN_FLAG_TLS13_OK) == 0) /* explicitly prohibited */
      78           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
      79             : 
      80         568 :         gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
      81             : 
      82         568 :         ret = _gnutls_check_key_usage_for_sig(session, key_usage, 0);
      83         568 :         if (ret < 0)
      84           2 :                 return gnutls_assert_val(ret);
      85             : 
      86         566 :         _gnutls_buffer_init(&buf);
      87             : 
      88         566 :         memset(prefix, 0x20, sizeof(prefix));
      89         566 :         ret = _gnutls_buffer_append_data(&buf, prefix, sizeof(prefix));
      90         566 :         if (ret < 0) {
      91           0 :                 gnutls_assert();
      92           0 :                 goto cleanup;
      93             :         }
      94             : 
      95         566 :         ret = _gnutls_buffer_append_data(&buf, context->data, context->size);
      96         566 :         if (ret < 0) {
      97           0 :                 gnutls_assert();
      98           0 :                 goto cleanup;
      99             :         }
     100             : 
     101         566 :         ret = _gnutls_buffer_append_data(&buf, "\x00", 1);
     102         566 :         if (ret < 0) {
     103           0 :                 gnutls_assert();
     104           0 :                 goto cleanup;
     105             :         }
     106             : 
     107         566 :         ret = gnutls_hash_fast(MAC_TO_DIG(session->security_parameters.prf->id),
     108         566 :                                session->internals.handshake_hash_buffer.data,
     109         566 :                                session->internals.handshake_hash_buffer_prev_len,
     110             :                                prefix);
     111         566 :         if (ret < 0) {
     112           0 :                 gnutls_assert();
     113           0 :                 goto cleanup;
     114             :         }
     115             : 
     116         566 :         ret = _gnutls_buffer_append_data(&buf, prefix, session->security_parameters.prf->output_size);
     117         566 :         if (ret < 0) {
     118           0 :                 gnutls_assert();
     119           0 :                 goto cleanup;
     120             :         }
     121             : 
     122         566 :         p.data = buf.data;
     123         566 :         p.size = buf.length;
     124             : 
     125             :         /* Here we intentionally enable flag GNUTLS_VERIFY_ALLOW_BROKEN
     126             :          * because we have checked whether the currently used signature
     127             :          * algorithm is allowed in the session. */
     128         566 :         ret = gnutls_pubkey_verify_data2(cert->pubkey, se->id,
     129             :                                          verify_flags|GNUTLS_VERIFY_ALLOW_BROKEN,
     130             :                                          &p, signature);
     131         566 :         if (ret < 0) {
     132           0 :                 gnutls_assert();
     133           0 :                 goto cleanup;
     134             :         }
     135             : 
     136             :         ret = 0;
     137         566 :  cleanup:
     138         566 :         _gnutls_buffer_clear(&buf);
     139             : 
     140         566 :         return ret;
     141             : }
     142             : 
     143             : int
     144        3760 : _gnutls13_handshake_sign_data(gnutls_session_t session,
     145             :                               gnutls_pcert_st * cert, gnutls_privkey_t pkey,
     146             :                               const gnutls_datum_t *context,
     147             :                               gnutls_datum_t * signature,
     148             :                               const gnutls_sign_entry_st *se)
     149             : {
     150        3760 :         gnutls_datum_t p;
     151        3760 :         int ret;
     152        3760 :         gnutls_buffer_st buf;
     153        3760 :         uint8_t tmp[MAX_HASH_SIZE];
     154             : 
     155        3760 :         if (unlikely(se == NULL || (se->flags & GNUTLS_SIGN_FLAG_TLS13_OK) == 0))
     156           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     157             : 
     158        7520 :         if (unlikely(sign_supports_priv_pk_algorithm(se, pkey->pk_algorithm) == 0))
     159           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     160             : 
     161             :         /* when we reach here we know we have a signing certificate */
     162        3760 :         _gnutls_handshake_log
     163             :             ("HSK[%p]: signing TLS 1.3 handshake data: using %s and PRF: %s\n", session, se->name,
     164             :              session->security_parameters.prf->name);
     165             : 
     166        3760 :         _gnutls_buffer_init(&buf);
     167             : 
     168        3760 :         ret = _gnutls_buffer_resize(&buf, PREFIX_SIZE);
     169        3760 :         if (ret < 0) {
     170           0 :                 gnutls_assert();
     171           0 :                 goto cleanup;
     172             :         }
     173             : 
     174        3760 :         memset(buf.data, 0x20, PREFIX_SIZE);
     175        3760 :         buf.length += PREFIX_SIZE;
     176             : 
     177        3760 :         ret = _gnutls_buffer_append_data(&buf, context->data, context->size);
     178        3760 :         if (ret < 0) {
     179           0 :                 gnutls_assert();
     180           0 :                 goto cleanup;
     181             :         }
     182             : 
     183        3760 :         ret = _gnutls_buffer_append_data(&buf, "\x00", 1);
     184        3760 :         if (ret < 0) {
     185           0 :                 gnutls_assert();
     186           0 :                 goto cleanup;
     187             :         }
     188             : 
     189        3760 :         ret = gnutls_hash_fast(MAC_TO_DIG(session->security_parameters.prf->id),
     190        3760 :                                session->internals.handshake_hash_buffer.data,
     191             :                                session->internals.handshake_hash_buffer.length,
     192             :                                tmp);
     193        3760 :         if (ret < 0) {
     194           0 :                 gnutls_assert();
     195           0 :                 goto cleanup;
     196             :         }
     197             : 
     198        3760 :         ret = _gnutls_buffer_append_data(&buf, tmp, session->security_parameters.prf->output_size);
     199        3760 :         if (ret < 0) {
     200           0 :                 gnutls_assert();
     201           0 :                 goto cleanup;
     202             :         }
     203             : 
     204        3760 :         p.data = buf.data;
     205        3760 :         p.size = buf.length;
     206             : 
     207        3760 :         ret = gnutls_privkey_sign_data2(pkey, se->id, 0, &p, signature);
     208        3760 :         if (ret < 0) {
     209           0 :                 gnutls_assert();
     210           0 :                 goto cleanup;
     211             :         }
     212             : 
     213             :         ret = 0;
     214        3760 :  cleanup:
     215        3760 :         _gnutls_buffer_clear(&buf);
     216             : 
     217        3760 :         return ret;
     218             : 
     219             : }

Generated by: LCOV version 1.14