EVP_PKEY_VERIFY_RECOVER(3SSL)
π EVP_PKEY_VERIFY_RECOVER π
okay bestie, so this one's from the OpenSSL manual set β the 3SSL girlies, section 3, you know the vibe π β and it's all about the verify-recover operation, which is lowkey one of the most underrated little moves in the whole public key toolkit. it's giving "wait, you can get the original data back?" and yes, queen, sometimes you can β¨
β¨ NAME β¨
EVP_PKEY_verify_recover_init, EVP_PKEY_verify_recover_init_ex, EVP_PKEY_verify_recover_init_ex2, EVP_PKEY_verify_recover β recover signature using a public key algorithm π¦
β¨ SYNOPSIS β¨
#include <openssl/evp.h>
int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_verify_recover_init_ex(EVP_PKEY_CTX *ctx,
const OSSL_PARAM params[]);
int EVP_PKEY_verify_recover_init_ex2(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *algo,
const OSSL_PARAM params[]);
int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
unsigned char *rout, size_t *routlen,
const unsigned char *sig, size_t siglen);
β¨ DESCRIPTION β¨
okay so let's go one by one π
EVP_PKEY_verify_recover_init()β this one sets up a public key algorithm contextctxfor a verify-recover operation, using whatever algorithm got chosen back when the context was created withEVP_PKEY_CTX_new(3)(or one of its variants, iykyk). that algorithm gets used to fetch anEVP_SIGNATUREmethod implicitly β and if you wanna know the whole tea about implicit fetches, go read "Implicit fetch" inprovider(7)πΈEVP_PKEY_verify_recover_init_ex()β literally the same asEVP_PKEY_verify_recover_init(), except it also sets the parameters you pass inparamson the context before it hands control back to you. cute, right? πEVP_PKEY_verify_recover_init_ex2()β same asEVP_PKEY_verify_recover_init_ex(), but it works with an explicitly fetchedEVP_SIGNATUREnamedalgo. π¨ heads up though: a contextctxwith no pre-loaded key can't be used with this one, periodt. and depending on which algorithm got fetched, some details about how the input toEVP_PKEY_verify_recover()gets treated may already be pre-determined β and in that case those details normally can't be changed. see NOTES below for the full deep dive πEVP_PKEY_verify_recover()β the main character π this recovers signed data usingctx. the signature comes in through thesigandsiglenparameters. ifroutisNULL, then the maximum size of the output buffer gets written to theroutlenparameter. ifroutis notNULL, then before the callroutlenshould contain the length of theroutbuffer β and if the call succeeds, the recovered data gets written torout, and the amount of data actually written goes intoroutlen. slay π
π«Ά NOTES π«Ά
ngl, most of the time an application only cares whether a signature verification succeeded or not β and in those cases you should just use EVP_verify(). that's the normal happy path, no drama π
Sometimes, though β and this is the fun part β it's useful to get back the data that was originally signed by a signing operation π. only certain public key algorithms can recover a signature this way (for example, RSA in PKCS padding mode β iconic behaviour, honestly).
- after you call
EVP_PKEY_verify_recover_init(), you can do algorithm-specific control operations to set whatever parameters the operation needs. - after you call
EVP_PKEY_verify_recover_init_ex2(), algorithm-specific control operations might not even be needed β because the chosen algorithm might already imply that those controls are pre-set (and immutable). so don't go trying to change them, bestie π« - and
EVP_PKEY_verify_recover()can be called more than once on the same context, if you're doing several operations with the same parameters. reuse era π₯
πΈ RETURN VALUES πΈ
EVP_PKEY_verify_recover_init() and EVP_PKEY_verify_recover() return 1 for success, and 0 or a negative value for failure π. in particular, a return value of -2 means the operation is not supported by the public key algorithm. so if you see -2, that's your sign to pick a different algorithm, gorgeous π¦
β EXAMPLES β
Recover digest originally signed using PKCS#1 and SHA256 digest:
#include <openssl/evp.h>
#include <openssl/rsa.h>
EVP_PKEY_CTX *ctx;
unsigned char *rout, *sig;
size_t routlen, siglen;
EVP_PKEY *verify_key;
/*
* NB: assumes verify_key, sig and siglen are already set up
* and that verify_key is an RSA public key
*/
ctx = EVP_PKEY_CTX_new(verify_key, NULL);
if (!ctx)
/* Error occurred */
if (EVP_PKEY_verify_recover_init(ctx) <= 0)
/* Error */
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
/* Error */
if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
/* Error */
/* Determine buffer length */
if (EVP_PKEY_verify_recover(ctx, NULL, &routlen, sig, siglen) <= 0)
/* Error */
rout = OPENSSL_malloc(routlen);
if (!rout)
/* malloc failure */
if (EVP_PKEY_verify_recover(ctx, rout, &routlen, sig, siglen) <= 0)
/* Error */
/* Recovered data is routlen bytes written to buffer rout */
see the two-call pattern? first call with rout as NULL to find out how big the buffer needs to be, then malloc, then call again for real. that's the classic β¨ ask-then-act β¨ and it never misses π
π₯ SEE ALSO π₯
EVP_PKEY_CTX_new(3), EVP_PKEY_encrypt(3), EVP_PKEY_decrypt(3), EVP_PKEY_sign(3), EVP_PKEY_verify(3), EVP_PKEY_derive(3)
the whole squad, fr fr π
π HISTORY π
EVP_PKEY_verify_recover_init()andEVP_PKEY_verify_recover()were added in OpenSSL 1.0.0.EVP_PKEY_verify_recover_init_ex()was added in OpenSSL 3.0.
(note: the original list doesn't mention a version for EVP_PKEY_verify_recover_init_ex2(), so i'm not gonna invent one β no cap π)
π COPYRIGHT π
Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.
and that's the whole page, bestie β¨ this was version4.0.3, dated2026-09-29, from theEVP_PKEY_VERIFY_RECOVER(3SSL)man page β go forth and recover those signatures, you absolute icon π π¦πΈ
π¦ where this page comes from
- ubuntu stonking: libssl-doc 4.0.3-1ubuntu1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms