Re: dovecot 2.4 issue with openssl >= 3.0.8

2023-08-21 Thread Michal Hlavinka

updated patch works


On 21/08/2023 22:29, Aki Tuomi wrote:

Hi!

Thanks for pointing this out, I've updated the patch, and made it bit 
differently to ensure it works regardless where the key came from.

Aki


On 21/08/2023 23:04 EEST Michal Hlavinka  wrote:

  
Hi,


this patch does not fix the issue. It fixes that first test that failed,
but it fails a little bit further:
"""
test_read_increment .. : ok
test-stream.c:241: Assert failed: is_2->stream_errno == 0
test_write_read_v1 ... :
FAILED
test-stream.c:294: Assert failed: is_2->stream_errno == 0
test_write_read_v1_short . :
FAILED
"""

previously compression format was forced only for hex dump, this patch
affects how some keys are created, but does not affect those that are
loaded directly for example through PEM_read_bio_PUBKEY in:
dcrypt-openssl3.c:
dcrypt_openssl_load_public_key:2460:PEM_read_bio_PUBKEY

Cheers,
Michal Hlavinka

On 21/08/2023 09:08, Aki Tuomi wrote:

I think this should fix it https://cmouse.fi/ec-point.patch, can you please 
give it a try?

Aki


On 21/08/2023 09:34 EEST Aki Tuomi  wrote:

   

On 16/08/2023 01:09 EEST Michal Hlavinka  wrote:

   
Hi,


I've started testing main git branch and found an issue with openssl 3.

Test suite fails:
test_load_v1_key ... : ok
test-crypto.c:445: Assert failed: ret == TRUE
test-crypto.c:446: Assert failed: error == NULL
Panic: file dcrypt-openssl3.c: line 2917
(dcrypt_openssl_public_key_type): assertion failed: (key != NULL &&
key->key != NULL)
Error: Raw backtrace: test-crypto(+0x5af01) [0x55951b667f01] ->
test-crypto(backtrace_get+0x2f) [0x55951b66877f] ->
test-crypto(+0x31291) [0x55951b63e291] -> test-crypto(+0x312d5)
[0x55951b63e2d5] -> test-crypto(+0x16025) [0x55951b623025] ->
libdcrypt_openssl.so(+0x70ff) [0x7f5a995b60ff] -> test-crypto(+0x2a17b)
[0x55951b63717b] -> test-crypto(+0x3055d) [0x55951b63d55d] ->
test-crypto(test_run+0x6c) [0x55951b63d61c] -> test-crypto(main+0x4e)
[0x55951b62b66e] -> libc.so.6(+0x27b4a) [0x7f5a995eeb4a] ->
libc.so.6(__libc_start_main+0x8b) [0x7f5a995eec0b] ->
test-crypto(_start+0x25) [0x55951b62b7e5]

The issue is caused by change in openssl >= 3.0.8

in lib-dcryt/dcrypt-openssl3.c method ec_key_get_pub_point_hex(...)

in old version (for openssl 1.x) it uses compressed format:

EC_POINT_point2hex(g, p, POINT_CONVERSION_COMPRESSED, NULL);

in openssl3 version it uses

EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, buf,
sizeof(buf), );

but key is created in dcrypt_evp_pkey_from_point(...)
with OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, "uncompressed"

this was working in openssl pre 3.0.8 as compression format was ignored
when dumping data and used always compressed format.

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

""" Before OpenSSL 3.0.8, the implementation of providers included with
OpenSSL always opted for an encoding in compressed format,
unconditionally. Since OpenSSL 3.0.8, the implementation has been
changed to honor the OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT
parameter, if set, or to default to uncompressed format."""

I don't see simple way how to force compressed format just for dumping
data without effecting the key itself. Method that can be used with
compression format argument is EC_POINT_point2hex but it requires quite
lengthy extraction of EC_POINT first. I've tried this for testing with:

static const char *ec_key_get_pub_point_hex(const EVP_PKEY *pkey)
{
if (!EVP_PKEY_is_a(pkey, "EC"))
return NULL;
size_t len;

EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL,
0, );
buffer_t *parambuf = t_buffer_create(len+1);
EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, (char
*)parambuf->data, len+1, );
int nid = OBJ_txt2nid(parambuf->data);

EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0,
);
parambuf = t_buffer_create(len+1);
EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
(unsigned char *)parambuf->data, len+1, );

EC_GROUP *ec_grp = EC_GROUP_new_by_curve_name(nid);
if (ec_grp == NULL)
return NULL;
EC_POINT *point = EC_POINT_new(ec_grp);
if (point == NULL) {
EC_GROUP_free(ec_grp);
return NULL;
}

if (!EC_POINT_oct2point(ec_grp, point, parambuf->data, len, NULL))
return NULL;
char *ret = EC_POINT_point2hex(ec_grp, point,
POINT_CONVERSION_COMPRESSED, NULL);
EC_GROUP_free(ec_grp);
EC_POINT_free(point);
return ret;
}

and it fixed the issue, but there may be an easier way how to achieve that.

Cheers
Michal Hlavinka




Thank you for reporting this, we'll take a look at it!

Aki





Re: dovecot 2.4 issue with openssl >= 3.0.8

2023-08-21 Thread Aki Tuomi via dovecot
Hi!

Thanks for pointing this out, I've updated the patch, and made it bit 
differently to ensure it works regardless where the key came from.

Aki

> On 21/08/2023 23:04 EEST Michal Hlavinka  wrote:
> 
>  
> Hi,
> 
> this patch does not fix the issue. It fixes that first test that failed, 
> but it fails a little bit further:
> """
> test_read_increment .. : ok
> test-stream.c:241: Assert failed: is_2->stream_errno == 0
> test_write_read_v1 ... : 
> FAILED
> test-stream.c:294: Assert failed: is_2->stream_errno == 0
> test_write_read_v1_short . : 
> FAILED
> """
> 
> previously compression format was forced only for hex dump, this patch 
> affects how some keys are created, but does not affect those that are 
> loaded directly for example through PEM_read_bio_PUBKEY in:
> dcrypt-openssl3.c:
> dcrypt_openssl_load_public_key:2460:PEM_read_bio_PUBKEY
> 
> Cheers,
> Michal Hlavinka
> 
> On 21/08/2023 09:08, Aki Tuomi wrote:
> > I think this should fix it https://cmouse.fi/ec-point.patch, can you please 
> > give it a try?
> > 
> > Aki
> > 
> >> On 21/08/2023 09:34 EEST Aki Tuomi  wrote:
> >>
> >>   
> >>> On 16/08/2023 01:09 EEST Michal Hlavinka  wrote:
> >>>
> >>>   
> >>> Hi,
> >>>
> >>> I've started testing main git branch and found an issue with openssl 3.
> >>>
> >>> Test suite fails:
> >>> test_load_v1_key ... : ok
> >>> test-crypto.c:445: Assert failed: ret == TRUE
> >>> test-crypto.c:446: Assert failed: error == NULL
> >>> Panic: file dcrypt-openssl3.c: line 2917
> >>> (dcrypt_openssl_public_key_type): assertion failed: (key != NULL &&
> >>> key->key != NULL)
> >>> Error: Raw backtrace: test-crypto(+0x5af01) [0x55951b667f01] ->
> >>> test-crypto(backtrace_get+0x2f) [0x55951b66877f] ->
> >>> test-crypto(+0x31291) [0x55951b63e291] -> test-crypto(+0x312d5)
> >>> [0x55951b63e2d5] -> test-crypto(+0x16025) [0x55951b623025] ->
> >>> libdcrypt_openssl.so(+0x70ff) [0x7f5a995b60ff] -> test-crypto(+0x2a17b)
> >>> [0x55951b63717b] -> test-crypto(+0x3055d) [0x55951b63d55d] ->
> >>> test-crypto(test_run+0x6c) [0x55951b63d61c] -> test-crypto(main+0x4e)
> >>> [0x55951b62b66e] -> libc.so.6(+0x27b4a) [0x7f5a995eeb4a] ->
> >>> libc.so.6(__libc_start_main+0x8b) [0x7f5a995eec0b] ->
> >>> test-crypto(_start+0x25) [0x55951b62b7e5]
> >>>
> >>> The issue is caused by change in openssl >= 3.0.8
> >>>
> >>> in lib-dcryt/dcrypt-openssl3.c method ec_key_get_pub_point_hex(...)
> >>>
> >>> in old version (for openssl 1.x) it uses compressed format:
> >>>
> >>> EC_POINT_point2hex(g, p, POINT_CONVERSION_COMPRESSED, NULL);
> >>>
> >>> in openssl3 version it uses
> >>>
> >>> EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, buf,
> >>> sizeof(buf), );
> >>>
> >>> but key is created in dcrypt_evp_pkey_from_point(...)
> >>> with OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, "uncompressed"
> >>>
> >>> this was working in openssl pre 3.0.8 as compression format was ignored
> >>> when dumping data and used always compressed format.
> >>>
> >>>   From https://www.openssl.org/docs/man3.0/man7/EVP_KEYMGMT-EC.html
> >>>
> >>> """ Before OpenSSL 3.0.8, the implementation of providers included with
> >>> OpenSSL always opted for an encoding in compressed format,
> >>> unconditionally. Since OpenSSL 3.0.8, the implementation has been
> >>> changed to honor the OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT
> >>> parameter, if set, or to default to uncompressed format."""
> >>>
> >>> I don't see simple way how to force compressed format just for dumping
> >>> data without effecting the key itself. Method that can be used with
> >>> compression format argument is EC_POINT_point2hex but it requires quite
> >>> lengthy extraction of EC_POINT first. I've tried this for testing with:
> >>>
> >>> static const char *ec_key_get_pub_point_hex(const EVP_PKEY *pkey)
> >>> {
> >>>   if (!EVP_PKEY_is_a(pkey, "EC"))
> >>>   return NULL;
> >>>   size_t len;
> >>>
> >>>   EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL,
> >>> 0, );
> >>>   buffer_t *parambuf = t_buffer_create(len+1);
> >>>   EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, (char
> >>> *)parambuf->data, len+1, );
> >>>   int nid = OBJ_txt2nid(parambuf->data);
> >>>
> >>>   EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0,
> >>> );
> >>>   parambuf = t_buffer_create(len+1);
> >>>   EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
> >>> (unsigned char *)parambuf->data, len+1, );
> >>>
> >>>   EC_GROUP *ec_grp = EC_GROUP_new_by_curve_name(nid);
> >>>   if (ec_grp == NULL)
> >>>   return NULL;
> >>>   EC_POINT *point = EC_POINT_new(ec_grp);
> >>>   if (point == NULL) {
> >>>   EC_GROUP_free(ec_grp);
> >>>   return NULL;
> >>>   }
> >>>
> >>>   if (!EC_POINT_oct2point(ec_grp, point, parambuf->data, len, NULL))
> >>>  

