GithubHelp home page GithubHelp logo

cng-openssl-provider's Introduction

OpenSSL provider using Cryptography API: Next Generation

Basic OpenSSL provider implementation that uses Windows Cryptography API: Next generation. It is primarily meant to be a stepping stone for anybody wanting to implement their own provider. The functionality of this provider is in greater detail in the section This providers functionality.

Any feedback or pull requests are welcome.

The code is licensed under the MIT license, in case anybody would like to have even more permissive license, create an issue, and I'm going to try and find a solution.

This providers functionality

This provider allows retrieval of certificates and their associated RSA keys (other types will be skipped) stored in Windows system stores. Associated keys can be used to sign digests with SHA2-256, 386 and 512 using OpenSSL API (with the work being done by CNG so non-exportable private keys can be used as well).

Usage of this provider

To load this provider use the name cng_provider in either the -provider command line argument where supported or in OSSL_PROVIDER_load(). To maintain full functionality od OpenSSL, also load the default provider.

This provider requires a URI with cng:// schema. After the schema comes the Windows system store name. Currently supported are:

cng://CA
cng://MY
cng://ROOT

Example commandline usage

openssl s_client -provider cng_provider -provider default -connect certificate-required-website.example.com:443 -cert cng:my-key-from-store

Example in-code usage

An example of how one might write code with this provider, that loads a specific certificate from the Windows store, can be found in the client folder.

Prerequisites for usage:

  • OpenSSL 3.0.0+ (should be 3.2.0 compatible as well)
  • Windows with CNG support

Prerequisites for compilation:

  • Prerequisites for usage
  • Visual Studio with C++ compilation packages
  • Strawberry Perl
  • NASM

Add NASM and Strawberry Perl to PATH.

cpan -i Text::Template
cpan -i Test::More

Now you should be ready for the next step.

Compilation

Make sure you have the all the prerequisities for compilation.

It is assumed, that the final product should be a x64 dynamically loadable provider. So OpenSSL and the provider are both compiled in x64 mode. See section x86 compilation for other architectures.

Compilation of OpenSSL:

"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
cd "C:\path\to\root\of\openssl\repo"
perl Configure VC-WIN64A -d no-shared enable-trace no-engine
nmake
nmake test
nmake install_ssldirs install_sw

Optionally also run nmake install install_docs.

Compilation of this project

cmake -S . -B ./custom-build-directory
cmake --build ./custom-build-directory --target cng_provider
cmake --build ./custom-build-directory --target install
cmake --build ./custom-build-directory --target client

x86 compilation

Make sure you compile OpenSSL in x86 mode and have it installed. Use amd64_x86 for vcvarsall.bat and VC-WIN32 for perl Configure. Change the appropriate install directory and OpenSSL location in CMakeLists.txt.

Common problems

  • You are trying to comile debug version and CMake cannot find your OpenSSL binaries: Easy solution is to name them libcryptod.lib and libssld.lib.
  • Provider cannot be installed/loaded: Check permissions on your ossl-modules folder and files in there, your user must be able to read (and/or write) there.
  • I changed the architecture and now it does not compile: Clean your caches and temporary files. Make sure you have the appropriate (x64/x86) OpenSSL version.
  • I cannot compile OpenSSL in x86 mode: You have to change two arguments during OpenSSL compilation and then two other in CMakeLists.txt.

cng-openssl-provider's People

Contributors

akretsch avatar levitte avatar lipovlan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

cng-openssl-provider's Issues

Allow querying certificates by their properties with scheme

The certificate name should be part of the scheme. I'm thinking about something along the lines of adding to the current scheme cng://store-type identifier type-value pair like cng://store-type/identifier-type/identifier-value. So addressing via cng://MY/commonName/CNG 2 Client should be possible.

Allow usage of other system stores

Right now initialize_windows_cert_store() uses CertOpenSystemStore() thus allowing only usage of CERT_SYSTEM_STORE_CURRENT_USER. When replaced with CertOpenStore() it could allow for usage of other stores such as CERT_SYSTEM_STORE_LOCAL_MACHINE.

This needs to reflect in the URI parsing done in cng_store_open(). Perhaps it will be a good idea to use parse_uri_from_store_open() and load more information into the store_ctx and use it later as arguments to initialize_windows_cert_store().

Automatic builds

A nice feature to have would be automatic builds on GitHub that would create x86 and x64 packages of the provider in both normal and debug version.

Use OpenSSL memory allocation methods

OpenSSL has function that core passes to the provider such asOSSL_FUNC_CRYPTO_MALLOC, OSSL_FUNC_CRYPTO_ZALLOC or OSSL_FUNC_CRYPTO_FREE. Those should be used instead of normal malloc and free so it can be better integrated with OpenSSL tools.

Use OpenSSL error methods

OpenSSL has function that core passes to the provider such as OSSL_FUNC_CORE_NEW_ERROR, OSSL_FUNC_CORE_SET_ERROR_DEBUG or OSSL_FUNC_CORE_VSET_ERROR. These should be used instead of the crude debug.h functions currently implemented.

Client did not load private key

I used the KeyStore Explorer to add an RSA key and a "CN=CNG 2 Client" Certificate to the Windows-MY store: KeyStoreExplorer
The client finds the certificate but not the related private key:

C:\git\cng-openssl-provider\custom-build-directory\client\Debug>client.exe
PROGRAM> We will connect to a remote server and check the SSL certificate
Configuration in section openssl_init
Adding config module 'alg_section'
Adding config module 'providers'
Adding config module 'random'
Loading providers module: section provider_sect
Configuring provider default
Provider params: start section default_sect
Provider params: finish section default_sect
Running module providers (provider_sect) returned 1
Looking up scheme cng
Found loader for scheme cng
Opened cng://MY => 0x24a5a2da3c0
Loading next object
Got a Certificate
PROGRAM> Found certificate in store
Loading next object
Got a Certificate
PROGRAM> Found certificate in store
Loading next object
Got a Certificate
PROGRAM> Found certificate in store
Loading next object
Got a Certificate
PROGRAM> Found certificate in store
Loading next object
Got a Certificate
PROGRAM> Found certificate in store
Loading next object
Got a Certificate
PROGRAM> Found certificate in store
Closing 0x24a5a2da3c0
Looking up scheme cng
Found loader for scheme cng
Opened cng://MY => 0x24a5bfe5710
Loading next object
Got a Certificate
Loading next object
Got a Certificate
Loading next object
Got a Certificate
Loading next object
Got a Certificate
Loading next object
Got a Certificate
Loading next object
Got a Certificate
Loading next object
Closing 0x24a5bfe5710
PROGRAM> Could not find matching private key in store
PROGRAM> Client exiting...
Cleaned up providers

My OpenSSL version is 3.2.0. Whats did I wrong?

Thanks in advance!

@DDvO

Cache OpenSSL build during automatic builds

Right now compilation of OpenSSL takes most of the automatic build time.

GitHub actions caching (actions/cache@v3) might be of use. The openssl-install directory is a great candidate for this. It is however probably going to need something along the lines of if: steps.cache-id.outputs.cache-hit != 'true' as not to trigger the OpenSSL compilation again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.