Botan 3.12.0
Crypto and TLS for C&
Botan::Certificate_Store_In_SQLite Class Referencefinal

#include <certstor_sqlite.h>

Inheritance diagram for Botan::Certificate_Store_In_SQLite:
Botan::Certificate_Store_In_SQL Botan::Certificate_Store

Public Member Functions

void affirm_cert (const X509_Certificate &cert)
 Reverses the revocation for "cert".
std::vector< X509_DNall_subjects () const override
bool certificate_known (const X509_Certificate &cert) const
 Certificate_Store_In_SQLite (std::string_view db_path, std::string_view passwd, RandomNumberGenerator &rng, std::string_view table_prefix="")
bool contains (const X509_Certificate &cert) const override
std::vector< X509_Certificatefind_all_certs (const X509_DN &subject_dn, const std::vector< uint8_t > &key_id) const override
std::optional< X509_Certificatefind_cert (const X509_DN &subject_dn, const std::vector< uint8_t > &key_id) const override
std::optional< X509_Certificatefind_cert_by_issuer_dn_and_serial_number (const X509_DN &issuer_dn, std::span< const uint8_t > serial_number) const override
std::optional< X509_Certificatefind_cert_by_pubkey_sha1 (const std::vector< uint8_t > &key_hash) const override
std::optional< X509_Certificatefind_cert_by_raw_subject_dn_sha256 (const std::vector< uint8_t > &subject_hash) const override
std::vector< X509_Certificatefind_certs_for_key (const Private_Key &key) const
 Returns all certificates for private key "key".
std::optional< X509_CRLfind_crl_for (const X509_Certificate &issuer) const override
std::shared_ptr< const Private_Keyfind_key (const X509_Certificate &cert) const
 Returns the private key for "cert" or an empty shared_ptr if none was found.
std::vector< X509_CRLgenerate_crls () const
bool insert_cert (const X509_Certificate &cert)
bool insert_key (const X509_Certificate &cert, const Private_Key &key)
bool remove_cert (const X509_Certificate &cert)
void remove_key (const Private_Key &key)
 Removes "key" from the store.
void revoke_cert (const X509_Certificate &cert, CRL_Code reason)
 Marks "cert" as revoked with no time specified.
void revoke_cert (const X509_Certificate &cert, CRL_Code reason, const X509_Time &time)
 Marks "cert" as revoked starting from "time".

Detailed Description

