XRootD
Loading...
Searching...
No Matches
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 335 of file XrdTlsTempCA.cc.

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

References XrdSysThread::Run().

Here is the call graph for this function:

◆ ~XrdTlsTempCA()

XrdTlsTempCA::~XrdTlsTempCA ( )

Definition at line 368 of file XrdTlsTempCA.cc.

369{
370 char indicator[1];
371 if (m_maintenance_pipe_w >= 0) {
372 indicator[0] = '1';
373 int rval;
374 do {rval = write(m_maintenance_pipe_w, indicator, 1);} while (rval != -1 || errno == EINTR);
375 if (m_maintenance_thread_pipe_r >= 0) {
376 do {rval = read(m_maintenance_thread_pipe_r, indicator, 1);} while (rval != -1 || errno == EINTR);
377 close(m_maintenance_thread_pipe_r);
378 close(m_maintenance_thread_pipe_w);
379 }
380 close(m_maintenance_pipe_r);
381 close(m_maintenance_pipe_w);
382 }
383}
#define close(a)
Definition XrdPosix.hh:48
#define write(a, b, c)
Definition XrdPosix.hh:121
#define read(a, b, c)
Definition XrdPosix.hh:86

References close, read, and write.

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: