XRootD
XrdTlsTempCA Class Reference

#include <XrdTlsTempCA.hh>

+ Collaboration diagram for XrdTlsTempCA:

Classes

class  TempCAGuard
 

Public Member Functions

 XrdTlsTempCA (XrdSysError *log, std::string ca_dir, bool build_store=true)
 
 ~XrdTlsTempCA ()
 
bool atLeastOneValidCRLFound () const
 
std::string CAFilename () const
 
std::shared_ptr< X509_STORE > CAStore () const
 
std::string CRLFilename () const
 
bool IsValid () const
 

Detailed Description

This class provides manages a "CA file" that is a concatenation of all the CAs in a given CA directory. This is useful in TLS contexts where, instead of loading all CAs for each connection, we only want to load a single file.

This will hand out the CA file directly, allowing external libraries (such as libcurl) do the loading of CAs directly.

Parsing those files is expensive – a grid CA directory costs tens of MB of heap once parsed – so a pre-parsed X509_STORE covering the same CAs and CRLs is maintained alongside them; see CAStore().

Definition at line 51 of file XrdTlsTempCA.hh.

Constructor & Destructor Documentation

◆ XrdTlsTempCA()

XrdTlsTempCA::XrdTlsTempCA ( XrdSysError log,
std::string  ca_dir,
bool  build_store = true 
)

Set build_store when the caller intends to use CAStore(). Maintaining the store costs tens of MB of resident memory, so callers that only need the bundle filenames should leave it off.

Definition at line 336 of file XrdTlsTempCA.cc.

337  : m_log(*err),
338  m_ca_dir(ca_dir),
339  m_build_store(build_store)
340 {
341  // Setup communication pipes; we write one byte to the child to tell it to shutdown;
342  // it'll write one byte back to acknowledge before our destructor exits.
343  int pipes[2];
344  if (-1 == XrdSysFD_Pipe(pipes)) {
345  m_log.Emsg("XrdTlsTempCA", "Failed to create communication pipes", strerror(errno));
346  return;
347  }
348  m_maintenance_pipe_r = pipes[0];
349  m_maintenance_pipe_w = pipes[1];
350  if (-1 == XrdSysFD_Pipe(pipes)) {
351  m_log.Emsg("XrdTlsTempCA", "Failed to create communication pipes", strerror(errno));
352  return;
353  }
354  m_maintenance_thread_pipe_r = pipes[0];
355  m_maintenance_thread_pipe_w = pipes[1];
356  if (!Maintenance()) {return;}
357 
358  pthread_t tid;
359  auto rc = XrdSysThread::Run(&tid, XrdTlsTempCA::MaintenanceThread,
360  static_cast<void*>(this), 0, "CA/CRL refresh");
361  if (rc) {
362  m_log.Emsg("XrdTlsTempCA", "Failed to launch CA monitoring thread");
363  m_ca_file.reset();
364  m_crl_file.reset();
365  }
366 }
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)

References XrdSysError::Emsg(), and XrdSysThread::Run().

+ Here is the call graph for this function:

◆ ~XrdTlsTempCA()

XrdTlsTempCA::~XrdTlsTempCA ( )

Definition at line 369 of file XrdTlsTempCA.cc.

370 {
371  char indicator[1];
372  if (m_maintenance_pipe_w >= 0) {
373  indicator[0] = '1';
374  int rval;
375  do {rval = write(m_maintenance_pipe_w, indicator, 1);} while (rval != -1 || errno == EINTR);
376  if (m_maintenance_thread_pipe_r >= 0) {
377  do {rval = read(m_maintenance_thread_pipe_r, indicator, 1);} while (rval != -1 || errno == EINTR);
378  close(m_maintenance_thread_pipe_r);
379  close(m_maintenance_thread_pipe_w);
380  }
381  close(m_maintenance_pipe_r);
382  close(m_maintenance_pipe_w);
383  }
384 }
ssize_t write(int fildes, const void *buf, size_t nbyte)
ssize_t read(int fildes, void *buf, size_t nbyte)
#define close(a)
Definition: XrdPosix.hh:48

References close, read(), and write().

+ Here is the call graph for this function:

Member Function Documentation

◆ atLeastOneValidCRLFound()

bool XrdTlsTempCA::atLeastOneValidCRLFound ( ) const
inline

Returns true if a valid CRL file has been found during the Maintenance thread execution false otherwise

Definition at line 87 of file XrdTlsTempCA.hh.

87 {XrdSysMutexHelper lock(m_mutex); return m_atLeastOneCRLFound;}

◆ CAFilename()

std::string XrdTlsTempCA::CAFilename ( ) const
inline

Returns the current location of the CA temp file.

Definition at line 76 of file XrdTlsTempCA.hh.

76 {XrdSysMutexHelper lock(m_mutex); return m_ca_file ? *m_ca_file : "";}

◆ CAStore()

std::shared_ptr<X509_STORE> XrdTlsTempCA::CAStore ( ) const
inline

Returns the CA and CRL contents pre-parsed into a single X509_STORE, rebuilt once per maintenance cycle. An X509_STORE is reference counted and internally locked by OpenSSL, so a single instance may be shared across any number of concurrent TLS handshakes – e.g. via SSL_CTX_set1_cert_store() – instead of having every connection parse the CA and CRL bundles for itself.

The returned reference keeps the store alive for as long as the caller holds it, so a maintenance cycle may publish a replacement without disturbing the TLS sessions still using the previous one.

Only ever null before the first successful maintenance run, which IsValid() reports on; a maintenance run that cannot build a store keeps the previous one rather than withdrawing it. Callers should treat a null store as a hard error, not as a cue to load the bundles themselves.

Definition at line 105 of file XrdTlsTempCA.hh.

105 {XrdSysMutexHelper lock(m_mutex); return m_ca_store;}

◆ CRLFilename()

std::string XrdTlsTempCA::CRLFilename ( ) const
inline

Returns the current location of the CA temp file.

Definition at line 81 of file XrdTlsTempCA.hh.

81 {XrdSysMutexHelper lock(m_mutex); return m_crl_file ? *m_crl_file : "";}

◆ IsValid()

bool XrdTlsTempCA::IsValid ( ) const
inline

Returns true if object is valid, i.e. the CA and CRL bundles were generated, and parsed into a store if one was asked for. Failing to build a requested store is fatal rather than recoverable: falling back to having every consumer parse the bundles for itself is what the store exists to avoid.

Definition at line 69 of file XrdTlsTempCA.hh.

69  {XrdSysMutexHelper lock(m_mutex);
70  return m_ca_file.get() && m_crl_file.get()
71  && (!m_build_store || m_ca_store.get());}

The documentation for this class was generated from the following files: