XRootD
Loading...
Searching...
No Matches
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.
 
 XrdTlsContext (XrdTlsContext &&ctx)=delete
 
 ~XrdTlsContext ()
 Destructor.
 
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.
 
static const uint64_t clcOF = 0x0000010000000000
 Disable client certificate request.
 
static const uint64_t crlAM = 0x0000001000000000
 Allow CA validation when CRL is missing (CRL soft-fail)
 
static const uint64_t crlFC = 0x000000C000000000
 Full crl chain checking.
 
static const uint64_t crlON = 0x0000008000000000
 Enables crl checking.
 
static const uint64_t crlRF = 0x00000000ffff0000
 Mask to isolate crl refresh in min.
 
static const int crlRS = 16
 Bits to shift vdept.
 
static int ctxIndex = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL)
 
static const int DEFAULT_CRL_REF_INT_SEC = 8 * 60 * 60
 Default CRL refresh interval in seconds.
 
static const uint64_t dnsok = 0x0000000200000000
 Trust DNS for host name.
 
static const uint64_t hsto = 0x00000000000000ff
 Mask to isolate the hsto.
 
static const uint64_t logVF = 0x0000000800000000
 Log verify failures.
 
static const uint64_t nopxy = 0x0000000100000000
 Do not allow proxy certs.
 
static const uint64_t rfCRL = 0x0000004000000000
 Turn on the CRL refresh thread.
 
static const int scClnt = 0x00040000
 Turn on cache client mode.
 
static const int scFMax = 0x00007fff
 
static const int scIdErr = 0x80000000
 Info: Id not set, is too long.
 
static const int scKeep = 0x40000000
 Info: TLS-controlled flush disabled.
 
static const int scNone = 0x00000000
 Do not change any option settings.
 
static const int scOff = 0x00010000
 Turn off cache.
 
static const int scSrvr = 0x00020000
 Turn on cache server mode (default)
 
static const uint64_t servr = 0x0000000400000000
 This is a server context.
 
static const int vdepS = 8
 Bits to shift vdept.
 
static const uint64_t vdept = 0x000000000000ff00
 Mask to isolate vdept.
 

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 671 of file XrdTlsContext.cc.

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

References artON, clcOF, crlAM, crlFC, crlON, crlRF, crlRS, ctxIndex, XrdTls::dbgALL, XrdTls::dbgCTX, XrdTls::dbgOUT, XrdTls::dbgSIO, XrdTls::dbgSOK, eMsg, emsg(), FATAL, FATAL_SSL, XrdOucUtils::getModificationTime(), Init(), logVF, nopxy, opts, rfCRL, servr, SetCrlRefresh(), XrdTls::SetDebug(), Stat, stat, vdepS, and vdept.

Referenced by XrdTlsContext(), XrdTlsContext(), Clone(), operator=(), operator=(), and Session().

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

◆ ~XrdTlsContext()

XrdTlsContext::~XrdTlsContext ( )

Destructor.

Definition at line 964 of file XrdTlsContext.cc.

965{
966// We can delet eour implementation of there is no refresh thread running. If
967// there is then the refresh thread has to delete the implementation.
968//
969 if (pImpl->crlRunning | pImpl->flsRunning)
970 {pImpl->crlMutex.WriteLock();
971 pImpl->owner = 0;
972 pImpl->crlMutex.UnLock();
973 } else delete pImpl;
974}

◆ XrdTlsContext() [2/3]

XrdTlsContext::XrdTlsContext ( const XrdTlsContext & ctx)
delete

Disallow any copies of this object.

References XrdTlsContext().

+ Here is the call graph for this function:

◆ XrdTlsContext() [3/3]

XrdTlsContext::XrdTlsContext ( XrdTlsContext && ctx)
delete

References XrdTlsContext().

+ Here is the call graph for this function:

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 980 of file XrdTlsContext.cc.

981{
982 XrdTlsContext::CTX_Params &my = pImpl->Parm;
983 const char *cert = (my.cert.size() ? my.cert.c_str() : 0);
984 const char *pkey = (my.pkey.size() ? my.pkey.c_str() : 0);
985 const char *caD = (my.cadir.size() ? my.cadir.c_str() : 0);
986 const char *caF = (my.cafile.size() ? my.cafile.c_str() : 0);
987
988// If this is a non-full context, get rid of any verification
989//
990 if (!full) caD = caF = 0;
991
992// Cloning simply means getting a object with the old parameters.
993//
994 uint64_t myOpts = my.opts;
995 if(startCRLRefresh){
996 myOpts |= XrdTlsContext::rfCRL;
997 } else {
998 myOpts &= ~XrdTlsContext::rfCRL;
999 }
1000 XrdTlsContext *xtc = new XrdTlsContext(cert, pkey, caD, caF, myOpts);
1001
1002// Verify that the context was built
1003//
1004 if (xtc->isOK()) {
1005 if(pImpl->sessionCacheOpts != -1){
1006 //A SessionCache() call was done for the current context, so apply it for this new cloned context
1007 xtc->SessionCache(pImpl->sessionCacheOpts,pImpl->sessionCacheId.c_str(),pImpl->sessionCacheId.size());
1008 }
1009 return xtc;
1010 }
1011
1012// We failed, cleanup.
1013//
1014 delete xtc;
1015 return 0;
1016}
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 cafile
-> ca cert file.
uint64_t opts
Options as passed to the constructor.
std::string cadir
-> ca cert directory.
std::string pkey
-> private key path.
std::string cert
-> certificate path.

References XrdTlsContext(), XrdTlsContext::CTX_Params::cadir, XrdTlsContext::CTX_Params::cafile, XrdTlsContext::CTX_Params::cert, isOK(), XrdTlsContext::CTX_Params::opts, XrdTlsContext::CTX_Params::pkey, rfCRL, and SessionCache().

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 1022 of file XrdTlsContext.cc.

1023{
1024 return pImpl->ctx;
1025}

◆ GetParams()

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

Definition at line 1031 of file XrdTlsContext.cc.

1032{
1033 return &pImpl->Parm;
1034}

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 1040 of file XrdTlsContext.cc.

1041{
1042
1043// Disallow use if this object unless SSL provides thread-safety!
1044//
1045#ifndef OPENSSL_THREADS
1046 return "Installed OpenSSL lacks the required thread support!";
1047#endif
1048
1049// Initialize the library (one time call)
1050//
1051 InitTLS();
1052 return 0;
1053}
bool InitTLS()
Definition XrdClTls.cc:96

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

+ 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 1059 of file XrdTlsContext.cc.

1060{
1061 return pImpl->ctx != 0;
1062}

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

+ Here is the caller graph for this function:

◆ newHostCertificateDetected()

bool XrdTlsContext::newHostCertificateDetected ( )

Definition at line 1288 of file XrdTlsContext.cc.

1288 {
1289 const std::string certPath = pImpl->Parm.cert;
1290 if(certPath.empty()) {
1291 //No certificate provided, should not happen though
1292 return false;
1293 }
1294 time_t modificationTime;
1295 if(!XrdOucUtils::getModificationTime(certPath.c_str(),modificationTime)){
1296 if (pImpl->lastCertModTime != modificationTime) {
1297 //The certificate file has changed
1298 pImpl->lastCertModTime = modificationTime;
1299 return true;
1300 }
1301 }
1302 return false;
1303}

References XrdOucUtils::getModificationTime().

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

References XrdTlsContext().

+ Here is the call graph for this function:

◆ operator=() [2/2]

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

References XrdTlsContext().

+ Here is the call graph for this function:

◆ 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 1074 of file XrdTlsContext.cc.

1075{
1076 EPNAME("Session");
1077 SSL *ssl;
1078
1079// Check if we have a refreshed context. If so, we need to replace the X509
1080// store in the current context with the new one before we create the session.
1081//
1082 pImpl->crlMutex.ReadLock();
1083 if (!(pImpl->ctxnew))
1084 {ssl = SSL_new(pImpl->ctx);
1085 pImpl->crlMutex.UnLock();
1086 return ssl;
1087 }
1088
1089// Things have changed, so we need to take the long route here. We need to
1090// replace the x509 cache with the current cache. Get a R/W lock now.
1091//
1092 pImpl->crlMutex.UnLock();
1093 pImpl->crlMutex.WriteLock();
1094
1095// If some other thread beat us to the punch, just return what we have.
1096//
1097 if (!(pImpl->ctxnew))
1098 {ssl = SSL_new(pImpl->ctx);
1099 pImpl->crlMutex.UnLock();
1100 return ssl;
1101 }
1102
1103// Do some tracing
1104//
1105 DBG_CTX("Replacing x509 store with new contents.");
1106
1107// Get the new store and set it in our context. Setting the store is black
1108// magic. For OpenSSL < 1.1, Two stores need to be set with the "set1" variant.
1109// Newer version only require SSL_CTX_set1_cert_store() to be used.
1110//
1111 //We have a new context generated by Refresh, so we must use it.
1112 XrdTlsContext * ctxnew = pImpl->ctxnew;
1113
1114 /*X509_STORE *newX509 = SSL_CTX_get_cert_store(ctxnew->pImpl->ctx);
1115 SSL_CTX_set1_verify_cert_store(pImpl->ctx, newX509);
1116 SSL_CTX_set1_chain_cert_store(pImpl->ctx, newX509);*/
1117 //The above two macros actually do not replace the certificate that has
1118 //to be used for that SSL session, so we will create the session with the SSL_CTX * of
1119 //the TlsContext created by Refresh()
1120 //First, free the current SSL_CTX, if it is used by any transfer, it will just decrease
1121 //the reference counter of it. There is therefore no risk of double free...
1122 SSL_CTX_free(pImpl->ctx);
1123 pImpl->ctx = ctxnew->pImpl->ctx;
1124
1125 //Update ex_data to point to this (the surviving owner), not the
1126 //cloned context which is about to be deleted.
1127 SSL_CTX_set_ex_data(pImpl->ctx, ctxIndex, this);
1128
1129 //In the destructor of XrdTlsContextImpl, SSL_CTX_Free() is
1130 //called if ctx is != 0. As this new ctx is used by the session
1131 //we just created, we don't want that to happen. We therefore set it to 0.
1132 //The SSL_free called on the session will cleanup the context for us.
1133 ctxnew->pImpl->ctx = 0;
1134
1135// Save the generated context and clear it's presence
1136//
1137 XrdTlsContext *ctxold = pImpl->ctxnew;
1138 pImpl->ctxnew = 0;
1139
1140// Generate a new session (might as well to keep the lock we have)
1141//
1142 ssl = SSL_new(pImpl->ctx);
1143
1144// OK, now we can drop all the locks and get rid of the old context
1145//
1146 pImpl->crlMutex.UnLock();
1147 delete ctxold;
1148 return ssl;
1149}
#define EPNAME(x)
#define DBG_CTX(y)

References XrdTlsContext(), XrdTlsContextImpl::ctx, ctxIndex, DBG_CTX, and EPNAME.

Referenced by XrdTlsSocket::Init().

+ 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 1155 of file XrdTlsContext.cc.

1156{
1157 static const int doSet = scSrvr | scClnt | scOff;
1158 long sslopt = 0;
1159 int flushT = opts & scFMax;
1160
1161 pImpl->sessionCacheOpts = opts;
1162 pImpl->sessionCacheId = id;
1163
1164// If initialization failed there is nothing to do
1165//
1166 if (pImpl->ctx == 0) return 0;
1167
1168// Set options as appropriate
1169//
1170 if (opts & doSet)
1171 {if (opts & scOff) sslopt = SSL_SESS_CACHE_OFF;
1172 else {if (opts & scSrvr) sslopt = SSL_SESS_CACHE_SERVER;
1173 if (opts & scClnt) sslopt |= SSL_SESS_CACHE_CLIENT;
1174 }
1175 }
1176
1177// Check if we should set any cache options or simply get them
1178//
1179 if (!(opts & doSet)) sslopt = SSL_CTX_get_session_cache_mode(pImpl->ctx);
1180 else {sslopt = SSL_CTX_set_session_cache_mode(pImpl->ctx, sslopt);
1181 if (opts & scOff) SSL_CTX_set_options(pImpl->ctx, SSL_OP_NO_TICKET);
1182 }
1183
1184// Compute what he previous cache options were
1185//
1186 opts = scNone;
1187 if (sslopt & SSL_SESS_CACHE_SERVER) opts |= scSrvr;
1188 if (sslopt & SSL_SESS_CACHE_CLIENT) opts |= scClnt;
1189 if (!opts) opts = scOff;
1190 if (sslopt & SSL_SESS_CACHE_NO_AUTO_CLEAR) opts |= scKeep;
1191 opts |= (static_cast<int>(pImpl->flushT) & scFMax);
1192
1193// Set the id is so wanted
1194//
1195 if (id && idlen > 0)
1196 {if (!SSL_CTX_set_session_id_context(pImpl->ctx,
1197 (unsigned const char *)id,
1198 (unsigned int)idlen)) opts |= scIdErr;
1199 }
1200
1201// If a flush interval was specified and it is different from what we have
1202// then reset the flush interval.
1203//
1204 if (flushT && flushT != pImpl->flushT)
1205 XrdTlsFlush::Setup_Flusher(pImpl, flushT);
1206
1207// All done
1208//
1209 return opts;
1210}
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 opts, scClnt, scFMax, scIdErr, scKeep, scNone, scOff, scSrvr, 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 1216 of file XrdTlsContext.cc.

1217{
1218 if (pImpl->ctx && SSL_CTX_set_cipher_list(pImpl->ctx, ciphers)) return true;
1219
1220 char eBuff[2048];
1221 snprintf(eBuff,sizeof(eBuff),"Unable to set context ciphers '%s'",ciphers);
1222 Fatal(0, eBuff, true);
1223 return false;
1224}
void Fatal(const char *op, const char *target)
Definition XrdCrc32c.cc:58

References 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 1239 of file XrdTlsContext.cc.

1240{
1241 pthread_t tid;
1242 int rc;
1243
1244// If it's negative or equal to 0, use the current setting
1245//
1246 if (refsec <= 0)
1247 {pImpl->crlMutex.WriteLock();
1248 refsec = pImpl->Parm.crlRT;
1249 pImpl->crlMutex.UnLock();
1250 if (!refsec) refsec = XrdTlsContext::DEFAULT_CRL_REF_INT_SEC;
1251 }
1252
1253// Make sure this is at least 60 seconds between refreshes
1254//
1255// if (refsec < 60) refsec = 60;
1256
1257// We will set the new interval and start a refresh thread if not running.
1258//
1259 pImpl->crlMutex.WriteLock();
1260 pImpl->Parm.crlRT = refsec;
1261 if (!pImpl->crlRunning)
1262 {if ((rc = XrdSysThread::Run(&tid, XrdTlsCrl::Refresh, (void *)pImpl,
1263 0, "CRL Refresh")))
1264 {char eBuff[512];
1265 snprintf(eBuff, sizeof(eBuff),
1266 "Unable to start CRL refresh thread; rc=%d", rc);
1267 XrdTls::Emsg("CrlRefresh:", eBuff, false);
1268 pImpl->crlMutex.UnLock();
1269 return false;
1270 } else pImpl->crlRunning = true;
1271 pImpl->crlMutex.UnLock();
1272 }
1273
1274// All done
1275//
1276 return true;
1277}
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 DEFAULT_CRL_REF_INT_SEC, XrdTls::Emsg(), XrdTlsCrl::Refresh(), and XrdSysThread::Run().

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 1230 of file XrdTlsContext.cc.

1231{
1232 sslCiphers = ciphers;
1233}

◆ 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 1305 of file XrdTlsContext.cc.

1305 {
1306 if (setting)
1307 {pImpl->Parm.opts &= ~clcOF;
1308 bool LogVF = (pImpl->Parm.opts & logVF) != 0;
1309 bool crlAllowMissingCA = (pImpl->Parm.opts & crlAM) != 0;
1310
1311 if (LogVF || crlAllowMissingCA)
1312 SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_PEER, verifyPeerCB);
1313 else
1314 SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_PEER, 0);
1315 } else
1316 {pImpl->Parm.opts |= clcOF;
1317 SSL_CTX_set_verify(pImpl->ctx, SSL_VERIFY_NONE, 0);
1318 }
1319}

References clcOF, crlAM, and logVF.

◆ x509Verify()

bool XrdTlsContext::x509Verify ( )

Check if certificates are being verified.

Returns
True if certificates are being verified, false otherwise.

Definition at line 1283 of file XrdTlsContext.cc.

1284{
1285 return !(pImpl->Parm.cadir.empty()) || !(pImpl->Parm.cafile.empty());
1286}

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 257 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ clcOF

const uint64_t XrdTlsContext::clcOF = 0x0000010000000000
static

Disable client certificate request.

Definition at line 258 of file XrdTlsContext.hh.

Referenced by XrdTlsContext(), and SetTlsClientAuth().

◆ crlAM

const uint64_t XrdTlsContext::crlAM = 0x0000001000000000
static

Allow CA validation when CRL is missing (CRL soft-fail)

Definition at line 255 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 256 of file XrdTlsContext.hh.

Referenced by XrdTlsContext().

◆ ctxIndex

int XrdTlsContext::ctxIndex = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL)
static

Definition at line 261 of file XrdTlsContext.hh.

Referenced by XrdTlsContext(), and Session().

◆ 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 XrdTlsContext::CTX_Params::CTX_Params(), and 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: