How to Include Openssl in Visual Studio

How to include OpenSSL in Visual Studio

Intro

  • Although the question / answer is based on:

    • OpenSSL 1.0.1*
    • VStudio 2012


    it applies to any OpenSSL version (v.0.9.*, v1.0.*, v1.1.*, v3.0), and any VStudio version (v2005+)

  • OpenSSL builds are also available at [GitHub]: CristiFati/Prebuilt-Binaries - (master) Prebuilt-Binaries/OpenSSL


Let's assume you have installed OpenSSL in a dir like: "C:\Program Files\Openssl-Win32-1.0.1p....." (or whatever other name); I am going to refer to that as OPENSSL_INSTALL_DIR (as it was an Nix style env var). So, ${OPENSSL_INSTALL_DIR} should contain a bunch of dirs and files, out of which matter for us:

  • Dirs:

    • include
    • lib
  • Files (since their names vary across versions, I'm going to refer to them using (again, Nix style var) placeholders; also they might be located in a bin subdir):

    • ${LIBCRYPTO}.dll
    • ${LIBSSL}.dll


    where LIBCRYPTO (#1.) and LIBSSL (#2.) are defined as follows:

    • v1.0.2 and older

      1. libeay32
      2. ssleay32 (might be also copied (or symlinked) to libssl32)
    • v1.1.*

      1. libcrypto-1_*(-x64)
      2. libssl-1_*(-x64)
    • v3.0

      1. libcrypto-3*
      2. libssl-3*

In order to make use of it, in your VStudio project you have to:

1. Configue the compiler ([MS.Docs]: Compiler Options Listed Alphabetically)
Instruct it:

  • Where to search for include (header (.h)) files. Go to your "Project Properties -> C/C++ -> General -> Additional Include Directories" and adding ${OPENSSL_INSTALL_DIR}\include (if you need to add other paths, separate them by a semicolon (;)). Now you can include in your source code OpenSSL header files.
    Note that because "${OPENSSL_INSTALL_DIR}\include" dir contains an openssl subdir and under that subdir are the actual header files, your #include clauses would have to look like this:

    #include <openssl/ssl.h>

    Of course you could add ${OPENSSL_INSTALL_DIR}\include\openssl dir to your project, and then the above include statement would be:

    #include <ssl.h>

    but the former is preferred (recommended)

2. Configure the linker ([MS.Docs]: Linker Options)
Instruct it:

  • Where to search for libraries. You can do that by going to your "Project Properties -> Linker -> General -> Additional Library Directories" and adding ${OPENSSL_INSTALL_DIR}\lib (again, if there are multiple paths, separate them by ;)

  • What libraries to use. "${OPENSSL_INSTALL_DIR}\lib" dir contains a bunch of .lib files. Out of those, you will (most likely) only need ${LIBCRYPTO}.lib and / or ${LIBSSL}.lib. Go to your "Project Properties -> Linker -> Input -> Additional Dependencies" and add those 2 libraries next to the existing ones

3. Build and run

Now, if all your settings and source code are correct, you should have a "buildable" project. When you'll want to run your project output (either an .exe or a .dll needed by another executable, I am not discussing here the possibility of you are using the static libs), the executable will need to find the 2 .dlls that I mentioned at the beginning. For that, you should either:

  • Add their dir to your PATH env var (I consider this the cleanest one). Example (from console): set PATH=%PATH%;${OPENSSL_INSTALL_DIR}

    • For the running VStudio instance:

      Img0

  • Copy them in the folder where your executable is located ([MS.Docs]: Dynamic-Link Library Search Order)

  • Copy them in one of the dirs from your %PATH%.
    Some installers might copy the 2 .dlls in your "%SystemRoot%\System32" dir, and in that case this will no longer be necessary (I find this practice of copying stuff in system dirs a bad one, as in our current example multiple versions can ship the same file names, and the last one installed would overwrite all the others)

Important note: Must be careful when targeting your project for 32bit or 64bit (setting Platform to Win32 or x64 in VStudio IDE) - that has to match your OpenSSL installation architecture.

How to link OpenSSL libraries statically in VS2019?

The .lib files that are created in a default build are just stubs to call the dlls.

When building OpenSSL you need to specify that you want to build it for static linking.

Modify the "Configure" line that you used to add "no-shared" onto the end, e.g.

perl Configure --prefix=d:\your\prefix\here VC-WIN32 no-shared

Then you will need to rebuild OpenSSL:

nmake clean
nmake
nmake test
nmake install

Is OpenSsl available in Visual Studio in Windows OS?

Is OpenSsl available in Visual Studio in Windows OS?

Yes, at least according to their FAQ and their available binaries.

Then what is purpose of System.Security.Cryptograpgy.Openssl Nouget Packet in Visual Studio ?

Because of the, non-intuitive way(at least to me), Microsoft Documentation is laid out, it's often harder to understand why something exists/ is available.

Understanding why this particular package isn't immediately useful. We have to look at several sections of the Documentation page that you linked.

Under the Remarks section we see

The RSAOpenSsl class is an implementation of the RSA algorithm using OpenSSL. It isn't available on Windows and is only available on other operating systems when OpenSSL is installed. ...

This is important because it essentially tells us that this particular package doesn't work on windows and is meant to target specifically non-windows platforms.

This may seem pretty non-intuitive because C# and several frameworks that Microsoft develop such as .NET Framework explicitly do not target anything BUT Windows/Microsoft platforms. So to figure this out we have to look a little deeper, and in this case, WAY deeper into the web page(since it's so long).

If we scroll all the way to the bottom of the page we can see the 'Applies To' section that most Microsoft documentation pages include.



















ProductVersions
.NET Core1.0, 1.1
.NET Platform Extensions2.1, 2.2, 3.0, 3.1, 5.0

Add OpenSSL static lib to Visual Studio 2017 project

Do NuGets modify the include and linking paths when added to a
project?

Sure. I can tell you explicitly that the nuget imports additional properties into the project through <package_id>.targets or <package_id>.props file, instead of manually adding include path again.

This is a mechanism for nuget packaging to add additional project properties such as library path directly to the project during the installation of the nuget package. More info you can refer to this link.

The <package_id>.targets was created during the process of packing the nuget package.
In other words, this method was designed by the author of the nuget package. And in my side, the file openssl-vc141-static-x86_64.targets exists in this path:

C:\Users\Admin\source\repos\ConsoleApplication25\packages\openssl-vc141-static-x86_64.1.1.0\build\native

also, boost seems to have added its linker directories to my project
(though I only see that in MSBuild output, not in Configuration
Properties->Linker->Command Line)

l think the issue is related to the difference between <package_id>.targets and <package_id>.props. Although using <package_id>.targets does not appear on the property UI, it still works for the whole project.

In more detail

When you install the nuget package into the project, these files are automatically executed. <target_id>.props file is added at the top of the file while .targets is added at the bottom.

When initializing the xxx.vcxproj file, because <package_id> .props is at the head of the file, the property UI can capture the properties in the file, and <package_id> .targets is at the end, so the initialization cannot be captured but still In the project. For the nuget, it uses openssl-vc141-static-x86_64.targets.

In openssl-vc141-static-x86_64.targets file, you can see this:

<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include\;%
(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAS_LIBTHRIFT;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
</ClCompile>

And l have set the output log to Diagnostic and build the project and found this:

Sample Image

The library path has been added into AdditionalIncludeDirectories by the openssl-vc141-static-x86_64.targets file automatically. So you do not have to worry about it.

Is there a proper way to add these projects that I'm missing? Or a
proper way to use the targets file? Or maybe the OpenSSL static NuGet
just missing something? Or maybe I should just look into vcpkg?

You do not need to worry about it and do not add the include path into project property. This is superfluous and when you have finished installing this nuget package, use it in cpp files directly.

In addition,

For c++ packages installed by nuget, you don't need to add any paths to the project property.

Update 1

The issue is related to your project rather than the nuget package. Exactly because your current project does not have $(Configuration), so in openssl-vc141-static-x86_64.targets, you can see these:

 <ItemDefinitionGroup Label="Win32 and vc141 and Debug" Condition="'$(Platform)' == 'Win32' And ( $(PlatformToolset.IndexOf('v141')) > -1 Or '$(PlatformToolset)' == 'WindowsKernelModeDriver8.0' Or '$(PlatformToolset)' == 'WindowsApplicationForDrivers8.0' Or '$(PlatformToolset)' == 'WindowsUserModeDriver8.0' ) And '$(Configuration)' == 'Debug'">
<Link>
<AdditionalLibraryDirectories>$(MSBuildThisFileDirectory)lib\Win32\static\Debug\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libssl.lib;libcrypto.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /Y "$(MSBuildThisFileDirectory)\lib\Win32\dynamic\*-1_1.dll" "$(OutDir)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>

This is the operation to import specific libssl.lib and libcrypto.Lib into the AdditionalDependencies node. But you can find out that there is a judge condition And '$(Configuration)' == 'Debug', since you do not have $(Configuration),therefore, it always returns false and these libs cannot be automatically imported into AdditionalDependencies.

As a workaround, you should add these lib path manually just as you said.

And l am sure that if you use a project which contains $(Configuration)(Debug or Release), you will not encouter this issue. And most of the C++ nuget packages can be used directly in the project which contains the Configuration node.

l am sure that if you use the $(Configuration) into your project and then reinstall this package(please clean the nuget cache before doing it), you will not face this error.

Also, your screen shot, where did you get that? I don't see anything
like that in the VS output console, or when I run msbuild on the
command line. Is there some way I might have accidentally broken the
default behaviour?

You can set MSBuild project build output verbosity to Diagnostic by Tools-->Options-->Projects and Solutions-->Build and Run.

When you build your project,the Output Window shows thw whole build process and records all the information and then you can search the key fields by the search box on the Output Window.

Error installing OpenSSL using VCPKG on Visual Studio code: Error: in triplet x64-windows: Unable to find a valid Visual Studio instance

Install the latest version of the Visual studio installer even if you have visual studio code installed.
Check the boxes to install desktop development tools for Linux and windows
Check the box to install C++ CMake tools as well
Then proceed with the installation.



Related Topics



Leave a reply



Submit