Botan  2.9.0
Crypto and TLS for C++11
tls_callbacks.cpp
Go to the documentation of this file.
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/oids.h>
17 #include <botan/tls_exceptn.h>
18 #include <botan/internal/ct_utils.h>
19 
20 #if defined(BOTAN_HAS_CURVE_25519)
21  #include <botan/curve25519.h>
22 #endif
23 
24 namespace Botan {
25 
27  {
28  // default is no op
29  }
30 
31 std::string TLS::Callbacks::tls_server_choose_app_protocol(const std::vector<std::string>&)
32  {
33  return "";
34  }
35 
37  {
38  }
39 
41  {
42  }
43 
45  {
46  return group_param_to_string(group_param);
47  }
48 
50  const std::vector<X509_Certificate>& cert_chain,
51  const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses,
52  const std::vector<Certificate_Store*>& trusted_roots,
53  Usage_Type usage,
54  const std::string& hostname,
55  const TLS::Policy& policy)
56  {
57  if(cert_chain.empty())
58  throw Invalid_Argument("Certificate chain was empty");
59 
62 
63  Path_Validation_Result result =
64  x509_path_validate(cert_chain,
65  restrictions,
66  trusted_roots,
67  (usage == Usage_Type::TLS_SERVER_AUTH ? hostname : ""),
68  usage,
69  std::chrono::system_clock::now(),
70  tls_verify_cert_chain_ocsp_timeout(),
71  ocsp_responses);
72 
73  if(!result.successful_validation())
74  {
76  "Certificate validation failure: " + result.result_string());
77  }
78  }
79 
80 std::vector<uint8_t> TLS::Callbacks::tls_sign_message(
81  const Private_Key& key,
83  const std::string& emsa,
84  Signature_Format format,
85  const std::vector<uint8_t>& msg)
86  {
87  PK_Signer signer(key, rng, emsa, format);
88 
89  return signer.sign_message(msg, rng);
90  }
91 
93  const Public_Key& key,
94  const std::string& emsa,
95  Signature_Format format,
96  const std::vector<uint8_t>& msg,
97  const std::vector<uint8_t>& sig)
98  {
99  PK_Verifier verifier(key, emsa, format);
100 
101  return verifier.verify_message(msg, sig);
102  }
103 
104 std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_dh_agree(
105  const std::vector<uint8_t>& modulus,
106  const std::vector<uint8_t>& generator,
107  const std::vector<uint8_t>& peer_public_value,
108  const Policy& policy,
110  {
111  BigInt p = BigInt::decode(modulus);
112  BigInt g = BigInt::decode(generator);
113  BigInt Y = BigInt::decode(peer_public_value);
114 
115  /*
116  * A basic check for key validity. As we do not know q here we
117  * cannot check that Y is in the right subgroup. However since
118  * our key is ephemeral there does not seem to be any
119  * advantage to bogus keys anyway.
120  */
121  if(Y <= 1 || Y >= p - 1)
123  "Server sent bad DH key for DHE exchange");
124 
125  DL_Group group(p, g);
126 
127  if(!group.verify_group(rng, false))
129  "DH group validation failed");
130 
131  DH_PublicKey peer_key(group, Y);
132 
133  policy.check_peer_key_acceptable(peer_key);
134 
135  DH_PrivateKey priv_key(rng, group);
136  PK_Key_Agreement ka(priv_key, rng, "Raw");
138  ka.derive_key(0, peer_key.public_value()).bits_of());
139 
140  return std::make_pair(dh_secret, priv_key.public_value());
141  }
142 
143 std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_ecdh_agree(
144  const std::string& curve_name,
145  const std::vector<uint8_t>& peer_public_value,
146  const Policy& policy,
148  bool compressed)
149  {
150  secure_vector<uint8_t> ecdh_secret;
151  std::vector<uint8_t> our_public_value;
152 
153  if(curve_name == "x25519")
154  {
155 #if defined(BOTAN_HAS_CURVE_25519)
156  if(peer_public_value.size() != 32)
157  {
158  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid X25519 key size");
159  }
160 
161  Curve25519_PublicKey peer_key(peer_public_value);
162  policy.check_peer_key_acceptable(peer_key);
163  Curve25519_PrivateKey priv_key(rng);
164  PK_Key_Agreement ka(priv_key, rng, "Raw");
165  ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of();
166 
167  // X25519 is always compressed but sent as "uncompressed" in TLS
168  our_public_value = priv_key.public_value();
169 #else
170  throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
171 #endif
172  }
173  else
174  {
175  EC_Group group(OIDS::lookup(curve_name));
176  ECDH_PublicKey peer_key(group, group.OS2ECP(peer_public_value));
177  policy.check_peer_key_acceptable(peer_key);
178  ECDH_PrivateKey priv_key(rng, group);
179  PK_Key_Agreement ka(priv_key, rng, "Raw");
180  ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of();
181  our_public_value = priv_key.public_value(compressed ? PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
182  }
183 
184  return std::make_pair(ecdh_secret, our_public_value);
185  }
186 
187 }
std::vector< uint8_t > public_value() const
Definition: dh.cpp:27
virtual std::string tls_decode_group_param(Group_Params group_param)
virtual std::pair< secure_vector< uint8_t >, std::vector< uint8_t > > tls_dh_agree(const std::vector< uint8_t > &modulus, const std::vector< uint8_t > &generator, const std::vector< uint8_t > &peer_public_value, const Policy &policy, RandomNumberGenerator &rng)
virtual std::pair< secure_vector< uint8_t >, std::vector< uint8_t > > tls_ecdh_agree(const std::string &curve_name, const std::vector< uint8_t > &peer_public_value, const Policy &policy, RandomNumberGenerator &rng, bool compressed)
std::vector< uint8_t > public_value() const
Definition: curve25519.h:30
virtual bool tls_verify_message(const Public_Key &key, const std::string &emsa, Signature_Format format, const std::vector< uint8_t > &msg, const std::vector< uint8_t > &sig)
virtual std::string tls_server_choose_app_protocol(const std::vector< std::string > &client_protos)
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
Definition: pubkey.cpp:324
virtual void check_peer_key_acceptable(const Public_Key &public_key) const
Definition: tls_policy.cpp:229
fe Y
Definition: ge.cpp:28
Signature_Format
Definition: pubkey.h:28
std::string group_param_to_string(Group_Params group)
Definition: tls_algos.cpp:155
secure_vector< uint8_t > strip_leading_zeros(const uint8_t in[], size_t length)
Definition: ct_utils.cpp:65
std::vector< uint8_t > sign_message(const uint8_t in[], size_t length, RandomNumberGenerator &rng)
Definition: pubkey.h:219
bool verify_group(RandomNumberGenerator &rng, bool strong=true) const
Definition: dl_group.cpp:372
virtual bool require_cert_revocation_info() const
Definition: tls_policy.cpp:206
virtual std::vector< uint8_t > tls_sign_message(const Private_Key &key, RandomNumberGenerator &rng, const std::string &emsa, Signature_Format format, const std::vector< uint8_t > &msg)
std::vector< uint8_t > public_value() const override
Definition: ecdh.h:92
PointGFp OS2ECP(const uint8_t bits[], size_t len) const
Definition: ec_group.cpp:538
virtual void tls_verify_cert_chain(const std::vector< X509_Certificate > &cert_chain, const std::vector< std::shared_ptr< const OCSP::Response >> &ocsp_responses, const std::vector< Certificate_Store *> &trusted_roots, Usage_Type usage, const std::string &hostname, const TLS::Policy &policy)
SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t params[], size_t params_len) const
Definition: pubkey.cpp:218
Definition: alg_id.cpp:13
Path_Validation_Result x509_path_validate(const std::vector< X509_Certificate > &end_certs, const Path_Validation_Restrictions &restrictions, const std::vector< Certificate_Store *> &trusted_roots, const std::string &hostname, Usage_Type usage, std::chrono::system_clock::time_point ref_time, std::chrono::milliseconds ocsp_timeout, const std::vector< std::shared_ptr< const OCSP::Response >> &ocsp_resp)
Definition: x509path.cpp:830
virtual void tls_examine_extensions(const Extensions &extn, Connection_Side which_side)
virtual size_t minimum_signature_strength() const
Definition: tls_policy.cpp:201
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side)
static BigInt decode(const uint8_t buf[], size_t length)
Definition: bigint.h:786
std::vector< uint8_t > public_value() const override
Definition: curve25519.h:83
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
virtual void tls_inspect_handshake_msg(const Handshake_Message &message)
std::vector< uint8_t > public_value() const override
Definition: dh.cpp:72
std::string lookup(const OID &oid)
Definition: oids.cpp:113
Usage_Type
Definition: x509cert.h:25