1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2005-2010 Free Software Foundation Europe e.V.
5 Copyright (C) 2018-2018 Bareos GmbH & Co. KG
6
7 This program is Free Software; you can redistribute it and/or
8 modify it under the terms of version three of the GNU Affero General Public
9 License as published by the Free Software Foundation and included
10 in the file LICENSE.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
21 */
22
23 #include "include/bareos.h"
24 #include "tls_openssl.h"
25 #include "tls_openssl_private.h"
26
27 #include "lib/bpoll.h"
28 #include "lib/crypto_openssl.h"
29 #include "lib/tls_openssl_crl.h"
30
31 #include "lib/parse_conf.h"
32 #include "lib/get_tls_psk_by_fqname_callback.h"
33 #include "lib/bstringlist.h"
34
35 #include <openssl/err.h>
36 #include <openssl/ssl.h>
37 #include <algorithm>
38
39 /* static private */
40 std::map<const SSL_CTX *, PskCredentials> TlsOpenSslPrivate::psk_client_credentials_;
41 std::mutex TlsOpenSslPrivate::psk_client_credentials_mutex_;
42 std::mutex TlsOpenSslPrivate::file_access_mutex_;
43
44 /* static private */
45 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
46 const std::string TlsOpenSslPrivate::tls_default_ciphers_ {"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"};
47
48
TlsOpenSslPrivate()49 TlsOpenSslPrivate::TlsOpenSslPrivate()
50 : openssl_(nullptr)
51 , openssl_ctx_(nullptr)
52 , tcp_file_descriptor_(0)
53 , pem_callback_(nullptr)
54 , pem_userdata_(nullptr)
55 , verify_peer_ (false)
56 {
57 Dmsg0(100, "Construct TlsOpenSslPrivate\n");
58 }
59
~TlsOpenSslPrivate()60 TlsOpenSslPrivate::~TlsOpenSslPrivate()
61 {
62 Dmsg0(100, "Destruct TlsOpenSslPrivate\n");
63
64 /* Free in this order:
65 * 1. openssl object
66 * 2. openssl_ctx object */
67
68 if (openssl_) {
69 SSL_free(openssl_);
70 openssl_ = nullptr;
71 }
72
73 /* the openssl_ctx object is the factory that creates
74 * openssl objects, so delete this at the end */
75 if (openssl_ctx_) {
76 psk_client_credentials_mutex_.lock();
77 psk_client_credentials_.erase(openssl_ctx_);
78 psk_client_credentials_mutex_.unlock();
79 SSL_CTX_free(openssl_ctx_);
80 openssl_ctx_ = nullptr;
81 }
82 };
83
init()84 bool TlsOpenSslPrivate::init()
85 {
86 if (!openssl_ctx_) {
87 OpensslPostErrors(M_FATAL, _("Error initializing TlsOpenSsl (no SSL_CTX)\n"));
88 return false;
89 }
90
91 if (cipherlist_.empty()) {
92 cipherlist_ = tls_default_ciphers_;
93 }
94
95 if (SSL_CTX_set_cipher_list(openssl_ctx_, cipherlist_.c_str()) != 1) {
96 Dmsg0(100, _("Error setting cipher list, no valid ciphers available\n"));
97 return false;
98 }
99
100 if (pem_callback_ == nullptr) {
101 pem_callback_ = CryptoDefaultPemCallback;
102 pem_userdata_ = NULL;
103 }
104
105 SSL_CTX_set_default_passwd_cb(openssl_ctx_, TlsOpenSslPrivate::tls_pem_callback_dispatch);
106 SSL_CTX_set_default_passwd_cb_userdata(openssl_ctx_, reinterpret_cast<void *>(this));
107
108 const char *ca_certfile = ca_certfile_.empty() ? nullptr : ca_certfile_.c_str();
109 const char *ca_certdir = ca_certdir_.empty() ? nullptr : ca_certdir_.c_str();
110
111 if (ca_certfile || ca_certdir) { /* at least one should be set */
112 std::lock_guard<std::mutex> lg(file_access_mutex_);
113 if (!SSL_CTX_load_verify_locations(openssl_ctx_, ca_certfile, ca_certdir)) {
114 OpensslPostErrors(M_FATAL, _("Error loading certificate verification stores"));
115 return false;
116 }
117 } else if (verify_peer_) {
118 /* At least one CA is required for peer verification */
119 Dmsg0(100, _("Either a certificate file or a directory must be"
120 " specified as a verification store\n"));
121 }
122
123 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
124 if (!crlfile_.empty()) {
125 std::lock_guard<std::mutex> lg(file_access_mutex_);
126 if (!SetCertificateRevocationList(crlfile_, openssl_ctx_)) {
127 return false;
128 }
129 }
130 #endif
131
132 if (!certfile_.empty()) {
133 std::lock_guard<std::mutex> lg(file_access_mutex_);
134 if (!SSL_CTX_use_certificate_chain_file(openssl_ctx_, certfile_.c_str())) {
135 OpensslPostErrors(M_FATAL, _("Error loading certificate file"));
136 return false;
137 }
138 }
139
140 if (!keyfile_.empty()) {
141 std::lock_guard<std::mutex> lg(file_access_mutex_);
142 if (!SSL_CTX_use_PrivateKey_file(openssl_ctx_, keyfile_.c_str(), SSL_FILETYPE_PEM)) {
143 OpensslPostErrors(M_FATAL, _("Error loading private key"));
144 return false;
145 }
146 }
147
148 if (!dhfile_.empty()) { /* Diffie-Hellman parameters */
149 BIO *bio;
150 std::lock_guard<std::mutex> lg(file_access_mutex_);
151 if (!(bio = BIO_new_file(dhfile_.c_str(), "r"))) {
152 OpensslPostErrors(M_FATAL, _("Unable to open DH parameters file"));
153 return false;
154 }
155 DH *dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
156 BIO_free(bio);
157 if (!dh) {
158 OpensslPostErrors(M_FATAL, _("Unable to load DH parameters from specified file"));
159 return false;
160 }
161 if (!SSL_CTX_set_tmp_dh(openssl_ctx_, dh)) {
162 OpensslPostErrors(M_FATAL, _("Failed to set TLS Diffie-Hellman parameters"));
163 DH_free(dh);
164 return false;
165 }
166 SSL_CTX_set_options(openssl_ctx_, SSL_OP_SINGLE_DH_USE);
167 }
168
169 if (verify_peer_) {
170 /*
171 * SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode
172 */
173 SSL_CTX_set_verify(openssl_ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
174 TlsOpenSslPrivate::OpensslVerifyPeer);
175 } else {
176 SSL_CTX_set_verify(openssl_ctx_, SSL_VERIFY_NONE, NULL);
177 }
178
179 openssl_ = SSL_new(openssl_ctx_);
180 if (!openssl_) {
181 OpensslPostErrors(M_FATAL, _("Error creating new SSL object"));
182 return false;
183 }
184
185 /* Non-blocking partial writes */
186 SSL_set_mode(openssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
187
188 BIO *bio = BIO_new(BIO_s_socket());
189 if (!bio) {
190 OpensslPostErrors(M_FATAL, _("Error creating file descriptor-based BIO"));
191 return false;
192 }
193
194 ASSERT(tcp_file_descriptor_);
195 BIO_set_fd(bio, tcp_file_descriptor_, BIO_NOCLOSE);
196
197 SSL_set_bio(openssl_, bio, bio);
198
199 return true;
200 }
201
202 /*
203 * report any errors that occured
204 */
OpensslVerifyPeer(int preverify_ok,X509_STORE_CTX * store)205 int TlsOpenSslPrivate::OpensslVerifyPeer(int preverify_ok, X509_STORE_CTX *store)
206 { /* static */
207 if (!preverify_ok) {
208 X509 *cert = X509_STORE_CTX_get_current_cert(store);
209 int depth = X509_STORE_CTX_get_error_depth(store);
210 int err = X509_STORE_CTX_get_error(store);
211 char issuer[256];
212 char subject[256];
213
214 X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
215 X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
216
217 Jmsg5(NULL, M_ERROR, 0,
218 _("Error with certificate at depth: %d, issuer = %s,"
219 " subject = %s, ERR=%d:%s\n"),
220 depth, issuer, subject, err, X509_verify_cert_error_string(err));
221 }
222
223 return preverify_ok;
224 }
225
OpensslBsockReadwrite(BareosSocket * bsock,char * ptr,int nbytes,bool write)226 int TlsOpenSslPrivate::OpensslBsockReadwrite(BareosSocket *bsock, char *ptr, int nbytes, bool write)
227 {
228 if (!openssl_) {
229 Dmsg0(100, "Attempt to write on a non initialized tls connection\n");
230 return 0;
231 }
232
233 int flags = bsock->SetNonblocking();
234
235 bsock->timer_start = watchdog_time;
236 bsock->ClearTimedOut();
237 bsock->SetKillable(false);
238
239 int nleft = nbytes;
240
241 while (nleft > 0) {
242 int nwritten = 0;
243 if (write) {
244 nwritten = SSL_write(openssl_, ptr, nleft);
245 } else {
246 nwritten = SSL_read(openssl_, ptr, nleft);
247 }
248
249 int ssl_error = SSL_get_error(openssl_, nwritten);
250 switch (ssl_error) {
251 case SSL_ERROR_NONE:
252 nleft -= nwritten;
253 if (nleft) {
254 ptr += nwritten;
255 }
256 break;
257 case SSL_ERROR_SYSCALL:
258 if (nwritten == -1) {
259 if (errno == EINTR) {
260 continue;
261 }
262 if (errno == EAGAIN) {
263 Bmicrosleep(0, 20000); /* try again in 20 ms */
264 continue;
265 }
266 }
267 OpensslPostErrors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure."));
268 goto cleanup;
269 case SSL_ERROR_WANT_READ:
270 WaitForReadableFd(bsock->fd_, 10000, false);
271 break;
272 case SSL_ERROR_WANT_WRITE:
273 WaitForWritableFd(bsock->fd_, 10000, false);
274 break;
275 case SSL_ERROR_ZERO_RETURN:
276 /* TLS connection was cleanly shut down */
277 /* Fall through wanted */
278 default:
279 /* Socket Error Occured */
280 OpensslPostErrors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure."));
281 goto cleanup;
282 }
283
284 if (bsock->UseBwlimit()) {
285 if (nwritten > 0) {
286 bsock->ControlBwlimit(nwritten);
287 }
288 }
289
290 /* Everything done? */
291 if (nleft == 0) {
292 goto cleanup;
293 }
294
295 /* Timeout/Termination, let's take what we can get */
296 if (bsock->IsTimedOut() || bsock->IsTerminated()) {
297 goto cleanup;
298 }
299 }
300
301 cleanup:
302 /* Restore saved flags */
303 bsock->RestoreBlocking(flags);
304
305 /* Clear timer */
306 bsock->timer_start = 0;
307 bsock->SetKillable(true);
308
309 return nbytes - nleft;
310 }
311
OpensslBsockSessionStart(BareosSocket * bsock,bool server)312 bool TlsOpenSslPrivate::OpensslBsockSessionStart(BareosSocket *bsock, bool server)
313 {
314 bool status = true;
315
316 int flags = bsock->SetNonblocking();
317
318 bsock->timer_start = watchdog_time;
319 bsock->ClearTimedOut();
320 bsock->SetKillable(false);
321
322 for (;;) {
323 int err_accept;
324 if (server) {
325 err_accept = SSL_accept(openssl_);
326 } else {
327 err_accept = SSL_connect(openssl_);
328 }
329
330 int ssl_error = SSL_get_error(openssl_, err_accept);
331 switch (ssl_error) {
332 case SSL_ERROR_NONE:
333 bsock->SetTlsEstablished();
334 status = true;
335 goto cleanup;
336 case SSL_ERROR_ZERO_RETURN:
337 /* TLS connection was cleanly shut down */
338 OpensslPostErrors(bsock->get_jcr(), M_FATAL, _("Connect failure"));
339 status = false;
340 goto cleanup;
341 case SSL_ERROR_WANT_READ:
342 WaitForReadableFd(bsock->fd_, 10000, false);
343 break;
344 case SSL_ERROR_WANT_WRITE:
345 WaitForWritableFd(bsock->fd_, 10000, false);
346 break;
347 default:
348 /* Socket Error Occurred */
349 OpensslPostErrors(bsock->get_jcr(), M_FATAL, _("Connect failure"));
350 status = false;
351 goto cleanup;
352 }
353
354 if (bsock->IsTimedOut()) {
355 goto cleanup;
356 }
357 }
358
359 cleanup:
360 /* Restore saved flags */
361 bsock->RestoreBlocking(flags);
362 /* Clear timer */
363 bsock->timer_start = 0;
364 bsock->SetKillable(true);
365
366 return status;
367 }
368
tls_pem_callback_dispatch(char * buf,int size,int rwflag,void * userdata)369 int TlsOpenSslPrivate::tls_pem_callback_dispatch(char *buf, int size, int rwflag, void *userdata)
370 {
371 TlsOpenSslPrivate *p = reinterpret_cast<TlsOpenSslPrivate *>(userdata);
372 return (p->pem_callback_(buf, size, p->pem_userdata_));
373 }
374
ClientContextInsertCredentials(const PskCredentials & credentials)375 void TlsOpenSslPrivate::ClientContextInsertCredentials(const PskCredentials &credentials)
376 {
377 if (!openssl_ctx_) { /* do not register nullptr */
378 Dmsg0(100, "Psk Server Callback: No SSL_CTX\n");
379 } else {
380 psk_client_credentials_mutex_.lock();
381 TlsOpenSslPrivate::psk_client_credentials_.insert(
382 std::pair<const SSL_CTX *, PskCredentials>(openssl_ctx_, credentials));
383 psk_client_credentials_mutex_.unlock();
384 }
385 }
386
psk_server_cb(SSL * ssl,const char * identity,unsigned char * psk_output,unsigned int max_psk_len)387 unsigned int TlsOpenSslPrivate::psk_server_cb(SSL *ssl,
388 const char *identity,
389 unsigned char *psk_output,
390 unsigned int max_psk_len)
391 {
392 unsigned int result = 0;
393
394 SSL_CTX *openssl_ctx = SSL_get_SSL_CTX(ssl);
395
396 if (!openssl_ctx) {
397 Dmsg0(100, "Psk Server Callback: No SSL_CTX\n");
398 return result;
399 }
400 BStringList lst(std::string(identity),AsciiControlCharacters::RecordSeparator());
401 Dmsg1(100, "psk_server_cb. identitiy: %s.\n", lst.JoinReadable().c_str());
402
403 std::string configured_psk;
404 GetTlsPskByFullyQualifiedResourceNameCb_t GetTlsPskByFullyQualifiedResourceNameCb =
405 reinterpret_cast<GetTlsPskByFullyQualifiedResourceNameCb_t>(SSL_CTX_get_ex_data(
406 openssl_ctx, TlsOpenSslPrivate::SslCtxExDataIndex::kGetTlsPskByFullyQualifiedResourceNameCb));
407
408 if (!GetTlsPskByFullyQualifiedResourceNameCb) {
409 Dmsg0(100, "Callback not set: kGetTlsPskByFullyQualifiedResourceNameCb\n");
410 return result;
411 }
412
413 ConfigurationParser *config = reinterpret_cast<ConfigurationParser*>(SSL_CTX_get_ex_data(
414 openssl_ctx, TlsOpenSslPrivate::SslCtxExDataIndex::kConfigurationParserPtr));
415
416 if (!config) {
417 Dmsg0(100, "Config not set: kConfigurationParserPtr\n");
418 return result;
419 }
420
421 if (!GetTlsPskByFullyQualifiedResourceNameCb(config, identity, configured_psk)) {
422 Dmsg0(100, "Error, TLS-PSK credentials not found.\n");
423 } else {
424 int psklen = Bsnprintf((char *)psk_output, max_psk_len, "%s", configured_psk.c_str());
425 result = (psklen < 0) ? 0 : psklen;
426 Dmsg1(100, "psk_server_cb. result: %d.\n", result);
427 }
428 return result;
429 }
430
psk_client_cb(SSL * ssl,const char *,char * identity,unsigned int max_identity_len,unsigned char * psk,unsigned int max_psk_len)431 unsigned int TlsOpenSslPrivate::psk_client_cb(SSL *ssl,
432 const char * /*hint*/,
433 char *identity,
434 unsigned int max_identity_len,
435 unsigned char *psk,
436 unsigned int max_psk_len)
437 {
438 const SSL_CTX *openssl_ctx = SSL_get_SSL_CTX(ssl);
439
440 if (!openssl_ctx) {
441 Dmsg0(100, "Psk Client Callback: No SSL_CTX\n");
442 return 0;
443 }
444
445 PskCredentials credentials;
446 bool found = false;
447
448 psk_client_credentials_mutex_.lock();
449 if (psk_client_credentials_.find(openssl_ctx) != psk_client_credentials_.end()) {
450 credentials = TlsOpenSslPrivate::psk_client_credentials_.at(openssl_ctx);
451 found = true;
452 }
453 psk_client_credentials_mutex_.unlock();
454
455 if (!found) {
456 Dmsg0(100, "Error, TLS-PSK CALLBACK not set because SSL_CTX is not registered.\n");
457 return 0;
458 }
459 int ret = Bsnprintf(identity, max_identity_len, "%s", credentials.get_identity().c_str());
460
461 if (ret < 0 || (unsigned int)ret > max_identity_len) {
462 Dmsg0(100, "Error, identify too long\n");
463 return 0;
464 }
465 std::string identity_log = identity;
466 std::replace(identity_log.begin(), identity_log.end(), AsciiControlCharacters::RecordSeparator(), ' ');
467 Dmsg1(100, "psk_client_cb. identity: %s.\n", identity_log.c_str());
468
469 ret = Bsnprintf((char *)psk, max_psk_len, "%s", credentials.get_psk().c_str());
470 if (ret < 0 || (unsigned int)ret > max_psk_len) {
471 Dmsg0(100, "Error, psk too long\n");
472 return 0;
473 }
474 return ret;
475 }
476
477 /*
478 * public interfaces from TlsOpenSsl that set private data
479 */
Setca_certfile_(const std::string & ca_certfile)480 void TlsOpenSsl::Setca_certfile_(const std::string &ca_certfile)
481 {
482 Dmsg1(100, "Set ca_certfile:\t<%s>\n", ca_certfile.c_str());
483 d_->ca_certfile_ = ca_certfile;
484 }
485
SetCaCertdir(const std::string & ca_certdir)486 void TlsOpenSsl::SetCaCertdir(const std::string &ca_certdir)
487 {
488 Dmsg1(100, "Set ca_certdir:\t<%s>\n", ca_certdir.c_str());
489 d_->ca_certdir_ = ca_certdir;
490 }
491
SetCrlfile(const std::string & crlfile_)492 void TlsOpenSsl::SetCrlfile(const std::string &crlfile_)
493 {
494 Dmsg1(100, "Set crlfile_:\t<%s>\n", crlfile_.c_str());
495 d_->crlfile_ = crlfile_;
496 }
497
SetCertfile(const std::string & certfile_)498 void TlsOpenSsl::SetCertfile(const std::string &certfile_)
499 {
500 Dmsg1(100, "Set certfile_:\t<%s>\n", certfile_.c_str());
501 d_->certfile_ = certfile_;
502 }
503
SetKeyfile(const std::string & keyfile_)504 void TlsOpenSsl::SetKeyfile(const std::string &keyfile_)
505 {
506 Dmsg1(100, "Set keyfile_:\t<%s>\n", keyfile_.c_str());
507 d_->keyfile_ = keyfile_;
508 }
509
SetPemCallback(CRYPTO_PEM_PASSWD_CB pem_callback)510 void TlsOpenSsl::SetPemCallback(CRYPTO_PEM_PASSWD_CB pem_callback)
511 {
512 Dmsg1(100, "Set pem_callback to address: <%#x>\n", reinterpret_cast<uint64_t>(pem_callback));
513 d_->pem_callback_ = pem_callback;
514 }
515
SetPemUserdata(void * pem_userdata)516 void TlsOpenSsl::SetPemUserdata(void *pem_userdata)
517 {
518 Dmsg1(100, "Set pem_userdata to address: <%#x>\n", reinterpret_cast<uint64_t>(pem_userdata));
519 d_->pem_userdata_ = pem_userdata;
520 }
521
SetDhFile(const std::string & dhfile_)522 void TlsOpenSsl::SetDhFile(const std::string &dhfile_)
523 {
524 Dmsg1(100, "Set dhfile_:\t<%s>\n", dhfile_.c_str());
525 d_->dhfile_ = dhfile_;
526 }
527
SetVerifyPeer(const bool & verify_peer)528 void TlsOpenSsl::SetVerifyPeer(const bool &verify_peer)
529 {
530 Dmsg1(100, "Set Verify Peer:\t<%s>\n", verify_peer ? "true" : "false");
531 d_->verify_peer_ = verify_peer;
532 }
533
SetTcpFileDescriptor(const int & fd)534 void TlsOpenSsl::SetTcpFileDescriptor(const int &fd)
535 {
536 Dmsg1(100, "Set tcp filedescriptor: <%d>\n", fd);
537 d_->tcp_file_descriptor_ = fd;
538 }
539
SetCipherList(const std::string & cipherlist)540 void TlsOpenSsl::SetCipherList(const std::string &cipherlist)
541 {
542 Dmsg1(100, "Set cipherlist:\t<%s>\n", cipherlist.c_str());
543 d_->cipherlist_ = cipherlist;
544 }
545