LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - cert-session.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 233 295 79.0 %
Date: 2020-10-30 04:50:48 Functions: 17 18 94.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2001-2015 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2015 Nikos Mavrogiannopoulos
       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 certificate authentication functions to be exported in the
      25             :  * API which did not fit elsewhere.
      26             :  */
      27             : 
      28             : #include "gnutls_int.h"
      29             : #include <auth/srp_kx.h>
      30             : #include <auth/anon.h>
      31             : #include <auth/cert.h>
      32             : #include <auth/psk.h>
      33             : #include "errors.h"
      34             : #include <auth.h>
      35             : #include <state.h>
      36             : #include <datum.h>
      37             : #include <algorithms.h>
      38             : #include <gnutls/ocsp.h>
      39             : #include "x509.h"
      40             : #include "hello_ext.h"
      41             : #include "x509/ocsp.h"
      42             : 
      43             : /**
      44             :  * gnutls_certificate_get_ours:
      45             :  * @session: is a gnutls session
      46             :  *
      47             :  * Gets the certificate as sent to the peer in the last handshake.
      48             :  * The certificate is in raw (DER) format.  No certificate
      49             :  * list is being returned. Only the first certificate.
      50             :  *
      51             :  * This function returns the certificate that was sent in the current
      52             :  * handshake. In subsequent resumed sessions this function will return
      53             :  * %NULL. That differs from gnutls_certificate_get_peers() which always
      54             :  * returns the peer's certificate used in the original session.
      55             :  *
      56             :  * Returns: a pointer to a #gnutls_datum_t containing our
      57             :  *   certificate, or %NULL in case of an error or if no certificate
      58             :  *   was used.
      59             :  **/
      60         579 : const gnutls_datum_t *gnutls_certificate_get_ours(gnutls_session_t session)
      61             : {
      62         579 :         gnutls_certificate_credentials_t cred;
      63             : 
      64         579 :         CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, NULL);
      65             : 
      66         579 :         cred = (gnutls_certificate_credentials_t)
      67         579 :             _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
      68         579 :         if (cred == NULL) {
      69           0 :                 gnutls_assert();
      70           0 :                 return NULL;
      71             :         }
      72             : 
      73         579 :         if (session->internals.selected_cert_list == NULL)
      74             :                 return NULL;
      75             : 
      76         264 :         return &session->internals.selected_cert_list[0].cert;
      77             : }
      78             : 
      79             : /**
      80             :  * gnutls_certificate_get_peers:
      81             :  * @session: is a gnutls session
      82             :  * @list_size: is the length of the certificate list (may be %NULL)
      83             :  *
      84             :  * Get the peer's raw certificate (chain) as sent by the peer.  These
      85             :  * certificates are in raw format (DER encoded for X.509).  In case of
      86             :  * a X.509 then a certificate list may be present.  The list
      87             :  * is provided as sent by the server; the server must send as first
      88             :  * certificate in the list its own certificate, following the
      89             :  * issuer's certificate, then the issuer's issuer etc. However, there
      90             :  * are servers which violate this principle and thus on certain
      91             :  * occasions this may be an unsorted list.
      92             :  *
      93             :  * In resumed sessions, this function will return the peer's certificate
      94             :  * list as used in the first/original session.
      95             :  *
      96             :  * Returns: a pointer to a #gnutls_datum_t containing the peer's
      97             :  *   certificates, or %NULL in case of an error or if no certificate
      98             :  *   was used.
      99             :  **/
     100        7225 : const gnutls_datum_t *gnutls_certificate_get_peers(gnutls_session_t
     101             :                                                    session,
     102             :                                                    unsigned int *list_size)
     103             : {
     104        7225 :         cert_auth_info_t info;
     105             : 
     106        7225 :         CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, NULL);
     107             : 
     108        7209 :         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
     109        3092 :         if (info == NULL)
     110             :                 return NULL;
     111             : 
     112        3092 :         if (list_size)
     113        3092 :                 *list_size = info->ncerts;
     114        3092 :         return info->raw_certificate_list;
     115             : }
     116             : 
     117             : /**
     118             :  * gnutls_certificate_client_get_request_status:
     119             :  * @session: is a gnutls session
     120             :  *
     121             :  * Get whether client certificate was requested on the last
     122             :  * handshake or not.
     123             :  *
     124             :  * Returns: 0 if the peer (server) did not request client
     125             :  *   authentication or 1 otherwise.
     126             :  **/
     127             : unsigned
     128        5830 : gnutls_certificate_client_get_request_status(gnutls_session_t session)
     129             : {
     130        5830 :         return (session->internals.hsk_flags & HSK_CRT_ASKED)?1:0;
     131             : }
     132             : 
     133             : /**
     134             :  * gnutls_certificate_set_params_function:
     135             :  * @res: is a gnutls_certificate_credentials_t type
     136             :  * @func: is the function to be called
     137             :  *
     138             :  * This function will set a callback in order for the server to get
     139             :  * the Diffie-Hellman or RSA parameters for certificate
     140             :  * authentication.  The callback should return %GNUTLS_E_SUCCESS (0) on success.
     141             :  *
     142             :  * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
     143             :  * or later. Since 3.6.0, DH parameters are negotiated
     144             :  * following RFC7919.
     145             :  *
     146             :  **/
     147             : void
     148         100 : gnutls_certificate_set_params_function(gnutls_certificate_credentials_t
     149             :                                        res, gnutls_params_function * func)
     150             : {
     151         100 :         res->params_func = func;
     152         100 : }
     153             : 
     154             : /**
     155             :  * gnutls_certificate_set_flags:
     156             :  * @res: is a gnutls_certificate_credentials_t type
     157             :  * @flags: are the flags of #gnutls_certificate_flags type
     158             :  *
     159             :  * This function will set flags to tweak the operation of
     160             :  * the credentials structure. See the #gnutls_certificate_flags enumerations
     161             :  * for more information on the available flags. 
     162             :  *
     163             :  * Since: 3.4.7
     164             :  **/
     165             : void
     166         302 : gnutls_certificate_set_flags(gnutls_certificate_credentials_t res,
     167             :                              unsigned int flags)
     168             : {
     169         302 :         res->flags = flags;
     170         302 : }
     171             : 
     172             : /**
     173             :  * gnutls_certificate_set_verify_flags:
     174             :  * @res: is a gnutls_certificate_credentials_t type
     175             :  * @flags: are the flags
     176             :  *
     177             :  * This function will set the flags to be used for verification 
     178             :  * of certificates and override any defaults.  The provided flags must be an OR of the
     179             :  * #gnutls_certificate_verify_flags enumerations. 
     180             :  *
     181             :  **/
     182             : void
     183         285 : gnutls_certificate_set_verify_flags(gnutls_certificate_credentials_t
     184             :                                     res, unsigned int flags)
     185             : {
     186         285 :         res->verify_flags = flags;
     187         285 : }
     188             : 
     189             : /**
     190             :  * gnutls_certificate_get_verify_flags:
     191             :  * @res: is a gnutls_certificate_credentials_t type
     192             :  *
     193             :  * Returns the verification flags set with
     194             :  * gnutls_certificate_set_verify_flags().
     195             :  *
     196             :  * Returns: The certificate verification flags used by @res.
     197             :  *
     198             :  * Since: 3.4.0
     199             :  */
     200             : unsigned int
     201           5 : gnutls_certificate_get_verify_flags(gnutls_certificate_credentials_t res)
     202             : {
     203           5 :         return res->verify_flags;
     204             : }
     205             : 
     206             : /**
     207             :  * gnutls_certificate_set_verify_limits:
     208             :  * @res: is a gnutls_certificate_credentials type
     209             :  * @max_bits: is the number of bits of an acceptable certificate (default 8200)
     210             :  * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
     211             :  *
     212             :  * This function will set some upper limits for the default
     213             :  * verification function, gnutls_certificate_verify_peers2(), to avoid
     214             :  * denial of service attacks.  You can set them to zero to disable
     215             :  * limits.
     216             :  **/
     217             : void
     218           0 : gnutls_certificate_set_verify_limits(gnutls_certificate_credentials_t res,
     219             :                                      unsigned int max_bits,
     220             :                                      unsigned int max_depth)
     221             : {
     222           0 :         res->verify_depth = max_depth;
     223           0 :         res->verify_bits = max_bits;
     224           0 : }
     225             : 
     226             : #ifdef ENABLE_OCSP
     227             : static int
     228             : _gnutls_ocsp_verify_mandatory_stapling(gnutls_session_t session,
     229             :                                        gnutls_x509_crt_t cert,
     230             :                                        unsigned int * ocsp_status);
     231             : 
     232             : /* If the certificate is revoked status will be GNUTLS_CERT_REVOKED.
     233             :  * 
     234             :  * Returns:
     235             :  *  Zero on success, a negative error code otherwise.
     236             :  */
     237             : static int
     238          40 : check_ocsp_response(gnutls_session_t session, gnutls_x509_crt_t cert,
     239             :                     gnutls_x509_trust_list_t tl,
     240             :                     unsigned verify_flags,
     241             :                     gnutls_x509_crt_t *cand_issuers, unsigned cand_issuers_size,
     242             :                     gnutls_datum_t * data, unsigned int *ostatus)
     243             : {
     244          40 :         gnutls_ocsp_resp_t resp;
     245          40 :         int ret;
     246          40 :         unsigned int status, cert_status;
     247          40 :         time_t rtime, vtime, ntime, now;
     248          40 :         int check_failed = 0;
     249             : 
     250          40 :         now = gnutls_time(0);
     251             : 
     252          40 :         ret = gnutls_ocsp_resp_init(&resp);
     253          40 :         if (ret < 0)
     254           0 :                 return gnutls_assert_val(ret);
     255             : 
     256          40 :         ret = gnutls_ocsp_resp_import(resp, data);
     257          40 :         if (ret < 0) {
     258           1 :                 _gnutls_audit_log(session,
     259             :                                   "There was an error parsing the OCSP response: %s.\n",
     260             :                                   gnutls_strerror(ret));
     261           1 :                 ret = gnutls_assert_val(0);
     262           1 :                 check_failed = 1;
     263           1 :                 *ostatus |= GNUTLS_CERT_INVALID;
     264           1 :                 *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
     265           1 :                 goto cleanup;
     266             :         }
     267             : 
     268          39 :         if (gnutls_ocsp_resp_get_status(resp) != GNUTLS_OCSP_RESP_SUCCESSFUL) {
     269           2 :                 ret = _gnutls_ocsp_verify_mandatory_stapling(session, cert, ostatus);
     270           2 :                 if (ret < 0) {
     271           0 :                         gnutls_assert();
     272           0 :                         goto cleanup;
     273             :                 }
     274           2 :                 if (*ostatus & GNUTLS_CERT_MISSING_OCSP_STATUS) {
     275           1 :                         _gnutls_audit_log(session,
     276             :                                           "Missing basic OCSP response while required: %s.\n",
     277             :                                           gnutls_strerror(ret));
     278           1 :                         check_failed = 1;
     279             :                 }
     280           2 :                 ret = gnutls_assert_val(0);
     281           2 :                 goto cleanup;
     282             :         }
     283             : 
     284          37 :         ret = gnutls_ocsp_resp_check_crt(resp, 0, cert);
     285          37 :         if (ret < 0) {
     286           2 :                 ret = gnutls_assert_val(0);
     287           2 :                 _gnutls_audit_log(session,
     288             :                                   "Got OCSP response with an unrelated certificate.\n");
     289           2 :                 check_failed = 1;
     290           2 :                 *ostatus |= GNUTLS_CERT_INVALID;
     291           2 :                 *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
     292           2 :                 goto cleanup;
     293             :         }
     294             : 
     295             :         /* Attempt to verify against our trusted list */
     296          35 :         ret = gnutls_ocsp_resp_verify(resp, tl, &status, verify_flags);
     297          35 :         if ((ret < 0 || status != 0) && cand_issuers_size > 0) {
     298             :                 /* Attempt to verify against the certificate list provided by the server */
     299             : 
     300          13 :                 ret = gnutls_ocsp_resp_verify_direct(resp, cand_issuers[0], &status, verify_flags);
     301             :                 /* if verification fails attempt to find whether any of the other
     302             :                  * bundled CAs is an issuer of the OCSP response */
     303          13 :                 if ((ret < 0 || status != 0) && cand_issuers_size > 1) {
     304             :                         int ret2;
     305             :                         unsigned status2, i;
     306             : 
     307           0 :                         for (i=1;i<cand_issuers_size;i++) {
     308           0 :                                 ret2 = gnutls_ocsp_resp_verify_direct(resp, cand_issuers[i], &status2, verify_flags);
     309           0 :                                 if (ret2 >= 0 && status2 == 0) {
     310           0 :                                         status = status2;
     311           0 :                                         ret = ret2;
     312           0 :                                         break;
     313             :                                 }
     314             :                         }
     315             :                 }
     316             :         }
     317             : 
     318          35 :         if (ret < 0) {
     319           0 :                 ret = gnutls_assert_val(0);
     320           0 :                 gnutls_assert();
     321           0 :                 check_failed = 1;
     322           0 :                 *ostatus |= GNUTLS_CERT_INVALID;
     323           0 :                 *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
     324           0 :                 goto cleanup;
     325             :         }
     326             : 
     327             :         /* do not consider revocation data if response was not verified */
     328          35 :         if (status != 0) {
     329           1 :                 char buf[MAX_OCSP_MSG_SIZE];
     330             : 
     331           1 :                 _gnutls_debug_log("OCSP rejection reason: %s\n",
     332             :                                   _gnutls_ocsp_verify_status_to_str(status, buf));
     333             : 
     334           1 :                 ret = gnutls_assert_val(0);
     335           1 :                 check_failed = 1;
     336           1 :                 *ostatus |= GNUTLS_CERT_INVALID;
     337           1 :                 *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
     338           1 :                 goto cleanup;
     339             :         }
     340             : 
     341          34 :         ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
     342             :                                           &cert_status, &vtime, &ntime,
     343             :                                           &rtime, NULL);
     344          34 :         if (ret < 0) {
     345           0 :                 _gnutls_audit_log(session,
     346             :                                   "There was an error parsing the OCSP response: %s.\n",
     347             :                                   gnutls_strerror(ret));
     348           0 :                 ret = gnutls_assert_val(0);
     349           0 :                 check_failed = 1;
     350           0 :                 *ostatus |= GNUTLS_CERT_INVALID;
     351           0 :                 *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
     352           0 :                 goto cleanup;
     353             :         }
     354             : 
     355          34 :         if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
     356           6 :                 _gnutls_audit_log(session,
     357             :                                   "The certificate was revoked via OCSP\n");
     358           6 :                 check_failed = 1;
     359           6 :                 *ostatus |= GNUTLS_CERT_INVALID;
     360           6 :                 *ostatus |= GNUTLS_CERT_REVOKED;
     361           6 :                 ret = gnutls_assert_val(0);
     362           6 :                 goto cleanup;
     363             :         }
     364             : 
     365             :         /* Report but do not fail on the following errors. That is
     366             :          * because including the OCSP response in the handshake shouldn't 
     367             :          * cause more problems that not including it.
     368             :          */
     369          28 :         if (ntime == -1) {
     370          27 :                 if (now - vtime > MAX_OCSP_VALIDITY_SECS) {
     371           1 :                         _gnutls_audit_log(session,
     372             :                                           "The OCSP response is old\n");
     373           1 :                         check_failed = 1;
     374           1 :                         *ostatus |= GNUTLS_CERT_INVALID;
     375           1 :                         *ostatus |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
     376           1 :                         goto cleanup;
     377             :                 }
     378             :         } else {
     379             :                 /* there is a newer OCSP answer, don't trust this one */
     380           1 :                 if (ntime < now) {
     381           1 :                         _gnutls_audit_log(session,
     382             :                                           "There is a newer OCSP response but was not provided by the server\n");
     383           1 :                         check_failed = 1;
     384           1 :                         *ostatus |= GNUTLS_CERT_INVALID;
     385           1 :                         *ostatus |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
     386           1 :                         goto cleanup;
     387             :                 }
     388             :         }
     389             : 
     390             :         ret = 0;
     391           2 :       cleanup:
     392          14 :         if (check_failed == 0)
     393          27 :                 session->internals.ocsp_check_ok = 1;
     394             : 
     395          40 :         gnutls_ocsp_resp_deinit(resp);
     396             : 
     397          40 :         return ret;
     398             : }
     399             : 
     400             : static int
     401         592 : _gnutls_ocsp_verify_mandatory_stapling(gnutls_session_t session,
     402             :                                        gnutls_x509_crt_t cert,
     403             :                                        unsigned int * ocsp_status)
     404             : {
     405         592 :         gnutls_x509_tlsfeatures_t tlsfeatures;
     406         592 :         int i, ret;
     407         592 :         unsigned feature;
     408             : 
     409             :         /* RFC 7633: If cert has TLS feature GNUTLS_EXTENSION_STATUS_REQUEST, stapling is mandatory.
     410             :          *
     411             :          * At this point, we know that we did not get the certificate status.
     412             :          *
     413             :          * To proceed, first check whether we have requested the certificate status
     414             :          */
     415         592 :         if (!(session->internals.hsk_flags & HSK_OCSP_REQUESTED))
     416             :                 return 0;
     417             : 
     418         591 :         ret = gnutls_x509_tlsfeatures_init(&tlsfeatures);
     419         591 :         if (ret < 0) {
     420           0 :                 gnutls_assert();
     421           0 :                 return ret;
     422             :         }
     423             : 
     424             :         /* We have requested the status, now check whether the certificate mandates a response */
     425         591 :         if (gnutls_x509_crt_get_tlsfeatures(cert, tlsfeatures, 0, NULL) == 0) {
     426           0 :                 for (i = 0;; ++i) {
     427           8 :                         ret = gnutls_x509_tlsfeatures_get(tlsfeatures, i, &feature);
     428           8 :                         if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     429             :                                 break;
     430             :                         }
     431             : 
     432           8 :                         if (ret < 0) {
     433           0 :                                 gnutls_assert();
     434           0 :                                 goto cleanup;
     435             :                         }
     436             : 
     437           8 :                         if (feature == 5 /* TLS ID for status request */) {
     438             :                                 /* We sent a status request, the certificate mandates a reply, but we did not get any. */
     439           8 :                                 *ocsp_status |= GNUTLS_CERT_INVALID;
     440           8 :                                 *ocsp_status |= GNUTLS_CERT_MISSING_OCSP_STATUS;
     441           8 :                                 break;
     442             :                         }
     443             :                 }
     444             :         }
     445             : 
     446             :         ret = 0;
     447         591 :  cleanup:
     448         591 :         gnutls_x509_tlsfeatures_deinit(tlsfeatures);
     449         591 :         return ret;
     450             : }
     451             : #endif
     452             : 
     453             : #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
     454             :         if (peer_certificate_list[x]) \
     455             :                 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
     456             :         } \
     457             :         gnutls_free( peer_certificate_list)
     458             : 
     459             : /*-
     460             :  * _gnutls_x509_cert_verify_peers - return the peer's certificate status
     461             :  * @session: is a gnutls session
     462             :  *
     463             :  * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
     464             :  * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
     465             :  * However you must also check the peer's name in order to check if the verified certificate belongs to the
     466             :  * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
     467             :  -*/
     468             : int
     469         431 : _gnutls_x509_cert_verify_peers(gnutls_session_t session,
     470             :                                gnutls_typed_vdata_st * data,
     471             :                                unsigned int elements,
     472             :                                unsigned int *status)
     473             : {
     474         431 :         cert_auth_info_t info;
     475         431 :         gnutls_certificate_credentials_t cred;
     476         431 :         gnutls_x509_crt_t *peer_certificate_list;
     477         431 :         gnutls_datum_t resp;
     478         431 :         int peer_certificate_list_size, i, x, ret;
     479         431 :         gnutls_x509_crt_t *cand_issuers;
     480         431 :         unsigned cand_issuers_size;
     481         431 :         unsigned int ocsp_status = 0;
     482         431 :         unsigned int verify_flags;
     483             : 
     484             :         /* No OCSP check so far */
     485         431 :         session->internals.ocsp_check_ok = 0;
     486             : 
     487         431 :         CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
     488             : 
     489         431 :         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
     490         431 :         if (info == NULL) {
     491           0 :                 gnutls_assert();
     492           0 :                 return GNUTLS_E_INVALID_REQUEST;
     493             :         }
     494             : 
     495         431 :         cred = (gnutls_certificate_credentials_t)
     496         431 :             _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
     497         431 :         if (cred == NULL) {
     498           0 :                 gnutls_assert();
     499           0 :                 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     500             :         }
     501             : 
     502         431 :         if (info->raw_certificate_list == NULL || info->ncerts == 0)
     503             :                 return GNUTLS_E_NO_CERTIFICATE_FOUND;
     504             : 
     505         431 :         if (info->ncerts > cred->verify_depth && cred->verify_depth > 0) {
     506           0 :                 gnutls_assert();
     507           0 :                 return GNUTLS_E_CONSTRAINT_ERROR;
     508             :         }
     509             : 
     510         431 :         verify_flags =
     511         431 :             cred->verify_flags | session->internals.additional_verify_flags;
     512             :         /* generate a list of gnutls_certs based on the auth info
     513             :          * raw certs.
     514             :          */
     515         431 :         peer_certificate_list_size = info->ncerts;
     516         431 :         peer_certificate_list =
     517         431 :             gnutls_calloc(peer_certificate_list_size,
     518             :                           sizeof(gnutls_x509_crt_t));
     519         431 :         if (peer_certificate_list == NULL) {
     520           0 :                 gnutls_assert();
     521           0 :                 return GNUTLS_E_MEMORY_ERROR;
     522             :         }
     523             : 
     524        1113 :         for (i = 0; i < peer_certificate_list_size; i++) {
     525         682 :                 ret = gnutls_x509_crt_init(&peer_certificate_list[i]);
     526         682 :                 if (ret < 0) {
     527           0 :                         gnutls_assert();
     528           0 :                         CLEAR_CERTS;
     529           0 :                         return ret;
     530             :                 }
     531             : 
     532         682 :                 ret =
     533        1364 :                     gnutls_x509_crt_import(peer_certificate_list[i],
     534         682 :                                            &info->raw_certificate_list[i],
     535             :                                            GNUTLS_X509_FMT_DER);
     536         682 :                 if (ret < 0) {
     537           0 :                         gnutls_assert();
     538           0 :                         CLEAR_CERTS;
     539           0 :                         return ret;
     540             :                 }
     541             :         }
     542             : 
     543             :         /* Use the OCSP extension if any */
     544             : #ifdef ENABLE_OCSP
     545         431 :         if (verify_flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)
     546          26 :                 goto skip_ocsp;
     547             : 
     548        1035 :         for (i=0;i<peer_certificate_list_size;i++) {
     549         630 :                 ret = gnutls_ocsp_status_request_get2(session, i, &resp);
     550         630 :                 if (ret < 0) {
     551         590 :                         ret = _gnutls_ocsp_verify_mandatory_stapling(session, peer_certificate_list[i], &ocsp_status);
     552         590 :                         if (ret < 0) {
     553           0 :                                 gnutls_assert();
     554           0 :                                 CLEAR_CERTS;
     555           0 :                                 return ret;
     556             :                         }
     557             : 
     558         590 :                         continue;
     559             :                 }
     560             : 
     561          40 :                 cand_issuers = NULL;
     562          40 :                 cand_issuers_size = 0;
     563          40 :                 if (peer_certificate_list_size > i+1) {
     564          19 :                         cand_issuers = &peer_certificate_list[i+1];
     565          19 :                         cand_issuers_size = peer_certificate_list_size-i-1;
     566             :                 }
     567             : 
     568          40 :                 ret =
     569          80 :                         check_ocsp_response(session,
     570          40 :                                             peer_certificate_list[i],
     571             :                                             cred->tlist, 
     572             :                                             verify_flags, cand_issuers,
     573             :                                             cand_issuers_size,
     574             :                                             &resp, &ocsp_status);
     575             : 
     576          40 :                 if (ret < 0) {
     577           0 :                         CLEAR_CERTS;
     578           0 :                         return gnutls_assert_val(ret);
     579             :                 }
     580             :         }
     581             : #endif
     582             : 
     583         405 :       skip_ocsp:
     584             :         /* Verify certificate 
     585             :          */
     586         431 :         ret =
     587         431 :             gnutls_x509_trust_list_verify_crt2(cred->tlist,
     588             :                                                peer_certificate_list,
     589             :                                                peer_certificate_list_size,
     590             :                                                data, elements,
     591             :                                                verify_flags, status, NULL);
     592             : 
     593         431 :         if (ret < 0) {
     594           0 :                 gnutls_assert();
     595           0 :                 CLEAR_CERTS;
     596           0 :                 return ret;
     597             :         }
     598             : 
     599        1113 :         CLEAR_CERTS;
     600             : 
     601         431 :         *status |= ocsp_status;
     602             : 
     603         431 :         return 0;
     604             : }
     605             : 
     606             : /**
     607             :  * gnutls_certificate_verify_peers2:
     608             :  * @session: is a gnutls session
     609             :  * @status: is the output of the verification
     610             :  *
     611             :  * This function will verify the peer's certificate and store
     612             :  * the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
     613             :  * values or zero if the certificate is trusted. Note that value in @status
     614             :  * is set only when the return value of this function is success (i.e, failure 
     615             :  * to trust a certificate does not imply a negative return value).
     616             :  * The default verification flags used by this function can be overridden
     617             :  * using gnutls_certificate_set_verify_flags().
     618             :  *
     619             :  * This function will take into account the stapled OCSP responses sent by the server,
     620             :  * as well as the following X.509 certificate extensions: Name Constraints,
     621             :  * Key Usage, and Basic Constraints (pathlen).
     622             :  * 
     623             :  * Note that you must also check the peer's name in order to check if
     624             :  * the verified certificate belongs to the actual peer, see gnutls_x509_crt_check_hostname(),
     625             :  * or use gnutls_certificate_verify_peers3().
     626             :  *
     627             :  * To avoid denial of service attacks some
     628             :  * default upper limits regarding the certificate key size and chain
     629             :  * size are set. To override them use gnutls_certificate_set_verify_limits().
     630             :  *
     631             :  * Note that when using raw public-keys verification will not work because there is
     632             :  * no corresponding certificate body belonging to the raw key that can be verified. In that
     633             :  * case this function will return %GNUTLS_E_INVALID_REQUEST.
     634             :  *
     635             :  * Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
     636             :  * A successful error code means that the @status parameter must be checked to obtain the validation status.
     637             :  **/
     638             : int
     639          30 : gnutls_certificate_verify_peers2(gnutls_session_t session,
     640             :                                  unsigned int *status)
     641             : {
     642          30 :         return gnutls_certificate_verify_peers(session, NULL, 0, status);
     643             : }
     644             : 
     645             : /**
     646             :  * gnutls_certificate_verify_peers3:
     647             :  * @session: is a gnutls session
     648             :  * @hostname: is the expected name of the peer; may be %NULL
     649             :  * @status: is the output of the verification
     650             :  *
     651             :  * This function will verify the peer's certificate and store the
     652             :  * the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
     653             :  * values or zero if the certificate is trusted. Note that value in @status
     654             :  * is set only when the return value of this function is success (i.e, failure 
     655             :  * to trust a certificate does not imply a negative return value).
     656             :  * The default verification flags used by this function can be overridden
     657             :  * using gnutls_certificate_set_verify_flags(). See the documentation
     658             :  * of gnutls_certificate_verify_peers2() for details in the verification process.
     659             :  *
     660             :  * This function will take into account the stapled OCSP responses sent by the server,
     661             :  * as well as the following X.509 certificate extensions: Name Constraints,
     662             :  * Key Usage, and Basic Constraints (pathlen).
     663             :  * 
     664             :  * If the @hostname provided is non-NULL then this function will compare
     665             :  * the hostname in the certificate against it. The comparison will follow
     666             :  * the RFC6125 recommendations. If names do not match the
     667             :  * %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set.
     668             :  *
     669             :  * In order to verify the purpose of the end-certificate (by checking the extended
     670             :  * key usage), use gnutls_certificate_verify_peers().
     671             :  *
     672             :  * To avoid denial of service attacks some
     673             :  * default upper limits regarding the certificate key size and chain
     674             :  * size are set. To override them use gnutls_certificate_set_verify_limits().
     675             :  *
     676             :  * Note that when using raw public-keys verification will not work because there is
     677             :  * no corresponding certificate body belonging to the raw key that can be verified. In that
     678             :  * case this function will return %GNUTLS_E_INVALID_REQUEST.
     679             :  *
     680             :  * Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
     681             :  * A successful error code means that the @status parameter must be checked to obtain the validation status.
     682             :  *
     683             :  * Since: 3.1.4
     684             :  **/
     685             : int
     686          56 : gnutls_certificate_verify_peers3(gnutls_session_t session,
     687             :                                  const char *hostname,
     688             :                                  unsigned int *status)
     689             : {
     690          56 : gnutls_typed_vdata_st data;
     691             : 
     692          56 :         data.type = GNUTLS_DT_DNS_HOSTNAME;
     693          56 :         data.size = 0;
     694          56 :         data.data = (void*)hostname;
     695             : 
     696          56 :         return gnutls_certificate_verify_peers(session, &data, 1, status);
     697             : }
     698             : 
     699             : /**
     700             :  * gnutls_certificate_verify_peers:
     701             :  * @session: is a gnutls session
     702             :  * @data: an array of typed data
     703             :  * @elements: the number of data elements
     704             :  * @status: is the output of the verification
     705             :  *
     706             :  * This function will verify the peer's certificate and store the
     707             :  * the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
     708             :  * values or zero if the certificate is trusted. Note that value in @status
     709             :  * is set only when the return value of this function is success (i.e, failure 
     710             :  * to trust a certificate does not imply a negative return value).
     711             :  * The default verification flags used by this function can be overridden
     712             :  * using gnutls_certificate_set_verify_flags(). See the documentation
     713             :  * of gnutls_certificate_verify_peers2() for details in the verification process.
     714             :  *
     715             :  * This function will take into account the stapled OCSP responses sent by the server,
     716             :  * as well as the following X.509 certificate extensions: Name Constraints,
     717             :  * Key Usage, and Basic Constraints (pathlen).
     718             :  * 
     719             :  * The acceptable @data types are %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_RFC822NAME and %GNUTLS_DT_KEY_PURPOSE_OID.
     720             :  * The former two accept as data a null-terminated hostname or email address, and the latter a null-terminated
     721             :  * object identifier (e.g., %GNUTLS_KP_TLS_WWW_SERVER).
     722             :  *
     723             :  * If a DNS hostname is provided then this function will compare
     724             :  * the hostname in the certificate against the given. If names do not match the 
     725             :  * %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set.
     726             :  * If a key purpose OID is provided and the end-certificate contains the extended key
     727             :  * usage PKIX extension, it will be required to be have the provided key purpose 
     728             :  * or be marked for any purpose, otherwise verification status will have the
     729             :  * %GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE flag set.
     730             :  *
     731             :  * To avoid denial of service attacks some
     732             :  * default upper limits regarding the certificate key size and chain
     733             :  * size are set. To override them use gnutls_certificate_set_verify_limits().
     734             :  *
     735             :  * Note that when using raw public-keys verification will not work because there is
     736             :  * no corresponding certificate body belonging to the raw key that can be verified. In that
     737             :  * case this function will return %GNUTLS_E_INVALID_REQUEST.
     738             :  *
     739             :  * Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
     740             :  * A successful error code means that the @status parameter must be checked to obtain the validation status.
     741             :  *
     742             :  * Since: 3.3.0
     743             :  **/
     744             : int
     745         431 : gnutls_certificate_verify_peers(gnutls_session_t session,
     746             :                                 gnutls_typed_vdata_st * data,
     747             :                                 unsigned int elements,
     748             :                                 unsigned int *status)
     749             : {
     750         431 :         cert_auth_info_t info;
     751             : 
     752         431 :         CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
     753             : 
     754         431 :         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
     755         431 :         if (info == NULL) {
     756             :                 return GNUTLS_E_NO_CERTIFICATE_FOUND;
     757             :         }
     758             : 
     759         431 :         if (info->raw_certificate_list == NULL || info->ncerts == 0)
     760             :                 return GNUTLS_E_NO_CERTIFICATE_FOUND;
     761             : 
     762             : 
     763         862 :         switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
     764         431 :                 case GNUTLS_CRT_X509:
     765         431 :                         return _gnutls_x509_cert_verify_peers(session, data, elements,
     766             :                                                                                 status);
     767             :                 default:
     768             :                         return GNUTLS_E_INVALID_REQUEST;
     769             :         }
     770             : }
     771             : 
     772             : /*-
     773             :  * _gnutls_x509_extract_certificate_activation_time - return the peer's certificate activation time
     774             :  * @cert: should contain an X.509 DER encoded certificate
     775             :  *
     776             :  * This function will return the certificate's activation time in UNIX time
     777             :  * (ie seconds since 00:00:00 UTC January 1, 1970).
     778             :  *
     779             :  * Returns a (time_t) -1 in case of an error.
     780             :  *
     781             :  -*/
     782             : static time_t
     783           3 : _gnutls_x509_get_raw_crt_activation_time(const gnutls_datum_t * cert)
     784             : {
     785           3 :         gnutls_x509_crt_t xcert;
     786           3 :         time_t result;
     787             : 
     788           3 :         result = gnutls_x509_crt_init(&xcert);
     789           3 :         if (result < 0)
     790             :                 return (time_t) - 1;
     791             : 
     792           3 :         result = gnutls_x509_crt_import(xcert, cert, GNUTLS_X509_FMT_DER);
     793           3 :         if (result < 0) {
     794           0 :                 gnutls_x509_crt_deinit(xcert);
     795           0 :                 return (time_t) - 1;
     796             :         }
     797             : 
     798           3 :         result = gnutls_x509_crt_get_activation_time(xcert);
     799             : 
     800           3 :         gnutls_x509_crt_deinit(xcert);
     801             : 
     802           3 :         return result;
     803             : }
     804             : 
     805             : /*-
     806             :  * gnutls_x509_extract_certificate_expiration_time:
     807             :  * @cert: should contain an X.509 DER encoded certificate
     808             :  *
     809             :  * This function will return the certificate's expiration time in UNIX
     810             :  * time (ie seconds since 00:00:00 UTC January 1, 1970).  Returns a
     811             :  *
     812             :  * (time_t) -1 in case of an error.
     813             :  *
     814             :  -*/
     815             : static time_t
     816           3 : _gnutls_x509_get_raw_crt_expiration_time(const gnutls_datum_t * cert)
     817             : {
     818           3 :         gnutls_x509_crt_t xcert;
     819           3 :         time_t result;
     820             : 
     821           3 :         result = gnutls_x509_crt_init(&xcert);
     822           3 :         if (result < 0)
     823             :                 return (time_t) - 1;
     824             : 
     825           3 :         result = gnutls_x509_crt_import(xcert, cert, GNUTLS_X509_FMT_DER);
     826           3 :         if (result < 0) {
     827           0 :                 gnutls_x509_crt_deinit(xcert);
     828           0 :                 return (time_t) - 1;
     829             :         }
     830             : 
     831           3 :         result = gnutls_x509_crt_get_expiration_time(xcert);
     832             : 
     833           3 :         gnutls_x509_crt_deinit(xcert);
     834             : 
     835           3 :         return result;
     836             : }
     837             : 
     838             : /**
     839             :  * gnutls_certificate_expiration_time_peers:
     840             :  * @session: is a gnutls session
     841             :  *
     842             :  * This function will return the peer's certificate expiration time.
     843             :  *
     844             :  * Returns: (time_t)-1 on error.
     845             :  *
     846             :  * Deprecated: gnutls_certificate_verify_peers2() now verifies expiration times.
     847             :  **/
     848           3 : time_t gnutls_certificate_expiration_time_peers(gnutls_session_t session)
     849             : {
     850           3 :         cert_auth_info_t info;
     851             : 
     852           3 :         CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
     853             : 
     854           3 :         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
     855           3 :         if (info == NULL) {
     856             :                 return (time_t) - 1;
     857             :         }
     858             : 
     859           3 :         if (info->raw_certificate_list == NULL || info->ncerts == 0) {
     860           0 :                 gnutls_assert();
     861           0 :                 return (time_t) - 1;
     862             :         }
     863             : 
     864           6 :         switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
     865           3 :                 case GNUTLS_CRT_X509:
     866           3 :                         return
     867           3 :                                         _gnutls_x509_get_raw_crt_expiration_time(&info->
     868             :                                                                                  raw_certificate_list[0]);
     869             :                 default:
     870             :                         return (time_t) - 1;
     871             :         }
     872             : }
     873             : 
     874             : /**
     875             :  * gnutls_certificate_activation_time_peers:
     876             :  * @session: is a gnutls session
     877             :  *
     878             :  * This function will return the peer's certificate activation time.
     879             :  *
     880             :  * Returns: (time_t)-1 on error.
     881             :  *
     882             :  * Deprecated: gnutls_certificate_verify_peers2() now verifies activation times.
     883             :  **/
     884           3 : time_t gnutls_certificate_activation_time_peers(gnutls_session_t session)
     885             : {
     886           3 :         cert_auth_info_t info;
     887             : 
     888           3 :         CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
     889             : 
     890           3 :         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
     891           3 :         if (info == NULL) {
     892             :                 return (time_t) - 1;
     893             :         }
     894             : 
     895           3 :         if (info->raw_certificate_list == NULL || info->ncerts == 0) {
     896           0 :                 gnutls_assert();
     897           0 :                 return (time_t) - 1;
     898             :         }
     899             : 
     900           6 :         switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
     901           3 :                 case GNUTLS_CRT_X509:
     902           3 :                         return
     903           3 :                                         _gnutls_x509_get_raw_crt_activation_time(&info->
     904             :                                                                                  raw_certificate_list[0]);
     905             :                 default:
     906             :                         return (time_t) - 1;
     907             :         }
     908             : }

Generated by: LCOV version 1.14