Coverage Report

Created: 2020-05-23 13:54

/src/botan/src/lib/tls/tls_callbacks.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* TLS Callbacks
3
* (C) 2016 Jack Lloyd
4
*     2017 Harry Reimann, Rohde & Schwarz Cybersecurity
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#include <botan/tls_callbacks.h>
10
#include <botan/tls_policy.h>
11
#include <botan/tls_algos.h>
12
#include <botan/x509path.h>
13
#include <botan/ocsp.h>
14
#include <botan/dh.h>
15
#include <botan/ecdh.h>
16
#include <botan/tls_exceptn.h>
17
#include <botan/internal/ct_utils.h>
18
19
#if defined(BOTAN_HAS_CURVE_25519)
20
  #include <botan/curve25519.h>
21
#endif
22
23
namespace Botan {
24
25
void TLS::Callbacks::tls_inspect_handshake_msg(const Handshake_Message&)
26
125k
   {
27
125k
   // default is no op
28
125k
   }
29
30
std::string TLS::Callbacks::tls_server_choose_app_protocol(const std::vector<std::string>&)
31
0
   {
32
0
   return "";
33
0
   }
34
35
std::string TLS::Callbacks::tls_peer_network_identity()
36
6.75k
   {
37
6.75k
   return "";
38
6.75k
   }
39
40
void TLS::Callbacks::tls_modify_extensions(Extensions&, Connection_Side)
41
28.0k
   {
42
28.0k
   }
43
44
void TLS::Callbacks::tls_examine_extensions(const Extensions&, Connection_Side)
45
26.9k
   {
46
26.9k
   }
47
48
std::string TLS::Callbacks::tls_decode_group_param(Group_Params group_param)
49
21.8k
   {
50
21.8k
   return group_param_to_string(group_param);
51
21.8k
   }
52
53
void TLS::Callbacks::tls_verify_cert_chain(
54
   const std::vector<X509_Certificate>& cert_chain,
55
   const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses,
56
   const std::vector<Certificate_Store*>& trusted_roots,
57
   Usage_Type usage,
58
   const std::string& hostname,
59
   const TLS::Policy& policy)
60
626
   {
61
626
   if(cert_chain.empty())
62
0
      throw Invalid_Argument("Certificate chain was empty");
63
626
64
626
   Path_Validation_Restrictions restrictions(policy.require_cert_revocation_info(),
65
626
                                             policy.minimum_signature_strength());
66
626
67
626
   Path_Validation_Result result =
68
626
      x509_path_validate(cert_chain,
69
626
                         restrictions,
70
626
                         trusted_roots,
71
626
                         (usage == Usage_Type::TLS_SERVER_AUTH ? hostname : ""),
72
626
                         usage,
73
626
                         std::chrono::system_clock::now(),
74
626
                         tls_verify_cert_chain_ocsp_timeout(),
75
626
                         ocsp_responses);
76
626
77
626
   if(!result.successful_validation())
78
626
      {
79
626
      throw TLS_Exception(Alert::BAD_CERTIFICATE,
80
626
                          "Certificate validation failure: " + result.result_string());
81
626
      }
82
626
   }
83
84
std::vector<uint8_t> TLS::Callbacks::tls_sign_message(
85
   const Private_Key& key,
86
   RandomNumberGenerator& rng,
87
   const std::string& emsa,
88
   Signature_Format format,
89
   const std::vector<uint8_t>& msg)
90
0
   {
91
0
   PK_Signer signer(key, rng, emsa, format);
92
0
93
0
   return signer.sign_message(msg, rng);
94
0
   }
95
96
bool TLS::Callbacks::tls_verify_message(
97
   const Public_Key& key,
98
   const std::string& emsa,
99
   Signature_Format format,
100
   const std::vector<uint8_t>& msg,
101
   const std::vector<uint8_t>& sig)
102
208
   {
103
208
   PK_Verifier verifier(key, emsa, format);
104
208
105
208
   return verifier.verify_message(msg, sig);
106
208
   }
107
108
std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_dh_agree(
109
   const std::vector<uint8_t>& modulus,
110
   const std::vector<uint8_t>& generator,
111
   const std::vector<uint8_t>& peer_public_value,
112
   const Policy& policy,
113
   RandomNumberGenerator& rng)
114
157
   {
115
157
   BigInt p = BigInt::decode(modulus);
116
157
   BigInt g = BigInt::decode(generator);
117
157
   BigInt Y = BigInt::decode(peer_public_value);
118
157
119
157
   /*
120
157
    * A basic check for key validity. As we do not know q here we
121
157
    * cannot check that Y is in the right subgroup. However since
122
157
    * our key is ephemeral there does not seem to be any
123
157
    * advantage to bogus keys anyway.
124
157
    */
125
157
   if(Y <= 1 || Y >= p - 1)
126
2
      throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
127
2
                          "Server sent bad DH key for DHE exchange");
128
155
129
155
   DL_Group group(p, g);
130
155
131
155
   if(!group.verify_group(rng, false))
132
73
      throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
133
73
                          "DH group validation failed");
134
82
135
82
   DH_PublicKey peer_key(group, Y);
136
82
137
82
   policy.check_peer_key_acceptable(peer_key);
138
82
139
82
   DH_PrivateKey priv_key(rng, group);
140
82
   PK_Key_Agreement ka(priv_key, rng, "Raw");
141
82
   secure_vector<uint8_t> dh_secret = CT::strip_leading_zeros(
142
82
      ka.derive_key(0, peer_key.public_value()).bits_of());
143
82
144
82
   return std::make_pair(dh_secret, priv_key.public_value());
145
82
   }
146
147
std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_ecdh_agree(
148
   const std::string& curve_name,
149
   const std::vector<uint8_t>& peer_public_value,
150
   const Policy& policy,
151
   RandomNumberGenerator& rng,
152
   bool compressed)
153
127
   {
154
127
   secure_vector<uint8_t> ecdh_secret;
155
127
   std::vector<uint8_t> our_public_value;
156
127
157
127
   if(curve_name == "x25519")
158
9
      {
159
9
#if defined(BOTAN_HAS_CURVE_25519)
160
9
      if(peer_public_value.size() != 32)
161
1
         {
162
1
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid X25519 key size");
163
1
         }
164
8
165
8
      Curve25519_PublicKey peer_key(peer_public_value);
166
8
      policy.check_peer_key_acceptable(peer_key);
167
8
      Curve25519_PrivateKey priv_key(rng);
168
8
      PK_Key_Agreement ka(priv_key, rng, "Raw");
169
8
      ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of();
170
8
171
8
      // X25519 is always compressed but sent as "uncompressed" in TLS
172
8
      our_public_value = priv_key.public_value();
173
#else
174
      throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
175
#endif
176
      }
177
118
   else
178
118
      {
179
118
      EC_Group group(OID::from_string(curve_name));
180
118
      ECDH_PublicKey peer_key(group, group.OS2ECP(peer_public_value));
181
118
      policy.check_peer_key_acceptable(peer_key);
182
118
      ECDH_PrivateKey priv_key(rng, group);
183
118
      PK_Key_Agreement ka(priv_key, rng, "Raw");
184
118
      ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of();
185
118
      our_public_value = priv_key.public_value(compressed ? PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
186
118
      }
187
127
188
127
   return std::make_pair(ecdh_secret, our_public_value);
189
127
   }
190
191
}