LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/ext - signature.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 168 205 82.0 %
Date: 2020-10-30 04:50:48 Functions: 12 13 92.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2002-2016 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2015-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             : /* This file contains the code for the Signature Algorithms TLS extension.
      25             :  * This extension is currently gnutls specific.
      26             :  */
      27             : 
      28             : #include "gnutls_int.h"
      29             : #include "errors.h"
      30             : #include "num.h"
      31             : #include <gnutls/gnutls.h>
      32             : #include <ext/signature.h>
      33             : #include <state.h>
      34             : #include <num.h>
      35             : #include <algorithms.h>
      36             : #include <abstract_int.h>
      37             : 
      38             : /*
      39             :  * Some (all SChannel) clients fail to send proper SigAlgs due to Micro$oft crazyness.
      40             :  * Patch the extension for them.
      41             :  */
      42             : #ifdef ENABLE_GOST
      43             : #define GOST_SIG_FIXUP_SCHANNEL
      44             : #endif
      45             : 
      46             : static int _gnutls_signature_algorithm_recv_params(gnutls_session_t
      47             :                                                    session,
      48             :                                                    const uint8_t * data,
      49             :                                                    size_t data_size);
      50             : static int _gnutls_signature_algorithm_send_params(gnutls_session_t
      51             :                                                    session,
      52             :                                                    gnutls_buffer_st * extdata);
      53             : static void signature_algorithms_deinit_data(gnutls_ext_priv_data_t priv);
      54             : static int signature_algorithms_pack(gnutls_ext_priv_data_t epriv,
      55             :                                      gnutls_buffer_st * ps);
      56             : static int signature_algorithms_unpack(gnutls_buffer_st * ps,
      57             :                                        gnutls_ext_priv_data_t * _priv);
      58             : 
      59             : const hello_ext_entry_st ext_mod_sig = {
      60             :         .name = "Signature Algorithms",
      61             :         .tls_id = 13,
      62             :         .gid = GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
      63             :         .validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_CLIENT_HELLO,
      64             :         .client_parse_point = GNUTLS_EXT_TLS,
      65             :         .server_parse_point = GNUTLS_EXT_TLS,
      66             :         .recv_func = _gnutls_signature_algorithm_recv_params,
      67             :         .send_func = _gnutls_signature_algorithm_send_params,
      68             :         .pack_func = signature_algorithms_pack,
      69             :         .unpack_func = signature_algorithms_unpack,
      70             :         .deinit_func = signature_algorithms_deinit_data,
      71             :         .cannot_be_overriden = 1
      72             : };
      73             : 
      74             : typedef struct {
      75             :         /* TLS 1.2 signature algorithms */
      76             :         gnutls_sign_algorithm_t sign_algorithms[MAX_ALGOS];
      77             :         uint16_t sign_algorithms_size;
      78             : } sig_ext_st;
      79             : 
      80             : /* generates a SignatureAndHashAlgorithm structure with length as prefix
      81             :  * by using the setup priorities.
      82             :  */
      83             : int
      84        6314 : _gnutls_sign_algorithm_write_params(gnutls_session_t session,
      85             :                                     gnutls_buffer_st * extdata)
      86             : {
      87        6314 :         uint8_t *p;
      88        6314 :         unsigned int len, i;
      89        6314 :         const sign_algorithm_st *aid, *prev = NULL;
      90        6314 :         uint8_t buffer[MAX_ALGOS*2];
      91             : 
      92        6314 :         p = buffer;
      93        6314 :         len = 0;
      94             : 
      95             :         /* This generates a list of TLS signature algorithms. It has
      96             :          * limited duplicate detection, and does not add twice the same
      97             :          * AID */
      98             : 
      99      121870 :         for (i=0;i<session->internals.priorities->sigalg.size;i++) {
     100      115556 :                 aid = &session->internals.priorities->sigalg.entry[i]->aid;
     101             : 
     102      115556 :                 if (HAVE_UNKNOWN_SIGAID(aid))
     103           0 :                         continue;
     104             : 
     105      115556 :                 if (prev && prev->id[0] == aid->id[0] && prev->id[1] == aid->id[1])
     106       12390 :                         continue;
     107             : 
     108             :                 /* Ignore non-GOST sign types for CertReq */
     109      103166 :                 if (session->security_parameters.cs &&
     110       49129 :                     _gnutls_kx_is_vko_gost(session->security_parameters.cs->kx_algorithm) &&
     111         546 :                     !_sign_is_gost(session->internals.priorities->sigalg.entry[i]))
     112         494 :                         continue;
     113             : 
     114      102672 :                 _gnutls_handshake_log
     115             :                     ("EXT[%p]: sent signature algo (%d.%d) %s\n", session,
     116             :                      (int)aid->id[0], (int)aid->id[1],
     117             :                      session->internals.priorities->sigalg.entry[i]->name);
     118             : 
     119      102672 :                 len += 2;
     120      102672 :                 if (unlikely(len >= sizeof(buffer))) {
     121             :                         len -= 2;
     122             :                         break;
     123             :                 }
     124             : 
     125      102672 :                 *p = aid->id[0];
     126      102672 :                 p++;
     127      102672 :                 *p = aid->id[1];
     128      102672 :                 p++;
     129      102672 :                 prev = aid;
     130             :         }
     131             : 
     132        6314 :         return _gnutls_buffer_append_data_prefix(extdata, 16, buffer, len);
     133             : }
     134             : 
     135             : 
     136             : /* Parses the Signature Algorithm structure and stores data into
     137             :  * session->security_parameters.extensions.
     138             :  */
     139             : int
     140       13950 : _gnutls_sign_algorithm_parse_data(gnutls_session_t session,
     141             :                                   const uint8_t * data, size_t data_size)
     142             : {
     143       13950 :         unsigned int sig, i;
     144       13950 :         sig_ext_st *priv;
     145       13950 :         gnutls_ext_priv_data_t epriv;
     146       13950 :         const version_entry_st *ver = get_version(session);
     147             : 
     148       13950 :         if (data_size == 0 || data_size % 2 != 0)
     149           9 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     150             : 
     151       13944 :         if (ver == NULL) { /* assume TLS 1.2 semantics */
     152           0 :                 ver = version_to_entry(GNUTLS_TLS1_2);
     153           0 :                 if (unlikely(ver == NULL)) {
     154           0 :                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     155             :                 }
     156             :         }
     157             : 
     158       13944 :         priv = gnutls_calloc(1, sizeof(*priv));
     159       13944 :         if (priv == NULL) {
     160           0 :                 gnutls_assert();
     161           0 :                 return GNUTLS_E_MEMORY_ERROR;
     162             :         }
     163             : 
     164      284017 :         for (i = 0; i < data_size; i += 2) {
     165      270076 :                 uint8_t id[2];
     166             : 
     167      270076 :                 id[0] = data[i];
     168      270076 :                 id[1] = data[i + 1];
     169             : 
     170      270076 :                 sig = _gnutls_tls_aid_to_sign(id[0], id[1], ver);
     171             : 
     172      270076 :                 _gnutls_handshake_log
     173             :                     ("EXT[%p]: rcvd signature algo (%d.%d) %s\n", session,
     174             :                      (int)id[0], (int)id[1],
     175             :                      gnutls_sign_get_name(sig));
     176             : 
     177      270076 :                 if (sig != GNUTLS_SIGN_UNKNOWN) {
     178      139817 :                         if (priv->sign_algorithms_size == MAX_ALGOS)
     179             :                                 break;
     180      139814 :                         priv->sign_algorithms[priv->
     181      139814 :                                               sign_algorithms_size++] = sig;
     182             :                 }
     183             :         }
     184             : 
     185       13944 :         epriv = priv;
     186       13944 :         _gnutls_hello_ext_set_priv(session,
     187             :                                      GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
     188             :                                      epriv);
     189             : 
     190       13944 :         return 0;
     191             : }
     192             : 
     193             : /*
     194             :  * In case of a server: if a SIGNATURE_ALGORITHMS extension type is
     195             :  * received then it stores into the session security parameters the
     196             :  * new value.
     197             :  *
     198             :  * In case of a client: If a signature_algorithms have been specified
     199             :  * then it is an error;
     200             :  */
     201             : 
     202             : static int
     203       13825 : _gnutls_signature_algorithm_recv_params(gnutls_session_t session,
     204             :                                         const uint8_t * data,
     205             :                                         size_t data_size)
     206             : {
     207       13825 :         int ret;
     208             : 
     209       13825 :         if (session->security_parameters.entity == GNUTLS_CLIENT) {
     210             :                 /* nothing for now */
     211           0 :                 gnutls_assert();
     212             :                 /* Although TLS 1.2 mandates that we must not accept reply
     213             :                  * to this message, there are good reasons to just ignore it. Check
     214             :                  * https://www.ietf.org/mail-archive/web/tls/current/msg03880.html
     215             :                  */
     216             :                 /* return GNUTLS_E_UNEXPECTED_PACKET; */
     217             :         } else {
     218             :                 /* SERVER SIDE
     219             :                  */
     220       13825 :                 if (data_size >= 2) {
     221       13822 :                         uint16_t len;
     222             : 
     223       13822 :                         DECR_LEN(data_size, 2);
     224       13822 :                         len = _gnutls_read_uint16(data);
     225       13822 :                         DECR_LEN(data_size, len);
     226             : 
     227       13465 :                         if (data_size > 0)
     228          19 :                                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     229             : 
     230       13454 :                         ret =
     231       13454 :                             _gnutls_sign_algorithm_parse_data(session,
     232             :                                                               data + 2,
     233             :                                                               len);
     234       13454 :                         if (ret < 0) {
     235           6 :                                 gnutls_assert();
     236           6 :                                 return ret;
     237             :                         }
     238             :                 } else {
     239           3 :                         return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     240             :                 }
     241             :         }
     242             : 
     243             :         return 0;
     244             : }
     245             : 
     246             : /* returns data_size or a negative number on failure
     247             :  */
     248             : static int
     249        3784 : _gnutls_signature_algorithm_send_params(gnutls_session_t session,
     250             :                                         gnutls_buffer_st * extdata)
     251             : {
     252        3784 :         int ret;
     253        3784 :         size_t init_length = extdata->length;
     254        3784 :         const version_entry_st *ver = get_version(session);
     255             : 
     256        3784 :         if (unlikely(ver == NULL))
     257           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     258             : 
     259             :         /* this function sends the client extension data */
     260        3784 :         if (session->security_parameters.entity == GNUTLS_CLIENT
     261        3784 :             && _gnutls_version_has_selectable_sighash(ver)) {
     262        3476 :                 if (session->internals.priorities->sigalg.size > 0) {
     263        3476 :                         ret =
     264        3476 :                             _gnutls_sign_algorithm_write_params(session, extdata);
     265        3476 :                         if (ret < 0)
     266           0 :                                 return gnutls_assert_val(ret);
     267             : 
     268        3476 :                         return extdata->length - init_length;
     269             :                 }
     270             :         }
     271             : 
     272             :         /* if we are here it means we don't send the extension */
     273             :         return 0;
     274             : }
     275             : 
     276             : #ifdef GOST_SIG_FIXUP_SCHANNEL
     277             : static bool
     278          37 : is_gost_sig_present(sig_ext_st *priv)
     279             : {
     280          37 :         unsigned i;
     281          37 :         const gnutls_sign_entry_st *se;
     282             : 
     283         599 :         for (i = 0; i < priv->sign_algorithms_size; i++) {
     284         597 :                 se = _gnutls_sign_to_entry(priv->sign_algorithms[i]);
     285         597 :                 if (se != NULL && _sign_is_gost(se))
     286             :                         return true;
     287             :         }
     288             : 
     289             :         return false;
     290             : }
     291             : #endif
     292             : 
     293             : /* Returns a requested by the peer signature algorithm that
     294             :  * matches the given certificate's public key algorithm.
     295             :  *
     296             :  * When the @client_cert flag is not set, then this function will
     297             :  * also check whether the signature algorithm is allowed to be
     298             :  * used in that session. Otherwise GNUTLS_SIGN_UNKNOWN is
     299             :  * returned.
     300             :  */
     301             : gnutls_sign_algorithm_t
     302       12624 : _gnutls_session_get_sign_algo(gnutls_session_t session,
     303             :                               gnutls_pcert_st * cert,
     304             :                               gnutls_privkey_t privkey,
     305             :                               unsigned client_cert,
     306             :                               gnutls_kx_algorithm_t kx_algorithm)
     307             : {
     308       12624 :         unsigned i;
     309       12624 :         int ret;
     310       12624 :         const version_entry_st *ver = get_version(session);
     311       12624 :         sig_ext_st *priv;
     312       12624 :         gnutls_ext_priv_data_t epriv;
     313       12624 :         unsigned int cert_algo;
     314       12624 :         const gnutls_sign_entry_st *se;
     315             : 
     316       12624 :         if (unlikely(ver == NULL))
     317           0 :                 return gnutls_assert_val(GNUTLS_SIGN_UNKNOWN);
     318             : 
     319       12624 :         cert_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
     320             : 
     321       12624 :         ret =
     322       12624 :             _gnutls_hello_ext_get_priv(session,
     323             :                                         GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
     324             :                                         &epriv);
     325       12624 :         if (ret < 0)
     326             :                 priv = NULL;
     327             :         else
     328       12010 :                 priv = epriv;
     329             : 
     330             : #ifdef GOST_SIG_FIXUP_SCHANNEL
     331             :         /*
     332             :          * Some (all SChannel) clients fail to send proper SigAlgs due to Micro$oft crazyness.
     333             :          * If we are negotiating GOST KX (because we have received GOST
     334             :          * ciphersuites) and if we have received no GOST SignatureAlgorithms,
     335             :          * assume that the client could not send them and continue negotiation
     336             :          * as if correct algorithm was sent.
     337             :          */
     338       12624 :         if (_gnutls_kx_is_vko_gost(kx_algorithm) &&
     339          37 :             (!priv ||
     340          37 :              !is_gost_sig_present(priv) ||
     341          35 :              !_gnutls_version_has_selectable_sighash(ver))) {
     342           2 :                 gnutls_digest_algorithm_t dig;
     343             : 
     344           2 :                 _gnutls_handshake_log("EXT[%p]: GOST KX, but no GOST SigAlgs received, patching up.", session);
     345             : 
     346           2 :                 if (cert_algo == GNUTLS_PK_GOST_01)
     347             :                         dig = GNUTLS_DIG_GOSTR_94;
     348           2 :                 else if (cert_algo == GNUTLS_PK_GOST_12_256)
     349             :                         dig = GNUTLS_DIG_STREEBOG_256;
     350           1 :                 else if (cert_algo == GNUTLS_PK_GOST_12_512)
     351             :                         dig = GNUTLS_DIG_STREEBOG_512;
     352             :                 else
     353           0 :                         dig = GNUTLS_DIG_SHA1;
     354             : 
     355           2 :                 ret = gnutls_pk_to_sign(cert_algo, dig);
     356             : 
     357           2 :                 if (!client_cert && _gnutls_session_sign_algo_enabled(session, ret) < 0)
     358           0 :                         goto fail;
     359           2 :                 return ret;
     360             :         }
     361             : #endif
     362             : 
     363       12622 :         if (!priv || !_gnutls_version_has_selectable_sighash(ver)) {
     364             :                 /* none set, allow SHA-1 only */
     365         614 :                 ret = gnutls_pk_to_sign(cert_algo, GNUTLS_DIG_SHA1);
     366             : 
     367         614 :                 if (!client_cert && _gnutls_session_sign_algo_enabled(session, ret) < 0)
     368          20 :                         goto fail;
     369         594 :                 return ret;
     370             :         }
     371             : 
     372             : 
     373             : 
     374       30755 :         for (i = 0; i < priv->sign_algorithms_size; i++) {
     375       28234 :                 se = _gnutls_sign_to_entry(priv->sign_algorithms[i]);
     376       28234 :                 if (se == NULL)
     377           0 :                         continue;
     378             : 
     379       28234 :                 _gnutls_handshake_log("checking cert compat with %s\n", se->name);
     380             : 
     381       28234 :                 if (_gnutls_privkey_compatible_with_sig(privkey, priv->sign_algorithms[i]) == 0)
     382        9631 :                         continue;
     383             : 
     384       37350 :                 if (sign_supports_cert_pk_algorithm(se, cert_algo) != 0) {
     385       10771 :                         if (_gnutls_pubkey_compatible_with_sig
     386             :                             (session, cert->pubkey, ver, se->id) < 0)
     387          68 :                                 continue;
     388             : 
     389       10703 :                         if (_gnutls_session_sign_algo_enabled
     390             :                             (session, se->id) < 0)
     391        1216 :                                 continue;
     392             : 
     393        9487 :                         return se->id;
     394             :                 }
     395             :         }
     396             : 
     397             :         /* When having a legacy client certificate which can only be signed
     398             :          * using algorithms we don't always enable by default (e.g., DSA-SHA1),
     399             :          * continue and sign with it. */
     400        2521 :         if (client_cert) {
     401           1 :                 _gnutls_audit_log(session, "No shared signature schemes with peer for client certificate (%s). Is the certificate a legacy one?\n",
     402             :                                   gnutls_pk_get_name(cert_algo));
     403             :         }
     404             : 
     405        2520 :  fail:
     406             :         return GNUTLS_SIGN_UNKNOWN;
     407             : }
     408             : 
     409             : /* Check if the given signature algorithm is supported.
     410             :  * This means that it is enabled by the priority functions,
     411             :  * and in case of a server a matching certificate exists.
     412             :  */
     413             : int
     414       13756 : _gnutls_session_sign_algo_enabled(gnutls_session_t session,
     415             :                                   gnutls_sign_algorithm_t sig)
     416             : {
     417       13756 :         unsigned i;
     418       13756 :         const version_entry_st *ver = get_version(session);
     419             : 
     420       13756 :         if (unlikely(ver == NULL))
     421           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     422             : 
     423       13756 :         if (!_gnutls_version_has_selectable_sighash(ver)) {
     424             :                 return 0;
     425             :         }
     426             : 
     427       13676 :         if (ver->tls13_sem) {
     428             :                 /* disallow RSA, DSA, and SHA1 */
     429        9534 :                 const gnutls_sign_entry_st *se;
     430             : 
     431        9534 :                 se = _gnutls_sign_to_entry(sig);
     432        9534 :                 if (se == NULL || (se->flags & GNUTLS_SIGN_FLAG_TLS13_OK) == 0) {
     433        1231 :                         gnutls_assert();
     434        1231 :                         goto disallowed;
     435             :                 }
     436             :         }
     437             : 
     438       40372 :         for (i = 0; i < session->internals.priorities->sigalg.size; i++) {
     439       40367 :                 if (session->internals.priorities->sigalg.entry[i]->id == sig) {
     440             :                         return 0;       /* ok */
     441             :                 }
     442             :         }
     443             : 
     444           5 :  disallowed:
     445        1236 :         _gnutls_handshake_log("Signature algorithm %s is not enabled\n", gnutls_sign_algorithm_get_name(sig));
     446             :         return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
     447             : }
     448             : 
     449       15070 : static void signature_algorithms_deinit_data(gnutls_ext_priv_data_t priv)
     450             : {
     451       15070 :         gnutls_free(priv);
     452       15070 : }
     453             : 
     454             : static int
     455        4084 : signature_algorithms_pack(gnutls_ext_priv_data_t epriv,
     456             :                           gnutls_buffer_st * ps)
     457             : {
     458        4084 :         sig_ext_st *priv = epriv;
     459        4084 :         int ret, i;
     460             : 
     461        4084 :         BUFFER_APPEND_NUM(ps, priv->sign_algorithms_size);
     462       62505 :         for (i = 0; i < priv->sign_algorithms_size; i++) {
     463       58421 :                 BUFFER_APPEND_NUM(ps, priv->sign_algorithms[i]);
     464             :         }
     465             :         return 0;
     466             : }
     467             : 
     468             : static int
     469        1170 : signature_algorithms_unpack(gnutls_buffer_st * ps,
     470             :                             gnutls_ext_priv_data_t * _priv)
     471             : {
     472        1170 :         sig_ext_st *priv;
     473        1170 :         int i, ret;
     474        1170 :         gnutls_ext_priv_data_t epriv;
     475             : 
     476        1170 :         priv = gnutls_calloc(1, sizeof(*priv));
     477        1170 :         if (priv == NULL) {
     478           0 :                 gnutls_assert();
     479           0 :                 return GNUTLS_E_MEMORY_ERROR;
     480             :         }
     481             : 
     482        1170 :         BUFFER_POP_NUM(ps, priv->sign_algorithms_size);
     483       19916 :         for (i = 0; i < priv->sign_algorithms_size; i++) {
     484       18746 :                 BUFFER_POP_NUM(ps, priv->sign_algorithms[i]);
     485             :         }
     486             : 
     487        1170 :         epriv = priv;
     488        1170 :         *_priv = epriv;
     489             : 
     490        1170 :         return 0;
     491             : 
     492           0 :       error:
     493           0 :         gnutls_free(priv);
     494           0 :         return ret;
     495             : }
     496             : 
     497             : 
     498             : 
     499             : /**
     500             :  * gnutls_sign_algorithm_get_requested:
     501             :  * @session: is a #gnutls_session_t type.
     502             :  * @indx: is an index of the signature algorithm to return
     503             :  * @algo: the returned certificate type will be stored there
     504             :  *
     505             :  * Returns the signature algorithm specified by index that was
     506             :  * requested by the peer. If the specified index has no data available
     507             :  * this function returns %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.  If
     508             :  * the negotiated TLS version does not support signature algorithms
     509             :  * then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned even
     510             :  * for the first index.  The first index is 0.
     511             :  *
     512             :  * This function is useful in the certificate callback functions
     513             :  * to assist in selecting the correct certificate.
     514             :  *
     515             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
     516             :  *   an error code is returned.
     517             :  *
     518             :  * Since: 2.10.0
     519             :  **/
     520             : int
     521           0 : gnutls_sign_algorithm_get_requested(gnutls_session_t session,
     522             :                                     size_t indx,
     523             :                                     gnutls_sign_algorithm_t * algo)
     524             : {
     525           0 :         const version_entry_st *ver = get_version(session);
     526           0 :         sig_ext_st *priv;
     527           0 :         gnutls_ext_priv_data_t epriv;
     528           0 :         int ret;
     529             : 
     530           0 :         if (unlikely(ver == NULL))
     531           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     532             : 
     533           0 :         ret =
     534           0 :             _gnutls_hello_ext_get_priv(session,
     535             :                                         GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
     536             :                                         &epriv);
     537           0 :         if (ret < 0) {
     538           0 :                 gnutls_assert();
     539           0 :                 return ret;
     540             :         }
     541           0 :         priv = epriv;
     542             : 
     543           0 :         if (!_gnutls_version_has_selectable_sighash(ver)
     544           0 :             || priv->sign_algorithms_size == 0) {
     545             :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     546             :         }
     547             : 
     548           0 :         if (indx < priv->sign_algorithms_size) {
     549           0 :                 *algo = priv->sign_algorithms[indx];
     550           0 :                 return 0;
     551             :         } else
     552             :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     553             : }
     554             : 
     555             : /**
     556             :  * gnutls_sign_algorithm_get:
     557             :  * @session: is a #gnutls_session_t type.
     558             :  *
     559             :  * Returns the signature algorithm that is (or will be) used in this
     560             :  * session by the server to sign data. This function should be
     561             :  * used only with TLS 1.2 or later.
     562             :  *
     563             :  * Returns: The sign algorithm or %GNUTLS_SIGN_UNKNOWN.
     564             :  *
     565             :  * Since: 3.1.1
     566             :  **/
     567       24522 : int gnutls_sign_algorithm_get(gnutls_session_t session)
     568             : {
     569       24522 :         return session->security_parameters.server_sign_algo;
     570             : }
     571             : 
     572             : /**
     573             :  * gnutls_sign_algorithm_get_client:
     574             :  * @session: is a #gnutls_session_t type.
     575             :  *
     576             :  * Returns the signature algorithm that is (or will be) used in this
     577             :  * session by the client to sign data. This function should be
     578             :  * used only with TLS 1.2 or later.
     579             :  *
     580             :  * Returns: The sign algorithm or %GNUTLS_SIGN_UNKNOWN.
     581             :  *
     582             :  * Since: 3.1.11
     583             :  **/
     584        6419 : int gnutls_sign_algorithm_get_client(gnutls_session_t session)
     585             : {
     586        6419 :         return session->security_parameters.client_sign_algo;
     587             : }

Generated by: LCOV version 1.14