Esempio n. 1
0
void SSLContextManager::reloadTrustStore(Uint32 contextType)
{
    PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::reloadTrustStore()");

    SSL_CTX* sslContext;
    String trustStore = String::EMPTY;

    if ( contextType == SERVER_CONTEXT && _sslContext )
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Context Type is Server Context.");
        sslContext = _sslContext->_rep->getContext();
        trustStore = _sslContext->getTrustStore();
    }
    else if ( contextType == EXPORT_CONTEXT && _exportSSLContext )
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Context Type is Export Context.");
        sslContext = _exportSSLContext->_rep->getContext();
        trustStore = _exportSSLContext->getTrustStore();
    }
    else
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
          "Could not reload the trust store, SSL Context is not initialized.");

        MessageLoaderParms parms(
         "Pegasus.Common.SSLContextManager.COULD_NOT_RELOAD_TRUSTSTORE_SSL_CONTEXT_NOT_INITIALIZED",
         "Could not reload the trust store, SSL Context is not initialized.");
        PEG_METHOD_EXIT();
        throw SSLException(parms);
    }

    if (trustStore == String::EMPTY)
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Could not reload the trust store, the trust store is not configured.");

        MessageLoaderParms parms(
            "Pegasus.Common.SSLContextManager.TRUST_STORE_NOT_CONFIGURED",
            "Could not reload the trust store, the trust store is not configured.");
        PEG_METHOD_EXIT();
        throw SSLException(parms);
    }

    X509_STORE* newStore = _getNewX509Store(trustStore);

    //
    // acquire write lock to Context object and then overwrite the trust 
    // store cache
    //
    {
        WriteLock contextLock(_sslContextObjectLock);
        SSL_CTX_set_cert_store(sslContext, newStore);
    }
    PEG_METHOD_EXIT();
}
Esempio n. 2
0
void SecureSocketImpl::connectSSL(bool performHandshake)
{
	poco_assert (!_pSSL);
	poco_assert (_pSocket->initialized());
	
	BIO* pBIO = BIO_new(BIO_s_socket());
	if (!pBIO) throw SSLException("Cannot create SSL BIO object");
	BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);

	_pSSL = SSL_new(_pContext->sslContext());
	if (!_pSSL) 
	{
		BIO_free(pBIO);
		throw SSLException("Cannot create SSL object");
	}
	SSL_set_bio(_pSSL, pBIO, pBIO);
	
#if OPENSSL_VERSION_NUMBER >= 0x0908060L && !defined(OPENSSL_NO_TLSEXT)
	if (!_peerHostName.empty())
	{
		SSL_set_tlsext_host_name(_pSSL, _peerHostName.c_str());
	}
#endif

	if (_pSession)
	{
		SSL_set_session(_pSSL, _pSession->sslSession());
	}
	
	try
	{
		if (performHandshake && _pSocket->getBlocking())
		{
			int ret = SSL_connect(_pSSL);
			handleError(ret);
			verifyPeerCertificate();
		}
		else
		{
			SSL_set_connect_state(_pSSL);
			_needHandshake = true;
		}
	}
	catch (...)
	{
		SSL_free(_pSSL);
		_pSSL = 0;
		throw;
	}
}
Esempio n. 3
0
void SSLContextManager::reloadCRLStore()
{
    PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::reloadCRLStore()");

    if (!_sslContext && !_exportSSLContext)
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
        "Could not reload the crl store, SSL Context is not initialized.");

        MessageLoaderParms parms(
         "Pegasus.Common.SSLContextManager.COULD_NOT_RELOAD_CRL_STORE_SSL_CONTEXT_NOT_INITIALIZED",
         "Could not reload the crl store, SSL Context is not initialized.");

        PEG_METHOD_EXIT();
        throw SSLException(parms);
    }

    String crlPath = _sslContext->getCRLPath();

    if (crlPath == String::EMPTY)
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Could not reload the crl store, the crl store is not configured.");

        MessageLoaderParms parms(
            "Pegasus.Common.SSLContextManager.CRL_STORE_NOT_CONFIGURED",
            "Could not reload the crl store, the crl store is not configured.");
        PEG_METHOD_EXIT();
        throw SSLException(parms);
    }

    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "CRL store path is " + crlPath);

    //update the CRL store for both the server and the export server since they share the same CRL store
    X509_STORE* crlStore;
    
    {
        WriteLock contextLock(_sslContextObjectLock);
        if (_sslContext)
        {
            _sslContext->_rep->setCRLStore(_getNewX509Store(crlPath));
        }
        if (_exportSSLContext)
        {
            _exportSSLContext->_rep->setCRLStore(_getNewX509Store(crlPath));
        }
    }

    PEG_METHOD_EXIT();
}
X509Certificate SecureStreamSocketImpl::peerCertificate() const
{
	X509* pCert = _impl.peerCertificate();
	if (pCert)
		return X509Certificate(pCert);
	else
		throw SSLException("No certificate available");
}
Esempio n. 5
0
void Context::createSSLContext()
{
	if (SSLManager::isFIPSEnabled())
	{
		_pSSLContext = SSL_CTX_new(TLSv1_method());
	}
	else
	{
		switch (_usage)
		{
		case CLIENT_USE:
			_pSSLContext = SSL_CTX_new(SSLv23_client_method());
			break;
		case SERVER_USE:
			_pSSLContext = SSL_CTX_new(SSLv23_server_method());
			break;
#if defined(SSL_OP_NO_TLSv1) && !defined(OPENSSL_NO_TLS1)
		case TLSV1_CLIENT_USE:
			_pSSLContext = SSL_CTX_new(TLSv1_client_method());
			break;
		case TLSV1_SERVER_USE:
			_pSSLContext = SSL_CTX_new(TLSv1_server_method());
			break;
#endif
#if defined(SSL_OP_NO_TLSv1_1) && !defined(OPENSSL_NO_TLS1)
/* SSL_OP_NO_TLSv1_1 is defined in ssl.h if the library version supports TLSv1.1.
 * OPENSSL_NO_TLS1 is defined in opensslconf.h or on the compiler command line
 * if TLS1.x was removed at OpenSSL library build time via Configure options.
 */
        case TLSV1_1_CLIENT_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_1_client_method());
            break;
        case TLSV1_1_SERVER_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_1_server_method());
            break;
#endif
#if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1)
        case TLSV1_2_CLIENT_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_2_client_method());
            break;
        case TLSV1_2_SERVER_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_2_server_method());
            break;
#endif
		default:
			throw Poco::InvalidArgumentException("Invalid or unsupported usage");
		}
	}
	if (!_pSSLContext) 
	{
		unsigned long err = ERR_get_error();
		throw SSLException("Cannot create SSL_CTX object", ERR_error_string(err, 0));
	}

	SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback);
	Utility::clearErrorStack();
	SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL);
}
Esempio n. 6
0
void SecureSocketImpl::acceptSSL()
{
	poco_assert (!_pSSL);

	BIO* pBIO = BIO_new(BIO_s_socket());
	if (!pBIO) throw SSLException("Cannot create BIO object");
	BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);

	_pSSL = SSL_new(_pContext->sslContext());
	if (!_pSSL)
	{
		BIO_free(pBIO);
		throw SSLException("Cannot create SSL object");
	}
	SSL_set_bio(_pSSL, pBIO, pBIO);
	SSL_set_accept_state(_pSSL);
	_needHandshake = true;
}
Esempio n. 7
0
int SecureSocketImpl::handleError(int rc)
{
	if (rc > 0) return rc;

	int sslError = SSL_get_error(_pSSL, rc);	
	switch (sslError)
	{
	case SSL_ERROR_ZERO_RETURN:
		return 0;
	case SSL_ERROR_WANT_READ:
		return SecureStreamSocket::ERR_SSL_WANT_READ;
	case SSL_ERROR_WANT_WRITE:
		return SecureStreamSocket::ERR_SSL_WANT_WRITE;
	case SSL_ERROR_WANT_CONNECT: 
	case SSL_ERROR_WANT_ACCEPT:
	case SSL_ERROR_WANT_X509_LOOKUP:
		// these should not occur
		poco_bugcheck();
		return rc;
	default:
		{
			long lastError = ERR_get_error();
			if (lastError == 0)
			{
				if (rc == 0 || rc == -1)
				{
					throw SSLConnectionUnexpectedlyClosedException();
				}
				else
				{
					SecureStreamSocketImpl::error(Poco::format("The BIO reported an error: %d", rc));
				}
			}
			else
			{
				char buffer[256];
				ERR_error_string_n(lastError, buffer, sizeof(buffer));
				std::string msg(buffer);
				throw SSLException(msg);
			}
		}
 		break;
	}
	return rc;
}
Esempio n. 8
0
void SSLManager::initDefaultContext(bool server)
{
	if (server && _ptrDefaultServerContext) return;
	if (!server && _ptrDefaultClientContext) return;

	Poco::Crypto::OpenSSLInitializer openSSLInitializer;
	initEvents(server);
	Poco::Util::AbstractConfiguration& config = appConfig();

#ifdef OPENSSL_FIPS
	bool fipsEnabled = config.getBool(CFG_FIPS_MODE, VAL_FIPS_MODE);
	if (fipsEnabled && !Poco::Crypto::OpenSSLInitializer::isFIPSEnabled())
	{
		Poco::Crypto::OpenSSLInitializer::enableFIPSMode(true);
	}
#endif

	std::string prefix = server ? CFG_SERVER_PREFIX : CFG_CLIENT_PREFIX;

	// mandatory options
	std::string privKeyFile = config.getString(prefix + CFG_PRIV_KEY_FILE, "");
	std::string certFile = config.getString(prefix + CFG_CERTIFICATE_FILE, privKeyFile);
	std::string caLocation = config.getString(prefix + CFG_CA_LOCATION, "");

	if (server && certFile.empty() && privKeyFile.empty())
		throw SSLException("Configuration error: no certificate file has been specified");

	// optional options for which we have defaults defined
	Context::VerificationMode verMode = VAL_VER_MODE;
	if (config.hasProperty(prefix + CFG_VER_MODE))
	{
		// either: none, relaxed, strict, once
		std::string mode = config.getString(prefix + CFG_VER_MODE);
		verMode = Utility::convertVerificationMode(mode);
	}

	int verDepth = config.getInt(prefix + CFG_VER_DEPTH, VAL_VER_DEPTH);
	bool loadDefCA = config.getBool(prefix + CFG_ENABLE_DEFAULT_CA, VAL_ENABLE_DEFAULT_CA);
	std::string cipherList = config.getString(prefix + CFG_CIPHER_LIST, VAL_CIPHER_LIST);
	cipherList = config.getString(prefix + CFG_CYPHER_LIST, cipherList); // for backwards compatibility
	bool requireTLSv1 = config.getBool(prefix + CFG_REQUIRE_TLSV1, false);
	bool requireTLSv1_1 = config.getBool(prefix + CFG_REQUIRE_TLSV1_1, false);
	bool requireTLSv1_2 = config.getBool(prefix + CFG_REQUIRE_TLSV1_2, false);
	Context::Usage usage;

	if (server)
	{
		if (requireTLSv1_2)
			usage = Context::TLSV1_2_SERVER_USE;
		else if (requireTLSv1_1)
			usage = Context::TLSV1_1_SERVER_USE;
		else if (requireTLSv1)
			usage = Context::TLSV1_SERVER_USE;
		else
			usage = Context::SERVER_USE;
		_ptrDefaultServerContext = new Context(usage, privKeyFile, certFile, caLocation, verMode, verDepth, loadDefCA, cipherList);
	}
	else
	{
		if (requireTLSv1_2)
			usage = Context::TLSV1_2_CLIENT_USE;
		else if (requireTLSv1_1)
			usage = Context::TLSV1_1_CLIENT_USE;
		else if (requireTLSv1)
			usage = Context::TLSV1_CLIENT_USE;
		else
			usage = Context::CLIENT_USE;
		_ptrDefaultClientContext = new Context(usage, privKeyFile, certFile, caLocation, verMode, verDepth, loadDefCA, cipherList);
	}


	bool cacheSessions = config.getBool(prefix + CFG_CACHE_SESSIONS, false);
	if (server)
	{
		std::string sessionIdContext = config.getString(prefix + CFG_SESSION_ID_CONTEXT, config.getString("application.name", ""));
		_ptrDefaultServerContext->enableSessionCache(cacheSessions, sessionIdContext);
		if (config.hasProperty(prefix + CFG_SESSION_CACHE_SIZE))
		{
			int cacheSize = config.getInt(prefix + CFG_SESSION_CACHE_SIZE);
			_ptrDefaultServerContext->setSessionCacheSize(cacheSize);
		}
		if (config.hasProperty(prefix + CFG_SESSION_TIMEOUT))
		{
			int timeout = config.getInt(prefix + CFG_SESSION_TIMEOUT);
			_ptrDefaultServerContext->setSessionTimeout(timeout);
		}
	}
	else
	{
		_ptrDefaultClientContext->enableSessionCache(cacheSessions);
	}
	bool extendedVerification = config.getBool(prefix + CFG_EXTENDED_VERIFICATION, false);
	if (server)
		_ptrDefaultServerContext->enableExtendedCertificateVerification(extendedVerification);
	else
		_ptrDefaultClientContext->enableExtendedCertificateVerification(extendedVerification);
}
Esempio n. 9
0
SSLContext* CIMServer::_getSSLContext()
{
    PEG_METHOD_ENTER(TRC_SERVER, "CIMServer::_getSSLContext()");

    static const String PROPERTY_NAME__SSL_CERT_FILEPATH =
        "sslCertificateFilePath";
    static const String PROPERTY_NAME__SSL_KEY_FILEPATH = "sslKeyFilePath";
    static const String PROPERTY_NAME__SSL_TRUST_STORE = "sslTrustStore";
    static const String PROPERTY_NAME__SSL_CRL_STORE = "crlStore";
    static const String PROPERTY_NAME__SSL_CLIENT_VERIFICATION =
        "sslClientVerificationMode";
    static const String PROPERTY_NAME__SSL_AUTO_TRUST_STORE_UPDATE =
        "enableSSLTrustStoreAutoUpdate";
    static const String PROPERTY_NAME__SSL_TRUST_STORE_USERNAME =
        "******";
    static const String PROPERTY_NAME__HTTP_ENABLED =
        "enableHttpConnection";
    static const String PROPERTY_NAME__SSL_CIPHER_SUITE = "sslCipherSuite";
    static const String PROPERTY_NAME__SSL_COMPATIBILITY =
        "sslBackwardCompatibility";

    String verifyClient;
    String trustStore;
    SSLContext* sslContext = 0;

    //
    // Get a config manager instance
    //
    ConfigManager* configManager = ConfigManager::getInstance();

    // Note that if invalid values were set for either sslKeyFilePath,
    // sslCertificateFilePath, crlStore or sslTrustStore, the invalid
    // paths would have been detected in SecurityPropertyOwner and
    // terminated the server startup. This happens regardless of whether
    // or not HTTPS is enabled (not a great design, but that seems to
    // be how other properties are validated as well)
    //
    // Get the sslClientVerificationMode property from the Config
    // Manager.
    //
    verifyClient = configManager->getCurrentValue(
        PROPERTY_NAME__SSL_CLIENT_VERIFICATION);

    //
    // Get the sslTrustStore property from the Config Manager.
    //
    trustStore = configManager->getCurrentValue(
        PROPERTY_NAME__SSL_TRUST_STORE);

    if (trustStore != String::EMPTY)
    {
        trustStore = ConfigManager::getHomedPath(trustStore);
    }

    PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,"Server trust store name: %s",
        (const char*)trustStore.getCString()));

    //
    // Get the sslTrustStoreUserName property from the Config Manager.
    //
    String trustStoreUserName;
    trustStoreUserName = configManager->getCurrentValue(
        PROPERTY_NAME__SSL_TRUST_STORE_USERNAME);

    if (!String::equal(verifyClient, "disabled"))
    {
        //
        // 'required' and 'optional' settings must have a valid truststore
        //
        if (trustStore == String::EMPTY)
        {
            MessageLoaderParms parms(
                "Pegasus.Server.SSLContextManager."
                    "SSL_CLIENT_VERIFICATION_EMPTY_TRUSTSTORE",
                "The \"sslTrustStore\" configuration property must be set "
                    "if \"sslClientVerificationMode\" is 'required' or "
                    "'optional'.");
            PEG_METHOD_EXIT();
            throw SSLException(parms);
        }

#ifdef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
        //
        // ATTN: 'required' setting must have http port enabled.
        // If only https is enabled, and a call to shutdown the
        // cimserver is given, the call will hang and a forced shutdown
        // will ensue. This is because the CIMClient::connectLocal call
        // cannot specify a certificate for authentication against
        // the local server.  This limitation is being investigated.
        // See Bugzilla 2995.
        //
        if (String::equal(verifyClient, "required"))
        {
            if (!ConfigManager::parseBooleanValue(
                configManager->getCurrentValue(
                    PROPERTY_NAME__HTTP_ENABLED)))
            {
                MessageLoaderParms parms(
                    "Pegasus.Server.SSLContextManager."
                        "INVALID_CONF_HTTPS_REQUIRED",
                    "The \"sslClientVerificationMode\" property cannot be "
                        "set to \"required\" if HTTP is disabled, as the "
                        "cimserver will be unable to properly shutdown.  "
                        "The recommended course of action is to change "
                        "the property value to \"optional\".");
                PEG_METHOD_EXIT();
                throw SSLException(parms);
            }
        }
#endif
        //
        // A truststore username must be specified if
        // sslClientVerificationMode is enabled and the truststore is a
        // single CA file.  If the truststore is a directory, then the
        // CertificateProvider should be used to register users with
        // certificates.
        //

        if (trustStore != String::EMPTY)
        {
            if (!FileSystem::exists(trustStore))
            {
                MessageLoaderParms parms(
                    "Pegasus.Server.SSLContextManager."
                        "COULD_NOT_ACCESS_TRUST_STORE",
                    "Could not access the trust store."
                        "Check the permissions of the truststore path \"$0\".",
                        trustStore);
                PEG_METHOD_EXIT();
                throw SSLException(parms);
            }

            if (!FileSystem::isDirectory(trustStore))
            {
                if (trustStoreUserName == String::EMPTY)
                {
                    MessageLoaderParms parms(
                        "Pegasus.Server.SSLContextManager."
                            "SSL_CLIENT_VERIFICATION_EMPTY_USERNAME",
                        "The \"sslTrustStoreUserName\" property must specify a "
                            "valid username if \"sslClientVerificationMode\" "
                            "is 'required' or 'optional' and the truststore is "
                            "a single CA file. To register individual "
                            "certificates to users, you must use a truststore "
                            "directory along with the CertificateProvider.");
                    PEG_METHOD_EXIT();
                    throw SSLException(parms);
                }
            }
        }
    }

#ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
    //
    // Get the crlStore property from the Config Manager.
    //
    String crlStore = configManager->getCurrentValue(
        PROPERTY_NAME__SSL_CRL_STORE);

    if (crlStore != String::EMPTY)
    {
        crlStore = ConfigManager::getHomedPath(crlStore);
    }
#else
    String crlStore;
#endif

    //
    // Get the sslCertificateFilePath property from the Config Manager.
    //
    String certPath;
    certPath = ConfigManager::getHomedPath(
        configManager->getCurrentValue(PROPERTY_NAME__SSL_CERT_FILEPATH));

    //
    // Get the sslKeyFilePath property from the Config Manager.
    //
    String keyPath;
    keyPath = ConfigManager::getHomedPath(
        configManager->getCurrentValue(PROPERTY_NAME__SSL_KEY_FILEPATH));

    String randFile;

#ifdef PEGASUS_SSL_RANDOMFILE
    // NOTE: It is technically not necessary to set up a random file on
    // the server side, but it is easier to use a consistent interface
    // on the client and server than to optimize out the random file on
    // the server side.
    randFile = ConfigManager::getHomedPath(PEGASUS_SSLSERVER_RANDOMFILE);
#endif

    //
    // Get the cipherSuite property from the Config Manager.
    //
    String cipherSuite = configManager->getCurrentValue(
        PROPERTY_NAME__SSL_CIPHER_SUITE);
    PEG_TRACE((TRC_SERVER, Tracer::LEVEL4, "Cipher suite is %s",
        (const char*)cipherSuite.getCString()));

    Boolean sslCompatibility = ConfigManager::parseBooleanValue(
        configManager->getCurrentValue(
        PROPERTY_NAME__SSL_COMPATIBILITY));
    //
    // Create the SSLContext defined by the configuration properties
    //
    if (String::equal(verifyClient, "required"))
    {
        PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL3,
            "SSL Client verification REQUIRED.");

        _sslContextMgr->createSSLContext(
            trustStore, certPath, keyPath, crlStore, false, randFile,
            cipherSuite,sslCompatibility);
    }
    else if (String::equal(verifyClient, "optional"))
    {
        PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL3,
            "SSL Client verification OPTIONAL.");

        _sslContextMgr->createSSLContext(
            trustStore, certPath, keyPath, crlStore, true, randFile,
            cipherSuite,sslCompatibility);
    }
    else if (String::equal(verifyClient, "disabled") ||
             verifyClient == String::EMPTY)
    {
        PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL3,
            "SSL Client verification DISABLED.");

        _sslContextMgr->createSSLContext(
            String::EMPTY, certPath, keyPath, crlStore, false, randFile,
            cipherSuite,sslCompatibility);
    }
    sslContext = _sslContextMgr->getSSLContext();

    try
    {
        sslContext->_validateCertificate();
    }
    catch (SSLException& e)
    {
        Logger::put(
            Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
            e.getMessage());
    }

    PEG_METHOD_EXIT();
    return sslContext;
}
Esempio n. 10
0
PEGASUS_NAMESPACE_BEGIN

//
// Basic SSL socket
//

SSLSocket::SSLSocket(
    SocketHandle socket,
    SSLContext * sslcontext,
    ReadWriteSem * sslContextObjectLock,
    const String& ipAddress)
   :
   _SSLConnection(0),
   _socket(socket),
   _SSLContext(sslcontext),
   _sslContextObjectLock(sslContextObjectLock),
   _ipAddress(ipAddress),
   _certificateVerified(false)
{
    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::SSLSocket()");

    SSL* sslConnection;
    SharedPtr<X509_STORE, FreeX509STOREPtr> tmpCrlStore;

    _sslReadErrno = 0;

    //
    // create the SSLConnection area
    //
    if (!(sslConnection = SSL_new(_SSLContext->_rep->getContext())))
    {
        PEG_METHOD_EXIT();
        MessageLoaderParms parms(
            "Common.TLS.COULD_NOT_GET_SSL_CONNECTION_AREA",
            "Could not get SSL Connection Area.");
        throw SSLException(parms);
    }

    // This try/catch block is necessary so that we can free the SSL Connection
    // Area if any exceptions are thrown.
    try
    {
        //
        // set the verification callback data
        //

        // we are only storing one set of data, so we can just use index 0,
        // this is defined in SSLContext.h
        //int index = SSL_get_ex_new_index(
        //    0, (void*)"pegasus", NULL, NULL, NULL);

        //
        // Create a new callback info for each new connection
        //
#ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
        tmpCrlStore = _SSLContext->_rep->getCRLStore();
#endif
        _SSLCallbackInfo.reset(new SSLCallbackInfo(
            _SSLContext->getSSLCertificateVerifyFunction(),
            tmpCrlStore.get(),
            _ipAddress ));

        if (SSL_set_ex_data(
                sslConnection,
                SSLCallbackInfo::SSL_CALLBACK_INDEX,
                _SSLCallbackInfo.get()))
        {
            PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
                "--->SSL: Set callback info");
        }
        else
        {
            PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
                "--->SSL: Error setting callback info");
        }

        //
        // and connect the active socket with the ssl operation
        //
        if (!(SSL_set_fd(sslConnection, _socket) ))
        {
            PEG_METHOD_EXIT();
            MessageLoaderParms parms(
                "Common.TLS.COULD_NOT_LINK_SOCKET",
                "Could not link socket to SSL Connection.");
            throw SSLException(parms);
        }
    }
    catch (...)
    {
        SSL_free(sslConnection);
        throw;
    }

    _SSLConnection = sslConnection;
    _crlStore = new SharedPtr<X509_STORE, FreeX509STOREPtr>(tmpCrlStore);

    PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: Created SSL socket");

    PEG_METHOD_EXIT();
}
Esempio n. 11
0
X509_STORE* SSLContextManager::_getNewX509Store(const String& storePath)
{
    PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::_getNewX509Store()");

    //
    // reload certificates from the specified store
    //
    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
        "Reloading certificates from the store: " + storePath);

    X509_STORE* newStore = X509_STORE_new(); 

    //
    // Check if there is a CA certificate file or directory specified. 
    // If specified, load the certificates from the specified store path.
    //
    if (FileSystem::isDirectory(storePath))
    {
        X509_LOOKUP* storeLookup = X509_STORE_add_lookup(newStore, 
                                              X509_LOOKUP_hash_dir()); 
        if (storeLookup == NULL)
        {
            X509_STORE_free(newStore);

            PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
                "Could not reload the trust or crl store.");

            MessageLoaderParms parms(
             "Pegasus.Common.SSLContextManager.COULD_NOT_RELOAD_TRUST_OR_CRL_STORE",
             "Could not reload the trust or crl store.");
            PEG_METHOD_EXIT();
            throw SSLException(parms);
        }
        X509_LOOKUP_add_dir(storeLookup, 
            storePath.getCString(), X509_FILETYPE_PEM); 
    }
    else if (FileSystem::exists(storePath))
    {
        X509_LOOKUP* storeLookup = X509_STORE_add_lookup(newStore, 
                                                     X509_LOOKUP_file()); 
        if (storeLookup == NULL)
        {
            X509_STORE_free(newStore);

            PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
                "Could not reload the trust or crl store.");

            MessageLoaderParms parms(
             "Pegasus.Common.SSLContextManager.COULD_NOT_RELOAD_TRUST_OR_CRL_STORE",
             "Could not reload the trust or crl store.");
            PEG_METHOD_EXIT();
            throw SSLException(parms);
        }
        X509_LOOKUP_load_file(storeLookup, 
            storePath.getCString(), X509_FILETYPE_PEM); 
    }
    else
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Could not reload the trust or crl store, configured store not found.");

        MessageLoaderParms parms(
         "Pegasus.Common.SSLContextManager.CONFIGURED_TRUST_OR_CRL_STORE_NOT_FOUND",
         "Could not reload the trust or crl store, configured store not found.");
        PEG_METHOD_EXIT();
        throw SSLException(parms);
    }

    PEG_METHOD_EXIT();
    return newStore;
}