Re: dovecot 2.4 issue with openssl >= 3.0.8

2023-08-21 Thread Michal Hlavinka

Hi,

this patch does not fix the issue. It fixes that first test that failed, 
but it fails a little bit further:

"""
test_read_increment .. : ok
test-stream.c:241: Assert failed: is_2->stream_errno == 0
test_write_read_v1 ... : 
FAILED

test-stream.c:294: Assert failed: is_2->stream_errno == 0
test_write_read_v1_short . : 
FAILED

"""

previously compression format was forced only for hex dump, this patch 
affects how some keys are created, but does not affect those that are 
loaded directly for example through PEM_read_bio_PUBKEY in:

dcrypt-openssl3.c:
dcrypt_openssl_load_public_key:2460:PEM_read_bio_PUBKEY

Cheers,
Michal Hlavinka

On 21/08/2023 09:08, Aki Tuomi wrote:

I think this should fix it https://cmouse.fi/ec-point.patch, can you please 
give it a try?

Aki


On 21/08/2023 09:34 EEST Aki Tuomi  wrote:

  

On 16/08/2023 01:09 EEST Michal Hlavinka  wrote:

  
Hi,


I've started testing main git branch and found an issue with openssl 3.

Test suite fails:
test_load_v1_key ... : ok
test-crypto.c:445: Assert failed: ret == TRUE
test-crypto.c:446: Assert failed: error == NULL
Panic: file dcrypt-openssl3.c: line 2917
(dcrypt_openssl_public_key_type): assertion failed: (key != NULL &&
key->key != NULL)
Error: Raw backtrace: test-crypto(+0x5af01) [0x55951b667f01] ->
test-crypto(backtrace_get+0x2f) [0x55951b66877f] ->
test-crypto(+0x31291) [0x55951b63e291] -> test-crypto(+0x312d5)
[0x55951b63e2d5] -> test-crypto(+0x16025) [0x55951b623025] ->
libdcrypt_openssl.so(+0x70ff) [0x7f5a995b60ff] -> test-crypto(+0x2a17b)
[0x55951b63717b] -> test-crypto(+0x3055d) [0x55951b63d55d] ->
test-crypto(test_run+0x6c) [0x55951b63d61c] -> test-crypto(main+0x4e)
[0x55951b62b66e] -> libc.so.6(+0x27b4a) [0x7f5a995eeb4a] ->
libc.so.6(__libc_start_main+0x8b) [0x7f5a995eec0b] ->
test-crypto(_start+0x25) [0x55951b62b7e5]

The issue is caused by change in openssl >= 3.0.8

in lib-dcryt/dcrypt-openssl3.c method ec_key_get_pub_point_hex(...)

in old version (for openssl 1.x) it uses compressed format:

EC_POINT_point2hex(g, p, POINT_CONVERSION_COMPRESSED, NULL);

in openssl3 version it uses

EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, buf,
sizeof(buf), );

but key is created in dcrypt_evp_pkey_from_point(...)
with OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, "uncompressed"

this was working in openssl pre 3.0.8 as compression format was ignored
when dumping data and used always compressed format.

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

""" Before OpenSSL 3.0.8, the implementation of providers included with
OpenSSL always opted for an encoding in compressed format,
unconditionally. Since OpenSSL 3.0.8, the implementation has been
changed to honor the OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT
parameter, if set, or to default to uncompressed format."""

I don't see simple way how to force compressed format just for dumping
data without effecting the key itself. Method that can be used with
compression format argument is EC_POINT_point2hex but it requires quite
lengthy extraction of EC_POINT first. I've tried this for testing with:

static const char *ec_key_get_pub_point_hex(const EVP_PKEY *pkey)
{
if (!EVP_PKEY_is_a(pkey, "EC"))
return NULL;
size_t len;

EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL,
0, );
buffer_t *parambuf = t_buffer_create(len+1);
EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, (char
*)parambuf->data, len+1, );
int nid = OBJ_txt2nid(parambuf->data);

EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0,
);
parambuf = t_buffer_create(len+1);
EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
(unsigned char *)parambuf->data, len+1, );

EC_GROUP *ec_grp = EC_GROUP_new_by_curve_name(nid);
if (ec_grp == NULL)
return NULL;
EC_POINT *point = EC_POINT_new(ec_grp);
if (point == NULL) {
EC_GROUP_free(ec_grp);
return NULL;
}

if (!EC_POINT_oct2point(ec_grp, point, parambuf->data, len, NULL))
return NULL;
char *ret = EC_POINT_point2hex(ec_grp, point,
POINT_CONVERSION_COMPRESSED, NULL);
EC_GROUP_free(ec_grp);
EC_POINT_free(point);
return ret;
}

and it fixed the issue, but there may be an easier way how to achieve that.

Cheers
Michal Hlavinka




Thank you for reporting this, we'll take a look at it!

Aki




___
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org


Re: dovecot 2.4 issue with openssl >= 3.0.8

2023-08-21 Thread Aki Tuomi via dovecot
I think this should fix it https://cmouse.fi/ec-point.patch, can you please 
give it a try?

Aki

> On 21/08/2023 09:34 EEST Aki Tuomi  wrote:
> 
>  
> > On 16/08/2023 01:09 EEST Michal Hlavinka  wrote:
> > 
> >  
> > Hi,
> > 
> > I've started testing main git branch and found an issue with openssl 3.
> > 
> > Test suite fails:
> > test_load_v1_key ... : ok
> > test-crypto.c:445: Assert failed: ret == TRUE
> > test-crypto.c:446: Assert failed: error == NULL
> > Panic: file dcrypt-openssl3.c: line 2917 
> > (dcrypt_openssl_public_key_type): assertion failed: (key != NULL && 
> > key->key != NULL)
> > Error: Raw backtrace: test-crypto(+0x5af01) [0x55951b667f01] -> 
> > test-crypto(backtrace_get+0x2f) [0x55951b66877f] -> 
> > test-crypto(+0x31291) [0x55951b63e291] -> test-crypto(+0x312d5) 
> > [0x55951b63e2d5] -> test-crypto(+0x16025) [0x55951b623025] -> 
> > libdcrypt_openssl.so(+0x70ff) [0x7f5a995b60ff] -> test-crypto(+0x2a17b) 
> > [0x55951b63717b] -> test-crypto(+0x3055d) [0x55951b63d55d] -> 
> > test-crypto(test_run+0x6c) [0x55951b63d61c] -> test-crypto(main+0x4e) 
> > [0x55951b62b66e] -> libc.so.6(+0x27b4a) [0x7f5a995eeb4a] -> 
> > libc.so.6(__libc_start_main+0x8b) [0x7f5a995eec0b] -> 
> > test-crypto(_start+0x25) [0x55951b62b7e5]
> > 
> > The issue is caused by change in openssl >= 3.0.8
> > 
> > in lib-dcryt/dcrypt-openssl3.c method ec_key_get_pub_point_hex(...)
> > 
> > in old version (for openssl 1.x) it uses compressed format:
> > 
> > EC_POINT_point2hex(g, p, POINT_CONVERSION_COMPRESSED, NULL);
> > 
> > in openssl3 version it uses
> > 
> > EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, buf, 
> > sizeof(buf), );
> > 
> > but key is created in dcrypt_evp_pkey_from_point(...)
> > with OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, "uncompressed"
> > 
> > this was working in openssl pre 3.0.8 as compression format was ignored 
> > when dumping data and used always compressed format.
> > 
> >  From https://www.openssl.org/docs/man3.0/man7/EVP_KEYMGMT-EC.html
> > 
> > """ Before OpenSSL 3.0.8, the implementation of providers included with 
> > OpenSSL always opted for an encoding in compressed format, 
> > unconditionally. Since OpenSSL 3.0.8, the implementation has been 
> > changed to honor the OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT 
> > parameter, if set, or to default to uncompressed format."""
> > 
> > I don't see simple way how to force compressed format just for dumping 
> > data without effecting the key itself. Method that can be used with 
> > compression format argument is EC_POINT_point2hex but it requires quite 
> > lengthy extraction of EC_POINT first. I've tried this for testing with:
> > 
> > static const char *ec_key_get_pub_point_hex(const EVP_PKEY *pkey)
> > {
> > if (!EVP_PKEY_is_a(pkey, "EC"))
> > return NULL;
> > size_t len;
> > 
> > EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 
> > 0, );
> > buffer_t *parambuf = t_buffer_create(len+1);
> > EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, (char 
> > *)parambuf->data, len+1, );
> > int nid = OBJ_txt2nid(parambuf->data);
> > 
> > EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, 
> > );
> > parambuf = t_buffer_create(len+1);
> > EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, 
> > (unsigned char *)parambuf->data, len+1, );
> > 
> > EC_GROUP *ec_grp = EC_GROUP_new_by_curve_name(nid);
> > if (ec_grp == NULL)
> > return NULL;
> > EC_POINT *point = EC_POINT_new(ec_grp);
> > if (point == NULL) {
> > EC_GROUP_free(ec_grp);
> > return NULL;
> > }
> > 
> > if (!EC_POINT_oct2point(ec_grp, point, parambuf->data, len, NULL))
> > return NULL;
> > char *ret = EC_POINT_point2hex(ec_grp, point, 
> > POINT_CONVERSION_COMPRESSED, NULL);
> > EC_GROUP_free(ec_grp);
> > EC_POINT_free(point);
> > return ret;
> > }
> > 
> > and it fixed the issue, but there may be an easier way how to achieve that.
> > 
> > Cheers
> > Michal Hlavinka
> > 
> > 
> 
> Thank you for reporting this, we'll take a look at it!
> 
> Aki
___
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org


Re: dovecot 2.4 issue with openssl >= 3.0.8

2023-08-21 Thread Aki Tuomi via dovecot
> On 16/08/2023 01:09 EEST Michal Hlavinka  wrote:
> 
>  
> Hi,
> 
> I've started testing main git branch and found an issue with openssl 3.
> 
> Test suite fails:
> test_load_v1_key ... : ok
> test-crypto.c:445: Assert failed: ret == TRUE
> test-crypto.c:446: Assert failed: error == NULL
> Panic: file dcrypt-openssl3.c: line 2917 
> (dcrypt_openssl_public_key_type): assertion failed: (key != NULL && 
> key->key != NULL)
> Error: Raw backtrace: test-crypto(+0x5af01) [0x55951b667f01] -> 
> test-crypto(backtrace_get+0x2f) [0x55951b66877f] -> 
> test-crypto(+0x31291) [0x55951b63e291] -> test-crypto(+0x312d5) 
> [0x55951b63e2d5] -> test-crypto(+0x16025) [0x55951b623025] -> 
> libdcrypt_openssl.so(+0x70ff) [0x7f5a995b60ff] -> test-crypto(+0x2a17b) 
> [0x55951b63717b] -> test-crypto(+0x3055d) [0x55951b63d55d] -> 
> test-crypto(test_run+0x6c) [0x55951b63d61c] -> test-crypto(main+0x4e) 
> [0x55951b62b66e] -> libc.so.6(+0x27b4a) [0x7f5a995eeb4a] -> 
> libc.so.6(__libc_start_main+0x8b) [0x7f5a995eec0b] -> 
> test-crypto(_start+0x25) [0x55951b62b7e5]
> 
> The issue is caused by change in openssl >= 3.0.8
> 
> in lib-dcryt/dcrypt-openssl3.c method ec_key_get_pub_point_hex(...)
> 
> in old version (for openssl 1.x) it uses compressed format:
> 
> EC_POINT_point2hex(g, p, POINT_CONVERSION_COMPRESSED, NULL);
> 
> in openssl3 version it uses
> 
> EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, buf, 
> sizeof(buf), );
> 
> but key is created in dcrypt_evp_pkey_from_point(...)
> with OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, "uncompressed"
> 
> this was working in openssl pre 3.0.8 as compression format was ignored 
> when dumping data and used always compressed format.
> 
>  From https://www.openssl.org/docs/man3.0/man7/EVP_KEYMGMT-EC.html
> 
> """ Before OpenSSL 3.0.8, the implementation of providers included with 
> OpenSSL always opted for an encoding in compressed format, 
> unconditionally. Since OpenSSL 3.0.8, the implementation has been 
> changed to honor the OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT 
> parameter, if set, or to default to uncompressed format."""
> 
> I don't see simple way how to force compressed format just for dumping 
> data without effecting the key itself. Method that can be used with 
> compression format argument is EC_POINT_point2hex but it requires quite 
> lengthy extraction of EC_POINT first. I've tried this for testing with:
> 
> static const char *ec_key_get_pub_point_hex(const EVP_PKEY *pkey)
> {
>   if (!EVP_PKEY_is_a(pkey, "EC"))
>   return NULL;
>   size_t len;
> 
>   EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 
> 0, );
>   buffer_t *parambuf = t_buffer_create(len+1);
>   EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, (char 
> *)parambuf->data, len+1, );
>   int nid = OBJ_txt2nid(parambuf->data);
> 
>   EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, 
> );
>   parambuf = t_buffer_create(len+1);
>   EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, 
> (unsigned char *)parambuf->data, len+1, );
> 
>   EC_GROUP *ec_grp = EC_GROUP_new_by_curve_name(nid);
>   if (ec_grp == NULL)
>   return NULL;
>   EC_POINT *point = EC_POINT_new(ec_grp);
>   if (point == NULL) {
>   EC_GROUP_free(ec_grp);
>   return NULL;
>   }
> 
>   if (!EC_POINT_oct2point(ec_grp, point, parambuf->data, len, NULL))
>   return NULL;
>   char *ret = EC_POINT_point2hex(ec_grp, point, 
> POINT_CONVERSION_COMPRESSED, NULL);
>   EC_GROUP_free(ec_grp);
>   EC_POINT_free(point);
>   return ret;
> }
> 
> and it fixed the issue, but there may be an easier way how to achieve that.
> 
> Cheers
> Michal Hlavinka
> 
> 

Thank you for reporting this, we'll take a look at it!

Aki
___
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org


Re: dovecot 2.4 issue with openssl >= 3.0.8

2023-08-17 Thread Teemu Huovila via dovecot


On 16.8.2023 1.09, Michal Hlavinka wrote:

Hi,

I've started testing main git branch and found an issue with openssl 3.

Test suite fails:
test_load_v1_key ... : ok
test-crypto.c:445: Assert failed: ret == TRUE
test-crypto.c:446: Assert failed: error == NULL
Panic: file dcrypt-openssl3.c: line 2917 (dcrypt_openssl_public_key_type): 
assertion failed: (key != NULL && key->key != NULL)
Error: Raw backtrace: test-crypto(+0x5af01) [0x55951b667f01] -> 
test-crypto(backtrace_get+0x2f) [0x55951b66877f] -> test-crypto(+0x31291) 
[0x55951b63e291] -> test-crypto(+0x312d5) [0x55951b63e2d5] -> test-crypto(+0x16025) 
[0x55951b623025] -> libdcrypt_openssl.so(+0x70ff) [0x7f5a995b60ff] -> 
test-crypto(+0x2a17b) [0x55951b63717b] -> test-crypto(+0x3055d) [0x55951b63d55d] -> 
test-crypto(test_run+0x6c) [0x55951b63d61c] -> test-crypto(main+0x4e) 
[0x55951b62b66e] -> libc.so.6(+0x27b4a) [0x7f5a995eeb4a] -> 
libc.so.6(__libc_start_main+0x8b) [0x7f5a995eec0b] -> test-crypto(_start+0x25) 
[0x55951b62b7e5]


The issue is caused by change in openssl >= 3.0.8

in lib-dcryt/dcrypt-openssl3.c method ec_key_get_pub_point_hex(...)

in old version (for openssl 1.x) it uses compressed format:

EC_POINT_point2hex(g, p, POINT_CONVERSION_COMPRESSED, NULL);

in openssl3 version it uses

EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, buf, sizeof(buf), 
);


but key is created in dcrypt_evp_pkey_from_point(...)
with OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, "uncompressed"

this was working in openssl pre 3.0.8 as compression format was ignored when 
dumping data and used always compressed format.


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

""" Before OpenSSL 3.0.8, the implementation of providers included with OpenSSL 
always opted for an encoding in compressed format, unconditionally. Since OpenSSL 
3.0.8, the implementation has been changed to honor the 
OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT parameter, if set, or to default to 
uncompressed format."""


I don't see simple way how to force compressed format just for dumping data without 
effecting the key itself. Method that can be used with compression format argument 
is EC_POINT_point2hex but it requires quite lengthy extraction of EC_POINT first. 
I've tried this for testing with:


static const char *ec_key_get_pub_point_hex(const EVP_PKEY *pkey)
{
if (!EVP_PKEY_is_a(pkey, "EC"))
    return NULL;
size_t len;

EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0, 
);
buffer_t *parambuf = t_buffer_create(len+1);
EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, (char 
*)parambuf->data, len+1, );

int nid = OBJ_txt2nid(parambuf->data);

EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, 
);
parambuf = t_buffer_create(len+1);
EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, (unsigned char 
*)parambuf->data, len+1, );


EC_GROUP *ec_grp = EC_GROUP_new_by_curve_name(nid);
if (ec_grp == NULL)
    return NULL;
EC_POINT *point = EC_POINT_new(ec_grp);
if (point == NULL) {
    EC_GROUP_free(ec_grp);
    return NULL;
}

if (!EC_POINT_oct2point(ec_grp, point, parambuf->data, len, NULL))
    return NULL;
char *ret = EC_POINT_point2hex(ec_grp, point, POINT_CONVERSION_COMPRESSED, 
NULL);
EC_GROUP_free(ec_grp);
EC_POINT_free(point);
return ret;
}

and it fixed the issue, but there may be an easier way how to achieve that.

Thank you for the report! I have created a ticket and we are tracking this internally 
as issue DOV-6155.


br,
Teemu



Cheers
Michal Hlavinka


___
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org

___
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org