tree-wide: Load libcrypto and libssl via dlopen()

Until now OpenSSL was linked into every binary and library that needed
cryptography, pulling libcrypto (and, for resolved, libssl) into the
address space of services that never touch them at runtime. This commit
moves all OpenSSL usage behind the same dlopen helper pattern that we
already use for other optional libraries (libpam, libseccomp, libxz, …)
so libcrypto/libssl are only loaded on demand.

The bulk of the work lives in src/shared/crypto-util.{c,h} (libcrypto)
and src/shared/ssl-util.{c,h} (libssl), which replace the previous
src/shared/openssl-util.{c,h}:

 - crypto-util.{c,h} declares every libcrypto function we call via
   DLSYM_PROTOTYPE() and resolves them inside dlopen_libcrypto().

 - ssl-util.{c,h} holds the libssl-specific DLSYM_PROTOTYPEs,
   dlopen_libssl(), and the SSL_freep cleanup helper, so translation
   units that only need libcrypto do not pull in libssl declarations.

 - Callers refer to the symbols through sym_* aliases rather than the
   original names.

 - Convenience macros that used to be provided by the OpenSSL headers
   (OPENSSL_free, BN_num_bytes, the sk_TYPE_* helpers, …) are
   reimplemented as sym_* wrappers so no code path needs to fall back
   to the linker-resolved symbols.

 - All _cleanup_ helpers are redefined in terms of the sym_* variants
   (EVP_PKEY_freep, X509_freep, BIO_freep, …) so cleanup attributes
   keep working without pulling in libcrypto symbols at link time.

 - The public crypto-util.c entry points (openssl_pubkey_from_pem,
   openssl_digest_many, openssl_hmac_many, openssl_cipher_many,
   kdf_ss_derive, kdf_kb_hmac_derive, rsa_* / ecc_* helpers,
   pubkey_fingerprint, digest_and_sign, pkcs7_new, x509_fingerprint,
   openssl_extract_public_key, pkey_generate_volume_keys, the load_*
   helpers, …) now call dlopen_libcrypto() at entry before touching any
   sym_* pointer.

The call sites across the tree have been converted to call
dlopen_libcrypto()/dlopen_libssl() at the appropriate entry point
before their first sym_* use, and to use sym_* variants throughout:

 - bootctl, sbsign, measure, pcrlock, pcrextend, tpm2-setup, repart,
   cryptsetup, cryptenroll, homectl, homed, homework, keyutil,
   sysupdate, creds, import, dissect-image, pe-binary, pkcs11-util,
   pkcs7-util, tpm2-util, creds-util. resolved additionally dlopens
   libssl for DoT.

The meson build files are updated to depend on libopenssl_cflags (a
new partial dependency that exposes include paths and compile flags
only, not the linker flags) instead of libopenssl for every target that
previously linked against OpenSSL. Nothing links against libcrypto or
libssl directly anymore.

A new src/sbsign/authenticode.c hosts the Authenticode ASN.1 type
definitions that used to live inline in sbsign.c. The OpenSSL
ASN1_SEQUENCE / ASN1_CHOICE / IMPLEMENT_ASN1_FUNCTIONS macros expand to
code that references libcrypto symbols directly, so to keep this
translation unit unlinked from libcrypto we redirect ASN1_item_* to
the sym_* variants via #define and wrap the ASN1_*_it() getters (which
appear as constant function pointers in static initializers) in small
trampoline functions that forward to the sym_* pointers at runtime.

