XRootD
XrdTlsContext Class Reference

#include <XrdTlsContext.hh>

+ Collaboration diagram for XrdTlsContext:

Classes

struct  CTX_Params
 

Public Member Functions

 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)
 
 XrdTlsContext (const XrdTlsContext &ctx)=delete
 Disallow any copies of this object. More...
 
 XrdTlsContext (XrdTlsContext &&ctx)=delete
 
 ~XrdTlsContext ()
 Destructor. More...
 
XrdTlsContextClone (bool full=true, bool startCRLRefresh=false)
 
void * Context ()
 
const CTX_ParamsGetParams ()
 
bool isOK ()
 
bool newHostCertificateDetected ()
 
XrdTlsContextoperator= (const XrdTlsContext &ctx)=delete
 
XrdTlsContextoperator= (XrdTlsContext &&ctx)=delete
 
void * Session ()
 
int SessionCache (int opts=scNone, const char *id=0, int idlen=0)
 
bool SetContextCiphers (const char *ciphers)
 
bool SetCrlRefresh (int refsec=-1)
 
void SetTlsClientAuth (bool setting)
 
bool x509Verify ()
 

Static Public Member Functions

static const char * Init ()
 
static void SetDefaultCiphers (const char *ciphers)
 

Static Public Attributes

static const uint64_t artON = 0x0000002000000000
 Auto retry Handshake. More...
 
static const uint64_t clcOF = 0x0000010000000000
 Disable client certificate request. More...
 
static const uint64_t crlFC = 0x000000C000000000
 Full crl chain checking. More...
 
static const uint64_t crlON = 0x0000008000000000
 Enables crl checking. More...
 
static const uint64_t crlRF = 0x00000000ffff0000
 Mask to isolate crl refresh in min. More...
 
static const int crlRS = 16
 Bits to shift vdept. More...
 
static const int DEFAULT_CRL_REF_INT_SEC = 8 * 60 * 60
 Default CRL refresh interval in seconds. More...
 
static const uint64_t dnsok = 0x0000000200000000
 Trust DNS for host name. More...
 
static const uint64_t hsto = 0x00000000000000ff
 Mask to isolate the hsto. More...
 
static const uint64_t logVF = 0x0000000800000000
 Log verify failures. More...
 
static const uint64_t nopxy = 0x0000000100000000
 Do not allow proxy certs. More...
 
static const uint64_t rfCRL = 0x0000004000000000
 Turn on the CRL refresh thread. More...
 
static const int scClnt = 0x00040000
 Turn on cache client mode. More...
 
static const int scFMax = 0x00007fff
 
static const int scIdErr = 0x80000000
 Info: Id not set, is too long. More...
 
static const int scKeep = 0x40000000
 Info: TLS-controlled flush disabled. More...
 
static const int scNone = 0x00000000
 Do not change any option settings. More...
 
static const int scOff = 0x00010000
 Turn off cache. More...
 
static const int scSrvr = 0x00020000
 Turn on cache server mode (default) More...
 
static const uint64_t servr = 0x0000000400000000
 This is a server context. More...
 
static const int vdepS = 8
 Bits to shift vdept. More...
 
static const uint64_t vdept = 0x000000000000ff00
 Mask to isolate vdept. More...
 

Detailed Description

Definition at line 36 of file XrdTlsContext.hh.

Constructor & Destructor Documentation

◆ XrdTlsContext() [1/3]

XrdTlsContext::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 
)

Definition at line 691 of file XrdTlsContext.cc.

694  : pImpl( new XrdTlsContextImpl(this) )
695 {
696  class ctx_helper
697  {public:
698 
699  void Keep() {ctxLoc = 0;}
700 
701  ctx_helper(SSL_CTX **ctxP) : ctxLoc(ctxP) {}
702  ~ctx_helper() {if (ctxLoc && *ctxLoc)
703  {SSL_CTX_free(*ctxLoc); *ctxLoc = 0;}
704  }
705  private:
706  SSL_CTX **ctxLoc;
707  } ctx_tracker(&pImpl->ctx);
708 
709  static const uint64_t sslOpts = SSL_OP_ALL
710  | SSL_OP_NO_SSLv2
711  | SSL_OP_NO_SSLv3
712  | SSL_OP_NO_COMPRESSION
713 #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
714  | SSL_OP_IGNORE_UNEXPECTED_EOF
715 #endif
716 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
717  | SSL_OP_NO_RENEGOTIATION
718 #endif
719  ;
720 
721  std::string certFN, eText;
722  const char *emsg;
723 
724 // Assume we will fail
725 //
726  pImpl->ctx = 0;
727 
728 // Verify that initialzation has occurred. This is not heavy weight as
729 // there will usually be no more than two instances of this object.
730 //
731  if (!initDbgDone)
732  {XrdSysMutexHelper dbgHelper(dbgMutex);
733  if (!initDbgDone)
734  {const char *dbg;
735  if (!(opts & servr) && (dbg = getenv("XRDTLS_DEBUG")))
736  {int dbgOpts = 0;
737  if (strstr(dbg, "ctx")) dbgOpts |= XrdTls::dbgCTX;
738  if (strstr(dbg, "sok")) dbgOpts |= XrdTls::dbgSOK;
739  if (strstr(dbg, "sio")) dbgOpts |= XrdTls::dbgSIO;
740  if (!dbgOpts) dbgOpts = XrdTls::dbgALL;
742  }
743  if ((emsg = Init())) FATAL(emsg);
744  initDbgDone = true;
745  }
746  }
747 
748 // If no CA cert information is specified and this is not a server context,
749 // then get the paths from the environment. They must exist as we need to
750 // verify peer certs in order to verify target host names client-side. We
751 // also use this setupt to see if we should use a specific cert and key.
752 //
753  if (!(opts & servr))
754  {if (!caDir && !caFile)
755  {caDir = getenv("X509_CERT_DIR");
756  caFile = getenv("X509_CERT_FILE");
757  if (!caDir && !caFile)
758  FATAL("No CA cert specified; host identity cannot be verified.");
759  }
760  if (!key) key = getenv("X509_USER_KEY");
761  if (!cert) cert = getenv("X509_USER_PROXY");
762  if (!cert)
763  {struct stat Stat;
764  long long int uid = static_cast<long long int>(getuid());
765  certFN = std::string("/tmp/x509up_u") + std::to_string(uid);
766  if (!stat(certFN.c_str(), &Stat)) cert = certFN.c_str();
767  }
768  }
769 
770 // Before we try to use any specified files, make sure they exist, are of
771 // the right type and do not have excessive access privileges.
772 // .a
773  if (!VerPaths(cert, key, caDir, caFile, eText)) FATAL( eText.c_str());
774 
775 // Copy parameters to out parm structure.
776 //
777  if (cert) {
778  pImpl->Parm.cert = cert;
779  //This call should not fail as a stat is already performed in the call of VerPaths() above
781  }
782  if (key) pImpl->Parm.pkey = key;
783  if (caDir) pImpl->Parm.cadir = caDir;
784  if (caFile) pImpl->Parm.cafile = caFile;
785  pImpl->Parm.opts = opts;
786  if (opts & crlRF) {
787  // What we store in crlRF is the time in minutes, convert it back to seconds
788  pImpl->Parm.crlRT = static_cast<int>((opts & crlRF) >> crlRS) * 60;
789  }
790 
791 // Get the correct method to use for TLS and check if successful create a
792 // server context that uses the method.
793 //
794  const SSL_METHOD *meth;
795  emsg = GetTlsMethod(meth);
796  if (emsg) FATAL(emsg);
797 
798  pImpl->ctx = SSL_CTX_new(meth);
799 
800 // Make sure we have a context here
801 //
802  if (pImpl->ctx == 0) FATAL_SSL("Unable to allocate TLS context!");
803 
804 // Always prohibit SSLv2 & SSLv3 as these are not secure.
805 //
806  SSL_CTX_set_options(pImpl->ctx, sslOpts);
807 
808 // Handle session re-negotiation automatically
809 //
810 // SSL_CTX_set_mode(pImpl->ctx, sslMode);
811 
812 // Turn off the session cache as it's useless with peer cert chains
813 //
814  SSL_CTX_set_session_cache_mode(pImpl->ctx, SSL_SESS_CACHE_OFF);
815 
816 // Establish the CA cert locations, if specified. Then set the verification
817 // depth and turn on peer cert validation. For now, we don't set a callback.
818 // In the future we may to grab debugging information.
819 //
820  if ((caDir || caFile) && !(opts & clcOF))
821  {if (!SSL_CTX_load_verify_locations(pImpl->ctx, caFile, caDir))
822  FATAL_SSL("Unable to load the CA cert file or directory.");
823 
824  int vDepth = (opts & vdept) >> vdepS;
825  SSL_CTX_set_verify_depth(pImpl->ctx, (vDepth ? vDepth : 9));
826 
827  bool LogVF = (opts & logVF) != 0;
828  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_PEER, (LogVF ? VerCB : 0));
829 
830  unsigned long xFlags = (opts & nopxy ? 0 : X509_V_FLAG_ALLOW_PROXY_CERTS);
831  if (opts & crlON)
832  {xFlags |= X509_V_FLAG_CRL_CHECK;
833  if (opts & crlFC) xFlags |= X509_V_FLAG_CRL_CHECK_ALL;
834  }
835  if (opts) X509_STORE_set_flags(SSL_CTX_get_cert_store(pImpl->ctx),xFlags);
836  } else {
837  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_NONE, 0);
838  }
839 
840 // Set cipher list
841 //
842  if (!SSL_CTX_set_cipher_list(pImpl->ctx, sslCiphers))
843  FATAL_SSL("Unable to set SSL cipher list; no supported ciphers.");
844 
845 // If we need to enable eliptic-curve support, do so now. Note that for
846 // OpenSSL 1.1.0+ this is automatically done for us.
847 //
848 #if SSL_CTRL_SET_ECDH_AUTO
849  SSL_CTX_set_ecdh_auto(pImpl->ctx, 1);
850 #endif
851 
852 // We normally handle renegotiation during reads and writes or selective
853 // prohibit on a SSL socket basis. The calle may request this be applied
854 // to all SSL's generated from this context. If so, do it here.
855 //
856  if (opts & artON) SSL_CTX_set_mode(pImpl->ctx, SSL_MODE_AUTO_RETRY);
857 
858 // If there is no cert then assume this is a generic context for a client
859 //
860  if (cert == 0)
861  {ctx_tracker.Keep();
862  return;
863  }
864 
865 // We have a cert. If the key is missing then we assume the key is in the
866 // cert file (ssl will complain if it isn't).
867 //
868  if (!key) key = cert;
869 
870 // Load certificate
871 //
872  if (SSL_CTX_use_certificate_chain_file(pImpl->ctx, cert) != 1)
873  FATAL_SSL("Unable to create TLS context; invalid certificate.");
874 
875 // Load the private key
876 //
877  if (key[0] == 'p') {
878  if (!EnsureOpenSSLConfigLoaded())
879  FATAL_SSL("Unable to load OpenSSL configuration; cannot initialize pkcs11.");
880 
881 #ifdef XRDTLS_HAVE_OSSL_STORE
882  // OpenSSL 3.x+: Use OSSL_STORE API with pkcs11-provider in an ISOLATED context
883  // This prevents PKCS11 from affecting other TLS operations (e.g., SciTokens library)
884 
885  OSSL_PROVIDER *defaultProv = nullptr;
886 
887  // Initialize isolated PKCS11 context
888  // This loads the OPENSSL_CONF into an isolated context so PKCS11 doesn't affect
889  // other libraries in the process (like SciTokens)
890  if (!InitIsolatedPKCS11Context(&pImpl->pkcs11LibCtx, &pImpl->pkcs11Provider, &defaultProv)) {
891  FATAL_SSL("Failed to initialize isolated PKCS11 context. Check OPENSSL_CONF and pkcs11-provider installation.");
892  }
893 
894  // Open PKCS11 URI using the isolated context
895  OSSL_STORE_CTX *store_ctx = OSSL_STORE_open_ex(key, pImpl->pkcs11LibCtx, nullptr,
896  nullptr, nullptr, nullptr, nullptr, nullptr);
897  if (!store_ctx) {
898  if (defaultProv) OSSL_PROVIDER_unload(defaultProv);
899  FATAL_SSL("Failed to open PKCS11 URI in isolated context.");
900  }
901 
902  EVP_PKEY *priv_key = nullptr;
903  while (!OSSL_STORE_eof(store_ctx)) {
904  OSSL_STORE_INFO *info = OSSL_STORE_load(store_ctx);
905  if (info) {
906  int type = OSSL_STORE_INFO_get_type(info);
907  if (type == OSSL_STORE_INFO_PKEY) {
908  priv_key = OSSL_STORE_INFO_get1_PKEY(info);
909  OSSL_STORE_INFO_free(info);
910  break;
911  }
912  OSSL_STORE_INFO_free(info);
913  }
914  }
915  OSSL_STORE_close(store_ctx);
916  if (defaultProv) OSSL_PROVIDER_unload(defaultProv);
917 
918  if (!priv_key)
919  FATAL_SSL("Failed to load private key from PKCS11 URI in isolated context.");
920 
921  if (SSL_CTX_use_PrivateKey(pImpl->ctx, priv_key) != 1) {
922  EVP_PKEY_free(priv_key);
923  FATAL_SSL("Failed to have SSL context use private key");
924  }
925  EVP_PKEY_free(priv_key);
926 
927 #elif defined(XRDTLS_HAVE_ENGINE)
928  // OpenSSL 1.1.x (EL8): Use ENGINE API with libp11/engine_pkcs11
929  ENGINE *e = ENGINE_by_id("pkcs11");
930  if (e) {
931  const char* modulePath = getenv("PKCS11_MODULE_PATH");
932  if (modulePath && modulePath[0]) {
933  if (!ENGINE_ctrl_cmd_string(e, "MODULE_PATH", modulePath, 0)) {
934  ENGINE_free(e);
935  FATAL_SSL("Unable to configure pkcs11 engine MODULE_PATH");
936  }
937  }
938  if(!ENGINE_init(e)) {
939  ENGINE_free(e);
940  FATAL_SSL("Unable to initialize pkcs11 engine");
941  }
942  } else {
943  FATAL_SSL("Unable to create pkcs11 engine");
944  }
945  auto priv_key = ENGINE_load_private_key(e, key, nullptr, nullptr);
946 
947  if (!priv_key) {
948  FATAL_SSL("Failed to load private key through engine");
949  }
950  if (SSL_CTX_use_PrivateKey(pImpl->ctx, priv_key) != 1)
951  FATAL_SSL("Failed to have SSL context use private key");
952  EVP_PKEY_free(priv_key);
953 #else
954  FATAL_SSL("PKCS11 support not available.");
955 #endif
956 
957  } else if (SSL_CTX_use_PrivateKey_file(pImpl->ctx, key, SSL_FILETYPE_PEM) != 1 )
958  FATAL_SSL("Unable to create TLS context; invalid private key.");
959 
960 // Make sure the key and certificate file match.
961 //
962  if (SSL_CTX_check_private_key(pImpl->ctx) != 1 )
963  FATAL_SSL("Unable to create TLS context; cert-key mismatch.");
964 
965 // All went well, start the CRL refresh thread and keep the context.
966 //
967  if(opts & rfCRL) {
968  SetCrlRefresh();
969  }
970  ctx_tracker.Keep();
971 }
struct stat Stat
Definition: XrdCks.cc:49
#define stat(a, b)
Definition: XrdPosix.hh:101
struct myOpts opts
int emsg(int rc, char *msg)
#define FATAL_SSL(msg)
#define FATAL(msg)
static int getModificationTime(const char *path, time_t &modificationTime)
static const uint64_t vdept
Mask to isolate vdept.
static const int crlRS
Bits to shift vdept.
static const uint64_t clcOF
Disable client certificate request.
static const uint64_t servr
This is a server context.
static const uint64_t rfCRL
Turn on the CRL refresh thread.
static const uint64_t nopxy
Do not allow proxy certs.
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.
static const int vdepS
Bits to shift vdept.
static const char * Init()
bool SetCrlRefresh(int refsec=-1)
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 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
XrdTlsContext::CTX_Params Parm
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.

References artON, XrdTlsContext::CTX_Params::cadir, XrdTlsContext::CTX_Params::cafile, XrdTlsContext::CTX_Params::cert, clcOF, crlFC, crlON, crlRF, crlRS, XrdTlsContext::CTX_Params::crlRT, XrdTlsContextImpl::ctx, XrdTls::dbgALL, XrdTls::dbgCTX, XrdTls::dbgOUT, XrdTls::dbgSIO, XrdTls::dbgSOK, emsg(), FATAL, FATAL_SSL, XrdOucUtils::getModificationTime(), Init(), XrdTlsContextImpl::lastCertModTime, logVF, nopxy, opts, XrdTlsContext::CTX_Params::opts, XrdTlsContextImpl::Parm, XrdTlsContext::CTX_Params::pkey, rfCRL, servr, SetCrlRefresh(), XrdTls::SetDebug(), Stat, stat, vdepS, and vdept.

Referenced by Clone().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ~XrdTlsContext()

XrdTlsContext::~XrdTlsContext ( )

Destructor.

Definition at line 977 of file XrdTlsContext.cc.

978 {
979 // We can delet eour implementation of there is no refresh thread running. If
980 // there is then the refresh thread has to delete the implementation.
981 //
982  if (pImpl->crlRunning | pImpl->flsRunning)
983  {pImpl->crlMutex.WriteLock();
984  pImpl->owner = 0;
985  pImpl->crlMutex.UnLock();
986  } else delete pImpl;
987 }
XrdTlsContext * owner
XrdSysRWLock crlMutex

References XrdTlsContextImpl::crlMutex, XrdTlsContextImpl::crlRunning, XrdTlsContextImpl::flsRunning, XrdTlsContextImpl::owner, XrdSysRWLock::UnLock(), and XrdSysRWLock::WriteLock().

Referenced by Clone().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdTlsContext() [2/3]

XrdTlsContext::XrdTlsContext ( const XrdTlsContext ctx)
delete

Disallow any copies of this object.

◆ XrdTlsContext() [3/3]

XrdTlsContext::XrdTlsContext ( XrdTlsContext &&  ctx)
delete

Member Function Documentation

◆ Clone()

XrdTlsContext * XrdTlsContext::Clone ( bool  full = true,
bool  startCRLRefresh = false 
)

Clone a new context from this context.

Parameters
fullWhen true the complete context is cloned. When false, a context with no peer verification is cloned.
Returns
Upon success, the pointer to a new XrdTlsContext is returned. Upon failure, a nil pointer is returned.
Note
The cloned context is identical to the one created by the original constructor. Note that while the crl refresh interval is set, the refresh thread needs to be started by calling crlRefresh(). Also, the session cache is set to off with no identifier.

Definition at line 993 of file XrdTlsContext.cc.

994 {
995  XrdTlsContext::CTX_Params &my = pImpl->Parm;
996  const char *cert = (my.cert.size() ? my.cert.c_str() : 0);
997  const char *pkey = (my.pkey.size() ? my.pkey.c_str() : 0);
998  const char *caD = (my.cadir.size() ? my.cadir.c_str() : 0);
999  const char *caF = (my.cafile.size() ? my.cafile.c_str() : 0);
1000 
1001 // If this is a non-full context, get rid of any verification
1002 //
1003  if (!full) caD = caF = 0;
1004 
1005 // Cloning simply means getting a object with the old parameters.
1006 //
1007  uint64_t myOpts = my.opts;
1008  if(startCRLRefresh){
1010  } else {
1012  }
1013  XrdTlsContext *xtc = new XrdTlsContext(cert, pkey, caD, caF, myOpts);
1014 
1015 // Verify that the context was built
1016 //
1017  if (xtc->isOK()) {
1018  if(pImpl->sessionCacheOpts != -1){
1019  //A SessionCache() call was done for the current context, so apply it for this new cloned context
1020  xtc->SessionCache(pImpl->sessionCacheOpts,pImpl->sessionCacheId.c_str(),pImpl->sessionCacheId.size());
1021  }
1022  return xtc;
1023  }
1024 
1025 // We failed, cleanup.
1026 //
1027  delete xtc;
1028  return 0;
1029 }
~XrdTlsContext()
Destructor.
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
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)
std::string sessionCacheId

References XrdTlsContext(), ~XrdTlsContext(), XrdTlsContext::CTX_Params::cadir, XrdTlsContext::CTX_Params::cafile, XrdTlsContext::CTX_Params::cert, isOK(), XrdTlsContext::CTX_Params::opts, XrdTlsContextImpl::Parm, XrdTlsContext::CTX_Params::pkey, rfCRL, SessionCache(), XrdTlsContextImpl::sessionCacheId, and XrdTlsContextImpl::sessionCacheOpts.

Referenced by XrdTlsCrl::Refresh().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Context()

void * XrdTlsContext::Context ( )

Get the underlying context (should not be used).

Returns
Pointer to the underlying context.

Definition at line 1035 of file XrdTlsContext.cc.

1036 {
1037  return pImpl->ctx;
1038 }

References XrdTlsContextImpl::ctx.

◆ GetParams()

const XrdTlsContext::CTX_Params * XrdTlsContext::GetParams ( )

Definition at line 1044 of file XrdTlsContext.cc.

1045 {
1046  return &pImpl->Parm;
1047 }

References XrdTlsContextImpl::Parm.

Referenced by XrdTlsSocket::Init().

+ Here is the caller graph for this function:

◆ Init()

const char * XrdTlsContext::Init ( )
static

Simply initialize the TLS library.

Returns
=0 Library initialized. !0 Library not initialized, return string indicates why.
Note
Init() is implicitly called by the contructor. Use this method to use the TLS libraries without instantiating a context.

Definition at line 1053 of file XrdTlsContext.cc.

1054 {
1055 
1056 // Disallow use if this object unless SSL provides thread-safety!
1057 //
1058 #ifndef OPENSSL_THREADS
1059  return "Installed OpenSSL lacks the required thread support!";
1060 #endif
1061 
1062 // Initialize the library (one time call)
1063 //
1064  InitTLS();
1065  return 0;
1066 }
bool InitTLS()
Definition: XrdClTls.cc:96

References XrdCl::InitTLS().

Referenced by XrdCryptosslFactory::XrdCryptosslFactory(), XrdTlsContext(), and XrdCryptoLite_New_bf32().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isOK()

bool XrdTlsContext::isOK ( )

Determine if this object was correctly built.

Returns
True if this object is usuable and false otherwise.

Definition at line 1072 of file XrdTlsContext.cc.

1073 {
1074  return pImpl->ctx != 0;
1075 }

References XrdTlsContextImpl::ctx.

Referenced by Clone(), and XrdTlsCrl::Refresh().

+ Here is the caller graph for this function:

◆ newHostCertificateDetected()

bool XrdTlsContext::newHostCertificateDetected ( )

Definition at line 1318 of file XrdTlsContext.cc.

1318  {
1319  const std::string certPath = pImpl->Parm.cert;
1320  if(certPath.empty()) {
1321  //No certificate provided, should not happen though
1322  return false;
1323  }
1324  time_t modificationTime;
1325  if(!XrdOucUtils::getModificationTime(certPath.c_str(),modificationTime)){
1326  if (pImpl->lastCertModTime != modificationTime) {
1327  //The certificate file has changed
1328  pImpl->lastCertModTime = modificationTime;
1329  return true;
1330  }
1331  }
1332  return false;
1333 }

References XrdTlsContext::CTX_Params::cert, XrdOucUtils::getModificationTime(), XrdTlsContextImpl::lastCertModTime, and XrdTlsContextImpl::Parm.

Referenced by XrdTlsCrl::Refresh().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ operator=() [1/2]

XrdTlsContext& XrdTlsContext::operator= ( const XrdTlsContext ctx)
delete

◆ operator=() [2/2]

XrdTlsContext& XrdTlsContext::operator= ( XrdTlsContext &&  ctx)
delete

◆ Session()

void * XrdTlsContext::Session ( )

Apply this context to obtain a new SSL session.

Returns
A pointer to a new SSL session if successful and nil otherwise.

Definition at line 1087 of file XrdTlsContext.cc.

1088 {
1089 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1090 
1091  EPNAME("Session");
1092  SSL *ssl;
1093 
1094 // Check if we have a refreshed context. If so, we need to replace the X509
1095 // store in the current context with the new one before we create the session.
1096 //
1097  pImpl->crlMutex.ReadLock();
1098  if (!(pImpl->ctxnew))
1099  {ssl = SSL_new(pImpl->ctx);
1100  pImpl->crlMutex.UnLock();
1101  return ssl;
1102  }
1103 
1104 // Things have changed, so we need to take the long route here. We need to
1105 // replace the x509 cache with the current cache. Get a R/W lock now.
1106 //
1107  pImpl->crlMutex.UnLock();
1108  pImpl->crlMutex.WriteLock();
1109 
1110 // If some other thread beat us to the punch, just return what we have.
1111 //
1112  if (!(pImpl->ctxnew))
1113  {ssl = SSL_new(pImpl->ctx);
1114  pImpl->crlMutex.UnLock();
1115  return ssl;
1116  }
1117 
1118 // Do some tracing
1119 //
1120  DBG_CTX("Replacing x509 store with new contents.");
1121 
1122 // Get the new store and set it in our context. Setting the store is black
1123 // magic. For OpenSSL < 1.1, Two stores need to be set with the "set1" variant.
1124 // Newer version only require SSL_CTX_set1_cert_store() to be used.
1125 //
1126  //We have a new context generated by Refresh, so we must use it.
1127  XrdTlsContext * ctxnew = pImpl->ctxnew;
1128 
1129  /*X509_STORE *newX509 = SSL_CTX_get_cert_store(ctxnew->pImpl->ctx);
1130  SSL_CTX_set1_verify_cert_store(pImpl->ctx, newX509);
1131  SSL_CTX_set1_chain_cert_store(pImpl->ctx, newX509);*/
1132  //The above two macros actually do not replace the certificate that has
1133  //to be used for that SSL session, so we will create the session with the SSL_CTX * of
1134  //the TlsContext created by Refresh()
1135  //First, free the current SSL_CTX, if it is used by any transfer, it will just decrease
1136  //the reference counter of it. There is therefore no risk of double free...
1137  SSL_CTX_free(pImpl->ctx);
1138  pImpl->ctx = ctxnew->pImpl->ctx;
1139  //In the destructor of XrdTlsContextImpl, SSL_CTX_Free() is
1140  //called if ctx is != 0. As this new ctx is used by the session
1141  //we just created, we don't want that to happen. We therefore set it to 0.
1142  //The SSL_free called on the session will cleanup the context for us.
1143  ctxnew->pImpl->ctx = 0;
1144 
1145 // Save the generated context and clear it's presence
1146 //
1147  XrdTlsContext *ctxold = pImpl->ctxnew;
1148  pImpl->ctxnew = 0;
1149 
1150 // Generate a new session (might as well to keep the lock we have)
1151 //
1152  ssl = SSL_new(pImpl->ctx);
1153 
1154 // OK, now we can drop all the locks and get rid of the old context
1155 //
1156  pImpl->crlMutex.UnLock();
1157  delete ctxold;
1158  return ssl;
1159 
1160 #else
1161 // If we did not compile crl refresh code, we can simply return the OpenSSL
1162 // session using our context. Otherwise, we need to see if we have a refreshed
1163 // context and if so, carry forward the X509_store to our original context.
1164 //
1165  return SSL_new(pImpl->ctx);
1166 #endif
1167 }
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define DBG_CTX(y)
Definition: XrdTlsTrace.hh:39
XrdTlsContext * ctxnew

References XrdTlsContextImpl::crlMutex, XrdTlsContextImpl::ctx, XrdTlsContextImpl::ctxnew, DBG_CTX, EPNAME, XrdSysRWLock::ReadLock(), XrdSysRWLock::UnLock(), and XrdSysRWLock::WriteLock().

Referenced by XrdTlsSocket::Init(), and XrdHttpProtocol::Process().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SessionCache()

int XrdTlsContext::SessionCache ( int  opts = scNone,
const char *  id = 0,
int  idlen = 0 
)

Definition at line 1173 of file XrdTlsContext.cc.

1174 {
1175  static const int doSet = scSrvr | scClnt | scOff;
1176  long sslopt = 0;
1177  int flushT = opts & scFMax;
1178 
1179  pImpl->sessionCacheOpts = opts;
1180  pImpl->sessionCacheId = id;
1181 
1182 // If initialization failed there is nothing to do
1183 //
1184  if (pImpl->ctx == 0) return 0;
1185 
1186 // Set options as appropriate
1187 //
1188  if (opts & doSet)
1189  {if (opts & scOff) sslopt = SSL_SESS_CACHE_OFF;
1190  else {if (opts & scSrvr) sslopt = SSL_SESS_CACHE_SERVER;
1191  if (opts & scClnt) sslopt |= SSL_SESS_CACHE_CLIENT;
1192  }
1193  }
1194 
1195 // Check if we should set any cache options or simply get them
1196 //
1197  if (!(opts & doSet)) sslopt = SSL_CTX_get_session_cache_mode(pImpl->ctx);
1198  else {sslopt = SSL_CTX_set_session_cache_mode(pImpl->ctx, sslopt);
1199  if (opts & scOff) SSL_CTX_set_options(pImpl->ctx, SSL_OP_NO_TICKET);
1200  }
1201 
1202 // Compute what he previous cache options were
1203 //
1204  opts = scNone;
1205  if (sslopt & SSL_SESS_CACHE_SERVER) opts |= scSrvr;
1206  if (sslopt & SSL_SESS_CACHE_CLIENT) opts |= scClnt;
1207  if (!opts) opts = scOff;
1208  if (sslopt & SSL_SESS_CACHE_NO_AUTO_CLEAR) opts |= scKeep;
1209  opts |= (static_cast<int>(pImpl->flushT) & scFMax);
1210 
1211 // Set the id is so wanted
1212 //
1213  if (id && idlen > 0)
1214  {if (!SSL_CTX_set_session_id_context(pImpl->ctx,
1215  (unsigned const char *)id,
1216  (unsigned int)idlen)) opts |= scIdErr;
1217  }
1218 
1219 // If a flush interval was specified and it is different from what we have
1220 // then reset the flush interval.
1221 //
1222  if (flushT && flushT != pImpl->flushT)
1223  XrdTlsFlush::Setup_Flusher(pImpl, flushT);
1224 
1225 // All done
1226 //
1227  return opts;
1228 }
static const int scIdErr
Info: Id not set, is too long.
static const int scClnt
Turn on cache client mode.
static const int scKeep
Info: TLS-controlled flush disabled.
static const int scNone
Do not change any option settings.
static const int scOff
Turn off cache.
static const int scFMax
static const int scSrvr
Turn on cache server mode (default)
bool Setup_Flusher(XrdTlsContextImpl *pImpl, int flushT)

References XrdTlsContextImpl::ctx, XrdTlsContextImpl::flushT, opts, scClnt, scFMax, scIdErr, scKeep, scNone, scOff, scSrvr, XrdTlsContextImpl::sessionCacheId, XrdTlsContextImpl::sessionCacheOpts, and XrdTlsFlush::Setup_Flusher().

Referenced by Clone().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SetContextCiphers()

bool XrdTlsContext::SetContextCiphers ( const char *  ciphers)

Set allowed ciphers for this context.

Parameters
ciphersThe colon separated list of allowable ciphers.
Returns
True if at least one cipher can be used; false otherwise. When false is reurned, this context is no longer usable.

Definition at line 1234 of file XrdTlsContext.cc.

1235 {
1236  if (pImpl->ctx && SSL_CTX_set_cipher_list(pImpl->ctx, ciphers)) return true;
1237 
1238  char eBuff[2048];
1239  snprintf(eBuff,sizeof(eBuff),"Unable to set context ciphers '%s'",ciphers);
1240  Fatal(0, eBuff, true);
1241  return false;
1242 }
void Fatal(const char *op, const char *target)
Definition: XrdCrc32c.cc:58

References XrdTlsContextImpl::ctx, and Fatal().

+ Here is the call graph for this function:

◆ SetCrlRefresh()

bool XrdTlsContext::SetCrlRefresh ( int  refsec = -1)

Set CRL refresh time. By default, CRL's are not refreshed.

Parameters
refsec>0: The number of seconds between refreshes. A value less than 60 sets it to 60. =0: Stops automatic refreshing. <0: Starts automatic refreshing with the current setting if it has not already been started.
Returns
True if the CRL refresh thread was started; false otherwise.

Definition at line 1257 of file XrdTlsContext.cc.

1258 {
1259 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1260 
1261  pthread_t tid;
1262  int rc;
1263 
1264 // If it's negative or equal to 0, use the current setting
1265 //
1266  if (refsec <= 0)
1267  {pImpl->crlMutex.WriteLock();
1268  refsec = pImpl->Parm.crlRT;
1269  pImpl->crlMutex.UnLock();
1270  if (!refsec) refsec = XrdTlsContext::DEFAULT_CRL_REF_INT_SEC;
1271  }
1272 
1273 // Make sure this is at least 60 seconds between refreshes
1274 //
1275 // if (refsec < 60) refsec = 60;
1276 
1277 // We will set the new interval and start a refresh thread if not running.
1278 //
1279  pImpl->crlMutex.WriteLock();
1280  pImpl->Parm.crlRT = refsec;
1281  if (!pImpl->crlRunning)
1282  {if ((rc = XrdSysThread::Run(&tid, XrdTlsCrl::Refresh, (void *)pImpl,
1283  0, "CRL Refresh")))
1284  {char eBuff[512];
1285  snprintf(eBuff, sizeof(eBuff),
1286  "Unable to start CRL refresh thread; rc=%d", rc);
1287  XrdTls::Emsg("CrlRefresh:", eBuff, false);
1288  pImpl->crlMutex.UnLock();
1289  return false;
1290  } else pImpl->crlRunning = true;
1291  pImpl->crlMutex.UnLock();
1292  }
1293 
1294 // All done
1295 //
1296  return true;
1297 
1298 #else
1299 // We use features present on OpenSSL 1.02 and above to implement crl refresh.
1300 // Older version are too difficult to deal with. Issue a message if this
1301 // feature is being enabled on an old version.
1302 //
1303  XrdTls::Emsg("CrlRefresh:", "Refreshing CRLs only supported in "
1304  "OpenSSL version >= 1.02; CRL refresh disabled!", false);
1305  return false;
1306 #endif
1307 }
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static const int DEFAULT_CRL_REF_INT_SEC
Default CRL refresh interval in seconds.
static void Emsg(const char *tid, const char *msg=0, bool flush=true)
Definition: XrdTls.cc:104
void * Refresh(void *parg)

References XrdTlsContextImpl::crlMutex, XrdTlsContext::CTX_Params::crlRT, XrdTlsContextImpl::crlRunning, DEFAULT_CRL_REF_INT_SEC, XrdTls::Emsg(), XrdTlsContextImpl::Parm, XrdTlsCrl::Refresh(), XrdSysThread::Run(), XrdSysRWLock::UnLock(), and XrdSysRWLock::WriteLock().

Referenced by XrdTlsContext().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SetDefaultCiphers()

void XrdTlsContext::SetDefaultCiphers ( const char *  ciphers)
static

Set allowed default ciphers.

Parameters
ciphersThe colon separated list of allowable ciphers.

Definition at line 1248 of file XrdTlsContext.cc.

1249 {
1250  sslCiphers = ciphers;
1251 }

◆ SetTlsClientAuth()

void XrdTlsContext::SetTlsClientAuth ( bool  setting)

Indicate how the server should handle TLS client authentication.

Parameters
settingtrue: All clients will be asked to send a TLS client certificate. false: No clients will be asked to send a TLS client certificate.

Note the TLS connection will not fail if the client is asked for a cert but none are provided.

Definition at line 1335 of file XrdTlsContext.cc.

1335  {
1336  bool LogVF = (pImpl->Parm.opts & logVF) != 0;
1337  if (setting)
1338  {pImpl->Parm.opts &= ~clcOF;
1339  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_PEER, (LogVF ? VerCB : 0));
1340  } else
1341  {pImpl->Parm.opts |= clcOF;
1342  SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_NONE, 0);
1343  }
1344 }

References clcOF, XrdTlsContextImpl::ctx, logVF, XrdTlsContext::CTX_Params::opts, and XrdTlsContextImpl::Parm.

◆ x509Verify()

bool XrdTlsContext::x509Verify ( )

Check if certificates are being verified.

Returns
True if certificates are being verified, false otherwise.

Definition at line 1313 of file XrdTlsContext.cc.

1314 {
1315  return !(pImpl->Parm.cadir.empty()) || !(pImpl->Parm.cafile.empty());
1316 }

References XrdTlsContext::CTX_Params::cadir, XrdTlsContext::CTX_Params::cafile, and XrdTlsContextImpl::Parm.

Referenced by XrdTlsSocket::Init(), and XrdTlsCrl::Refresh().

+ Here is the caller graph for this function:

Member Data Documentation

◆ artON

const uint64_t XrdTlsContext::artON = 0x0000002000000000
static

Auto retry Handshake.

Definition at line 256 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ clcOF

const uint64_t XrdTlsContext::clcOF = 0x0000010000000000
static

Disable client certificate request.

Definition at line 257 of file XrdTlsContext.hh.

Referenced by XrdTlsContext(), and SetTlsClientAuth().

◆ crlFC

const uint64_t XrdTlsContext::crlFC = 0x000000C000000000
static

Full crl chain checking.

Definition at line 253 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ crlON

const uint64_t XrdTlsContext::crlON = 0x0000008000000000
static

Enables crl checking.

Definition at line 252 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ crlRF

const uint64_t XrdTlsContext::crlRF = 0x00000000ffff0000
static

Mask to isolate crl refresh in min.

Definition at line 254 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ crlRS

const int XrdTlsContext::crlRS = 16
static

Bits to shift vdept.

