Botan 3.13.0
Crypto and TLS for C&
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* 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
6* 2023 René Meusel - Rohde & Schwarz Cybersecurity
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#include <botan/tls_callbacks.h>
12
13#include <botan/dh.h>
14#include <botan/dl_group.h>
15#include <botan/ec_group.h>
16#include <botan/ecdh.h>
17#include <botan/ocsp.h>
18#include <botan/pk_algs.h>
19#include <botan/tls_algos.h>
20#include <botan/tls_exceptn.h>
21#include <botan/tls_policy.h>
22#include <botan/tls_session.h>
23#include <botan/x509path.h>
24#include <botan/internal/fmt.h>
25#include <botan/internal/stl_util.h>
26
27#if defined(BOTAN_HAS_X25519)
28 #include <botan/x25519.h>
29#endif
30
31#if defined(BOTAN_HAS_X448)
32 #include <botan/x448.h>
33#endif
34
35#if defined(BOTAN_HAS_ML_KEM)
36 #include <botan/ml_kem.h>
37#endif
38
39#if defined(BOTAN_HAS_FRODOKEM)
40 #include <botan/frodokem.h>
41#endif
42
43#if defined(BOTAN_HAS_TLS_13_PQC)
44 #include <botan/internal/hybrid_public_key.h>
45#endif
46
47namespace Botan {
48
50 // default is no op
51}
52
53std::string TLS::Callbacks::tls_server_choose_app_protocol(const std::vector<std::string>& /*unused*/) {
54 return "";
55}
56
58 return "";
59}
60
61std::chrono::system_clock::time_point TLS::Callbacks::tls_current_timestamp() {
62 return std::chrono::system_clock::now();
63}
64
66 const auto now = std::chrono::steady_clock::now().time_since_epoch();
67 return std::chrono::duration_cast<std::chrono::milliseconds>(now).count();
68}
69
71 Connection_Side /*unused*/,
72 Handshake_Type /*unused*/) {}
73
75 Connection_Side /*unused*/,
76 Handshake_Type /*unused*/) {}
77
79 // RFC 5077 3.3
80 // The ticket_lifetime_hint field contains a hint from the server about
81 // how long the ticket should be stored. A value of zero is reserved to
82 // indicate that the lifetime of the ticket is unspecified.
83 //
84 // RFC 8446 4.6.1
85 // [A ticket_lifetime] of zero indicates that the ticket should be discarded
86 // immediately.
87 //
88 // By default we opt to keep all sessions, except for TLS 1.3 with a lifetime
89 // hint of zero.
90 return session.lifetime_hint().count() > 0 || session.version().is_pre_tls_13();
91}
92
93void TLS::Callbacks::tls_verify_cert_chain(const std::vector<X509_Certificate>& cert_chain,
94 const std::vector<std::optional<OCSP::Response>>& ocsp_responses,
95 const std::vector<Certificate_Store*>& trusted_roots,
96 Usage_Type usage,
97 std::string_view hostname,
98 const TLS::Policy& policy) {
99 if(cert_chain.empty()) {
100 throw Invalid_Argument("Certificate chain was empty");
101 }
102
105
106 /*
107 Hostname is always provided in order to allow host-specific logic if required,
108 but it should not be passed to x509_path_validate unless we are verifying
109 the server.
110 */
111 const std::string_view name_to_match = (usage == Usage_Type::TLS_CLIENT_AUTH) ? std::string_view{} : hostname;
112
113 const Path_Validation_Result result = x509_path_validate(cert_chain,
114 restrictions,
115 trusted_roots,
116 name_to_match,
117 usage,
120 ocsp_responses);
121
122 if(!result.successful_validation()) {
123 throw TLS_Exception(Alert::BadCertificate, "Certificate validation failure: " + result.result_string());
124 }
125}
126
128 Usage_Type usage,
129 std::string_view hostname,
130 const TLS::Policy& policy) {
131 BOTAN_UNUSED(raw_public_key, usage, hostname, policy);
132 // There is no good default implementation for authenticating raw public key.
133 // Applications that wish to use them for authentication, must override this.
134 throw TLS_Exception(Alert::CertificateUnknown, "Application did not provide a means to validate the raw public key");
135}
136
137std::optional<OCSP::Response> TLS::Callbacks::tls_parse_ocsp_response(const std::vector<uint8_t>& raw_response) {
138 try {
139 return OCSP::Response(raw_response);
140 } catch(const Decoding_Error&) {
141 // ignore parsing errors and just ignore the broken OCSP response
142 return std::nullopt;
143 }
144}
145
146std::vector<std::vector<uint8_t>> TLS::Callbacks::tls_provide_cert_chain_status(
147 const std::vector<X509_Certificate>& chain, const Certificate_Status_Request& csr) {
148 std::vector<std::vector<uint8_t>> result(chain.size());
149 if(!chain.empty()) {
150 result[0] = tls_provide_cert_status(chain, csr);
151 }
152 return result;
153}
154
155std::vector<uint8_t> TLS::Callbacks::tls_sign_message(const Private_Key& key,
157 std::string_view padding,
158 Signature_Format format,
159 const std::vector<uint8_t>& msg) {
160 PK_Signer signer(key, rng, padding, format);
161
162 return signer.sign_message(msg, rng);
163}
164
166 std::string_view padding,
167 Signature_Format format,
168 const std::vector<uint8_t>& msg,
169 const std::vector<uint8_t>& sig) {
170 PK_Verifier verifier(key, padding, format);
171
172 return verifier.verify_message(msg, sig);
173}
174
175namespace {
176
177bool is_dh_group(const std::variant<TLS::Group_Params, DL_Group>& group) {
178 return std::holds_alternative<DL_Group>(group) || std::get<TLS::Group_Params>(group).is_dh_named_group();
179}
180
181DL_Group get_dl_group(const std::variant<TLS::Group_Params, DL_Group>& group) {
182 BOTAN_ASSERT_NOMSG(is_dh_group(group));
183
184 // TLS 1.2 allows specifying arbitrary DL_Group parameters in-lieu of
185 // a standardized DH group identifier. TLS 1.3 just offers pre-defined
186 // groups.
187 return std::visit(overloaded{[](const DL_Group& dl_group) { return dl_group; },
188 [&](TLS::Group_Params group_param) {
189 return DL_Group::from_name(group_param.to_algorithm_spec().value());
190 }},
191 group);
192}
193
194} // namespace
195
197 const std::variant<TLS::Group_Params, DL_Group>& group, std::span<const uint8_t> key_bits) {
198 if(is_dh_group(group)) {
199 // TLS 1.2 allows specifying arbitrary DL_Group parameters in-lieu of
200 // a standardized DH group identifier.
201 const auto dl_group = get_dl_group(group);
202
203 auto Y = BigInt::from_bytes(key_bits);
204
205 /*
206 * A basic check for key validity. As we do not know q here we
207 * cannot check that Y is in the right subgroup. However since
208 * our key is ephemeral there does not seem to be any
209 * advantage to bogus keys anyway.
210 */
211 if(Y <= 1 || Y >= dl_group.get_p() - 1) {
212 throw Decoding_Error("Server sent bad DH key for DHE exchange");
213 }
214
215 return std::make_unique<DH_PublicKey>(dl_group, Y);
216 }
217
218 // The special case for TLS 1.2 with an explicit DH group definition is
219 // handled above. All other cases are based on the opaque group definition.
220 BOTAN_ASSERT_NOMSG(std::holds_alternative<TLS::Group_Params>(group));
221 const auto group_params = std::get<TLS::Group_Params>(group);
222
223 if(group_params.is_ecdh_named_curve()) {
224 const auto ec_group = EC_Group::from_name(group_params.to_algorithm_spec().value());
225 // TLS 1.3 requires uncompressed points (checked when parsing the key
226 // share); TLS 1.2 may negotiate the compressed format. The deprecated
227 // hybrid encoding and the identity element are never accepted.
228
229 auto point = [&]() -> EC_AffinePoint {
230 if(auto pt_uncompressed = EC_AffinePoint::deserialize_uncompressed(ec_group, key_bits)) {
231 return std::move(pt_uncompressed).value();
232 } else if(auto pt_compressed = EC_AffinePoint::deserialize_compressed(ec_group, key_bits)) {
233 return std::move(pt_compressed).value();
234 } else {
235 throw Decoding_Error("Invalid ECDH public key encoding");
236 }
237 }();
238 return std::make_unique<ECDH_PublicKey>(ec_group, std::move(point));
239 }
240
241#if defined(BOTAN_HAS_X25519)
242 if(group_params.is_x25519()) {
243 return std::make_unique<X25519_PublicKey>(key_bits);
244 }
245#endif
246
247#if defined(BOTAN_HAS_X448)
248 if(group_params.is_x448()) {
249 return std::make_unique<X448_PublicKey>(key_bits);
250 }
251#endif
252
253#if defined(BOTAN_HAS_TLS_13_PQC)
254 if(group_params.is_pqc_hybrid()) {
255 return Hybrid_KEM_PublicKey::load_for_group(group_params, key_bits);
256 }
257#endif
258
259#if defined(BOTAN_HAS_ML_KEM)
260 if(group_params.is_pure_ml_kem()) {
261 return std::make_unique<ML_KEM_PublicKey>(key_bits, ML_KEM_Mode(group_params.to_algorithm_spec().value()));
262 }
263#endif
264
265#if defined(BOTAN_HAS_FRODOKEM)
266 if(group_params.is_pure_frodokem()) {
267 return std::make_unique<FrodoKEM_PublicKey>(key_bits, FrodoKEMMode(group_params.to_algorithm_spec().value()));
268 }
269#endif
270
271 throw Decoding_Error("cannot create a key offering without a group definition");
272}
273
275#if defined(BOTAN_HAS_ML_KEM)
276 if(group.is_pure_ml_kem()) {
277 return std::make_unique<ML_KEM_PrivateKey>(rng, ML_KEM_Mode(group.to_algorithm_spec().value()));
278 }
279#endif
280
281#if defined(BOTAN_HAS_FRODOKEM)
282 if(group.is_pure_frodokem()) {
283 return std::make_unique<FrodoKEM_PrivateKey>(rng, FrodoKEMMode(group.to_algorithm_spec().value()));
284 }
285#endif
286
287#if defined(BOTAN_HAS_TLS_13_PQC)
288 if(group.is_pqc_hybrid()) {
290 }
291#endif
292
293 return tls_generate_ephemeral_key(group, rng);
294}
295
297 const std::vector<uint8_t>& encoded_public_key,
299 const Policy& policy) {
300 if(group.is_kem()) {
301 auto kem_pub_key = [&] {
302 try {
303 return tls_deserialize_peer_public_key(group, encoded_public_key);
304 } catch(const Decoding_Error& ex) {
305 // This exception means that the public key was invalid. However,
306 // TLS' DecodeError would imply that a protocol message was invalid.
307 throw TLS_Exception(Alert::IllegalParameter, ex.what());
308 } catch(const Invalid_Argument& ex) {
309 throw TLS_Exception(Alert::IllegalParameter, ex.what());
310 }
311 }();
312
313 BOTAN_ASSERT_NONNULL(kem_pub_key);
314 policy.check_peer_key_acceptable(*kem_pub_key);
315
316 try {
317 return PK_KEM_Encryptor(*kem_pub_key, "Raw").encrypt(rng);
318 } catch(const Decoding_Error& ex) {
319 throw TLS_Exception(Alert::IllegalParameter, ex.what());
320 } catch(const Invalid_Argument& ex) {
321 throw TLS_Exception(Alert::IllegalParameter, ex.what());
322 }
323 } else {
324 // TODO: We could use the KEX_to_KEM_Adapter to remove the case distinction
325 // of KEM and KEX. However, the workarounds in this adapter class
326 // should first be addressed.
327 auto ephemeral_keypair = tls_generate_ephemeral_key(group, rng);
328 BOTAN_ASSERT_NONNULL(ephemeral_keypair);
329 return {ephemeral_keypair->public_value(),
330 tls_ephemeral_key_agreement(group, *ephemeral_keypair, encoded_public_key, rng, policy)};
331 }
332}
333
335 const Private_Key& private_key,
336 const std::vector<uint8_t>& encapsulated_bytes,
338 const Policy& policy) {
339 if(group.is_kem()) {
340 PK_KEM_Decryptor kemdec(private_key, rng, "Raw");
341 if(encapsulated_bytes.size() != kemdec.encapsulated_key_length()) {
342 throw TLS_Exception(Alert::IllegalParameter, "Invalid encapsulated key length");
343 }
344 try {
345 return kemdec.decrypt(encapsulated_bytes, 0, {});
346 } catch(const Decoding_Error& ex) {
347 throw TLS_Exception(Alert::IllegalParameter, ex.what());
348 } catch(const Invalid_Argument& ex) {
349 throw TLS_Exception(Alert::IllegalParameter, ex.what());
350 }
351 }
352
353 try {
354 const auto& key_agreement_key = dynamic_cast<const PK_Key_Agreement_Key&>(private_key);
355 return tls_ephemeral_key_agreement(group, key_agreement_key, encapsulated_bytes, rng, policy);
356 } catch(const std::bad_cast&) {
357 throw Invalid_Argument("provided ephemeral key is not a PK_Key_Agreement_Key");
358 }
359}
360
361std::unique_ptr<PK_Key_Agreement_Key> TLS::Callbacks::tls_generate_ephemeral_key(
362 const std::variant<TLS::Group_Params, DL_Group>& group, RandomNumberGenerator& rng) {
363 if(is_dh_group(group)) {
364 const DL_Group dl_group = get_dl_group(group);
365 return std::make_unique<DH_PrivateKey>(rng, dl_group);
366 }
367
368 BOTAN_ASSERT_NOMSG(std::holds_alternative<TLS::Group_Params>(group));
369 const auto group_params = std::get<TLS::Group_Params>(group);
370
371 if(group_params.is_ecdh_named_curve()) {
372 const auto ec_group = EC_Group::from_name(group_params.to_algorithm_spec().value());
373 auto ecdh_key = std::make_unique<ECDH_PrivateKey>(rng, ec_group);
374
375 // RFC 8446 Ch. 4.2.8.2
376 //
377 // Note: Versions of TLS prior to 1.3 permitted point format
378 // negotiation; TLS 1.3 removes this feature in favor of a single point
379 // format for each curve.
380 //
381 // Hence, TLS 1.3 won't take Policy::use_ecc_point_compression() or
382 // ClientHello::prefers_compressed_ec_points() into account but always use
383 // uncompressed point encoding. Note that TLS 1.2 uses the
384 // `tls12_generate_ephemeral_ecdh_key()` callback, which allows to specify
385 // the point encoding format.
386 ecdh_key->set_point_encoding(EC_Point_Format::Uncompressed);
387 return ecdh_key;
388 }
389
390#if defined(BOTAN_HAS_X25519)
391 if(group_params.is_x25519()) {
392 return std::make_unique<X25519_PrivateKey>(rng);
393 }
394#endif
395
396#if defined(BOTAN_HAS_X448)
397 if(group_params.is_x448()) {
398 return std::make_unique<X448_PrivateKey>(rng);
399 }
400#endif
401
402 if(group_params.is_kem()) {
403 throw TLS_Exception(Alert::IllegalParameter, "cannot generate an ephemeral KEX key for a KEM");
404 }
405
406 throw TLS_Exception(Alert::DecodeError, "cannot create a key offering without a group definition");
407}
408
409std::unique_ptr<PK_Key_Agreement_Key> TLS::Callbacks::tls12_generate_ephemeral_ecdh_key(
410 TLS::Group_Params group, RandomNumberGenerator& rng, EC_Point_Format tls12_ecc_pubkey_encoding_format) {
411 // Delegating to the "universal" callback to obtain an ECDH key pair
412 auto key = tls_generate_ephemeral_key(group, rng);
413
414 // For ordinary ECDH key pairs (that are derived from `ECDH_PublicKey`), we
415 // set the internal point encoding flag for the key before passing it on into
416 // the TLS 1.2 implementation. For user-defined keypair types (e.g. to
417 // offload to some crypto hardware) inheriting from Botan's `ECDH_PublicKey`
418 // might not be feasible. Such users should consider overriding this
419 // ECDH-specific callback and ensure that their custom class handles the
420 // public point encoding as requested by `tls12_ecc_pubkey_encoding_format`.
421 if(auto* ecc_key = dynamic_cast<ECDH_PublicKey*>(key.get())) {
422 ecc_key->set_point_encoding(tls12_ecc_pubkey_encoding_format);
423 }
424
425 return key;
426}
427
429 const std::variant<TLS::Group_Params, DL_Group>& group,
430 const PK_Key_Agreement_Key& private_key,
431 const std::vector<uint8_t>& public_value,
433 const Policy& policy) {
434 const auto kex_pub_key = [&]() {
435 try {
436 return tls_deserialize_peer_public_key(group, public_value);
437 } catch(const Decoding_Error& ex) {
438 // This exception means that the public key was invalid. However,
439 // TLS' DecodeError would imply that a protocol message was invalid.
440 throw TLS_Exception(Alert::IllegalParameter, ex.what());
441 } catch(const Invalid_Argument& ex) {
442 throw TLS_Exception(Alert::IllegalParameter, ex.what());
443 }
444 }();
445
446 BOTAN_ASSERT_NONNULL(kex_pub_key);
447 policy.check_peer_key_acceptable(*kex_pub_key);
448
449 // RFC 8422 - 5.11.
450 // With X25519 and X448, a receiving party MUST check whether the
451 // computed premaster secret is the all-zero value and abort the
452 // handshake if so, as described in Section 6 of [RFC7748].
453 //
454 // This is done within the key agreement operation and throws
455 // an Invalid_Argument exception if the shared secret is all-zero.
456 try {
457 const PK_Key_Agreement ka(private_key, rng, "Raw");
458 return ka.derive_key(0, kex_pub_key->raw_public_key_bits()).bits_of();
459 } catch(const Invalid_Argument& ex) {
460 throw TLS_Exception(Alert::IllegalParameter, ex.what());
461 }
462}
463
467
468std::vector<uint8_t> TLS::Callbacks::tls_provide_cert_status(const std::vector<X509_Certificate>& chain,
469 const Certificate_Status_Request& csr) {
470 BOTAN_UNUSED(chain, csr);
471 return std::vector<uint8_t>();
472}
473
474void TLS::Callbacks::tls_log_error(const char* err) {
475 BOTAN_UNUSED(err);
476}
477
478void TLS::Callbacks::tls_log_debug(const char* what) {
479 BOTAN_UNUSED(what);
480}
481
482void TLS::Callbacks::tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len) {
483 BOTAN_UNUSED(descr, val, val_len);
484}
485
486void TLS::Callbacks::tls_ssl_key_log_data(std::string_view label,
487 std::span<const uint8_t> client_random,
488 std::span<const uint8_t> secret) const {
489 BOTAN_UNUSED(label, client_random, secret);
490}
491
492std::unique_ptr<KDF> TLS::Callbacks::tls12_protocol_specific_kdf(std::string_view prf_algo) const {
493 if(prf_algo == "MD5" || prf_algo == "SHA-1") {
494 return KDF::create_or_throw("TLS-12-PRF(SHA-256)");
495 }
496
497 return KDF::create_or_throw(Botan::fmt("TLS-12-PRF({})", prf_algo));
498}
499
500} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
static DL_Group from_name(std::string_view name)
Definition dl_group.cpp:266
static std::optional< EC_AffinePoint > deserialize_uncompressed(const EC_Group &group, std::span< const uint8_t > bytes)
static std::optional< EC_AffinePoint > deserialize_compressed(const EC_Group &group, std::span< const uint8_t > bytes)
static EC_Group from_name(std::string_view name)
Definition ec_group.cpp:478
const char * what() const noexcept override
Definition exceptn.h:94
static std::unique_ptr< KDF > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition kdf.cpp:208
secure_vector< uint8_t > bits_of() const
Definition symkey.h:46
size_t encapsulated_key_length() const
Definition pubkey.cpp:189
void decrypt(std::span< uint8_t > out_shared_key, std::span< const uint8_t > encap_key, size_t desired_shared_key_len=32, std::span< const uint8_t > salt={})
Definition pubkey.cpp:208
KEM_Encapsulation encrypt(RandomNumberGenerator &rng, size_t desired_shared_key_len=32, std::span< const uint8_t > salt={})
Definition pubkey.h:672
SymmetricKey derive_key(size_t key_len, std::span< const uint8_t > peer_key, std::span< const uint8_t > salt) const
Definition pubkey.cpp:249
std::vector< uint8_t > sign_message(const uint8_t in[], size_t length, RandomNumberGenerator &rng)
Definition pubkey.h:191
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
Definition pubkey.cpp:415
std::string result_string() const
virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const
virtual std::vector< uint8_t > tls_provide_cert_status(const std::vector< X509_Certificate > &chain, const Certificate_Status_Request &csr)
virtual std::string tls_peer_network_identity()
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
virtual std::vector< std::vector< uint8_t > > tls_provide_cert_chain_status(const std::vector< X509_Certificate > &chain, const Certificate_Status_Request &csr)
virtual void tls_log_debug_bin(const char *descr, const uint8_t val[], size_t val_len)
virtual void tls_log_error(const char *err)
virtual void tls_log_debug(const char *what)
virtual std::unique_ptr< PK_Key_Agreement_Key > tls12_generate_ephemeral_ecdh_key(TLS::Group_Params group, RandomNumberGenerator &rng, EC_Point_Format tls12_ecc_pubkey_encoding_format)
virtual std::string tls_server_choose_app_protocol(const std::vector< std::string > &client_protos)
virtual std::optional< OCSP::Response > tls_parse_ocsp_response(const std::vector< uint8_t > &raw_response)
virtual void tls_examine_extensions(const Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
virtual std::vector< uint8_t > tls_sign_message(const Private_Key &key, RandomNumberGenerator &rng, std::string_view padding, Signature_Format format, const std::vector< uint8_t > &msg)
virtual void tls_session_established(const Session_Summary &session)
virtual void tls_verify_raw_public_key(const Public_Key &raw_public_key, Usage_Type usage, std::string_view hostname, const TLS::Policy &policy)
virtual std::unique_ptr< KDF > tls12_protocol_specific_kdf(std::string_view prf_algo) const
virtual KEM_Encapsulation tls_kem_encapsulate(TLS::Group_Params group, const std::vector< uint8_t > &encoded_public_key, RandomNumberGenerator &rng, const Policy &policy)
virtual bool tls_should_persist_resumption_information(const Session &session)
virtual std::unique_ptr< Private_Key > tls_kem_generate_key(TLS::Group_Params group, RandomNumberGenerator &rng)
virtual std::unique_ptr< Public_Key > tls_deserialize_peer_public_key(const std::variant< TLS::Group_Params, DL_Group > &group, std::span< const uint8_t > key_bits)
virtual secure_vector< uint8_t > tls_ephemeral_key_agreement(const std::variant< TLS::Group_Params, DL_Group > &group, const PK_Key_Agreement_Key &private_key, const std::vector< uint8_t > &public_value, RandomNumberGenerator &rng, const Policy &policy)
virtual secure_vector< uint8_t > tls_kem_decapsulate(TLS::Group_Params group, const Private_Key &private_key, const std::vector< uint8_t > &encapsulated_bytes, RandomNumberGenerator &rng, const Policy &policy)
virtual std::chrono::system_clock::time_point tls_current_timestamp()
virtual uint64_t tls_current_monotonic_clock_ms()
virtual std::unique_ptr< PK_Key_Agreement_Key > tls_generate_ephemeral_key(const std::variant< TLS::Group_Params, DL_Group > &group, RandomNumberGenerator &rng)
virtual void tls_verify_cert_chain(const std::vector< X509_Certificate > &cert_chain, const std::vector< std::optional< OCSP::Response > > &ocsp_responses, const std::vector< Certificate_Store * > &trusted_roots, Usage_Type usage, std::string_view hostname, const TLS::Policy &policy)
virtual void tls_ssl_key_log_data(std::string_view label, std::span< const uint8_t > client_random, std::span< const uint8_t > secret) const
virtual bool tls_verify_message(const Public_Key &key, std::string_view padding, Signature_Format format, const std::vector< uint8_t > &msg, const std::vector< uint8_t > &sig)
virtual void tls_inspect_handshake_msg(const Handshake_Message &message)
std::optional< std::string > to_algorithm_spec() const
constexpr bool is_pqc_hybrid() const
Definition tls_algos.h:240
constexpr bool is_kem() const
Definition tls_algos.h:242
constexpr bool is_pure_frodokem() const
Definition tls_algos.h:201
constexpr bool is_pure_ml_kem() const
Definition tls_algos.h:196
static std::unique_ptr< Hybrid_KEM_PrivateKey > generate_from_group(Group_Params group, RandomNumberGenerator &rng)
static std::unique_ptr< Hybrid_KEM_PublicKey > load_for_group(Group_Params group, std::span< const uint8_t > concatenated_public_values)
virtual void check_peer_key_acceptable(const Public_Key &public_key) const
virtual bool require_cert_revocation_info() const
virtual size_t minimum_signature_strength() const
Protocol_Version version() const
Definition tls_session.h:74
std::chrono::seconds lifetime_hint() const
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
KyberMode ML_KEM_Mode
Definition ml_kem.h:21
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, std::string_view hostname, Usage_Type usage, std::chrono::system_clock::time_point ref_time, std::chrono::milliseconds ocsp_timeout, const std::vector< std::optional< OCSP::Response > > &ocsp_resp)
Signature_Format
Definition pk_keys.h:32
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128