test-dlopen-so gains assertions for dlopen_libcrypto and dlopen_libssl
so the dlopen contract is exercised in CI, and the openssl-specific
test was renamed from test-openssl.c to test-crypto-util.c to match
the new header naming.
This commit is contained in:
Daan De Meyer
2026-04-24 06:32:42 +02:00
committed by Daan De Meyer
parent bbadd35596
commit 8c3f64e61f
70 changed files with 2396 additions and 1064 deletions
+1
View File
@@ -1258,6 +1258,7 @@ libgnutls_cflags = libgnutls.partial_dependency(includes: true, compile_args: tr
libopenssl = dependency('openssl',
version : '>= 3.0.0',
required : get_option('openssl'))
libopenssl_cflags = libopenssl.partial_dependency(includes: true, compile_args: true)
conf.set10('HAVE_OPENSSL', libopenssl.found())
libp11kit = dependency('p11-kit-1',
+10
View File
@@ -69,6 +69,15 @@ struct fdisk_context;
struct fdisk_table;
struct crypt_device;
typedef struct buf_mem_st BUF_MEM;
typedef struct evp_pkey_st EVP_PKEY;
typedef struct evp_md_st EVP_MD;
typedef struct evp_md_ctx_st EVP_MD_CTX;
typedef struct ssl_st SSL;
typedef struct ssl_ctx_st SSL_CTX;
typedef struct ssl_session_st SSL_SESSION;
typedef struct x509_st X509;
/* basic/ forward declarations */
typedef void (*hash_func_t)(const void *p, struct siphash *state);
@@ -111,6 +120,7 @@ typedef struct Set Set;
typedef struct dual_timestamp dual_timestamp;
typedef struct triple_timestamp triple_timestamp;
typedef struct Compressor Compressor;
typedef struct ConfFile ConfFile;
typedef struct LockFile LockFile;
typedef struct PidRef PidRef;
+20 -15
View File
@@ -7,6 +7,7 @@
#include "sd-varlink.h"
#include "alloc-util.h"
#include "ask-password-api.h"
#include "blockdev-util.h"
#include "boot-entry.h"
#include "bootctl.h"
@@ -15,6 +16,7 @@
#include "bootctl-util.h"
#include "chase.h"
#include "copy.h"
#include "crypto-util.h"
#include "dirent-util.h"
#include "efi-api.h"
#include "efi-fundamental.h"
@@ -31,7 +33,6 @@
#include "json-util.h"
#include "kernel-config.h"
#include "log.h"
#include "openssl-util.h"
#include "parse-argument.h"
#include "path-util.h"
#include "pe-binary.h"
@@ -117,11 +118,11 @@ static void install_context_done(InstallContext *c) {
c->xbootldr_fd = safe_close(c->xbootldr_fd);
#if HAVE_OPENSSL
if (c->secure_boot_private_key) {
EVP_PKEY_free(c->secure_boot_private_key);
sym_EVP_PKEY_free(c->secure_boot_private_key);
c->secure_boot_private_key = NULL;
}
if (c->secure_boot_certificate) {
X509_free(c->secure_boot_certificate);
sym_X509_free(c->secure_boot_certificate);
c->secure_boot_certificate = NULL;
}
#endif
@@ -1035,12 +1036,16 @@ static int install_secure_boot_auto_enroll(InstallContext *c) {
if (!c->secure_boot_certificate || !c->secure_boot_private_key)
return 0;
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
_cleanup_free_ uint8_t *dercert = NULL;
int dercertsz;
dercertsz = i2d_X509(c->secure_boot_certificate, &dercert);
dercertsz = sym_i2d_X509(c->secure_boot_certificate, &dercert);
if (dercertsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert X.509 certificate to DER: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (c->esp_fd < 0)
return c->esp_fd;
@@ -1087,7 +1092,7 @@ static int install_secure_boot_auto_enroll(InstallContext *c) {
FOREACH_STRING(db, "PK", "KEK", "db") {
_cleanup_(BIO_freep) BIO *bio = NULL;
bio = BIO_new(BIO_s_mem());
bio = sym_BIO_new(sym_BIO_s_mem());
if (!bio)
return log_oom();
@@ -1096,34 +1101,34 @@ static int install_secure_boot_auto_enroll(InstallContext *c) {
return log_oom();
/* Don't count the trailing NUL terminator. */
if (BIO_write(bio, db16, char16_strsize(db16) - sizeof(char16_t)) < 0)
if (sym_BIO_write(bio, db16, char16_strsize(db16) - sizeof(char16_t)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable name to bio");
EFI_GUID *guid = STR_IN_SET(db, "PK", "KEK") ? &(EFI_GUID) EFI_GLOBAL_VARIABLE : &(EFI_GUID) EFI_IMAGE_SECURITY_DATABASE_GUID;
if (BIO_write(bio, guid, sizeof(*guid)) < 0)
if (sym_BIO_write(bio, guid, sizeof(*guid)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable GUID to bio");
if (BIO_write(bio, &attrs, sizeof(attrs)) < 0)
if (sym_BIO_write(bio, &attrs, sizeof(attrs)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable attributes to bio");
if (BIO_write(bio, &timestamp, sizeof(timestamp)) < 0)
if (sym_BIO_write(bio, &timestamp, sizeof(timestamp)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write timestamp to bio");
if (BIO_write(bio, siglist, siglistsz) < 0)
if (sym_BIO_write(bio, siglist, siglistsz) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write signature list to bio");
_cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
p7 = PKCS7_sign(c->secure_boot_certificate, c->secure_boot_private_key, /* certs= */ NULL, bio, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY|PKCS7_NOSMIMECAP);
p7 = sym_PKCS7_sign(c->secure_boot_certificate, c->secure_boot_private_key, /* certs= */ NULL, bio, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY|PKCS7_NOSMIMECAP);
if (!p7)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to calculate PKCS7 signature: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
_cleanup_free_ uint8_t *sig = NULL;
int sigsz = i2d_PKCS7(p7, &sig);
int sigsz = sym_i2d_PKCS7(p7, &sig);
if (sigsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
size_t authsz = offsetof(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo.CertData) + sigsz;
_cleanup_free_ EFI_VARIABLE_AUTHENTICATION_2 *auth = malloc(authsz);
+1 -1
View File
@@ -17,6 +17,7 @@
#include "bootctl-unlink.h"
#include "bootctl-util.h"
#include "build.h"
#include "crypto-util.h"
#include "devnum-util.h"
#include "dissect-image.h"
#include "efi-loader.h"
@@ -30,7 +31,6 @@
#include "loop-util.h"
#include "main-func.h"
#include "mount-util.h"
#include "openssl-util.h"
#include "options.h"
#include "pager.h"
#include "parse-argument.h"
+1 -1
View File
@@ -23,6 +23,6 @@ executables += [
],
'sources' : bootctl_sources,
'link_with' : boot_link_with,
'dependencies' : [libopenssl],
'dependencies' : [libopenssl_cflags],
},
]
+1 -1
View File
@@ -11,7 +11,7 @@ executables += [
'sources' : files('creds.c'),
'dependencies' : [
libmount_cflags,
libopenssl,
libopenssl_cflags,
threads,
],
},
+1 -1
View File
@@ -2,10 +2,10 @@
#include "alloc-util.h"
#include "cryptenroll-pkcs11.h"
#include "crypto-util.h"
#include "cryptsetup-util.h"
#include "hexdecoct.h"
#include "json-util.h"
#include "openssl-util.h"
#include "pkcs11-util.h"
#if HAVE_P11KIT && HAVE_OPENSSL
+1 -1
View File
@@ -24,7 +24,7 @@ executables += [
libcryptsetup_cflags,
libdl,
libfido2_cflags,
libopenssl,
libopenssl_cflags,
libp11kit_cflags,
],
},
+7 -2
View File
@@ -12,6 +12,7 @@
#include "alloc-util.h"
#include "ask-password-api.h"
#include "build.h"
#include "crypto-util.h"
#include "cryptsetup-fido2.h"
#include "cryptsetup-keyfile.h"
#include "cryptsetup-pkcs11.h"
@@ -537,6 +538,10 @@ static int parse_one_option(const char *option) {
#if HAVE_OPENSSL
_cleanup_strv_free_ char **l = NULL;
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
l = strv_split(val, ":");
if (!l)
return log_oom();
@@ -544,11 +549,11 @@ static int parse_one_option(const char *option) {
STRV_FOREACH(i, l) {
const EVP_MD *implementation;
implementation = EVP_get_digestbyname(*i);
implementation = sym_EVP_get_digestbyname(*i);
if (!implementation)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", val);
if (strv_extend(&arg_tpm2_measure_banks, EVP_MD_name(implementation)) < 0)
if (strv_extend(&arg_tpm2_measure_banks, sym_EVP_MD_get0_name(implementation)) < 0)
return log_oom();
}
#else
+1 -1
View File
@@ -21,7 +21,7 @@ executables += [
libcryptsetup_cflags,
libfido2_cflags,
libmount_cflags,
libopenssl,
libopenssl_cflags,
libp11kit_cflags,
],
},
+1 -1
View File
@@ -2,12 +2,12 @@
#include "sd-json.h"
#include "crypto-util.h"
#include "errno-util.h"
#include "hexdecoct.h"
#include "homectl-pkcs11.h"
#include "libcrypt-util.h"
#include "log.h"
#include "openssl-util.h"
#include "pkcs11-util.h"
#include "string-util.h"
#include "strv.h"
+6 -2
View File
@@ -18,6 +18,7 @@
#include "cgroup-util.h"
#include "chase.h"
#include "creds-util.h"
#include "crypto-util.h"
#include "dirent-util.h"
#include "dns-domain.h"
#include "env-util.h"
@@ -39,7 +40,6 @@
#include "libfido2-util.h"
#include "locale-util.h"
#include "main-func.h"
#include "openssl-util.h"
#include "pager.h"
#include "parse-argument.h"
#include "parse-util.h"
@@ -5316,13 +5316,17 @@ static int verb_list_signing_keys(int argc, char *argv[], uintptr_t _data, void
/* Let's decode the PEM key to DER (so that we lose prefix/suffix), then truncate it
* for display reasons. */
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
_cleanup_(EVP_PKEY_freep) EVP_PKEY *key = NULL;
r = openssl_pubkey_from_pem(pem, SIZE_MAX, &key);
if (r < 0)
return log_error_errno(r, "Failed to parse PEM: %m");
_cleanup_free_ void *der = NULL;
int n = i2d_PUBKEY(key, (unsigned char**) &der);
int n = sym_i2d_PUBKEY(key, (unsigned char**) &der);
if (n < 0)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to encode key as DER.");
+3 -3
View File
@@ -12,6 +12,7 @@
#include "bus-message-util.h"
#include "bus-object.h"
#include "bus-polkit.h"
#include "crypto-util.h"
#include "fileio.h"
#include "format-util.h"
#include "home-util.h"
@@ -22,7 +23,6 @@
#include "homed-manager-bus.h"
#include "homed-operation.h"
#include "log.h"
#include "openssl-util.h"
#include "path-util.h"
#include "set.h"
#include "string-util.h"
@@ -936,14 +936,14 @@ static bool manager_has_public_key(Manager *m, EVP_PKEY *needle) {
EVP_PKEY *pkey;
HASHMAP_FOREACH(pkey, m->public_keys) {
r = EVP_PKEY_eq(pkey, needle);
r = sym_EVP_PKEY_eq(pkey, needle);
if (r > 0)
return true;
/* EVP_PKEY_eq() returns -1 and -2 too under some conditions, which we'll all treat as "not the same" */
}
r = EVP_PKEY_eq(m->private_key, needle);
r = sym_EVP_PKEY_eq(m->private_key, needle);
if (r > 0)
return true;
+17 -13
View File
@@ -4,7 +4,6 @@
#include <linux/fscrypt.h>
#include <linux/magic.h>
#include <math.h>
#include <openssl/pem.h>
#include <pwd.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
@@ -25,6 +24,7 @@
#include "clean-ipc.h"
#include "common-signal.h"
#include "conf-files.h"
#include "crypto-util.h"
#include "device-util.h"
#include "dirent-util.h"
#include "errno-util.h"
@@ -43,7 +43,6 @@
#include "homed-varlink.h"
#include "mkdir.h"
#include "notify-recv.h"
#include "openssl-util.h"
#include "ordered-set.h"
#include "quota-util.h"
#include "random-util.h"
@@ -313,7 +312,7 @@ Manager* manager_free(Manager *m) {
m->homes_by_sysfs = hashmap_free(m->homes_by_sysfs);
if (m->private_key)
EVP_PKEY_free(m->private_key);
sym_EVP_PKEY_free(m->private_key);
hashmap_free(m->public_keys);
@@ -1317,7 +1316,7 @@ static int manager_load_key_pair(Manager *m) {
assert(m);
if (m->private_key) {
EVP_PKEY_free(m->private_key);
sym_EVP_PKEY_free(m->private_key);
m->private_key = NULL;
}
@@ -1337,7 +1336,7 @@ static int manager_load_key_pair(Manager *m) {
if (st.st_uid != 0 || (st.st_mode & 0077) != 0)
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Private key file is readable by more than the root user");
m->private_key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
m->private_key = sym_PEM_read_PrivateKey(f, NULL, NULL, NULL);
if (!m->private_key)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to load private key pair");
@@ -1353,20 +1352,20 @@ static int manager_generate_key_pair(Manager *m) {
int r;
if (m->private_key) {
EVP_PKEY_free(m->private_key);
sym_EVP_PKEY_free(m->private_key);
m->private_key = NULL;
}
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
ctx = sym_EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
if (!ctx)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate Ed25519 key generation context.");
if (EVP_PKEY_keygen_init(ctx) <= 0)
if (sym_EVP_PKEY_keygen_init(ctx) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize Ed25519 key generation context.");
log_info("Generating key pair for signing local user identity records.");
if (EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
if (sym_EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate Ed25519 key pair");
log_info("Successfully created Ed25519 key pair.");
@@ -1378,7 +1377,7 @@ static int manager_generate_key_pair(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to open key file for writing: %m");
if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
if (sym_PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
(void) fchmod(fileno(fpublic), 0444); /* Make public key world readable */
@@ -1394,7 +1393,7 @@ static int manager_generate_key_pair(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to open key file for writing: %m");
if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, NULL) <= 0)
if (sym_PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, NULL) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
(void) fchmod(fileno(fprivate), 0400); /* Make private key root readable */
@@ -1459,7 +1458,8 @@ int manager_sign_user_record(Manager *m, UserRecord *u, UserRecord **ret, sd_bus
return user_record_sign(u, m->private_key, ret);
}
DEFINE_HASH_OPS_FULL(public_key_hash_ops, char, string_hash_func, string_compare_func, free, EVP_PKEY, EVP_PKEY_free);
/* dlopen_libcrypto() must have been called before populating this hashmap. */
DEFINE_HASH_OPS_FULL(public_key_hash_ops, char, string_hash_func, string_compare_func, free, EVP_PKEY, sym_EVP_PKEY_free);
static int manager_load_public_key_one(Manager *m, const char *path) {
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
@@ -1495,7 +1495,7 @@ static int manager_load_public_key_one(Manager *m, const char *path) {
if (st.st_uid != 0 || (st.st_mode & 0022) != 0)
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Public key file %s is writable by more than the root user, refusing.", path);
pkey = PEM_read_PUBKEY(f, &pkey, NULL, NULL);
pkey = sym_PEM_read_PUBKEY(f, &pkey, NULL, NULL);
if (!pkey)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key file %s.", path);
@@ -1537,6 +1537,10 @@ int manager_startup(Manager *m) {
assert(m);
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
r = manager_listen_notify(m);
if (r < 0)
return r;
-2
View File
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <openssl/evp.h>
#include "homed-forward.h"
#include "user-record.h"
+33 -23
View File
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/fscrypt.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
@@ -10,6 +8,7 @@
#include <unistd.h>
#include "alloc-util.h"
#include "crypto-util.h"
#include "errno-util.h"
#include "fd-util.h"
#include "format-util.h"
@@ -25,7 +24,6 @@
#include "mkdir.h"
#include "mount-util.h"
#include "nulstr-util.h"
#include "openssl-util.h"
#include "parse-util.h"
#include "process-util.h"
#include "random-util.h"
@@ -180,8 +178,8 @@ static void calculate_key_descriptor(
/* Derive the key descriptor from the volume key via double SHA512, in order to be compatible with e4crypt */
assert_se(SHA512(key, key_size, hashed) == hashed);
assert_se(SHA512(hashed, sizeof(hashed), hashed2) == hashed2);
assert_se(sym_SHA512(key, key_size, hashed) == hashed);
assert_se(sym_SHA512(hashed, sizeof(hashed), hashed2) == hashed2);
assert_cc(sizeof(hashed2) >= FS_KEY_DESCRIPTOR_SIZE);
@@ -211,6 +209,10 @@ static int fscrypt_slot_try_one(
assert(encrypted_size > 0);
assert(match_key_descriptor);
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
/* Our construction is like this:
*
* 1. In each key slot we store a salt value plus the encrypted volume key
@@ -226,37 +228,37 @@ static int fscrypt_slot_try_one(
CLEANUP_ERASE(derived);
if (PKCS5_PBKDF2_HMAC(
if (sym_PKCS5_PBKDF2_HMAC(
password, strlen(password),
salt, salt_size,
0xFFFF, EVP_sha512(),
0xFFFF, sym_EVP_sha512(),
sizeof(derived), derived) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed.");
context = EVP_CIPHER_CTX_new();
context = sym_EVP_CIPHER_CTX_new();
if (!context)
return log_oom();
/* We use AES256 in counter mode */
assert_se(cc = EVP_aes_256_ctr());
assert_se(cc = sym_EVP_aes_256_ctr());
/* We only use the first half of the derived key */
assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
assert(sizeof(derived) >= (size_t) sym_EVP_CIPHER_get_key_length(cc));
if (EVP_DecryptInit_ex(context, cc, NULL, derived, NULL) != 1)
if (sym_EVP_DecryptInit_ex(context, cc, NULL, derived, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context.");
decrypted_size = encrypted_size + EVP_CIPHER_key_length(cc) * 2;
decrypted_size = encrypted_size + sym_EVP_CIPHER_get_key_length(cc) * 2;
decrypted = malloc(decrypted_size);
if (!decrypted)
return log_oom();
if (EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
if (sym_EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to decrypt volume key.");
assert((size_t) decrypted_size_out1 <= decrypted_size);
if (EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
if (sym_EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish decryption of volume key.");
assert((size_t) decrypted_size_out1 + (size_t) decrypted_size_out2 < decrypted_size);
@@ -484,43 +486,47 @@ static int fscrypt_slot_set(
size_t encrypted_size;
ssize_t ss;
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
r = crypto_random_bytes(salt, sizeof(salt));
if (r < 0)
return log_error_errno(r, "Failed to generate salt: %m");
CLEANUP_ERASE(derived);
if (PKCS5_PBKDF2_HMAC(
if (sym_PKCS5_PBKDF2_HMAC(
password, strlen(password),
salt, sizeof(salt),
0xFFFF, EVP_sha512(),
0xFFFF, sym_EVP_sha512(),
sizeof(derived), derived) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed");
context = EVP_CIPHER_CTX_new();
context = sym_EVP_CIPHER_CTX_new();
if (!context)
return log_oom();
/* We use AES256 in counter mode */
cc = EVP_aes_256_ctr();
cc = sym_EVP_aes_256_ctr();
/* We only use the first half of the derived key */
assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
assert(sizeof(derived) >= (size_t) sym_EVP_CIPHER_get_key_length(cc));
if (EVP_EncryptInit_ex(context, cc, NULL, derived, NULL) != 1)
if (sym_EVP_EncryptInit_ex(context, cc, NULL, derived, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context.");
encrypted_size = volume_key_size + EVP_CIPHER_key_length(cc) * 2;
encrypted_size = volume_key_size + sym_EVP_CIPHER_get_key_length(cc) * 2;
encrypted = malloc(encrypted_size);
if (!encrypted)
return log_oom();
if (EVP_EncryptUpdate(context, (uint8_t*) encrypted, &encrypted_size_out1, volume_key, volume_key_size) != 1)
if (sym_EVP_EncryptUpdate(context, (uint8_t*) encrypted, &encrypted_size_out1, volume_key, volume_key_size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt volume key.");
assert((size_t) encrypted_size_out1 <= encrypted_size);
if (EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
if (sym_EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish encryption of volume key.");
assert((size_t) encrypted_size_out1 + (size_t) encrypted_size_out2 < encrypted_size);
@@ -569,6 +575,10 @@ int home_create_fscrypt(
assert(setup);
assert(ret_home);
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
assert_se(ip = user_record_image_path(h));
r = tempfn_random(ip, "homework", &d);
+19 -15
View File
@@ -21,6 +21,7 @@
#include "blockdev-util.h"
#include "btrfs-util.h"
#include "chattr-util.h"
#include "crypto-util.h"
#include "cryptsetup-util.h"
#include "device-util.h"
#include "devnum-util.h"
@@ -48,7 +49,6 @@
#include "memory-util.h"
#include "mkdir.h"
#include "mkfs-util.h"
#include "openssl-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "pidref.h"
@@ -805,6 +805,10 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
assert(cd);
assert(ret);
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
/* Let's find the right OpenSSL EVP_CIPHER object that matches the encryption settings of the LUKS
* device */
@@ -832,12 +836,12 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
if (asprintf(&cipher_name, "%s-%zu-%s", cipher, key_bits, cipher_mode) < 0)
return log_oom();
cc = EVP_get_cipherbyname(cipher_name);
cc = sym_EVP_get_cipherbyname(cipher_name);
if (!cc)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Selected cipher mode '%s' not supported, can't encrypt JSON record.", cipher_name);
/* Verify that our key length calculations match what OpenSSL thinks */
r = EVP_CIPHER_key_length(cc);
r = sym_EVP_CIPHER_get_key_length(cc);
if (r < 0 || (uint64_t) r != key_size)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Key size of selected cipher doesn't meet our expectations.");
@@ -909,27 +913,27 @@ static int luks_validate_home_record(
r = crypt_device_to_evp_cipher(cd, &cc);
if (r < 0)
return r;
if (iv_size > INT_MAX || EVP_CIPHER_iv_length(cc) != (int) iv_size)
if (iv_size > INT_MAX || sym_EVP_CIPHER_get_iv_length(cc) != (int) iv_size)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "IV size doesn't match.");
context = EVP_CIPHER_CTX_new();
context = sym_EVP_CIPHER_CTX_new();
if (!context)
return log_oom();
if (EVP_DecryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
if (sym_EVP_DecryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context.");
decrypted_size = encrypted_size + EVP_CIPHER_key_length(cc) * 2;
decrypted_size = encrypted_size + sym_EVP_CIPHER_get_key_length(cc) * 2;
decrypted = new(char, decrypted_size);
if (!decrypted)
return log_oom();
if (EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
if (sym_EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to decrypt JSON record.");
assert((size_t) decrypted_size_out1 <= decrypted_size);
if (EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
if (sym_EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish decryption of JSON record.");
assert((size_t) decrypted_size_out1 + (size_t) decrypted_size_out2 < decrypted_size);
@@ -990,8 +994,8 @@ static int format_luks_token_text(
if (r < 0)
return r;
key_size = EVP_CIPHER_key_length(cc);
iv_size = EVP_CIPHER_iv_length(cc);
key_size = sym_EVP_CIPHER_get_key_length(cc);
iv_size = sym_EVP_CIPHER_get_iv_length(cc);
if (iv_size > 0) {
iv = malloc(iv_size);
@@ -1003,11 +1007,11 @@ static int format_luks_token_text(
return log_error_errno(r, "Failed to generate IV: %m");
}
context = EVP_CIPHER_CTX_new();
context = sym_EVP_CIPHER_CTX_new();
if (!context)
return log_oom();
if (EVP_EncryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
if (sym_EVP_EncryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context.");
r = sd_json_variant_format(hr->json, 0, &text);
@@ -1021,12 +1025,12 @@ static int format_luks_token_text(
if (!encrypted)
return log_oom();
if (EVP_EncryptUpdate(context, encrypted, &encrypted_size_out1, (uint8_t*) text, text_length) != 1)
if (sym_EVP_EncryptUpdate(context, encrypted, &encrypted_size_out1, (uint8_t*) text, text_length) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt JSON record.");
assert((size_t) encrypted_size_out1 <= encrypted_size);
if (EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
if (sym_EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish encryption of JSON record.");
assert((size_t) encrypted_size_out1 + (size_t) encrypted_size_out2 <= encrypted_size);
+3 -3
View File
@@ -65,7 +65,7 @@ executables += [
'extract' : systemd_homed_extract_sources,
'dependencies' : [
libm,
libopenssl,
libopenssl_cflags,
threads,
],
},
@@ -76,7 +76,7 @@ executables += [
'dependencies' : [
libblkid_cflags,
libfdisk_cflags,
libopenssl,
libopenssl_cflags,
libp11kit_cflags,
threads,
],
@@ -88,7 +88,7 @@ executables += [
'objects' : ['systemd-homed'],
'dependencies' : [
libdl,
libopenssl,
libopenssl_cflags,
libp11kit_cflags,
threads,
],
+4 -4
View File
@@ -1,9 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "crypto-util.h"
#include "json-util.h"
#include "log.h"
#include "openssl-util.h"
#include "user-record-sign.h"
#include "user-record.h"
@@ -118,14 +118,14 @@ int user_record_verify(UserRecord *ur, EVP_PKEY *public_key) {
if (r < 0)
return r;
md_ctx = EVP_MD_CTX_new();
md_ctx = sym_EVP_MD_CTX_new();
if (!md_ctx)
return -ENOMEM;
if (EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, public_key) <= 0)
if (sym_EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, public_key) <= 0)
return -EIO;
if (EVP_DigestVerify(md_ctx, signature, signature_size, (uint8_t*) text, strlen(text)) <= 0) {
if (sym_EVP_DigestVerify(md_ctx, signature, signature_size, (uint8_t*) text, strlen(text)) <= 0) {
n_bad++;
continue;
}
-2
View File
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <openssl/evp.h>
#include "shared-forward.h"
int user_record_sign(UserRecord *ur, EVP_PKEY *private_key, UserRecord **ret);
+1 -1
View File
@@ -31,7 +31,7 @@ executables += [
'pull-tar.c',
),
'objects' : ['systemd-importd'],
'dependencies' : libopenssl,
'dependencies' : libopenssl_cflags,
},
libexec_template + {
'name' : 'systemd-import',
+1
View File
@@ -10,6 +10,7 @@
#include "fd-util.h"
#include "hexdecoct.h"
#include "io-util.h"
#include "iovec-util.h"
#include "log.h"
#include "memory-util.h"
#include "os-util.h"
+13 -7
View File
@@ -6,6 +6,8 @@
#include <unistd.h>
#include "alloc-util.h"
#include "compress.h"
#include "crypto-util.h"
#include "curl-util.h"
#include "fd-util.h"
#include "format-util.h"
@@ -57,7 +59,7 @@ PullJob* pull_job_unref(PullJob *j) {
j->compress = compressor_free(j->compress);
if (j->checksum_ctx)
EVP_MD_CTX_free(j->checksum_ctx);
sym_EVP_MD_CTX_free(j->checksum_ctx);
free(j->url);
free(j->etag);
@@ -138,7 +140,7 @@ int pull_job_restart(PullJob *j, const char *new_url) {
j->compress = compressor_free(j->compress);
if (j->checksum_ctx) {
EVP_MD_CTX_free(j->checksum_ctx);
sym_EVP_MD_CTX_free(j->checksum_ctx);
j->checksum_ctx = NULL;
}
@@ -279,7 +281,7 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
goto finish;
}
r = EVP_DigestFinal_ex(j->checksum_ctx, j->checksum.iov_base, &checksum_len);
r = sym_EVP_DigestFinal_ex(j->checksum_ctx, j->checksum.iov_base, &checksum_len);
if (r == 0) {
r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get checksum.");
goto finish;
@@ -294,7 +296,7 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
goto finish;
}
log_debug("%s of %s is %s.", EVP_MD_CTX_get0_name(j->checksum_ctx), pull_job_description(j), h);
log_debug("%s of %s is %s.", sym_EVP_MD_CTX_get0_name(j->checksum_ctx), pull_job_description(j), h);
}
if (iovec_is_set(&j->expected_checksum) &&
@@ -448,7 +450,7 @@ static int pull_job_write_compressed(PullJob *j, const struct iovec *data) {
"Content length incorrect.");
if (j->checksum_ctx) {
r = EVP_DigestUpdate(j->checksum_ctx, data->iov_base, data->iov_len);
r = sym_EVP_DigestUpdate(j->checksum_ctx, data->iov_base, data->iov_len);
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Could not hash chunk.");
@@ -485,11 +487,15 @@ static int pull_job_open_disk(PullJob *j) {
}
if (j->calc_checksum) {
j->checksum_ctx = EVP_MD_CTX_new();
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
j->checksum_ctx = sym_EVP_MD_CTX_new();
if (!j->checksum_ctx)
return log_oom();
r = EVP_DigestInit_ex(j->checksum_ctx, EVP_sha256(), NULL);
r = sym_EVP_DigestInit_ex(j->checksum_ctx, sym_EVP_sha256(), NULL);
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to initialize hash context.");
+1 -2
View File
@@ -3,9 +3,8 @@
#include <curl/curl.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include "compress.h"
#include "openssl-util.h"
#include "shared-forward.h"
typedef struct CurlGlue CurlGlue;
+1
View File
@@ -31,6 +31,7 @@
#include "pull-oci.h"
#include "rm-rf.h"
#include "set.h"
#include "sha256-fundamental.h"
#include "signal-util.h"
#include "stat-util.h"
#include "string-util.h"
+1
View File
@@ -13,6 +13,7 @@
#include "import-common.h"
#include "import-util.h"
#include "install-file.h"
#include "iovec-util.h"
#include "log.h"
#include "mkdir-label.h"
#include "pull-common.h"
+15 -11
View File
@@ -3,13 +3,13 @@
#include "alloc-util.h"
#include "ask-password-api.h"
#include "build.h"
#include "crypto-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-table.h"
#include "fs-util.h"
#include "log.h"
#include "main-func.h"
#include "openssl-util.h"
#include "options.h"
#include "parse-argument.h"
#include "pretty-print.h"
@@ -240,6 +240,10 @@ static int verb_extract_public(int argc, char *argv[], uintptr_t _data, void *us
return r;
}
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
r = openssl_load_x509_certificate(
arg_certificate_source_type,
arg_certificate_source,
@@ -248,7 +252,7 @@ static int verb_extract_public(int argc, char *argv[], uintptr_t _data, void *us
if (r < 0)
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
public_key = X509_get_pubkey(certificate);
public_key = sym_X509_get_pubkey(certificate);
if (!public_key)
return log_error_errno(
SYNTHETIC_ERRNO(EIO),
@@ -288,7 +292,7 @@ static int verb_extract_public(int argc, char *argv[], uintptr_t _data, void *us
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --certificate=, or --private-key= must be specified");
if (PEM_write_PUBKEY(stdout, public_key) == 0)
if (sym_PEM_write_PUBKEY(stdout, public_key) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key to stdout");
return 0;
@@ -317,7 +321,7 @@ static int verb_extract_certificate(int argc, char *argv[], uintptr_t _data, voi
if (r < 0)
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
if (PEM_write_X509(stdout, certificate) == 0)
if (sym_PEM_write_X509(stdout, certificate) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write certificate to stdout.");
return 0;
@@ -376,18 +380,18 @@ static int verb_pkcs7(int argc, char *argv[], uintptr_t _data, void *userdata) {
if (content_len == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Content file %s is empty", arg_content);
if (!PKCS7_content_new(pkcs7, NID_pkcs7_data))
if (!sym_PKCS7_content_new(pkcs7, NID_pkcs7_data))
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Error creating new PKCS7 content field");
ASN1_STRING_set0(pkcs7->d.sign->contents->d.data, TAKE_PTR(content), content_len);
sym_ASN1_STRING_set0(pkcs7->d.sign->contents->d.data, TAKE_PTR(content), content_len);
} else
if (PKCS7_set_detached(pkcs7, true) == 0)
if (sym_PKCS7_set_detached(pkcs7, true) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to set PKCS#7 detached attribute: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
/* Add PKCS1 signature to PKCS7_SIGNER_INFO */
ASN1_STRING_set0(signer_info->enc_digest, TAKE_PTR(pkcs1), pkcs1_len);
sym_ASN1_STRING_set0(signer_info->enc_digest, TAKE_PTR(pkcs1), pkcs1_len);
_cleanup_fclose_ FILE *output = NULL;
_cleanup_(unlink_and_freep) char *tmp = NULL;
@@ -395,9 +399,9 @@ static int verb_pkcs7(int argc, char *argv[], uintptr_t _data, void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to open temporary file: %m");
if (!i2d_PKCS7_fp(output, pkcs7))
if (!sym_i2d_PKCS7_fp(output, pkcs7))
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write PKCS#7 file: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
r = flink_tmpfile(output, tmp, arg_output, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
if (r < 0)
+1 -1
View File
@@ -7,6 +7,6 @@ executables += [
'HAVE_OPENSSL',
],
'sources' : files('keyutil.c'),
'dependencies' : libopenssl,
'dependencies' : libopenssl_cflags,
},
]
+34 -26
View File
@@ -7,6 +7,7 @@
#include "alloc-util.h"
#include "ask-password-api.h"
#include "build.h"
#include "crypto-util.h"
#include "efi-loader.h"
#include "efivars.h"
#include "fd-util.h"
@@ -15,7 +16,6 @@
#include "hexdecoct.h"
#include "log.h"
#include "main-func.h"
#include "openssl-util.h"
#include "options.h"
#include "pager.h"
#include "parse-argument.h"
@@ -178,11 +178,15 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
"Select TPM bank (SHA1, SHA256, SHA384, SHA512)"): {
const EVP_MD *implementation;
implementation = EVP_get_digestbyname(arg);
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
implementation = sym_EVP_get_digestbyname(arg);
if (!implementation)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", arg);
if (strv_extend(&arg_banks, EVP_MD_name(implementation)) < 0)
if (strv_extend(&arg_banks, sym_EVP_MD_get0_name(implementation)) < 0)
return log_oom();
break;
@@ -529,7 +533,7 @@ static void evp_md_ctx_free_all(EVP_MD_CTX **md[]) {
return;
for (size_t i = 0; (*md)[i]; i++)
EVP_MD_CTX_free((*md)[i]);
sym_EVP_MD_CTX_free((*md)[i]);
*md = mfree(*md);
}
@@ -546,22 +550,22 @@ static int pcr_state_extend(PcrState *pcr_state, const void *data, size_t sz) {
/* Extends a (virtual) PCR by the given data */
mc = EVP_MD_CTX_new();
mc = sym_EVP_MD_CTX_new();
if (!mc)
return log_oom();
if (EVP_DigestInit_ex(mc, pcr_state->md, NULL) != 1)
if (sym_EVP_DigestInit_ex(mc, pcr_state->md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize %s context.", pcr_state->bank);
/* First thing we do, is hash the old PCR value */
if (EVP_DigestUpdate(mc, pcr_state->value, pcr_state->value_size) != 1)
if (sym_EVP_DigestUpdate(mc, pcr_state->value, pcr_state->value_size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
/* Then, we hash the new data */
if (EVP_DigestUpdate(mc, data, sz) != 1)
if (sym_EVP_DigestUpdate(mc, data, sz) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
if (EVP_DigestFinal_ex(mc, pcr_state->value, &value_size) != 1)
if (sym_EVP_DigestFinal_ex(mc, pcr_state->value, &value_size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize hash context.");
assert(value_size == pcr_state->value_size);
@@ -629,11 +633,11 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
return log_oom();
for (size_t i = 0; i < n; i++) {
mdctx[i] = EVP_MD_CTX_new();
mdctx[i] = sym_EVP_MD_CTX_new();
if (!mdctx[i])
return log_oom();
if (EVP_DigestInit_ex(mdctx[i], pcr_states[i].md, NULL) != 1)
if (sym_EVP_DigestInit_ex(mdctx[i], pcr_states[i].md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to initialize data %s context.", pcr_states[i].bank);
}
@@ -648,7 +652,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
break;
for (size_t i = 0; i < n; i++)
if (EVP_DigestUpdate(mdctx[i], buffer, sz) != 1)
if (sym_EVP_DigestUpdate(mdctx[i], buffer, sz) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
m += sz;
@@ -668,7 +672,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
return log_oom();
/* Measure name of section */
if (EVP_Digest(unified_sections[c], strlen(unified_sections[c]) + 1, data_hash, &data_hash_size, pcr_states[i].md, NULL) != 1)
if (sym_EVP_Digest(unified_sections[c], strlen(unified_sections[c]) + 1, data_hash, &data_hash_size, pcr_states[i].md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to hash section name with %s.", pcr_states[i].bank);
assert(data_hash_size == (unsigned) pcr_states[i].value_size);
@@ -678,7 +682,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
return r;
/* Retrieve hash of data and measure it */
if (EVP_DigestFinal_ex(mdctx[i], data_hash, &data_hash_size) != 1)
if (sym_EVP_DigestFinal_ex(mdctx[i], data_hash, &data_hash_size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize hash context.");
assert(data_hash_size == (unsigned) pcr_states[i].value_size);
@@ -719,7 +723,7 @@ static int measure_phase(PcrState *pcr_states, size_t n, const char *phase) {
_cleanup_free_ void *b = NULL;
int bsz;
bsz = EVP_MD_size(pcr_states[i].md);
bsz = sym_EVP_MD_get_size(pcr_states[i].md);
assert(bsz > 0);
b = malloc(bsz);
@@ -727,7 +731,7 @@ static int measure_phase(PcrState *pcr_states, size_t n, const char *phase) {
return log_oom();
/* First hash the word itself */
if (EVP_Digest(*word, wl, b, NULL, pcr_states[i].md, NULL) != 1)
if (sym_EVP_Digest(*word, wl, b, NULL, pcr_states[i].md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash word '%s'.", *word);
/* And then extend the PCR with the resulting hash */
@@ -757,13 +761,13 @@ static int pcr_states_allocate(PcrState **ret) {
_cleanup_free_ char *b = NULL;
int sz;
assert_se(implementation = EVP_get_digestbyname(*d)); /* Must work, we already checked while parsing command line */
assert_se(implementation = sym_EVP_get_digestbyname(*d)); /* Must work, we already checked while parsing command line */
b = strdup(EVP_MD_name(implementation));
b = strdup(sym_EVP_MD_get0_name(implementation));
if (!b)
return log_oom();
sz = EVP_MD_size(implementation);
sz = sym_EVP_MD_get_size(implementation);
if (sz <= 0 || sz >= INT_MAX)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected digest size: %i", sz);
@@ -986,11 +990,11 @@ static int build_policy_digest(bool sign) {
if (!pubkeyf)
return log_error_errno(errno, "Failed to open public key file '%s': %m", arg_public_key);
pubkey = PEM_read_PUBKEY(pubkeyf, NULL, NULL, NULL);
pubkey = sym_PEM_read_PUBKEY(pubkeyf, NULL, NULL, NULL);
if (!pubkey)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key '%s'.", arg_public_key);
} else if (certificate) {
pubkey = X509_get_pubkey(certificate);
pubkey = sym_X509_get_pubkey(certificate);
if (!pubkey)
return log_error_errno(
SYNTHETIC_ERRNO(EIO),
@@ -1026,7 +1030,7 @@ static int build_policy_digest(bool sign) {
for (size_t i = 0; i < n; i++) {
PcrState *p = pcr_states + i;
int tpmalg = tpm2_hash_alg_from_string(EVP_MD_name(p->md));
int tpmalg = tpm2_hash_alg_from_string(sym_EVP_MD_get0_name(p->md));
if (tpmalg < 0)
return log_error_errno(tpmalg, "Unsupported PCR bank");
@@ -1044,19 +1048,19 @@ static int build_policy_digest(bool sign) {
size_t ss = 0;
if (privkey) {
/* We always use SHA256 for signing currently. Regardless of the bank. */
const EVP_MD *sha256 = ASSERT_PTR(EVP_get_digestbyname("sha256"));
const EVP_MD *sha256 = ASSERT_PTR(sym_EVP_get_digestbyname("sha256"));
r = digest_and_sign(sha256, privkey, pcr_policy_digest.buffer, pcr_policy_digest.size, &sig, &ss);
if (r == -EADDRNOTAVAIL)
return log_error_errno(r, "Hash algorithm '%s' not available while signing. (Maybe OS security policy disables this algorithm?)", EVP_MD_name(p->md));
return log_error_errno(r, "Hash algorithm '%s' not available while signing. (Maybe OS security policy disables this algorithm?)", sym_EVP_MD_get0_name(p->md));
if (r < 0)
return log_error_errno(r, "Failed to sign PCR policy with hash algorithm '%s': %m", EVP_MD_name(p->md));
return log_error_errno(r, "Failed to sign PCR policy with hash algorithm '%s': %m", sym_EVP_MD_get0_name(p->md));
}
_cleanup_free_ void *pubkey_fp = NULL;
size_t pubkey_fp_size = 0;
if (pubkey) {
r = pubkey_fingerprint(pubkey, EVP_sha256(), &pubkey_fp, &pubkey_fp_size);
r = pubkey_fingerprint(pubkey, sym_EVP_sha256(), &pubkey_fp, &pubkey_fp_size);
if (r < 0)
return r;
}
@@ -1121,6 +1125,10 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
return dispatch_verb_with_args(args, NULL);
}
+1 -1
View File
@@ -9,6 +9,6 @@ executables += [
'HAVE_TPM2',
],
'sources' : files('measure-tool.c'),
'dependencies' : libopenssl,
'dependencies' : libopenssl_cflags,
},
]
+1 -1
View File
@@ -11,7 +11,7 @@ executables += [
],
'sources' : files('pcrextend.c'),
'dependencies' : [
libopenssl,
libopenssl_cflags,
tpm2,
],
},
+7 -2
View File
@@ -6,6 +6,7 @@
#include "alloc-util.h"
#include "build.h"
#include "crypto-util.h"
#include "efi-loader.h"
#include "escape.h"
#include "format-table.h"
@@ -96,11 +97,15 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
OPTION_LONG("bank", "DIGEST", "Select TPM PCR bank (SHA1, SHA256)"): {
const EVP_MD *implementation;
implementation = EVP_get_digestbyname(arg);
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
implementation = sym_EVP_get_digestbyname(arg);
if (!implementation)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", arg);
if (strv_extend(&arg_banks, EVP_MD_name(implementation)) < 0)
if (strv_extend(&arg_banks, sym_EVP_MD_get0_name(implementation)) < 0)
return log_oom();
break;
+1 -1
View File
@@ -13,7 +13,7 @@ executables += [
),
'dependencies' : [
libm,
libopenssl,
libopenssl_cflags,
tpm2,
],
'public' : true,
+3 -4
View File
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <openssl/evp.h>
#include "crypto-util.h"
#include "log.h"
#include "memory-util.h"
#include "pcrlock-firmware.h"
@@ -149,13 +148,13 @@ int validate_firmware_header(
continue;
}
implementation = EVP_get_digestbyname(a);
implementation = sym_EVP_get_digestbyname(a);
if (!implementation) {
log_notice("Event log advertises hash algorithm '%s' we don't implement, can't validate.", a);
continue;
}
if (EVP_MD_size(implementation) != id->digestSizes[i].digestSize)
if (sym_EVP_MD_get_size(implementation) != id->digestSizes[i].digestSize)
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Advertised digest size for '%s' is wrong, refusing.", a);
}
+37 -33
View File
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <openssl/evp.h>
#include <sys/file.h>
#include <unistd.h>
@@ -18,6 +17,7 @@
#include "color-util.h"
#include "conf-files.h"
#include "creds-util.h"
#include "crypto-util.h"
#include "efi-api.h"
#include "efivars.h"
#include "env-util.h"
@@ -1346,7 +1346,7 @@ static int event_log_calculate_pcrs(EventLog *el) {
const char *a;
assert_se(a = tpm2_hash_alg_to_string(el->algorithms[i]));
assert_se(md = EVP_get_digestbyname(a));
assert_se(md = sym_EVP_get_digestbyname(a));
el->mds[i] = md;
}
@@ -1354,7 +1354,7 @@ static int event_log_calculate_pcrs(EventLog *el) {
for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++)
for (size_t i = 0; i < el->n_algorithms; i++) {
EventLogRegisterBank *b = el->registers[pcr].banks + i;
event_log_initial_pcr_state(el, pcr, EVP_MD_size(el->mds[i]), &b->calculated);
event_log_initial_pcr_state(el, pcr, sym_EVP_MD_get_size(el->mds[i]), &b->calculated);
}
FOREACH_ARRAY(rr, el->records, el->n_records) {
@@ -1379,20 +1379,20 @@ static int event_log_calculate_pcrs(EventLog *el) {
reg_b = reg->banks + i;
mc = EVP_MD_CTX_new();
mc = sym_EVP_MD_CTX_new();
if (!mc)
return log_oom();
if (EVP_DigestInit_ex(mc, el->mds[i], NULL) != 1)
if (sym_EVP_DigestInit_ex(mc, el->mds[i], NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize %s message digest context.", n);
if (EVP_DigestUpdate(mc, reg_b->calculated.buffer, reg_b->calculated.size) != 1)
if (sym_EVP_DigestUpdate(mc, reg_b->calculated.buffer, reg_b->calculated.size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
if (EVP_DigestUpdate(mc, rec_b->hash.buffer, rec_b->hash.size) != 1)
if (sym_EVP_DigestUpdate(mc, rec_b->hash.buffer, rec_b->hash.size) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
if (EVP_DigestFinal_ex(mc, reg_b->calculated.buffer, &sz) != 1)
if (sym_EVP_DigestFinal_ex(mc, reg_b->calculated.buffer, &sz) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize hash context.");
assert(sz == reg_b->calculated.size);
@@ -1481,7 +1481,7 @@ static int event_log_record_validate_hash_firmware(
strict = false;
}
int mdsz = EVP_MD_size(md);
int mdsz = sym_EVP_MD_get_size(md);
assert(mdsz > 0);
assert((size_t) mdsz <= sizeof_field(TPM2B_DIGEST, buffer));
@@ -1491,13 +1491,13 @@ static int event_log_record_validate_hash_firmware(
unsigned dsz = mdsz;
if (EVP_Digest(hdata, hsz, payload_hash.buffer, &dsz, md, NULL) != 1)
if (sym_EVP_Digest(hdata, hsz, payload_hash.buffer, &dsz, md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to calculate event payload hash.");
assert(dsz == (unsigned) mdsz);
/* If this didn't match then let's try the alternative format here, if we have one, and check things then. */
if (memcmp_nn(bank->hash.buffer, bank->hash.size, payload_hash.buffer, payload_hash.size) != 0 && hdata_alternative) {
if (EVP_Digest(hdata_alternative, hsz_alternative, payload_hash.buffer, &dsz, md, NULL) != 1)
if (sym_EVP_Digest(hdata_alternative, hsz_alternative, payload_hash.buffer, &dsz, md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to calculate event payload hash.");
assert(dsz == (unsigned) mdsz);
}
@@ -1541,7 +1541,7 @@ static int event_log_record_validate_hash_userspace(
assert(sd_json_variant_is_string(js));
s = sd_json_variant_string(js);
mdsz = EVP_MD_size(md);
mdsz = sym_EVP_MD_get_size(md);
assert(mdsz > 0);
payload_hash_size = mdsz;
@@ -1549,7 +1549,7 @@ static int event_log_record_validate_hash_userspace(
if (!payload_hash)
return log_oom();
if (EVP_Digest(s, strlen(s), payload_hash, &payload_hash_size, md, NULL) != 1)
if (sym_EVP_Digest(s, strlen(s), payload_hash, &payload_hash_size, md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to calculate event payload hash.");
assert((int) payload_hash_size == mdsz);
@@ -1575,7 +1575,7 @@ static int event_log_validate_record_hashes(EventLog *el) {
const char *a;
assert_se(a = tpm2_hash_alg_to_string(bank->algorithm));
assert_se(md = EVP_get_digestbyname(a));
assert_se(md = sym_EVP_get_digestbyname(a));
r = event_log_record_validate_hash_firmware(*rr, bank, md);
if (r < 0)
@@ -2788,8 +2788,8 @@ static int make_pcrlock_record(
const char *a;
assert_se(a = tpm2_hash_alg_to_string(*pa));
assert_se(md = EVP_get_digestbyname(a));
hash_ssize = EVP_MD_size(md);
assert_se(md = sym_EVP_get_digestbyname(a));
hash_ssize = sym_EVP_MD_get_size(md);
assert(hash_ssize > 0);
hash_usize = hash_ssize;
@@ -2797,7 +2797,7 @@ static int make_pcrlock_record(
if (!hash)
return log_oom();
if (EVP_Digest(data, data_size, hash, &hash_usize, md, NULL) != 1)
if (sym_EVP_Digest(data, data_size, hash, &hash_usize, md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data with algorithm '%s'.", a);
r = sd_json_variant_append_arraybo(
@@ -2821,7 +2821,7 @@ static void evp_md_ctx_free_all(EVP_MD_CTX *(*md)[TPM2_N_HASH_ALGORITHMS]) {
assert(md);
FOREACH_ARRAY(alg, *md, TPM2_N_HASH_ALGORITHMS)
if (*alg)
EVP_MD_CTX_free(*alg);
sym_EVP_MD_CTX_free(*alg);
}
static int make_pcrlock_record_from_stream(
@@ -2841,13 +2841,13 @@ static int make_pcrlock_record_from_stream(
const EVP_MD *md;
assert_se(a = tpm2_hash_alg_to_string(tpm2_hash_algorithms[i]));
assert_se(md = EVP_get_digestbyname(a));
assert_se(md = sym_EVP_get_digestbyname(a));
mdctx[i] = EVP_MD_CTX_new();
mdctx[i] = sym_EVP_MD_CTX_new();
if (!mdctx[i])
return log_oom();
if (EVP_DigestInit_ex(mdctx[i], md, NULL) != 1)
if (sym_EVP_DigestInit_ex(mdctx[i], md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to initialize message digest for %s.", a);
}
@@ -2863,7 +2863,7 @@ static int make_pcrlock_record_from_stream(
break;
for (size_t i = 0; i < TPM2_N_HASH_ALGORITHMS; i++)
if (EVP_DigestUpdate(mdctx[i], buffer, n) != 1)
if (sym_EVP_DigestUpdate(mdctx[i], buffer, n) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
}
@@ -2873,12 +2873,12 @@ static int make_pcrlock_record_from_stream(
unsigned hash_usize;
assert_se(a = tpm2_hash_alg_to_string(tpm2_hash_algorithms[i]));
hash_ssize = EVP_MD_CTX_size(mdctx[i]);
hash_ssize = sym_EVP_MD_CTX_get_size(mdctx[i]);
assert(hash_ssize > 0 && hash_ssize <= EVP_MAX_MD_SIZE);
hash_usize = hash_ssize;
unsigned char hash[hash_usize];
if (EVP_DigestFinal_ex(mdctx[i], hash, &hash_usize) != 1)
if (sym_EVP_DigestFinal_ex(mdctx[i], hash, &hash_usize) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to finalize hash context for algorithn '%s'.", a);
@@ -3072,7 +3072,7 @@ static const EVP_MD* evp_from_tpm2_alg(uint16_t alg) {
if (!name)
return NULL;
return EVP_get_digestbyname(name);
return sym_EVP_get_digestbyname(name);
}
static int event_log_component_variant_calculate(
@@ -3106,13 +3106,13 @@ static int event_log_component_variant_calculate(
continue;
}
md_ctx = EVP_MD_CTX_new();
md_ctx = sym_EVP_MD_CTX_new();
if (!md_ctx)
return log_oom();
const EVP_MD *md = ASSERT_PTR(evp_from_tpm2_alg(tpm2_hash_algorithms[i]));
int sz = EVP_MD_size(md);
int sz = sym_EVP_MD_get_size(md);
assert(sz > 0);
assert((size_t) sz <= sizeof_field(TPM2B_DIGEST, buffer));
@@ -3121,17 +3121,17 @@ static int event_log_component_variant_calculate(
assert(result->hash[i].size == (size_t) sz);
assert(b->hash.size == (size_t) sz);
if (EVP_DigestInit_ex(md_ctx, md, NULL) != 1)
if (sym_EVP_DigestInit_ex(md_ctx, md, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to initialize message digest.");
if (EVP_DigestUpdate(md_ctx, result->hash[i].buffer, sz) != 1)
if (sym_EVP_DigestUpdate(md_ctx, result->hash[i].buffer, sz) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash bank value.");
if (EVP_DigestUpdate(md_ctx, b->hash.buffer, sz) != 1)
if (sym_EVP_DigestUpdate(md_ctx, b->hash.buffer, sz) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data value.");
unsigned l = (unsigned) sz;
if (EVP_DigestFinal_ex(md_ctx, result->hash[i].buffer, &l) != 1)
if (sym_EVP_DigestFinal_ex(md_ctx, result->hash[i].buffer, &l) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to finalize message digest.");
assert(l == (unsigned) sz);
@@ -4749,7 +4749,7 @@ static int verb_lock_pe(int argc, char *argv[], uintptr_t _data, void *userdata)
const char *a;
assert_se(a = tpm2_hash_alg_to_string(*pa));
assert_se(md = EVP_get_digestbyname(a));
assert_se(md = sym_EVP_get_digestbyname(a));
r = pe_hash(fd < 0 ? STDIN_FILENO : fd, md, &hash, &hash_size);
if (r < 0)
@@ -4813,7 +4813,7 @@ static int verb_lock_uki(int argc, char *argv[], uintptr_t _data, void *userdata
const char *a;
assert_se(a = tpm2_hash_alg_to_string(tpm2_hash_algorithms[i]));
assert_se(md = EVP_get_digestbyname(a));
assert_se(md = sym_EVP_get_digestbyname(a));
r = pe_hash(fd < 0 ? STDIN_FILENO : fd, md, &peh, hash_sizes + i);
if (r < 0)
@@ -5472,6 +5472,10 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
if (arg_varlink) {
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
+2 -2
View File
@@ -16,7 +16,7 @@ executables += [
libblkid_cflags,
libfdisk_cflags,
libmount_cflags,
libopenssl,
libopenssl_cflags,
threads,
],
},
@@ -34,7 +34,7 @@ executables += [
libblkid_cflags,
libfdisk_cflags,
libmount_cflags,
libopenssl,
libopenssl_cflags,
threads,
],
},
+15 -9
View File
@@ -24,6 +24,7 @@
#include "conf-parser.h"
#include "constants.h"
#include "copy.h"
#include "crypto-util.h"
#include "cryptsetup-util.h"
#include "device-util.h"
#include "devnum-util.h"
@@ -59,7 +60,6 @@
#include "mount-util.h"
#include "mountpoint-util.h"
#include "nulstr-util.h"
#include "openssl-util.h"
#include "options.h"
#include "parse-argument.h"
#include "parse-helpers.h"
@@ -985,9 +985,11 @@ static Context* context_free(Context *context) {
free(context->node);
#if HAVE_OPENSSL
X509_free(context->certificate);
if (context->certificate)
sym_X509_free(context->certificate);
openssl_ask_password_ui_free(context->ui);
EVP_PKEY_free(context->private_key);
if (context->private_key)
sym_EVP_PKEY_free(context->private_key);
#endif
context->link = sd_varlink_unref(context->link);
@@ -5826,7 +5828,7 @@ static int sign_verity_roothash(
_cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
_cleanup_free_ char *hex = NULL;
_cleanup_free_ uint8_t *sig = NULL;
int sigsz;
int sigsz, r;
assert(context);
assert(context->certificate);
@@ -5835,23 +5837,27 @@ static int sign_verity_roothash(
assert(iovec_is_set(roothash));
assert(ret_signature);
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
hex = hexmem(roothash->iov_base, roothash->iov_len);
if (!hex)
return log_oom();
rb = BIO_new_mem_buf(hex, -1);
rb = sym_BIO_new_mem_buf(hex, -1);
if (!rb)
return log_oom();
p7 = PKCS7_sign(context->certificate, context->private_key, NULL, rb, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY);
p7 = sym_PKCS7_sign(context->certificate, context->private_key, NULL, rb, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY);
if (!p7)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to calculate PKCS7 signature: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
sigsz = i2d_PKCS7(p7, &sig);
sigsz = sym_i2d_PKCS7(p7, &sig);
if (sigsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
*ret_signature = IOVEC_MAKE(TAKE_PTR(sig), sigsz);
+1 -1
View File
@@ -70,7 +70,7 @@ endif
resolve_common_template = {
'dependencies' : [
libidn2_cflags,
libopenssl,
libopenssl_cflags,
libm,
threads,
],
+1 -1
View File
@@ -20,6 +20,7 @@
#include "bus-locator.h"
#include "bus-message-util.h"
#include "bus-util.h"
#include "crypto-util.h"
#include "dns-configuration.h"
#include "dns-domain.h"
#include "dns-packet.h"
@@ -34,7 +35,6 @@
#include "main-func.h"
#include "missing-network.h"
#include "netlink-util.h"
#include "openssl-util.h"
#include "ordered-set.h"
#include "pager.h"
#include "parse-argument.h"
+81 -74
View File
@@ -2,6 +2,7 @@
#include "alloc-util.h"
#include "bitmap.h"
#include "crypto-util.h"
#include "dns-answer.h"
#include "dns-domain.h"
#include "dns-rr.h"
@@ -10,19 +11,12 @@
#include "log.h"
#include "memory-util.h"
#include "memstream-util.h"
#include "openssl-util.h"
#include "resolved-dns-dnssec.h"
#include "sort-util.h"
#include "string-table.h"
#include "string-util.h"
#include "time-util.h"
#if HAVE_OPENSSL
DISABLE_WARNING_DEPRECATED_DECLARATIONS;
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(RSA*, RSA_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_KEY*, EC_KEY_free, NULL);
REENABLE_WARNING;
#endif
#define VERIFY_RRS_MAX 256
#define MAX_KEY_SIZE (32*1024)
@@ -84,49 +78,49 @@ static int dnssec_rsa_verify_raw(
assert(hash_algorithm);
e = BN_bin2bn(exponent, exponent_size, NULL);
e = sym_BN_bin2bn(exponent, exponent_size, NULL);
if (!e)
return -EIO;
m = BN_bin2bn(modulus, modulus_size, NULL);
m = sym_BN_bin2bn(modulus, modulus_size, NULL);
if (!m)
return -EIO;
rpubkey = RSA_new();
rpubkey = sym_RSA_new();
if (!rpubkey)
return -ENOMEM;
if (RSA_set0_key(rpubkey, m, e, NULL) <= 0)
if (sym_RSA_set0_key(rpubkey, m, e, NULL) <= 0)
return -EIO;
e = m = NULL;
if ((size_t) RSA_size(rpubkey) != signature_size)
if ((size_t) sym_RSA_size(rpubkey) != signature_size)
return -EINVAL;
epubkey = EVP_PKEY_new();
epubkey = sym_EVP_PKEY_new();
if (!epubkey)
return -ENOMEM;
if (EVP_PKEY_assign_RSA(epubkey, RSAPublicKey_dup(rpubkey)) <= 0)
if (sym_EVP_PKEY_assign_RSA(epubkey, sym_RSAPublicKey_dup(rpubkey)) <= 0)
return -EIO;
ctx = EVP_PKEY_CTX_new(epubkey, NULL);
ctx = sym_EVP_PKEY_CTX_new(epubkey, NULL);
if (!ctx)
return -ENOMEM;
if (EVP_PKEY_verify_init(ctx) <= 0)
if (sym_EVP_PKEY_verify_init(ctx) <= 0)
return -EIO;
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
if (sym_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
return -EIO;
if (EVP_PKEY_CTX_set_signature_md(ctx, hash_algorithm) <= 0)
if (sym_EVP_PKEY_CTX_set_signature_md(ctx, hash_algorithm) <= 0)
return -EIO;
r = EVP_PKEY_verify(ctx, signature, signature_size, data, data_size);
r = sym_EVP_PKEY_verify(ctx, signature, signature_size, data, data_size);
if (r < 0)
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"Signature verification failed: 0x%lx", ERR_get_error());
"Signature verification failed: 0x%lx", sym_ERR_get_error());
REENABLE_WARNING;
return r;
@@ -207,58 +201,58 @@ static int dnssec_ecdsa_verify_raw(
assert(hash_algorithm);
ec_group = EC_GROUP_new_by_curve_name(curve);
ec_group = sym_EC_GROUP_new_by_curve_name(curve);
if (!ec_group)
return -ENOMEM;
p = EC_POINT_new(ec_group);
p = sym_EC_POINT_new(ec_group);
if (!p)
return -ENOMEM;
bctx = BN_CTX_new();
bctx = sym_BN_CTX_new();
if (!bctx)
return -ENOMEM;
if (EC_POINT_oct2point(ec_group, p, key, key_size, bctx) <= 0)
if (sym_EC_POINT_oct2point(ec_group, p, key, key_size, bctx) <= 0)
return -EIO;
eckey = EC_KEY_new();
eckey = sym_EC_KEY_new();
if (!eckey)
return -ENOMEM;
if (EC_KEY_set_group(eckey, ec_group) <= 0)
if (sym_EC_KEY_set_group(eckey, ec_group) <= 0)
return -EIO;
if (EC_KEY_set_public_key(eckey, p) <= 0)
if (sym_EC_KEY_set_public_key(eckey, p) <= 0)
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"EC_KEY_set_public_key failed: 0x%lx", ERR_get_error());
"EC_KEY_set_public_key failed: 0x%lx", sym_ERR_get_error());
if (EC_KEY_check_key(eckey) != 1)
if (sym_EC_KEY_check_key(eckey) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"EC_KEY_check_key failed: 0x%lx", ERR_get_error());
"EC_KEY_check_key failed: 0x%lx", sym_ERR_get_error());
r = BN_bin2bn(signature_r, signature_r_size, NULL);
r = sym_BN_bin2bn(signature_r, signature_r_size, NULL);
if (!r)
return -EIO;
s = BN_bin2bn(signature_s, signature_s_size, NULL);
s = sym_BN_bin2bn(signature_s, signature_s_size, NULL);
if (!s)
return -EIO;
/* TODO: We should eventually use the EVP API once it supports ECDSA signature verification */
sig = ECDSA_SIG_new();
sig = sym_ECDSA_SIG_new();
if (!sig)
return -ENOMEM;
if (ECDSA_SIG_set0(sig, r, s) <= 0)
if (sym_ECDSA_SIG_set0(sig, r, s) <= 0)
return -EIO;
r = s = NULL;
k = ECDSA_do_verify(data, data_size, sig, eckey);
k = sym_ECDSA_do_verify(data, data_size, sig, eckey);
if (k < 0)
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"Signature verification failed: 0x%lx", ERR_get_error());
"Signature verification failed: 0x%lx", sym_ERR_get_error());
REENABLE_WARNING;
return k;
@@ -326,30 +320,30 @@ static int dnssec_eddsa_verify_raw(
q[0] = 0x04; /* Prepend 0x04 to indicate an uncompressed key */
memcpy(q+1, signature, signature_size);
evkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, key, key_size);
evkey = sym_EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, key, key_size);
if (!evkey)
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"EVP_PKEY_new_raw_public_key failed: 0x%lx", ERR_get_error());
"EVP_PKEY_new_raw_public_key failed: 0x%lx", sym_ERR_get_error());
pctx = EVP_PKEY_CTX_new(evkey, NULL);
pctx = sym_EVP_PKEY_CTX_new(evkey, NULL);
if (!pctx)
return -ENOMEM;
ctx = EVP_MD_CTX_new();
ctx = sym_EVP_MD_CTX_new();
if (!ctx)
return -ENOMEM;
/* This prevents EVP_DigestVerifyInit from managing pctx and complicating our free logic. */
EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
sym_EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
/* One might be tempted to use EVP_PKEY_verify_init, but see Ed25519(7ssl). */
if (EVP_DigestVerifyInit(ctx, &pctx, NULL, NULL, evkey) <= 0)
if (sym_EVP_DigestVerifyInit(ctx, &pctx, NULL, NULL, evkey) <= 0)
return -EIO;
r = EVP_DigestVerify(ctx, signature, signature_size, data, data_size);
r = sym_EVP_DigestVerify(ctx, signature, signature_size, data, data_size);
if (r < 0)
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"Signature verification failed: 0x%lx", ERR_get_error());
"Signature verification failed: 0x%lx", sym_ERR_get_error());
return r;
}
@@ -382,12 +376,12 @@ static int dnssec_eddsa_verify(
}
static int md_add_uint8(EVP_MD_CTX *ctx, uint8_t v) {
return EVP_DigestUpdate(ctx, &v, sizeof(v));
return sym_EVP_DigestUpdate(ctx, &v, sizeof(v));
}
static int md_add_uint16(EVP_MD_CTX *ctx, uint16_t v) {
v = htobe16(v);
return EVP_DigestUpdate(ctx, &v, sizeof(v));
return sym_EVP_DigestUpdate(ctx, &v, sizeof(v));
}
static void fwrite_uint8(FILE *fp, uint8_t v) {
@@ -504,17 +498,17 @@ static const EVP_MD* algorithm_to_implementation_id(uint8_t algorithm) {
case DNSSEC_ALGORITHM_RSASHA1:
case DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1:
return EVP_sha1();
return sym_EVP_sha1();
case DNSSEC_ALGORITHM_RSASHA256:
case DNSSEC_ALGORITHM_ECDSAP256SHA256:
return EVP_sha256();
return sym_EVP_sha256();
case DNSSEC_ALGORITHM_ECDSAP384SHA384:
return EVP_sha384();
return sym_EVP_sha384();
case DNSSEC_ALGORITHM_RSASHA512:
return EVP_sha512();
return sym_EVP_sha512();
default:
return NULL;
@@ -645,19 +639,19 @@ static int dnssec_rrset_verify_sig(
if (!md_algorithm)
return -EOPNOTSUPP;
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = sym_EVP_MD_CTX_new();
if (!ctx)
return -ENOMEM;
/* If the signature algorithm is supported by systemd-resolved but disabled by host policy,
* also return -EOPNOTSUPP. */
if (EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
if (sym_EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
return -EOPNOTSUPP;
if (EVP_DigestUpdate(ctx, sig_data, sig_size) <= 0)
if (sym_EVP_DigestUpdate(ctx, sig_data, sig_size) <= 0)
return -EIO;
if (EVP_DigestFinal_ex(ctx, hash, &hash_size) <= 0)
if (sym_EVP_DigestFinal_ex(ctx, hash, &hash_size) <= 0)
return -EIO;
assert(hash_size > 0);
@@ -709,6 +703,11 @@ int dnssec_verify_rrset(
assert(rrsig);
assert(dnskey);
assert(result);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
assert(rrsig->key->type == DNS_TYPE_RRSIG);
assert(dnskey->key->type == DNS_TYPE_DNSKEY);
@@ -1041,13 +1040,13 @@ static const EVP_MD* digest_to_hash_md(uint8_t algorithm) {
switch (algorithm) {
case DNSSEC_DIGEST_SHA1:
return EVP_sha1();
return sym_EVP_sha1();
case DNSSEC_DIGEST_SHA256:
return EVP_sha256();
return sym_EVP_sha256();
case DNSSEC_DIGEST_SHA384:
return EVP_sha384();
return sym_EVP_sha384();
default:
return NULL;
@@ -1062,6 +1061,10 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
assert(dnskey);
assert(ds);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
/* Implements DNSKEY verification by a DS, according to RFC 4035, section 5.2 */
if (dnskey->key->type != DNS_TYPE_DNSKEY)
@@ -1092,22 +1095,22 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = NULL;
uint8_t result[EVP_MAX_MD_SIZE];
unsigned hash_size = EVP_MD_size(md_algorithm);
unsigned hash_size = sym_EVP_MD_get_size(md_algorithm);
assert(hash_size > 0);
if (ds->ds.digest_size != hash_size)
return 0;
ctx = EVP_MD_CTX_new();
ctx = sym_EVP_MD_CTX_new();
if (!ctx)
return -ENOMEM;
/* If the digest is supported by systemd-resolved but disabled by host policy, also return -EOPNOTSUPP
*/
if (EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
if (sym_EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
return -EOPNOTSUPP;
if (EVP_DigestUpdate(ctx, wire_format, encoded_length) <= 0)
if (sym_EVP_DigestUpdate(ctx, wire_format, encoded_length) <= 0)
return -EIO;
if (mask_revoke)
@@ -1121,10 +1124,10 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
r = md_add_uint8(ctx, dnskey->dnskey.algorithm);
if (r <= 0)
return r;
if (EVP_DigestUpdate(ctx, dnskey->dnskey.key, dnskey->dnskey.key_size) <= 0)
if (sym_EVP_DigestUpdate(ctx, dnskey->dnskey.key, dnskey->dnskey.key_size) <= 0)
return -EIO;
if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
return -EIO;
return memcmp(result, ds->ds.digest, ds->ds.digest_size) == 0;
@@ -1183,7 +1186,7 @@ static const EVP_MD* nsec3_hash_to_hash_md(uint8_t algorithm) {
switch (algorithm) {
case NSEC3_ALGORITHM_SHA1:
return EVP_sha1();
return sym_EVP_sha1();
default:
return NULL;
@@ -1198,6 +1201,10 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
assert(name);
assert(ret);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
if (nsec3->key->type != DNS_TYPE_NSEC3)
return -EINVAL;
@@ -1210,41 +1217,41 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
if (!algorithm)
return -EOPNOTSUPP;
size_t hash_size = EVP_MD_size(algorithm);
size_t hash_size = sym_EVP_MD_get_size(algorithm);
assert(hash_size > 0);
if (nsec3->nsec3.next_hashed_name_size != hash_size)
return -EINVAL;
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = sym_EVP_MD_CTX_new();
if (!ctx)
return -ENOMEM;
if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
if (sym_EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
return -EOPNOTSUPP;
r = dns_name_to_wire_format(name, wire_format, sizeof(wire_format), true);
if (r < 0)
return r;
if (EVP_DigestUpdate(ctx, wire_format, r) <= 0)
if (sym_EVP_DigestUpdate(ctx, wire_format, r) <= 0)
return -EIO;
if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
if (sym_EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
return -EIO;
uint8_t result[EVP_MAX_MD_SIZE];
if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
return -EIO;
for (unsigned k = 0; k < nsec3->nsec3.iterations; k++) {
if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
if (sym_EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
return -EOPNOTSUPP;
if (EVP_DigestUpdate(ctx, result, hash_size) <= 0)
if (sym_EVP_DigestUpdate(ctx, result, hash_size) <= 0)
return -EIO;
if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
if (sym_EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
return -EIO;
if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
return -EIO;
}
+56 -49
View File
@@ -4,22 +4,21 @@
#error This source file requires DNS-over-TLS to be enabled and OpenSSL to be available.
#endif
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "alloc-util.h"
#include "openssl-util.h"
#include "crypto-util.h"
#include "log.h"
#include "resolved-dns-server.h"
#include "resolved-dns-stream.h"
#include "resolved-dnstls.h"
#include "resolved-manager.h"
#include "ssl-util.h"
static char *dnstls_error_string(int ssl_error, char *buf, size_t count) {
assert(buf || count == 0);
if (ssl_error == SSL_ERROR_SSL)
ERR_error_string_n(ERR_get_error(), buf, count);
sym_ERR_error_string_n(sym_ERR_get_error(), buf, count);
else
snprintf(buf, count, "SSL_get_error()=%d", ssl_error);
return buf;
@@ -54,7 +53,7 @@ static int dnstls_flush_write_buffer(DnsStream *stream) {
stream->dnstls_events |= EPOLLOUT;
return -EAGAIN;
} else {
BIO_reset(SSL_get_wbio(stream->dnstls_data.ssl));
sym_BIO_reset(sym_SSL_get_wbio(stream->dnstls_data.ssl));
stream->dnstls_data.buffer_offset = 0;
}
}
@@ -72,55 +71,55 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
assert(stream->manager);
assert(server);
rb = BIO_new_socket(stream->fd, 0);
rb = sym_BIO_new_socket(stream->fd, 0);
if (!rb)
return -ENOMEM;
wb = BIO_new(BIO_s_mem());
wb = sym_BIO_new(sym_BIO_s_mem());
if (!wb)
return -ENOMEM;
BIO_get_mem_ptr(wb, &stream->dnstls_data.write_buffer);
sym_BIO_get_mem_ptr(wb, &stream->dnstls_data.write_buffer);
stream->dnstls_data.buffer_offset = 0;
s = SSL_new(stream->manager->dnstls_data.ctx);
s = sym_SSL_new(stream->manager->dnstls_data.ctx);
if (!s)
return -ENOMEM;
SSL_set_connect_state(s);
r = SSL_set_session(s, server->dnstls_data.session);
sym_SSL_set_connect_state(s);
r = sym_SSL_set_session(s, server->dnstls_data.session);
if (r == 0)
return -EIO;
SSL_set_bio(s, TAKE_PTR(rb), TAKE_PTR(wb));
sym_SSL_set_bio(s, TAKE_PTR(rb), TAKE_PTR(wb));
if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) {
X509_VERIFY_PARAM *v;
SSL_set_verify(s, SSL_VERIFY_PEER, NULL);
v = SSL_get0_param(s);
sym_SSL_set_verify(s, SSL_VERIFY_PEER, NULL);
v = sym_SSL_get0_param(s);
if (server->server_name) {
X509_VERIFY_PARAM_set_hostflags(v, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
if (X509_VERIFY_PARAM_set1_host(v, server->server_name, 0) == 0)
sym_X509_VERIFY_PARAM_set_hostflags(v, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
if (sym_X509_VERIFY_PARAM_set1_host(v, server->server_name, 0) == 0)
return -ECONNREFUSED;
} else {
const unsigned char *ip;
ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr;
if (X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0)
if (sym_X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0)
return -ECONNREFUSED;
}
}
if (server->server_name) {
r = SSL_set_tlsext_host_name(s, server->server_name);
r = sym_SSL_set_tlsext_host_name(s, server->server_name);
if (r <= 0)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to set server name: %s", DNSTLS_ERROR_STRING(SSL_ERROR_SSL));
}
ERR_clear_error();
stream->dnstls_data.handshake = SSL_do_handshake(s);
sym_ERR_clear_error();
stream->dnstls_data.handshake = sym_SSL_do_handshake(s);
if (stream->dnstls_data.handshake <= 0) {
error = SSL_get_error(s, stream->dnstls_data.handshake);
error = sym_SSL_get_error(s, stream->dnstls_data.handshake);
if (!IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE))
return log_debug_errno(SYNTHETIC_ERRNO(ECONNREFUSED),
"Failed to invoke SSL_do_handshake: %s", DNSTLS_ERROR_STRING(error));
@@ -131,7 +130,7 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
r = dnstls_flush_write_buffer(stream);
if (r < 0 && r != -EAGAIN) {
SSL_free(TAKE_PTR(stream->dnstls_data.ssl));
sym_SSL_free(TAKE_PTR(stream->dnstls_data.ssl));
return r;
}
@@ -143,7 +142,7 @@ void dnstls_stream_free(DnsStream *stream) {
assert(stream->encrypted);
if (stream->dnstls_data.ssl)
SSL_free(stream->dnstls_data.ssl);
sym_SSL_free(stream->dnstls_data.ssl);
}
int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
@@ -161,8 +160,8 @@ int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
}
if (stream->dnstls_data.shutdown) {
ERR_clear_error();
r = SSL_shutdown(stream->dnstls_data.ssl);
sym_ERR_clear_error();
r = sym_SSL_shutdown(stream->dnstls_data.ssl);
if (r == 0) {
stream->dnstls_events = 0;
@@ -172,7 +171,7 @@ int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
return -EAGAIN;
} else if (r < 0) {
error = SSL_get_error(stream->dnstls_data.ssl, r);
error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
stream->dnstls_events = error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
@@ -198,10 +197,10 @@ int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
dns_stream_unref(stream);
return DNSTLS_STREAM_CLOSED;
} else if (stream->dnstls_data.handshake <= 0) {
ERR_clear_error();
stream->dnstls_data.handshake = SSL_do_handshake(stream->dnstls_data.ssl);
sym_ERR_clear_error();
stream->dnstls_data.handshake = sym_SSL_do_handshake(stream->dnstls_data.ssl);
if (stream->dnstls_data.handshake <= 0) {
error = SSL_get_error(stream->dnstls_data.ssl, stream->dnstls_data.handshake);
error = sym_SSL_get_error(stream->dnstls_data.ssl, stream->dnstls_data.handshake);
if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
stream->dnstls_events = error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
r = dnstls_flush_write_buffer(stream);
@@ -233,18 +232,18 @@ int dnstls_stream_shutdown(DnsStream *stream, int error) {
assert(stream->dnstls_data.ssl);
if (stream->server) {
s = SSL_get1_session(stream->dnstls_data.ssl);
s = sym_SSL_get1_session(stream->dnstls_data.ssl);
if (s) {
if (stream->server->dnstls_data.session)
SSL_SESSION_free(stream->server->dnstls_data.session);
sym_SSL_SESSION_free(stream->server->dnstls_data.session);
stream->server->dnstls_data.session = s;
}
}
if (error == ETIMEDOUT) {
ERR_clear_error();
r = SSL_shutdown(stream->dnstls_data.ssl);
sym_ERR_clear_error();
r = sym_SSL_shutdown(stream->dnstls_data.ssl);
if (r == 0) {
if (!stream->dnstls_data.shutdown) {
stream->dnstls_data.shutdown = true;
@@ -259,7 +258,7 @@ int dnstls_stream_shutdown(DnsStream *stream, int error) {
return -EAGAIN;
} else if (r < 0) {
ssl_error = SSL_get_error(stream->dnstls_data.ssl, r);
ssl_error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
if (IN_SET(ssl_error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
stream->dnstls_events = ssl_error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
r = dnstls_flush_write_buffer(stream);
@@ -291,10 +290,10 @@ static ssize_t dnstls_stream_write(DnsStream *stream, const char *buf, size_t co
int error, r;
ssize_t ss;
ERR_clear_error();
ss = r = SSL_write(stream->dnstls_data.ssl, buf, count);
sym_ERR_clear_error();
ss = r = sym_SSL_write(stream->dnstls_data.ssl, buf, count);
if (r <= 0) {
error = SSL_get_error(stream->dnstls_data.ssl, r);
error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
stream->dnstls_events = error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
ss = -EAGAIN;
@@ -352,10 +351,10 @@ ssize_t dnstls_stream_read(DnsStream *stream, void *buf, size_t count) {
assert(stream->dnstls_data.ssl);
assert(buf);
ERR_clear_error();
ss = r = SSL_read(stream->dnstls_data.ssl, buf, count);
sym_ERR_clear_error();
ss = r = sym_SSL_read(stream->dnstls_data.ssl, buf, count);
if (r <= 0) {
error = SSL_get_error(stream->dnstls_data.ssl, r);
error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
/* If we receive SSL_ERROR_WANT_READ here, there are two possible scenarios:
* OpenSSL needs to renegotiate (so we want to get an EPOLLIN event), or
@@ -390,7 +389,7 @@ void dnstls_server_free(DnsServer *server) {
assert(server);
if (server->dnstls_data.session)
SSL_SESSION_free(server->dnstls_data.session);
sym_SSL_SESSION_free(server->dnstls_data.session);
}
int dnstls_manager_init(Manager *manager) {
@@ -398,25 +397,33 @@ int dnstls_manager_init(Manager *manager) {
assert(manager);
manager->dnstls_data.ctx = SSL_CTX_new(TLS_client_method());
r = dlopen_libcrypto(LOG_WARNING);
if (r < 0)
return r;
r = dlopen_libssl(LOG_WARNING);
if (r < 0)
return r;
manager->dnstls_data.ctx = sym_SSL_CTX_new(sym_TLS_client_method());
if (!manager->dnstls_data.ctx)
return log_warning_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to create SSL context: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
r = SSL_CTX_set_min_proto_version(manager->dnstls_data.ctx, TLS1_2_VERSION);
r = sym_SSL_CTX_set_min_proto_version(manager->dnstls_data.ctx, TLS1_2_VERSION);
if (r == 0)
return log_warning_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to set protocol version on SSL context: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
(void) SSL_CTX_set_options(manager->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
(void) sym_SSL_CTX_set_options(manager->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
r = SSL_CTX_set_default_verify_paths(manager->dnstls_data.ctx);
r = sym_SSL_CTX_set_default_verify_paths(manager->dnstls_data.ctx);
if (r == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EIO),
"Failed to load system trust store: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
return 0;
}
@@ -424,5 +431,5 @@ void dnstls_manager_free(Manager *manager) {
assert(manager);
if (manager->dnstls_data.ctx)
SSL_CTX_free(manager->dnstls_data.ctx);
sym_SSL_CTX_free(manager->dnstls_data.ctx);
}
-2
View File
@@ -7,8 +7,6 @@
#error This source file requires OpenSSL to be available.
#endif
#include <openssl/ssl.h>
#include "resolved-forward.h"
typedef struct DnsTlsManagerData {
+125
View File
@@ -0,0 +1,125 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <openssl/asn1t.h>
#include "authenticode.h"
#include "crypto-util.h"
/* OpenSSL's ASN1_SEQUENCE/ASN1_CHOICE/IMPLEMENT_ASN1_FUNCTIONS macros expand to code that references
* libcrypto symbols directly, which would force us to link this object against libcrypto and defeat the
* dlopen approach used everywhere else. We work around that in two different ways depending on where the
* reference appears in the macro expansion:
*
* - ASN1_item_new/ASN1_item_free/ASN1_item_d2i/ASN1_item_i2d are called from the bodies of the functions
* generated by IMPLEMENT_ASN1_FUNCTIONS. We can simply #define them to the matching sym_* variants, so
* the generated bodies end up calling our dlopen'd pointers.
*
* - ASN1_ANY_it/ASN1_BIT_STRING_it/... (the "_it" getters) are embedded as function pointers in the
* static const ASN1_ADB / ASN1_TEMPLATE tables emitted by the ASN1_SEQUENCE/ASN1_CHOICE macros. Static
* initializers can only contain constant expressions, so we can't point them at the sym_* variables
* (which are non-const globals filled in at dlopen time). Instead we define static trampoline
* functions (openssl_ASN1_*_it) whose addresses are constant, each forwarding to the corresponding
* sym_* pointer at runtime, and #define the OpenSSL names to our trampolines before the tables are
* emitted.
*
* Note that this file must only call these redefined macros indirectly, via the IMPLEMENT_ASN1_FUNCTIONS
* expansions, and callers of those generated wrappers (e.g. sbsign.c) must have dlopen_libcrypto()
* before invoking them, otherwise the sym_* pointers will still be NULL. */
static const ASN1_ITEM* openssl_ASN1_ANY_it(void) {
assert(sym_ASN1_ANY_it);
return sym_ASN1_ANY_it();
}
static const ASN1_ITEM* openssl_ASN1_BIT_STRING_it(void) {
assert(sym_ASN1_BIT_STRING_it);
return sym_ASN1_BIT_STRING_it();
}
static const ASN1_ITEM* openssl_ASN1_BMPSTRING_it(void) {
assert(sym_ASN1_BMPSTRING_it);
return sym_ASN1_BMPSTRING_it();
}
static const ASN1_ITEM* openssl_ASN1_IA5STRING_it(void) {
assert(sym_ASN1_IA5STRING_it);
return sym_ASN1_IA5STRING_it();
}
static const ASN1_ITEM* openssl_ASN1_OBJECT_it(void) {
assert(sym_ASN1_OBJECT_it);
return sym_ASN1_OBJECT_it();
}
static const ASN1_ITEM* openssl_ASN1_OCTET_STRING_it(void) {
assert(sym_ASN1_OCTET_STRING_it);
return sym_ASN1_OCTET_STRING_it();
}
#define ASN1_item_new sym_ASN1_item_new
#define ASN1_item_free sym_ASN1_item_free
#define ASN1_item_d2i sym_ASN1_item_d2i
#define ASN1_item_i2d sym_ASN1_item_i2d
#define ASN1_ANY_it openssl_ASN1_ANY_it
#define ASN1_BIT_STRING_it openssl_ASN1_BIT_STRING_it
#define ASN1_BMPSTRING_it openssl_ASN1_BMPSTRING_it
#define ASN1_IA5STRING_it openssl_ASN1_IA5STRING_it
#define ASN1_OBJECT_it openssl_ASN1_OBJECT_it
#define ASN1_OCTET_STRING_it openssl_ASN1_OCTET_STRING_it
ASN1_SEQUENCE(SpcAttributeTypeAndOptionalValue) = {
ASN1_SIMPLE(SpcAttributeTypeAndOptionalValue, type, ASN1_OBJECT),
ASN1_OPT(SpcAttributeTypeAndOptionalValue, value, ASN1_ANY)
} ASN1_SEQUENCE_END(SpcAttributeTypeAndOptionalValue);
IMPLEMENT_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue);
ASN1_SEQUENCE(AlgorithmIdentifier) = {
ASN1_SIMPLE(AlgorithmIdentifier, algorithm, ASN1_OBJECT),
ASN1_OPT(AlgorithmIdentifier, parameters, ASN1_ANY)
} ASN1_SEQUENCE_END(AlgorithmIdentifier)
IMPLEMENT_ASN1_FUNCTIONS(AlgorithmIdentifier);
ASN1_SEQUENCE(DigestInfo) = {
ASN1_SIMPLE(DigestInfo, digestAlgorithm, AlgorithmIdentifier),
ASN1_SIMPLE(DigestInfo, digest, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(DigestInfo);
IMPLEMENT_ASN1_FUNCTIONS(DigestInfo);
ASN1_SEQUENCE(SpcIndirectDataContent) = {
ASN1_SIMPLE(SpcIndirectDataContent, data, SpcAttributeTypeAndOptionalValue),
ASN1_SIMPLE(SpcIndirectDataContent, messageDigest, DigestInfo)
} ASN1_SEQUENCE_END(SpcIndirectDataContent);
IMPLEMENT_ASN1_FUNCTIONS(SpcIndirectDataContent);
ASN1_CHOICE(SpcString) = {
ASN1_IMP_OPT(SpcString, value.unicode, ASN1_BMPSTRING, 0),
ASN1_IMP_OPT(SpcString, value.ascii, ASN1_IA5STRING, 1)
} ASN1_CHOICE_END(SpcString);
IMPLEMENT_ASN1_FUNCTIONS(SpcString);
ASN1_SEQUENCE(SpcSerializedObject) = {
ASN1_SIMPLE(SpcSerializedObject, classId, ASN1_OCTET_STRING),
ASN1_SIMPLE(SpcSerializedObject, serializedData, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(SpcSerializedObject);
IMPLEMENT_ASN1_FUNCTIONS(SpcSerializedObject);
ASN1_CHOICE(SpcLink) = {
ASN1_IMP_OPT(SpcLink, value.url, ASN1_IA5STRING, 0),
ASN1_IMP_OPT(SpcLink, value.moniker, SpcSerializedObject, 1),
ASN1_EXP_OPT(SpcLink, value.file, SpcString, 2)
} ASN1_CHOICE_END(SpcLink);
IMPLEMENT_ASN1_FUNCTIONS(SpcLink);
ASN1_SEQUENCE(SpcPeImageData) = {
ASN1_SIMPLE(SpcPeImageData, flags, ASN1_BIT_STRING),
ASN1_EXP_OPT(SpcPeImageData, file, SpcLink, 0)
} ASN1_SEQUENCE_END(SpcPeImageData)
IMPLEMENT_ASN1_FUNCTIONS(SpcPeImageData);
+3 -62
View File
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <openssl/asn1t.h>
#include <openssl/asn1.h>
#include "shared-forward.h"
@@ -15,13 +15,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue);
ASN1_SEQUENCE(SpcAttributeTypeAndOptionalValue) = {
ASN1_SIMPLE(SpcAttributeTypeAndOptionalValue, type, ASN1_OBJECT),
ASN1_OPT(SpcAttributeTypeAndOptionalValue, value, ASN1_ANY)
} ASN1_SEQUENCE_END(SpcAttributeTypeAndOptionalValue);
IMPLEMENT_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue);
typedef struct {
ASN1_OBJECT *algorithm;
ASN1_TYPE *parameters;
@@ -29,13 +22,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(AlgorithmIdentifier);
ASN1_SEQUENCE(AlgorithmIdentifier) = {
ASN1_SIMPLE(AlgorithmIdentifier, algorithm, ASN1_OBJECT),
ASN1_OPT(AlgorithmIdentifier, parameters, ASN1_ANY)
} ASN1_SEQUENCE_END(AlgorithmIdentifier)
IMPLEMENT_ASN1_FUNCTIONS(AlgorithmIdentifier);
typedef struct {
AlgorithmIdentifier *digestAlgorithm;
ASN1_OCTET_STRING *digest;
@@ -43,13 +29,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(DigestInfo);
ASN1_SEQUENCE(DigestInfo) = {
ASN1_SIMPLE(DigestInfo, digestAlgorithm, AlgorithmIdentifier),
ASN1_SIMPLE(DigestInfo, digest, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(DigestInfo);
IMPLEMENT_ASN1_FUNCTIONS(DigestInfo);
typedef struct {
SpcAttributeTypeAndOptionalValue *data;
DigestInfo *messageDigest;
@@ -57,15 +36,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(SpcIndirectDataContent);
ASN1_SEQUENCE(SpcIndirectDataContent) = {
ASN1_SIMPLE(SpcIndirectDataContent, data, SpcAttributeTypeAndOptionalValue),
ASN1_SIMPLE(SpcIndirectDataContent, messageDigest, DigestInfo)
} ASN1_SEQUENCE_END(SpcIndirectDataContent);
IMPLEMENT_ASN1_FUNCTIONS(SpcIndirectDataContent);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcIndirectDataContent*, SpcIndirectDataContent_free, NULL);
typedef struct {
int type;
union {
@@ -76,13 +46,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(SpcString);
ASN1_CHOICE(SpcString) = {
ASN1_IMP_OPT(SpcString, value.unicode, ASN1_BMPSTRING, 0),
ASN1_IMP_OPT(SpcString, value.ascii, ASN1_IA5STRING, 1)
} ASN1_CHOICE_END(SpcString);
IMPLEMENT_ASN1_FUNCTIONS(SpcString);
typedef struct {
ASN1_OCTET_STRING *classId;
ASN1_OCTET_STRING *serializedData;
@@ -90,13 +53,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(SpcSerializedObject);
ASN1_SEQUENCE(SpcSerializedObject) = {
ASN1_SIMPLE(SpcSerializedObject, classId, ASN1_OCTET_STRING),
ASN1_SIMPLE(SpcSerializedObject, serializedData, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(SpcSerializedObject);
IMPLEMENT_ASN1_FUNCTIONS(SpcSerializedObject);
typedef struct {
int type;
union {
@@ -108,16 +64,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(SpcLink);
ASN1_CHOICE(SpcLink) = {
ASN1_IMP_OPT(SpcLink, value.url, ASN1_IA5STRING, 0),
ASN1_IMP_OPT(SpcLink, value.moniker, SpcSerializedObject, 1),
ASN1_EXP_OPT(SpcLink, value.file, SpcString, 2)
} ASN1_CHOICE_END(SpcLink);
IMPLEMENT_ASN1_FUNCTIONS(SpcLink);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcLink*, SpcLink_free, NULL);
typedef struct {
ASN1_BIT_STRING *flags;
SpcLink *file;
@@ -125,11 +71,6 @@ typedef struct {
DECLARE_ASN1_FUNCTIONS(SpcPeImageData);
ASN1_SEQUENCE(SpcPeImageData) = {
ASN1_SIMPLE(SpcPeImageData, flags, ASN1_BIT_STRING),
ASN1_EXP_OPT(SpcPeImageData, file, SpcLink, 0)
} ASN1_SEQUENCE_END(SpcPeImageData)
IMPLEMENT_ASN1_FUNCTIONS(SpcPeImageData);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcIndirectDataContent*, SpcIndirectDataContent_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcLink*, SpcLink_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcPeImageData*, SpcPeImageData_free, NULL);
+5 -2
View File
@@ -6,7 +6,10 @@ executables += [
'conditions' : [
'HAVE_OPENSSL',
],
'sources' : files('sbsign.c'),
'dependencies' : libopenssl,
'sources' : files(
'sbsign.c',
'authenticode.c',
),
'dependencies' : libopenssl_cflags,
},
]
+68 -63
View File
@@ -4,9 +4,11 @@
#include "alloc-util.h"
#include "ansi-color.h"
#include "ask-password-api.h"
#include "authenticode.h"
#include "build.h"
#include "copy.h"
#include "crypto-util.h"
#include "efi-fundamental.h"
#include "fd-util.h"
#include "fileio.h"
@@ -16,7 +18,6 @@
#include "io-util.h"
#include "log.h"
#include "main-func.h"
#include "openssl-util.h"
#include "options.h"
#include "parse-argument.h"
#include "pe-binary.h"
@@ -203,13 +204,13 @@ static int spc_indirect_data_content_new(const void *digest, size_t digestsz, ui
return log_oom();
link->value.file->type = 0;
link->value.file->value.unicode = ASN1_BMPSTRING_new();
link->value.file->value.unicode = sym_ASN1_BMPSTRING_new();
if (!link->value.file->value.unicode)
return log_oom();
if (ASN1_STRING_set(link->value.file->value.unicode, obsolete, sizeof(obsolete)) == 0)
if (sym_ASN1_STRING_set(link->value.file->value.unicode, obsolete, sizeof(obsolete)) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set ASN1 string: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
_cleanup_(SpcPeImageData_freep) SpcPeImageData *peid = SpcPeImageData_new();
if (!peid)
@@ -221,46 +222,46 @@ static int spc_indirect_data_content_new(const void *digest, size_t digestsz, ui
int peidrawsz = i2d_SpcPeImageData(peid, &peidraw);
if (peidrawsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert SpcPeImageData to BER: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
_cleanup_(SpcIndirectDataContent_freep) SpcIndirectDataContent *idc = SpcIndirectDataContent_new();
idc->data->value = ASN1_TYPE_new();
idc->data->value = sym_ASN1_TYPE_new();
if (!idc->data->value)
return log_oom();
idc->data->value->type = V_ASN1_SEQUENCE;
idc->data->value->value.sequence = ASN1_STRING_new();
idc->data->value->value.sequence = sym_ASN1_STRING_new();
if (!idc->data->value->value.sequence)
return log_oom();
idc->data->type = OBJ_txt2obj(SPC_PE_IMAGE_DATA_OBJID, /* no_name= */ 1);
idc->data->type = sym_OBJ_txt2obj(SPC_PE_IMAGE_DATA_OBJID, /* no_name= */ 1);
if (!idc->data->type)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SpcPeImageData object: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (!ASN1_STRING_set(idc->data->value->value.sequence, peidraw, peidrawsz))
if (!sym_ASN1_STRING_set(idc->data->value->value.sequence, peidraw, peidrawsz))
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set ASN1_STRING data.");
idc->messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(NID_sha256);
idc->messageDigest->digestAlgorithm->algorithm = sym_OBJ_nid2obj(NID_sha256);
if (!idc->messageDigest->digestAlgorithm->algorithm)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SHA256 object: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
idc->messageDigest->digestAlgorithm->parameters = ASN1_TYPE_new();
idc->messageDigest->digestAlgorithm->parameters = sym_ASN1_TYPE_new();
if (!idc->messageDigest->digestAlgorithm->parameters)
return log_oom();
idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
if (ASN1_OCTET_STRING_set(idc->messageDigest->digest, digest, digestsz) == 0)
if (sym_ASN1_OCTET_STRING_set(idc->messageDigest->digest, digest, digestsz) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set digest: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
_cleanup_free_ uint8_t *idcraw = NULL;
int idcrawsz = i2d_SpcIndirectDataContent(idc, &idcraw);
if (idcrawsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert SpcIndirectDataContent to BER: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
*ret_idc = TAKE_PTR(idcraw);
*ret_idcsz = (size_t) idcrawsz;
@@ -276,12 +277,12 @@ static int asn1_timestamp(ASN1_TIME **ret) {
usec_t epoch = parse_source_date_epoch();
if (epoch == USEC_INFINITY) {
time = X509_gmtime_adj(NULL, 0);
time = sym_X509_gmtime_adj(NULL, 0);
if (!time)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get current time: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
} else {
time = ASN1_TIME_set(NULL, (time_t) (epoch / USEC_PER_SEC));
time = sym_ASN1_TIME_set(NULL, (time_t) (epoch / USEC_PER_SEC));
if (!time)
return log_oom();
}
@@ -323,37 +324,37 @@ static int pkcs7_new_with_attributes(
}
/* Add an empty SMIMECAP attribute to indicate we don't have any SMIME capabilities. */
_cleanup_(x509_algor_free_manyp) STACK_OF(X509_ALGOR) *smcap = sk_X509_ALGOR_new_null();
_cleanup_(x509_algor_free_manyp) STACK_OF(X509_ALGOR) *smcap = (STACK_OF(X509_ALGOR)*) sym_OPENSSL_sk_new_null();
if (!smcap)
return log_oom();
if (PKCS7_add_attrib_smimecap(si, smcap) == 0)
if (sym_PKCS7_add_attrib_smimecap(si, smcap) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add smimecap signed attribute to signer info: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (PKCS7_add_attrib_content_type(si, NULL) == 0)
if (sym_PKCS7_add_attrib_content_type(si, NULL) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add content type signed attribute to signer info: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
_cleanup_(ASN1_TIME_freep) ASN1_TIME *time = NULL;
r = asn1_timestamp(&time);
if (r < 0)
return r;
if (PKCS7_add0_attrib_signing_time(si, time) == 0)
if (sym_PKCS7_add0_attrib_signing_time(si, time) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add signing time signed attribute to signer info: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
TAKE_PTR(time);
ASN1_OBJECT *idc = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
ASN1_OBJECT *idc = sym_OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
if (!idc)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SpcIndirectDataContent object: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, idc) == 0)
if (sym_PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, idc) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add signed attribute to pkcs7 signer info: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
*ret_p7 = TAKE_PTR(p7);
*ret_si = TAKE_PTR(si);
@@ -363,23 +364,23 @@ static int pkcs7_new_with_attributes(
static int pkcs7_populate_data_bio(PKCS7* p7, const void *data, size_t size, BIO **ret) {
assert(ret);
_cleanup_(BIO_free_allp) BIO *bio = PKCS7_dataInit(p7, NULL);
_cleanup_(BIO_free_allp) BIO *bio = sym_PKCS7_dataInit(p7, NULL);
if (!bio)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to create PKCS7 data bio: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
int tag, class;
long psz;
const uint8_t *p = data;
/* This function weirdly enough reports errors by setting the 0x80 bit in its return value. */
if (ASN1_get_object(&p, &psz, &tag, &class, size) & 0x80)
if (sym_ASN1_get_object(&p, &psz, &tag, &class, size) & 0x80)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse ASN.1 object: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (BIO_write(bio, p, psz) < 0)
if (sym_BIO_write(bio, p, psz) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write to PKCS7 data bio: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
*ret = TAKE_PTR(bio);
@@ -391,26 +392,26 @@ static int pkcs7_add_digest_attribute(PKCS7 *p7, BIO *data, PKCS7_SIGNER_INFO *s
assert(data);
assert(si);
BIO *mdbio = BIO_find_type(data, BIO_TYPE_MD);
BIO *mdbio = sym_BIO_find_type(data, BIO_TYPE_MD);
if (!mdbio)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to find digest bio: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
EVP_MD_CTX *mdc;
if (BIO_get_md_ctx(mdbio, &mdc) <= 0)
if (sym_BIO_get_md_ctx(mdbio, &mdc) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest context from bio: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned digestsz;
if (EVP_DigestFinal_ex(mdc, digest, &digestsz) == 0)
if (sym_EVP_DigestFinal_ex(mdc, digest, &digestsz) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (PKCS7_add1_attrib_digest(si, digest, digestsz) == 0)
if (sym_PKCS7_add1_attrib_digest(si, digest, digestsz) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add PKCS9 message digest signed attribute to signer info: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
return 0;
}
@@ -425,6 +426,10 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(iovec_done) struct iovec signed_attributes_signature = {};
int r;
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
if (argc < 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No input file specified");
@@ -487,9 +492,9 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
return log_error_errno(r, "Failed to read signed attributes file '%s': %m", arg_signed_data);
const uint8_t *p = content;
if (!ASN1_item_d2i((ASN1_VALUE **) &signed_attributes, &p, contentsz, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)))
if (!sym_ASN1_item_d2i((ASN1_VALUE **) &signed_attributes, &p, contentsz, sym_PKCS7_ATTR_SIGN_it()))
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse signed attributes: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
}
if (arg_signed_data_signature) {
@@ -526,7 +531,7 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_free_ void *pehash = NULL;
size_t pehashsz;
r = pe_hash(srcfd, EVP_sha256(), &pehash, &pehashsz);
r = pe_hash(srcfd, sym_EVP_sha256(), &pehash, &pehashsz);
if (r < 0)
return log_error_errno(r, "Failed to hash PE binary %s: %m", argv[0]);
@@ -555,10 +560,10 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
return r;
_cleanup_free_ unsigned char *abuf = NULL;
int alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
int alen = sym_ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, sym_PKCS7_ATTR_SIGN_it());
if (alen < 0 || !abuf)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert signed attributes ASN.1 to DER: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
r = loop_write(dstfd, abuf, alen);
if (r < 0)
@@ -573,51 +578,51 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
}
if (iovec_is_set(&signed_attributes_signature))
ASN1_STRING_set0(si->enc_digest, TAKE_PTR(signed_attributes_signature.iov_base), signed_attributes_signature.iov_len);
sym_ASN1_STRING_set0(si->enc_digest, TAKE_PTR(signed_attributes_signature.iov_base), signed_attributes_signature.iov_len);
else {
_cleanup_(BIO_free_allp) BIO *bio = NULL;
r = pkcs7_populate_data_bio(p7, idcraw, idcrawsz, &bio);
if (r < 0)
return r;
if (PKCS7_dataFinal(p7, bio) == 0)
if (sym_PKCS7_dataFinal(p7, bio) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to sign data: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
}
_cleanup_(PKCS7_freep) PKCS7 *p7c = PKCS7_new();
_cleanup_(PKCS7_freep) PKCS7 *p7c = sym_PKCS7_new();
if (!p7c)
return log_oom();
p7c->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
p7c->type = sym_OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
if (!p7c->type)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SpcIndirectDataContent object: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
p7c->d.other = ASN1_TYPE_new();
p7c->d.other = sym_ASN1_TYPE_new();
if (!p7c->d.other)
return log_oom();
p7c->d.other->type = V_ASN1_SEQUENCE;
p7c->d.other->value.sequence = ASN1_STRING_new();
p7c->d.other->value.sequence = sym_ASN1_STRING_new();
if (!p7c->d.other->value.sequence)
return log_oom();
if (ASN1_STRING_set(p7c->d.other->value.sequence, idcraw, idcrawsz) == 0)
if (sym_ASN1_STRING_set(p7c->d.other->value.sequence, idcraw, idcrawsz) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set ASN1 string: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (PKCS7_set_content(p7, p7c) == 0)
if (sym_PKCS7_set_content(p7, p7c) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 data: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
TAKE_PTR(p7c);
_cleanup_free_ uint8_t *sig = NULL;
int sigsz = i2d_PKCS7(p7, &sig);
int sigsz = sym_i2d_PKCS7(p7, &sig);
if (sigsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
_cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
_cleanup_free_ PeHeader *pe_header = NULL;
+57 -48
View File
@@ -6,10 +6,6 @@
#include "efivars.h"
#include "time-util.h"
#if HAVE_OPENSSL
#include <openssl/err.h>
#endif
#include "sd-id128.h"
#include "sd-json.h"
#include "sd-varlink.h"
@@ -19,6 +15,7 @@
#include "chattr-util.h"
#include "copy.h"
#include "creds-util.h"
#include "crypto-util.h"
#include "efi-api.h"
#include "env-util.h"
#include "errno-util.h"
@@ -32,7 +29,6 @@
#include "log.h"
#include "memory-util.h"
#include "mkdir-label.h"
#include "openssl-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "random-util.h"
@@ -734,6 +730,7 @@ static int sha256_hash_host_and_tpm2_key(
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *md = NULL;
unsigned l;
int r;
assert(iovec_is_valid(host_key));
assert(iovec_is_valid(tpm2_key));
@@ -741,22 +738,26 @@ static int sha256_hash_host_and_tpm2_key(
/* Combines the host key and the TPM2 HMAC hash into a SHA256 hash value we'll use as symmetric encryption key. */
md = EVP_MD_CTX_new();
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
md = sym_EVP_MD_CTX_new();
if (!md)
return log_oom();
if (EVP_DigestInit_ex(md, EVP_sha256(), NULL) != 1)
if (sym_EVP_DigestInit_ex(md, sym_EVP_sha256(), NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initial SHA256 context.");
if (iovec_is_set(host_key) && EVP_DigestUpdate(md, host_key->iov_base, host_key->iov_len) != 1)
if (iovec_is_set(host_key) && sym_EVP_DigestUpdate(md, host_key->iov_base, host_key->iov_len) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to hash host key.");
if (iovec_is_set(tpm2_key) && EVP_DigestUpdate(md, tpm2_key->iov_base, tpm2_key->iov_len) != 1)
if (iovec_is_set(tpm2_key) && sym_EVP_DigestUpdate(md, tpm2_key->iov_base, tpm2_key->iov_len) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to hash TPM2 key.");
assert(EVP_MD_CTX_size(md) == SHA256_DIGEST_LENGTH);
assert(sym_EVP_MD_CTX_get_size(md) == SHA256_DIGEST_LENGTH);
if (EVP_DigestFinal_ex(md, ret, &l) != 1)
if (sym_EVP_DigestFinal_ex(md, ret, &l) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize SHA256 hash.");
assert(l == SHA256_DIGEST_LENGTH);
@@ -1039,16 +1040,20 @@ int encrypt_credential_and_warn(
return r;
}
assert_se(cc = EVP_aes_256_gcm());
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
ksz = EVP_CIPHER_key_length(cc);
assert_se(cc = sym_EVP_aes_256_gcm());
ksz = sym_EVP_CIPHER_get_key_length(cc);
assert(ksz == sizeof(md));
bsz = EVP_CIPHER_block_size(cc);
bsz = sym_EVP_CIPHER_get_block_size(cc);
assert(bsz > 0);
assert((size_t) bsz <= CREDENTIAL_FIELD_SIZE_MAX);
ivsz = EVP_CIPHER_iv_length(cc);
ivsz = sym_EVP_CIPHER_get_iv_length(cc);
if (ivsz > 0) {
assert((size_t) ivsz <= CREDENTIAL_FIELD_SIZE_MAX);
@@ -1059,14 +1064,14 @@ int encrypt_credential_and_warn(
tsz = 16; /* FIXME: On OpenSSL 3 there is EVP_CIPHER_CTX_get_tag_length(), until then let's hardcode this */
context = EVP_CIPHER_CTX_new();
context = sym_EVP_CIPHER_CTX_new();
if (!context)
return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to allocate encryption object: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (EVP_EncryptInit_ex(context, cc, NULL, md, iv.iov_base) != 1)
if (sym_EVP_EncryptInit_ex(context, cc, NULL, md, iv.iov_base) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
/* Just an upper estimate */
output.iov_len =
@@ -1131,9 +1136,9 @@ int encrypt_credential_and_warn(
}
/* Pass the encrypted + TPM2 header + scoped header as AAD */
if (EVP_EncryptUpdate(context, NULL, &added, output.iov_base, p) != 1)
if (sym_EVP_EncryptUpdate(context, NULL, &added, output.iov_base, p) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to write AAD data: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
/* Now construct the metadata header */
ml = strlen_ptr(name);
@@ -1147,27 +1152,27 @@ int encrypt_credential_and_warn(
memcpy_safe(m->name, name, ml);
/* And encrypt the metadata header */
if (EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, (const unsigned char*) m, ALIGN8(offsetof(struct metadata_credential_header, name) + ml)) != 1)
if (sym_EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, (const unsigned char*) m, ALIGN8(offsetof(struct metadata_credential_header, name) + ml)) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt metadata header: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
assert(added >= 0);
assert((size_t) added <= output.iov_len - p);
p += added;
/* Then encrypt the plaintext */
if (EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, input->iov_base, input->iov_len) != 1)
if (sym_EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, input->iov_base, input->iov_len) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt data: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
assert(added >= 0);
assert((size_t) added <= output.iov_len - p);
p += added;
/* Finalize */
if (EVP_EncryptFinal_ex(context, (uint8_t*) output.iov_base + p, &added) != 1)
if (sym_EVP_EncryptFinal_ex(context, (uint8_t*) output.iov_base + p, &added) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize data encryption: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
assert(added >= 0);
assert((size_t) added <= output.iov_len - p);
@@ -1176,9 +1181,9 @@ int encrypt_credential_and_warn(
assert(p <= output.iov_len - tsz);
/* Append tag */
if (EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_GET_TAG, tsz, (uint8_t*) output.iov_base + p) != 1)
if (sym_EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_GET_TAG, tsz, (uint8_t*) output.iov_base + p) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get tag: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
p += tsz;
assert(p <= output.iov_len);
@@ -1435,59 +1440,63 @@ int decrypt_credential_and_warn(
return r;
}
assert_se(cc = EVP_aes_256_gcm());
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
assert_se(cc = sym_EVP_aes_256_gcm());
/* Make sure cipher expectations match the header */
if (EVP_CIPHER_key_length(cc) != (int) le32toh(h->key_size))
if (sym_EVP_CIPHER_get_key_length(cc) != (int) le32toh(h->key_size))
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Unexpected key size in header.");
if (EVP_CIPHER_block_size(cc) != (int) le32toh(h->block_size))
if (sym_EVP_CIPHER_get_block_size(cc) != (int) le32toh(h->block_size))
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Unexpected block size in header.");
context = EVP_CIPHER_CTX_new();
context = sym_EVP_CIPHER_CTX_new();
if (!context)
return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to allocate decryption object: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (EVP_DecryptInit_ex(context, cc, NULL, NULL, NULL) != 1)
if (sym_EVP_DecryptInit_ex(context, cc, NULL, NULL, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_IVLEN, le32toh(h->iv_size), NULL) != 1)
if (sym_EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_IVLEN, le32toh(h->iv_size), NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set IV size on decryption context: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (EVP_DecryptInit_ex(context, NULL, NULL, md, h->iv) != 1)
if (sym_EVP_DecryptInit_ex(context, NULL, NULL, md, h->iv) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set IV and key: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (EVP_DecryptUpdate(context, NULL, &added, input->iov_base, p) != 1)
if (sym_EVP_DecryptUpdate(context, NULL, &added, input->iov_base, p) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to write AAD data: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
plaintext.iov_base = malloc(input->iov_len - p - le32toh(h->tag_size));
if (!plaintext.iov_base)
return -ENOMEM;
if (EVP_DecryptUpdate(
if (sym_EVP_DecryptUpdate(
context,
plaintext.iov_base,
&added,
(uint8_t*) input->iov_base + p,
input->iov_len - p - le32toh(h->tag_size)) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to decrypt data: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
assert(added >= 0);
assert((size_t) added <= input->iov_len - p - le32toh(h->tag_size));
plaintext.iov_len = added;
if (EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_TAG, le32toh(h->tag_size), (uint8_t*) input->iov_base + input->iov_len - le32toh(h->tag_size)) != 1)
if (sym_EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_TAG, le32toh(h->tag_size), (uint8_t*) input->iov_base + input->iov_len - le32toh(h->tag_size)) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set tag: %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
if (EVP_DecryptFinal_ex(context, (uint8_t*) plaintext.iov_base + plaintext.iov_len, &added) != 1)
if (sym_EVP_DecryptFinal_ex(context, (uint8_t*) plaintext.iov_base + plaintext.iov_len, &added) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Decryption failed (incorrect key?): %s",
ERR_error_string(ERR_get_error(), NULL));
sym_ERR_error_string(sym_ERR_get_error(), NULL));
plaintext.iov_len += added;
File diff suppressed because it is too large Load Diff
+406
View File
@@ -0,0 +1,406 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "shared-forward.h"
#include "iovec-util.h"
#include "sha256.h"
typedef enum CertificateSourceType {
OPENSSL_CERTIFICATE_SOURCE_FILE,
OPENSSL_CERTIFICATE_SOURCE_PROVIDER,
_OPENSSL_CERTIFICATE_SOURCE_MAX,
_OPENSSL_CERTIFICATE_SOURCE_INVALID = -EINVAL,
} CertificateSourceType;
typedef enum KeySourceType {
OPENSSL_KEY_SOURCE_FILE,
OPENSSL_KEY_SOURCE_ENGINE,
OPENSSL_KEY_SOURCE_PROVIDER,
_OPENSSL_KEY_SOURCE_MAX,
_OPENSSL_KEY_SOURCE_INVALID = -EINVAL,
} KeySourceType;
typedef struct OpenSSLAskPasswordUI OpenSSLAskPasswordUI;
int parse_openssl_certificate_source_argument(const char *argument, char **certificate_source, CertificateSourceType *certificate_source_type);
int parse_openssl_key_source_argument(const char *argument, char **private_key_source, KeySourceType *private_key_source_type);
int dlopen_libcrypto(int log_level);
#define X509_FINGERPRINT_SIZE SHA256_DIGEST_SIZE
#if HAVE_OPENSSL
# include <openssl/bio.h> /* IWYU pragma: export */
# include <openssl/bn.h> /* IWYU pragma: export */
# include <openssl/crypto.h> /* IWYU pragma: export */
# include <openssl/ec.h> /* IWYU pragma: export */
# include <openssl/err.h> /* IWYU pragma: export */
# include <openssl/evp.h> /* IWYU pragma: export */
# include <openssl/hmac.h> /* IWYU pragma: export */
# include <openssl/param_build.h> /* IWYU pragma: export */
# include <openssl/pem.h> /* IWYU pragma: export */
# include <openssl/pkcs7.h> /* IWYU pragma: export */
# include <openssl/rsa.h> /* IWYU pragma: export */
# include <openssl/sha.h> /* IWYU pragma: export */
# include "dlfcn-util.h"
extern DLSYM_PROTOTYPE(ASN1_ANY_it);
extern DLSYM_PROTOTYPE(ASN1_BIT_STRING_it);
extern DLSYM_PROTOTYPE(ASN1_BMPSTRING_it);
extern DLSYM_PROTOTYPE(ASN1_BMPSTRING_new);
extern DLSYM_PROTOTYPE(ASN1_get_object);
extern DLSYM_PROTOTYPE(ASN1_IA5STRING_it);
extern DLSYM_PROTOTYPE(ASN1_item_d2i);
extern DLSYM_PROTOTYPE(ASN1_item_free);
extern DLSYM_PROTOTYPE(ASN1_item_i2d);
extern DLSYM_PROTOTYPE(ASN1_item_new);
extern DLSYM_PROTOTYPE(ASN1_OBJECT_it);
extern DLSYM_PROTOTYPE(ASN1_OCTET_STRING_free);
extern DLSYM_PROTOTYPE(ASN1_OCTET_STRING_it);
extern DLSYM_PROTOTYPE(ASN1_OCTET_STRING_set);
extern DLSYM_PROTOTYPE(ASN1_STRING_get0_data);
extern DLSYM_PROTOTYPE(ASN1_STRING_length);
extern DLSYM_PROTOTYPE(ASN1_STRING_new);
extern DLSYM_PROTOTYPE(ASN1_STRING_set);
extern DLSYM_PROTOTYPE(ASN1_STRING_set0);
extern DLSYM_PROTOTYPE(ASN1_TIME_free);
extern DLSYM_PROTOTYPE(ASN1_TIME_set);
extern DLSYM_PROTOTYPE(ASN1_TYPE_new);
extern DLSYM_PROTOTYPE(BIO_ctrl);
extern DLSYM_PROTOTYPE(BIO_find_type);
extern DLSYM_PROTOTYPE(BIO_free_all);
extern DLSYM_PROTOTYPE(BIO_free);
extern DLSYM_PROTOTYPE(BIO_new_mem_buf);
extern DLSYM_PROTOTYPE(BIO_new_socket);
extern DLSYM_PROTOTYPE(BIO_new);
extern DLSYM_PROTOTYPE(BIO_s_mem);
extern DLSYM_PROTOTYPE(BIO_write);
extern DLSYM_PROTOTYPE(BN_bin2bn);
extern DLSYM_PROTOTYPE(BN_bn2nativepad);
extern DLSYM_PROTOTYPE(BN_CTX_free);
extern DLSYM_PROTOTYPE(BN_CTX_new);
extern DLSYM_PROTOTYPE(BN_free);
extern DLSYM_PROTOTYPE(BN_new);
extern DLSYM_PROTOTYPE(BN_num_bits);
extern DLSYM_PROTOTYPE(CRYPTO_free);
extern DLSYM_PROTOTYPE(d2i_ASN1_OCTET_STRING);
extern DLSYM_PROTOTYPE(d2i_ECPKParameters);
extern DLSYM_PROTOTYPE(d2i_PKCS7);
extern DLSYM_PROTOTYPE(d2i_PUBKEY);
extern DLSYM_PROTOTYPE(d2i_X509);
extern DLSYM_PROTOTYPE(EC_GROUP_free);
extern DLSYM_PROTOTYPE(EC_GROUP_get_curve_name);
extern DLSYM_PROTOTYPE(EC_GROUP_get_curve);
extern DLSYM_PROTOTYPE(EC_GROUP_get_field_type);
extern DLSYM_PROTOTYPE(EC_GROUP_get0_generator);
extern DLSYM_PROTOTYPE(EC_GROUP_get0_order);
extern DLSYM_PROTOTYPE(EC_GROUP_new_by_curve_name);
extern DLSYM_PROTOTYPE(EC_POINT_free);
extern DLSYM_PROTOTYPE(EC_POINT_new);
extern DLSYM_PROTOTYPE(EC_POINT_oct2point);
extern DLSYM_PROTOTYPE(EC_POINT_point2oct);
extern DLSYM_PROTOTYPE(ECDSA_SIG_free);
extern DLSYM_PROTOTYPE(ERR_clear_error);
extern DLSYM_PROTOTYPE(ERR_error_string_n);
extern DLSYM_PROTOTYPE(ERR_error_string);
extern DLSYM_PROTOTYPE(ERR_get_error);
extern DLSYM_PROTOTYPE(EVP_aes_256_ctr);
extern DLSYM_PROTOTYPE(EVP_aes_256_gcm);
extern DLSYM_PROTOTYPE(EVP_CIPHER_CTX_ctrl);
extern DLSYM_PROTOTYPE(EVP_CIPHER_CTX_free);
extern DLSYM_PROTOTYPE(EVP_CIPHER_CTX_new);
extern DLSYM_PROTOTYPE(EVP_CIPHER_free);
extern DLSYM_PROTOTYPE(EVP_CIPHER_get_block_size);
extern DLSYM_PROTOTYPE(EVP_CIPHER_get_iv_length);
extern DLSYM_PROTOTYPE(EVP_CIPHER_get_key_length);
extern DLSYM_PROTOTYPE(EVP_DecryptFinal_ex);
extern DLSYM_PROTOTYPE(EVP_DecryptInit_ex);
extern DLSYM_PROTOTYPE(EVP_DecryptUpdate);
extern DLSYM_PROTOTYPE(EVP_Digest);
extern DLSYM_PROTOTYPE(EVP_DigestFinal_ex);
extern DLSYM_PROTOTYPE(EVP_DigestInit_ex);
extern DLSYM_PROTOTYPE(EVP_DigestUpdate);
extern DLSYM_PROTOTYPE(EVP_DigestVerify);
extern DLSYM_PROTOTYPE(EVP_DigestVerifyInit);
extern DLSYM_PROTOTYPE(EVP_EncryptFinal_ex);
extern DLSYM_PROTOTYPE(EVP_EncryptInit_ex);
extern DLSYM_PROTOTYPE(EVP_EncryptUpdate);
extern DLSYM_PROTOTYPE(EVP_get_cipherbyname);
extern DLSYM_PROTOTYPE(EVP_get_digestbyname);
extern DLSYM_PROTOTYPE(EVP_MAC_CTX_free);
extern DLSYM_PROTOTYPE(EVP_MAC_free);
extern DLSYM_PROTOTYPE(EVP_MD_CTX_free);
extern DLSYM_PROTOTYPE(EVP_MD_CTX_get0_md);
extern DLSYM_PROTOTYPE(EVP_MD_CTX_new);
extern DLSYM_PROTOTYPE(EVP_MD_CTX_set_pkey_ctx);
extern DLSYM_PROTOTYPE(EVP_MD_free);
extern DLSYM_PROTOTYPE(EVP_MD_get_size);
extern DLSYM_PROTOTYPE(EVP_MD_get0_name);
extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_free);
extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_new_from_name);
extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_new_id);
extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_new);
extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_rsa_padding);
extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_signature_md);
extern DLSYM_PROTOTYPE(EVP_PKEY_eq);
extern DLSYM_PROTOTYPE(EVP_PKEY_free);
extern DLSYM_PROTOTYPE(EVP_PKEY_fromdata_init);
extern DLSYM_PROTOTYPE(EVP_PKEY_fromdata);
extern DLSYM_PROTOTYPE(EVP_PKEY_get_id);
extern DLSYM_PROTOTYPE(EVP_PKEY_keygen_init);
extern DLSYM_PROTOTYPE(EVP_PKEY_keygen);
extern DLSYM_PROTOTYPE(EVP_PKEY_new_raw_public_key);
extern DLSYM_PROTOTYPE(EVP_PKEY_new);
extern DLSYM_PROTOTYPE(EVP_PKEY_verify_init);
extern DLSYM_PROTOTYPE(EVP_PKEY_verify);
extern DLSYM_PROTOTYPE(EVP_sha1);
extern DLSYM_PROTOTYPE(EVP_sha256);
extern DLSYM_PROTOTYPE(EVP_sha384);
extern DLSYM_PROTOTYPE(EVP_sha512);
extern DLSYM_PROTOTYPE(HMAC);
extern DLSYM_PROTOTYPE(i2d_ASN1_INTEGER);
extern DLSYM_PROTOTYPE(i2d_PKCS7_fp);
extern DLSYM_PROTOTYPE(i2d_PKCS7);
extern DLSYM_PROTOTYPE(i2d_PUBKEY);
extern DLSYM_PROTOTYPE(i2d_X509_NAME);
extern DLSYM_PROTOTYPE(i2d_X509);
extern DLSYM_PROTOTYPE(OBJ_nid2obj);
extern DLSYM_PROTOTYPE(OBJ_nid2sn);
extern DLSYM_PROTOTYPE(OBJ_sn2nid);
extern DLSYM_PROTOTYPE(OBJ_txt2obj);
extern DLSYM_PROTOTYPE(OPENSSL_sk_new_null);
extern DLSYM_PROTOTYPE(OPENSSL_sk_num);
extern DLSYM_PROTOTYPE(OPENSSL_sk_pop_free);
extern DLSYM_PROTOTYPE(OPENSSL_sk_push);
extern DLSYM_PROTOTYPE(OPENSSL_sk_value);
extern DLSYM_PROTOTYPE(OSSL_EC_curve_nid2name);
extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_BN);
extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_end);
extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_octet_string);
extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_utf8_string);
extern DLSYM_PROTOTYPE(OSSL_PARAM_free);
extern DLSYM_PROTOTYPE(PEM_read_PrivateKey);
extern DLSYM_PROTOTYPE(PEM_read_PUBKEY);
extern DLSYM_PROTOTYPE(PEM_read_X509);
extern DLSYM_PROTOTYPE(PEM_write_PrivateKey);
extern DLSYM_PROTOTYPE(PEM_write_PUBKEY);
extern DLSYM_PROTOTYPE(PEM_write_X509);
extern DLSYM_PROTOTYPE(PKCS5_PBKDF2_HMAC);
extern DLSYM_PROTOTYPE(PKCS7_add_attrib_content_type);
extern DLSYM_PROTOTYPE(PKCS7_add_attrib_smimecap);
extern DLSYM_PROTOTYPE(PKCS7_add_signed_attribute);
extern DLSYM_PROTOTYPE(PKCS7_add0_attrib_signing_time);
extern DLSYM_PROTOTYPE(PKCS7_add1_attrib_digest);
extern DLSYM_PROTOTYPE(PKCS7_ATTR_SIGN_it);
extern DLSYM_PROTOTYPE(PKCS7_content_new);
extern DLSYM_PROTOTYPE(PKCS7_ctrl);
extern DLSYM_PROTOTYPE(PKCS7_dataFinal);
extern DLSYM_PROTOTYPE(PKCS7_dataInit);
extern DLSYM_PROTOTYPE(PKCS7_free);
extern DLSYM_PROTOTYPE(PKCS7_get_signer_info);
extern DLSYM_PROTOTYPE(PKCS7_new);
extern DLSYM_PROTOTYPE(PKCS7_set_content);
extern DLSYM_PROTOTYPE(PKCS7_sign);
extern DLSYM_PROTOTYPE(PKCS7_SIGNER_INFO_free);
extern DLSYM_PROTOTYPE(PKCS7_verify);
extern DLSYM_PROTOTYPE(SHA1);
extern DLSYM_PROTOTYPE(SHA512);
extern DLSYM_PROTOTYPE(X509_ALGOR_free);
extern DLSYM_PROTOTYPE(X509_ATTRIBUTE_free);
extern DLSYM_PROTOTYPE(X509_free);
extern DLSYM_PROTOTYPE(X509_get_pubkey);
extern DLSYM_PROTOTYPE(X509_get_subject_name);
extern DLSYM_PROTOTYPE(X509_gmtime_adj);
extern DLSYM_PROTOTYPE(X509_NAME_free);
extern DLSYM_PROTOTYPE(X509_NAME_oneline);
extern DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set_hostflags);
extern DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set1_host);
extern DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set1_ip);
#if !defined(OPENSSL_NO_DEPRECATED_3_0)
DISABLE_WARNING_DEPRECATED_DECLARATIONS;
extern DLSYM_PROTOTYPE(ECDSA_SIG_new);
extern DLSYM_PROTOTYPE(ECDSA_SIG_set0);
extern DLSYM_PROTOTYPE(ECDSA_do_verify);
extern DLSYM_PROTOTYPE(EC_KEY_check_key);
extern DLSYM_PROTOTYPE(EC_KEY_free);
extern DLSYM_PROTOTYPE(EC_KEY_new);
extern DLSYM_PROTOTYPE(EC_KEY_set_group);
extern DLSYM_PROTOTYPE(EC_KEY_set_public_key);
extern DLSYM_PROTOTYPE(EVP_PKEY_assign);
extern DLSYM_PROTOTYPE(RSA_free);
extern DLSYM_PROTOTYPE(RSA_new);
extern DLSYM_PROTOTYPE(RSA_set0_key);
extern DLSYM_PROTOTYPE(RSA_size);
extern DLSYM_PROTOTYPE(RSAPublicKey_dup);
REENABLE_WARNING;
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EC_KEY*, sym_EC_KEY_free, EC_KEY_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(RSA*, sym_RSA_free, RSA_freep, NULL);
#endif
/* Mirrors of OpenSSL macros that go through our dlopen'd sym_* variants, so we don't end up linking against
* libcrypto just for these. */
#define sym_BIO_get_md_ctx(b, mdcp) sym_BIO_ctrl((b), BIO_C_GET_MD_CTX, 0, (char*) (mdcp))
#define sym_BIO_get_mem_ptr(b, pp) sym_BIO_ctrl((b), BIO_C_GET_BUF_MEM_PTR, 0, (char *) (pp))
#define sym_BIO_reset(b) sym_BIO_ctrl((b), BIO_CTRL_RESET, 0, NULL)
#define sym_BN_num_bytes(a) ((sym_BN_num_bits(a) + 7) / 8)
#define sym_EVP_MD_CTX_get_size(ctx) sym_EVP_MD_get_size(sym_EVP_MD_CTX_get0_md(ctx))
#define sym_EVP_MD_CTX_get0_name(ctx) sym_EVP_MD_get0_name(sym_EVP_MD_CTX_get0_md(ctx))
#define sym_EVP_PKEY_assign_RSA(pkey, rsa) sym_EVP_PKEY_assign((pkey), EVP_PKEY_RSA, (rsa))
#define sym_OPENSSL_free(addr) sym_CRYPTO_free((addr), OPENSSL_FILE, OPENSSL_LINE)
#define sym_PKCS7_set_detached(p, v) sym_PKCS7_ctrl((p), PKCS7_OP_SET_DETACHED_SIGNATURE, (v), NULL)
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO_RENAME(void*, sym_OPENSSL_free, OPENSSL_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(ASN1_OCTET_STRING*, sym_ASN1_OCTET_STRING_free, ASN1_OCTET_STRING_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(ASN1_TIME*, sym_ASN1_TIME_free, ASN1_TIME_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BIGNUM*, sym_BN_free, BN_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BIO*, sym_BIO_free_all, BIO_free_allp, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BIO*, sym_BIO_free, BIO_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BN_CTX*, sym_BN_CTX_free, BN_CTX_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EC_GROUP*, sym_EC_GROUP_free, EC_GROUP_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EC_POINT*, sym_EC_POINT_free, EC_POINT_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(ECDSA_SIG*, sym_ECDSA_SIG_free, ECDSA_SIG_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_CIPHER_CTX*, sym_EVP_CIPHER_CTX_free, EVP_CIPHER_CTX_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_CIPHER*, sym_EVP_CIPHER_free, EVP_CIPHER_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MAC_CTX*, sym_EVP_MAC_CTX_free, EVP_MAC_CTX_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MAC*, sym_EVP_MAC_free, EVP_MAC_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MD_CTX*, sym_EVP_MD_CTX_free, EVP_MD_CTX_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MD*, sym_EVP_MD_free, EVP_MD_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_PKEY_CTX*, sym_EVP_PKEY_CTX_free, EVP_PKEY_CTX_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_PKEY*, sym_EVP_PKEY_free, EVP_PKEY_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(OSSL_PARAM*, sym_OSSL_PARAM_free, OSSL_PARAM_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(PKCS7_SIGNER_INFO*, sym_PKCS7_SIGNER_INFO_free, PKCS7_SIGNER_INFO_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(PKCS7*, sym_PKCS7_free, PKCS7_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(X509_NAME*, sym_X509_NAME_free, X509_NAME_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(X509*, sym_X509_free, X509_freep, NULL);
/* Stack-of macros that go through the dlopen'd sym_OPENSSL_sk_* variants, mirroring the sk_TYPE_OP() helpers
* from <openssl/x509.h> and friends. */
#define sym_sk_X509_new_null() \
((STACK_OF(X509)*) sym_OPENSSL_sk_new_null())
#define sym_sk_X509_push(sk, ptr) \
sym_OPENSSL_sk_push(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sym_sk_X509_pop_free(sk, freefunc) \
sym_OPENSSL_sk_pop_free(ossl_check_X509_sk_type(sk), ossl_check_X509_freefunc_type(freefunc))
#define sym_sk_X509_ALGOR_pop_free(sk, freefunc) \
sym_OPENSSL_sk_pop_free(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_freefunc_type(freefunc))
#define sym_sk_X509_ATTRIBUTE_pop_free(sk, freefunc) \
sym_OPENSSL_sk_pop_free(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc))
#define sym_sk_PKCS7_SIGNER_INFO_num(sk) \
sym_OPENSSL_sk_num(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk))
#define sym_sk_PKCS7_SIGNER_INFO_value(sk, idx) \
((PKCS7_SIGNER_INFO*) sym_OPENSSL_sk_value(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk), (idx)))
static inline STACK_OF(X509_ALGOR) *x509_algor_free_many(STACK_OF(X509_ALGOR) *attrs) {
if (!attrs)
return NULL;
sym_sk_X509_ALGOR_pop_free(attrs, sym_X509_ALGOR_free);
return NULL;
}
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ALGOR)*, x509_algor_free_many, NULL);
static inline STACK_OF(X509_ATTRIBUTE) *x509_attribute_free_many(STACK_OF(X509_ATTRIBUTE) *attrs) {
if (!attrs)
return NULL;
sym_sk_X509_ATTRIBUTE_pop_free(attrs, sym_X509_ATTRIBUTE_free);
return NULL;
}
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ATTRIBUTE)*, x509_attribute_free_many, NULL);
static inline void sk_X509_free_allp(STACK_OF(X509) **sk) {
if (!sk || !*sk)
return;
sym_sk_X509_pop_free(*sk, sym_X509_free);
}
int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret);
int openssl_pubkey_to_pem(EVP_PKEY *pkey, char **ret);
int openssl_digest_size(const char *digest_alg, size_t *ret_digest_size);
int openssl_digest_many(const char *digest_alg, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
static inline int openssl_digest(const char *digest_alg, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
return openssl_digest_many(digest_alg, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
}
int openssl_hmac_many(const char *digest_alg, const void *key, size_t key_size, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
static inline int openssl_hmac(const char *digest_alg, const void *key, size_t key_size, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
return openssl_hmac_many(digest_alg, key, key_size, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
}
int openssl_cipher_many(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const struct iovec data[], size_t n_data, void **ret, size_t *ret_size);
static inline int openssl_cipher(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const void *buf, size_t len, void **ret, size_t *ret_size) {
return openssl_cipher_many(alg, bits, mode, key, key_size, iv, iv_size, &IOVEC_MAKE((void*) buf, len), 1, ret, ret_size);
}
int kdf_ss_derive(const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, size_t derive_size, void **ret);
int kdf_kb_hmac_derive(const char *mode, const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, const void *seed, size_t seed_size, size_t derive_size, void **ret);
int rsa_encrypt_bytes(EVP_PKEY *pkey, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
int rsa_oaep_encrypt_bytes(const EVP_PKEY *pkey, const char *digest_alg, const char *label, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
int rsa_pkey_to_suitable_key_size(EVP_PKEY *pkey, size_t *ret_suitable_key_size);
int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size, EVP_PKEY **ret);
int rsa_pkey_to_n_e(const EVP_PKEY *pkey, void **ret_n, size_t *ret_n_size, void **ret_e, size_t *ret_e_size);
int ecc_pkey_from_curve_x_y(int curve_id, const void *x, size_t x_size, const void *y, size_t y_size, EVP_PKEY **ret);
int ecc_pkey_to_curve_x_y(const EVP_PKEY *pkey, int *ret_curve_id, void **ret_x, size_t *ret_x_size, void **ret_y, size_t *ret_y_size);
int ecc_pkey_new(int curve_id, EVP_PKEY **ret);
int ecc_ecdh(const EVP_PKEY *private_pkey, const EVP_PKEY *peer_pkey, void **ret_shared_secret, size_t *ret_shared_secret_size);
int pkey_generate_volume_keys(EVP_PKEY *pkey, void **ret_decrypted_key, size_t *ret_decrypted_key_size, void **ret_saved_key, size_t *ret_saved_key_size);
int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_size);
int digest_and_sign(const EVP_MD *md, EVP_PKEY *privkey, const void *data, size_t size, void **ret, size_t *ret_size);
int pkcs7_new(X509 *certificate, EVP_PKEY *private_key, const char *hash_algorithm, PKCS7 **ret_p7, PKCS7_SIGNER_INFO **ret_si);
int string_hashsum(const char *s, size_t len, const char *md_algorithm, char **ret);
static inline int string_hashsum_sha224(const char *s, size_t len, char **ret) {
return string_hashsum(s, len, "SHA224", ret);
}
static inline int string_hashsum_sha256(const char *s, size_t len, char **ret) {
return string_hashsum(s, len, "SHA256", ret);
}
int x509_fingerprint(X509 *cert, uint8_t buffer[static X509_FINGERPRINT_SIZE]);
int openssl_load_x509_certificate(
CertificateSourceType certificate_source_type,
const char *certificate_source,
const char *certificate,
X509 **ret);
int openssl_load_private_key(
KeySourceType private_key_source_type,
const char *private_key_source,
const char *private_key,
const AskPasswordRequest *request,
EVP_PKEY **ret_private_key,
OpenSSLAskPasswordUI **ret_user_interface);
int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret);
OpenSSLAskPasswordUI* openssl_ask_password_ui_free(OpenSSLAskPasswordUI *ui);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OpenSSLAskPasswordUI*, openssl_ask_password_ui_free, NULL);
#endif
+12 -14
View File
@@ -6,12 +6,6 @@
#include <sys/mount.h>
#include <unistd.h>
#if HAVE_OPENSSL
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#endif
#include "sd-device.h"
#include "sd-id128.h"
#include "sd-json.h"
@@ -26,6 +20,7 @@
#include "conf-files.h"
#include "constants.h"
#include "copy.h"
#include "crypto-util.h"
#include "cryptsetup-util.h"
#include "device-private.h"
#include "devnum-util.h"
@@ -57,7 +52,6 @@
#include "mountpoint-util.h"
#include "namespace-util.h"
#include "nulstr-util.h"
#include "openssl-util.h"
#include "os-util.h"
#include "path-util.h"
#include "pcrextend-util.h"
@@ -3087,6 +3081,10 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
assert(iovec_is_set(&verity->root_hash));
assert(iovec_is_set(&verity->root_hash_sig));
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
/* Because installing a signature certificate into the kernel chain is so messy, let's optionally do
* userspace validation. */
@@ -3099,7 +3097,7 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
}
const unsigned char *d = verity->root_hash_sig.iov_base;
p7 = d2i_PKCS7(NULL, &d, (long) verity->root_hash_sig.iov_len);
p7 = sym_d2i_PKCS7(NULL, &d, (long) verity->root_hash_sig.iov_len);
if (!p7)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse PKCS7 DER signature data.");
@@ -3107,11 +3105,11 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
if (!s)
return log_oom_debug();
bio = BIO_new_mem_buf(s, strlen(s));
bio = sym_BIO_new_mem_buf(s, strlen(s));
if (!bio)
return log_oom_debug();
sk = sk_X509_new_null();
sk = sym_sk_X509_new_null();
if (!sk)
return log_oom_debug();
@@ -3125,23 +3123,23 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
continue;
}
c = PEM_read_X509(f, NULL, NULL, NULL);
c = sym_PEM_read_X509(f, NULL, NULL, NULL);
if (!c) {
log_debug("Failed to load X509 certificate '%s', ignoring.", *i);
continue;
}
if (sk_X509_push(sk, c) == 0)
if (sym_sk_X509_push(sk, c) == 0)
return log_oom_debug();
TAKE_PTR(c);
}
r = PKCS7_verify(p7, sk, NULL, bio, NULL, PKCS7_NOINTERN|PKCS7_NOVERIFY);
r = sym_PKCS7_verify(p7, sk, NULL, bio, NULL, PKCS7_NOINTERN|PKCS7_NOVERIFY);
if (r)
log_debug("Userspace PKCS#7 validation succeeded.");
else
log_debug("Userspace PKCS#7 validation failed: %s", ERR_error_string(ERR_get_error(), NULL));
log_debug("Userspace PKCS#7 validation failed: %s", sym_ERR_error_string(sym_ERR_get_error(), NULL));
return r;
#else
+3 -2
View File
@@ -51,6 +51,7 @@ shared_sources = files(
'coredump-util.c',
'cpu-set-util.c',
'creds-util.c',
'crypto-util.c',
'cryptsetup-fido2.c',
'cryptsetup-tpm2.c',
'cryptsetup-util.c',
@@ -151,7 +152,6 @@ shared_sources = files(
'nsresource.c',
'numa-util.c',
'open-file.c',
'openssl-util.c',
'options.c',
'osc-context.c',
'output-mode.c',
@@ -197,6 +197,7 @@ shared_sources = files(
'socket-label.c',
'socket-netlink.c',
'specifier.c',
'ssl-util.c',
'switch-root.c',
'swtpm-util.c',
'tar-util.c',
@@ -400,7 +401,7 @@ libshared_deps = [threads,
libkmod_cflags,
libmicrohttpd_cflags,
libmount_cflags,
libopenssl,
libopenssl_cflags,
libp11kit_cflags,
libpam_cflags,
libpcre2_cflags,
-196
View File
@@ -1,196 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "ask-password-api.h"
#include "shared-forward.h"
#include "iovec-util.h"
#include "sha256.h"
typedef enum CertificateSourceType {
OPENSSL_CERTIFICATE_SOURCE_FILE,
OPENSSL_CERTIFICATE_SOURCE_PROVIDER,
_OPENSSL_CERTIFICATE_SOURCE_MAX,
_OPENSSL_CERTIFICATE_SOURCE_INVALID = -EINVAL,
} CertificateSourceType;
typedef enum KeySourceType {
OPENSSL_KEY_SOURCE_FILE,
OPENSSL_KEY_SOURCE_ENGINE,
OPENSSL_KEY_SOURCE_PROVIDER,
_OPENSSL_KEY_SOURCE_MAX,
_OPENSSL_KEY_SOURCE_INVALID = -EINVAL,
} KeySourceType;
typedef struct OpenSSLAskPasswordUI OpenSSLAskPasswordUI;
int parse_openssl_certificate_source_argument(const char *argument, char **certificate_source, CertificateSourceType *certificate_source_type);
int parse_openssl_key_source_argument(const char *argument, char **private_key_source, KeySourceType *private_key_source_type);
#define X509_FINGERPRINT_SIZE SHA256_DIGEST_SIZE
#if HAVE_OPENSSL
# include <openssl/bio.h> /* IWYU pragma: export */
# include <openssl/bn.h> /* IWYU pragma: export */
# include <openssl/core_names.h> /* IWYU pragma: export */
# include <openssl/crypto.h> /* IWYU pragma: export */
# include <openssl/err.h> /* IWYU pragma: export */
# include <openssl/evp.h> /* IWYU pragma: export */
# include <openssl/kdf.h> /* IWYU pragma: export */
# include <openssl/opensslv.h> /* IWYU pragma: export */
# include <openssl/param_build.h> /* IWYU pragma: export */
# include <openssl/pkcs7.h> /* IWYU pragma: export */
# include <openssl/provider.h> /* IWYU pragma: export */
# include <openssl/ssl.h> /* IWYU pragma: export */
# include <openssl/store.h> /* IWYU pragma: export */
# ifndef OPENSSL_NO_UI_CONSOLE
# include <openssl/ui.h> /* IWYU pragma: export */
# endif
# include <openssl/x509v3.h> /* IWYU pragma: export */
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(void*, OPENSSL_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ASN1_OCTET_STRING*, ASN1_OCTET_STRING_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ASN1_TIME*, ASN1_TIME_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BIO*, BIO_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BIO*, BIO_free_all, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BIGNUM*, BN_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BN_CTX*, BN_CTX_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_GROUP*, EC_GROUP_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_POINT*, EC_POINT_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ECDSA_SIG*, ECDSA_SIG_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_CIPHER*, EVP_CIPHER_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_CIPHER_CTX*, EVP_CIPHER_CTX_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF*, EVP_KDF_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF_CTX*, EVP_KDF_CTX_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC*, EVP_MAC_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC_CTX*, EVP_MAC_CTX_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD*, EVP_MD_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD_CTX*, EVP_MD_CTX_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY*, EVP_PKEY_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY_CTX*, EVP_PKEY_CTX_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM*, OSSL_PARAM_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM_BLD*, OSSL_PARAM_BLD_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_CTX*, OSSL_STORE_close, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_INFO*, OSSL_STORE_INFO_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(PKCS7*, PKCS7_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(PKCS7_SIGNER_INFO*, PKCS7_SIGNER_INFO_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SSL*, SSL_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(X509*, X509_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(X509_NAME*, X509_NAME_free, NULL);
static inline STACK_OF(X509_ALGOR) *x509_algor_free_many(STACK_OF(X509_ALGOR) *attrs) {
if (!attrs)
return NULL;
sk_X509_ALGOR_pop_free(attrs, X509_ALGOR_free);
return NULL;
}
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ALGOR)*, x509_algor_free_many, NULL);
static inline STACK_OF(X509_ATTRIBUTE) *x509_attribute_free_many(STACK_OF(X509_ATTRIBUTE) *attrs) {
if (!attrs)
return NULL;
sk_X509_ATTRIBUTE_pop_free(attrs, X509_ATTRIBUTE_free);
return NULL;
}
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ATTRIBUTE)*, x509_attribute_free_many, NULL);
static inline void sk_X509_free_allp(STACK_OF(X509) **sk) {
if (!sk || !*sk)
return;
sk_X509_pop_free(*sk, X509_free);
}
int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret);
int openssl_pubkey_to_pem(EVP_PKEY *pkey, char **ret);
int openssl_digest_size(const char *digest_alg, size_t *ret_digest_size);
int openssl_digest_many(const char *digest_alg, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
static inline int openssl_digest(const char *digest_alg, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
return openssl_digest_many(digest_alg, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
}
int openssl_hmac_many(const char *digest_alg, const void *key, size_t key_size, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
static inline int openssl_hmac(const char *digest_alg, const void *key, size_t key_size, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
return openssl_hmac_many(digest_alg, key, key_size, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
}
int openssl_cipher_many(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const struct iovec data[], size_t n_data, void **ret, size_t *ret_size);
static inline int openssl_cipher(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const void *buf, size_t len, void **ret, size_t *ret_size) {
return openssl_cipher_many(alg, bits, mode, key, key_size, iv, iv_size, &IOVEC_MAKE((void*) buf, len), 1, ret, ret_size);
}
int kdf_ss_derive(const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, size_t derive_size, void **ret);
int kdf_kb_hmac_derive(const char *mode, const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, const void *seed, size_t seed_size, size_t derive_size, void **ret);
int rsa_encrypt_bytes(EVP_PKEY *pkey, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
int rsa_oaep_encrypt_bytes(const EVP_PKEY *pkey, const char *digest_alg, const char *label, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
int rsa_pkey_to_suitable_key_size(EVP_PKEY *pkey, size_t *ret_suitable_key_size);
int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size, EVP_PKEY **ret);
int rsa_pkey_to_n_e(const EVP_PKEY *pkey, void **ret_n, size_t *ret_n_size, void **ret_e, size_t *ret_e_size);
int ecc_pkey_from_curve_x_y(int curve_id, const void *x, size_t x_size, const void *y, size_t y_size, EVP_PKEY **ret);
int ecc_pkey_to_curve_x_y(const EVP_PKEY *pkey, int *ret_curve_id, void **ret_x, size_t *ret_x_size, void **ret_y, size_t *ret_y_size);
int ecc_pkey_new(int curve_id, EVP_PKEY **ret);
int ecc_ecdh(const EVP_PKEY *private_pkey, const EVP_PKEY *peer_pkey, void **ret_shared_secret, size_t *ret_shared_secret_size);
int pkey_generate_volume_keys(EVP_PKEY *pkey, void **ret_decrypted_key, size_t *ret_decrypted_key_size, void **ret_saved_key, size_t *ret_saved_key_size);
int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_size);
int digest_and_sign(const EVP_MD *md, EVP_PKEY *privkey, const void *data, size_t size, void **ret, size_t *ret_size);
int pkcs7_new(X509 *certificate, EVP_PKEY *private_key, const char *hash_algorithm, PKCS7 **ret_p7, PKCS7_SIGNER_INFO **ret_si);
int string_hashsum(const char *s, size_t len, const char *md_algorithm, char **ret);
static inline int string_hashsum_sha224(const char *s, size_t len, char **ret) {
return string_hashsum(s, len, "SHA224", ret);
}
static inline int string_hashsum_sha256(const char *s, size_t len, char **ret) {
return string_hashsum(s, len, "SHA256", ret);
}
int x509_fingerprint(X509 *cert, uint8_t buffer[static X509_FINGERPRINT_SIZE]);
int openssl_load_x509_certificate(
CertificateSourceType certificate_source_type,
const char *certificate_source,
const char *certificate,
X509 **ret);
int openssl_load_private_key(
KeySourceType private_key_source_type,
const char *private_key_source,
const char *private_key,
const AskPasswordRequest *request,
EVP_PKEY **ret_private_key,
OpenSSLAskPasswordUI **ret_user_interface);
int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret);
struct OpenSSLAskPasswordUI {
AskPasswordRequest request;
#ifndef OPENSSL_NO_UI_CONSOLE
UI_METHOD *method;
#endif
};
OpenSSLAskPasswordUI* openssl_ask_password_ui_free(OpenSSLAskPasswordUI *ui);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OpenSSLAskPasswordUI*, openssl_ask_password_ui_free, NULL);
#endif
+21 -12
View File
@@ -4,6 +4,7 @@
#include <unistd.h>
#include "alloc-util.h"
#include "crypto-util.h"
#include "hexdecoct.h"
#include "log.h"
#include "pe-binary.h"
@@ -325,7 +326,7 @@ static int hash_file(int fd, EVP_MD_CTX *md_ctx, uint64_t offset, uint64_t size)
if ((size_t) n != m)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Short read while hashing.");
if (EVP_DigestUpdate(md_ctx, buffer, m) != 1)
if (sym_EVP_DigestUpdate(md_ctx, buffer, m) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
offset += m;
@@ -358,6 +359,10 @@ int pe_hash(int fd,
assert(ret_hash_size);
assert(ret_hash);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
if (fstat(fd, &st) < 0)
return log_debug_errno(errno, "Failed to stat file: %m");
r = stat_verify_regular(&st);
@@ -376,11 +381,11 @@ int pe_hash(int fd,
if (!certificate_table)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "File lacks certificate table.");
mdctx = EVP_MD_CTX_new();
mdctx = sym_EVP_MD_CTX_new();
if (!mdctx)
return log_oom_debug();
if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
if (sym_EVP_DigestInit_ex(mdctx, md, NULL) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
/* Everything from beginning of file to CheckSum field in PE header */
@@ -428,11 +433,11 @@ int pe_hash(int fd,
return r;
/* If the file size is not a multiple of 8 bytes, pad the hash with zero bytes. */
if (st.st_size % 8 != 0 && EVP_DigestUpdate(mdctx, (const uint8_t[8]) {}, 8 - (st.st_size % 8)) != 1)
if (st.st_size % 8 != 0 && sym_EVP_DigestUpdate(mdctx, (const uint8_t[8]) {}, 8 - (st.st_size % 8)) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
}
int hsz = EVP_MD_CTX_size(mdctx);
int hsz = sym_EVP_MD_CTX_get_size(mdctx);
if (hsz < 0)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get hash size.");
@@ -441,7 +446,7 @@ int pe_hash(int fd,
if (!hash)
return log_oom_debug();
if (EVP_DigestFinal_ex(mdctx, hash, &hash_size) != 1)
if (sym_EVP_DigestFinal_ex(mdctx, hash, &hash_size) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to finalize hash function.");
assert(hash_size == (unsigned) hsz);
@@ -525,6 +530,10 @@ int uki_hash(int fd,
assert(ret_hashes);
assert(ret_hash_size);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
r = pe_load_headers(fd, &dos_header, &pe_header);
if (r < 0)
return r;
@@ -533,7 +542,7 @@ int uki_hash(int fd,
if (r < 0)
return r;
int hsz = EVP_MD_size(md);
int hsz = sym_EVP_MD_get_size(md);
if (hsz < 0)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get hash size.");
@@ -553,11 +562,11 @@ int uki_hash(int fd,
if (hashes[i])
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Duplicate section");
mdctx = EVP_MD_CTX_new();
mdctx = sym_EVP_MD_CTX_new();
if (!mdctx)
return log_oom_debug();
if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
if (sym_EVP_DigestInit_ex(mdctx, md, NULL) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
r = hash_file(fd, mdctx, le32toh(section->PointerToRawData), MIN(le32toh(section->VirtualSize), le32toh(section->SizeOfRawData)));
@@ -571,7 +580,7 @@ int uki_hash(int fd,
while (remaining > 0) {
size_t sz = MIN(sizeof(zeroes), remaining);
if (EVP_DigestUpdate(mdctx, zeroes, sz) != 1)
if (sym_EVP_DigestUpdate(mdctx, zeroes, sz) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
remaining -= sz;
@@ -583,7 +592,7 @@ int uki_hash(int fd,
return log_oom_debug();
unsigned hash_size = (unsigned) hsz;
if (EVP_DigestFinal_ex(mdctx, hashes[i], &hash_size) != 1)
if (sym_EVP_DigestFinal_ex(mdctx, hashes[i], &hash_size) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to finalize hash function.");
assert(hash_size == (unsigned) hsz);
@@ -592,7 +601,7 @@ int uki_hash(int fd,
_cleanup_free_ char *hs = NULL;
hs = hexmem(hashes[i], hsz);
log_debug("Section %s with %s is %s.", n, EVP_MD_name(md), strna(hs));
log_debug("Section %s with %s is %s.", n, sym_EVP_MD_get0_name(md), strna(hs));
}
}
-1
View File
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "openssl-util.h"
#include "sparse-endian.h"
#include "uki.h"
+70 -49
View File
@@ -1,16 +1,20 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#if HAVE_OPENSSL
# include <openssl/core_names.h>
#endif
#include "sd-dlopen.h"
#include "alloc-util.h"
#include "ask-password-api.h"
#include "crypto-util.h"
#include "dlfcn-util.h"
#include "env-util.h"
#include "escape.h"
#include "format-table.h"
#include "log.h"
#include "memory-util.h"
#include "openssl-util.h"
#include "pkcs11-util.h"
#include "random-util.h"
#include "string-util.h"
@@ -429,7 +433,7 @@ static int read_public_key_info(
"Failed to read CKA_PUBLIC_KEY_INFO: %s", sym_p11_kit_strerror(rv));
const unsigned char *value = attribute.pValue;
pkey = d2i_PUBKEY(NULL, &value, attribute.ulValueLen);
pkey = sym_d2i_PUBKEY(NULL, &value, attribute.ulValueLen);
if (!pkey)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse CKA_PUBLIC_KEY_INFO");
@@ -449,6 +453,10 @@ int pkcs11_token_read_public_key(
assert(ret_pkey);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
r = read_public_key_info(m, session, object, &pkey);
if (r >= 0) {
*ret_pkey = TAKE_PTR(pkey);
@@ -543,67 +551,67 @@ int pkcs11_token_read_public_key(
_cleanup_(ASN1_OCTET_STRING_freep) ASN1_OCTET_STRING *os = NULL;
const unsigned char *ec_params_value = ec_attributes[0].pValue;
group = d2i_ECPKParameters(NULL, &ec_params_value, ec_attributes[0].ulValueLen);
group = sym_d2i_ECPKParameters(NULL, &ec_params_value, ec_attributes[0].ulValueLen);
if (!group)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_PARAMS.");
const unsigned char *ec_point_value = ec_attributes[1].pValue;
os = d2i_ASN1_OCTET_STRING(NULL, &ec_point_value, ec_attributes[1].ulValueLen);
os = sym_d2i_ASN1_OCTET_STRING(NULL, &ec_point_value, ec_attributes[1].ulValueLen);
if (!os)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_POINT.");
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
if (!ctx)
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to create an EVP_PKEY_CTX for EC.");
if (EVP_PKEY_fromdata_init(ctx) != 1)
if (sym_EVP_PKEY_fromdata_init(ctx) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to init an EVP_PKEY_CTX for EC.");
OSSL_PARAM ec_params[8] = {
/* We need to drop the const from the data param, because ec_params is
* modified below. But we'll not modify ec_params[0]. */
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
(unsigned char *) ASN1_STRING_get0_data(os),
ASN1_STRING_length(os)),
(unsigned char *) sym_ASN1_STRING_get0_data(os),
sym_ASN1_STRING_length(os)),
};
_cleanup_free_ void *order = NULL, *p = NULL, *a = NULL, *b = NULL, *generator = NULL;
size_t order_size, p_size, a_size, b_size, generator_size;
int nid = EC_GROUP_get_curve_name(group);
int nid = sym_EC_GROUP_get_curve_name(group);
if (nid != NID_undef) {
const char* name = OSSL_EC_curve_nid2name(nid);
ec_params[1] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, (char*)name, strlen(name));
ec_params[2] = OSSL_PARAM_construct_end();
const char* name = sym_OSSL_EC_curve_nid2name(nid);
ec_params[1] = sym_OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, (char*)name, strlen(name));
ec_params[2] = sym_OSSL_PARAM_construct_end();
} else {
const char *field_type = EC_GROUP_get_field_type(group) == NID_X9_62_prime_field ?
const char *field_type = sym_EC_GROUP_get_field_type(group) == NID_X9_62_prime_field ?
"prime-field" : "characteristic-two-field";
const BIGNUM *bn_order = EC_GROUP_get0_order(group);
const BIGNUM *bn_order = sym_EC_GROUP_get0_order(group);
_cleanup_(BN_CTX_freep) BN_CTX *bnctx = BN_CTX_new();
_cleanup_(BN_CTX_freep) BN_CTX *bnctx = sym_BN_CTX_new();
if (!bnctx)
return log_oom_debug();
_cleanup_(BN_freep) BIGNUM *bn_p = BN_new();
_cleanup_(BN_freep) BIGNUM *bn_p = sym_BN_new();
if (!bn_p)
return log_oom_debug();
_cleanup_(BN_freep) BIGNUM *bn_a = BN_new();
_cleanup_(BN_freep) BIGNUM *bn_a = sym_BN_new();
if (!bn_a)
return log_oom_debug();
_cleanup_(BN_freep) BIGNUM *bn_b = BN_new();
_cleanup_(BN_freep) BIGNUM *bn_b = sym_BN_new();
if (!bn_b)
return log_oom_debug();
if (EC_GROUP_get_curve(group, bn_p, bn_a, bn_b, bnctx) != 1)
if (sym_EC_GROUP_get_curve(group, bn_p, bn_a, bn_b, bnctx) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract EC parameters from EC_GROUP.");
order_size = BN_num_bytes(bn_order);
p_size = BN_num_bytes(bn_p);
a_size = BN_num_bytes(bn_a);
b_size = BN_num_bytes(bn_b);
order_size = sym_BN_num_bytes(bn_order);
p_size = sym_BN_num_bytes(bn_p);
a_size = sym_BN_num_bytes(bn_a);
b_size = sym_BN_num_bytes(bn_b);
order = malloc(order_size);
if (!order)
@@ -621,14 +629,14 @@ int pkcs11_token_read_public_key(
if (!b)
return log_oom_debug();
if (BN_bn2nativepad(bn_order, order, order_size) <= 0 ||
BN_bn2nativepad(bn_p, p, p_size) <= 0 ||
BN_bn2nativepad(bn_a, a, a_size) <= 0 ||
BN_bn2nativepad(bn_b, b, b_size) <= 0 )
if (sym_BN_bn2nativepad(bn_order, order, order_size) <= 0 ||
sym_BN_bn2nativepad(bn_p, p, p_size) <= 0 ||
sym_BN_bn2nativepad(bn_a, a, a_size) <= 0 ||
sym_BN_bn2nativepad(bn_b, b, b_size) <= 0 )
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to store EC parameters in native byte order.");
const EC_POINT *point_gen = EC_GROUP_get0_generator(group);
generator_size = EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bnctx);
const EC_POINT *point_gen = sym_EC_GROUP_get0_generator(group);
generator_size = sym_EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bnctx);
if (generator_size == 0)
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine size of a EC generator.");
@@ -636,20 +644,20 @@ int pkcs11_token_read_public_key(
if (!generator)
return log_oom_debug();
generator_size = EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, generator, generator_size, bnctx);
generator_size = sym_EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, generator, generator_size, bnctx);
if (generator_size == 0)
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert a EC generator to octet string.");
ec_params[1] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, (char*)field_type, strlen(field_type));
ec_params[2] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, generator, generator_size);
ec_params[3] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_ORDER, order, order_size);
ec_params[4] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_P, p, p_size);
ec_params[5] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_A, a, a_size);
ec_params[6] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_B, b, b_size);
ec_params[7] = OSSL_PARAM_construct_end();
ec_params[1] = sym_OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, (char*)field_type, strlen(field_type));
ec_params[2] = sym_OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, generator, generator_size);
ec_params[3] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_ORDER, order, order_size);
ec_params[4] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_P, p, p_size);
ec_params[5] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_A, a, a_size);
ec_params[6] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_B, b, b_size);
ec_params[7] = sym_OSSL_PARAM_construct_end();
}
if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, ec_params) != 1)
if (sym_EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, ec_params) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to create EVP_PKEY from EC parameters.");
break;
}
@@ -695,16 +703,20 @@ int pkcs11_token_read_x509_certificate(
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"Failed to read X.509 certificate data off token: %s", sym_p11_kit_strerror(rv));
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
const unsigned char *p = attribute.pValue;
_cleanup_(X509_freep) X509 *x509 = d2i_X509(NULL, &p, attribute.ulValueLen);
_cleanup_(X509_freep) X509 *x509 = sym_d2i_X509(NULL, &p, attribute.ulValueLen);
if (!x509)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse X.509 certificate.");
const X509_NAME *name = X509_get_subject_name(x509);
const X509_NAME *name = sym_X509_get_subject_name(x509);
if (!name)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to acquire X.509 subject name.");
_cleanup_free_ char *t = X509_NAME_oneline(name, NULL, 0);
_cleanup_free_ char *t = sym_X509_NAME_oneline(name, NULL, 0);
if (!t)
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to format X.509 subject name as string.");
@@ -1009,23 +1021,27 @@ static int ecc_convert_to_compressed(
_cleanup_free_ void *compressed_point = NULL;
size_t compressed_point_size;
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
const unsigned char *ec_params_value = ec_params_attr.pValue;
group = d2i_ECPKParameters(NULL, &ec_params_value, ec_params_attr.ulValueLen);
group = sym_d2i_ECPKParameters(NULL, &ec_params_value, ec_params_attr.ulValueLen);
if (!group)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_PARAMS");
point = EC_POINT_new(group);
point = sym_EC_POINT_new(group);
if (!point)
return log_oom();
bnctx = BN_CTX_new();
bnctx = sym_BN_CTX_new();
if (!bnctx)
return log_oom();
if (EC_POINT_oct2point(group, point, uncompressed_point, uncompressed_point_size, bnctx) != 1)
if (sym_EC_POINT_oct2point(group, point, uncompressed_point, uncompressed_point_size, bnctx) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode an uncompressed EC point");
compressed_point_size = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, bnctx);
compressed_point_size = sym_EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, bnctx);
if (compressed_point_size == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine size of a compressed EC point");
@@ -1033,7 +1049,7 @@ static int ecc_convert_to_compressed(
if (!compressed_point)
return log_oom();
compressed_point_size = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, compressed_point, compressed_point_size, bnctx);
compressed_point_size = sym_EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, compressed_point, compressed_point_size, bnctx);
if (compressed_point_size == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert a EC point to compressed format");
@@ -1521,7 +1537,8 @@ struct pkcs11_acquire_public_key_callback_data {
static void pkcs11_acquire_public_key_callback_data_release(struct pkcs11_acquire_public_key_callback_data *data) {
erase_and_free(data->pin_used);
EVP_PKEY_free(data->pkey);
if (data->pkey)
sym_EVP_PKEY_free(data->pkey);
}
static int pkcs11_acquire_public_key_callback(
@@ -1673,7 +1690,11 @@ static int pkcs11_acquire_public_key_callback(
if (r < 0)
return log_error_errno(r, "Failed to read a found X.509 certificate.");
pkey = X509_get_pubkey(cert);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
pkey = sym_X509_get_pubkey(cert);
if (!pkey)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract public key from X.509 certificate.");
}
-4
View File
@@ -1,10 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#if HAVE_OPENSSL
# include <openssl/evp.h>
#endif
#if HAVE_P11KIT
# include <p11-kit/p11-kit.h> /* IWYU pragma: export */
# include <p11-kit/uri.h> /* IWYU pragma: export */
+15 -7
View File
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "openssl-util.h"
#include "crypto-util.h"
#include "pkcs7-util.h"
#include "log.h"
@@ -28,6 +28,10 @@ int pkcs7_extract_signers(
Signer **ret_signers,
size_t *ret_n_signers) {
#if HAVE_OPENSSL
int r;
#endif
assert(ret_signers);
assert(ret_n_signers);
@@ -35,16 +39,20 @@ int pkcs7_extract_signers(
return -EBADMSG;
#if HAVE_OPENSSL
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
const unsigned char *d = sig->iov_base;
_cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
p7 = d2i_PKCS7(/* a= */ NULL, &d, (long) sig->iov_len);
p7 = sym_d2i_PKCS7(/* a= */ NULL, &d, (long) sig->iov_len);
if (!p7)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse PKCS7 DER signature data.");
STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7);
STACK_OF(PKCS7_SIGNER_INFO) *sinfos = sym_PKCS7_get_signer_info(p7);
if (!sinfos)
return log_debug_errno(SYNTHETIC_ERRNO(ENODATA), "No signature information in PKCS7 signature?");
int n = sk_PKCS7_SIGNER_INFO_num(sinfos);
int n = sym_sk_PKCS7_SIGNER_INFO_num(sinfos);
if (n == 0)
return log_debug_errno(SYNTHETIC_ERRNO(ENODATA), "No signatures in PKCS7 signature, refusing.");
if (n > SIGNERS_MAX) /* safety net, in case people send us weirdly complex signatures */
@@ -59,17 +67,17 @@ int pkcs7_extract_signers(
CLEANUP_ARRAY(signers, n_signers, signer_free_many);
for (int i = 0; i < n; i++) {
PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(PKCS7_get_signer_info(p7), i);
PKCS7_SIGNER_INFO *si = sym_sk_PKCS7_SIGNER_INFO_value(sym_PKCS7_get_signer_info(p7), i);
if (!si)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get signer information.");
_cleanup_(signer_done) Signer signer = {};
_cleanup_free_ unsigned char *p = NULL;
int len = i2d_X509_NAME(si->issuer_and_serial->issuer, &p);
int len = sym_i2d_X509_NAME(si->issuer_and_serial->issuer, &p);
signer.issuer = IOVEC_MAKE(TAKE_PTR(p), len);
len = i2d_ASN1_INTEGER(si->issuer_and_serial->serial, &p);
len = sym_i2d_ASN1_INTEGER(si->issuer_and_serial->serial, &p);
signer.serial = IOVEC_MAKE(TAKE_PTR(p), len);
signers[n_signers++] = TAKE_STRUCT(signer);
+1
View File
@@ -45,6 +45,7 @@ typedef enum UserDBFlags UserDBFlags;
typedef enum UserRecordLoadFlags UserRecordLoadFlags;
typedef enum UserStorage UserStorage;
typedef struct AskPasswordRequest AskPasswordRequest;
typedef struct Bitmap Bitmap;
typedef struct BootConfig BootConfig;
typedef struct BPFProgram BPFProgram;
+75
View File
@@ -0,0 +1,75 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-dlopen.h"
#include "log.h" /* IWYU pragma: keep */
#include "ssl-util.h"
#if HAVE_OPENSSL
static void *libssl_dl = NULL;
DLSYM_PROTOTYPE(SSL_ctrl) = NULL;
DLSYM_PROTOTYPE(SSL_CTX_ctrl) = NULL;
DLSYM_PROTOTYPE(SSL_CTX_free) = NULL;
DLSYM_PROTOTYPE(SSL_CTX_new) = NULL;
DLSYM_PROTOTYPE(SSL_CTX_set_default_verify_paths) = NULL;
DLSYM_PROTOTYPE(SSL_CTX_set_options) = NULL;
DLSYM_PROTOTYPE(SSL_do_handshake) = NULL;
DLSYM_PROTOTYPE(SSL_free) = NULL;
DLSYM_PROTOTYPE(SSL_get_error) = NULL;
DLSYM_PROTOTYPE(SSL_get_wbio) = NULL;
DLSYM_PROTOTYPE(SSL_get0_param) = NULL;
DLSYM_PROTOTYPE(SSL_get1_session) = NULL;
DLSYM_PROTOTYPE(SSL_new) = NULL;
DLSYM_PROTOTYPE(SSL_read) = NULL;
DLSYM_PROTOTYPE(SSL_SESSION_free) = NULL;
DLSYM_PROTOTYPE(SSL_set_bio) = NULL;
DLSYM_PROTOTYPE(SSL_set_connect_state) = NULL;
DLSYM_PROTOTYPE(SSL_set_session) = NULL;
DLSYM_PROTOTYPE(SSL_set_verify) = NULL;
DLSYM_PROTOTYPE(SSL_shutdown) = NULL;
DLSYM_PROTOTYPE(SSL_write) = NULL;
DLSYM_PROTOTYPE(TLS_client_method) = NULL;
#endif
int dlopen_libssl(int log_level) {
#if HAVE_OPENSSL
SD_ELF_NOTE_DLOPEN(
"libssl",
"Support for TLS",
SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
"libssl.so.3");
return dlopen_many_sym_or_warn(
&libssl_dl,
"libssl.so.3",
log_level,
DLSYM_ARG(SSL_ctrl),
DLSYM_ARG(SSL_CTX_ctrl),
DLSYM_ARG(SSL_CTX_free),
DLSYM_ARG(SSL_CTX_new),
DLSYM_ARG(SSL_CTX_set_default_verify_paths),
DLSYM_ARG(SSL_CTX_set_options),
DLSYM_ARG(SSL_do_handshake),
DLSYM_ARG(SSL_free),
DLSYM_ARG(SSL_get_error),
DLSYM_ARG(SSL_get_wbio),
DLSYM_ARG(SSL_get0_param),
DLSYM_ARG(SSL_get1_session),
DLSYM_ARG(SSL_new),
DLSYM_ARG(SSL_read),
DLSYM_ARG(SSL_SESSION_free),
DLSYM_ARG(SSL_set_bio),
DLSYM_ARG(SSL_set_connect_state),
DLSYM_ARG(SSL_set_session),
DLSYM_ARG(SSL_set_verify),
DLSYM_ARG(SSL_shutdown),
DLSYM_ARG(SSL_write),
DLSYM_ARG(TLS_client_method));
#else
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"libssl support is not compiled in.");
#endif
}
+46
View File
@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "shared-forward.h"
int dlopen_libssl(int log_level);
#if HAVE_OPENSSL
# include <openssl/ssl.h> /* IWYU pragma: export */
# include "dlfcn-util.h"
extern DLSYM_PROTOTYPE(SSL_ctrl);
extern DLSYM_PROTOTYPE(SSL_CTX_ctrl);
extern DLSYM_PROTOTYPE(SSL_CTX_free);
extern DLSYM_PROTOTYPE(SSL_CTX_new);
extern DLSYM_PROTOTYPE(SSL_CTX_set_default_verify_paths);
extern DLSYM_PROTOTYPE(SSL_CTX_set_options);
extern DLSYM_PROTOTYPE(SSL_do_handshake);
extern DLSYM_PROTOTYPE(SSL_free);
extern DLSYM_PROTOTYPE(SSL_get_error);
extern DLSYM_PROTOTYPE(SSL_get_wbio);
extern DLSYM_PROTOTYPE(SSL_get0_param);
extern DLSYM_PROTOTYPE(SSL_get1_session);
extern DLSYM_PROTOTYPE(SSL_new);
extern DLSYM_PROTOTYPE(SSL_read);
extern DLSYM_PROTOTYPE(SSL_SESSION_free);
extern DLSYM_PROTOTYPE(SSL_set_bio);
extern DLSYM_PROTOTYPE(SSL_set_connect_state);
extern DLSYM_PROTOTYPE(SSL_set_session);
extern DLSYM_PROTOTYPE(SSL_set_verify);
extern DLSYM_PROTOTYPE(SSL_shutdown);
extern DLSYM_PROTOTYPE(SSL_write);
extern DLSYM_PROTOTYPE(TLS_client_method);
/* Mirrors of OpenSSL macros that go through our dlopen'd sym_* variants, so we don't end up linking against
* libssl just for these. */
#define sym_SSL_set_tlsext_host_name(s, name) \
sym_SSL_ctrl((s), SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (void *) (name))
#define sym_SSL_CTX_set_min_proto_version(ctx, version) \
sym_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MIN_PROTO_VERSION, (version), NULL)
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(SSL*, sym_SSL_free, SSL_freep, NULL);
#endif
+55 -25
View File
@@ -13,6 +13,7 @@
#include "chase.h"
#include "constants.h"
#include "creds-util.h"
#include "crypto-util.h"
#include "cryptsetup-util.h"
#include "device-private.h"
#include "device-util.h"
@@ -51,10 +52,6 @@
#include "unaligned.h"
#include "virt.h"
#if HAVE_OPENSSL
# include <openssl/hmac.h>
#endif
#if HAVE_TPM2
static void *libtss2_esys_dl = NULL;
static void *libtss2_rc_dl = NULL;
@@ -3087,11 +3084,15 @@ int tpm2_get_good_pcr_banks_strv(
#if HAVE_OPENSSL
_cleanup_free_ TPMI_ALG_HASH *algs = NULL;
_cleanup_strv_free_ char **l = NULL;
int n_algs;
int n_algs, r;
assert(c);
assert(ret);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
n_algs = tpm2_get_good_pcr_banks(c, pcr_mask, &algs);
if (n_algs < 0)
return n_algs;
@@ -3105,11 +3106,11 @@ int tpm2_get_good_pcr_banks_strv(
if (!salg)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure.");
implementation = EVP_get_digestbyname(salg);
implementation = sym_EVP_get_digestbyname(salg);
if (!implementation)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure.");
n = strdup(ASSERT_PTR(EVP_MD_name(implementation)));
n = strdup(ASSERT_PTR(sym_EVP_MD_get0_name(implementation)));
if (!n)
return log_oom_debug();
@@ -3783,6 +3784,10 @@ int tpm2_policy_signed_hmac_sha256(
* specified in the hmac_key parameter. The secret key must be loaded into the TPM already and
* referenced in hmac_key_handle. */
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
log_debug("Submitting PolicySigned policy for HMAC-SHA256.");
/* Acquire the nonce from the TPM that we shall sign */
@@ -3818,7 +3823,7 @@ int tpm2_policy_signed_hmac_sha256(
unsigned hmac_signature_size = sizeof(hmac_signature);
/* And sign this with our key */
if (!HMAC(EVP_sha256(),
if (!sym_HMAC(sym_EVP_sha256(),
hmac_key->iov_base,
hmac_key->iov_len,
digest_to_sign.buffer,
@@ -4555,6 +4560,10 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret)
assert(pkey);
assert(ret);
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
TPMT_PUBLIC public = {
.nameAlg = TPM2_ALG_SHA256,
.objectAttributes = TPMA_OBJECT_DECRYPT | TPMA_OBJECT_SIGN_ENCRYPT | TPMA_OBJECT_USERWITHAUTH,
@@ -4564,7 +4573,7 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret)
},
};
int key_id = EVP_PKEY_get_id(pkey);
int key_id = sym_EVP_PKEY_get_id(pkey);
switch (key_id) {
case EVP_PKEY_EC: {
public.type = TPM2_ALG_ECC;
@@ -4662,8 +4671,12 @@ int tpm2_tpm2b_public_to_fingerprint(
if (r < 0)
return r;
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
/* Hardcode fingerprint to SHA256 */
return pubkey_fingerprint(pkey, EVP_sha256(), ret_fingerprint, ret_fingerprint_size);
return pubkey_fingerprint(pkey, sym_EVP_sha256(), ret_fingerprint, ret_fingerprint_size);
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
#endif
@@ -6812,17 +6825,21 @@ static int tpm2_userspace_log(
if (fd < 0) /* Apparently tpm2_local_log_open() failed earlier, let's not complain again */
return 0;
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
for (size_t i = 0; i < values->count; i++) {
const EVP_MD *implementation;
const char *a;
assert_se(a = tpm2_hash_alg_to_string(values->digests[i].hashAlg));
assert_se(implementation = EVP_get_digestbyname(a));
assert_se(implementation = sym_EVP_get_digestbyname(a));
r = sd_json_variant_append_arraybo(
&array,
SD_JSON_BUILD_PAIR_STRING("hashAlg", a),
SD_JSON_BUILD_PAIR_HEX("digest", &values->digests[i].digest, EVP_MD_size(implementation)));
SD_JSON_BUILD_PAIR_HEX("digest", &values->digests[i].digest, sym_EVP_MD_get_size(implementation)));
if (r < 0)
return log_debug_errno(r, "Failed to append digest object to JSON array: %m");
}
@@ -6880,6 +6897,7 @@ int tpm2_pcr_extend_bytes(
_cleanup_close_ int log_fd = -EBADF;
TPML_DIGEST_VALUES values = {};
TSS2_RC rc;
int r;
assert(c);
assert(iovec_is_valid(data));
@@ -6894,19 +6912,23 @@ int tpm2_pcr_extend_bytes(
if (strv_isempty(banks))
return 0;
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
STRV_FOREACH(bank, banks) {
const EVP_MD *implementation;
int id;
assert_se(implementation = EVP_get_digestbyname(*bank));
assert_se(implementation = sym_EVP_get_digestbyname(*bank));
if (values.count >= ELEMENTSOF(values.digests))
return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
if ((size_t) sym_EVP_MD_get_size(implementation) > sizeof(values.digests[values.count].digest))
return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
id = tpm2_hash_alg_from_string(EVP_MD_name(implementation));
id = tpm2_hash_alg_from_string(sym_EVP_MD_get0_name(implementation));
if (id < 0)
return log_debug_errno(id, "Can't map hash name to TPM2.");
@@ -6919,9 +6941,9 @@ int tpm2_pcr_extend_bytes(
* some unrelated purpose, who knows). Hence we instead measure an HMAC signature of a
* private non-secret string instead. */
if (iovec_is_set(secret) > 0) {
if (!HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL))
if (!sym_HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL))
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
} else if (EVP_Digest(data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
} else if (sym_EVP_Digest(data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data to measure.");
values.count++;
@@ -7054,6 +7076,10 @@ int tpm2_nvpcr_extend_bytes(
assert(iovec_is_valid(data));
assert(iovec_is_valid(secret));
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
_cleanup_(nvpcr_data_done) NvPCRData p = {};
r = nvpcr_data_load(name, &p);
if (r < 0)
@@ -7077,10 +7103,10 @@ int tpm2_nvpcr_extend_bytes(
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported algorithm for NvPCR, refusing.");
const EVP_MD *implementation;
assert_se(implementation = EVP_get_digestbyname(an));
assert_se(implementation = sym_EVP_get_digestbyname(an));
_cleanup_(iovec_done) struct iovec digest = {
.iov_len = EVP_MD_size(implementation),
.iov_len = sym_EVP_MD_get_size(implementation),
};
digest.iov_base = malloc(digest.iov_len);
@@ -7091,9 +7117,9 @@ int tpm2_nvpcr_extend_bytes(
data = &iovec_empty;
if (iovec_is_set(secret)) {
if (!HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, digest.iov_base, NULL))
if (!sym_HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, digest.iov_base, NULL))
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
} else if (EVP_Digest(data->iov_base, data->iov_len, digest.iov_base, NULL, implementation, NULL) != 1)
} else if (sym_EVP_Digest(data->iov_base, data->iov_len, digest.iov_base, NULL, implementation, NULL) != 1)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data to measure.");
_cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
@@ -7595,10 +7621,14 @@ int tpm2_nvpcr_initialize(
if (!an)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported algorithm for NvPCR, refusing.");
const EVP_MD *implementation;
assert_se(implementation = EVP_get_digestbyname(an));
r = dlopen_libcrypto(LOG_DEBUG);
if (r < 0)
return r;
int digest_size = EVP_MD_get_size(implementation);
const EVP_MD *implementation;
assert_se(implementation = sym_EVP_get_digestbyname(an));
int digest_size = sym_EVP_MD_get_size(implementation);
assert_se(digest_size > 0);
if ((size_t) digest_size > sizeof_field(TPM2B_MAX_NV_BUFFER, buffer))
@@ -7619,7 +7649,7 @@ int tpm2_nvpcr_initialize(
CLEANUP_ERASE(buf);
/* We measure HMAC(anchor_secret, name) into the NvPCR to anchor it on our secret. */
if (!HMAC(implementation, anchor_secret->iov_base, anchor_secret->iov_len, hmac_buffer, hmac_buffer_size, buf.buffer, NULL))
if (!sym_HMAC(implementation, anchor_secret->iov_base, anchor_secret->iov_len, hmac_buffer, hmac_buffer_size, buf.buffer, NULL))
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
_cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
+2 -1
View File
@@ -2,8 +2,9 @@
#pragma once
#include "bitfield.h"
#include "openssl-util.h"
#include "iovec-util.h"
#include "shared-forward.h"
#include "sha256-fundamental.h"
typedef enum TPM2Flags {
TPM2_FLAGS_USE_PIN = 1 << 0,
+1 -1
View File
@@ -29,7 +29,7 @@ executables += [
'extract' : systemd_sysupdate_extract_sources,
'dependencies' : [
libfdisk_cflags,
libopenssl,
libopenssl_cflags,
threads,
],
},
+4 -9
View File
@@ -289,8 +289,8 @@ executables += [
'c_args' : ['-fno-sanitize=all', '-fno-optimize-sibling-calls', '-O1'],
},
test_template + {
'sources' : files('test-cryptolib.c'),
'dependencies' : libopenssl,
'sources' : files('test-crypto-util.c'),
'dependencies' : libopenssl_cflags,
'conditions' : ['HAVE_OPENSSL'],
},
test_template + {
@@ -410,14 +410,9 @@ executables += [
'dependencies' : libdl,
'conditions' : ['ENABLE_NSS'],
},
test_template + {
'sources' : files('test-openssl.c'),
'dependencies' : libopenssl,
'conditions' : ['HAVE_OPENSSL'],
},
test_template + {
'sources' : files('test-pkcs7-util.c'),
'dependencies' : libopenssl,
'dependencies' : libopenssl_cflags,
'conditions' : ['HAVE_OPENSSL'],
},
test_template + {
@@ -494,7 +489,7 @@ executables += [
},
test_template + {
'sources' : files('test-tpm2.c'),
'dependencies' : libopenssl,
'dependencies' : libopenssl_cflags,
'timeout' : 120,
},
test_template + {
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "openssl-util.h"
#include "crypto-util.h"
#include "tests.h"
TEST(openssl_pkey_from_pem) {
@@ -42,16 +42,16 @@ TEST(rsa_pkey_n_e) {
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
assert_se(rsa_pkey_from_n_e(n, n_len, &e, sizeof(e), &pkey) >= 0);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new(pkey, NULL);
assert_se(ctx);
assert_se(EVP_PKEY_verify_init(ctx) == 1);
assert_se(sym_EVP_PKEY_verify_init(ctx) == 1);
const char *msg = "this is a secret";
DEFINE_HEX_PTR(sig, "14b53e0c6ad99a350c3d7811e8160f4ae03ad159815bb91bddb9735b833588df2eac221fbd3fc4ece0dd63bfaeddfdaf4ae67021e759f3638bc194836413414f54e8c4d01c9c37fa4488ea2ef772276b8a33822a53c97b1c35acfb4bc621cfb8fad88f0cf7d5491f05236886afbf9ed47f9469536482f50f74a20defa59d99676bed62a17b5eb98641df5a2f8080fa4b24f2749cc152fa65ba34c14022fcb27f1b36f52021950d7b9b6c3042c50b84cfb7d55a5f9235bfd58e1bf1f604eb93416c5fb5fd90cb68f1270dfa9daf67f52c604f62c2f2beee5e7e672b0e6e9833dd43dba99b77668540c850c9a81a5ea7aaf6297383e6135bd64572362333121fc7");
assert_se(EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
assert_se(sym_EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
DEFINE_HEX_PTR(invalid_sig, "1234");
assert_se(EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
assert_se(sym_EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
_cleanup_free_ void *n2 = NULL, *e2 = NULL;
size_t n2_size, e2_size;
@@ -69,16 +69,16 @@ TEST(ecc_pkey_curve_x_y) {
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
assert_se(ecc_pkey_from_curve_x_y(curveid, x, x_len, y, y_len, &pkey) >= 0);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new(pkey, NULL);
assert_se(ctx);
assert_se(EVP_PKEY_verify_init(ctx) == 1);
assert_se(sym_EVP_PKEY_verify_init(ctx) == 1);
const char *msg = "this is a secret";
DEFINE_HEX_PTR(sig, "3045022100f6ca10f7ed57a020679899b26dd5ac5a1079265885e2a6477f527b6a3f02b5ca02207b550eb3e7b69360aff977f7f6afac99c3f28266b6c5338ce373f6b59263000a");
assert_se(EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
assert_se(sym_EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
DEFINE_HEX_PTR(invalid_sig, "1234");
assert_se(EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
assert_se(sym_EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
_cleanup_free_ void *x2 = NULL, *y2 = NULL;
size_t x2_size, y2_size;
@@ -465,4 +465,31 @@ TEST(ecc_ecdh) {
assert_se(memcmp_nn(secretAC, secretAC_size, secretAB, secretAB_size) != 0);
}
DEFINE_TEST_MAIN(LOG_DEBUG);
TEST(string_hashsum) {
_cleanup_free_ char *out1 = NULL, *out2 = NULL, *out3 = NULL, *out4 = NULL;
ASSERT_OK(string_hashsum("asdf", 4, "SHA224", &out1));
/* echo -n 'asdf' | sha224sum - */
ASSERT_STREQ(out1, "7872a74bcbf298a1e77d507cd95d4f8d96131cbbd4cdfc571e776c8a");
ASSERT_OK(string_hashsum("asdf", 4, "SHA256", &out2));
/* echo -n 'asdf' | sha256sum - */
ASSERT_STREQ(out2, "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b");
ASSERT_OK(string_hashsum("", 0, "SHA224", &out3));
/* echo -n '' | sha224sum - */
ASSERT_STREQ(out3, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
ASSERT_OK(string_hashsum("", 0, "SHA256", &out4));
/* echo -n '' | sha256sum - */
ASSERT_STREQ(out4, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
}
static int intro(void) {
if (dlopen_libcrypto(LOG_DEBUG) < 0)
return log_tests_skipped("libcrypto is not available");
return EXIT_SUCCESS;
}
DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro);
-27
View File
@@ -1,27 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "openssl-util.h"
#include "tests.h"
TEST(string_hashsum) {
_cleanup_free_ char *out1 = NULL, *out2 = NULL, *out3 = NULL, *out4 = NULL;
ASSERT_OK(string_hashsum("asdf", 4, "SHA224", &out1));
/* echo -n 'asdf' | sha224sum - */
ASSERT_STREQ(out1, "7872a74bcbf298a1e77d507cd95d4f8d96131cbbd4cdfc571e776c8a");
ASSERT_OK(string_hashsum("asdf", 4, "SHA256", &out2));
/* echo -n 'asdf' | sha256sum - */
ASSERT_STREQ(out2, "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b");
ASSERT_OK(string_hashsum("", 0, "SHA224", &out3));
/* echo -n '' | sha224sum - */
ASSERT_STREQ(out3, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
ASSERT_OK(string_hashsum("", 0, "SHA256", &out4));
/* echo -n '' | sha256sum - */
ASSERT_STREQ(out4, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
}
DEFINE_TEST_MAIN(LOG_INFO);
+4
View File
@@ -5,6 +5,7 @@
#include "blkid-util.h"
#include "bpf-dlopen.h"
#include "compress.h"
#include "crypto-util.h"
#include "cryptsetup-util.h"
#include "curl-util.h"
#include "elf-util.h"
@@ -28,6 +29,7 @@
#include "qrcode-util.h"
#include "seccomp-util.h"
#include "selinux-util.h"
#include "ssl-util.h"
#include "tests.h"
#include "tpm2-util.h"
@@ -68,6 +70,8 @@ static int run(int argc, char **argv) {
ASSERT_DLOPEN(dlopen_libpam, HAVE_PAM);
ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
ASSERT_DLOPEN(dlopen_libselinux, HAVE_SELINUX);
ASSERT_DLOPEN(dlopen_libcrypto, HAVE_OPENSSL);
ASSERT_DLOPEN(dlopen_libssl, HAVE_OPENSSL);
ASSERT_DLOPEN(dlopen_xz, HAVE_XZ);
ASSERT_DLOPEN(dlopen_lz4, HAVE_LZ4);
ASSERT_DLOPEN(dlopen_microhttpd, HAVE_MICROHTTPD);
+8 -7
View File
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "architecture.h"
#include "crypto-util.h"
#include "hexdecoct.h"
#include "tests.h"
#include "tpm2-util.h"
@@ -782,25 +783,25 @@ TEST(tpm2b_public_to_openssl_pkey) {
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey_rsa = NULL;
assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_rsa) >= 0);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_rsa = EVP_PKEY_CTX_new(pkey_rsa, NULL);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_rsa = sym_EVP_PKEY_CTX_new(pkey_rsa, NULL);
assert_se(ctx_rsa);
assert_se(EVP_PKEY_verify_init(ctx_rsa) == 1);
assert_se(EVP_PKEY_CTX_set_signature_md(ctx_rsa, EVP_sha256()) > 0);
assert_se(sym_EVP_PKEY_verify_init(ctx_rsa) == 1);
assert_se(sym_EVP_PKEY_CTX_set_signature_md(ctx_rsa, sym_EVP_sha256()) > 0);
DEFINE_HEX_PTR(sig_rsa, "9f70a9e68911be3ec464cae91126328307bf355872127e042d6c61e0a80982872c151033bcf727abfae5fc9500c923120011e7ef4aa5fc690a59a034697b6022c141b4b209e2df6f4b282288cd9181073fbe7158ce113c79d87623423c1f3996ff931e59cc91db74f8e8656215b1436fc93ddec0f1f8fa8510826e674b250f047e6cba94c95ff98072a286baca94646b577974a1e00d56c21944e38960d8ee90511a2f938e5cf1ac7b7cc7ff8e3ac001d321254d3e4f988b90e9f6f873c26ecd0a12a626b3474833cdbb9e9f793238f6c97ee5b75a1a89bb7a7858d34ecfa6d34ac58d95085e6c4fbbebd47a4364be2725c2c6b3fa15d916f3c0b62a66fe76ae");
assert_se(EVP_PKEY_verify(ctx_rsa, sig_rsa, sig_rsa_len, (unsigned char*) msg, msg_len) == 1);
assert_se(sym_EVP_PKEY_verify(ctx_rsa, sig_rsa, sig_rsa_len, (unsigned char*) msg, msg_len) == 1);
/* ECC */
tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256, "6fc0ecf3645c673ab7e86d1ec5b315afb950257c5f68ab23296160006711fac2", "8dd2ef7a2c9ecede91493ba98c8fb3f893aff325c6a1e0f752c657b2d6ca1413");
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey_ecc = NULL;
assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_ecc) >= 0);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_ecc = EVP_PKEY_CTX_new(pkey_ecc, NULL);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_ecc = sym_EVP_PKEY_CTX_new(pkey_ecc, NULL);
assert_se(ctx_ecc);
assert_se(EVP_PKEY_verify_init(ctx_ecc) == 1);
assert_se(sym_EVP_PKEY_verify_init(ctx_ecc) == 1);
DEFINE_HEX_PTR(sig_ecc, "304602210092447ac0b5b32e90923f79bb4aba864b9c546a9900cf193a83243d35d189a2110221009a8b4df1dfa85e225eff9c606694d4d205a7a3968c9552f50bc2790209a90001");
assert_se(EVP_PKEY_verify(ctx_ecc, sig_ecc, sig_ecc_len, (unsigned char*) msg, msg_len) == 1);
assert_se(sym_EVP_PKEY_verify(ctx_ecc, sig_ecc, sig_ecc_len, (unsigned char*) msg, msg_len) == 1);
}
static void get_tpm2b_public_from_pem(const void *pem, size_t pem_size, TPM2B_PUBLIC *ret) {
+1 -1
View File
@@ -10,7 +10,7 @@ executables += [
'HAVE_TPM2',
],
'dependencies' : [
libopenssl,
libopenssl_cflags,
],
},
libexec_template + {
+8 -3
View File
@@ -9,6 +9,7 @@
#include "build.h"
#include "conf-files.h"
#include "constants.h"
#include "crypto-util.h"
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
@@ -127,7 +128,7 @@ static void public_key_data_done(struct public_key_data *d) {
assert(d);
if (d->pkey) {
EVP_PKEY_free(d->pkey);
sym_EVP_PKEY_free(d->pkey);
d->pkey = NULL;
}
if (d->public) {
@@ -148,7 +149,7 @@ static int public_key_make_fingerprint(struct public_key_data *d) {
assert(!d->fingerprint);
assert(!d->fingerprint_hex);
r = pubkey_fingerprint(d->pkey, EVP_sha256(), &d->fingerprint, &d->fingerprint_size);
r = pubkey_fingerprint(d->pkey, sym_EVP_sha256(), &d->fingerprint, &d->fingerprint_size);
if (r < 0)
return log_error_errno(r, "Failed to calculate fingerprint of public key: %m");
@@ -320,7 +321,7 @@ static int setup_srk(void) {
if (r < 0)
return log_error_errno(r, "Failed to open SRK public key file '%s' for writing: %m", pem_path);
if (PEM_write_PUBKEY(f, tpm2_key.pkey) <= 0)
if (sym_PEM_write_PUBKEY(f, tpm2_key.pkey) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write SRK public key file '%s'.", pem_path);
if (fchmod(fileno(f), 0444) < 0)
@@ -504,6 +505,10 @@ static int run(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
r = dlopen_libcrypto(LOG_ERR);
if (r < 0)
return r;
umask(0022);
/* Execute both jobs, and then return unlisted errors preferably, and listed errors