.. include:: ../vars.rst

.. _chapter-openssl-engines:

***************************
Support for OpenSSL Engines
***************************

.. note::

  This chapter does *NOT* apply if you are using |OpenSSL_TM| version 3.0.0 or
  above. For those versions, see
  :ref:`p3_advanced/openssl_providers:Support for OpenSSL Providers`.

|OpenSSL| engines allow you to define custom implementations for cryptographic operations. When you load an engine, |OpenSSL| will call the cryptographic functions defined by the engine instead of its default builtin functions. The |RTI_SP_PRODUCT| support the option of using an |OpenSSL| engine, enabling you to use optimized cryptographic libraries, add support for custom hardware acceleration, etc.

.. note::

  When set, the :property:`openssl_engine` property defines the |OpenSSL|
  engine to be used. If you create a |DP| that sets this property to a non-NULL
  value and there are no other |DPs| using the |RTI_SP_PRODUCT| that are currently running
  in the application, then this value will be the value for all subsequent
  |DPs| in the application. Setting this property to a different value for
  subsequent |DPs| will not be effective and will be silently ignored.


.. admonition:: Disclaimer
  :class: attention

  |CONNEXT| is only tested with the |OpenSSL| builtin engine. Modifying or Configuring |OpenSSL| engines may result in deviations from tested scenarios. Support for custom |OpenSSL| configurations may require a support contract with RTI Professional Services.


Properties for Configuring OpenSSL Engines
==========================================

:numref:`Properties for Configuring OpenSSL Engines` lists the properties that you can set to configure |OpenSSL| engines. These properties are configured through the |DP|'s PROPERTY QosPolicy (see :ref:`section-sp-properties`).

.. list-table:: Properties for Configuring OpenSSL Engines
  :name: Properties for Configuring OpenSSL Engines
  :widths: 40 60
  :header-rows: 1
  :class: longtable

  * - Property Name (prefix with :property:`com.rti.serv.secure.`) [#fPrefix]_
    - Property Value Description

  * - :property:`openssl_engine`
    - :required:`Optional`

      One or more dynamic libraries, each implementing an |OpenSSL| engine.

      If this property value is not set, the |RTI_SP_PRODUCT| will use native |OpenSSL| code
      with its default engine.

      Otherwise, you must set this value to the filename, excluding the
      :file:`lib` prefix and the file extension, of the dynamic libraries that
      implement the engines. These libraries and the dependent libraries must be
      in at least one of the following:

      * Your library search path (pointed to by the environment variable
        ``LD_LIBRARY_PATH`` on Linux systems, ``DYLD_LIBRARY_PATH`` on macOS
        systems, or ``PATH`` on Windows systems).
      * The path pointed to by the environment variable ``OPENSSL_ENGINES``.
      * The standard |OpenSSL| engines directory (only if ``OPENSSL_ENGINES`` is
        not set)

      When specifying multiple libraries, they must be separated by a semicolon
      (e.g., ``engine1;engine2``).

      Failure to load any of the engines will result in failure to create the
      |DP|.

      Each engine may implement a different set of security functions. For
      example, one engine may implement certificate management, while another
      engine may implement cryptographic operations such as encryption, HMAC,
      and Diffie-Hellman. For any security functions needed by the security
      plugins but not implemented by any of the engines, their builtin |OpenSSL|
      implementations will be invoked.

      Note:
        The value of this property for the first |DP| of the application will be
        the value for all other |DPs| in the application. Setting this property
        to a different value for subsequent |DPs| will not be effective and will
        be silently ignored.

      :type:`String`.

      Default: not set, meaning that the |OpenSSL| builtin engine will be used.

  * - :property:`authentication.keyform`
    - :required:`Optional`

      The format of the private key specified by :property:`dds.sec.auth.private_key` (see :numref:`DDS Security Properties for Configuring Authentication`).

      The value of this property can be one of the following:

      * :value:`pem`: The |OpenSSL| engine will use the |PrivateKey| loaded by the |RTI_SP_PRODUCT| with the :property:`dds.sec.auth.private_key` property. In this case, the |PrivateKey| is in PEM format and will be loaded as a file or a string, depending on its :value:`file:` or :value:`data:,` prefix.
      * :value:`engine`: The |OpenSSL| engine will be responsible for loading and/or using the |PrivateKey|. This is useful to interface keys located in a trusted storage, such as a crypto chip, or when the key is an array of bytes that the engine loads using the function ``ENGINE_load_private_key()``.

      :type:`Enum`: :value:`pem`, :value:`engine`

      Default: :value:`pem`



.. [#fPrefix] Assuming you used :value:`com.rti.serv.secure` as the alias to load the plugin. If not, change the prefix to match the string used with :property:`com.rti.serv.load_plugins`, followed by the :value:`.` character.


Advanced Concepts
=================

Support for Engine Control Commands
-----------------------------------

You may use properties to invoke a sequence of ``ENGINE_ctrl_cmd_string()`` function calls (see :link_external_openssl_docs:`Issuing control commands to an ENGINE from OpenSSL Documentation <ENGINE_ctrl_cmd_string.html>`). These properties are configured through the |DP|'s PROPERTY QosPolicy (see :link_connext_dds_pro_um:`PROPERTY QosPolicy (DDS Extension) in the Core Libraries User's Manual <#users_manual/PROPERTY_Qos.htm>`). The XML format of the properties in the QoS Profile is as follows, assuming that you used :value:`com.rti.serv.secure` as the alias to load the |RTI_SP_PRODUCT| (see :numref:`Properties for Enabling Security`):

.. code-block:: xml

  <domain_participant_qos>
    <property>
      <value>
        <element>
          <name>com.rti.serv.secure.openssl_engine</name>
          <value>[engineName]</value>
        </element>
        <element>
          <name>com.rti.serv.secure.openssl_engine.[engineName].[cmdName1]</name>
          <value>[arg1]</value>
        </element>
        <element>
          <name>com.rti.serv.secure.openssl_engine.[engineName].[cmdName2]</name>
          <value>[arg2]</value>
        </element>
      ...
      </value>
    </property>
  </domain_participant_qos>


The above properties will result in the following code being called by the |RTI_SP_PRODUCT| upon loading the engine:

.. code-block:: c

  ENGINE_ctrl_cmd_string(engineIdentifiedBy[engineName], [cmdName1], [arg1], 0);
  ENGINE_ctrl_cmd_string(engineIdentifiedBy[engineName], [cmdName2], [arg2], 0);

