Before openssl 3, (in openssl 1.1.1) when reading an RSA private key file, I used this function:
PEM_read_RSAPrivateKey(f, NULL, NULL, (void*)pass);
Where f
is the FILE*
and pass
is a const char*
.
If pass
was NULL
, this function automatically prompt a the user for password.
If pass
wasn't NULL
then it used the value pointed by pass
as a password.
Now in openssl 3
I had to use another function:
OSSL_DECODER_from_fp(*dctx, f)
Where dctx
is some context created by OSSL_DECODER_CTX_new_for_pkey()
and f
is that same private key file from before.
In order to set the password automatically (compared to having value for pass
in openssl 1.1.1
) I can use this function:
OSSL_DECODER_CTX_set_passphrase()
In case I do not call OSSL_DECODER_CTX_set_passphrase()
, OSSL_DECODER_from_fp()
fails with error:07880106:common libcrypto routines::passed invalid argument
without prompting the user for password.
From the man pages I see this (they use OSSL_DECODER_from_bio()
instead of ...fp()
):
if (pass != NULL)
OSSL_DECODER_CTX_set_passphrase(dctx, pass, strlen(pass));
if (OSSL_DECODER_from_bio(dctx, bio)) {
/* pkey is created with the decoded data from the bio */
} else {
/* decoding failure */
}
Which shows what I was trying to do - call OSSL_DECODER_from_fp()
and expect it to prompt the user for password in case pass == NULL
.
Unfortunately there aren't any good examples, or any examples at all for openssl 3
.
I tried digging in their source files and I saw some complicated stuff which I think may do that simple thing that I was trying to do, which is what was the generic-default behavior in openssl 1.1.1
, which is to prompt the user for password.
Stuff with ui
and UI_construct_prompt
...
Question: is there any simple way to prompt the user for password when reading a private key RSA file using openssl 3
with OSSL_DECODER_from_fp()
, as it was with openssl 1.1.1
with PEM_read_RSAPrivateKey()
?
Thanks.
Reproducible example:
#include <openssl/err.h>
#include <openssl/decoder.h>
#include <string.h>
int main() {
EVP_PKEY *pKey;
OSSL_DECODER_CTX *dctx = OSSL_DECODER_CTX_new_for_pkey((EVP_PKEY**)&pKey,
"PEM",
NULL,
"RSA",
OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
NULL,
NULL);
if (!dctx) {
printf("dctx\n");
return -1;
}
const char* prv_path = "/path/to/prv.pem";
FILE* f = fopen(prv_path, "rb");
if (!f) {
printf( "fopen() %s\n", prv_path);
return -1;
}
if (OSSL_DECODER_from_fp(dctx, f) <= 0) {
char buf[1024] = {0};
ERR_error_string_n(ERR_peek_error(), buf, sizeof(buf));
printf("OSSL_DECODER_from_fp(): %s\n", buf);
return -1;
}
return 0;
}
- Make sure you change the
prv_path
to an actual path to a private key generated with password. - Compile and run:
$ gcc example.c /usr/lib/x86_64-linux-gnu/libcrypto.a -lssl && ./a.out
OSSL_DECODER_from_fp(): error:07880106:common libcrypto routines::passed invalid argument
Example of how to generate a private key with password from this site