Skip to content

Commit

Permalink
openssl-fips: create "alias" recipe for FIPS validated OpenSSL
Browse files Browse the repository at this point in the history
This is especially necessary for when 2 distinct versions of the FIPS module and the rest of the openssl libs/execs.
  • Loading branch information
gegles committed Mar 28, 2024
1 parent c7c6e63 commit 9788740
Show file tree
Hide file tree
Showing 8 changed files with 1,015 additions and 0 deletions.
12 changes: 12 additions & 0 deletions recipes/openssl-fips/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
sources:
# Note: Only ever add the versions of OpenSSL that have been FIPS certified
3.0.9:
url:
- "https://www.openssl.org/source/openssl-3.0.9.tar.gz"
- "https://github.com/openssl/openssl/releases/download/openssl-3.0.9/openssl-3.0.9.tar.gz"
sha256: eb1ab04781474360f77c318ab89d8c5a03abc38e63d65a603cabbf1b00a1dc90
3.0.8:
url:
- "https://www.openssl.org/source/openssl-3.0.8.tar.gz"
- "https://github.com/openssl/openssl/releases/download/openssl-3.0.8/openssl-3.0.8.tar.gz"
sha256: 6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e
685 changes: 685 additions & 0 deletions recipes/openssl-fips/all/conanfile.py

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions recipes/openssl-fips/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.15)
project(test_package LANGUAGES C)

option(OPENSSL_WITH_LEGACY "OpenSSL with support for the legacy provider" ON)
option(OPENSSL_WITH_MD4 "OpenSSL with MD4 support (needs legacy provider)" ON)
option(OPENSSL_WITH_RIPEMD160 "OpenSSL with RIPEMD16 support (needs legacy provider)" ON)

set(OpenSSL_DEBUG 1)
find_package(OpenSSL REQUIRED)

# Test whether variables from https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
# are properly defined in conan generators
set(_custom_vars
OPENSSL_FOUND
OPENSSL_INCLUDE_DIR
OPENSSL_CRYPTO_LIBRARY
OPENSSL_CRYPTO_LIBRARIES
OPENSSL_SSL_LIBRARY
OPENSSL_SSL_LIBRARIES
OPENSSL_LIBRARIES
OPENSSL_VERSION
)
foreach(_custom_var ${_custom_vars})
if(DEFINED ${_custom_var})
message(STATUS "${_custom_var}: ${${_custom_var}}")
else()
message(FATAL_ERROR "${_custom_var} not defined")
endif()
endforeach()

add_executable(test_package test_package.c digest.c)
target_link_libraries(test_package PRIVATE OpenSSL::SSL OpenSSL::Crypto)

if(OPENSSL_WITH_LEGACY)
target_sources(test_package PRIVATE digest_legacy.c)
# do now show deperecation warnings
target_compile_definitions(test_package PRIVATE OPENSSL_SUPPRESS_DEPRECATED TEST_OPENSSL_LEGACY)
if(OPENSSL_WITH_MD4)
target_compile_definitions(test_package PRIVATE OPENSSL_WITH_MD4)
endif()
if(OPENSSL_WITH_RIPEMD160)
target_compile_definitions(test_package PRIVATE OPENSSL_WITH_RIPEMD160)
endif()
endif()
38 changes: 38 additions & 0 deletions recipes/openssl-fips/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "VirtualRunEnv"
test_type = "explicit"

def layout(self):
cmake_layout(self)

def requirements(self):
self.requires(self.tested_reference_str)

def _with_legacy(self):
return (not self.dependencies["openssl-fips"].options.no_legacy and
((not self.dependencies["openssl-fips"].options.no_md4) or
(not self.dependencies["openssl-fips"].options.no_rmd160)))

def generate(self):
tc = CMakeToolchain(self)
tc.cache_variables["OPENSSL_WITH_LEGACY"] = self._with_legacy()
tc.cache_variables["OPENSSL_WITH_MD4"] = not self.dependencies["openssl-fips"].options.no_md4
tc.cache_variables["OPENSSL_WITH_RIPEMD160"] = not self.dependencies["openssl-fips"].options.no_rmd160
tc.generate()

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
self.run(bin_path, env="conanrun")
65 changes: 65 additions & 0 deletions recipes/openssl-fips/all/test_package/digest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif

void SHA3_hash(const EVP_MD *type, const unsigned char *message, size_t message_len, unsigned char *digest, unsigned int *digest_len) {
EVP_MD_CTX *mdctx;

if((mdctx = EVP_MD_CTX_create()) == NULL)
printf("EVP_MD_CTX_create error!\n");

if(EVP_DigestInit_ex(mdctx, type, NULL) != 1)
printf("EVP_DigestInit_ex error!\n");

if(EVP_DigestUpdate(mdctx, message, message_len) != 1)
printf("EVP_DigestUpdate error!\n");

if(EVP_DigestFinal_ex(mdctx, digest, digest_len) != 1)
printf("EVP_DigestFinal_ex error!\n");

EVP_MD_CTX_destroy(mdctx);
}

void digest()
{
unsigned int digest_len;
unsigned char sha256_digest[SHA256_DIGEST_LENGTH],
sha512_digest[SHA512_DIGEST_LENGTH],
sha3_256_digest[SHA256_DIGEST_LENGTH],
sha3_512_digest[SHA512_DIGEST_LENGTH];
char sha256_string[SHA256_DIGEST_LENGTH*2+1] = {0},
sha512_string[SHA512_DIGEST_LENGTH*2+1] = {0},
sha3_256_string[SHA256_DIGEST_LENGTH*2+1] = {0},
sha3_512_string[SHA512_DIGEST_LENGTH*2+1] = {0};
char string[] = "happy";

SHA256((unsigned char*)&string, strlen(string), (unsigned char*)&sha256_digest);
SHA512((unsigned char*)&string, strlen(string), (unsigned char*)&sha512_digest);
SHA3_hash(EVP_sha3_256(), (unsigned char*)&string, strlen(string), (unsigned char*)&sha3_256_digest, &digest_len);
SHA3_hash(EVP_sha3_512(), (unsigned char*)&string, strlen(string), (unsigned char*)&sha3_512_digest, &digest_len);

for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
snprintf(&sha256_string[i*2], sizeof(sha256_string)-i*2, "%02x", (unsigned int)sha256_digest[i]);
snprintf(&sha3_256_string[i*2], sizeof(sha3_256_string)-i*2, "%02x", (unsigned int)sha3_256_digest[i]);
}

for(int i = 0; i < SHA512_DIGEST_LENGTH; i++) {
snprintf(&sha512_string[i*2], sizeof(sha512_string)-i*2, "%02x", (unsigned int)sha512_digest[i]);
snprintf(&sha3_512_string[i*2], sizeof(sha3_512_string)-i*2, "%02x", (unsigned int)sha3_512_digest[i]);
}

printf("sha256 digest: %s\n", sha256_string);
printf("sha512 digest: %s\n", sha512_string);
printf("sha3 256 digest: %s\n", sha3_256_string);
printf("sha3 512 digest: %s\n", sha3_512_string);

}
141 changes: 141 additions & 0 deletions recipes/openssl-fips/all/test_package/digest_legacy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include <openssl/evp.h>
#if OPENSSL_WITH_MD4
#include <openssl/md4.h> // MD4 needs legacy provider
#endif
#if OPENSSL_WITH_RIPEMD160
#include <openssl/ripemd.h> // RIPEMD160 needs legacy provider
#endif
#include <openssl/md5.h>
#include <openssl/provider.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif

int MDx_hash(const EVP_MD *type, const unsigned char *message, size_t message_len, unsigned char *digest, unsigned int *digest_len) {
EVP_MD_CTX *mdctx;

if((mdctx = EVP_MD_CTX_create()) == NULL)
{
printf("EVP_MD_CTX_create error!\n");
return 1;
}

if(EVP_DigestInit_ex(mdctx, type, NULL) != 1)
{
printf("EVP_DigestInit_ex error!\n");
return 1;
}

if(EVP_DigestUpdate(mdctx, message, message_len) != 1)
{
printf("EVP_DigestUpdate error!\n");
return 1;
}

if(EVP_DigestFinal_ex(mdctx, digest, digest_len) != 1)
{
printf("EVP_DigestFinal_ex error!\n");
return 1;
}

EVP_MD_CTX_destroy(mdctx);
return 0;
}

int digest_legacy()
{
unsigned int digest_len;
unsigned char md5_digest[MD5_DIGEST_LENGTH];
unsigned char md5_digest2[MD5_DIGEST_LENGTH];
char md5_string[MD5_DIGEST_LENGTH*2+1] = {0};
char md5_string2[MD5_DIGEST_LENGTH*2+1] = {0};
char string[] = "happy";

MD5((unsigned char*)&string, strlen(string), (unsigned char*)&md5_digest);
if (MDx_hash(EVP_md5(), (unsigned char*)&string, strlen(string), (unsigned char*)&md5_digest2, &digest_len))
return 1;

for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
snprintf(&md5_string[i*2], sizeof(md5_string)-i*2, "%02x", (unsigned int)md5_digest[i]);
snprintf(&md5_string2[i*2], sizeof(md5_string2)-i*2, "%02x", (unsigned int)md5_digest2[i]);
}

