int dercertsz;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to convert X.509 certificate to DER");
if (c->esp_fd < 0)
return c->esp_fd;
/* Don't count the trailing NUL terminator. */
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");
+ return log_openssl_errors(LOG_ERR, "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 (sym_BIO_write(bio, guid, sizeof(*guid)) < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable GUID to bio");
+ return log_openssl_errors(LOG_ERR, "Failed to write variable GUID to bio");
if (sym_BIO_write(bio, &attrs, sizeof(attrs)) < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable attributes to bio");
+ return log_openssl_errors(LOG_ERR, "Failed to write variable attributes to bio");
if (sym_BIO_write(bio, ×tamp, sizeof(timestamp)) < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write timestamp to bio");
+ return log_openssl_errors(LOG_ERR, "Failed to write timestamp to bio");
if (sym_BIO_write(bio, siglist, siglistsz) < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write signature list to bio");
+ return log_openssl_errors(LOG_ERR, "Failed to write signature list to bio");
_cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to calculate PKCS7 signature");
_cleanup_free_ uint8_t *sig = NULL;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to convert PKCS7 signature to DER");
size_t authsz = offsetof(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo.CertData) + sigsz;
_cleanup_free_ EFI_VARIABLE_AUTHENTICATION_2 *auth = malloc(authsz);
#include "bus-object.h"
#include "bus-polkit.h"
#include "crypto-util.h"
+#include "errno-util.h"
#include "fileio.h"
#include "format-util.h"
#include "home-util.h"
if (r == 0)
return 1; /* Will call us back */
+ /* Load libcrypto up front so that its unavailability (e.g. -EOPNOTSUPP) is propagated as the real
+ * error instead of being misattributed to the user-supplied key below. */
+ r = dlopen_libcrypto(LOG_DEBUG);
+ if (r < 0)
+ return r;
+
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
r = openssl_pubkey_from_pem(pem, /* pem_size= */ SIZE_MAX, &pkey);
- if (r == -EIO)
+ if (r < 0) {
+ /* libcrypto is loaded at this point, so any failure here is a failure to parse or load the
+ * user-supplied key (the translated OpenSSL errno varies: -EBADMSG, -EINVAL, -EOPNOTSUPP,
+ * -EIO, …) — treat it as an invalid public key, except resource exhaustion which we
+ * propagate as-is. */
+ if (ERRNO_IS_NEG_RESOURCE(r))
+ return r;
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Public key invalid: %s", fn);
- if (r < 0)
- return r;
+ }
/* Make sure the local key is loaded before can detect conflicts */
r = manager_acquire_key_pair(m);
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");
+ return log_openssl_errors(LOG_ERR, "Failed to load private key pair");
log_info("Successfully loaded private key pair.");
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.");
+ return log_openssl_errors(LOG_ERR, "Failed to allocate Ed25519 key generation context.");
if (sym_EVP_PKEY_keygen_init(ctx) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize Ed25519 key generation context.");
+ return log_openssl_errors(LOG_ERR, "Failed to initialize Ed25519 key generation context.");
log_info("Generating key pair for signing local user identity records.");
if (sym_EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate Ed25519 key pair");
+ return log_openssl_errors(LOG_ERR, "Failed to generate Ed25519 key pair");
log_info("Successfully created Ed25519 key pair.");
return log_error_errno(r, "Failed to open key file for writing: %m");
if (sym_PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
+ return log_openssl_errors(LOG_ERR, "Failed to write public key.");
(void) fchmod(fileno(fpublic), 0444); /* Make public key world readable */
return log_error_errno(r, "Failed to open key file for writing: %m");
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.");
+ return log_openssl_errors(LOG_ERR, "Failed to write private key pair.");
(void) fchmod(fileno(fprivate), 0400); /* Make private key root readable */
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);
+ return log_openssl_errors(LOG_ERR, "Failed to parse public key file %s.", path);
r = hashmap_ensure_put(&m->public_keys, &public_key_hash_ops, fn, pkey);
if (r < 0)
return -ENOMEM;
if (sym_EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, public_key) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize signature verification");
if (sym_EVP_DigestVerify(md_ctx, signature, signature_size, (uint8_t*) text, strlen(text)) <= 0) {
+ /* A bad signature is an expected outcome here (counted as n_bad), but it may leave
+ * entries in the thread-local OpenSSL error queue. Clear them so a later iteration's
+ * failure — or an unrelated caller on this thread — translates its own error rather
+ * than this stale one. */
+ sym_ERR_clear_error();
n_bad++;
continue;
}
public_key = sym_X509_get_pubkey(certificate);
if (!public_key)
- return log_error_errno(
- SYNTHETIC_ERRNO(EIO),
+ return log_openssl_errors(
+ LOG_ERR,
"Failed to extract public key from certificate %s.",
arg_certificate);
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --certificate=, or --private-key= must be specified");
if (sym_PEM_write_PUBKEY(stdout, public_key) == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key to stdout");
+ return log_openssl_errors(LOG_ERR, "Failed to write public key to stdout");
return 0;
}
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
if (sym_PEM_write_X509(stdout, certificate) == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write certificate to stdout.");
+ return log_openssl_errors(LOG_ERR, "Failed to write certificate to stdout.");
return 0;
}
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Content file %s is empty", arg_content);
if (!sym_PKCS7_content_new(pkcs7, NID_pkcs7_data))
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Error creating new PKCS7 content field");
+ return log_openssl_errors(LOG_ERR, "Error creating new PKCS7 content field");
sym_ASN1_STRING_set0(pkcs7->d.sign->contents->d.data, TAKE_PTR(content), content_len);
} else
if (sym_PKCS7_set_detached(pkcs7, true) == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO),
- "Failed to set PKCS#7 detached attribute: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set PKCS#7 detached attribute");
/* Add PKCS1 signature to PKCS7_SIGNER_INFO */
sym_ASN1_STRING_set0(signer_info->enc_digest, TAKE_PTR(pkcs1), pkcs1_len);
return log_error_errno(r, "Failed to open temporary file: %m");
if (!sym_i2d_PKCS7_fp(output, pkcs7))
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write PKCS#7 file: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to write PKCS#7 file");
r = flink_tmpfile(output, tmp, arg_output, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
if (r < 0)
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to calculate PKCS7 signature");
sigsz = sym_i2d_PKCS7(p7, &sig);
if (sigsz < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to convert PKCS7 signature to DER");
*ret_signature = IOVEC_MAKE(TAKE_PTR(sig), sigsz);
return CMP(DNS_RESOURCE_RECORD_RDATA_SIZE(x), DNS_RESOURCE_RECORD_RDATA_SIZE(y));
}
+/* The DNSSEC verification and digest helpers below reserve -EOPNOTSUPP to mean "this algorithm or digest
+ * is not supported (or is disabled by host policy)" — a condition their callers deliberately treat as an
+ * insecure-but-accepted result (DNSSEC_UNSUPPORTED_ALGORITHM and friends). Once an algorithm has been
+ * established as supported, a low-level OpenSSL failure during the actual computation can nonetheless
+ * translate to -EOPNOTSUPP (e.g. an OpenSSL provider pushing ERR_R_UNSUPPORTED, ERR_R_FETCH_FAILED, or
+ * ERR_R_DISABLED under FIPS or similar). Such a failure must fail closed, so collapse it onto -EIO and
+ * keep -EOPNOTSUPP exclusively for the genuine unsupported-algorithm signal. */
+static int dnssec_verify_errno(int r) {
+ return r == -EOPNOTSUPP ? -EIO : r;
+}
+
static int dnssec_rsa_verify_raw(
const EVP_MD *hash_algorithm,
const void *signature, size_t signature_size,
e = sym_BN_bin2bn(exponent, exponent_size, NULL);
if (!e)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to convert RSA exponent to BIGNUM");
m = sym_BN_bin2bn(modulus, modulus_size, NULL);
if (!m)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to convert RSA modulus to BIGNUM");
rpubkey = sym_RSA_new();
if (!rpubkey)
return -ENOMEM;
if (sym_RSA_set0_key(rpubkey, m, e, NULL) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to set RSA public key");
e = m = NULL;
if ((size_t) sym_RSA_size(rpubkey) != signature_size)
return -ENOMEM;
if (sym_EVP_PKEY_assign_RSA(epubkey, sym_RSAPublicKey_dup(rpubkey)) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to assign RSA public key");
ctx = sym_EVP_PKEY_CTX_new(epubkey, NULL);
if (!ctx)
return -ENOMEM;
if (sym_EVP_PKEY_verify_init(ctx) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize RSA signature verification");
if (sym_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to set RSA padding");
if (sym_EVP_PKEY_CTX_set_signature_md(ctx, hash_algorithm) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to set RSA signature digest");
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", sym_ERR_get_error());
+ return log_openssl_errors(LOG_DEBUG, "Signature verification failed");
REENABLE_WARNING;
return r;
return -ENOMEM;
if (sym_EC_POINT_oct2point(ec_group, p, key, key_size, bctx) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to parse EC public key point");
eckey = sym_EC_KEY_new();
if (!eckey)
return -ENOMEM;
if (sym_EC_KEY_set_group(eckey, ec_group) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to set EC group");
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", sym_ERR_get_error());
+ return log_openssl_errors(LOG_DEBUG, "EC_KEY_set_public_key failed");
if (sym_EC_KEY_check_key(eckey) != 1)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO),
- "EC_KEY_check_key failed: 0x%lx", sym_ERR_get_error());
+ return log_openssl_errors(LOG_DEBUG, "EC_KEY_check_key failed");
r = sym_BN_bin2bn(signature_r, signature_r_size, NULL);
if (!r)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to convert ECDSA signature r to BIGNUM");
s = sym_BN_bin2bn(signature_s, signature_s_size, NULL);
if (!s)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to convert ECDSA signature s to BIGNUM");
/* TODO: We should eventually use the EVP API once it supports ECDSA signature verification */
return -ENOMEM;
if (sym_ECDSA_SIG_set0(sig, r, s) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to set ECDSA signature");
r = s = NULL;
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", sym_ERR_get_error());
+ return log_openssl_errors(LOG_DEBUG, "Signature verification failed");
REENABLE_WARNING;
return k;
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", sym_ERR_get_error());
+ return log_openssl_errors(LOG_DEBUG, "EVP_PKEY_new_raw_public_key failed");
pctx = sym_EVP_PKEY_CTX_new(evkey, NULL);
if (!pctx)
/* One might be tempted to use EVP_PKEY_verify_init, but see Ed25519(7ssl). */
if (sym_EVP_DigestVerifyInit(ctx, &pctx, NULL, NULL, evkey) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EdDSA verification");
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", sym_ERR_get_error());
+ return log_openssl_errors(LOG_DEBUG, "Signature verification failed");
return r;
}
switch (rrsig->rrsig.algorithm) {
case DNSSEC_ALGORITHM_ED25519:
- return dnssec_eddsa_verify(
+ /* The algorithm is supported, so a -EOPNOTSUPP from the actual verification is a hard
+ * crypto failure, not an unsupported-algorithm condition: fail closed. */
+ return dnssec_verify_errno(dnssec_eddsa_verify(
rrsig->rrsig.algorithm,
sig_data, sig_size,
rrsig,
- dnskey);
+ dnskey));
case DNSSEC_ALGORITHM_ED448:
return -EOPNOTSUPP;
default:
return -EOPNOTSUPP;
if (sym_EVP_DigestUpdate(ctx, sig_data, sig_size) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to update digest"));
if (sym_EVP_DigestFinal_ex(ctx, hash, &hash_size) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to finalize digest"));
assert(hash_size > 0);
}
case DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1:
case DNSSEC_ALGORITHM_RSASHA256:
case DNSSEC_ALGORITHM_RSASHA512:
- return dnssec_rsa_verify(
+ return dnssec_verify_errno(dnssec_rsa_verify(
md_algorithm,
hash, hash_size,
rrsig,
- dnskey);
+ dnskey));
case DNSSEC_ALGORITHM_ECDSAP256SHA256:
case DNSSEC_ALGORITHM_ECDSAP384SHA384:
- return dnssec_ecdsa_verify(
+ return dnssec_verify_errno(dnssec_ecdsa_verify(
md_algorithm,
rrsig->rrsig.algorithm,
hash, hash_size,
rrsig,
- dnskey);
+ dnskey));
default:
assert_not_reached();
return -EOPNOTSUPP;
if (sym_EVP_DigestUpdate(ctx, wire_format, encoded_length) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to update digest"));
if (mask_revoke)
md_add_uint16(ctx, dnskey->dnskey.flags & ~DNSKEY_FLAG_REVOKE);
if (r <= 0)
return r;
if (sym_EVP_DigestUpdate(ctx, dnskey->dnskey.key, dnskey->dnskey.key_size) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to update digest"));
if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to finalize digest"));
return memcmp(result, ds->ds.digest, ds->ds.digest_size) == 0;
}
return r;
if (sym_EVP_DigestUpdate(ctx, wire_format, r) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to update digest"));
if (sym_EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to update digest"));
uint8_t result[EVP_MAX_MD_SIZE];
if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to finalize digest"));
for (unsigned k = 0; k < nsec3->nsec3.iterations; k++) {
if (sym_EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
return -EOPNOTSUPP;
if (sym_EVP_DigestUpdate(ctx, result, hash_size) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to update digest"));
if (sym_EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to update digest"));
if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
- return -EIO;
+ return dnssec_verify_errno(log_openssl_errors(LOG_DEBUG, "Failed to finalize digest"));
}
memcpy(ret, result, hash_size);
return -ENOMEM;
sym_SSL_set_connect_state(s);
+
+ /* Clear any errors left in the thread-local queue by a prior connection attempt (resolved drives
+ * everything from a single event-loop thread), so the translation below reflects this
+ * SSL_set_session() failure rather than a stale FIFO entry. */
+ sym_ERR_clear_error();
r = sym_SSL_set_session(s, server->dnstls_data.session);
if (r == 0)
- return -EIO;
+ return openssl_to_errno(sym_ERR_get_error());
sym_SSL_set_bio(s, TAKE_PTR(rb), TAKE_PTR(wb));
if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) {
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_WARNING, "Failed to create SSL context");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_WARNING, "Failed to set protocol version on SSL context");
(void) sym_SSL_CTX_set_options(manager->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_WARNING, "Failed to load system trust store");
return 0;
}
return log_oom();
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set ASN1 string");
_cleanup_(SpcPeImageData_freep) SpcPeImageData *peid = SpcPeImageData_new();
if (!peid)
_cleanup_free_ uint8_t *peidraw = NULL;
int peidrawsz = i2d_SpcPeImageData(peid, &peidraw);
if (peidrawsz < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert SpcPeImageData to BER: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to convert SpcPeImageData to BER");
_cleanup_(SpcIndirectDataContent_freep) SpcIndirectDataContent *idc = SpcIndirectDataContent_new();
idc->data->value = sym_ASN1_TYPE_new();
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get SpcPeImageData object");
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.");
+ return log_openssl_errors(LOG_ERR, "Failed to set ASN1_STRING data.");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get SHA256 object");
idc->messageDigest->digestAlgorithm->parameters = sym_ASN1_TYPE_new();
if (!idc->messageDigest->digestAlgorithm->parameters)
idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
if (sym_ASN1_OCTET_STRING_set(idc->messageDigest->digest, digest, digestsz) == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set digest: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set digest");
_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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to convert SpcIndirectDataContent to BER");
*ret_idc = TAKE_PTR(idcraw);
*ret_idcsz = (size_t) idcrawsz;
if (epoch == USEC_INFINITY) {
time = sym_X509_gmtime_adj(NULL, 0);
if (!time)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get current time: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get current time");
} else {
time = sym_ASN1_TIME_set(NULL, (time_t) (epoch / USEC_PER_SEC));
if (!time)
return log_oom();
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to add smimecap signed attribute to signer info");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to add content type signed attribute to signer info");
_cleanup_(ASN1_TIME_freep) ASN1_TIME *time = NULL;
r = asn1_timestamp(&time);
return r;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to add signing time signed attribute to signer info");
TAKE_PTR(time);
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get SpcIndirectDataContent object");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to add signed attribute to pkcs7 signer info");
*ret_p7 = TAKE_PTR(p7);
*ret_si = TAKE_PTR(si);
_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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to create PKCS7 data bio");
int tag, class;
long psz;
/* This function weirdly enough reports errors by setting the 0x80 bit in its return value. */
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to parse ASN.1 object");
if (sym_BIO_write(bio, p, psz) < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write to PKCS7 data bio: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to write to PKCS7 data bio");
*ret = TAKE_PTR(bio);
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to find digest bio");
EVP_MD_CTX *mdc;
if (sym_BIO_get_md_ctx(mdbio, &mdc) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest context from bio: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get digest context from bio");
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned digestsz;
if (sym_EVP_DigestFinal_ex(mdc, digest, &digestsz) == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get digest");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to add PKCS9 message digest signed attribute to signer info");
return 0;
}
const uint8_t *p = content;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to parse signed attributes");
}
if (arg_signed_data_signature) {
_cleanup_free_ unsigned char *abuf = NULL;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to convert signed attributes ASN.1 to DER");
r = loop_write(dstfd, abuf, alen);
if (r < 0)
return r;
if (sym_PKCS7_dataFinal(p7, bio) == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to sign data: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to sign data");
}
_cleanup_(PKCS7_freep) PKCS7 *p7c = sym_PKCS7_new();
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get SpcIndirectDataContent object");
p7c->d.other = sym_ASN1_TYPE_new();
if (!p7c->d.other)
return log_oom();
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set ASN1 string");
if (sym_PKCS7_set_content(p7, p7c) == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 data: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set PKCS7 data");
TAKE_PTR(p7c);
_cleanup_free_ uint8_t *sig = NULL;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to convert PKCS7 signature to DER");
_cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
_cleanup_free_ PeHeader *pe_header = NULL;
context = sym_EVP_CIPHER_CTX_new();
if (!context)
- return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to allocate encryption object: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to allocate encryption object");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to initialize encryption context");
/* Just an upper estimate */
output.iov_len =
/* Pass the encrypted + TPM2 header + scoped header as AAD */
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to write AAD data");
/* Now construct the metadata header */
ml = strlen_ptr(name);
/* And encrypt the metadata header */
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to encrypt metadata header");
assert(added >= 0);
assert((size_t) added <= output.iov_len - p);
/* Then encrypt the plaintext */
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to encrypt data");
assert(added >= 0);
assert((size_t) added <= output.iov_len - p);
/* Finalize */
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to finalize data encryption");
assert(added >= 0);
assert((size_t) added <= output.iov_len - p);
/* Append tag */
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to get tag");
p += tsz;
assert(p <= output.iov_len);
context = sym_EVP_CIPHER_CTX_new();
if (!context)
- return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to allocate decryption object: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to allocate decryption object");
if (sym_EVP_DecryptInit_ex(context, cc, NULL, NULL, NULL) != 1)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to initialize decryption context");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set IV size on decryption context");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set IV and key");
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to write AAD data");
plaintext.iov_base = malloc(input->iov_len - p - le32toh(h->tag_size));
if (!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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to decrypt data");
assert(added >= 0);
assert((size_t) added <= input->iov_len - p - le32toh(h->tag_size));
plaintext.iov_len = added;
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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
-
- 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",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_ERR, "Failed to set tag");
+
+ if (sym_EVP_DecryptFinal_ex(context, (uint8_t*) plaintext.iov_base + plaintext.iov_len, &added) != 1) {
+ log_openssl_errors(LOG_ERR, "Decryption failed (incorrect key?)");
+ /* A GCM tag/authentication mismatch (wrong key or corrupted blob) is the common case here
+ * and typically leaves the OpenSSL error queue empty, so we can't rely on the translated
+ * errno. Return -EBADMSG unconditionally: it's this function's documented "corrupted file"
+ * code, and credentials_varlink_error_table[] maps it to io.systemd.Credentials.BadFormat. */
+ return -EBADMSG;
+ }
plaintext.iov_len += added;
#if HAVE_OPENSSL
-/* For each error in the OpenSSL thread error queue, log the provided message and the OpenSSL error
- * string. If there are no errors in the OpenSSL thread queue, this logs the message with "No OpenSSL
- * errors." This logs at level debug. Returns -EIO (or -ENOMEM). */
-#define log_openssl_errors(fmt, ...) _log_openssl_errors(UNIQ, fmt, ##__VA_ARGS__)
-#define _log_openssl_errors(u, fmt, ...) \
- ({ \
- size_t UNIQ_T(MAX, u) = 512 /* arbitrary, but openssl doc states it must be >= 256 */; \
- _cleanup_free_ char *UNIQ_T(BUF, u) = malloc(UNIQ_T(MAX, u)); \
- !UNIQ_T(BUF, u) \
- ? log_oom_debug() \
- : __log_openssl_errors(u, UNIQ_T(BUF, u), UNIQ_T(MAX, u), fmt, ##__VA_ARGS__) \
- ?: log_debug_errno(SYNTHETIC_ERRNO(EIO), fmt ": No OpenSSL errors.", ##__VA_ARGS__); \
- })
-#define __log_openssl_errors(u, buf, max, fmt, ...) \
- ({ \
- int UNIQ_T(R, u) = 0; \
- for (;;) { \
- unsigned long UNIQ_T(E, u) = sym_ERR_get_error(); \
- if (UNIQ_T(E, u) == 0) \
- break; \
- sym_ERR_error_string_n(UNIQ_T(E, u), buf, max); \
- UNIQ_T(R, u) = log_debug_errno(SYNTHETIC_ERRNO(EIO), fmt ": %s", ##__VA_ARGS__, buf); \
- } \
- UNIQ_T(R, u); \
- })
+int openssl_to_errno(unsigned long e) {
+ if (e == 0)
+ return -ENOTRECOVERABLE;
+
+ if (ERR_SYSTEM_ERROR(e))
+ /* ERR_GET_REASON() returns the raw errno in this case. OpenSSL can record a system error
+ * with a zero errno though (e.g. bio_sock2.c raises ERR_LIB_SYS with a socket error that
+ * "may be 0"), which would yield 0 here. Clamp that to -ENOTRECOVERABLE so we never return 0
+ * and break the negative-return invariant that the log_openssl_errors() call sites depend
+ * on. */
+ return -ERR_GET_REASON(e) ?: -ENOTRECOVERABLE;
+
+ switch (ERR_GET_REASON(e)) {
+
+ case ERR_R_MALLOC_FAILURE:
+ return -ENOMEM;
+
+ case ERR_R_PASSED_NULL_PARAMETER:
+ case ERR_R_PASSED_INVALID_ARGUMENT:
+#ifdef ERR_R_INVALID_PROPERTY_DEFINITION
+ case ERR_R_INVALID_PROPERTY_DEFINITION:
+#endif
+ return -EINVAL;
+
+ case ERR_R_UNSUPPORTED:
+ case ERR_R_FETCH_FAILED:
+ case ERR_R_DISABLED:
+ return -EOPNOTSUPP;
+
+ case ERR_R_NESTED_ASN1_ERROR:
+ case ERR_R_MISSING_ASN1_EOS:
+ return -EBADMSG;
+
+#ifdef ERR_R_INTERRUPTED_OR_CANCELLED
+ case ERR_R_INTERRUPTED_OR_CANCELLED:
+ return -EINTR;
+#endif
+
+ default:
+ /* Includes the internal/should-not-happen reasons (ERR_R_INTERNAL_ERROR,
+ * ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, ERR_R_INIT_FAIL, ERR_R_OPERATION_FAIL, …) and the
+ * "error originated in sub-library X" markers, none of which have a meaningful errno. Use
+ * -ENOTRECOVERABLE for these opaque OpenSSL failures, matching the convention used for
+ * unexpected crypto/digest failures elsewhere in the tree, and keeping them distinct from
+ * genuine -EIO (disk/socket) errors. */
+ return -ENOTRECOVERABLE;
+ }
+}
+
+int log_openssl_errors_internal(int level, const char *file, int line, const char *func, const char *format, ...) {
+ _cleanup_free_ char *prefix = NULL;
+ va_list ap;
+ int r;
+
+ va_start(ap, format);
+ r = vasprintf(&prefix, format, ap);
+ va_end(ap);
+ if (r < 0)
+ return log_oom_full(level);
+
+ char buf[512]; /* openssl docs require >= 256 */
+ int ret = 0;
+ for (;;) {
+ unsigned long e = sym_ERR_get_error();
+ if (e == 0)
+ break;
+
+ sym_ERR_error_string_n(e, buf, sizeof(buf));
+
+ /* The queue is drained oldest-first (ERR_get_error() is FIFO), and the oldest entry is
+ * normally the deepest, most-specific reason while newer entries are higher-level
+ * "came-from" wrappers that translate to the -ENOTRECOVERABLE fallback. Keep the first
+ * specific (non-fallback) errno we see, so a trailing wrapper can't shadow it. */
+ int translated = openssl_to_errno(e);
+ if (ret == 0 || (ret == -ENOTRECOVERABLE && translated != -ENOTRECOVERABLE))
+ ret = translated;
+
+ log_internal(level, SYNTHETIC_ERRNO(translated), file, line, func, "%s: %s", prefix, buf);
+ }
+
+ if (ret == 0) /* The queue was empty. */
+ return log_internal(level, SYNTHETIC_ERRNO(ENOTRECOVERABLE), file, line, func, "%s: No OpenSSL errors.", prefix);
+
+ return ret;
+}
int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret) {
int r;
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = sym_PEM_read_PUBKEY(f, /* x= */ NULL, /* pam_password_cb= */ NULL, /* userdata= */ NULL);
if (!pkey)
- return log_openssl_errors("Failed to parse PEM");
+ return log_openssl_errors(LOG_DEBUG, "Failed to parse PEM");
*ret = TAKE_PTR(pkey);
return 0;
return -ENOMEM;
if (sym_PEM_write_PUBKEY(f, pkey) <= 0)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to write public key in PEM format");
return memstream_finalize(&m, ret, /* ret_size= */ NULL);
}
size_t digest_size = sym_EVP_MD_get_size(md);
if (digest_size == 0)
- return log_openssl_errors("Failed to get Digest size");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get Digest size");
*ret_digest_size = digest_size;
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = sym_EVP_MD_CTX_new();
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_MD_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_MD_CTX");
if (!sym_EVP_DigestInit_ex(ctx, md, NULL))
- return log_openssl_errors("Failed to initialize EVP_MD_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_MD_CTX");
for (size_t i = 0; i < n_data; i++)
if (!sym_EVP_DigestUpdate(ctx, data[i].iov_base, data[i].iov_len))
- return log_openssl_errors("Failed to update Digest");
+ return log_openssl_errors(LOG_DEBUG, "Failed to update Digest");
size_t digest_size;
r = openssl_digest_size(digest_alg, &digest_size);
unsigned size;
if (!sym_EVP_DigestFinal_ex(ctx, buf, &size))
- return log_openssl_errors("Failed to finalize Digest");
+ return log_openssl_errors(LOG_DEBUG, "Failed to finalize Digest");
assert(size == digest_size);
_cleanup_(EVP_MAC_freep) EVP_MAC *mac = sym_EVP_MAC_fetch(NULL, "HMAC", NULL);
if (!mac)
- return log_openssl_errors("Failed to create new EVP_MAC");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_MAC");
_cleanup_(EVP_MAC_CTX_freep) EVP_MAC_CTX *ctx = sym_EVP_MAC_CTX_new(mac);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_MAC_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_MAC_CTX");
_cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
if (!bld)
- return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new OSSL_PARAM_BLD");
if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_MAC_PARAM_DIGEST, (char*) digest_alg, 0))
- return log_openssl_errors("Failed to set HMAC OSSL_MAC_PARAM_DIGEST");
+ return log_openssl_errors(LOG_DEBUG, "Failed to set HMAC OSSL_MAC_PARAM_DIGEST");
_cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
if (!params)
- return log_openssl_errors("Failed to build HMAC OSSL_PARAM");
+ return log_openssl_errors(LOG_DEBUG, "Failed to build HMAC OSSL_PARAM");
if (!sym_EVP_MAC_init(ctx, key, key_size, params))
- return log_openssl_errors("Failed to initialize EVP_MAC_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_MAC_CTX");
for (size_t i = 0; i < n_data; i++)
if (!sym_EVP_MAC_update(ctx, data[i].iov_base, data[i].iov_len))
- return log_openssl_errors("Failed to update HMAC");
+ return log_openssl_errors(LOG_DEBUG, "Failed to update HMAC");
size_t digest_size = sym_EVP_MAC_CTX_get_mac_size(ctx);
if (digest_size == 0)
- return log_openssl_errors("Failed to get HMAC digest size");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get HMAC digest size");
_cleanup_free_ void *buf = malloc(digest_size);
if (!buf)
size_t size;
if (!sym_EVP_MAC_final(ctx, buf, &size, digest_size))
- return log_openssl_errors("Failed to finalize HMAC");
+ return log_openssl_errors(LOG_DEBUG, "Failed to finalize HMAC");
assert(size == digest_size);
_cleanup_(EVP_CIPHER_CTX_freep) EVP_CIPHER_CTX *ctx = sym_EVP_CIPHER_CTX_new();
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_CIPHER_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_CIPHER_CTX");
/* Verify enough key data was provided. */
int cipher_key_length = sym_EVP_CIPHER_get_key_length(cipher);
"Not enough IV bytes provided, require %d", cipher_iv_length);
if (!sym_EVP_EncryptInit(ctx, cipher, key, iv))
- return log_openssl_errors("Failed to initialize EVP_CIPHER_CTX.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_CIPHER_CTX.");
int cipher_block_size = sym_EVP_CIPHER_CTX_get_block_size(ctx);
assert(cipher_block_size > 0);
int update_size;
if (!sym_EVP_EncryptUpdate(ctx, &buf[size], &update_size, data[i].iov_base, data[i].iov_len))
- return log_openssl_errors("Failed to update Cipher.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to update Cipher.");
size += update_size;
}
int final_size;
if (!sym_EVP_EncryptFinal_ex(ctx, &buf[size], &final_size))
- return log_openssl_errors("Failed to finalize Cipher.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to finalize Cipher.");
*ret = TAKE_PTR(buf);
*ret_size = size + final_size;
_cleanup_(EVP_KDF_freep) EVP_KDF *kdf = sym_EVP_KDF_fetch(NULL, "SSKDF", NULL);
if (!kdf)
- return log_openssl_errors("Failed to create new EVP_KDF");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_KDF");
_cleanup_(EVP_KDF_CTX_freep) EVP_KDF_CTX *ctx = sym_EVP_KDF_CTX_new(kdf);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_KDF_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_KDF_CTX");
_cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
if (!bld)
- return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new OSSL_PARAM_BLD");
_cleanup_free_ void *buf = malloc(derive_size);
if (!buf)
return log_oom_debug();
if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_DIGEST, (char*) digest, 0))
- return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_DIGEST");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-SS OSSL_KDF_PARAM_DIGEST");
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_KEY, (char*) key, key_size))
- return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_KEY");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-SS OSSL_KDF_PARAM_KEY");
if (salt)
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SALT, (char*) salt, salt_size))
- return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_SALT");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-SS OSSL_KDF_PARAM_SALT");
if (info)
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_INFO, (char*) info, info_size))
- return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_INFO");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-SS OSSL_KDF_PARAM_INFO");
_cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
if (!params)
- return log_openssl_errors("Failed to build KDF-SS OSSL_PARAM");
+ return log_openssl_errors(LOG_DEBUG, "Failed to build KDF-SS OSSL_PARAM");
if (sym_EVP_KDF_derive(ctx, buf, derive_size, params) <= 0)
- return log_openssl_errors("OpenSSL KDF-SS derive failed");
+ return log_openssl_errors(LOG_DEBUG, "OpenSSL KDF-SS derive failed");
*ret = TAKE_PTR(buf);
_cleanup_(EVP_KDF_freep) EVP_KDF *kdf = sym_EVP_KDF_fetch(NULL, "KBKDF", NULL);
if (!kdf)
- return log_openssl_errors("Failed to create new EVP_KDF");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_KDF");
_cleanup_(EVP_KDF_CTX_freep) EVP_KDF_CTX *ctx = sym_EVP_KDF_CTX_new(kdf);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_KDF_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_KDF_CTX");
_cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
if (!bld)
- return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new OSSL_PARAM_BLD");
if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_MAC, (char*) "HMAC", 0))
- return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_MAC");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-KB OSSL_KDF_PARAM_MAC");
if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_MODE, (char*) mode, 0))
- return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_MODE");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-KB OSSL_KDF_PARAM_MODE");
if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_DIGEST, (char*) digest, 0))
- return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_DIGEST");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-KB OSSL_KDF_PARAM_DIGEST");
if (key)
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_KEY, (char*) key, key_size))
- return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_KEY");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-KB OSSL_KDF_PARAM_KEY");
if (salt)
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SALT, (char*) salt, salt_size))
- return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_SALT");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-KB OSSL_KDF_PARAM_SALT");
if (info)
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_INFO, (char*) info, info_size))
- return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_INFO");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-KB OSSL_KDF_PARAM_INFO");
if (seed)
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SEED, (char*) seed, seed_size))
- return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_SEED");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add KDF-KB OSSL_KDF_PARAM_SEED");
_cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
if (!params)
- return log_openssl_errors("Failed to build KDF-KB OSSL_PARAM");
+ return log_openssl_errors(LOG_DEBUG, "Failed to build KDF-KB OSSL_PARAM");
_cleanup_free_ void *buf = malloc(derive_size);
if (!buf)
return log_oom_debug();
if (sym_EVP_KDF_derive(ctx, buf, derive_size, params) <= 0)
- return log_openssl_errors("OpenSSL KDF-KB derive failed");
+ return log_openssl_errors(LOG_DEBUG, "OpenSSL KDF-KB derive failed");
*ret = TAKE_PTR(buf);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new((EVP_PKEY*) pkey, NULL);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_PKEY_CTX");
if (sym_EVP_PKEY_encrypt_init(ctx) <= 0)
- return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_PKEY_CTX");
if (sym_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
- return log_openssl_errors("Failed to configure RSA-OAEP padding");
+ return log_openssl_errors(LOG_DEBUG, "Failed to configure RSA-OAEP padding");
if (sym_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0)
- return log_openssl_errors("Failed to configure RSA-OAEP MD");
+ return log_openssl_errors(LOG_DEBUG, "Failed to configure RSA-OAEP MD");
if (label) {
_cleanup_free_ char *duplabel = strdup(label);
return log_oom_debug();
if (sym_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, duplabel, strlen(duplabel) + 1) <= 0)
- return log_openssl_errors("Failed to configure RSA-OAEP label");
+ return log_openssl_errors(LOG_DEBUG, "Failed to configure RSA-OAEP label");
/* ctx owns this now, don't free */
TAKE_PTR(duplabel);
}
size_t size = 0;
if (sym_EVP_PKEY_encrypt(ctx, NULL, &size, decrypted_key, decrypted_key_size) <= 0)
- return log_openssl_errors("Failed to determine RSA-OAEP encrypted key size");
+ return log_openssl_errors(LOG_DEBUG, "Failed to determine RSA-OAEP encrypted key size");
_cleanup_free_ void *buf = malloc(size);
if (!buf)
return log_oom_debug();
if (sym_EVP_PKEY_encrypt(ctx, buf, &size, decrypted_key, decrypted_key_size) <= 0)
- return log_openssl_errors("Failed to RSA-OAEP encrypt");
+ return log_openssl_errors(LOG_DEBUG, "Failed to RSA-OAEP encrypt");
*ret_encrypt_key = TAKE_PTR(buf);
*ret_encrypt_key_size = size;
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_PKEY_CTX");
if (sym_EVP_PKEY_fromdata_init(ctx) <= 0)
- return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_PKEY_CTX");
OSSL_PARAM params[3];
params[2] = sym_OSSL_PARAM_construct_end();
if (sym_EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
- return log_openssl_errors("Failed to create RSA EVP_PKEY");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create RSA EVP_PKEY");
*ret = TAKE_PTR(pkey);
_cleanup_(BN_freep) BIGNUM *bn_n = NULL;
if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn_n))
- return log_openssl_errors("Failed to get RSA n");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get RSA n");
_cleanup_(BN_freep) BIGNUM *bn_e = NULL;
if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn_e))
- return log_openssl_errors("Failed to get RSA e");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get RSA e");
size_t n_size = sym_BN_num_bytes(bn_n), e_size = sym_BN_num_bytes(bn_e);
_cleanup_free_ void *n = malloc(n_size), *e = malloc(e_size);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_PKEY_CTX");
_cleanup_(BN_freep) BIGNUM *bn_x = sym_BN_bin2bn(x, x_size, NULL);
if (!bn_x)
- return log_openssl_errors("Failed to create BIGNUM x");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create BIGNUM x");
_cleanup_(BN_freep) BIGNUM *bn_y = sym_BN_bin2bn(y, y_size, NULL);
if (!bn_y)
- return log_openssl_errors("Failed to create BIGNUM y");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create BIGNUM y");
_cleanup_(EC_GROUP_freep) EC_GROUP *group = sym_EC_GROUP_new_by_curve_name(curve_id);
if (!group)
- return log_openssl_errors("ECC curve id %d not supported", curve_id);
+ return log_openssl_errors(LOG_DEBUG, "ECC curve id %d not supported", curve_id);
_cleanup_(EC_POINT_freep) EC_POINT *point = sym_EC_POINT_new(group);
if (!point)
- return log_openssl_errors("Failed to create new EC_POINT");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EC_POINT");
if (!sym_EC_POINT_set_affine_coordinates(group, point, bn_x, bn_y, NULL))
- return log_openssl_errors("Failed to set ECC coordinates");
+ return log_openssl_errors(LOG_DEBUG, "Failed to set ECC coordinates");
if (sym_EVP_PKEY_fromdata_init(ctx) <= 0)
- return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_PKEY_CTX");
_cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
if (!bld)
- return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new OSSL_PARAM_BLD");
if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, (char*) sym_OSSL_EC_curve_nid2name(curve_id), 0))
- return log_openssl_errors("Failed to add ECC OSSL_PKEY_PARAM_GROUP_NAME");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add ECC OSSL_PKEY_PARAM_GROUP_NAME");
_cleanup_(OPENSSL_freep) void *pbuf = NULL;
size_t pbuf_len = 0;
pbuf_len = sym_EC_POINT_point2buf(group, point, POINT_CONVERSION_UNCOMPRESSED, (unsigned char**) &pbuf, NULL);
if (pbuf_len == 0)
- return log_openssl_errors("Failed to convert ECC point to buffer");
+ return log_openssl_errors(LOG_DEBUG, "Failed to convert ECC point to buffer");
if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, pbuf, pbuf_len))
- return log_openssl_errors("Failed to add ECC OSSL_PKEY_PARAM_PUB_KEY");
+ return log_openssl_errors(LOG_DEBUG, "Failed to add ECC OSSL_PKEY_PARAM_PUB_KEY");
_cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
if (!params)
- return log_openssl_errors("Failed to build ECC OSSL_PARAM");
+ return log_openssl_errors(LOG_DEBUG, "Failed to build ECC OSSL_PARAM");
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
if (sym_EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
- return log_openssl_errors("Failed to create ECC EVP_PKEY");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create ECC EVP_PKEY");
*ret = TAKE_PTR(pkey);
return 0;
size_t name_size;
if (!sym_EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0, &name_size))
- return log_openssl_errors("Failed to get ECC group name size");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get ECC group name size");
_cleanup_free_ char *name = new(char, name_size + 1);
if (!name)
return log_oom_debug();
if (!sym_EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, name, name_size + 1, NULL))
- return log_openssl_errors("Failed to get ECC group name");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get ECC group name");
curve_id = sym_OBJ_sn2nid(name);
if (curve_id == NID_undef)
- return log_openssl_errors("Failed to get ECC curve id");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get ECC curve id");
if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &bn_x))
- return log_openssl_errors("Failed to get ECC point x");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get ECC point x");
if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &bn_y))
- return log_openssl_errors("Failed to get ECC point y");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get ECC point y");
size_t x_size = sym_BN_num_bytes(bn_x), y_size = sym_BN_num_bytes(bn_y);
_cleanup_free_ void *x = malloc(x_size), *y = malloc(y_size);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_PKEY_CTX");
if (sym_EVP_PKEY_keygen_init(ctx) <= 0)
- return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_PKEY_CTX");
if (sym_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve_id) <= 0)
- return log_openssl_errors("Failed to set ECC curve %d", curve_id);
+ return log_openssl_errors(LOG_DEBUG, "Failed to set ECC curve %d", curve_id);
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
if (sym_EVP_PKEY_keygen(ctx, &pkey) <= 0)
- return log_openssl_errors("Failed to generate ECC key");
+ return log_openssl_errors(LOG_DEBUG, "Failed to generate ECC key");
*ret = TAKE_PTR(pkey);
_cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new((EVP_PKEY*) private_pkey, NULL);
if (!ctx)
- return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_PKEY_CTX");
if (sym_EVP_PKEY_derive_init(ctx) <= 0)
- return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize EVP_PKEY_CTX");
if (sym_EVP_PKEY_derive_set_peer(ctx, (EVP_PKEY*) peer_pkey) <= 0)
- return log_openssl_errors("Failed to set ECC derive peer");
+ return log_openssl_errors(LOG_DEBUG, "Failed to set ECC derive peer");
size_t shared_secret_size;
if (sym_EVP_PKEY_derive(ctx, NULL, &shared_secret_size) <= 0)
- return log_openssl_errors("Failed to get ECC shared secret size");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get ECC shared secret size");
_cleanup_(erase_and_freep) void *shared_secret = malloc(shared_secret_size);
if (!shared_secret)
return log_oom_debug();
if (sym_EVP_PKEY_derive(ctx, (unsigned char*) shared_secret, &shared_secret_size) <= 0)
- return log_openssl_errors("Failed to derive ECC shared secret");
+ return log_openssl_errors(LOG_DEBUG, "Failed to derive ECC shared secret");
*ret_shared_secret = TAKE_PTR(shared_secret);
*ret_shared_secret_size = shared_secret_size;
sz = sym_i2d_PublicKey(pk, NULL);
if (sz < 0)
- return log_openssl_errors("Unable to convert public key to DER format");
+ return log_openssl_errors(LOG_DEBUG, "Unable to convert public key to DER format");
dd = d = malloc(sz);
if (!d)
lsz = sym_i2d_PublicKey(pk, &dd);
if (lsz < 0)
- return log_openssl_errors("Unable to convert public key to DER format");
+ return log_openssl_errors(LOG_DEBUG, "Unable to convert public key to DER format");
m = sym_EVP_MD_CTX_new();
if (!m)
- return log_openssl_errors("Failed to create new EVP_MD_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_MD_CTX");
if (sym_EVP_DigestInit_ex(m, md, NULL) != 1)
- return log_openssl_errors("Failed to initialize %s context", sym_EVP_MD_get0_name(md));
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize %s context", sym_EVP_MD_get0_name(md));
if (sym_EVP_DigestUpdate(m, d, lsz) != 1)
- return log_openssl_errors("Failed to run %s context", sym_EVP_MD_get0_name(md));
+ return log_openssl_errors(LOG_DEBUG, "Failed to run %s context", sym_EVP_MD_get0_name(md));
msz = sym_EVP_MD_get_size(md);
assert(msz > 0);
umsz = msz;
if (sym_EVP_DigestFinal_ex(m, h, &umsz) != 1)
- return log_openssl_errors("Failed to finalize hash context");
+ return log_openssl_errors(LOG_DEBUG, "Failed to finalize hash context");
assert(umsz == (unsigned) msz);
_cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX* mdctx = sym_EVP_MD_CTX_new();
if (!mdctx)
- return log_openssl_errors("Failed to create new EVP_MD_CTX");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create new EVP_MD_CTX");
/* Note that a NULL 'md' (message digest algorithm) means to sign the provided data directly, without
* hashing it first, as long as a suitable signing algorithm is used that supports this, such as
/* Distro security policies often disable support for SHA-1. Let's return a recognizable
* error for that case. */
bool invalid_digest = ERR_GET_REASON(sym_ERR_peek_last_error()) == EVP_R_INVALID_DIGEST;
- r = log_openssl_errors("Failed to initialize signature context");
+ r = log_openssl_errors(LOG_DEBUG, "Failed to initialize signature context");
return invalid_digest ? -EADDRNOTAVAIL : r;
}
/* Determine signature size */
size_t ss;
if (sym_EVP_DigestSign(mdctx, NULL, &ss, data, size) != 1)
- return log_openssl_errors("Failed to determine size of signature");
+ return log_openssl_errors(LOG_DEBUG, "Failed to determine size of signature");
_cleanup_free_ void *sig = malloc(ss);
if (!sig)
return log_oom_debug();
if (sym_EVP_DigestSign(mdctx, sig, &ss, data, size) != 1)
- return log_openssl_errors("Failed to sign data");
+ return log_openssl_errors(LOG_DEBUG, "Failed to sign data");
*ret = TAKE_PTR(sig);
*ret_size = ss;
return log_oom();
if (sym_PKCS7_set_type(p7, NID_pkcs7_signed) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 type: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set PKCS7 type");
if (sym_PKCS7_content_new(p7, NID_pkcs7_data) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 content: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set PKCS7 content");
if (sym_PKCS7_add_certificate(p7, certificate) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 certificate: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set PKCS7 certificate");
int x509_pknid = 0;
if (sym_X509_get_signature_info(certificate, NULL, &x509_pknid, NULL, NULL) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to get X509 digest NID: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to get X509 digest NID");
const EVP_MD *md = sym_EVP_get_digestbyname(hash_algorithm ?: "SHA256");
if (!md)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest algorithm '%s'",
+ return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported digest algorithm '%s'",
hash_algorithm ?: "SHA256");
_cleanup_(PKCS7_SIGNER_INFO_freep) PKCS7_SIGNER_INFO *si = sym_PKCS7_SIGNER_INFO_new();
if (private_key) {
if (sym_PKCS7_SIGNER_INFO_set(si, certificate, private_key, md) <= 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to configure signer info: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to configure signer info");
} else {
if (sym_ASN1_INTEGER_set(si->version, 1) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info version: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set signer info version");
if (sym_X509_NAME_set(&si->issuer_and_serial->issuer, sym_X509_get_issuer_name(certificate)) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info issuer: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set signer info issuer");
sym_ASN1_INTEGER_free(si->issuer_and_serial->serial);
si->issuer_and_serial->serial = sym_ASN1_INTEGER_dup(sym_X509_get0_serialNumber(certificate));
if (!si->issuer_and_serial->serial)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info serial: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set signer info serial");
if (sym_X509_ALGOR_set0(si->digest_alg, sym_OBJ_nid2obj(sym_EVP_MD_get_type(md)), V_ASN1_NULL, NULL) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info digest algorithm: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set signer info digest algorithm");
if (sym_X509_ALGOR_set0(si->digest_enc_alg, sym_OBJ_nid2obj(x509_pknid), V_ASN1_NULL, NULL) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info signing algorithm: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set signer info signing algorithm");
}
if (sym_PKCS7_add_signer(p7, si) == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 signer info: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to set PKCS7 signer info");
*ret_p7 = TAKE_PTR(p7);
if (ret_si)
return r;
if (sym_EVP_PKEY_get_group_name(pkey, NULL, 0, &len) != 1 || len == 0)
- return log_openssl_errors("Failed to determine PKEY group name length");
+ return log_openssl_errors(LOG_DEBUG, "Failed to determine PKEY group name length");
len++;
curve_name = new(char, len);
return log_oom_debug();
if (sym_EVP_PKEY_get_group_name(pkey, curve_name, len, &len) != 1)
- return log_openssl_errors("Failed to get PKEY group name");
+ return log_openssl_errors(LOG_DEBUG, "Failed to get PKEY group name");
r = ecc_pkey_new(sym_OBJ_sn2nid(curve_name), &pkey_new);
if (r < 0)
See https://github.com/openssl/openssl/discussions/22835 */
saved_key_size = sym_EVP_PKEY_get1_encoded_public_key(pkey_new, &saved_key);
if (saved_key_size == 0)
- return log_openssl_errors("Failed to convert the generated public key to SEC1 format");
+ return log_openssl_errors(LOG_DEBUG, "Failed to convert the generated public key to SEC1 format");
*ret_decrypted_key = TAKE_PTR(decrypted_key);
*ret_decrypted_key_size = decrypted_key_size;
/* Load the provider so that this can work without any custom written configuration in /etc/.
* Also load the 'default' as that seems to be the recommendation. */
if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true))
- return log_openssl_errors("Failed to load OpenSSL provider '%s'", provider);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load OpenSSL provider '%s'", provider);
if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, "default", /* retain_fallbacks= */ true))
- return log_openssl_errors("Failed to load OpenSSL provider 'default'");
+ return log_openssl_errors(LOG_DEBUG, "Failed to load OpenSSL provider 'default'");
_cleanup_(OSSL_STORE_closep) OSSL_STORE_CTX *store = sym_OSSL_STORE_open(
private_key_uri,
/* post_process= */ NULL,
/* post_process_data= */ NULL);
if (!store)
- return log_openssl_errors("Failed to open OpenSSL store via '%s'", private_key_uri);
+ return log_openssl_errors(LOG_DEBUG, "Failed to open OpenSSL store via '%s'", private_key_uri);
if (sym_OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) == 0)
- return log_openssl_errors("Failed to filter store by private keys");
+ return log_openssl_errors(LOG_DEBUG, "Failed to filter store by private keys");
_cleanup_(OSSL_STORE_INFO_freep) OSSL_STORE_INFO *info = sym_OSSL_STORE_load(store);
if (!info)
- return log_openssl_errors("Failed to load OpenSSL store via '%s'", private_key_uri);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load OpenSSL store via '%s'", private_key_uri);
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = sym_OSSL_STORE_INFO_get1_PKEY(info);
if (!private_key)
- return log_openssl_errors("Failed to load private key via '%s'", private_key_uri);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load private key via '%s'", private_key_uri);
*ret = TAKE_PTR(private_key);
DISABLE_WARNING_DEPRECATED_DECLARATIONS;
_cleanup_(ENGINE_freep) ENGINE *e = sym_ENGINE_by_id(engine);
if (!e)
- return log_openssl_errors("Failed to load signing engine '%s'", engine);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load signing engine '%s'", engine);
if (sym_ENGINE_init(e) == 0)
- return log_openssl_errors("Failed to initialize signing engine '%s'", engine);
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize signing engine '%s'", engine);
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = sym_ENGINE_load_private_key(e, private_key_uri, ui_method, /* callback_data= */ NULL);
if (!private_key)
- return log_openssl_errors("Failed to load private key from '%s'", private_key_uri);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load private key from '%s'", private_key_uri);
REENABLE_WARNING;
*ret = TAKE_PTR(private_key);
}
if (sym_UI_set_result(ui, uis, *l) != 0) {
- log_openssl_errors("Failed to set user interface result");
+ log_openssl_errors(LOG_DEBUG, "Failed to set user interface result");
return 0;
}
pk = sym_PEM_read_bio_PrivateKey(kb, NULL, NULL, NULL);
if (!pk)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse PEM private key: %s",
- sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ return log_openssl_errors(LOG_DEBUG, "Failed to parse PEM private key");
*ret = TAKE_PTR(pk);
_cleanup_(UI_destroy_methodp) UI_METHOD *method = sym_UI_create_method("systemd-ask-password");
if (!method)
- return log_openssl_errors("Failed to initialize openssl user interface");
+ return log_openssl_errors(LOG_DEBUG, "Failed to initialize openssl user interface");
if (sym_UI_method_set_reader(method, openssl_ask_password_ui_read) != 0)
- return log_openssl_errors("Failed to set openssl user interface reader");
+ return log_openssl_errors(LOG_DEBUG, "Failed to set openssl user interface reader");
OpenSSLAskPasswordUI *ui = new(OpenSSLAskPasswordUI, 1);
if (!ui)
sym_UI_set_default_method(ui->method);
if (sym_UI_method_set_ex_data(ui->method, 0, &ui->request) == 0)
- return log_openssl_errors("Failed to set extra data for UI method");
+ return log_openssl_errors(LOG_DEBUG, "Failed to set extra data for UI method");
*ret = TAKE_PTR(ui);
return 0;
/* Load the provider so that this can work without any custom written configuration in /etc/.
* Also load the 'default' as that seems to be the recommendation. */
if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true))
- return log_openssl_errors("Failed to load OpenSSL provider '%s'", provider);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load OpenSSL provider '%s'", provider);
if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, "default", /* retain_fallbacks= */ true))
- return log_openssl_errors("Failed to load OpenSSL provider 'default'");
+ return log_openssl_errors(LOG_DEBUG, "Failed to load OpenSSL provider 'default'");
_cleanup_(OSSL_STORE_closep) OSSL_STORE_CTX *store = sym_OSSL_STORE_open(
certificate_uri,
/* post_process= */ NULL,
/* post_process_data= */ NULL);
if (!store)
- return log_openssl_errors("Failed to open OpenSSL store via '%s'", certificate_uri);
+ return log_openssl_errors(LOG_DEBUG, "Failed to open OpenSSL store via '%s'", certificate_uri);
if (sym_OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) == 0)
- return log_openssl_errors("Failed to filter store by X.509 certificates");
+ return log_openssl_errors(LOG_DEBUG, "Failed to filter store by X.509 certificates");
_cleanup_(OSSL_STORE_INFO_freep) OSSL_STORE_INFO *info = sym_OSSL_STORE_load(store);
if (!info)
- return log_openssl_errors("Failed to load OpenSSL store via '%s'", certificate_uri);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load OpenSSL store via '%s'", certificate_uri);
_cleanup_(X509_freep) X509 *cert = sym_OSSL_STORE_INFO_get1_CERT(info);
if (!cert)
- return log_openssl_errors("Failed to load certificate via '%s'", certificate_uri);
+ return log_openssl_errors(LOG_DEBUG, "Failed to load certificate via '%s'", certificate_uri);
*ret = TAKE_PTR(cert);
dersz = sym_i2d_X509(cert, &der);
if (dersz < 0)
- return log_openssl_errors("Unable to convert PEM certificate to DER format");
+ return log_openssl_errors(LOG_DEBUG, "Unable to convert PEM certificate to DER format");
sha256_direct(der, dersz, buffer);
return 0;
return -ENOMEM;
if (sym_i2d_PUBKEY_fp(tf, private_key) != 1)
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to extract public key in DER format");
_cleanup_(erase_and_freep) char *buf = NULL;
size_t len;
const unsigned char *t = (const unsigned char*) buf;
if (!sym_d2i_PUBKEY(ret, &t, len))
- return -EIO;
+ return log_openssl_errors(LOG_DEBUG, "Failed to parse public key in DER format");
return 0;
}
sym_sk_X509_pop_free(*sk, sym_X509_free);
}
+/* Translates an OpenSSL error code (as returned by ERR_get_error()) into a negative errno. Returns
+ * -ENOTRECOVERABLE when passed 0 or when the error's reason has no more specific errno. */
+int openssl_to_errno(unsigned long e);
+
+int log_openssl_errors_internal(int level, const char *file, int line, const char *func, const char *format, ...) _printf_(5, 6);
+
+/* Logs `format` at `level`, suffixed with each error from the OpenSSL thread-local error queue (or
+ * "No OpenSSL errors." when it is empty), and returns a negative errno derived from the last error
+ * (-ENOTRECOVERABLE when the queue is empty or the reason isn't recognized). */
+#define log_openssl_errors(level, format, ...) \
+ log_openssl_errors_internal(level, PROJECT_FILE, __LINE__, __func__, format, ##__VA_ARGS__)
+
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);
if (r)
log_debug("Userspace PKCS#7 validation succeeded.");
else
- log_debug("Userspace PKCS#7 validation failed: %s", sym_ERR_error_string(sym_ERR_get_error(), NULL));
+ log_openssl_errors(LOG_DEBUG, "Userspace PKCS#7 validation failed");
return r;
#else
_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.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create an EVP_PKEY_CTX for EC.");
if (sym_EVP_PKEY_fromdata_init(ctx) != 1)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to init an EVP_PKEY_CTX for EC.");
+ return log_openssl_errors(LOG_DEBUG, "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
return log_oom_debug();
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.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to extract EC parameters from EC_GROUP.");
order_size = sym_BN_num_bytes(bn_order);
p_size = sym_BN_num_bytes(bn_p);
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.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to store EC parameters in native byte order.");
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.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to determine size of a EC generator.");
generator = malloc(generator_size);
if (!generator)
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.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to convert a EC generator to octet string.");
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);
}
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.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to create EVP_PKEY from EC parameters.");
break;
}
default:
_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.");
+ return log_openssl_errors(LOG_DEBUG, "Failed to format X.509 subject name as string.");
log_debug("Using X.509 certificate issued for '%s'.", t);
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");
+ return log_openssl_errors(LOG_ERR, "Failed to determine size of a compressed EC point");
compressed_point = malloc(compressed_point_size);
if (!compressed_point)
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");
+ return log_openssl_errors(LOG_ERR, "Failed to convert a EC point to compressed format");
*ret_compressed_point = TAKE_PTR(compressed_point);
*ret_compressed_point_size = compressed_point_size;
pkey = sym_X509_get_pubkey(cert);
if (!pkey)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract public key from X.509 certificate.");
+ return log_openssl_errors(LOG_ERR, "Failed to extract public key from X.509 certificate.");
}
success:
/* Let's read some random data off the token and write it to the kernel pool before we generate our
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
DEFINE_HEX_PTR(key, "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d466b7b");
- assert_se(openssl_pubkey_from_pem(key, key_len, &pkey) == -EIO);
+ /* OpenSSL's decoder reports ERR_R_UNSUPPORTED for this garbage, which openssl_to_errno() maps
+ * to -EOPNOTSUPP. */
+ ASSERT_ERROR(openssl_pubkey_from_pem(key, key_len, &pkey), EOPNOTSUPP);
ASSERT_NULL(pkey);
}
return log_error_errno(r, "Failed to open SRK public key file '%s' for writing: %m", pem_path);
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);
+ return log_openssl_errors(LOG_ERR, "Failed to write SRK public key file '%s'.", pem_path);
if (fchmod(fileno(f), 0444) < 0)
return log_error_errno(errno, "Failed to adjust access mode of SRK public key file '%s' to 0444: %m", pem_path);