Botan 3.12.0
Crypto and TLS for C&
x509_cert_cache.cpp
Go to the documentation of this file.
1/*
2* (C) 2026 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/internal/x509_cert_cache.h>
8
9#include <botan/hash.h>
10
11namespace Botan {
12
13X509_Certificate_Cache::X509_Certificate_Cache(size_t max_entries) : m_max_entries(max_entries) {}
14
15X509_Certificate X509_Certificate_Cache::find_or_insert(std::span<const uint8_t> encoding) {
16 if(m_max_entries == 0) {
17 return X509_Certificate(encoding);
18 }
19
20 // Hash the DER
21 auto sha256 = HashFunction::create_or_throw("SHA-256");
22 DER_Hash hash;
23 sha256->update(encoding);
24 sha256->final(hash.m_hash);
25
26 // Check for a cache hit
27 {
28 const lock_guard_type<mutex_type> lock(m_mutex);
29 if(auto it = m_cache.find(hash); it != m_cache.end()) {
30 return it->second;
31 }
32 }
33
34 // Deserialize the certificate
35 X509_Certificate cert(encoding);
36
37 // Lock again
38 const lock_guard_type<mutex_type> lock(m_mutex);
39
40 // Check for a cache hit (possibly racing with another thread)
41 if(auto it = m_cache.find(hash); it != m_cache.end()) {
42 return it->second;
43 }
44
45 // Evict if required
46 //
47 // Effectively this is just a random drop, might make sense to add LRU here
48 while(m_cache.size() >= m_max_entries) {
49 m_cache.erase(m_cache.begin());
50 }
51
52 // Add the newly deserialized cert to the cache
53 auto it = m_cache.emplace(hash, std::move(cert)).first;
54 return it->second;
55}
56
57} // namespace Botan
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:308
X509_Certificate find_or_insert(std::span< const uint8_t > encoding)
X509_Certificate_Cache(size_t max_entries=64)
secure_vector< T > lock(const std::vector< T > &in)
Definition secmem.h:80
lock_guard< T > lock_guard_type
Definition mutex.h:55