/******************************************************************************/ /* */ /* X r d C r y p t o S s l F a c t o r y . c c */ /* */ /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */ /* Produced by Gerri Ganis for CERN */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ /* ************************************************************************** */ /* */ /* Implementation of the OpenSSL crypto factory */ /* */ /* ************************************************************************** */ #include "XrdCrypto/XrdCryptosslFactory.hh" #include "XrdCrypto/XrdCryptosslAux.hh" #include "XrdCrypto/XrdCryptosslCipher.hh" #include "XrdCrypto/XrdCryptosslMsgDigest.hh" #include "XrdCrypto/XrdCryptosslRSA.hh" #include "XrdCrypto/XrdCryptosslX509.hh" #include "XrdCrypto/XrdCryptosslX509Crl.hh" #include "XrdCrypto/XrdCryptosslX509Req.hh" #include "XrdSys/XrdSysLogger.hh" #include "XrdSys/XrdSysError.hh" #include "XrdSut/XrdSutRndm.hh" #include "XrdCrypto/XrdCryptosslTrace.hh" #include "XrdVersion.hh" #include #include // // For error logging and tracing static XrdSysLogger Logger; static XrdSysError eDest(0,"cryptossl_"); // Mutexes for OpenSSL XrdSysMutex *XrdCryptosslFactory::CryptoMutexPool[SSLFACTORY_MAX_CRYPTO_MUTEX]; /******************************************************************************/ /* T h r e a d - S a f e n e s s F u n c t i o n s */ /******************************************************************************/ #if OPENSSL_VERSION_NUMBER < 0x10100000L #ifdef __solaris__ extern "C" { #endif static unsigned long sslfactory_id_callback(void) { return (unsigned long)XrdSysThread::ID(); } static void sslfactory_lock(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { if (XrdCryptosslFactory::CryptoMutexPool[n]) { XrdCryptosslFactory::CryptoMutexPool[n]->Lock(); } } else { if (XrdCryptosslFactory::CryptoMutexPool[n]) { XrdCryptosslFactory::CryptoMutexPool[n]->UnLock(); } } } #ifdef __solaris__ } #endif #endif //______________________________________________________________________________ XrdCryptosslFactory::XrdCryptosslFactory() : XrdCryptoFactory("ssl",XrdCryptosslFactoryID) { // Constructor: init the needed components of the OpenSSL library EPNAME("sslFactory::XrdCryptosslFactory"); // Init SSL ... SSL_library_init(); // ... and its error strings SSL_load_error_strings(); // Load Ciphers OpenSSL_add_all_ciphers(); // Load Msg Digests OpenSSL_add_all_digests(); if (SSLFACTORY_MAX_CRYPTO_MUTEX < CRYPTO_num_locks() ) { SetTrace(0); TRACE(ALL, "WARNING: do not have enough crypto mutexes as required by crypto_ssl"); TRACE(ALL, " (suggestion: recompile increasing SSLFACTORY_MAX_CRYPTO_MUTEX to "<< CRYPTO_num_locks()<<")"); } else { // This code taken from XrdSecProtocolssl thread-safety for (int i = 0; i < SSLFACTORY_MAX_CRYPTO_MUTEX; i++) { XrdCryptosslFactory::CryptoMutexPool[i] = new XrdSysMutex(); } } #if defined(OPENSSL_THREADS) // Thread support enabled: set callback functions CRYPTO_set_locking_callback(sslfactory_lock); CRYPTO_set_id_callback(sslfactory_id_callback); #else SetTrace(0); TRACE(ALL, "WARNING: OpenSSL lacks thread support: possible thread-safeness problems!"); TRACE(ALL, " (suggestion: recompile enabling thread support)"); #endif // Init Random machinery int klen = 32; char *ktmp = XrdSutRndm::GetBuffer(klen); if (ktmp) { // Feed the random engine RAND_seed(ktmp,klen); delete[] ktmp; } } //______________________________________________________________________________ void XrdCryptosslFactory::SetTrace(kXR_int32 trace) { // Set trace flags according to 'trace' // // Initiate error logging and tracing eDest.logger(&Logger); if (!sslTrace) sslTrace = new XrdOucTrace(&eDest); if (sslTrace) { // Set debug mask sslTrace->What = 0; // Low level only if ((trace & sslTRACE_Notify)) sslTrace->What |= sslTRACE_Notify; // Medium level if ((trace & sslTRACE_Debug)) sslTrace->What |= (sslTRACE_Notify | sslTRACE_Debug); // High level if ((trace & sslTRACE_Dump)) sslTrace->What |= sslTRACE_ALL; } } //______________________________________________________________________________ XrdCryptoKDFunLen_t XrdCryptosslFactory::KDFunLen() { // Return an instance of an implementation of the PBKDF2 fun length. return &XrdCryptosslKDFunLen; } //______________________________________________________________________________ XrdCryptoKDFun_t XrdCryptosslFactory::KDFun() { // Return an instance of an implementation of the PBKDF2 function. return &XrdCryptosslKDFun; } //______________________________________________________________________________ bool XrdCryptosslFactory::SupportedCipher(const char *t) { // Returns true if specified cipher is supported return XrdCryptosslCipher::IsSupported(t); } //______________________________________________________________________________ bool XrdCryptosslFactory::HasPaddingSupport() { // Returns true if cipher padding is supported #if defined(HAVE_DH_PADDED) || defined(HAVE_DH_PADDED_FUNC) return true; #else return false; #endif } //______________________________________________________________________________ XrdCryptoCipher *XrdCryptosslFactory::Cipher(const char *t, int l) { // Return an instance of a ssl implementation of XrdCryptoCipher. XrdCryptoCipher *cip = new XrdCryptosslCipher(t,l); if (cip) { if (cip->IsValid()) return cip; else delete cip; } return (XrdCryptoCipher *)0; } //______________________________________________________________________________ XrdCryptoCipher *XrdCryptosslFactory::Cipher(const char *t, int l, const char *k, int liv, const char *iv) { // Return an instance of a ssl implementation of XrdCryptoCipher. XrdCryptoCipher *cip = new XrdCryptosslCipher(t,l,k,liv,iv); if (cip) { if (cip->IsValid()) return cip; else delete cip; } return (XrdCryptoCipher *)0; } //______________________________________________________________________________ XrdCryptoCipher *XrdCryptosslFactory::Cipher(XrdSutBucket *b) { // Return an instance of a Local implementation of XrdCryptoCipher. XrdCryptoCipher *cip = new XrdCryptosslCipher(b); if (cip) { if (cip->IsValid()) return cip; else delete cip; } return (XrdCryptoCipher *)0; } //______________________________________________________________________________ XrdCryptoCipher *XrdCryptosslFactory::Cipher(bool padded, int b, char *p, int l, const char *t) { // Return an instance of a Ssl implementation of XrdCryptoCipher. XrdCryptoCipher *cip = new XrdCryptosslCipher(padded, b,p,l,t); if (cip) { if (cip->IsValid()) return cip; else delete cip; } return (XrdCryptoCipher *)0; } //______________________________________________________________________________ XrdCryptoCipher *XrdCryptosslFactory::Cipher(int b, char *p, int l, const char *t) { // Return an instance of a Ssl implementation of XrdCryptoCipher. XrdCryptoCipher *cip = new XrdCryptosslCipher(false,b,p,l,t); if (cip) { if (cip->IsValid()) return cip; else delete cip; } return (XrdCryptoCipher *)0; } //______________________________________________________________________________ XrdCryptoCipher *XrdCryptosslFactory::Cipher(const XrdCryptoCipher &c) { // Return an instance of a Ssl implementation of XrdCryptoCipher. XrdCryptoCipher *cip = new XrdCryptosslCipher(*((XrdCryptosslCipher *)&c)); if (cip) { if (cip->IsValid()) return cip; else delete cip; } return (XrdCryptoCipher *)0; } //______________________________________________________________________________ bool XrdCryptosslFactory::SupportedMsgDigest(const char *dgst) { // Returns true if specified digest is supported return XrdCryptosslMsgDigest::IsSupported(dgst); } //______________________________________________________________________________ XrdCryptoMsgDigest *XrdCryptosslFactory::MsgDigest(const char *dgst) { // Return an instance of a ssl implementation of XrdCryptoMsgDigest. XrdCryptoMsgDigest *md = new XrdCryptosslMsgDigest(dgst); if (md) { if (md->IsValid()) return md; else delete md; } return (XrdCryptoMsgDigest *)0; } //______________________________________________________________________________ XrdCryptoRSA *XrdCryptosslFactory::RSA(int bits, int exp) { // Return an instance of a ssl implementation of XrdCryptoRSA. XrdCryptoRSA *rsa = new XrdCryptosslRSA(bits,exp); if (rsa) { if (rsa->IsValid()) return rsa; else delete rsa; } return (XrdCryptoRSA *)0; } //______________________________________________________________________________ XrdCryptoRSA *XrdCryptosslFactory::RSA(const char *pub, int lpub) { // Return an instance of a ssl implementation of XrdCryptoRSA. XrdCryptoRSA *rsa = new XrdCryptosslRSA(pub,lpub); if (rsa) { if (rsa->IsValid()) return rsa; else delete rsa; } return (XrdCryptoRSA *)0; } //______________________________________________________________________________ XrdCryptoRSA *XrdCryptosslFactory::RSA(const XrdCryptoRSA &r) { // Return an instance of a Ssl implementation of XrdCryptoRSA. XrdCryptoRSA *rsa = new XrdCryptosslRSA(*((XrdCryptosslRSA *)&r)); if (rsa) { if (rsa->IsValid()) return rsa; else delete rsa; } return (XrdCryptoRSA *)0; } //______________________________________________________________________________ XrdCryptoX509 *XrdCryptosslFactory::X509(const char *cf, const char *kf) { // Return an instance of a ssl implementation of XrdCryptoX509. XrdCryptoX509 *x509 = new XrdCryptosslX509(cf, kf); if (x509) { if (x509->Opaque()) return x509; else delete x509; } return (XrdCryptoX509 *)0; } //______________________________________________________________________________ XrdCryptoX509 *XrdCryptosslFactory::X509(XrdSutBucket *b) { // Return an instance of a ssl implementation of XrdCryptoX509. XrdCryptoX509 *x509 = new XrdCryptosslX509(b); if (x509) { if (x509->Opaque()) return x509; else delete x509; } return (XrdCryptoX509 *)0; } //______________________________________________________________________________ XrdCryptoX509Crl *XrdCryptosslFactory::X509Crl(const char *cf, int opt) { // Return an instance of a ssl implementation of XrdCryptoX509Crl. XrdCryptoX509Crl *x509Crl = new XrdCryptosslX509Crl(cf, opt); if (x509Crl) { if (x509Crl->Opaque()) return x509Crl; else delete x509Crl; } return (XrdCryptoX509Crl *)0; } //______________________________________________________________________________ XrdCryptoX509Crl *XrdCryptosslFactory::X509Crl(XrdCryptoX509 *ca) { // Return an instance of a ssl implementation of XrdCryptoX509Crl. XrdCryptoX509Crl *x509Crl = new XrdCryptosslX509Crl(ca); if (x509Crl) { if (x509Crl->Opaque()) return x509Crl; else delete x509Crl; } return (XrdCryptoX509Crl *)0; } //______________________________________________________________________________ XrdCryptoX509Req *XrdCryptosslFactory::X509Req(XrdSutBucket *b) { // Return an instance of a ssl implementation of XrdCryptoX509Crl. XrdCryptoX509Req *x509Req = new XrdCryptosslX509Req(b); if (x509Req) { if (x509Req->Opaque()) return x509Req; else delete x509Req; } return (XrdCryptoX509Req *)0; } //______________________________________________________________________________ XrdCryptoX509VerifyCert_t XrdCryptosslFactory::X509VerifyCert() { // Return hook to the OpenSSL implementation of the verification // function for X509 certificate. return &XrdCryptosslX509VerifyCert; } //______________________________________________________________________________ XrdCryptoX509VerifyChain_t XrdCryptosslFactory::X509VerifyChain() { // Return hook to the OpenSSL implementation of the verification // function for X509 certificate chains. return &XrdCryptosslX509VerifyChain; } //______________________________________________________________________________ XrdCryptoX509ExportChain_t XrdCryptosslFactory::X509ExportChain() { // Return an instance of an implementation of a function // to export a X509 certificate chain. return &XrdCryptosslX509ExportChain; } //______________________________________________________________________________ XrdCryptoX509ChainToFile_t XrdCryptosslFactory::X509ChainToFile() { // Return an instance of an implementation of a function // to dump a X509 certificate chain to a file. return &XrdCryptosslX509ChainToFile; } //______________________________________________________________________________ XrdCryptoX509ParseFile_t XrdCryptosslFactory::X509ParseFile() { // Return an instance of an implementation of a function // to parse a file supposed to contain for X509 certificates. return &XrdCryptosslX509ParseFile; } //______________________________________________________________________________ XrdCryptoX509ParseBucket_t XrdCryptosslFactory::X509ParseBucket() { // Return an instance of an implementation of a function // to parse a file supposed to contain for X509 certificates. return &XrdCryptosslX509ParseBucket; } //______________________________________________________________________________ XrdCryptoProxyCertInfo_t XrdCryptosslFactory::ProxyCertInfo() { // Check if the proxyCertInfo extension exists return &XrdCryptosslProxyCertInfo; } //______________________________________________________________________________ XrdCryptoSetPathLenConstraint_t XrdCryptosslFactory::SetPathLenConstraint() { // Set the path length constraint return &XrdCryptosslSetPathLenConstraint; } //______________________________________________________________________________ XrdCryptoX509CreateProxy_t XrdCryptosslFactory::X509CreateProxy() { // Create a proxy certificate return &XrdCryptosslX509CreateProxy; } //______________________________________________________________________________ XrdCryptoX509CreateProxyReq_t XrdCryptosslFactory::X509CreateProxyReq() { // Create a proxy request return &XrdCryptosslX509CreateProxyReq; } //______________________________________________________________________________ XrdCryptoX509SignProxyReq_t XrdCryptosslFactory::X509SignProxyReq() { // Sign a proxy request return &XrdCryptosslX509SignProxyReq; } //______________________________________________________________________________ XrdCryptoX509CheckProxy3_t XrdCryptosslFactory::X509CheckProxy3() { // Check consistency of a GSI 3 compliant proxy return &XrdCryptosslX509CheckProxy3; } //______________________________________________________________________________ XrdCryptoX509GetVOMSAttr_t XrdCryptosslFactory::X509GetVOMSAttr() { // Get VOMS attributes, if any return &XrdCryptosslX509GetVOMSAttr; } /******************************************************************************/ /* X r d C r y p t o S s l F a c t o r y O b j e c t */ /******************************************************************************/ XrdVERSIONINFO(XrdCryptosslFactoryObject,cryptossl); extern "C" { XrdCryptoFactory *XrdCryptosslFactoryObject() { // Return a pointer to the instantiated Ssl factory singleton. // Instantiate the singleton on the first call. static XrdCryptosslFactory SslCryptoFactory; return &SslCryptoFactory; }}