]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/gadgets.h
Maintenance: Removed most NULLs using modernize-use-nullptr (#1075)
[thirdparty/squid.git] / src / ssl / gadgets.h
1 /*
2 * Copyright (C) 1996-2022 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_GADGETS_H
10 #define SQUID_SSL_GADGETS_H
11
12 #if USE_OPENSSL
13
14 #include "base/HardFun.h"
15 #include "compat/openssl.h"
16 #include "security/forward.h"
17 #include "ssl/crtd_message.h"
18
19 #include <string>
20
21 #if HAVE_OPENSSL_ASN1_H
22 #include <openssl/asn1.h>
23 #endif
24 #if HAVE_OPENSSL_TXT_DB_H
25 #include <openssl/txt_db.h>
26 #endif
27 #if HAVE_OPENSSL_X509V3_H
28 #include <openssl/x509v3.h>
29 #endif
30
31 namespace Ssl
32 {
33 /**
34 \defgroup SslCrtdSslAPI SSL certificate generator API
35 These functions must not depend on Squid runtime code such as debug()
36 because they are used by security_file_certgen helper.
37 */
38
39 #if !defined(SQUID_SSL_SIGN_HASH_IF_NONE)
40 #define SQUID_SSL_SIGN_HASH_IF_NONE "sha256"
41 #endif
42
43 /**
44 * std::unique_ptr typedefs for common SSL objects
45 */
46 sk_dtor_wrapper(sk_X509, STACK_OF(X509) *, X509_free);
47 typedef std::unique_ptr<STACK_OF(X509), sk_X509_free_wrapper> X509_STACK_Pointer;
48
49 typedef std::unique_ptr<BIGNUM, HardFun<void, BIGNUM*, &BN_free>> BIGNUM_Pointer;
50
51 typedef std::unique_ptr<BIO, HardFun<void, BIO*, &BIO_vfree>> BIO_Pointer;
52
53 typedef std::unique_ptr<ASN1_INTEGER, HardFun<void, ASN1_INTEGER*, &ASN1_INTEGER_free>> ASN1_INT_Pointer;
54
55 typedef std::unique_ptr<ASN1_OCTET_STRING, HardFun<void, ASN1_OCTET_STRING*, &ASN1_OCTET_STRING_free>> ASN1_OCTET_STRING_Pointer;
56
57 typedef std::unique_ptr<TXT_DB, HardFun<void, TXT_DB*, &TXT_DB_free>> TXT_DB_Pointer;
58
59 typedef std::unique_ptr<X509_NAME, HardFun<void, X509_NAME*, &X509_NAME_free>> X509_NAME_Pointer;
60
61 typedef std::unique_ptr<RSA, HardFun<void, RSA*, &RSA_free>> RSA_Pointer;
62
63 typedef std::unique_ptr<X509_REQ, HardFun<void, X509_REQ*, &X509_REQ_free>> X509_REQ_Pointer;
64
65 typedef std::unique_ptr<AUTHORITY_KEYID, HardFun<void, AUTHORITY_KEYID*, &AUTHORITY_KEYID_free>> AUTHORITY_KEYID_Pointer;
66
67 sk_dtor_wrapper(sk_GENERAL_NAME, STACK_OF(GENERAL_NAME) *, GENERAL_NAME_free);
68 typedef std::unique_ptr<STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_free_wrapper> GENERAL_NAME_STACK_Pointer;
69
70 typedef std::unique_ptr<GENERAL_NAME, HardFun<void, GENERAL_NAME*, &GENERAL_NAME_free>> GENERAL_NAME_Pointer;
71
72 typedef std::unique_ptr<X509_EXTENSION, HardFun<void, X509_EXTENSION*, &X509_EXTENSION_free>> X509_EXTENSION_Pointer;
73
74 typedef std::unique_ptr<X509_STORE_CTX, HardFun<void, X509_STORE_CTX *, &X509_STORE_CTX_free>> X509_STORE_CTX_Pointer;
75
76 // not using CtoCpp1() here because OpenSSL_free() takes void* rather than char*
77 inline void OPENSSL_free_for_c_strings(char * const string) { OPENSSL_free(string); }
78 using UniqueCString = std::unique_ptr<char, HardFun<void, char *, &OPENSSL_free_for_c_strings> >;
79
80 /// Clear any errors accumulated by OpenSSL in its global storage.
81 void ForgetErrors();
82
83 /// Manipulator to report errors accumulated by OpenSSL in its global storage.
84 /// Each error is reported on a dedicated Debug::Extra line.
85 /// Nothing is reported if there are no errors.
86 /// Also clears all reported errors.
87 std::ostream &ReportAndForgetErrors(std::ostream &);
88
89 /**
90 \ingroup SslCrtdSslAPI
91 * Create 1024 bits rsa key.
92 */
93 EVP_PKEY * createSslPrivateKey();
94
95 /**
96 \ingroup SslCrtdSslAPI
97 * Write private key and SSL certificate to memory.
98 */
99 bool writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey, std::string & bufferToWrite);
100
101 /**
102 \ingroup SslCrtdSslAPI
103 * Append SSL certificate to bufferToWrite.
104 */
105 bool appendCertToMemory(Security::CertPointer const & cert, std::string & bufferToWrite);
106
107 /**
108 \ingroup SslCrtdSslAPI
109 * Write private key and SSL certificate to memory.
110 */
111 bool readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, char const * bufferToRead);
112
113 /// Creates and returns a BIO for reading from the given c-string.
114 /// The returned BIO lifetime must not exceed that of the given c-string!
115 BIO_Pointer ReadOnlyBioTiedTo(const char *);
116
117 /**
118 \ingroup SslCrtdSslAPI
119 * Read private key from file.
120 */
121 void ReadPrivateKeyFromFile(char const * keyFilename, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback);
122
123 /**
124 \ingroup SslCrtdSslAPI
125 * Initialize the bio with the file 'filename' opened for reading
126 */
127 bool OpenCertsFileForReading(BIO_Pointer &bio, const char *filename);
128
129 /// Reads and returns a certificate using the given OpenSSL BIO.
130 /// Never returns a nil pointer.
131 Security::CertPointer ReadCertificate(const BIO_Pointer &);
132
133 /// Reads and returns a certificate using the given OpenSSL BIO.
134 /// \returns a nil pointer if the given BIO is empty or exhausted
135 Security::CertPointer ReadOptionalCertificate(const BIO_Pointer &);
136
137 /**
138 \ingroup SslCrtdSslAPI
139 * Read a private key from bio
140 */
141 bool ReadPrivateKey(BIO_Pointer &bio, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback);
142
143 /**
144 \ingroup SslCrtdSslAPI
145 * Initialize the bio with the file 'filename' opened for writing
146 */
147
148 bool OpenCertsFileForWriting(BIO_Pointer &bio, const char *filename);
149
150 /**
151 \ingroup SslCrtdSslAPI
152 * Write certificate to BIO.
153 */
154 bool WriteX509Certificate(BIO_Pointer &bio, const Security::CertPointer & cert);
155
156 /**
157 \ingroup SslCrtdSslAPI
158 * Write private key to BIO.
159 */
160 bool WritePrivateKey(BIO_Pointer &bio, const Security::PrivateKeyPointer &pkey);
161
162 /// a RAII wrapper for the memory-allocating flavor of X509_NAME_oneline()
163 UniqueCString OneLineSummary(X509_NAME &);
164
165 /**
166 \ingroup SslCrtdSslAPI
167 * Supported certificate signing algorithms
168 */
169 enum CertSignAlgorithm {algSignTrusted = 0, algSignUntrusted, algSignSelf, algSignEnd};
170
171 /**
172 \ingroup SslCrtdSslAPI
173 * Short names for certificate signing algorithms
174 */
175
176 extern const char *CertSignAlgorithmStr[];
177
178 /**
179 \ingroup SslCrtdSslAPI
180 * Return the short name of the signing algorithm "sg"
181 */
182 inline const char *certSignAlgorithm(int sg)
183 {
184 if (sg >=0 && sg < Ssl::algSignEnd)
185 return Ssl::CertSignAlgorithmStr[sg];
186
187 return nullptr;
188 }
189
190 /**
191 \ingroup SslCrtdSslAPI
192 * Return the id of the signing algorithm "sg"
193 */
194 inline CertSignAlgorithm certSignAlgorithmId(const char *sg)
195 {
196 for (int i = 0; i < algSignEnd && Ssl::CertSignAlgorithmStr[i] != nullptr; i++)
197 if (strcmp(Ssl::CertSignAlgorithmStr[i], sg) == 0)
198 return (CertSignAlgorithm)i;
199
200 return algSignEnd;
201 }
202
203 /**
204 \ingroup SslCrtdSslAPI
205 * Supported certificate adaptation algorithms
206 */
207 enum CertAdaptAlgorithm {algSetValidAfter = 0, algSetValidBefore, algSetCommonName, algSetEnd};
208
209 /**
210 \ingroup SslCrtdSslAPI
211 * Short names for certificate adaptation algorithms
212 */
213 extern const char *CertAdaptAlgorithmStr[];
214
215 /**
216 \ingroup SslCrtdSslAPI
217 * Return the short name of the adaptation algorithm "alg"
218 */
219 inline const char *sslCertAdaptAlgoritm(int alg)
220 {
221 if (alg >=0 && alg < Ssl::algSetEnd)
222 return Ssl::CertAdaptAlgorithmStr[alg];
223
224 return nullptr;
225 }
226
227 /**
228 \ingroup SslCrtdSslAPI
229 * Simple struct to pass certificate generation parameters to generateSslCertificate function.
230 */
231 class CertificateProperties
232 {
233 public:
234 CertificateProperties();
235 Security::CertPointer mimicCert; ///< Certificate to mimic
236 Security::CertPointer signWithX509; ///< Certificate to sign the generated request
237 Security::PrivateKeyPointer signWithPkey; ///< The key of the signing certificate
238 bool setValidAfter; ///< Do not mimic "Not Valid After" field
239 bool setValidBefore; ///< Do not mimic "Not Valid Before" field
240 bool setCommonName; ///< Replace the CN field of the mimicking subject with the given
241 std::string commonName; ///< A CN to use for the generated certificate
242 CertSignAlgorithm signAlgorithm; ///< The signing algorithm to use
243 const EVP_MD *signHash; ///< The signing hash to use
244 private:
245 CertificateProperties(CertificateProperties &);
246 CertificateProperties &operator =(CertificateProperties const &);
247 };
248
249 /// \ingroup SslCrtdSslAPI
250 /// \returns certificate database key
251 std::string & OnDiskCertificateDbKey(const CertificateProperties &);
252
253 /**
254 \ingroup SslCrtdSslAPI
255 * Decide on the kind of certificate and generate a CA- or self-signed one.
256 * The generated certificate will inherite properties from certToMimic
257 * Return generated certificate and private key in resultX509 and resultPkey
258 * variables.
259 */
260 bool generateSslCertificate(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, CertificateProperties const &properties);
261
262 /**
263 \ingroup SslCrtdSslAPI
264 * Verify date. Date format it ASN1_UTCTIME. if there is out of date error,
265 * return false.
266 */
267 bool sslDateIsInTheFuture(char const * date);
268
269 /**
270 \ingroup SslCrtdSslAPI
271 * Check if the major fields of a certificates matches the properties given by
272 * a CertficateProperties object
273 \return true if the certificates matches false otherwise.
274 */
275 bool certificateMatchesProperties(X509 *peer_cert, CertificateProperties const &properties);
276
277 /**
278 \ingroup ServerProtocolSSLAPI
279 * Returns CN from the certificate, suitable for use as a host name.
280 * Uses static memory to temporary store the extracted name.
281 */
282 const char *CommonHostName(X509 *x509);
283
284 /**
285 \ingroup ServerProtocolSSLAPI
286 * Returns Organization from the certificate.
287 * Uses static memory to temporary store the extracted name.
288 */
289 const char *getOrganization(X509 *x509);
290
291 /// \ingroup ServerProtocolSSLAPI
292 /// \return whether both certificates exist and are the same (e.g., have identical ASN.1 images)
293 bool CertificatesCmp(const Security::CertPointer &cert1, const Security::CertPointer &cert2);
294
295 /// wrapper for OpenSSL X509_get0_signature() which takes care of
296 /// portability issues with older OpenSSL versions
297 const ASN1_BIT_STRING *X509_get_signature(const Security::CertPointer &);
298
299 } // namespace Ssl
300
301 #endif // USE_OPENSSL
302 #endif // SQUID_SSL_GADGETS_H
303