Search code examples
windowsopensslbinaries

How to bundle OpenSSL v3 binaries with application on Windows?


How to bundle OpenSSL v3 binaries with application on Windows?

Withing executable I have libcrypto-3-x64.dll and libssl-3-x64.dll.

In ./lib directory I have DLLs in engines-3 and ossl-modules.

Good, but to start application I forced to use *.bat file with something like:

set OPENSSL_MODULES=./lib/ossl-modules
set OPENSSL_ENGINES=./lib/engines-3
start "" my_app.exe %

How to avoid using of this *.bat file, and have only my_app.exe that won't produce Windows error message?

Want to add that:

int main( int argc, char ** argv )
{
    qputenv( "OPENSSL_MODULES", "./lib/ossl-modules" );
    qputenv( "OPENSSL_ENGINES", "./lib/engines-3" );

doesn't solve the problem.

And a following *.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <environment name="OPENSSL_MODULES" value="./lib/ossl-modules" />
      <environment name="OPENSSL_ENGINES" value="./lib/engines-3" />
    </windowsSettings>
  </application>
</assembly>

doesn't solve the problem too.

Thanks.


Solution

  • If the bat file works but this code does not:

    int main( int argc, char ** argv )
    {
        qputenv( "OPENSSL_MODULES", "./lib/ossl-modules" );
        qputenv( "OPENSSL_ENGINES", "./lib/engines-3" );
    

    that means you have to set the environment variables before the OS loads the process.

    So do just that. Re-load the process after you set the envvals:

    int main( int argc, char ** argv )
    {
        QByteArray envval = qgetenv( "OPENSSL_MODULES" );
    
        // assumes a "default constructed" QByteArray will
        // return true here - not tested
        if ( ennval.isEmpty() )
        {
            qputenv( "OPENSSL_MODULES", "./lib/ossl-modules" );
            qputenv( "OPENSSL_ENGINES", "./lib/engines-3" );
    
            execv( argv[ 0 ], argv );
            perror( "execv" );
            exit( 1 );
        }
        .
        .
        .
    

    Headers and error checking have been omitted to keep the code example short enough so it doesn't have a vertical scroll bar.

    And turn off Microsoft's risible, "We've deprecated every portable non-Microsoft thing we can get away with" "warning"

    Note that those envvals assume the current working directory is the parent of that particular lib directory. You can add quite a bit of robustness and remove the requirement by finding the absolute path of the application binary first and then use that to determine the absolute path to the lib directory.