certificate_db.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
10#include "base/HardFun.h"
11#include "base/TextException.h"
12#include "sbuf/Stream.h"
14
15#include <cerrno>
16#include <fstream>
17#include <memory>
18#include <stdexcept>
19#if HAVE_SYS_STAT_H
20#include <sys/stat.h>
21#endif
22#if HAVE_FCNTL_H
23#include <fcntl.h>
24#endif
25#if HAVE_SYS_FILE_H
26#include <sys/file.h>
27#endif
28
29Ssl::Lock::Lock(std::string const &aFilename) :
30 filename(aFilename),
31#if _SQUID_WINDOWS_
32 hFile(INVALID_HANDLE_VALUE)
33#else
34 fd(-1)
35#endif
36{
37}
38
40{
41#if _SQUID_WINDOWS_
42 return hFile != INVALID_HANDLE_VALUE;
43#else
44 return fd != -1;
45#endif
46}
47
49{
50
51#if _SQUID_WINDOWS_
52 hFile = CreateFile(TEXT(filename.c_str()), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
53 if (hFile == INVALID_HANDLE_VALUE)
54#else
55 fd = open(filename.c_str(), O_RDWR);
56 if (fd == -1)
57#endif
58 throw TextException(ToSBuf("Failed to open file ", filename), Here());
59
60#if _SQUID_WINDOWS_
61 if (!LockFile(hFile, 0, 0, 1, 0))
62#elif _SQUID_SOLARIS_
63 if (lockf(fd, F_LOCK, 0) != 0)
64#else
65 if (flock(fd, LOCK_EX) != 0)
66#endif
67 throw TextException(ToSBuf("Failed to get a lock of ", filename), Here());
68}
69
71{
72#if _SQUID_WINDOWS_
73 if (hFile != INVALID_HANDLE_VALUE) {
74 UnlockFile(hFile, 0, 0, 1, 0);
75 CloseHandle(hFile);
76 hFile = INVALID_HANDLE_VALUE;
77 }
78#else
79 if (fd != -1) {
80#if _SQUID_SOLARIS_
81 lockf(fd, F_ULOCK, 0);
82#else
83 flock(fd, LOCK_UN);
84#endif
85 close(fd);
86 fd = -1;
87 }
88#endif
89 else
90 throw TextException(ToSBuf("Lock is already unlocked for ", filename), Here());
91}
92
94{
95 if (locked())
96 unlock();
97}
98
99Ssl::Locker::Locker(Lock &aLock, const SourceLocation &aCaller):
100 weLocked(false),
101 lock(aLock),
102 caller(aCaller)
103{
104 if (!lock.locked()) {
105 lock.lock();
106 weLocked = true;
107 }
108}
109
111{
112 if (weLocked)
113 lock.unlock();
114}
115
117{
118 row = (char **)OPENSSL_malloc(sizeof(char *) * (width + 1));
119 for (size_t i = 0; i < width + 1; ++i)
120 row[i] = nullptr;
121}
122
123Ssl::CertificateDb::Row::Row(char **aRow, size_t aWidth): width(aWidth)
124{
125 row = aRow;
126}
127
129{
130 if (!row)
131 return;
132
133 void *max;
134 if ((max = (void *)row[width]) != nullptr) {
135 // It is an openSSL allocated row. The TXT_DB_read function stores the
136 // index and row items one one memory segment. The row[width] points
137 // to the end of buffer. We have to check for items in the array which
138 // are not stored in this segment. These items should released.
139 for (size_t i = 0; i < width + 1; ++i) {
140 if (((row[i] < (char *)row) || (row[i] > max)) && (row[i] != nullptr))
141 OPENSSL_free(row[i]);
142 }
143 } else {
144 for (size_t i = 0; i < width + 1; ++i) {
145 if (row[i])
146 OPENSSL_free(row[i]);
147 }
148 }
149 OPENSSL_free(row);
150}
151
153{
154 row = nullptr;
155}
156
157void Ssl::CertificateDb::Row::setValue(size_t cell, char const * value)
158{
159 assert(cell < width);
160 if (row[cell]) {
161 free(row[cell]);
162 }
163 if (value) {
164 row[cell] = static_cast<char *>(OPENSSL_malloc(sizeof(char) * (strlen(value) + 1)));
165 memcpy(row[cell], value, sizeof(char) * (strlen(value) + 1));
166 } else
167 row[cell] = nullptr;
168}
169
171{
172 return row;
173}
174
175void Ssl::CertificateDb::sq_TXT_DB_delete(TXT_DB *db, const char **row)
176{
177 if (!db)
178 return;
179
180#if SQUID_SSLTXTDB_PSTRINGDATA
181 for (int i = 0; i < sk_OPENSSL_PSTRING_num(db->data); ++i) {
182#if SQUID_STACKOF_PSTRINGDATA_HACK
183 const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db->data), i));
184#else
185 const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db->data, i));
186#endif
187#else
188 for (int i = 0; i < sk_num(db->data); ++i) {
189 const char ** current_row = ((const char **)sk_value(db->data, i));
190#endif
191 if (current_row == row) {
193 return;
194 }
195 }
196}
197
198#define countof(arr) (sizeof(arr)/sizeof(*arr))
200 char **rrow;
201#if SQUID_SSLTXTDB_PSTRINGDATA
202 rrow = (char **)sk_OPENSSL_PSTRING_delete(db->data, idx);
203#else
204 rrow = (char **)sk_delete(db->data, idx);
205#endif
206
207 if (!rrow)
208 return;
209
210 Row row(rrow, cnlNumber); // row wrapper used to free the rrow
211
212 const Columns db_indexes[]= {cnlSerial, cnlKey};
213 for (unsigned int i = 0; i < countof(db_indexes); ++i) {
214 void *data = nullptr;
215#if SQUID_SSLTXTDB_PSTRINGDATA
216 if (LHASH_OF(OPENSSL_STRING) *fieldIndex = db->index[db_indexes[i]])
217 data = lh_OPENSSL_STRING_delete(fieldIndex, rrow);
218#else
219 if (LHASH *fieldIndex = db->index[db_indexes[i]])
220 data = OPENSSL_LH_delete(fieldIndex, rrow);
221#endif
222 if (data)
223 assert(data == rrow);
224 }
225}
226
227unsigned long Ssl::CertificateDb::index_serial_hash(const char **a) {
228 const char *n = a[Ssl::CertificateDb::cnlSerial];
229 while (*n == '0')
230 ++n;
231 return OPENSSL_LH_strhash(n);
232}
233
234int Ssl::CertificateDb::index_serial_cmp(const char **a, const char **b) {
235 const char *aa, *bb;
236 for (aa = a[Ssl::CertificateDb::cnlSerial]; *aa == '0'; ++aa);
237 for (bb = b[Ssl::CertificateDb::cnlSerial]; *bb == '0'; ++bb);
238 return strcmp(aa, bb);
239}
240
241unsigned long Ssl::CertificateDb::index_name_hash(const char **a) {
243}
244
245int Ssl::CertificateDb::index_name_cmp(const char **a, const char **b) {
247}
248
249const std::string Ssl::CertificateDb::db_file("index.txt");
250const std::string Ssl::CertificateDb::cert_dir("certs");
251const std::string Ssl::CertificateDb::size_file("size");
252
253Ssl::CertificateDb::CertificateDb(std::string const & aDb_path, size_t aMax_db_size, size_t aFs_block_size)
254 : db_path(aDb_path),
255 db_full(aDb_path + "/" + db_file),
256 cert_full(aDb_path + "/" + cert_dir),
257 size_full(aDb_path + "/" + size_file),
258 max_db_size(aMax_db_size),
259 fs_block_size((aFs_block_size ? aFs_block_size : 2048)),
261{}
262
263bool
264Ssl::CertificateDb::find(std::string const &key, const Security::CertPointer &expectedOrig, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey)
265{
266 const Locker locker(dbLock, Here());
267 load();
268 return pure_find(key, expectedOrig, cert, pkey);
269}
270
271bool Ssl::CertificateDb::purgeCert(std::string const & key) {
272 const Locker locker(dbLock, Here());
273 load();
274 if (!db)
275 return false;
276
277 if (!deleteByKey(key))
278 return false;
279
280 save();
281 return true;
282}
283
284bool
285Ssl::CertificateDb::addCertAndPrivateKey(std::string const &useKey, const Security::CertPointer &cert, const Security::PrivateKeyPointer &pkey, const Security::CertPointer &orig)
286{
287 const Locker locker(dbLock, Here());
288 load();
289 if (!db || !cert || !pkey)
290 return false;
291
292 if(useKey.empty())
293 return false;
294
295 Row row;
296 ASN1_INTEGER * ai = X509_get_serialNumber(cert.get());
297 std::string serial_string;
298 Ssl::BIGNUM_Pointer serial(ASN1_INTEGER_to_BN(ai, nullptr));
299 {
300 const UniqueCString hex_bn(BN_bn2hex(serial.get()));
301 serial_string = std::string(hex_bn.get());
302 }
303 row.setValue(cnlSerial, serial_string.c_str());
304 char ** rrow = TXT_DB_get_by_index(db.get(), cnlSerial, row.getRow());
305 // We are creating certificates with unique serial numbers. If the serial
306 // number is found in the database, the same certificate is already stored.
307 if (rrow != nullptr) {
308 // TODO: check if the stored row is valid.
309 return true;
310 }
311
312 // Remove any entry with given key
313 deleteByKey(useKey);
314
315 // check db size while trying to minimize calls to size()
316 size_t dbSize = size();
317 if ((dbSize == 0 && hasRows()) ||
318 (dbSize > 0 && !hasRows()) ||
319 (dbSize > 10 * max_db_size)) {
320 // Invalid database size, rebuild
321 dbSize = rebuildSize();
322 }
323 while (dbSize > max_db_size && deleteInvalidCertificate()) {
324 dbSize = size(); // get the current database size
325 // and try to find another invalid certificate if needed
326 }
327 // there are no more invalid ones, but there must be valid certificates
328 while (dbSize > max_db_size) {
329 if (!deleteOldestCertificate()) {
330 rebuildSize(); // No certificates in database.Update the size file.
331 save(); // Some entries may have been removed. Update the index file.
332 return false; // errors prevented us from freeing enough space
333 }
334 dbSize = size(); // get the current database size
335 }
336
337 const auto tm = X509_getm_notAfter(cert.get());
338 row.setValue(cnlExp_date, std::string(reinterpret_cast<char *>(tm->data), tm->length).c_str());
339 const auto subject = OneLineSummary(*X509_get_subject_name(cert.get()));
340 row.setValue(cnlName, subject.get());
341 row.setValue(cnlKey, useKey.c_str());
342
343 if (!TXT_DB_insert(db.get(), row.getRow())) {
344 // failed to add index (???) but we may have already modified
345 // the database so save before exit
346 save();
347 return false;
348 }
349 rrow = row.getRow();
350 row.reset();
351
352 std::string filename(cert_full + "/" + serial_string + ".pem");
353 if (!WriteEntry(filename.c_str(), cert, pkey, orig)) {
354 //remove row from txt_db and save
355 sq_TXT_DB_delete(db.get(), (const char **)rrow);
356 save();
357 return false;
358 }
359 addSize(filename);
360
361 save();
362 return true;
363}
364
365void
367 if (db_path == "")
368 throw TextException("Path to db is empty", Here());
369 std::string db_full(db_path + "/" + db_file);
370 std::string cert_full(db_path + "/" + cert_dir);
371 std::string size_full(db_path + "/" + size_file);
372
373 if (mkdir(db_path.c_str(), 0777))
374 throw TextException(ToSBuf("Cannot create ", db_path), Here());
375
376 if (mkdir(cert_full.c_str(), 0777))
377 throw TextException(ToSBuf("Cannot create ", cert_full), Here());
378
379 std::ofstream size(size_full.c_str());
380 if (size)
381 size << 0;
382 else
383 throw TextException(ToSBuf("Cannot open ", size_full, " to open"), Here());
384 std::ofstream db(db_full.c_str());
385 if (!db)
386 throw TextException(ToSBuf("Cannot open ", db_full, " to open"), Here());
387}
388
389void
390Ssl::CertificateDb::Check(std::string const & db_path, size_t max_db_size, size_t fs_block_size) {
391 CertificateDb db(db_path, max_db_size, fs_block_size);
392 db.load();
393
394 // Call readSize to force rebuild size file in the case it is corrupted
395 (void)db.readSize();
396}
397
399{
400 size_t dbSize = 0;
401#if SQUID_SSLTXTDB_PSTRINGDATA
402 for (int i = 0; i < sk_OPENSSL_PSTRING_num(db.get()->data); ++i) {
403#if SQUID_STACKOF_PSTRINGDATA_HACK
404 const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), i));
405#else
406 const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db.get()->data, i));
407#endif
408#else
409 for (int i = 0; i < sk_num(db.get()->data); ++i) {
410 const char ** current_row = ((const char **)sk_value(db.get()->data, i));
411#endif
412 const std::string filename(cert_full + "/" + current_row[cnlSerial] + ".pem");
413 const size_t fSize = getFileSize(filename);
414 dbSize += fSize;
415 }
416 writeSize(dbSize);
417 return dbSize;
418}
419
420bool
421Ssl::CertificateDb::pure_find(std::string const &key, const Security::CertPointer &expectedOrig, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey)
422{
423 if (!db)
424 return false;
425
426 Row row;
427 row.setValue(cnlKey, key.c_str());
428
429 char **rrow = TXT_DB_get_by_index(db.get(), cnlKey, row.getRow());
430 if (rrow == nullptr)
431 return false;
432
433 if (!sslDateIsInTheFuture(rrow[cnlExp_date]))
434 return false;
435
436 Security::CertPointer storedOrig;
437 // read cert and pkey from file.
438 std::string filename(cert_full + "/" + rrow[cnlSerial] + ".pem");
439 if (!ReadEntry(filename.c_str(), cert, pkey, storedOrig))
440 return false;
441
442 if (!storedOrig && !expectedOrig)
443 return true;
444 else
445 return Ssl::CertificatesCmp(expectedOrig, storedOrig);
446}
447
449 return readSize();
450}
451
452void Ssl::CertificateDb::addSize(std::string const & filename) {
453 // readSize will rebuild 'size' file if missing or it is corrupted
454 size_t dbSize = readSize();
455 dbSize += getFileSize(filename);
456 writeSize(dbSize);
457}
458
459void Ssl::CertificateDb::subSize(std::string const & filename) {
460 // readSize will rebuild 'size' file if missing or it is corrupted
461 size_t dbSize = readSize();
462 const size_t fileSize = getFileSize(filename);
463 dbSize = dbSize > fileSize ? dbSize - fileSize : 0;
464 writeSize(dbSize);
465}
466
468 std::ifstream ifstr(size_full.c_str());
469 size_t db_size = 0;
470 if (!ifstr || !(ifstr >> db_size))
471 return rebuildSize();
472 return db_size;
473}
474
475void Ssl::CertificateDb::writeSize(size_t db_size) {
476 std::ofstream ofstr(size_full.c_str());
477 if (!ofstr)
478 throw TextException(ToSBuf("cannot write \"", size_full, "\" file"), Here());
479 ofstr << db_size;
480}
481
482size_t Ssl::CertificateDb::getFileSize(std::string const & filename) {
483 std::ifstream file(filename.c_str(), std::ios::binary);
484 if (!file)
485 return 0;
486 file.seekg(0, std::ios_base::end);
487 const std::streampos file_size = file.tellg();
488 if (file_size < 0)
489 return 0;
490 return ((static_cast<size_t>(file_size) + fs_block_size - 1) / fs_block_size) * fs_block_size;
491}
492
494 // Load db from file.
495 Ssl::BIO_Pointer in(BIO_new(BIO_s_file()));
496 if (!in || BIO_read_filename(in.get(), db_full.c_str()) <= 0)
497 throw TextException(ToSBuf("Uninitialized SSL certificate database directory: ", db_path, ". To initialize, run \"security_file_certgen -c -s ", db_path, "\"."), Here());
498
499 bool corrupt = false;
500 Ssl::TXT_DB_Pointer temp_db(TXT_DB_read(in.get(), cnlNumber));
501 if (!temp_db)
502 corrupt = true;
503
504 // Create indexes in db.
505 if (!corrupt && !TXT_DB_create_index(temp_db.get(), cnlSerial, nullptr, LHASH_HASH_FN(index_serial_hash), LHASH_COMP_FN(index_serial_cmp)))
506 corrupt = true;
507
508 if (!corrupt && !TXT_DB_create_index(temp_db.get(), cnlKey, nullptr, LHASH_HASH_FN(index_name_hash), LHASH_COMP_FN(index_name_cmp)))
509 corrupt = true;
510
511 if (corrupt)
512 throw TextException(ToSBuf("The SSL certificate database ", db_path, " is corrupted. Please rebuild"), Here());
513
514 db.reset(temp_db.release());
515}
516
518 if (!db)
519 throw TextException("The certificates database is not loaded", Here());
520
521 // To save the db to file, create a new BIO with BIO file methods.
522 Ssl::BIO_Pointer out(BIO_new(BIO_s_file()));
523 if (!out || !BIO_write_filename(out.get(), const_cast<char *>(db_full.c_str())))
524 throw TextException(ToSBuf("Failed to initialize ", db_full, " file for writing"), Here());
525
526 if (TXT_DB_write(out.get(), db.get()) < 0)
527 throw TextException(ToSBuf("Failed to write ", db_full, " file"), Here());
528}
529
530// Normally defined in defines.h file
531void Ssl::CertificateDb::deleteRow(const char **row, int rowIndex) {
532 const std::string filename(cert_full + "/" + row[cnlSerial] + ".pem");
533 sq_TXT_DB_delete_row(db.get(), rowIndex);
534
535 subSize(filename);
536 int ret = remove(filename.c_str());
537 if (ret < 0 && errno != ENOENT)
538 throw TextException(ToSBuf("Failed to remove certificate file ", filename, " from db"), Here());
539}
540
542 if (!db)
543 return false;
544
545 bool removed_one = false;
546#if SQUID_SSLTXTDB_PSTRINGDATA
547 for (int i = 0; i < sk_OPENSSL_PSTRING_num(db.get()->data); ++i) {
548#if SQUID_STACKOF_PSTRINGDATA_HACK
549 const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), i));
550#else
551 const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db.get()->data, i));
552#endif
553#else
554 for (int i = 0; i < sk_num(db.get()->data); ++i) {
555 const char ** current_row = ((const char **)sk_value(db.get()->data, i));
556#endif
557
558 if (!sslDateIsInTheFuture(current_row[cnlExp_date])) {
559 deleteRow(current_row, i);
560 removed_one = true;
561 break;
562 }
563 }
564
565 if (!removed_one)
566 return false;
567 return true;
568}
569
571{
572 if (!hasRows())
573 return false;
574
575#if SQUID_SSLTXTDB_PSTRINGDATA
576#if SQUID_STACKOF_PSTRINGDATA_HACK
577 const char **row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), 0));
578#else
579 const char **row = (const char **)sk_OPENSSL_PSTRING_value(db.get()->data, 0);
580#endif
581#else
582 const char **row = (const char **)sk_value(db.get()->data, 0);
583#endif
584
585 deleteRow(row, 0);
586
587 return true;
588}
589
590bool
591Ssl::CertificateDb::deleteByKey(std::string const & key) {
592 if (!db)
593 return false;
594
595#if SQUID_SSLTXTDB_PSTRINGDATA
596 for (int i = 0; i < sk_OPENSSL_PSTRING_num(db.get()->data); ++i) {
597#if SQUID_STACKOF_PSTRINGDATA_HACK
598 const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), i));
599#else
600 const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db.get()->data, i));
601#endif
602#else
603 for (int i = 0; i < sk_num(db.get()->data); ++i) {
604 const char ** current_row = ((const char **)sk_value(db.get()->data, i));
605#endif
606 if (key == current_row[cnlKey]) {
607 deleteRow(current_row, i);
608 return true;
609 }
610 }
611 return false;
612}
613
615{
616 if (!db)
617 return false;
618
619#if SQUID_SSLTXTDB_PSTRINGDATA
620 if (sk_OPENSSL_PSTRING_num(db.get()->data) == 0)
621#else
622 if (sk_num(db.get()->data) == 0)
623#endif
624 return false;
625 return true;
626}
627
628bool
629Ssl::CertificateDb::WriteEntry(const std::string &filename, const Security::CertPointer &cert, const Security::PrivateKeyPointer &pkey, const Security::CertPointer &orig)
630{
632 if (!Ssl::OpenCertsFileForWriting(bio, filename.c_str()))
633 return false;
634 if (!Ssl::WriteX509Certificate(bio, cert))
635 return false;
636 if (!Ssl::WritePrivateKey(bio, pkey))
637 return false;
638 if (orig && !Ssl::WriteX509Certificate(bio, orig))
639 return false;
640 return true;
641}
642
643bool
644Ssl::CertificateDb::ReadEntry(std::string filename, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey, Security::CertPointer &orig)
645{
647 if (!Ssl::OpenCertsFileForReading(bio, filename.c_str()))
648 return false;
649
650 cert = Ssl::ReadCertificate(bio);
651
652 if (!Ssl::ReadPrivateKey(bio, pkey, nullptr))
653 return false;
654
656
657 return true;
658}
659
#define Here()
source code location of the caller
Definition: Here.h:15
int size
Definition: ModDevPoll.cc:75
#define assert(EX)
Definition: assert.h:17
#define countof(arr)
T * get() const
Returns raw and possibly nullptr pointer.
a source code location that is cheap to create, copy, and store
Definition: Here.h:30
A wrapper for OpenSSL database row of TXT_DB database.
void setValue(size_t number, char const *value)
Set cell's value in row.
size_t width
Number of cells in the row.
Row()
Create row wrapper.
void reset()
Abandon row and don't free memory.
char ** getRow()
Raw row.
bool deleteByKey(std::string const &key)
Delete using key.
const size_t fs_block_size
File system block size.
static bool WriteEntry(const std::string &filename, const Security::CertPointer &cert, const Security::PrivateKeyPointer &pkey, const Security::CertPointer &orig)
stores the db entry into a file
static int index_serial_cmp(const char **a, const char **b)
Callback compare function for serials. Used to create TXT_DB index of serials.
static void Create(std::string const &db_path)
Create and initialize a database under the db_path.
void deleteRow(const char **row, int rowIndex)
Delete a row from TXT_DB.
const std::string size_full
Full path of the file to store the db size.
TXT_DB_Pointer db
Database with certificates info.
bool pure_find(std::string const &key, const Security::CertPointer &expectedOrig, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey)
Only find certificate in current db and return it.
void writeSize(size_t db_size)
Write size to file size_file.
static unsigned long index_serial_hash(const char **a)
Callback hash function for serials. Used to create TXT_DB index of serials.
bool purgeCert(std::string const &key)
Delete a certificate from database.
static const std::string cert_dir
Base name of the directory to store the certs.
const std::string cert_full
Full path of the directory to store the certs.
void subSize(std::string const &filename)
Decrease db size by the given file size and update size_file.
bool deleteOldestCertificate()
Delete oldest certificate.
static unsigned long index_name_hash(const char **a)
Callback hash function for names. Used to create TXT_DB index of names..
void addSize(std::string const &filename)
Increase db size by the given file size and update size_file.
static bool ReadEntry(std::string filename, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey, Security::CertPointer &orig)
loads a db entry from the file
size_t readSize()
Read size from file size_file.
bool hasRows() const
Whether the TXT_DB has stored items.
static int index_name_cmp(const char **a, const char **b)
Callback compare function for names. Used to create TXT_DB index of names..
const size_t max_db_size
Max size of db.
void save()
Save db to disk.
static void Check(std::string const &db_path, size_t max_db_size, size_t fs_block_size)
Check the database stored under the db_path.
Columns
Names of db columns.
CertificateDb(std::string const &db_path, size_t aMax_db_size, size_t aFs_block_size)
bool addCertAndPrivateKey(std::string const &useKey, const Security::CertPointer &cert, const Security::PrivateKeyPointer &pkey, const Security::CertPointer &orig)
Save certificate to disk.
static const std::string size_file
bool find(std::string const &key, const Security::CertPointer &expectedOrig, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey)
finds matching generated certificate and its private key
const std::string db_full
Full path of the database index file.
static const char **static const char **static const std::string db_file
Base name of the database index file.
const std::string db_path
The database directory.
bool deleteInvalidCertificate()
Delete invalid certificate.
static void sq_TXT_DB_delete(TXT_DB *db, const char **row)
Removes the first matching row from TXT_DB. Ignores failures.
Lock dbLock
protects the database file
static void sq_TXT_DB_delete_row(TXT_DB *db, int idx)
Remove the row on position idx from TXT_DB. Ignores failures.
size_t getFileSize(std::string const &filename)
get file size on disk.
void load()
Load db from disk.
maintains an exclusive blocking file-based lock
Lock(std::string const &filename)
creates an unlocked lock
~Lock()
releases the lock if it is locked
bool locked() const
whether our lock is locked
void lock()
locks the lock, may block
void unlock()
unlocks locked lock or throws
an exception-safe way to obtain and release a lock
~Locker()
unlocks the lock if it was locked by us
Locker(Lock &, const SourceLocation &)
locks the lock if the lock was unlocked
Lock & lock
the lock we are operating on
bool weLocked
whether we locked the lock
an std::runtime_error with thrower location info
Definition: TextException.h:21
A const & max(A const &lhs, A const &rhs)
char * db_path
TDB_CONTEXT * db
bool CertificatesCmp(const Security::CertPointer &cert1, const Security::CertPointer &cert2)
Definition: gadgets.cc:980
bool ReadPrivateKey(BIO_Pointer &bio, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback)
Definition: gadgets.cc:768
bool OpenCertsFileForWriting(BIO_Pointer &bio, const char *filename)
Definition: gadgets.cc:790
bool WritePrivateKey(BIO_Pointer &bio, const Security::PrivateKeyPointer &pkey)
Definition: gadgets.cc:811
bool sslDateIsInTheFuture(char const *date)
Definition: gadgets.cc:826
bool OpenCertsFileForReading(BIO_Pointer &bio, const char *filename)
Definition: gadgets.cc:722
bool WriteX509Certificate(BIO_Pointer &bio, const Security::CertPointer &cert)
Definition: gadgets.cc:801
std::unique_ptr< BIO, HardFun< void, BIO *, &BIO_vfree > > BIO_Pointer
Definition: gadgets.h:54
std::unique_ptr< BIGNUM, HardFun< void, BIGNUM *, &BN_free > > BIGNUM_Pointer
Definition: gadgets.h:52
std::unique_ptr< TXT_DB, HardFun< void, TXT_DB *, &TXT_DB_free > > TXT_DB_Pointer
Definition: gadgets.h:60
Security::CertPointer ReadOptionalCertificate(const BIO_Pointer &)
Definition: gadgets.cc:733
UniqueCString OneLineSummary(X509_NAME &)
a RAII wrapper for the memory-allocating flavor of X509_NAME_oneline()
Definition: gadgets.cc:821
Security::CertPointer ReadCertificate(const BIO_Pointer &)
Definition: gadgets.cc:758
std::unique_ptr< char, HardFun< void, char *, &OPENSSL_free_for_c_strings > > UniqueCString
Definition: gadgets.h:81
#define OPENSSL_LH_strhash
Definition: openssl.h:129
#define OPENSSL_LH_delete
Definition: openssl.h:128
#define X509_getm_notAfter
Definition: openssl.h:247
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors