]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
bbc27441 AJ |
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 | ||
95d2589c CT |
9 | #ifndef SQUID_SSL_GADGETS_H |
10 | #define SQUID_SSL_GADGETS_H | |
11 | ||
b05c1954 AR |
12 | #if USE_OPENSSL |
13 | ||
9726727b | 14 | #include "base/HardFun.h" |
b05c1954 | 15 | #include "compat/openssl.h" |
f97700a0 | 16 | #include "security/forward.h" |
fb2178bb | 17 | #include "ssl/crtd_message.h" |
95d2589c | 18 | |
b05c1954 AR |
19 | #include <string> |
20 | ||
24b30fdc EQ |
21 | #if HAVE_OPENSSL_ASN1_H |
22 | #include <openssl/asn1.h> | |
23 | #endif | |
95d2589c CT |
24 | #if HAVE_OPENSSL_TXT_DB_H |
25 | #include <openssl/txt_db.h> | |
26 | #endif | |
5f1318b1 CT |
27 | #if HAVE_OPENSSL_X509V3_H |
28 | #include <openssl/x509v3.h> | |
29 | #endif | |
95d2589c CT |
30 | |
31 | namespace Ssl | |
32 | { | |
33 | /** | |
051da40c | 34 | \defgroup SslCrtdSslAPI SSL certificate generator API |
95d2589c | 35 | These functions must not depend on Squid runtime code such as debug() |
051da40c | 36 | because they are used by security_file_certgen helper. |
95d2589c CT |
37 | */ |
38 | ||
3c26b00a CT |
39 | #if !defined(SQUID_SSL_SIGN_HASH_IF_NONE) |
40 | #define SQUID_SSL_SIGN_HASH_IF_NONE "sha256" | |
41 | #endif | |
42 | ||
95d2589c | 43 | /** |
3662819a | 44 | * std::unique_ptr typedefs for common SSL objects |
95d2589c | 45 | */ |
48c7e8cb | 46 | sk_dtor_wrapper(sk_X509, STACK_OF(X509) *, X509_free); |
3662819a | 47 | typedef std::unique_ptr<STACK_OF(X509), sk_X509_free_wrapper> X509_STACK_Pointer; |
a594dbfa | 48 | |
9726727b | 49 | typedef std::unique_ptr<BIGNUM, HardFun<void, BIGNUM*, &BN_free>> BIGNUM_Pointer; |
14851ec2 | 50 | |
9726727b | 51 | typedef std::unique_ptr<BIO, HardFun<void, BIO*, &BIO_vfree>> BIO_Pointer; |
14851ec2 | 52 | |
9726727b | 53 | typedef std::unique_ptr<ASN1_INTEGER, HardFun<void, ASN1_INTEGER*, &ASN1_INTEGER_free>> ASN1_INT_Pointer; |
14851ec2 | 54 | |
9726727b | 55 | typedef std::unique_ptr<ASN1_OCTET_STRING, HardFun<void, ASN1_OCTET_STRING*, &ASN1_OCTET_STRING_free>> ASN1_OCTET_STRING_Pointer; |
5f1318b1 | 56 | |
9726727b | 57 | typedef std::unique_ptr<TXT_DB, HardFun<void, TXT_DB*, &TXT_DB_free>> TXT_DB_Pointer; |
14851ec2 | 58 | |
9726727b | 59 | typedef std::unique_ptr<X509_NAME, HardFun<void, X509_NAME*, &X509_NAME_free>> X509_NAME_Pointer; |
14851ec2 | 60 | |
9726727b | 61 | typedef std::unique_ptr<RSA, HardFun<void, RSA*, &RSA_free>> RSA_Pointer; |
14851ec2 | 62 | |
9726727b | 63 | typedef std::unique_ptr<X509_REQ, HardFun<void, X509_REQ*, &X509_REQ_free>> X509_REQ_Pointer; |
14851ec2 | 64 | |
9726727b | 65 | typedef std::unique_ptr<AUTHORITY_KEYID, HardFun<void, AUTHORITY_KEYID*, &AUTHORITY_KEYID_free>> AUTHORITY_KEYID_Pointer; |
5f1318b1 | 66 | |
48c7e8cb | 67 | sk_dtor_wrapper(sk_GENERAL_NAME, STACK_OF(GENERAL_NAME) *, GENERAL_NAME_free); |
3662819a | 68 | typedef std::unique_ptr<STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_free_wrapper> GENERAL_NAME_STACK_Pointer; |
5f1318b1 | 69 | |
9726727b | 70 | typedef std::unique_ptr<GENERAL_NAME, HardFun<void, GENERAL_NAME*, &GENERAL_NAME_free>> GENERAL_NAME_Pointer; |
5f1318b1 | 71 | |
9726727b | 72 | typedef std::unique_ptr<X509_EXTENSION, HardFun<void, X509_EXTENSION*, &X509_EXTENSION_free>> X509_EXTENSION_Pointer; |
5f1318b1 | 73 | |
800967af | 74 | typedef std::unique_ptr<X509_STORE_CTX, HardFun<void, X509_STORE_CTX *, &X509_STORE_CTX_free>> X509_STORE_CTX_Pointer; |
95d2589c CT |
75 | /** |
76 | \ingroup SslCrtdSslAPI | |
77 | * Create 1024 bits rsa key. | |
78 | */ | |
79 | EVP_PKEY * createSslPrivateKey(); | |
80 | ||
95d2589c CT |
81 | /** |
82 | \ingroup SslCrtdSslAPI | |
83 | * Write private key and SSL certificate to memory. | |
84 | */ | |
cf487124 | 85 | bool writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey, std::string & bufferToWrite); |
95d2589c | 86 | |
9a90aace CT |
87 | /** |
88 | \ingroup SslCrtdSslAPI | |
89 | * Append SSL certificate to bufferToWrite. | |
90 | */ | |
f97700a0 | 91 | bool appendCertToMemory(Security::CertPointer const & cert, std::string & bufferToWrite); |
9a90aace | 92 | |
95d2589c CT |
93 | /** |
94 | \ingroup SslCrtdSslAPI | |
95 | * Write private key and SSL certificate to memory. | |
96 | */ | |
cf487124 | 97 | bool readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, char const * bufferToRead); |
95d2589c | 98 | |
9a90aace CT |
99 | /** |
100 | \ingroup SslCrtdSslAPI | |
101 | * Read SSL certificate from memory. | |
102 | */ | |
f97700a0 | 103 | bool readCertFromMemory(Security::CertPointer & cert, char const * bufferToRead); |
9a90aace | 104 | |
5107d2c4 CT |
105 | /** |
106 | \ingroup SslCrtdSslAPI | |
107 | * Read private key from file. | |
108 | */ | |
cf487124 | 109 | void ReadPrivateKeyFromFile(char const * keyFilename, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback); |
5107d2c4 CT |
110 | |
111 | /** | |
112 | \ingroup SslCrtdSslAPI | |
2f8abb64 | 113 | * Initialize the bio with the file 'filename' opened for reading |
5107d2c4 CT |
114 | */ |
115 | bool OpenCertsFileForReading(BIO_Pointer &bio, const char *filename); | |
116 | ||
b05c1954 AR |
117 | /// reads and returns a certificate using the given OpenSSL BIO |
118 | /// \returns a nil pointer on errors (TODO: throw instead) | |
119 | Security::CertPointer ReadX509Certificate(const BIO_Pointer &); | |
5107d2c4 CT |
120 | |
121 | /** | |
122 | \ingroup SslCrtdSslAPI | |
123 | * Read a private key from bio | |
124 | */ | |
cf487124 | 125 | bool ReadPrivateKey(BIO_Pointer &bio, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback); |
5107d2c4 CT |
126 | |
127 | /** | |
128 | \ingroup SslCrtdSslAPI | |
2f8abb64 | 129 | * Initialize the bio with the file 'filename' opened for writing |
5107d2c4 CT |
130 | */ |
131 | ||
132 | bool OpenCertsFileForWriting(BIO_Pointer &bio, const char *filename); | |
133 | ||
134 | /** | |
135 | \ingroup SslCrtdSslAPI | |
136 | * Write certificate to BIO. | |
137 | */ | |
138 | bool WriteX509Certificate(BIO_Pointer &bio, const Security::CertPointer & cert); | |
139 | ||
140 | /** | |
141 | \ingroup SslCrtdSslAPI | |
142 | * Write private key to BIO. | |
143 | */ | |
cf487124 | 144 | bool WritePrivateKey(BIO_Pointer &bio, const Security::PrivateKeyPointer &pkey); |
5107d2c4 | 145 | |
aebe6888 CT |
146 | /** |
147 | \ingroup SslCrtdSslAPI | |
148 | * Supported certificate signing algorithms | |
149 | */ | |
150 | enum CertSignAlgorithm {algSignTrusted = 0, algSignUntrusted, algSignSelf, algSignEnd}; | |
151 | ||
95d2589c CT |
152 | /** |
153 | \ingroup SslCrtdSslAPI | |
aebe6888 | 154 | * Short names for certificate signing algorithms |
95d2589c | 155 | */ |
aebe6888 CT |
156 | |
157 | extern const char *CertSignAlgorithmStr[]; | |
95d2589c CT |
158 | |
159 | /** | |
160 | \ingroup SslCrtdSslAPI | |
aebe6888 CT |
161 | * Return the short name of the signing algorithm "sg" |
162 | */ | |
163 | inline const char *certSignAlgorithm(int sg) | |
164 | { | |
165 | if (sg >=0 && sg < Ssl::algSignEnd) | |
166 | return Ssl::CertSignAlgorithmStr[sg]; | |
167 | ||
168 | return NULL; | |
169 | } | |
170 | ||
171 | /** | |
172 | \ingroup SslCrtdSslAPI | |
173 | * Return the id of the signing algorithm "sg" | |
95d2589c | 174 | */ |
aebe6888 CT |
175 | inline CertSignAlgorithm certSignAlgorithmId(const char *sg) |
176 | { | |
177 | for (int i = 0; i < algSignEnd && Ssl::CertSignAlgorithmStr[i] != NULL; i++) | |
178 | if (strcmp(Ssl::CertSignAlgorithmStr[i], sg) == 0) | |
179 | return (CertSignAlgorithm)i; | |
180 | ||
181 | return algSignEnd; | |
182 | } | |
95d2589c | 183 | |
fb2178bb CT |
184 | /** |
185 | \ingroup SslCrtdSslAPI | |
186 | * Supported certificate adaptation algorithms | |
187 | */ | |
aebe6888 | 188 | enum CertAdaptAlgorithm {algSetValidAfter = 0, algSetValidBefore, algSetCommonName, algSetEnd}; |
fb2178bb CT |
189 | |
190 | /** | |
191 | \ingroup SslCrtdSslAPI | |
192 | * Short names for certificate adaptation algorithms | |
193 | */ | |
194 | extern const char *CertAdaptAlgorithmStr[]; | |
195 | ||
196 | /** | |
197 | \ingroup SslCrtdSslAPI | |
198 | * Return the short name of the adaptation algorithm "alg" | |
199 | */ | |
200 | inline const char *sslCertAdaptAlgoritm(int alg) | |
201 | { | |
aebe6888 | 202 | if (alg >=0 && alg < Ssl::algSetEnd) |
fb2178bb CT |
203 | return Ssl::CertAdaptAlgorithmStr[alg]; |
204 | ||
205 | return NULL; | |
206 | } | |
207 | ||
aebe6888 CT |
208 | /** |
209 | \ingroup SslCrtdSslAPI | |
210 | * Simple struct to pass certificate generation parameters to generateSslCertificate function. | |
211 | */ | |
87f237a9 A |
212 | class CertificateProperties |
213 | { | |
aebe6888 CT |
214 | public: |
215 | CertificateProperties(); | |
f97700a0 AJ |
216 | Security::CertPointer mimicCert; ///< Certificate to mimic |
217 | Security::CertPointer signWithX509; ///< Certificate to sign the generated request | |
cf487124 | 218 | Security::PrivateKeyPointer signWithPkey; ///< The key of the signing certificate |
87f237a9 | 219 | bool setValidAfter; ///< Do not mimic "Not Valid After" field |
aebe6888 | 220 | bool setValidBefore; ///< Do not mimic "Not Valid Before" field |
2f8abb64 | 221 | bool setCommonName; ///< Replace the CN field of the mimicking subject with the given |
aebe6888 CT |
222 | std::string commonName; ///< A CN to use for the generated certificate |
223 | CertSignAlgorithm signAlgorithm; ///< The signing algorithm to use | |
3c26b00a | 224 | const EVP_MD *signHash; ///< The signing hash to use |
aebe6888 CT |
225 | private: |
226 | CertificateProperties(CertificateProperties &); | |
227 | CertificateProperties &operator =(CertificateProperties const &); | |
228 | }; | |
229 | ||
5107d2c4 CT |
230 | /// \ingroup SslCrtdSslAPI |
231 | /// \returns certificate database key | |
232 | std::string & OnDiskCertificateDbKey(const CertificateProperties &); | |
233 | ||
9a90aace CT |
234 | /** |
235 | \ingroup SslCrtdSslAPI | |
236 | * Decide on the kind of certificate and generate a CA- or self-signed one. | |
237 | * The generated certificate will inherite properties from certToMimic | |
238 | * Return generated certificate and private key in resultX509 and resultPkey | |
239 | * variables. | |
240 | */ | |
cf487124 | 241 | bool generateSslCertificate(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, CertificateProperties const &properties); |
9a90aace | 242 | |
95d2589c CT |
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); |
0efa4d01 CT |
257 | |
258 | /** | |
259 | \ingroup ServerProtocolSSLAPI | |
260 | * Returns CN from the certificate, suitable for use as a host name. | |
261 | * Uses static memory to temporary store the extracted name. | |
262 | */ | |
263 | const char *CommonHostName(X509 *x509); | |
264 | ||
265 | /** | |
266 | \ingroup ServerProtocolSSLAPI | |
267 | * Returns Organization from the certificate. | |
268 | * Uses static memory to temporary store the extracted name. | |
269 | */ | |
270 | const char *getOrganization(X509 *x509); | |
271 | ||
5107d2c4 CT |
272 | /// \ingroup ServerProtocolSSLAPI |
273 | /// \return whether both certificates exist and are the same (e.g., have identical ASN.1 images) | |
274 | bool CertificatesCmp(const Security::CertPointer &cert1, const Security::CertPointer &cert2); | |
70cfe22f AJ |
275 | |
276 | /// wrapper for OpenSSL X509_get0_signature() which takes care of | |
277 | /// portability issues with older OpenSSL versions | |
278 | const ASN1_BIT_STRING *X509_get_signature(const Security::CertPointer &); | |
279 | ||
95d2589c | 280 | } // namespace Ssl |
b05c1954 AR |
281 | |
282 | #endif // USE_OPENSSL | |
95d2589c | 283 | #endif // SQUID_SSL_GADGETS_H |
f53969cc | 284 |