Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,21 @@ check_library_exists(pthread pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP)
check_library_exists(pthread pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP)

# WITH_CRYPTO
set(WITH_CRYPTO "gcrypt" CACHE STRING "gcrypt|nss")
set(WITH_CRYPTO "gcrypt" CACHE STRING "gcrypt|nss|openssl")
set_property(CACHE WITH_CRYPTO PROPERTY STRINGS "gcrypt" "nss" "openssl")
if(${WITH_CRYPTO} STREQUAL "nss")
message("-- Using NSS")
find_package(NSS)
elseif(${WITH_CRYPTO} STREQUAL "openssl")
message("-- Using OpenSSL for crypto backend")
# OpenSSL is already a required dependency (see find_package(OpenSSL REQUIRED) above);
# this flag tells the crapi layer to use it as the digest backend.
set(OPENSCAP_CRYPTO_OPENSSL TRUE)
else()
message("-- Using GCrypt")
find_package(GCrypt)
endif()
if(GCRYPT_FOUND OR NSS_FOUND)
if(GCRYPT_FOUND OR NSS_FOUND OR OPENSCAP_CRYPTO_OPENSSL)
set(CRYPTO_FOUND TRUE)
endif()

Expand Down
5 changes: 5 additions & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
#define HAVE_NSS3
#endif

#cmakedefine OPENSCAP_CRYPTO_OPENSSL
#if defined(OPENSCAP_CRYPTO_OPENSSL)
#define HAVE_OPENSSL_CRYPTO
#endif

#define OSCAP_DEFAULT_SCHEMA_PATH "@OSCAP_DEFAULT_SCHEMA_PATH@"
#define OSCAP_DEFAULT_XSLT_PATH "@OSCAP_DEFAULT_XSLT_PATH@"
#define OSCAP_DEFAULT_CPE_PATH "@OSCAP_DEFAULT_CPE_PATH@"
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ if (ENABLE_PROBES)
)
endif()
endif()
if (HAVE_MMAN_H AND (GCRYPT_FOUND OR NSS_FOUND))
if (HAVE_MMAN_H AND (GCRYPT_FOUND OR NSS_FOUND OR OPENSCAP_CRYPTO_OPENSSL))
list(APPEND OBJECTS_TO_LINK_AGAINST
$<TARGET_OBJECTS:crapi_object>
)
Expand Down
11 changes: 11 additions & 0 deletions src/OVAL/probes/crapi/crapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@

return(0);
}
#elif defined(HAVE_OPENSSL_CRYPTO)
#include <openssl/evp.h>
#include <openssl/opensslv.h>
int crapi_init (void *unused)

Check warning on line 53 in src/OVAL/probes/crapi/crapi.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused parameter "unused", make it unnamed, or declare it "[[maybe_unused]]".

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AZzUXVXratZvORe71sWJ&open=AZzUXVXratZvORe71sWJ&pullRequest=2319
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
/* OpenSSL < 1.1.0 requires explicit digest algorithm registration. */
OpenSSL_add_all_digests();
#endif
return 0;
}
#else
int crapi_init (void *unused)
{
Expand Down
153 changes: 152 additions & 1 deletion src/OVAL/probes/crapi/digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,23 @@
#include <sechash.h>
#elif defined(HAVE_GCRYPT)
#include <gcrypt.h>
#elif defined(HAVE_OPENSSL_CRYPTO)
#include <openssl/evp.h>
#include <openssl/opensslv.h>
#else
#error "No crypto library available!"
#endif

/*
* Compatibility shim for OpenSSL < 1.1.0, which used EVP_MD_CTX_create() and
* EVP_MD_CTX_destroy() instead of the EVP_MD_CTX_new() / EVP_MD_CTX_free()
* names introduced in 1.1.0.
*/
#if defined(HAVE_OPENSSL_CRYPTO) && OPENSSL_VERSION_NUMBER < 0x10100000L
# define EVP_MD_CTX_new() EVP_MD_CTX_create()
# define EVP_MD_CTX_free(c) EVP_MD_CTX_destroy(c)
#endif

#if defined(HAVE_NSS3)
static int crapi_alg_t_to_lib_arg(crapi_alg_t alg)
{
Expand Down Expand Up @@ -95,8 +108,79 @@
return -1;
}
}
#elif defined(HAVE_OPENSSL_CRYPTO)
static const EVP_MD *crapi_alg_t_to_evp_md(crapi_alg_t alg)
{
switch (alg) {
#ifdef OPENSCAP_ENABLE_MD5
case CRAPI_DIGEST_MD5:
return EVP_md5();
#endif
#ifdef OPENSCAP_ENABLE_SHA1
case CRAPI_DIGEST_SHA1:
return EVP_sha1();
#endif
case CRAPI_DIGEST_SHA224:
return EVP_sha224();
case CRAPI_DIGEST_SHA256:
return EVP_sha256();
case CRAPI_DIGEST_SHA384:
return EVP_sha384();
case CRAPI_DIGEST_SHA512:
return EVP_sha512();
default:
return NULL;
}
}
#endif

