Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Overview

SSL feature was added to FIX Antenna C++ in version 2.13.0.

The following parameters were added for configuring SSL sessions:

  • Engine::SessionExtraParameters::sslContext_  in FIX Antenna C++.
  • com::b2bits::fixantenna::sessionExtraParameters::SSLContext in FIX Antenna .NET.

But FIX Antenna 2.26.0. has updated SSL support, extending the variety of formats accepted and password-protected certificates/keys support.

Now FIX Antenna support certificates in PEM, PFX, and DER formats along with private keys in PEM and DER formats. Password-protected certificates/keys can be used as well. The password is specified within plain text in the engine.properties file.

Starting from version 2.26 SSL interface has been slightly changed:

  • com::b2bits::fixantenna::sessionExtraParameters::SSLContext FIX Antenna .NET object got retired and doesn't exist any more.
  • Engine::SessionExtraParameters::sslContext_ FIX Antenna C++ object has lost configuration routines such as loadCertificateAndPrivateKey() and informational properties such as certFileName_ and privKeyFileName_.
  • New FIX Antenna C++ interface to configure SSL has been introduced System::SSLContextConfigurator (along with accompanying Engine::SSLContextConfiguratorConverter )which is used to pass certificates, keys, and so on to the SSL engine.
  • FIX Antenna C++ Engine::FAProperties::getSSLContextConfiguratorInstance() API static routine has been introduced. This routine returns newly created instance of System::SSLContextConfigurator using built in implementation.

Please refer to the SSL parameters page to see the full list of SSL properties in the engine.properties file. 

SSL Configuration

SSL configuration for Acceptor session

Parameters for SSL Acceptor are configured in the engine.properties file and can't be changed after Engine initialization. They are common for all SSL-enabled acceptors. 

Warning

Since some security issues with SSL v3 and RC4 encryption algorithms have been discovered recently and TLS 1.0, and TLS 1.1 also contain known vulnerabilities, we strongly recommend using TLS 1.2 protocol.

Typical configuration:

Code Block
languageperl
titleengine.properties
######### Engine wide properties #########
# Used for all acceptor sessions and as default values for Initiator sessions. if ListenSSLPort is specified and optional otherwise.
# Mandatory. Set protocols accepted by the engine.
SSLProtocols = TLSv1_2
# Optional. Engine default values used if omitted.
SSLCiphersList = AES+aRSA:AES+aECDH:AES+aECDSA:@STRENGTH
# mandatory. Certificate file to use.
SSLCertificate = mycert.pem
# Optional. Applicable if only certificates is password protected.
SSLCertificatePassword = mycertPassword
# Optionality is correlated with SSLCertificate.
# It means if no SSLCertificate  specified then this property becomes seamless. It becomes optional if private key is already contained inside SSLCertificate file.
# This is possible for PEM and PFX formats but not for DER!
SSLPrivateKey = mycertKey.pem
# Optional if private key is not password protected. Please pay attention to the fact the this password is used for private key stored within certificate file as well.
# So it has meaning even if SSLPrivateKey is empty in this case.
SSLPrivateKeyPassword = mycertKeyPassword
# Optional if no peer certificate validation is required. This is a path to the file containing CA certificates (all in one file on after another, PEM format only!).
# This certificates are used to build accepted certificates list sent to peer as well.
SSLCACertificate = CACerts.pem
# Optional. false by default. Setting this property to true requires SSL engine to validate counter-party's certificate against CAs provided.
# If validation has failed or no certificate was provided by counter-party connection is terminated immediately.
# Set this to true in order to accept only connection verified with certificate.
SSLValidatePeerCertificate = true
 
 
######### ESVR/CTG Acceptor session #########
# Restricts the session to accept connections from SSL listener only.
Session.ESVR/CTG.SSL = true
# All remaining properties are engine wide for the acceptors and can't be specified on per-session basis.
# So they are configured with engine wide properties.

SSL configuration for Initiator session in Antenna C++

To enable SSL in the Initiator session create SSL Client Context in extra parameters before creating the session:

Code Block
languagecpp
titleSSLQuickStart.cpp
FIXApp application;
Engine::SessionExtraParameters params;
params.sslContext_ = System::SSLClientContext();

Engine::Session* pSI =  Engine::FixEngine::singleton()->createSession( &application, "TargetCompID", "SenderCompID",  Engine::FIX44, &params );

For advanced configuration use System::SSLClientContext::loadCertificateAndPrivateKey method to specify certificate, private key paths. Set the last boolean value to true to check if a private key matches the server certificate.

Code Block
languagecpp
titleSSLQuickStart.cpp
System::SSLClientContext sslContext;
sslContext.loadCertificateAndPrivateKey("cert.pem", "cert.pem", true);
params.sslContext_ = sslContext;

SSL configuration for Initiator session in FIX Antenna .NET.

To enable SSL in the Initiator session create the session with the SSLContext parameter.

Code Block
languagec#
titleSSLQuickStart.cs
SessionExtraParameters @params = new SessionExtraParameters();   
 
SessionExtraParameters.SSLContextParameters sslContext = new SessionExtraParameters.SSLContextParameters(); 
@params.SSLContext = sslContext; 
 
Session session = FixEngine.Instance.CreateSession(new SessionId("Sender", "Target", null), FixVersion.FIX50SP2, @params, MessageStorageType.Persistent);

For advanced configuration also specify SSL protocols to use, certificate, and private key paths, and set a boolean value to check if a private key matches the server certificate.

Code Block
languagec#
titleSSLQuickStart.cs
sslContext.SSLProtocolsUsed = SSLProtocols.TLSv1 | SSLProtocols.TLSv1_1 | SSLProtocols.TLSv1_2; 
sslContext.SSLCertificate = "cert.pem"; 
sslContext.SSLPrivateKey = "cert.pem"; 
sslContext.SSLCheckPrivateKey = true;

Ciphers configuration in FIX Antenna C++ based applications

Info
The feature was added to FIX Antenna C++ in version 2.25.1

The allowed ciphers list can be configured with SSLCiphersList in the engine.properties file.

This parameter is optional. The default OpenSSL built-in configuration is used in case of parameter absence.

The list is passed as is to OpenSSL during engine initialization in case of acceptor sessions (acceptor sessions are sharing the same configuration) and during session initialization in case of initiator sessions. See a list of the supported ciphers and the list format is at the official OpenSSL site.

Code Block
languageperl
titleengine.properties
SSLCiphersList = AES+aRSA:AES+aECDH:AES+aECDSA:@STRENGTH

C++ simple example

Code Block
languagecpp
titleServer.cpp
int main(int argc, char **argv)
{
    try {
        Engine::FixEngine::InitParameters params;
        params.propertiesFileName_ = "engine.properties";
 
        // Initializes engine.
        Engine::FixEngine::init( params );

		//FIXApp class derived from Engine::Application
        FIXApp acceptor;
 		Engine::SessionExtraParameters params;
	 
        // Create FIX session instance
        Engine::Session* pSI =  Engine::FixEngine::singleton()->createSession( &acceptor, "SenderCompID", "TargetCompID", Engine::FIX44);

        // Connect session as acceptor
        pSI ->connect();
 
		//wait for data in acceptor
        string cmd;
        while( "exit" != cmd ) {
            cout << "Type 'exit' to exit > ";
            getline( cin, cmd );
        }

        // disconnect and release
        pSI->disconnectNonGracefully();
        pSI->release();
    } catch( const std::exception& ex ) {
        cout << "Error: " << ex.what() << endl;
    } catch ( ... ) {
        cout << "Unknown error." << endl;
    }
    // stop engine
    Engine::FixEngine::destroy();
    return 0;
}
Code Block
languagecpp
titleClent.cpp
int main(int argc, char **argv)
{
    try {
        // Initialize engine.
        Engine::FixEngine::init( "engine.properties" );

		//FIXApp class derived from Engine::Application
        FIXApp initiator;
 
        // Create FIX session instance with SSL.
        Engine::SessionExtraParameters params;
		params.sslContext_ = System::SSLClientContext();
        Engine::Session* pSI =  Engine::FixEngine::singleton()->createSession( &initiator, "TargetCompID", "SenderCompID",  Engine::FIX44, &params );
        // Connect session as initiator to LISTENER_IP address
        pSI->connect( 30, LISTENER_IP, 9107);
 
        // create FIX 4.4 New Order Single using the Flat model
        std::auto_ptr<Engine::FIXMessage> pMessage( Engine::FIXMsgFactory::singleton()->newSkel( Engine::FIX44, "D" ) );
        string clordid;
        Engine::UTCTimestamp::now().toFixString( &clordid );
        pMessage->set( FIXField::ClOrdID, clordid );
        pMessage->set( FIXField::Symbol, "MSFT" );
        pMessage->set( FIXField::Side, '1' ); // Buy
        pMessage->set( FIXField::OrderQty, 400 );
        pMessage->set( FIXField::OrdType, '2' ); // Limit
        pMessage->set( FIXField::Price, Engine::Decimal( 1132, -2 ) );
        pMessage->set( FIXField::TransactTime, Engine::UTCTimestamp::now() );

        // Send order to session initiator
        pSI->put( pMessage.get() );
 
		// Wait message processed.
		System::Thread::sleep(2000);
        // disconnect and release session
        pSI->disconnect();
        pSI->release();
    } catch( const std::exception& ex ) {
        cout << "Error: " << ex.what() << endl;
    } catch ( ... ) {
        cout << "Unknown error." << endl;
    }
    // stop engine
    Engine::FixEngine::destroy();
    return 0;
}

