]> git.ipfire.org Git - thirdparty/squid.git/blob - src/security/cert_generators/file/certificate_db.h
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / security / cert_generators / file / certificate_db.h
1 /*
2 * Copyright (C) 1996-2020 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 #ifndef SQUID_SSL_CERTIFICATE_DB_H
10 #define SQUID_SSL_CERTIFICATE_DB_H
11
12 #include "ssl/gadgets.h"
13
14 #include <string>
15
16 namespace Ssl
17 {
18 /// maintains an exclusive blocking file-based lock
19 class Lock
20 {
21 public:
22 explicit Lock(std::string const &filename); ///< creates an unlocked lock
23 ~Lock(); ///< releases the lock if it is locked
24 void lock(); ///< locks the lock, may block
25 void unlock(); ///< unlocks locked lock or throws
26 bool locked() const; ///< whether our lock is locked
27 const char *name() const { return filename.c_str(); }
28 private:
29 std::string filename;
30 #if _SQUID_WINDOWS_
31 HANDLE hFile; ///< Windows file handle.
32 #else
33 int fd; ///< Linux file descriptor.
34 #endif
35 };
36
37 /// an exception-safe way to obtain and release a lock
38 class Locker
39 {
40 public:
41 /// locks the lock if the lock was unlocked
42 Locker(Lock &lock, const char *aFileName, int lineNo);
43 /// unlocks the lock if it was locked by us
44 ~Locker();
45 private:
46 bool weLocked; ///< whether we locked the lock
47 Lock &lock; ///< the lock we are operating on
48 const std::string fileName; ///< where the lock was needed
49 const int lineNo; ///< where the lock was needed
50 };
51
52 /// convenience macro to pass source code location to Locker and others
53 #define Here __FILE__, __LINE__
54
55 /**
56 * Database class for storing SSL certificates and their private keys.
57 * A database consist by:
58 * - A disk file to store current serial number
59 * - A disk file to store the current database size
60 * - A disk file which is a normal TXT_DB openSSL database
61 * - A directory under which the certificates and their private keys stored.
62 * The database before used must initialized with CertificateDb::create static method.
63 */
64 class CertificateDb
65 {
66 public:
67 /// Names of db columns.
68 enum Columns {
69 cnlKey = 0, //< The key to use for storing/retrieving entries from DB.
70 cnlExp_date,
71 cnlRev_date,
72 cnlSerial,
73 cnlName,
74 cnlNumber
75 };
76
77 /// A wrapper for OpenSSL database row of TXT_DB database.
78 class Row
79 {
80 public:
81 /// Create row wrapper.
82 Row();
83 ///Create row wrapper for row with width items
84 Row(char **row, size_t width);
85 /// Delete all row.
86 ~Row();
87 void setValue(size_t number, char const * value); ///< Set cell's value in row
88 char ** getRow(); ///< Raw row
89 void reset(); ///< Abandon row and don't free memory
90 private:
91 char **row; ///< Raw row
92 size_t width; ///< Number of cells in the row
93 };
94
95 CertificateDb(std::string const & db_path, size_t aMax_db_size, size_t aFs_block_size);
96 /// finds matching generated certificate and its private key
97 bool find(std::string const & key, const Security::CertPointer &expectedOrig, Security::CertPointer & cert, Security::PrivateKeyPointer & pkey);
98 /// Delete a certificate from database
99 bool purgeCert(std::string const & key);
100 /// Save certificate to disk.
101 bool addCertAndPrivateKey(std::string const & useKey, const Security::CertPointer & cert, const Security::PrivateKeyPointer & pkey, const Security::CertPointer &orig);
102
103 /// Create and initialize a database under the db_path
104 static void Create(std::string const & db_path);
105 /// Check the database stored under the db_path.
106 static void Check(std::string const & db_path, size_t max_db_size, size_t fs_block_size);
107 private:
108 void load(); ///< Load db from disk.
109 void save(); ///< Save db to disk.
110 size_t size(); ///< Get db size on disk in bytes.
111 /// Increase db size by the given file size and update size_file
112 void addSize(std::string const & filename);
113 /// Decrease db size by the given file size and update size_file
114 void subSize(std::string const & filename);
115 size_t readSize(); ///< Read size from file size_file
116 void writeSize(size_t db_size); ///< Write size to file size_file.
117 size_t getFileSize(std::string const & filename); ///< get file size on disk.
118 size_t rebuildSize(); ///< Rebuild size_file
119 /// Only find certificate in current db and return it.
120 bool pure_find(std::string const & key, const Security::CertPointer & expectedOrig, Security::CertPointer & cert, Security::PrivateKeyPointer & pkey);
121
122 void deleteRow(const char **row, int rowIndex); ///< Delete a row from TXT_DB
123 bool deleteInvalidCertificate(); ///< Delete invalid certificate.
124 bool deleteOldestCertificate(); ///< Delete oldest certificate.
125 bool deleteByKey(std::string const & key); ///< Delete using key.
126 bool hasRows() const; ///< Whether the TXT_DB has stored items.
127
128 /// stores the db entry into a file
129 static bool WriteEntry(const std::string &filename, const Security::CertPointer & cert, const Security::PrivateKeyPointer & pkey, const Security::CertPointer &orig);
130
131 /// loads a db entry from the file
132 static bool ReadEntry(std::string filename, Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, Security::CertPointer &orig);
133
134 /// Removes the first matching row from TXT_DB. Ignores failures.
135 static void sq_TXT_DB_delete(TXT_DB *db, const char **row);
136 /// Remove the row on position idx from TXT_DB. Ignores failures.
137 static void sq_TXT_DB_delete_row(TXT_DB *db, int idx);
138
139 /// Callback hash function for serials. Used to create TXT_DB index of serials.
140 static unsigned long index_serial_hash(const char **a);
141 /// Callback compare function for serials. Used to create TXT_DB index of serials.
142 static int index_serial_cmp(const char **a, const char **b);
143 /// Callback hash function for names. Used to create TXT_DB index of names..
144 static unsigned long index_name_hash(const char **a);
145 /// Callback compare function for names. Used to create TXT_DB index of names..
146 static int index_name_cmp(const char **a, const char **b);
147
148 /// Definitions required by openSSL, to use the index_* functions defined above
149 ///with TXT_DB_create_index.
150 #if SQUID_USE_SSLLHASH_HACK
151 static unsigned long index_serial_hash_LHASH_HASH(const void *a) {
152 return index_serial_hash((const char **)a);
153 }
154 static int index_serial_cmp_LHASH_COMP(const void *arg1, const void *arg2) {
155 return index_serial_cmp((const char **)arg1, (const char **)arg2);
156 }
157 static unsigned long index_name_hash_LHASH_HASH(const void *a) {
158 return index_name_hash((const char **)a);
159 }
160 static int index_name_cmp_LHASH_COMP(const void *arg1, const void *arg2) {
161 return index_name_cmp((const char **)arg1, (const char **)arg2);
162 }
163 #else
164 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
165 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
166 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
167 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
168 #endif
169
170 static const std::string db_file; ///< Base name of the database index file.
171 static const std::string cert_dir; ///< Base name of the directory to store the certs.
172 static const std::string size_file; ///< Base name of the file to store db size.
173 /// Min size of disk db. If real size < min_db_size the db will be disabled.
174 static const size_t min_db_size;
175
176 const std::string db_path; ///< The database directory.
177 const std::string db_full; ///< Full path of the database index file.
178 const std::string cert_full; ///< Full path of the directory to store the certs.
179 const std::string size_full; ///< Full path of the file to store the db size.
180
181 TXT_DB_Pointer db; ///< Database with certificates info.
182 const size_t max_db_size; ///< Max size of db.
183 const size_t fs_block_size; ///< File system block size.
184 mutable Lock dbLock; ///< protects the database file
185 };
186
187 } // namespace Ssl
188 #endif // SQUID_SSL_CERTIFICATE_DB_H
189