if (r < 0)
return r;
- _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX* mdctx = NULL;
- mdctx = EVP_MD_CTX_new();
- if (!mdctx)
- return log_oom();
-
- if (EVP_DigestSignInit(mdctx, NULL, p->md, NULL, privkey) != 1)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to initialize signature context.");
-
- if (EVP_DigestSignUpdate(mdctx, pcr_policy_digest.buffer, pcr_policy_digest.size) != 1)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to sign data.");
-
+ _cleanup_free_ void *sig = NULL;
size_t ss;
- if (EVP_DigestSignFinal(mdctx, NULL, &ss) != 1)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to finalize signature");
- _cleanup_free_ void *sig = malloc(ss);
- if (!sig)
- return log_oom();
-
- if (EVP_DigestSignFinal(mdctx, sig, &ss) != 1)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to acquire signature data");
+ r = digest_and_sign(p->md, privkey, pcr_policy_digest.buffer, pcr_policy_digest.size, &sig, &ss);
+ if (r < 0)
+ return log_error_errno(r, "Failed to sign PCR policy: %m");
_cleanup_free_ void *pubkey_fp = NULL;
size_t pubkey_fp_size = 0;
_cleanup_(memstream_done) MemStream m = {};
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
_cleanup_(user_record_unrefp) UserRecord *signed_ur = NULL;
- _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *md_ctx = NULL;
_cleanup_free_ char *text = NULL, *key = NULL;
_cleanup_free_ void *signature = NULL;
size_t signature_size = 0;
if (r < 0)
return r;
- md_ctx = EVP_MD_CTX_new();
- if (!md_ctx)
- return -ENOMEM;
-
- if (EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, private_key) <= 0)
- return -EIO;
-
- /* Request signature size */
- if (EVP_DigestSign(md_ctx, NULL, &signature_size, (uint8_t*) text, strlen(text)) <= 0)
- return -EIO;
-
- signature = malloc(signature_size);
- if (!signature)
- return -ENOMEM;
-
- if (EVP_DigestSign(md_ctx, signature, &signature_size, (uint8_t*) text, strlen(text)) <= 0)
- return -EIO;
+ r = digest_and_sign(/* md= */ NULL, private_key, text, SIZE_MAX, &signature, &signature_size);
+ if (r < 0)
+ return r;
f = memstream_init(&m);
if (!f)
return 0;
}
+int digest_and_sign(
+ const EVP_MD *md,
+ EVP_PKEY *privkey,
+ const void *data, size_t size,
+ void **ret, size_t *ret_size) {
+
+ assert(privkey);
+ assert(ret);
+ assert(ret_size);
+
+ if (size == 0)
+ data = ""; /* make sure to pass a valid pointer to OpenSSL */
+ else {
+ assert(data);
+
+ if (size == SIZE_MAX) /* If SIZE_MAX input is a string whose size we determine automatically */
+ size = strlen(data);
+ }
+
+ _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
+ if (!mdctx)
+ return log_openssl_errors("Failed to create new EVP_MD_CTX");
+
+ if (EVP_DigestSignInit(mdctx, NULL, md, NULL, privkey) != 1)
+ return log_openssl_errors("Failed to initialize signature context");
+
+ /* Determine signature size */
+ size_t ss;
+ if (EVP_DigestSign(mdctx, NULL, &ss, data, size) != 1)
+ return log_openssl_errors("Failed to determine size of signature");
+
+ _cleanup_free_ void *sig = malloc(ss);
+ if (!sig)
+ return log_oom_debug();
+
+ if (EVP_DigestSign(mdctx, sig, &ss, data, size) != 1)
+ return log_openssl_errors("Failed to sign data");
+
+ *ret = TAKE_PTR(sig);
+ *ret_size = ss;
+ return 0;
+}
+
# if PREFER_OPENSSL
int string_hashsum(
const char *s,
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);
+
#else
typedef struct X509 X509;