Re: EVP_PKEY_get_raw_public_key fails with OpenSSL 3.0

2022-11-23 Thread fus




Am 11.11.2022 um 17:44 schrieb Matt Caswell:



On 11/11/2022 12:41, f...@plutonium24.de wrote:


My apologies. I tested the code you supplied and of course it also fails with 1.1.1. The 
code was changed without my knowledge when updating to 3.0 and the version that was 
working used the deprecated "EC_POINT_point2oct". During my test I missed this.

Concerning the questions James akesd: I extract the key from an X509 
certificate (with X509_get0_pubkey). And as you suggested I just need the bytes 
of the public EC point. As a reference to which I want to compare this data I 
only have the raw public key and a proprietarily encoded curve id which I also 
check.


I'd like to come back to the question : how can I get the raw public 
key^without using deprecated functionality?

Frank



Probably calling EVP_PKEY_get_octet_string_param() and asking for the parameter 
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY should do it. See these man pages:

https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_get_params.html

https://www.openssl.org/docs/man3.0/man7/EVP_PKEY-EC.html

Matt


Many thanks, asking for the encoded public key as an octet string did work 
correctly.

Frank


Re: EVP_PKEY_get_raw_public_key fails with OpenSSL 3.0

2022-11-11 Thread Matt Caswell




On 11/11/2022 12:41, f...@plutonium24.de wrote:


My apologies. I tested the code you supplied and of course it also fails 
with 1.1.1. The code was changed without my knowledge when updating to 
3.0 and the version that was working used the deprecated 
"EC_POINT_point2oct". During my test I missed this.


Concerning the questions James akesd: I extract the key from an X509 
certificate (with X509_get0_pubkey). And as you suggested I just need 
the bytes of the public EC point. As a reference to which I want to 
compare this data I only have the raw public key and a proprietarily 
encoded curve id which I also check.



I'd like to come back to the question : how can I get the raw public 
key^without using deprecated functionality?


Frank



Probably calling EVP_PKEY_get_octet_string_param() and asking for the 
parameter OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY should do it. See these man 
pages:


https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_get_params.html

https://www.openssl.org/docs/man3.0/man7/EVP_PKEY-EC.html

Matt



Re: EVP_PKEY_get_raw_public_key fails with OpenSSL 3.0

2022-11-11 Thread Matt Caswell




On 11/11/2022 00:49, James Muir wrote:

On 2022-11-10 18:35, f...@plutonium24.de wrote:
I have been using EVP_PKEY_get_raw_public_key with OpenSSL 1.1.1 
without any problems to extract a raw public key (secp521r1, NIST 
curve P-521). With OpenSSL 3.0 this fails. I'm using this call to get 
the raw public key and to compare it with a reference value I have and 
I also check that the group name is "secp521r1".


That doesn't work in 3.0.

Quoting from 
https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_new.html  :



EVP_PKEY_get_raw_public_key() fills the buffer provided by pub with raw 
public key data. The size of the pub buffer should be in *len on entry 
to the function, and on exit *len is updated with the number of bytes 
actually written. If the buffer pub is NULL then *len is populated with 
the number of bytes required to hold the key. The calling application is 
responsible for ensuring that the buffer is large enough to receive the 
public key data. This function only works for algorithms that support 
raw public keys. Currently this is: EVP_PKEY_X25519, EVP_PKEY_ED25519, 
EVP_PKEY_X448 or EVP_PKEY_ED448.





That text exists even in the 1.1.1 version of the man page:

https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_get_raw_public_key.html

I am surprised that this was working in 1.1.1from code inspection I 
can't see how it would since EC keys seem to lack the necessary support. 
I threw together some test code to check this using 1.1.1:


#include 
#include 
#include 
#include 
#include 
#include 

int main(void)
{
EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp521r1);
EVP_PKEY *pkey = EVP_PKEY_new();
unsigned char rawkey[1024];
size_t keylen = sizeof(rawkey);

if (key == NULL || pkey == NULL) {
printf("Failed to allocate keys\n");
goto err;
}

if (!EC_KEY_generate_key(key)) {
printf("Failed to generate key\n");
goto err;
}

if (!EVP_PKEY_assign_EC_KEY(pkey, key)) {
printf("Failed to assign EC_KEY\n");
goto err;
}

if (!EVP_PKEY_get_raw_public_key(pkey, rawkey, &keylen)) {
printf("Failed to get raw public key\n");
goto err;
}

printf("Raw key is:\n");
BIO_dump_fp(stdout, rawkey, keylen);
printf("\n");

return EXIT_SUCCESS;
 err:
ERR_print_errors_fp(stdout);
return EXIT_FAILURE;
}

Running this I get:

$ openssl version
OpenSSL 1.1.1t-dev  xx XXX 
$ ./eckeygen
Failed to get raw public key
140164760770368:error:060CB096:digital envelope 
routines:EVP_PKEY_get_raw_public_key:operation not supported for this 
keytype:crypto/evp/p_lib.c:309:


So, I don't understand how this ever worked for you. There must be 
something slightly strange about your key/setup??


Matt

You were reading the P521 public-key previously (with 1.1.1), but in 
what format was it sent you?  Do you want just the bytes of the public 
EC point?


-James M



Re: EVP_PKEY_get_raw_public_key fails with OpenSSL 3.0

2022-11-10 Thread James Muir

On 2022-11-10 18:35, f...@plutonium24.de wrote:
I have been using EVP_PKEY_get_raw_public_key with OpenSSL 1.1.1 without 
any problems to extract a raw public key (secp521r1, NIST curve P-521). 
With OpenSSL 3.0 this fails. I'm using this call to get the raw public 
key and to compare it with a reference value I have and I also check 
that the group name is "secp521r1".


That doesn't work in 3.0.

Quoting from 
https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_new.html  :



EVP_PKEY_get_raw_public_key() fills the buffer provided by pub with raw 
public key data. The size of the pub buffer should be in *len on entry 
to the function, and on exit *len is updated with the number of bytes 
actually written. If the buffer pub is NULL then *len is populated with 
the number of bytes required to hold the key. The calling application is 
responsible for ensuring that the buffer is large enough to receive the 
public key data. This function only works for algorithms that support 
raw public keys. Currently this is: EVP_PKEY_X25519, EVP_PKEY_ED25519, 
EVP_PKEY_X448 or EVP_PKEY_ED448.



You were reading the P521 public-key previously (with 1.1.1), but in 
what format was it sent you?  Do you want just the bytes of the public 
EC point?


-James M


EVP_PKEY_get_raw_public_key fails with OpenSSL 3.0

2022-11-10 Thread fus
I have been using EVP_PKEY_get_raw_public_key with OpenSSL 1.1.1 without 
any problems to extract a raw public key (secp521r1, NIST curve P-521). 
With OpenSSL 3.0 this fails. I'm using this call to get the raw public 
key and to compare it with a reference value I have and I also check 
that the group name is "secp521r1".


This is what happens:
1) as pkey->keymgmt != NULL EVP_PKEY_get_raw_public_key calls 
evp_keymgmt_util_export with selection=OSSL_KEYMGMT_SELECT_PUBLIC_KEY

2) evp_keymgmt_util_export calls evp_keymgmt_export
3) evp_keymgmt_export calls ec_export
4) ec_export fails as it does not support returning a public key without 
domain parameters (selection only contains 
OSSL_KEYMGMT_SELECT_PUBLIC_KEY)


In OpenSSL 1.1.1 the pkey->keymgmt check in the first step is not 
present and a totally different path is taken which returns the correct 
public key.


At first this seems incompatible to me. But I think it would also be 
possible that by accident I misued the function with OpenSSL 1.1.1 as 
the algorithm is also not in the list of supported algorithms for 
OpenSSL 1.1.1.


Is this the correct function call and what did I do wrong? Or: what 
would be the correct approach to get the raw key?


Regards
Frank