C++ advanced example 

Code Block
languagecpp
titleServer.cpp
collapsetrue
int main(int argc, char **argv)
{
    try {
        Engine::FixEngine::InitParameters params;
        params.propertiesFileName_ = "engine.properties";

		// Setup SSL parameters
        params.properties_[Engine::FIXPropertiesNames::LISTEN_SSL_PORT_PARAM] = "9107";
        params.properties_[Engine::FIXPropertiesNames::LISTEN_SSL_CHECK_PRIVATE_KEY_PARAM] = "true";
        params.properties_[Engine::FIXPropertiesNames::LISTEN_SSL_CERTIFICATE_PARAM] = "cert.pem";
        params.properties_[Engine::FIXPropertiesNames::LISTEN_SSL_PRIVATE_KEY_PARAM] = "cert.pem";
        params.properties_[Engine::FIXPropertiesNames::LISTEN_SSL_PROTOCOLS_PARAM] = "TLSv1, TLSv1_1, TLSv1_2";
 
        // Initializes engine.
        Engine::FixEngine::init( params );

		//FIXApp class derived from Engine::Application
        FIXApp acceptor;
 		Engine::SessionExtraParameters params;

        // Create FIX session instance
        Engine::Session* pSI =  Engine::FixEngine::singleton()->createSession( &acceptor, "SenderCompID", "TargetCompID", Engine::FIX44, &params);

        // Connect session as acceptor
        pSI ->connect();
 
		//wait for data in acceptor
        string cmd;
        while( "exit" != cmd ) {
            cout << "Type 'exit' to exit > ";
            getline( cin, cmd );
        }

        // disconnect and release
        pSI->disconnectNonGracefully();
        pSI->release();
    } catch( const std::exception& ex ) {
        cout << "Error: " << ex.what() << endl;
    } catch ( ... ) {
        cout << "Unknown error." << endl;
    }
    // stop engine
    Engine::FixEngine::destroy();
    return 0;
}
Code Block
languagecpp
titleClent.cpp
collapsetrue
int main(int argc, char **argv)
{
    try {
        // Initialize engine.
        Engine::FixEngine::init( "engine.properties" );

		//FIXApp class derived from Engine::Application
        FIXApp initiator;
 
        // Create FIX session instance with SSL.
        Engine::SessionExtraParameters params;
        System::SSLClientContext sslContext;
        sslContext.loadCertificateAndPrivateKey("cert.pem", "cert.pem", true);
        params.sslContext_ = sslContext;
        Engine::Session* pSI =  Engine::FixEngine::singleton()->createSession( &initiator, "TargetCompID", "SenderCompID",  Engine::FIX44, &params );
        // Connect session as initiator to LISTENER_IP address
        pSI->connect( 30, LISTENER_IP, 9107);
 
        // create FIX 4.4 New Order Single using the Flat model
        std::auto_ptr<Engine::FIXMessage> pMessage( Engine::FIXMsgFactory::singleton()->newSkel( Engine::FIX44, "D" ) );
        string clordid;
        Engine::UTCTimestamp::now().toFixString( &clordid );
        pMessage->set( FIXField::ClOrdID, clordid );
        pMessage->set( FIXField::Symbol, "MSFT" );
        pMessage->set( FIXField::Side, '1' ); // Buy
        pMessage->set( FIXField::OrderQty, 400 );
        pMessage->set( FIXField::OrdType, '2' ); // Limit
        pMessage->set( FIXField::Price, Engine::Decimal( 1132, -2 ) );
        pMessage->set( FIXField::TransactTime, Engine::UTCTimestamp::now() );

        // Send order to session initiator
        pSI->put( pMessage.get() );
 
		// Wait message processed.
		System::Thread::sleep(2000);
        // disconnect and release session
        pSI->disconnect();
        pSI->release();
    } catch( const std::exception& ex ) {
        cout << "Error: " << ex.what() << endl;
    } catch ( ... ) {
        cout << "Unknown error." << endl;
    }
    // stop engine
    Engine::FixEngine::destroy();
    return 0;
}

Also samples ./samples/FIX_QuickStart in FIX Antenna C++ package  or ./samples/SimpleClient FIX Antenna .NET in package show how to create session throught SSL connection.

Info
titlereference

Please read FIX Antenna Quick Start Guide and Installation Guide for information about creating application with FIX Antenna C++.

Migration to version 2.26.0 FIX Antenna C++

The following properties have changed their names or been removed. Please modify the code accordingly if you use them.

  • Engine::FIXPropertiesNames::LISTEN_SSL_PROTOCOLS_PARAM→ Engine::FIXPropertiesNames::SSL_PROTOCOLS_PARAM
  • Engine::FIXPropertiesNames::LISTEN_SSL_CIPHERS_LIST_PARAM→ Engine::FIXPropertiesNames::SSL_CIPHERS_LIST_PARAM
  • Engine::FIXPropertiesNames::LISTEN_SSL_CERTIFICATE_PARAM→ Engine::FIXPropertiesNames::SSL_CERTIFICATE_PARAM
  • Engine::FIXPropertiesNames::LISTEN_SSL_PRIVATE_KEY_PARAM→ Engine::FIXPropertiesNames::SSL_PRIVATE_KEY_PARAM
  • Engine::FIXPropertiesNames::LISTEN_SSL_CA_CERTIFICATE_PARAM→ Engine::FIXPropertiesNames::SSL_CA_CERTIFICATE_PARAM
  • Engine::FIXPropertiesNames::LISTEN_SSL_REQ_CLIENT_CERT_PARAM → Engine::FIXPropertiesNames::SSL_VALIDATE_PEER_CERT_PARAM
  • Engine::FIXPropertiesNames::LISTEN_SSL_CHECK_PRIVATE_KEY_PARAM  has retired no longer defined. Execution flow goes that way as this property is always true.

Acceptor's migration is transparent. Since all acceptors share the same configuration defined globally no changes are required.

Initiator's migration is not complicated. See the sample below.

Code Block
languagecpp
titleBefore
System::SSLClientContext sslContext;
sslContext.loadCertificateAndPrivateKey("cert.pem", "cert.pem", true);
params.sslContext_ = sslContext
Code Block
languagecpp
titleAfter
System::SSLContextConfiguratorPtr pSSLContextConfigurator = Engine::FAProperties::getSSLContextConfiguratorInstance(0, "", "", "cert.pem", "cert.pem", "" ,"", false);
System::SSLClientContext sslContext(Engine::FixEngine::singleton()->getProperties()->getSSLUseProtocols(), pSSLContextConfigurator );
params.sslContext_ = sslContext;

Migration to version 2.26.0 FIX Antenna .NET

Acceptor's migration is transparent. Since all acceptors share the same configuration defined globally no changes are required.

if you want to limit sessions to an SSL socket only set the SessionExtraParameters SSL property to true. See the sample for initiators below. The same flow applies to acceptors as well.

Initiator's migration is not complicated. See the sample below.

Code Block
languagec#
titleBefore
SessionExtraParameters @params = new SessionExtraParameters();   
  
SessionExtraParameters.SSLContextParameters sslContext = new SessionExtraParameters.SSLContextParameters(); 
sslContext.SSLProtocolsUsed = SSLProtocols.TLSv1 | SSLProtocols.TLSv1_1 | SSLProtocols.TLSv1_2; 
sslContext.SSLCertificate = "cert.pem"; 
sslContext.SSLPrivateKey = "cert.pem"; 
sslContext.SSLCheckPrivateKey = true;
@params.SSLContext = sslContext; 
  
Session session = FixEngine.Instance.CreateSession(new SessionId("Sender", "Target", null), FixVersion.FIX50SP2, @params, MessageStorageType.Persistent);
Code Block
languagec#
titleAfter
SessionExtraParameters @params = new SessionExtraParameters();   
 
@params.SSL = true; 
@params.SSLProtocolsUsed = SSLProtocols.TLSv1 | SSLProtocols.TLSv1_1 | SSLProtocols.TLSv1_2; 
@params.SSLCertificate = "cert.pem"; 
@params.SSLPrivateKey = "cert.pem"; 
Session session = FixEngine.Instance.CreateSession(new SessionId("Sender", "Target", null), FixVersion.FIX50SP2, @params, MessageStorageType.Persistent);


Filter by label (Content by label)
showLabelsfalse
max5
spacesEPMBFIXA
showSpacefalse
sortmodified
reversetrue
typepage
cqllabel = "ssl" and type = "page" and space = "EPMBFIXA"
labelsSSL

Page Properties
hiddentrue
Related issues