]>
Commit | Line | Data |
---|---|---|
95d2589c CT |
1 | /* |
2 | * 2009/01/17 | |
3 | */ | |
4 | ||
5 | #ifndef SQUID_SSL_GADGETS_H | |
6 | #define SQUID_SSL_GADGETS_H | |
7 | ||
8 | #include "base/TidyPointer.h" | |
fb2178bb | 9 | #include "ssl/crtd_message.h" |
95d2589c CT |
10 | |
11 | #if HAVE_OPENSSL_SSL_H | |
12 | #include <openssl/ssl.h> | |
13 | #endif | |
14 | #if HAVE_OPENSSL_TXT_DB_H | |
15 | #include <openssl/txt_db.h> | |
16 | #endif | |
17 | #if HAVE_STRING | |
18 | #include <string> | |
19 | #endif | |
20 | ||
21 | namespace Ssl | |
22 | { | |
23 | /** | |
24 | \defgroup SslCrtdSslAPI ssl_crtd SSL api. | |
25 | These functions must not depend on Squid runtime code such as debug() | |
26 | because they are used by ssl_crtd. | |
27 | */ | |
28 | ||
aebe6888 CT |
29 | /** |
30 | \ingroup SslCrtdSslAPI | |
31 | * Add SSL locking (a.k.a. reference counting) to TidyPointer | |
32 | */ | |
33 | template <typename T, void (*DeAllocator)(T *t), int lock> | |
34 | class LockingPointer: public TidyPointer<T, DeAllocator> | |
35 | { | |
36 | public: | |
37 | typedef TidyPointer<T, DeAllocator> Parent; | |
38 | ||
39 | LockingPointer(T *t = NULL): Parent(t) { | |
40 | } | |
41 | ||
42 | void resetAndLock(T *t) { | |
43 | if (t != this->get()) { | |
44 | reset(t); | |
45 | if (t) | |
46 | CRYPTO_add(&t->references, 1, lock); | |
47 | } | |
48 | } | |
49 | }; | |
50 | ||
3a665e67 | 51 | // Macro to be used to define the C++ equivalent function of an extern "C" |
14851ec2 CT |
52 | // function. The C++ function suffixed with the _cpp extension |
53 | #define CtoCpp1(function, argument) \ | |
54 | extern "C++" inline void function ## _cpp(argument a) { \ | |
55 | function(a); \ | |
56 | } | |
95d2589c CT |
57 | |
58 | /** | |
59 | \ingroup SslCrtdSslAPI | |
60 | * TidyPointer typedefs for common SSL objects | |
61 | */ | |
14851ec2 | 62 | CtoCpp1(X509_free, X509 *) |
aebe6888 | 63 | typedef LockingPointer<X509, X509_free_cpp, CRYPTO_LOCK_X509> X509_Pointer; |
14851ec2 | 64 | |
a594dbfa CT |
65 | CtoCpp1(sk_X509_free, STACK_OF(X509) *) |
66 | typedef TidyPointer<STACK_OF(X509), sk_X509_free_cpp> X509_STACK_Pointer; | |
67 | ||
14851ec2 | 68 | CtoCpp1(EVP_PKEY_free, EVP_PKEY *) |
aebe6888 | 69 | typedef LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, CRYPTO_LOCK_EVP_PKEY> EVP_PKEY_Pointer; |
14851ec2 CT |
70 | |
71 | CtoCpp1(BN_free, BIGNUM *) | |
72 | typedef TidyPointer<BIGNUM, BN_free_cpp> BIGNUM_Pointer; | |
73 | ||
74 | CtoCpp1(BIO_free, BIO *) | |
75 | typedef TidyPointer<BIO, BIO_free_cpp> BIO_Pointer; | |
76 | ||
77 | CtoCpp1(ASN1_INTEGER_free, ASN1_INTEGER *) | |
78 | typedef TidyPointer<ASN1_INTEGER, ASN1_INTEGER_free_cpp> ASN1_INT_Pointer; | |
79 | ||
80 | CtoCpp1(TXT_DB_free, TXT_DB *) | |
81 | typedef TidyPointer<TXT_DB, TXT_DB_free_cpp> TXT_DB_Pointer; | |
82 | ||
83 | CtoCpp1(X509_NAME_free, X509_NAME *) | |
84 | typedef TidyPointer<X509_NAME, X509_NAME_free_cpp> X509_NAME_Pointer; | |
85 | ||
86 | CtoCpp1(RSA_free, RSA *) | |
87 | typedef TidyPointer<RSA, RSA_free_cpp> RSA_Pointer; | |
88 | ||
89 | CtoCpp1(X509_REQ_free, X509_REQ *) | |
90 | typedef TidyPointer<X509_REQ, X509_REQ_free_cpp> X509_REQ_Pointer; | |
91 | ||
92 | CtoCpp1(SSL_CTX_free, SSL_CTX *) | |
93 | typedef TidyPointer<SSL_CTX, SSL_CTX_free_cpp> SSL_CTX_Pointer; | |
94 | ||
95 | CtoCpp1(SSL_free, SSL *) | |
96 | typedef TidyPointer<SSL, SSL_free_cpp> SSL_Pointer; | |
95d2589c CT |
97 | |
98 | ||
99 | /** | |
100 | \ingroup SslCrtdSslAPI | |
101 | * Create 1024 bits rsa key. | |
102 | */ | |
103 | EVP_PKEY * createSslPrivateKey(); | |
104 | ||
95d2589c CT |
105 | /** |
106 | \ingroup SslCrtdSslAPI | |
107 | * Write private key and SSL certificate to memory. | |
108 | */ | |
109 | bool writeCertAndPrivateKeyToMemory(X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite); | |
110 | ||
9a90aace CT |
111 | /** |
112 | \ingroup SslCrtdSslAPI | |
113 | * Append SSL certificate to bufferToWrite. | |
114 | */ | |
115 | bool appendCertToMemory(X509_Pointer const & cert, std::string & bufferToWrite); | |
116 | ||
95d2589c CT |
117 | /** |
118 | \ingroup SslCrtdSslAPI | |
119 | * Write private key and SSL certificate to file. | |
120 | */ | |
121 | bool writeCertAndPrivateKeyToFile(X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey, char const * filename); | |
122 | ||
123 | /** | |
124 | \ingroup SslCrtdSslAPI | |
125 | * Write private key and SSL certificate to memory. | |
126 | */ | |
127 | bool readCertAndPrivateKeyFromMemory(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, char const * bufferToRead); | |
128 | ||
9a90aace CT |
129 | /** |
130 | \ingroup SslCrtdSslAPI | |
131 | * Read SSL certificate from memory. | |
132 | */ | |
133 | bool readCertFromMemory(X509_Pointer & cert, char const * bufferToRead); | |
134 | ||
aebe6888 CT |
135 | /** |
136 | \ingroup SslCrtdSslAPI | |
137 | * Supported certificate signing algorithms | |
138 | */ | |
139 | enum CertSignAlgorithm {algSignTrusted = 0, algSignUntrusted, algSignSelf, algSignEnd}; | |
140 | ||
95d2589c CT |
141 | /** |
142 | \ingroup SslCrtdSslAPI | |
aebe6888 | 143 | * Short names for certificate signing algorithms |
95d2589c | 144 | */ |
aebe6888 CT |
145 | |
146 | extern const char *CertSignAlgorithmStr[]; | |
95d2589c CT |
147 | |
148 | /** | |
149 | \ingroup SslCrtdSslAPI | |
aebe6888 CT |
150 | * Return the short name of the signing algorithm "sg" |
151 | */ | |
152 | inline const char *certSignAlgorithm(int sg) | |
153 | { | |
154 | if (sg >=0 && sg < Ssl::algSignEnd) | |
155 | return Ssl::CertSignAlgorithmStr[sg]; | |
156 | ||
157 | return NULL; | |
158 | } | |
159 | ||
160 | /** | |
161 | \ingroup SslCrtdSslAPI | |
162 | * Return the id of the signing algorithm "sg" | |
95d2589c | 163 | */ |
aebe6888 CT |
164 | inline CertSignAlgorithm certSignAlgorithmId(const char *sg) |
165 | { | |
166 | for (int i = 0; i < algSignEnd && Ssl::CertSignAlgorithmStr[i] != NULL; i++) | |
167 | if (strcmp(Ssl::CertSignAlgorithmStr[i], sg) == 0) | |
168 | return (CertSignAlgorithm)i; | |
169 | ||
170 | return algSignEnd; | |
171 | } | |
95d2589c | 172 | |
fb2178bb CT |
173 | /** |
174 | \ingroup SslCrtdSslAPI | |
175 | * Supported certificate adaptation algorithms | |
176 | */ | |
aebe6888 | 177 | enum CertAdaptAlgorithm {algSetValidAfter = 0, algSetValidBefore, algSetCommonName, algSetEnd}; |
fb2178bb CT |
178 | |
179 | /** | |
180 | \ingroup SslCrtdSslAPI | |
181 | * Short names for certificate adaptation algorithms | |
182 | */ | |
183 | extern const char *CertAdaptAlgorithmStr[]; | |
184 | ||
185 | /** | |
186 | \ingroup SslCrtdSslAPI | |
187 | * Return the short name of the adaptation algorithm "alg" | |
188 | */ | |
189 | inline const char *sslCertAdaptAlgoritm(int alg) | |
190 | { | |
aebe6888 | 191 | if (alg >=0 && alg < Ssl::algSetEnd) |
fb2178bb CT |
192 | return Ssl::CertAdaptAlgorithmStr[alg]; |
193 | ||
194 | return NULL; | |
195 | } | |
196 | ||
aebe6888 CT |
197 | /** |
198 | \ingroup SslCrtdSslAPI | |
199 | * Simple struct to pass certificate generation parameters to generateSslCertificate function. | |
200 | */ | |
201 | class CertificateProperties { | |
202 | public: | |
203 | CertificateProperties(); | |
204 | X509_Pointer mimicCert; ///< Certificate to mimic | |
205 | X509_Pointer signWithX509; ///< Certificate to sign the generated request | |
206 | EVP_PKEY_Pointer signWithPkey; ///< The key of the signing certificate | |
aebe6888 CT |
207 | bool setValidAfter; ///< Do not mimic "Not Valid After" field |
208 | bool setValidBefore; ///< Do not mimic "Not Valid Before" field | |
209 | bool setCommonName; ///< Replace the CN field of the mimicing subject with the given | |
210 | std::string commonName; ///< A CN to use for the generated certificate | |
211 | CertSignAlgorithm signAlgorithm; ///< The signing algorithm to use | |
06997a38 CT |
212 | /// Returns certificate database primary key. New fake certificates |
213 | /// purge old fake certificates with the same key. | |
214 | std::string & dbKey() const; | |
aebe6888 CT |
215 | private: |
216 | CertificateProperties(CertificateProperties &); | |
217 | CertificateProperties &operator =(CertificateProperties const &); | |
218 | }; | |
219 | ||
9a90aace CT |
220 | /** |
221 | \ingroup SslCrtdSslAPI | |
222 | * Decide on the kind of certificate and generate a CA- or self-signed one. | |
223 | * The generated certificate will inherite properties from certToMimic | |
224 | * Return generated certificate and private key in resultX509 and resultPkey | |
225 | * variables. | |
226 | */ | |
aebe6888 | 227 | bool generateSslCertificate(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, CertificateProperties const &properties); |
9a90aace | 228 | |
a594dbfa CT |
229 | /** |
230 | \ingroup SslCrtdSslAPI | |
231 | * Read private key from file. Make sure that this is not encrypted file. | |
232 | */ | |
780b55ee | 233 | EVP_PKEY * readSslPrivateKey(char const * keyFilename, pem_password_cb *passwd_callback = NULL); |
a594dbfa | 234 | |
95d2589c CT |
235 | /** |
236 | \ingroup SslCrtdSslAPI | |
237 | * Read certificate and private key from files. | |
238 | * \param certFilename name of file with certificate. | |
239 | * \param keyFilename name of file with private key. | |
240 | */ | |
241 | void readCertAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename); | |
242 | ||
243 | /** | |
244 | \ingroup SslCrtdSslAPI | |
245 | * Verify date. Date format it ASN1_UTCTIME. if there is out of date error, | |
246 | * return false. | |
247 | */ | |
248 | bool sslDateIsInTheFuture(char const * date); | |
249 | ||
e7bcc25f CT |
250 | /** |
251 | \ingroup SslCrtdSslAPI | |
4ece76b2 CT |
252 | * Check if the major fields of a certificates matches the properties given by |
253 | * a CertficateProperties object | |
e7bcc25f CT |
254 | \return true if the certificates matches false otherwise. |
255 | */ | |
4ece76b2 | 256 | bool certificateMatchesProperties(X509 *peer_cert, CertificateProperties const &properties); |
95d2589c CT |
257 | } // namespace Ssl |
258 | #endif // SQUID_SSL_GADGETS_H |