#if defined(HAVE_OPENSSL_CRYPTO)
/* Read fd and compute its digest using the streaming EVP API. */
static int crapi_digest_fd_stream(int fd, const EVP_MD *evp_md, void *dst, size_t *size)
{
uint8_t buf[CRAPI_IO_BUFSZ];
ssize_t ret;

EVP_MD_CTX *ctx = EVP_MD_CTX_new();
if (ctx == NULL)
return -1;
if (EVP_DigestInit_ex(ctx, evp_md, NULL) != 1) {
EVP_MD_CTX_free(ctx);
return -1;
}
while ((ret = read(fd, buf, sizeof buf)) == sizeof buf) {
if (EVP_DigestUpdate(ctx, (const void *)buf, sizeof buf) != 1) {
EVP_MD_CTX_free(ctx);
return -1;
}
}
switch (ret) {
case 0:
break;
case -1:
EVP_MD_CTX_free(ctx);
return -1;
default:
if (ret <= 0) {
EVP_MD_CTX_free(ctx);
return -1;
}
if (EVP_DigestUpdate(ctx, (const void *)buf, (size_t)ret) != 1) {
EVP_MD_CTX_free(ctx);
return -1;
}
}
unsigned int md_len = (unsigned int)*size;
if (EVP_DigestFinal_ex(ctx, (unsigned char *)dst, &md_len) != 1) {
EVP_MD_CTX_free(ctx);
return -1;
}
*size = (size_t)md_len;
EVP_MD_CTX_free(ctx);
return 0;
}
#endif /* HAVE_OPENSSL_CRYPTO */

int crapi_digest_fd(int fd, crapi_alg_t alg, void *dst, size_t *size)
{
struct stat st;
Expand All @@ -107,6 +191,22 @@
errno = EFAULT;
return -1;
}

/*
* Resolve the algorithm and verify the output buffer is large enough
* to hold the digest.
*/
#if defined(HAVE_OPENSSL_CRYPTO)
const EVP_MD *evp_md = crapi_alg_t_to_evp_md(alg);
if (evp_md == NULL) {
errno = EINVAL;
return -1;
}
if (*size < (size_t)EVP_MD_size(evp_md)) {
errno = ENOBUFS;
return -1;
}
#else
int lib_alg = crapi_alg_t_to_lib_arg(alg);
#if defined(HAVE_NSS3)
if (*size < HASH_ResultLen(lib_alg)) {
Expand All @@ -116,6 +216,7 @@
errno = ENOBUFS;
return -1;
}
#endif /* HAVE_OPENSSL_CRYPTO */

