XRootD
XrdTlsContext.cc
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2011-2018 by European Organization for Nuclear Research (CERN)
3 // Author: Michal Simon <simonm@cern.ch>
4 //------------------------------------------------------------------------------
5 // XRootD is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // XRootD is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with XRootD. If not, see <http://www.gnu.org/licenses/>.
17 //------------------------------------------------------------------------------
18 
19 #include <cstdio>
20 #include <openssl/bio.h>
21 #include <openssl/crypto.h>
22 #include <openssl/err.h>
23 #include <openssl/ssl.h>
24 #include <openssl/opensslv.h>
25 #include <sys/stat.h>
26 
27 #include "XrdOuc/XrdOucUtils.hh"
28 #include "XrdSys/XrdSysRAtomic.hh"
29 #include "XrdSys/XrdSysError.hh"
30 #include "XrdSys/XrdSysPthread.hh"
31 #include "XrdSys/XrdSysTimer.hh"
32 
33 #include "XrdTls/XrdTls.hh"
34 #include "XrdTls/XrdTlsContext.hh"
35 #include "XrdTls/XrdTlsTrace.hh"
36 
37 #if OPENSSL_VERSION_NUMBER >= 0x30400010
38 #define SSL_CTX_flush_sessions SSL_CTX_flush_sessions_ex
39 #endif
40 
41 /******************************************************************************/
42 /* G l o b a l s */
43 /******************************************************************************/
44 
45 namespace XrdTlsGlobal
46 {
48 };
49 
50 /******************************************************************************/
51 /* X r d T l s C o n t e x t I m p l */
52 /******************************************************************************/
53 
55 {
57  : ctx(0), ctxnew(0), owner(p), flsCVar(0),
58  flushT(0),
59  crlRunning(false), flsRunning(false) {}
60  ~XrdTlsContextImpl() {if (ctx) SSL_CTX_free(ctx);
61  if (ctxnew) delete ctxnew;
62  if (flsCVar) delete flsCVar;
63  }
64 
65  SSL_CTX *ctx;
71  short flushT;
72  bool crlRunning;
73  bool flsRunning;
74  time_t lastCertModTime = 0;
75  int sessionCacheOpts = -1;
76  std::string sessionCacheId;
77  uint64_t opts{0};
78 };
79 
80 /******************************************************************************/
81 /* C r l R e f r e s h S u p p o r t */
82 /******************************************************************************/
83 
84 namespace XrdTlsCrl
85 {
86 // Inital entry for refreshing crls
87 //
88 void *Refresh(void *parg)
89 {
90  EPNAME("Refresh");
91  int sleepTime;
92  bool doreplace;
93 
94 // Get the implementation details
95 //
96  XrdTlsContextImpl *ctxImpl = static_cast<XrdTlsContextImpl*>(parg);
97 
98 // Indicate we have started in the trace record
99 //
100  DBG_CTX("CRL refresh started.")
101 
102 // Do this forever but first get the sleep time
103 //
104 do{ctxImpl->crlMutex.ReadLock();
105  sleepTime = ctxImpl->Parm.crlRT;
106  ctxImpl->crlMutex.UnLock();
107 
108 // We may have been cancelled, in which case we just exit
109 //
110  if (!sleepTime)
111  {ctxImpl->crlMutex.WriteLock();
112  ctxImpl->crlRunning = false;
113  ctxImpl->crlMutex.UnLock();
114  DBG_CTX("CRL refresh ending by request!");
115  return (void *)0;
116  }
117 
118 // Indicate we how long before a refresh
119 //
120  DBG_CTX("CRL refresh will happen in " <<sleepTime <<" seconds.");
121 
122 // Now sleep the request amount of time
123 //
124  XrdSysTimer::Snooze(sleepTime);
125 
126  if (ctxImpl->owner->x509Verify() || ctxImpl->owner->newHostCertificateDetected()) {
127  // Check if this context is still alive. Generally, it never gets deleted.
128  //
129  ctxImpl->crlMutex.WriteLock();
130  if (!ctxImpl->owner) break;
131 
132  // We clone the original, this will give us the latest crls (i.e. refreshed).
133  // We drop the lock while doing so as this may take a long time. This is
134  // completely safe to do because we implicitly own the implementation.
135  //
136  ctxImpl->crlMutex.UnLock();
137  XrdTlsContext *newctx = ctxImpl->owner->Clone();
138 
139  // Verify that the context was properly built
140  //
141  if (!newctx || !newctx->isOK())
142  {XrdTls::Emsg("CrlRefresh:","Refresh of context failed!!!",false);
143  continue;
144  }
145 
146  // OK, set the new context to be used next time Session() is called.
147  //
148  ctxImpl->crlMutex.WriteLock();
149  doreplace = (ctxImpl->ctxnew != 0);
150  if (doreplace) delete ctxImpl->ctxnew;
151  ctxImpl->ctxnew = newctx;
152  ctxImpl->crlMutex.UnLock();
153 
154  // Do some debugging
155  //
156  if (doreplace) {DBG_CTX("CRL refresh created replacement x509 store.");}
157  else {DBG_CTX("CRL refresh created new x509 store.");}
158  }
159  } while(true);
160 
161 // If we are here the context that started us has gone away and we are done
162 //
163  bool keepctx = ctxImpl->flsRunning;
164  ctxImpl->crlRunning = false;
165  ctxImpl->crlMutex.UnLock();
166  if (!keepctx) delete ctxImpl;
167  return (void *)0;
168 }
169 }
170 
171 /******************************************************************************/
172 /* C a c h e F l u s h S u p p o r t */
173 /******************************************************************************/
174 
175 namespace XrdTlsFlush
176 {
177 /******************************************************************************/
178 /* F l u s h e r */
179 /******************************************************************************/
180 // Inital entry for refreshing crls
181 //
182 void *Flusher(void *parg)
183 {
184  EPNAME("Flusher");
185  time_t tStart, tWaited;
186  int flushT, waitT, hits, miss, sesn, tmos;
187  long tNow;
188 
189 // Get the implementation details
190 //
191  XrdTlsContextImpl *ctxImpl = static_cast<XrdTlsContextImpl*>(parg);
192 
193 // Get the interval as it may change as we are running
194 //
195  ctxImpl->crlMutex.ReadLock();
196  waitT = flushT = ctxImpl->flushT;
197  ctxImpl->crlMutex.UnLock();
198 
199 // Indicate we have started in the trace record
200 //
201  DBG_CTX("Cache flusher started; interval="<<flushT<<" seconds.");
202 
203 // Do this forever
204 //
205 do{tStart = time(0);
206  ctxImpl->flsCVar->Wait(waitT);
207  tWaited= time(0) - tStart;
208 
209 // Check if this context is still alive. Generally, it never gets deleted.
210 //
211  ctxImpl->crlMutex.ReadLock();
212  if (!ctxImpl->owner) break;
213 
214 // If the interval changed, see if we should wait a bit longer
215 //
216  if (flushT != ctxImpl->flushT && tWaited < ctxImpl->flushT-1)
217  {waitT = ctxImpl->flushT - tWaited;
218  ctxImpl->crlMutex.UnLock();
219  continue;
220  }
221 
222 // Get the new values and drop the lock
223 //
224  waitT = flushT = ctxImpl->flushT;
225  ctxImpl->crlMutex.UnLock();
226 
227 // Get some relevant statistics
228 //
229  sesn = SSL_CTX_sess_number(ctxImpl->ctx);
230  hits = SSL_CTX_sess_hits(ctxImpl->ctx);
231  miss = SSL_CTX_sess_misses(ctxImpl->ctx);
232  tmos = SSL_CTX_sess_timeouts(ctxImpl->ctx);
233 
234 // Flush the cache
235 //
236  tNow = time(0);
237  SSL_CTX_flush_sessions(ctxImpl->ctx, tNow);
238 
239 // Print some stuff should debugging be on
240 //
241  if (TRACING(XrdTls::dbgCTX))
242  {char mBuff[512];
243  snprintf(mBuff, sizeof(mBuff), "sess=%d hits=%d miss=%d timeouts=%d",
244  sesn, hits, miss, tmos);
245  DBG_CTX("Cache flushed; " <<mBuff);
246  }
247  } while(true);
248 
249 // If we are here the context that started us has gone away and we are done
250 //
251  bool keepctx = ctxImpl->crlRunning;
252  ctxImpl->flsRunning = false;
253  ctxImpl->crlMutex.UnLock();
254  if (!keepctx) delete ctxImpl;
255  return (void *)0;
256 }
257 
258 /******************************************************************************/
259 /* S e t u p _ F l u s h e r */
260 /******************************************************************************/
261 
262 bool Setup_Flusher(XrdTlsContextImpl *pImpl, int flushT)
263 {
264  pthread_t tid;
265  int rc;
266 
267 // Set the new flush interval
268 //
269  pImpl->crlMutex.WriteLock();
270  pImpl->flushT = flushT;
271  pImpl->crlMutex.UnLock();
272 
273 // If the flush thread is already running, then wake it up to get the new value
274 //
275  if (pImpl->flsRunning)
276  {pImpl->flsCVar->Signal();
277  return true;
278  }
279 
280 // Start the flusher thread
281 //
282  pImpl->flsCVar = new XrdSysCondVar();
283  if ((rc = XrdSysThread::Run(&tid, XrdTlsFlush::Flusher, (void *)pImpl,
284  0, "Cache Flusher")))
285  {char eBuff[512];
286  snprintf(eBuff, sizeof(eBuff),
287  "Unable to start cache flusher thread; rc=%d", rc);
288  XrdTls::Emsg("SessCache:", eBuff, false);
289  return false;
290  }
291 
292 // Finish up
293 //
294  pImpl->flsRunning = true;
295  SSL_CTX_set_session_cache_mode(pImpl->ctx, SSL_SESS_CACHE_NO_AUTO_CLEAR);
296  return true;
297 }
298 }
299 
300 /******************************************************************************/
301 /* S S L T h r e a d i n g S u p p o r t */
302 /******************************************************************************/
303 
304 // The following may confusing because SSL MT support is somewhat bizarre.
305 // Versions < 1.0 require a numeric thread_id and lock callbasks.
306 // Versions < 1.1 require a lock_callbacks but the thread_is callback is
307 // optional. While the numeric thread_id callback can be used
308 // it's deprecated and fancier pointer/numeric call should be
309 // used. In our case, we use the deprecated version.
310 // Versions >- 1.1 Do not need any callbacks as all threading functions are
311 // internally defined to use native MT functions.
312 
313 #if OPENSSL_VERSION_NUMBER < 0x10100000L && defined(OPENSSL_THREADS)
314 namespace
315 {
316 #define XRDTLS_SET_CALLBACKS 1
317 #ifdef __solaris__
318 extern "C" {
319 #endif
320 
321 template<bool is32>
322 struct tlsmix;
323 
324 template<>
325 struct tlsmix<false> {
326  static unsigned long mixer(unsigned long x) {
327  // mixer based on splitmix64
328  x ^= x >> 30;
329  x *= 0xbf58476d1ce4e5b9UL;
330  x ^= x >> 27;
331  x *= 0x94d049bb133111ebUL;
332  x ^= x >> 31;
333  return x;
334  }
335 };
336 
337 template<>
338 struct tlsmix<true> {
339  static unsigned long mixer(unsigned long x) {
340  // mixer based on murmurhash3
341  x ^= x >> 16;
342  x *= 0x85ebca6bU;
343  x ^= x >> 13;
344  x *= 0xc2b2ae35U;
345  x ^= x >> 16;
346  return x;
347  }
348 };
349 
350 unsigned long sslTLS_id_callback(void)
351 {
352  // base thread-id on the id given by XrdSysThread;
353  // but openssl 1.0 uses thread-id as a key for looking
354  // up per thread crypto ERR structures in a hash-table.
355  // So mix bits so that the table's hash function gives
356  // better distribution.
357 
358  unsigned long x = (unsigned long)XrdSysThread::ID();
359  return tlsmix<sizeof(unsigned long)==4>::mixer(x);
360 }
361 
362 XrdSysMutex *MutexVector = 0;
363 
364 void sslTLS_lock(int mode, int n, const char *file, int line)
365 {
366 // Use exclusive locks. At some point, SSL categorizes these as read and
367 // write locks but it's not clear when this actually occurs, sigh.
368 //
369  if (mode & CRYPTO_LOCK) MutexVector[n].Lock();
370  else MutexVector[n].UnLock();
371 }
372 #ifdef __solaris__
373 }
374 #endif
375 } // namespace
376 #else
377 #undef XRDTLS_SET_CALLBACKS
378 #endif
379 
380 /******************************************************************************/
381 /* F i l e L o c a l D e f i n i t i o n s */
382 /******************************************************************************/
383 
384 namespace
385 {
386 // The following is the default cipher list. Note that for OpenSSL v1.0.2+ we
387 // use the recommended cipher list from Mozilla. Otherwise, we use the dumber
388 // less secure ciphers as older versions of openssl have issues with them. See
389 // ssl-config.mozilla.org/#config=intermediate&openssl=1.0.2k&guideline=5.4
390 //
391 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
392 const char *sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:"
393  "ECDHE-RSA-AES128-GCM-SHA256:"
394  "ECDHE-ECDSA-AES256-GCM-SHA384:"
395  "ECDHE-RSA-AES256-GCM-SHA384:"
396  "ECDHE-ECDSA-CHACHA20-POLY1305:"
397  "ECDHE-RSA-CHACHA20-POLY1305:"
398  "DHE-RSA-AES128-GCM-SHA256:"
399  "DHE-RSA-AES256-GCM-SHA384";
400 #else
401 const char *sslCiphers = "ALL:!LOW:!EXP:!MD5:!MD2";
402 #endif
403 
404 XrdSysMutex dbgMutex, tlsMutex;
405 XrdSys::RAtomic<bool> initDbgDone{ false };
406 bool initTlsDone{ false };
407 
408 /******************************************************************************/
409 /* I n i t T L S */
410 /******************************************************************************/
411 
412 void InitTLS() // This is strictly a one-time call!
413 {
414  XrdSysMutexHelper tlsHelper(tlsMutex);
415 
416 // Make sure we are not trying to load the ssl library more than once. This can
417 // happen when a server and a client instance happen to be both defined.
418 //
419  if (initTlsDone) return;
420  initTlsDone = true;
421 
422 // SSL library initialisation
423 //
424  SSL_library_init();
425  OpenSSL_add_all_algorithms();
426  SSL_load_error_strings();
427  OpenSSL_add_all_ciphers();
428 #if OPENSSL_VERSION_NUMBER < 0x30000000L
429  ERR_load_BIO_strings();
430 #endif
431  ERR_load_crypto_strings();
432 
433 // Set callbacks if we need to do this
434 //
435 #ifdef XRDTLS_SET_CALLBACKS
436 
437  int n = CRYPTO_num_locks();
438  if (n > 0)
439  {MutexVector = new XrdSysMutex[n];
440  CRYPTO_set_locking_callback(sslTLS_lock);
441  }
442  CRYPTO_set_id_callback(sslTLS_id_callback);
443 
444 #endif
445 }
446 
447 /******************************************************************************/
448 /* F a t a l */
449 /******************************************************************************/
450 
451 void Fatal(std::string *eMsg, const char *msg, bool sslmsg=false)
452 {
453 // If there is an outboard error string object, return the message there.
454 //
455  if (eMsg) *eMsg = msg;
456 
457 // Now route the message to the message callback function. If this is an ssl
458 // related error we also flush the ssl error queue to prevent suprises.
459 //
460  XrdTls::Emsg("TLS_Context:", msg, sslmsg);
461 }
462 
463 /******************************************************************************/
464 /* G e t T l s M e t h o d */
465 /******************************************************************************/
466 
467 const char *GetTlsMethod(const SSL_METHOD *&meth)
468 {
469 #if OPENSSL_VERSION_NUMBER > 0x1010000fL /* v1.1.0 */
470  meth = TLS_method();
471 #else
472  meth = SSLv23_method();
473 #endif
474  if (meth == 0) return "No negotiable TLS method available.";
475  return 0;
476 }
477 
478 /******************************************************************************/
479 /* V e r P a t h s */
480 /******************************************************************************/
481 
482 bool VerPaths(const char *cert, const char *pkey,
483  const char *cadr, const char *cafl, std::string &eMsg)
484 {
485  static const mode_t cert_mode = S_IRUSR | S_IWUSR | S_IRWXG | S_IROTH;
486  static const mode_t pkey_mode = S_IRUSR | S_IWUSR;
487  static const mode_t cadr_mode = S_IRWXU | S_IRGRP | S_IXGRP
488  | S_IROTH | S_IXOTH;
489  static const mode_t cafl_mode = S_IRUSR | S_IWUSR | S_IRWXG | S_IROTH;
490  const char *emsg;
491 
492 // If the ca cert directory is present make sure it's a directory and
493 // only the ower can write to that directory (anyone can read from it).
494 //
495  if (cadr && (emsg = XrdOucUtils::ValPath(cadr, cadr_mode, true)))
496  {eMsg = "Unable to use CA cert directory ";
497  eMsg += cadr; eMsg += "; "; eMsg += emsg;
498  return false;
499  }
500 
501 // If a ca cert file is present make sure it's a file and only the owner can
502 // write it (anyone can read it).
503 //
504  if (cafl && (emsg = XrdOucUtils::ValPath(cafl, cafl_mode, false)))
505  {eMsg = "Unable to use CA cert file ";
506  eMsg += cafl; eMsg += "; "; eMsg += emsg;
507  return false;
508  }
509 
510 // If a private key is present than make sure it's a file and only the
511 // owner has access to it.
512 //
513  if (pkey && (emsg = XrdOucUtils::ValPath(pkey, pkey_mode, false)))
514  {eMsg = "Unable to use key file ";
515  eMsg += pkey; eMsg += "; "; eMsg += emsg;
516  return false;
517  }
518 
519 // If a cert file is present then make sure it's a file. If a keyfile is
520 // present then anyone can read it but only the owner can write it.
521 // Otherwise, only the owner can gave access to it (it contains the key).
522 //
523  if (cert)
524  {mode_t cmode = (pkey ? cert_mode : pkey_mode);
525  if ((emsg = XrdOucUtils::ValPath(cert, cmode, false)))
526  {if (pkey) eMsg = "Unable to use cert file ";
527  else eMsg = "Unable to use cert+key file ";
528  eMsg += cert; eMsg += "; "; eMsg += emsg;
529  return false;
530  }
531  }
532 
533 // All tests succeeded.
534 //
535  return true;
536 }
537 
538 /******************************************************************************/
539 /* V e r C B */
540 /******************************************************************************/
541 
542 extern "C"
543 {
544 int VerCB(int aOK, X509_STORE_CTX *x509P)
545 {
546  if (!aOK)
547  {X509 *cert = X509_STORE_CTX_get_current_cert(x509P);
548  int depth = X509_STORE_CTX_get_error_depth(x509P);
549  int err = X509_STORE_CTX_get_error(x509P);
550  char name[512], info[1024];
551 
552  X509_NAME_oneline(X509_get_subject_name(cert), name, sizeof(name));
553  snprintf(info,sizeof(info),"Cert verification failed for DN=%s",name);
554  XrdTls::Emsg("CertVerify:", info, false);
555 
556  X509_NAME_oneline(X509_get_issuer_name(cert), name, sizeof(name));
557  snprintf(info,sizeof(info),"Failing cert issuer=%s", name);
558  XrdTls::Emsg("CertVerify:", info, false);
559 
560  snprintf(info, sizeof(info), "Error %d at depth %d [%s]", err, depth,
561  X509_verify_cert_error_string(err));
562  XrdTls::Emsg("CertVerify:", info, true);
563  }
564 
565  return aOK;
566 }
567 }
568 
569 } // Anonymous namespace end
570 
571 /******************************************************************************/
572 /* C o n s t r u c t o r */
573 /******************************************************************************/
574 
575 #define KILL_CTX(x) if (x) {SSL_CTX_free(x); x = 0;}
576 
577 #define FATAL(msg) {Fatal(eMsg, msg); KILL_CTX(pImpl->ctx); return;}
578 
579 #define FATAL_SSL(msg) {Fatal(eMsg, msg, true); KILL_CTX(pImpl->ctx); return;}
580 
581 XrdTlsContext::XrdTlsContext(const char *cert, const char *key,
582  const char *caDir, const char *caFile,
583  uint64_t opts, std::string *eMsg)
584  : pImpl( new XrdTlsContextImpl(this) )
585 {
586  class ctx_helper
587  {public:
588 
589  void Keep() {ctxLoc = 0;}
590 
591  ctx_helper(SSL_CTX **ctxP) : ctxLoc(ctxP) {}
592  ~ctx_helper() {if (ctxLoc && *ctxLoc)
593  {SSL_CTX_free(*ctxLoc); *ctxLoc = 0;}
594  }
595  private:
596  SSL_CTX **ctxLoc;
597  } ctx_tracker(&pImpl->ctx);
598 
599  pImpl->opts = opts;
600 
601  static const uint64_t sslOpts = SSL_OP_ALL
602  | SSL_OP_NO_SSLv2
603  | SSL_OP_NO_SSLv3
604  | SSL_OP_NO_COMPRESSION
605 #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
606  | SSL_OP_IGNORE_UNEXPECTED_EOF
607 #endif
608 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
609  | SSL_OP_NO_RENEGOTIATION
610 #endif
611  ;
612 
613  std::string certFN, eText;
614  const char *emsg;
615 
616 // Assume we will fail
617 //
618  pImpl->ctx = 0;
619 
620 // Verify that initialzation has occurred. This is not heavy weight as
621 // there will usually be no more than two instances of this object.
622 //
623  if (!initDbgDone)
624  {XrdSysMutexHelper dbgHelper(dbgMutex);
625  if (!initDbgDone)
626  {const char *dbg;
627  if (!(opts & servr) && (dbg = getenv("XRDTLS_DEBUG")))
628  {int dbgOpts = 0;
629  if (strstr(dbg, "ctx")) dbgOpts |= XrdTls::dbgCTX;
630  if (strstr(dbg, "sok")) dbgOpts |= XrdTls::dbgSOK;
631  if (strstr(dbg, "sio")) dbgOpts |= XrdTls::dbgSIO;
632  if (!dbgOpts) dbgOpts = XrdTls::dbgALL;
634  }
635  if ((emsg = Init())) FATAL(emsg);
636  initDbgDone = true;
637  }
638  }
639 
640 // If no CA cert information is specified and this is not a server context,
641 // then get the paths from the environment. They must exist as we need to
642 // verify peer certs in order to verify target host names client-side. We
643 // also use this setupt to see if we should use a specific cert and key.
644 //
645  if (!(opts & servr))
646  {if (!caDir && !caFile)
647  {caDir = getenv("X509_CERT_DIR");
648  caFile = getenv("X509_CERT_FILE");
649  if (!caDir && !caFile)
650  FATAL("No CA cert specified; host identity cannot be verified.");
651  }
652  if (!key) key = getenv("X509_USER_KEY");
653  if (!cert) cert = getenv("X509_USER_PROXY");
654  if (!cert)
655  {struct stat Stat;
656  long long int uid = static_cast<long long int>(getuid());
657  certFN = std::string("/tmp/x509up_u") + std::to_string(uid);
658  if (!stat(certFN.c_str(), &Stat)) cert = certFN.c_str();
659  }
660  }
661 
662 // Before we try to use any specified files, make sure they exist, are of
663 // the right type and do not have excessive access privileges.
664 // .a
665  if (!VerPaths(cert, key, caDir, caFile, eText)) FATAL( eText.c_str());
666 
667 // Copy parameters to out parm structure.
668 //
669  if (cert) {
670  pImpl->Parm.cert = cert;
671  //This call should not fail as a stat is already performed in the call of VerPaths() above
673  }
674  if (key) pImpl->Parm.pkey = key;
675  if (caDir) pImpl->Parm.cadir = caDir;
676  if (caFile) pImpl->Parm.cafile = caFile;
677  pImpl->Parm.opts = opts;
678  if (opts & crlRF) {
679  // What we store in crlRF is the time in minutes, convert it back to seconds
680  pImpl->Parm.crlRT = static_cast<int>((opts & crlRF) >> crlRS) * 60;
681  }
682 
683 // Get the correct method to use for TLS and check if successful create a
684 // server context that uses the method.
685 //
686  const SSL_METHOD *meth;
687  emsg = GetTlsMethod(meth);
688  if (emsg) FATAL(emsg);
689 
690  pImpl->ctx = SSL_CTX_new(meth);
691 
692 // Make sure we have a context here
693 //
694  if (pImpl->ctx == 0) FATAL_SSL("Unable to allocate TLS context!");
695 
696 // Always prohibit SSLv2 & SSLv3 as these are not secure.
697 //
698  SSL_CTX_set_options(pImpl->ctx, sslOpts);
699 
700 // Handle session re-negotiation automatically
701 //
702 // SSL_CTX_set_mode(pImpl->ctx, sslMode);
703 
704 // Turn off the session cache as it's useless with peer cert chains
705 //
706  SSL_CTX_set_session_cache_mode(pImpl->ctx, SSL_SESS_CACHE_OFF);
707 
708 // Establish the CA cert locations, if specified. Then set the verification
709 // depth and turn on peer cert validation. For now, we don't set a callback.
710 // In the future we may to grab debugging information.
711 //
712  if (caDir || caFile)
713  {if (!SSL_CTX_load_verify_locations(pImpl->ctx, caFile, caDir))
714  FATAL_SSL("Unable to load the CA cert file or directory.");
715 
716  int vDepth = (opts & vdept) >> vdepS;
717  SSL_CTX_set_verify_depth(pImpl->ctx, (vDepth ? vDepth : 9));
718 
719  bool LogVF = (opts & logVF) != 0;
720  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_PEER, (LogVF ? VerCB : 0));
721 
722  unsigned long xFlags = (opts & nopxy ? 0 : X509_V_FLAG_ALLOW_PROXY_CERTS);
723  if (opts & crlON)
724  {xFlags |= X509_V_FLAG_CRL_CHECK;
725  if (opts & crlFC) xFlags |= X509_V_FLAG_CRL_CHECK_ALL;
726  }
727  if (opts) X509_STORE_set_flags(SSL_CTX_get_cert_store(pImpl->ctx),xFlags);
728  } else {
729  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_NONE, 0);
730  }
731 
732 // Set cipher list
733 //
734  if (!SSL_CTX_set_cipher_list(pImpl->ctx, sslCiphers))
735  FATAL_SSL("Unable to set SSL cipher list; no supported ciphers.");
736 
737 // If we need to enable eliptic-curve support, do so now. Note that for
738 // OpenSSL 1.1.0+ this is automatically done for us.
739 //
740 #if SSL_CTRL_SET_ECDH_AUTO
741  SSL_CTX_set_ecdh_auto(pImpl->ctx, 1);
742 #endif
743 
744 // We normally handle renegotiation during reads and writes or selective
745 // prohibit on a SSL socket basis. The calle may request this be applied
746 // to all SSL's generated from this context. If so, do it here.
747 //
748  if (opts & artON) SSL_CTX_set_mode(pImpl->ctx, SSL_MODE_AUTO_RETRY);
749 
750 // If there is no cert then assume this is a generic context for a client
751 //
752  if (cert == 0)
753  {ctx_tracker.Keep();
754  return;
755  }
756 
757 // We have a cert. If the key is missing then we assume the key is in the
758 // cert file (ssl will complain if it isn't).
759 //
760  if (!key) key = cert;
761 
762 // Load certificate
763 //
764  if (SSL_CTX_use_certificate_chain_file(pImpl->ctx, cert) != 1)
765  FATAL_SSL("Unable to create TLS context; invalid certificate.");
766 
767 // Load the private key
768 //
769  if (SSL_CTX_use_PrivateKey_file(pImpl->ctx, key, SSL_FILETYPE_PEM) != 1 )
770  FATAL_SSL("Unable to create TLS context; invalid private key.");
771 
772 // Make sure the key and certificate file match.
773 //
774  if (SSL_CTX_check_private_key(pImpl->ctx) != 1 )
775  FATAL_SSL("Unable to create TLS context; cert-key mismatch.");
776 
777 // All went well, start the CRL refresh thread and keep the context.
778 //
779  if(opts & rfCRL) {
780  SetCrlRefresh();
781  }
782  ctx_tracker.Keep();
783 }
784 
785 /******************************************************************************/
786 /* D e s t r u c t o r */
787 /******************************************************************************/
788 
790 {
791 // We can delet eour implementation of there is no refresh thread running. If
792 // there is then the refresh thread has to delete the implementation.
793 //
794  if (pImpl->crlRunning | pImpl->flsRunning)
795  {pImpl->crlMutex.WriteLock();
796  pImpl->owner = 0;
797  pImpl->crlMutex.UnLock();
798  } else delete pImpl;
799 }
800 
801 /******************************************************************************/
802 /* C l o n e */
803 /******************************************************************************/
804 
805 XrdTlsContext *XrdTlsContext::Clone(bool full,bool startCRLRefresh)
806 {
807  XrdTlsContext::CTX_Params &my = pImpl->Parm;
808  const char *cert = (my.cert.size() ? my.cert.c_str() : 0);
809  const char *pkey = (my.pkey.size() ? my.pkey.c_str() : 0);
810  const char *caD = (my.cadir.size() ? my.cadir.c_str() : 0);
811  const char *caF = (my.cafile.size() ? my.cafile.c_str() : 0);
812 
813 // If this is a non-full context, get rid of any verification
814 //
815  if (!full) caD = caF = 0;
816 
817 // Cloning simply means getting a object with the old parameters.
818 //
819  uint64_t myOpts = my.opts;
820  if(startCRLRefresh){
822  } else {
824  }
825  XrdTlsContext *xtc = new XrdTlsContext(cert, pkey, caD, caF, myOpts);
826 
827 // Verify that the context was built
828 //
829  if (xtc->isOK()) {
830  if(pImpl->sessionCacheOpts != -1){
831  //A SessionCache() call was done for the current context, so apply it for this new cloned context
832  xtc->SessionCache(pImpl->sessionCacheOpts,pImpl->sessionCacheId.c_str(),pImpl->sessionCacheId.size());
833  }
834  return xtc;
835  }
836 
837 // We failed, cleanup.
838 //
839  delete xtc;
840  return 0;
841 }
842 
843 /******************************************************************************/
844 /* C o n t e x t */
845 /******************************************************************************/
846 
848 {
849  return pImpl->ctx;
850 }
851 
852 /******************************************************************************/
853 /* G e t P a r a m s */
854 /******************************************************************************/
855 
857 {
858  return &pImpl->Parm;
859 }
860 
861 /******************************************************************************/
862 /* I n i t */
863 /******************************************************************************/
864 
865 const char *XrdTlsContext::Init()
866 {
867 
868 // Disallow use if this object unless SSL provides thread-safety!
869 //
870 #ifndef OPENSSL_THREADS
871  return "Installed OpenSSL lacks the required thread support!";
872 #endif
873 
874 // Initialize the library (one time call)
875 //
876  InitTLS();
877  return 0;
878 }
879 
880 /******************************************************************************/
881 /* i s O K */
882 /******************************************************************************/
883 
885 {
886  return pImpl->ctx != 0;
887 }
888 
889 /******************************************************************************/
890 /* S e s s i o n */
891 /******************************************************************************/
892 
893 // Note: The reason we handle the x509 store update here is because allow the
894 // SSL context to be exported and then have no lock control over it. This may
895 // happen for transient purposes other than creating sessions. Once we
896 // disallow direct access to the context, the exchange can happen in the
897 // refresh thread which simplifies this whole process.
898 
900 {
901 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
902 
903  EPNAME("Session");
904  SSL *ssl;
905 
906 // Check if we have a refreshed context. If so, we need to replace the X509
907 // store in the current context with the new one before we create the session.
908 //
909  pImpl->crlMutex.ReadLock();
910  if (!(pImpl->ctxnew))
911  {ssl = SSL_new(pImpl->ctx);
912  pImpl->crlMutex.UnLock();
913  return ssl;
914  }
915 
916 // Things have changed, so we need to take the long route here. We need to
917 // replace the x509 cache with the current cache. Get a R/W lock now.
918 //
919  pImpl->crlMutex.UnLock();
920  pImpl->crlMutex.WriteLock();
921 
922 // If some other thread beat us to the punch, just return what we have.
923 //
924  if (!(pImpl->ctxnew))
925  {ssl = SSL_new(pImpl->ctx);
926  pImpl->crlMutex.UnLock();
927  return ssl;
928  }
929 
930 // Do some tracing
931 //
932  DBG_CTX("Replacing x509 store with new contents.");
933 
934 // Get the new store and set it in our context. Setting the store is black
935 // magic. For OpenSSL < 1.1, Two stores need to be set with the "set1" variant.
936 // Newer version only require SSL_CTX_set1_cert_store() to be used.
937 //
938  //We have a new context generated by Refresh, so we must use it.
939  XrdTlsContext * ctxnew = pImpl->ctxnew;
940 
941  /*X509_STORE *newX509 = SSL_CTX_get_cert_store(ctxnew->pImpl->ctx);
942  SSL_CTX_set1_verify_cert_store(pImpl->ctx, newX509);
943  SSL_CTX_set1_chain_cert_store(pImpl->ctx, newX509);*/
944  //The above two macros actually do not replace the certificate that has
945  //to be used for that SSL session, so we will create the session with the SSL_CTX * of
946  //the TlsContext created by Refresh()
947  //First, free the current SSL_CTX, if it is used by any transfer, it will just decrease
948  //the reference counter of it. There is therefore no risk of double free...
949  SSL_CTX_free(pImpl->ctx);
950  pImpl->ctx = ctxnew->pImpl->ctx;
951  //In the destructor of XrdTlsContextImpl, SSL_CTX_Free() is
952  //called if ctx is != 0. As this new ctx is used by the session
953  //we just created, we don't want that to happen. We therefore set it to 0.
954  //The SSL_free called on the session will cleanup the context for us.
955  ctxnew->pImpl->ctx = 0;
956 
957 // Save the generated context and clear it's presence
958 //
959  XrdTlsContext *ctxold = pImpl->ctxnew;
960  pImpl->ctxnew = 0;
961 
962 // Generate a new session (might as well to keep the lock we have)
963 //
964  ssl = SSL_new(pImpl->ctx);
965 
966 // OK, now we can drop all the locks and get rid of the old context
967 //
968  pImpl->crlMutex.UnLock();
969  delete ctxold;
970  return ssl;
971 
972 #else
973 // If we did not compile crl refresh code, we can simply return the OpenSSL
974 // session using our context. Otherwise, we need to see if we have a refreshed
975 // context and if so, carry forward the X509_store to our original context.
976 //
977  return SSL_new(pImpl->ctx);
978 #endif
979 }
980 
981 /******************************************************************************/
982 /* S e s s i o n C a c h e */
983 /******************************************************************************/
984 
985 int XrdTlsContext::SessionCache(int opts, const char *id, int idlen)
986 {
987  static const int doSet = scSrvr | scClnt | scOff;
988  long sslopt = 0;
989  int flushT = opts & scFMax;
990 
991  pImpl->sessionCacheOpts = opts;
992  pImpl->sessionCacheId = id;
993 
994 // If initialization failed there is nothing to do
995 //
996  if (pImpl->ctx == 0) return 0;
997 
998 // Set options as appropriate
999 //
1000  if (opts & doSet)
1001  {if (opts & scOff) sslopt = SSL_SESS_CACHE_OFF;
1002  else {if (opts & scSrvr) sslopt = SSL_SESS_CACHE_SERVER;
1003  if (opts & scClnt) sslopt |= SSL_SESS_CACHE_CLIENT;
1004  }
1005  }
1006 
1007 // Check if we should set any cache options or simply get them
1008 //
1009  if (!(opts & doSet)) sslopt = SSL_CTX_get_session_cache_mode(pImpl->ctx);
1010  else {sslopt = SSL_CTX_set_session_cache_mode(pImpl->ctx, sslopt);
1011  if (opts & scOff) SSL_CTX_set_options(pImpl->ctx, SSL_OP_NO_TICKET);
1012  }
1013 
1014 // Compute what he previous cache options were
1015 //
1016  opts = scNone;
1017  if (sslopt & SSL_SESS_CACHE_SERVER) opts |= scSrvr;
1018  if (sslopt & SSL_SESS_CACHE_CLIENT) opts |= scClnt;
1019  if (!opts) opts = scOff;
1020  if (sslopt & SSL_SESS_CACHE_NO_AUTO_CLEAR) opts |= scKeep;
1021  opts |= (static_cast<int>(pImpl->flushT) & scFMax);
1022 
1023 // Set the id is so wanted
1024 //
1025  if (id && idlen > 0)
1026  {if (!SSL_CTX_set_session_id_context(pImpl->ctx,
1027  (unsigned const char *)id,
1028  (unsigned int)idlen)) opts |= scIdErr;
1029  }
1030 
1031 // If a flush interval was specified and it is different from what we have
1032 // then reset the flush interval.
1033 //
1034  if (flushT && flushT != pImpl->flushT)
1035  XrdTlsFlush::Setup_Flusher(pImpl, flushT);
1036 
1037 // All done
1038 //
1039  return opts;
1040 }
1041 
1042 /******************************************************************************/
1043 /* S e t C o n t e x t C i p h e r s */
1044 /******************************************************************************/
1045 
1046 bool XrdTlsContext::SetContextCiphers(const char *ciphers)
1047 {
1048  if (pImpl->ctx && SSL_CTX_set_cipher_list(pImpl->ctx, ciphers)) return true;
1049 
1050  char eBuff[2048];
1051  snprintf(eBuff,sizeof(eBuff),"Unable to set context ciphers '%s'",ciphers);
1052  Fatal(0, eBuff, true);
1053  return false;
1054 }
1055 
1056 /******************************************************************************/
1057 /* S e t D e f a u l t C i p h e r s */
1058 /******************************************************************************/
1059 
1060 void XrdTlsContext::SetDefaultCiphers(const char *ciphers)
1061 {
1062  sslCiphers = ciphers;
1063 }
1064 
1065 /******************************************************************************/
1066 /* S e t C r l R e f r e s h */
1067 /******************************************************************************/
1068 
1070 {
1071 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1072 
1073  pthread_t tid;
1074  int rc;
1075 
1076 // If it's negative or equal to 0, use the current setting
1077 //
1078  if (refsec <= 0)
1079  {pImpl->crlMutex.WriteLock();
1080  refsec = pImpl->Parm.crlRT;
1081  pImpl->crlMutex.UnLock();
1082  if (!refsec) refsec = XrdTlsContext::DEFAULT_CRL_REF_INT_SEC;
1083  }
1084 
1085 // Make sure this is at least 60 seconds between refreshes
1086 //
1087 // if (refsec < 60) refsec = 60;
1088 
1089 // We will set the new interval and start a refresh thread if not running.
1090 //
1091  pImpl->crlMutex.WriteLock();
1092  pImpl->Parm.crlRT = refsec;
1093  if (!pImpl->crlRunning)
1094  {if ((rc = XrdSysThread::Run(&tid, XrdTlsCrl::Refresh, (void *)pImpl,
1095  0, "CRL Refresh")))
1096  {char eBuff[512];
1097  snprintf(eBuff, sizeof(eBuff),
1098  "Unable to start CRL refresh thread; rc=%d", rc);
1099  XrdTls::Emsg("CrlRefresh:", eBuff, false);
1100  pImpl->crlMutex.UnLock();
1101  return false;
1102  } else pImpl->crlRunning = true;
1103  pImpl->crlMutex.UnLock();
1104  }
1105 
1106 // All done
1107 //
1108  return true;
1109 
1110 #else
1111 // We use features present on OpenSSL 1.02 and above to implement crl refresh.
1112 // Older version are too difficult to deal with. Issue a message if this
1113 // feature is being enabled on an old version.
1114 //
1115  XrdTls::Emsg("CrlRefresh:", "Refreshing CRLs only supported in "
1116  "OpenSSL version >= 1.02; CRL refresh disabled!", false);
1117  return false;
1118 #endif
1119 }
1120 
1121 /******************************************************************************/
1122 /* x 5 0 9 V e r i f y */
1123 /******************************************************************************/
1124 
1126 {
1127  return !(pImpl->Parm.cadir.empty()) || !(pImpl->Parm.cafile.empty());
1128 }
1129 
1131  const std::string certPath = pImpl->Parm.cert;
1132  if(certPath.empty()) {
1133  //No certificate provided, should not happen though
1134  return false;
1135  }
1136  time_t modificationTime;
1137  if(!XrdOucUtils::getModificationTime(certPath.c_str(),modificationTime)){
1138  if (pImpl->lastCertModTime != modificationTime) {
1139  //The certificate file has changed
1140  pImpl->lastCertModTime = modificationTime;
1141  return true;
1142  }
1143  }
1144  return false;
1145 }
1146 
1148 
1149  bool LogVF = (pImpl->opts & logVF) != 0;
1150  switch (setting) {
1151  case kOn:
1152  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_PEER, (LogVF ? VerCB : 0));
1153  break;
1154  case kOff:
1155  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_NONE, 0);
1156  break;
1157  default:
1158  return false;
1159  }
1160  return true;
1161 }
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
struct stat Stat
Definition: XrdCks.cc:49
void Fatal(const char *op, const char *target)
Definition: XrdCrc32c.cc:58
int stat(const char *path, struct stat *buf)
#define eMsg(x)
struct myOpts opts
int emsg(int rc, char *msg)
#define FATAL_SSL(msg)
#define FATAL(msg)
#define DBG_CTX(y)
Definition: XrdTlsTrace.hh:39
#define TRACING(x)
Definition: XrdTrace.hh:70
static int getModificationTime(const char *path, time_t &modificationTime)
static const char * ValPath(const char *path, mode_t allow, bool isdir)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static pthread_t ID(void)
static void Snooze(int seconds)
Definition: XrdSysTimer.cc:168
static const int scIdErr
Info: Id not set, is too long.
XrdTlsContext * Clone(bool full=true, bool startCRLRefresh=false)
~XrdTlsContext()
Destructor.
static const uint64_t vdept
Mask to isolate vdept.
static const int crlRS
Bits to shift vdept.
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
static void SetDefaultCiphers(const char *ciphers)
XrdTlsContext(const char *cert=0, const char *key=0, const char *cadir=0, const char *cafile=0, uint64_t opts=0, std::string *eMsg=0)
static const int scClnt
Turn on cache client mode.
static const int DEFAULT_CRL_REF_INT_SEC
Default CRL refresh interval in seconds.
static const uint64_t servr
This is a server context.
static const uint64_t rfCRL
Turn on the CRL refresh thread.
static const int scKeep
Info: TLS-controlled flush disabled.
static const uint64_t nopxy
Do not allow proxy certs.
bool SetTlsClientAuth(ClientAuthSetting setting)
static const int scNone
Do not change any option settings.
static const uint64_t logVF
Log verify failures.
static const uint64_t crlFC
Full crl chain checking.
static const uint64_t crlON
Enables crl checking.
static const uint64_t artON
Auto retry Handshake.
void * Session()
void * Context()
static const int vdepS
Bits to shift vdept.
const CTX_Params * GetParams()
static const int scOff
Turn off cache.
static const char * Init()
bool newHostCertificateDetected()
bool SetContextCiphers(const char *ciphers)
static const int scFMax
bool SetCrlRefresh(int refsec=-1)
static const int scSrvr
Turn on cache server mode (default)
static const uint64_t crlRF
Mask to isolate crl refresh in min.
static const int dbgSIO
Turn debugging in for socket I/O.
Definition: XrdTls.hh:102
static const int dbgSOK
Turn debugging in for socket operations.
Definition: XrdTls.hh:101
static const int dbgOUT
Force msgs to stderr for easier client debug.
Definition: XrdTls.hh:104
static void Emsg(const char *tid, const char *msg=0, bool flush=true)
Definition: XrdTls.cc:104
static const int dbgALL
Turn debugging for everything.
Definition: XrdTls.hh:103
static const int dbgCTX
Turn debugging in for context operations.
Definition: XrdTls.hh:100
static void SetDebug(int opts, XrdSysLogger *logP=0)
Definition: XrdTls.cc:177
bool InitTLS()
Definition: XrdClTls.cc:96
void * Refresh(void *parg)
void * Flusher(void *parg)
bool Setup_Flusher(XrdTlsContextImpl *pImpl, int flushT)
XrdSysTrace SysTrace("TLS", 0)
XrdTlsContextImpl(XrdTlsContext *p)
std::string sessionCacheId
XrdTlsContext * owner
XrdTlsContext::CTX_Params Parm
XrdTlsContext * ctxnew
XrdSysCondVar * flsCVar
XrdSysRWLock crlMutex
std::string cafile
-> ca cert file.
uint64_t opts
Options as passed to the constructor.
std::string cadir
-> ca cert directory.
int crlRT
crl refresh interval time in seconds
std::string pkey
-> private key path.
std::string cert
-> certificate path.