Definition at line 255 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ DEFAULT_CRL_REF_INT_SEC

const int XrdTlsContext::DEFAULT_CRL_REF_INT_SEC = 8 * 60 * 60
static

Default CRL refresh interval in seconds.

Definition at line 66 of file XrdTlsContext.hh.

Referenced by SetCrlRefresh().

◆ dnsok

const uint64_t XrdTlsContext::dnsok = 0x0000000200000000
static

Trust DNS for host name.

Definition at line 249 of file XrdTlsContext.hh.

Referenced by XrdTlsSocket::Init().

◆ hsto

const uint64_t XrdTlsContext::hsto = 0x00000000000000ff
static

Mask to isolate the hsto.

Constructor. Note that you should use isOK() to determine if construction was successful. A false return indicates failure.

Parameters
certPointer to the certificate file to be used. If nil, a generic context is created for client use.
keyPointer to the private key flle to be used. It must correspond to the certificate file. If nil, it is assumed that the key is contained in the cert file.
cadirpath to the directory containing the CA certificates.
cafilepath to the file containing the CA certificates.
optsProcessing options (or'd bitwise): artON - Auto retry handshakes (i.e. block on handshake) crlON - Perform crl check on the leaf node crlFC - Apply crl check to full chain crlRF - Initial crl refresh interval in minutes. dnsok - trust DNS when verifying hostname. hsto - the handshake timeout value in seconds. logVF - Turn on verification failure logging. nopxy - Do not allow proxy cert (normally allowed) servr - This is a server-side context and x509 peer certificate validation may be turned off. vdept - The maximum depth of the certificate chain that must be validated (max is 255).
eMsgIf non-zero, the reason for the failure is returned,
Note
a) If neither cadir nor cafile is specified, certificate validation is not performed if and only if the servr option is specified. Otherwise, the cadir value is obtained from the X509_CERT_DIR envar and the cafile value is obtained from the X509_CERT_File envar. If both are nil, context creation fails. b) Additionally for client-side contructions, if cert or key is not specified their locations come from X509_USER_PROXY and X509_USER_KEY. These may be nil in which case a generic context is created with a local key-pair and no certificate. c) You should immediately call isOK() after instantiating this object. A return value of false means that construction failed. d) Failure messages are routed to the message callback function during construction. e) While the crl refresh interval is set you must engage it by calling crlRefresh() so as to avoid unnecessary refresh threads.

Definition at line 244 of file XrdTlsContext.hh.

Referenced by XrdTlsSocket::Init().

◆ logVF

const uint64_t XrdTlsContext::logVF = 0x0000000800000000
static

Log verify failures.

Definition at line 247 of file XrdTlsContext.hh.

Referenced by XrdConfig::XrdConfig(), XrdTlsContext(), and SetTlsClientAuth().

◆ nopxy

const uint64_t XrdTlsContext::nopxy = 0x0000000100000000
static

Do not allow proxy certs.

Definition at line 250 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ rfCRL

const uint64_t XrdTlsContext::rfCRL = 0x0000004000000000
static

Turn on the CRL refresh thread.

Definition at line 251 of file XrdTlsContext.hh.

Referenced by XrdTlsContext(), and Clone().

◆ scClnt

const int XrdTlsContext::scClnt = 0x00040000
static

Turn on cache client mode.

Definition at line 135 of file XrdTlsContext.hh.

Referenced by SessionCache().

◆ scFMax

const int XrdTlsContext::scFMax = 0x00007fff
static

Maximum flush interval in seconds When 0 keeps the current setting

Definition at line 138 of file XrdTlsContext.hh.

Referenced by SessionCache().

◆ scIdErr

const int XrdTlsContext::scIdErr = 0x80000000
static

Info: Id not set, is too long.

Definition at line 137 of file XrdTlsContext.hh.

Referenced by SessionCache().

◆ scKeep

const int XrdTlsContext::scKeep = 0x40000000
static

Info: TLS-controlled flush disabled.

Definition at line 136 of file XrdTlsContext.hh.

Referenced by SessionCache().

◆ scNone

const int XrdTlsContext::scNone = 0x00000000
static

Do not change any option settings.

Get or set session cache parameters for generated sessions.

Parameters
optsOne or more bit or'd options (see below).
idThe identifier to be used (may be nil to keep setting).
idlenThe length of the identifier (may be zero as above).
Returns
The cache settings prior to any changes are returned. When setting the id, the scIdErr may be returned if the name is too long. If the context has been pprroperly initialized, zero is returned. By default, the session cache is disabled as it is impossible to verify a peer certificate chain when a cached session is reused.

Definition at line 132 of file XrdTlsContext.hh.

Referenced by SessionCache().

◆ scOff

const int XrdTlsContext::scOff = 0x00010000
static

Turn off cache.

Definition at line 133 of file XrdTlsContext.hh.

Referenced by SessionCache().

◆ scSrvr

const int XrdTlsContext::scSrvr = 0x00020000
static

Turn on cache server mode (default)

Definition at line 134 of file XrdTlsContext.hh.

Referenced by SessionCache().

◆ servr

const uint64_t XrdTlsContext::servr = 0x0000000400000000
static

This is a server context.

Definition at line 248 of file XrdTlsContext.hh.

Referenced by XrdConfig::XrdConfig(), and XrdTlsContext().

◆ vdepS

const int XrdTlsContext::vdepS = 8
static

Bits to shift vdept.

Definition at line 246 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ vdept

const uint64_t XrdTlsContext::vdept = 0x000000000000ff00
static

Mask to isolate vdept.

Definition at line 245 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().


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