if (fstat (fd, &st) != 0)
return (-1);
Expand All @@ -129,6 +230,10 @@
# endif
if (buffer == NULL) {
#endif /* _FILE_OFFSET_BITS == 32 */
#if defined(HAVE_OPENSSL_CRYPTO)
if (crapi_digest_fd_stream(fd, evp_md, dst, size) != 0)
return -1;
#else
uint8_t _buffer[CRAPI_IO_BUFSZ];
ssize_t ret;

Expand Down Expand Up @@ -181,10 +286,18 @@
memcpy (dst, buffer, gcry_md_get_algo_dlen(lib_alg));
gcry_md_close (hd);
#endif
#endif /* !HAVE_OPENSSL_CRYPTO */

#if _FILE_OFFSET_BITS == 32
} else {
#if defined(HAVE_NSS3)
#if defined(HAVE_OPENSSL_CRYPTO)
unsigned int md_len = (unsigned int)*size;
if (EVP_Digest(buffer, buflen, (unsigned char *)dst, &md_len, evp_md, NULL) != 1) {
munmap(buffer, buflen);
return -1;
}
*size = (size_t)md_len;
#elif defined(HAVE_NSS3)
HASH_HashBuf(lib_alg, (unsigned char *)dst, (unsigned char *)buffer, (unsigned int)buflen);
#elif defined(HAVE_GCRYPT)
gcry_md_hash_buffer(lib_alg, dst, (const void *)buffer, buflen);
Expand All @@ -201,6 +314,8 @@
HASHContext *ctx;
#elif defined(HAVE_GCRYPT)
gcry_md_hd_t ctx;
#elif defined(HAVE_OPENSSL_CRYPTO)
EVP_MD_CTX *ctx;
#endif
void *dst;
size_t *size;
Expand All @@ -215,14 +330,35 @@
{
struct crapi_digest_ctx *ctx = malloc(sizeof(struct crapi_digest_ctx));

#if defined(HAVE_NSS3) || defined(HAVE_GCRYPT)
int lib_alg = crapi_alg_t_to_lib_arg(alg);
#endif
#if defined(HAVE_NSS3)
ctx->ctx = HASH_Create(lib_alg);
#elif defined(HAVE_GCRYPT)
if (gcry_md_open(&ctx->ctx, lib_alg, 0) != 0) {
free(ctx);
return NULL;
}
#elif defined(HAVE_OPENSSL_CRYPTO)
if (ctx == NULL)
return NULL;
const EVP_MD *evp_md = crapi_alg_t_to_evp_md(alg);
if (evp_md == NULL) {
free(ctx);
errno = EINVAL;
return NULL;
}
ctx->ctx = EVP_MD_CTX_new();
if (ctx->ctx == NULL) {
free(ctx);
return NULL;
}
if (EVP_DigestInit_ex(ctx->ctx, evp_md, NULL) != 1) {
EVP_MD_CTX_free(ctx->ctx);
free(ctx);
return NULL;
}
#endif
ctx->dst = dst;
ctx->size = size;
Expand All @@ -245,11 +381,14 @@
HASH_Update(ctx->ctx, (const unsigned char *)bptr, (unsigned int)blen);
#elif defined(HAVE_GCRYPT)
gcry_md_write(ctx->ctx, (const void *)bptr, blen);
#elif defined(HAVE_OPENSSL_CRYPTO)
if (EVP_DigestUpdate(ctx->ctx, (const void *)bptr, blen) != 1)
return -1;
#endif
return (0);
}

static int crapi_digest_fini(struct crapi_digest_ctx *ctx, crapi_alg_t alg)

Check warning on line 391 in src/OVAL/probes/crapi/digest.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused parameter "alg", make it unnamed, or declare it "[[maybe_unused]]".

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AZyzw4KNB3W2cI3o4ZKY&open=AZyzw4KNB3W2cI3o4ZKY&pullRequest=2319
{
#if defined(HAVE_NSS3)
unsigned int result_len;
Expand All @@ -264,6 +403,15 @@
buffer = (void *)gcry_md_read(ctx->ctx, lib_alg);
memcpy(ctx->dst, buffer, gcry_md_get_algo_dlen(lib_alg));
gcry_md_close(ctx->ctx);
#elif defined(HAVE_OPENSSL_CRYPTO)
unsigned int md_len = (unsigned int)*ctx->size;
if (EVP_DigestFinal_ex(ctx->ctx, (unsigned char *)ctx->dst, &md_len) != 1) {
EVP_MD_CTX_free(ctx->ctx);
free(ctx);
return -1;
}
*ctx->size = (size_t)md_len;
EVP_MD_CTX_free(ctx->ctx);
#endif
free (ctx);

Expand All @@ -275,6 +423,9 @@
#if defined(HAVE_NSS3)
HASH_Destroy(ctx->ctx);
free(ctx);
#elif defined(HAVE_OPENSSL_CRYPTO)
EVP_MD_CTX_free(ctx->ctx);
free(ctx);
#endif
return;
}
Expand Down
Loading