// MD4 needs the legacy provider
OSSL_LIB_CTX* context = OSSL_LIB_CTX_new();
// From https://wiki.openssl.org/index.php/OpenSSL_3.0
/* Load Multiple providers into the default (nullptr) library context */
OSSL_PROVIDER* legacy = OSSL_PROVIDER_load(context, "legacy");
if (0 == legacy) {
const char* error_string = ERR_error_string(ERR_get_error(), 0);
fprintf(stderr, "Loading legacy provider failed with this error:\n");
fprintf(stderr, "\t%s\n", error_string);
return 1;
}
OSSL_LIB_CTX* oldcontex = OSSL_LIB_CTX_set0_default(context);
printf("Legacy provider successfully loaded.\n");

#if OPENSSL_WITH_MD4
unsigned char md4_digest[MD4_DIGEST_LENGTH];
unsigned char md4_digest2[MD4_DIGEST_LENGTH];
char md4_string[MD4_DIGEST_LENGTH*2+1] = {0};
char md4_string2[MD4_DIGEST_LENGTH*2+1] = {0};

MD4((unsigned char*)&string, strlen(string), (unsigned char*)&md4_digest);
if (MDx_hash(EVP_md4(), (unsigned char*)&string, strlen(string), (unsigned char*)&md4_digest2, &digest_len)) {
const char* error_string = ERR_error_string(ERR_get_error(), 0);
fprintf(stderr, "MD4 calculation failed with this error:\n");
fprintf(stderr, "\t%s\n", error_string);
return 1;
}

for(int i = 0; i < MD4_DIGEST_LENGTH; i++) {
snprintf(&md4_string[i*2], sizeof(md4_string)-i*2, "%02x", (unsigned int)md4_digest[i]);
snprintf(&md4_string2[i*2], sizeof(md4_string2)-i*2, "%02x", (unsigned int)md4_digest2[i]);
}
#endif

#if OPENSSL_WITH_RIPEMD160
unsigned char ripemd160_digest[RIPEMD160_DIGEST_LENGTH];
unsigned char ripemd160_digest2[RIPEMD160_DIGEST_LENGTH];
char ripemd160_string[RIPEMD160_DIGEST_LENGTH*2+1] = {0};
char ripemd160_string2[RIPEMD160_DIGEST_LENGTH*2+1] = {0};

RIPEMD160((unsigned char*)&string, strlen(string), (unsigned char*)&ripemd160_digest);
if (MDx_hash(EVP_ripemd160(), (unsigned char*)&string, strlen(string), (unsigned char*)&ripemd160_digest2, &digest_len)) {
const char* error_string = ERR_error_string(ERR_get_error(), 0);
fprintf(stderr, "RIPEMD160 calculation failed with this error:\n");
fprintf(stderr, "\t%s\n", error_string);
return 1;
}

for(int i = 0; i < RIPEMD160_DIGEST_LENGTH; i++) {
snprintf(&ripemd160_string[i*2], sizeof(ripemd160_string)-i*2, "%02x", (unsigned int)ripemd160_digest[i]);
snprintf(&ripemd160_string2[i*2], sizeof(ripemd160_string2)-i*2, "%02x", (unsigned int)ripemd160_digest2[i]);
}
#endif

OSSL_LIB_CTX_set0_default(oldcontex);
OSSL_PROVIDER_unload(legacy);
OSSL_LIB_CTX_free(context);

printf("MD5 digest: %s\n", md5_string);
printf("MD5 digest (variant 2): %s\n", md5_string2);
#if OPENSSL_WITH_MD4
printf("MD4 digest: %s\n", md4_string);
printf("MD4 digest (variant 2): %s\n", md4_string2);
#endif
#if OPENSSL_WITH_RIPEMD160
printf("RIPEMD160 digest: %s\n", ripemd160_string);
printf("RIPEMD160 digest (variant 2): %s\n", ripemd160_string2);
#endif

return 0;
}
24 changes: 24 additions & 0 deletions recipes/openssl-fips/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <openssl/ssl.h>

void digest();
int digest_legacy();

int main()
{
int legacy_result = 0;
OPENSSL_init_ssl(0, NULL);
printf("OpenSSL version: %s\n", OpenSSL_version(OPENSSL_VERSION));

digest();

#if defined(TEST_OPENSSL_LEGACY)
legacy_result = digest_legacy();
if (legacy_result != 0) {
printf("Error testing the digest_legacy() function\n");
return 1;
}
#endif

return 0;
}
6 changes: 6 additions & 0 deletions recipes/openssl-fips/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
versions:
# Note: Only ever add the versions of OpenSSL that have been FIPS certified
3.0.9:
folder: "all"
3.0.8:
folder: "all"

0 comments on commit 9788740

Please sign in to comment.