Certificate and private key store backed by an sqlite (https://sqlite.org) database.

Definition at line 18 of file certstor_sqlite.h.

Constructor & Destructor Documentation

◆ Certificate_Store_In_SQLite()

Botan::Certificate_Store_In_SQLite::Certificate_Store_In_SQLite ( std::string_view db_path,
std::string_view passwd,
RandomNumberGenerator & rng,
std::string_view table_prefix = "" )

Create/open a certificate store.

Parameters
db_pathpath to the database file
passwdpassword to encrypt private keys in the database
Random Number Generatorsused for encrypting keys
table_prefixoptional prefix for db table names

Definition at line 14 of file certstor_sqlite.cpp.

17 :
18 Certificate_Store_In_SQL(std::make_shared<Sqlite3_Database>(db_path), passwd, rng, table_prefix) {}
Certificate_Store_In_SQL(std::shared_ptr< SQL_Database > db, std::string_view passwd, RandomNumberGenerator &rng, std::string_view table_prefix="")

References Botan::Certificate_Store_In_SQL::Certificate_Store_In_SQL().

Member Function Documentation

◆ affirm_cert()

void Botan::Certificate_Store_In_SQL::affirm_cert ( const X509_Certificate & cert)
inherited

Reverses the revocation for "cert".

Definition at line 293 of file certstor_sql.cpp.

293 {
294 auto stmt = m_database->new_statement("DELETE FROM " + m_prefix + "revoked WHERE fingerprint == ?1");
295
296 stmt->bind(1, cert.fingerprint("SHA-256"));
297 stmt->spin();
298}

References Botan::X509_Certificate::fingerprint().

◆ all_subjects()

std::vector< X509_DN > Botan::Certificate_Store_In_SQL::all_subjects ( ) const
overridevirtualinherited

Returns all subject DNs known to the store instance.

Implements Botan::Certificate_Store.

Definition at line 128 of file certstor_sql.cpp.

128 {
129 std::vector<X509_DN> ret;
130 auto stmt = m_database->new_statement("SELECT subject_dn FROM " + m_prefix + "certificates");
131
132 while(stmt->step()) {
133 auto blob = stmt->get_blob(0);
134 BER_Decoder dec(std::span<const uint8_t>{blob.first, blob.second}, BER_Decoder::Limits::DER());
135 X509_DN dn;
136
137 dn.decode_from(dec);
138
139 ret.push_back(dn);
140 }
141
142 return ret;
143}
static Limits DER()
Definition ber_dec.h:35

References Botan::X509_DN::decode_from(), and Botan::BER_Decoder::Limits::DER().

◆ certificate_known()

bool Botan::Certificate_Store::certificate_known ( const X509_Certificate & cert) const
inherited

Old version of contains

Definition at line 24 of file certstor.cpp.

24 {
25 return contains(cert);
26}
virtual bool contains(const X509_Certificate &cert) const
Definition certstor.cpp:28

References contains().

Referenced by find_cert_by_issuer_dn_and_serial_number().

◆ contains()

bool Botan::Certificate_Store_In_SQL::contains ( const X509_Certificate & cert) const
overridevirtualinherited
Returns
whether this certificate is contained within the store
Parameters
certcertificate to be searched

Default implementation uses find_all_certs

Reimplemented from Botan::Certificate_Store.

Definition at line 168 of file certstor_sql.cpp.

168 {
169 auto stmt = m_database->new_statement("SELECT 1 FROM " + m_prefix + "certificates WHERE fingerprint == ?1");
170 stmt->bind(1, cert.fingerprint("SHA-256"));
171 return stmt->step();
172}

References Botan::X509_Certificate::fingerprint().

◆ find_all_certs()

std::vector< X509_Certificate > Botan::Certificate_Store_In_SQL::find_all_certs ( const X509_DN & subject_dn,
const std::vector< uint8_t > & key_id ) const
overridevirtualinherited

Find all certificates with a given Subject DN. Subject DN and even the key identifier might not be unique.

Implements Botan::Certificate_Store.

Definition at line 74 of file certstor_sql.cpp.

75 {
76 std::vector<X509_Certificate> certs;
77
78 std::shared_ptr<SQL_Database::Statement> stmt;
79
80 const std::vector<uint8_t> dn_encoding = subject_dn.BER_encode();
81
82 if(key_id.empty()) {
83 stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE subject_dn == ?1");
84 stmt->bind(1, dn_encoding);
85 } else {
86 stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix +
87 "certificates WHERE\
88 subject_dn == ?1 AND (key_id IS NULL OR key_id == ?2)");
89 stmt->bind(1, dn_encoding);
90 stmt->bind(2, key_id);
91 }
92
93 while(stmt->step()) {
94 auto blob = stmt->get_blob(0);
95 certs.push_back(X509_Certificate(blob.first, blob.second));
96 }
97
98 return certs;
99}

References Botan::ASN1_Object::BER_encode().

◆ find_cert()

std::optional< X509_Certificate > Botan::Certificate_Store_In_SQL::find_cert ( const X509_DN & subject_dn,
const std::vector< uint8_t > & key_id ) const
overridevirtualinherited

Returns the first certificate with matching subject DN and optional key ID.

Reimplemented from Botan::Certificate_Store.

Definition at line 48 of file certstor_sql.cpp.

49 {
50 std::shared_ptr<SQL_Database::Statement> stmt;
51
52 const std::vector<uint8_t> dn_encoding = subject_dn.BER_encode();
53
54 if(key_id.empty()) {
55 stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix +
56 "certificates WHERE subject_dn == ?1 LIMIT 1");
57 stmt->bind(1, dn_encoding);
58 } else {
59 stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix +
60 "certificates WHERE\
61 subject_dn == ?1 AND (key_id IS NULL OR key_id == ?2) LIMIT 1");
62 stmt->bind(1, dn_encoding);
63 stmt->bind(2, key_id);
64 }
65
66 while(stmt->step()) {
67 auto blob = stmt->get_blob(0);
68 return X509_Certificate(blob.first, blob.second);
69 }
70
71 return std::optional<X509_Certificate>();
72}

References Botan::ASN1_Object::BER_encode().

Referenced by remove_cert().

◆ find_cert_by_issuer_dn_and_serial_number()

std::optional< X509_Certificate > Botan::Certificate_Store_In_SQL::find_cert_by_issuer_dn_and_serial_number ( const X509_DN & issuer_dn,
std::span< const uint8_t > serial_number ) const
overridevirtualinherited

Find a certificate by searching for one with a matching issuer DN and serial number. Used for CMS or PKCS#7.

Parameters
issuer_dnthe distinguished name of the issuer
serial_numberthe certificate's serial number
Returns
a matching certificate or nullopt otherwise

Implements Botan::Certificate_Store.

Definition at line 111 of file certstor_sql.cpp.

112 {
113 throw Not_Implemented("Certificate_Store_In_SQL::find_cert_by_issuer_dn_and_serial_number");
114}

◆ find_cert_by_pubkey_sha1()

std::optional< X509_Certificate > Botan::Certificate_Store_In_SQL::find_cert_by_pubkey_sha1 ( const std::vector< uint8_t > & key_hash) const
overridevirtualinherited

Find a certificate by searching for one with a matching SHA-1 hash of public key. Used for OCSP.

Parameters
key_hashSHA-1 hash of the subject's public key
Returns
a matching certificate or nullopt otherwise

Implements Botan::Certificate_Store.

Definition at line 101 of file certstor_sql.cpp.

102 {
103 throw Not_Implemented("Certificate_Store_In_SQL::find_cert_by_pubkey_sha1");
104}

◆ find_cert_by_raw_subject_dn_sha256()

std::optional< X509_Certificate > Botan::Certificate_Store_In_SQL::find_cert_by_raw_subject_dn_sha256 ( const std::vector< uint8_t > & subject_hash) const
overridevirtualinherited

Find a certificate by searching for one with a matching SHA-256 hash of raw subject name. Used for OCSP.

Parameters
subject_hashSHA-256 hash of the subject's raw name
Returns
a matching certificate or nullopt otherwise

Implements Botan::Certificate_Store.

Definition at line 106 of file certstor_sql.cpp.

107 {
108 throw Not_Implemented("Certificate_Store_In_SQL::find_cert_by_raw_subject_dn_sha256");
109}

◆ find_certs_for_key()

std::vector< X509_Certificate > Botan::Certificate_Store_In_SQL::find_certs_for_key ( const Private_Key & key) const
inherited

Returns all certificates for private key "key".

Definition at line 208 of file certstor_sql.cpp.

208 {
209 auto fprint = key.fingerprint_private("SHA-256");
210 auto stmt =
211 m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE priv_fingerprint == ?1");
212
213 stmt->bind(1, fprint);
214
215 std::vector<X509_Certificate> certs;
216 while(stmt->step()) {
217 auto blob = stmt->get_blob(0);
218 certs.push_back(X509_Certificate(blob.first, blob.second));
219 }
220
221 return certs;
222}

References Botan::Private_Key::fingerprint_private().

◆ find_crl_for()

std::optional< X509_CRL > Botan::Certificate_Store_In_SQL::find_crl_for ( const X509_Certificate & issuer) const
overridevirtualinherited

Generates a CRL for all certificates issued by the given issuer.

Reimplemented from Botan::Certificate_Store.

Definition at line 116 of file certstor_sql.cpp.

116 {
117 const auto all_crls = generate_crls();
118
119 for(const auto& crl : all_crls) {
120 if(!crl.get_revoked().empty() && crl.issuer_dn() == subject.issuer_dn()) {
121 return crl;
122 }
123 }
124
125 return std::optional<X509_CRL>();
126}
std::vector< X509_CRL > generate_crls() const

References generate_crls(), and Botan::X509_Certificate::issuer_dn().

◆ find_key()

std::shared_ptr< const Private_Key > Botan::Certificate_Store_In_SQL::find_key ( const X509_Certificate & cert) const
inherited

Returns the private key for "cert" or an empty shared_ptr if none was found.

Definition at line 188 of file certstor_sql.cpp.

188 {
189 auto stmt = m_database->new_statement("SELECT key FROM " + m_prefix +
190 "keys "
191 "JOIN " +
192 m_prefix + "certificates ON " + m_prefix + "keys.fingerprint == " + m_prefix +
193 "certificates.priv_fingerprint "
194 "WHERE " +
195 m_prefix + "certificates.fingerprint == ?1");
196 stmt->bind(1, cert.fingerprint("SHA-256"));
197
198 std::shared_ptr<const Private_Key> key;
199 while(stmt->step()) {
200 auto blob = stmt->get_blob(0);
201 DataSource_Memory src(blob.first, blob.second);
202 key = PKCS8::load_key(src, m_password);
203 }
204
205 return key;
206}
std::unique_ptr< Private_Key > load_key(DataSource &source, const std::function< std::string()> &get_pass)
Definition pkcs8.cpp:319

References Botan::X509_Certificate::fingerprint(), and Botan::PKCS8::load_key().

Referenced by insert_key().

◆ generate_crls()

std::vector< X509_CRL > Botan::Certificate_Store_In_SQL::generate_crls ( ) const
inherited

Generates Certificate Revocation Lists for all certificates marked as revoked. A CRL is returned for each unique issuer DN.

Definition at line 300 of file certstor_sql.cpp.

300 {
301 auto stmt = m_database->new_statement("SELECT certificate,reason,time FROM " + m_prefix +
302 "revoked "
303 "JOIN " +
304 m_prefix + "certificates ON " + m_prefix +
305 "certificates.fingerprint == " + m_prefix + "revoked.fingerprint");
306
307 std::map<X509_DN, std::vector<CRL_Entry>> crls;
308 while(stmt->step()) {
309 auto blob = stmt->get_blob(0);
310 auto cert = X509_Certificate(std::vector<uint8_t>(blob.first, blob.first + blob.second));
311 auto code = static_cast<CRL_Code>(stmt->get_size_t(1));
312 auto ent = CRL_Entry(cert, code);
313
314 auto i = crls.find(cert.issuer_dn());
315 if(i == crls.end()) {
316 crls.insert(std::make_pair(cert.issuer_dn(), std::vector<CRL_Entry>({ent})));
317 } else {
318 i->second.push_back(ent);
319 }
320 }
321
322 const X509_Time t(std::chrono::system_clock::now());
323
324 std::vector<X509_CRL> ret;
325 ret.reserve(crls.size());
326
327 for(const auto& p : crls) {
328 ret.push_back(X509_CRL(p.first, t, t, p.second));
329 }
330
331 return ret;
332}
ASN1_Time X509_Time
Definition asn1_obj.h:23

Referenced by find_crl_for().

◆ insert_cert()

bool Botan::Certificate_Store_In_SQL::insert_cert ( const X509_Certificate & cert)
inherited

Inserts "cert" into the store, returns false if the certificate is already known and true if insertion was successful.

Definition at line 145 of file certstor_sql.cpp.

145 {
146 const std::vector<uint8_t> dn_encoding = cert.subject_dn().BER_encode();
147 const std::vector<uint8_t> cert_encoding = cert.BER_encode();
148
149 auto stmt = m_database->new_statement("INSERT OR REPLACE INTO " + m_prefix +
150 "certificates (\
151 fingerprint, \
152 subject_dn, \
153 key_id, \
154 priv_fingerprint, \
155 certificate \
156 ) VALUES ( ?1, ?2, ?3, ?4, ?5 )");
157
158 stmt->bind(1, cert.fingerprint("SHA-256"));
159 stmt->bind(2, dn_encoding);
160 stmt->bind(3, cert.subject_key_id());
161 stmt->bind(4, std::vector<uint8_t>());
162 stmt->bind(5, cert_encoding);
163 stmt->spin();
164
165 return true;
166}

References Botan::ASN1_Object::BER_encode(), Botan::X509_Certificate::fingerprint(), Botan::X509_Certificate::subject_dn(), and Botan::X509_Certificate::subject_key_id().

Referenced by insert_key(), revoke_cert(), and revoke_cert().

◆ insert_key()

bool Botan::Certificate_Store_In_SQL::insert_key ( const X509_Certificate & cert,
const Private_Key & key )
inherited

Inserts "key" for "cert" into the store, returns false if the key is already known and true if insertion was successful.

Definition at line 224 of file certstor_sql.cpp.

224 {
225 insert_cert(cert);
226
227 if(find_key(cert)) {
228 return false;
229 }
230
231 auto pkcs8 = PKCS8::BER_encode(key, m_rng, m_password);
232 auto fprint = key.fingerprint_private("SHA-256");
233
234 auto stmt1 =
235 m_database->new_statement("INSERT OR REPLACE INTO " + m_prefix + "keys ( fingerprint, key ) VALUES ( ?1, ?2 )");
236
237 stmt1->bind(1, fprint);
238 stmt1->bind(2, pkcs8.data(), pkcs8.size());
239 stmt1->spin();
240
241 auto stmt2 = m_database->new_statement("UPDATE " + m_prefix +
242 "certificates SET priv_fingerprint = ?1 WHERE fingerprint == ?2");
243
244 stmt2->bind(1, fprint);
245 stmt2->bind(2, cert.fingerprint("SHA-256"));
246 stmt2->spin();
247
248 return true;
249}
bool insert_cert(const X509_Certificate &cert)
std::shared_ptr< const Private_Key > find_key(const X509_Certificate &cert) const
Returns the private key for "cert" or an empty shared_ptr if none was found.
std::vector< uint8_t > BER_encode(const Private_Key &key, RandomNumberGenerator &rng, std::string_view pass, std::chrono::milliseconds msec, std::string_view pbe_algo)
Definition pkcs8.cpp:166

References Botan::PKCS8::BER_encode(), find_key(), Botan::X509_Certificate::fingerprint(), Botan::Private_Key::fingerprint_private(), and insert_cert().

◆ remove_cert()

bool Botan::Certificate_Store_In_SQL::remove_cert ( const X509_Certificate & cert)
inherited

Removes "cert" from the store. Returns false if the certificate could not be found and true if removal was successful.

Definition at line 174 of file certstor_sql.cpp.

174 {
175 if(!find_cert(cert.subject_dn(), cert.subject_key_id())) {
176 return false;
177 }
178
179 auto stmt = m_database->new_statement("DELETE FROM " + m_prefix + "certificates WHERE fingerprint == ?1");
180
181 stmt->bind(1, cert.fingerprint("SHA-256"));
182 stmt->spin();
183
184 return true;
185}
std::optional< X509_Certificate > find_cert(const X509_DN &subject_dn, const std::vector< uint8_t > &key_id) const override

References find_cert(), Botan::X509_Certificate::fingerprint(), Botan::X509_Certificate::subject_dn(), and Botan::X509_Certificate::subject_key_id().

◆ remove_key()

void Botan::Certificate_Store_In_SQL::remove_key ( const Private_Key & key)
inherited

Removes "key" from the store.

Definition at line 251 of file certstor_sql.cpp.

251 {
252 auto fprint = key.fingerprint_private("SHA-256");
253 auto stmt = m_database->new_statement("DELETE FROM " + m_prefix + "keys WHERE fingerprint == ?1");
254
255 stmt->bind(1, fprint);
256 stmt->spin();
257}

References Botan::Private_Key::fingerprint_private().

◆ revoke_cert() [1/2]

void Botan::Certificate_Store_In_SQL::revoke_cert ( const X509_Certificate & cert,
CRL_Code reason )
inherited

Marks "cert" as revoked with no time specified.

Definition at line 280 of file certstor_sql.cpp.

280 {
281 insert_cert(cert);
282
283 auto stmt1 = m_database->new_statement("INSERT OR REPLACE INTO " + m_prefix +
284 "revoked ( fingerprint, reason, time ) VALUES ( ?1, ?2, ?3 )");
285
286 stmt1->bind(1, cert.fingerprint("SHA-256"));
287 stmt1->bind(2, static_cast<uint32_t>(code));
288 stmt1->bind(3, static_cast<size_t>(-1));
289
290 stmt1->spin();
291}

References Botan::X509_Certificate::fingerprint(), and insert_cert().

◆ revoke_cert() [2/2]

void Botan::Certificate_Store_In_SQL::revoke_cert ( const X509_Certificate & cert,
CRL_Code reason,
const X509_Time & time )
inherited

Marks "cert" as revoked starting from "time".

Definition at line 260 of file certstor_sql.cpp.

260 {
261 // TODO(Botan4) require that time be valid
262 insert_cert(cert);
263
264 auto stmt1 = m_database->new_statement("INSERT OR REPLACE INTO " + m_prefix +
265 "revoked ( fingerprint, reason, time ) VALUES ( ?1, ?2, ?3 )");
266
267 stmt1->bind(1, cert.fingerprint("SHA-256"));
268 stmt1->bind(2, static_cast<uint32_t>(code));
269
270 if(time.time_is_set()) {
271 stmt1->bind(3, time.BER_encode());
272 } else {
273 stmt1->bind(3, static_cast<size_t>(-1));
274 }
275
276 stmt1->spin();
277}

References Botan::ASN1_Object::BER_encode(), Botan::X509_Certificate::fingerprint(), insert_cert(), and Botan::ASN1_Time::time_is_set().


The documentation for this class was generated from the following files: