RE: [External] Support for -fvisibility=hidden in openssl 3.0
Answering myself here. It appears this is pretty logical. Openssl 3.0 has a "legacy" provider which is normally compiled as a separate legacy.so module which is loaded on demand at run time. Now, when compiled with -fvisibility=hidden, this does not work because neither side can see each other's symbols. The solution appears to be simple: one needs to pass no-module option to the openssl config, which causes the legacy provider to be linked directly into libcrypto.a. Another solution would probably be to convince the aws-cpp-sdk library to not to try to load the legacy provider in the first place. I see this is done inside a conditional compilation block (#ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_RC4), so should be somehow configurable as well. Cheers Paavo From: openssl-users On Behalf Of Helde, Paavo Sent: neljapäev, 10. november 2022 16:45 To: openssl-users@openssl.org Subject: [External] Support for -fvisibility=hidden in openssl 3.0 We have a Linux application which can load a lot of different .so modules at runtime, which in turn might be contain various third-party libraries. In the past we have seen the problems that there might appear different binarily incompatible openssl versions in the process memory, which might get mixed up and cause crashes or worse. The worst offender was libpython which can install and load its own modules on fly, with totally uncontrollable openssl versions in them. We attempted to fight with this by compiling static openssl libraries with -fvisibility=hidden and linking our own .so-s against it. This ought to hide the symbols from Python at least. It looks like this actually worked with openssl-1.1. Alas, now we are switching over to openssl-3.0 (the fresh 3.0.7) and it looks like this approach does not work anymore. We are getting initialization errors, I think from OSSL_PROVIDER_load("legacy") or such. s2n_init() failed: 402653268 (Failed to load or unload an openssl provider) Fatal error condition occurred in /srv/paavo/DataAnalysis/Acapella/trunk/Production/Intermediates/ThirdParty/src/aws-sdk-cpp/crt/aws-crt-cpp/crt/aws-c-io/source/s2n/s2n_tls_channel_handler.c:197: 0 && "s2n_init() failed" Exiting Application No call stack information available Aborted (core dumped) Removing the -fvisibility=hidden flag from openssl compilation gets rid of this problem, but I'm afraid this may cause conflicts with python again. So my question is should this usage work, and if so, how to get it working? TIA Paavo
Re: Question about migrating from d2i_ECPrivateKey() to d2i_PrivateKey(EVP_PKEY_EC, ...)
On Fri, Nov 18, 2022 at 11:33:08PM -0600, Nico Williams wrote: > On Fri, Nov 18, 2022 at 04:53:44PM -0600, Nico Williams wrote: > > I can't use d2i_PrivateKey() because that requires an existing > > EVP_PKEY * that has the group already set. > > Although, that's just what's documented. From code inspection, if the > parameters are found in the encoded private key, then the group will be > set internally and no error will be returned. Often, if you want a clear example of OpenSSL API usage, one place to look is the Postfix "tls" library. In this case: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L245-L266 https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L363-L370 Postfix does not do much with low-level crypto, but it exercises a non-trivial chunk of the certificate and TLS API surface, ECDH/DH setup and digests. Generally, I would expect d2i_... to automatically detect the algorithm when tagged with a suitable OIDs, and so d2i_AutoPrivateKey() could often work, but if you know the expected key type, you can ask for that explicitly with d2i_PrivateKey(). You don't need to pass an existing key. Just pass NULL for (EVP_PKEY **) pointer, and let OpenSSL return a freshly allocated key: EVP_PKEY *key; key = d2i_PrivateKey(type, NULL, ...); key = d2i_AutoPrivateKey(NULL, ...); I strive to also check that the buffer pointer advanced by the expected length (no "left-over" data): https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L293-L306 -- Viktor.
Re: X52219/X448 export public key coordinates
Yeah, of course, sorry for the typo. I’ve already found a solution that seems to be working by using EVP_PKEY_get_raw_public_key() for these types of curves. I was confused why it’s not working with EC_KEY interfaces though it’s type of elliptic curve. Then I found somewhere that it’s implemented outside the context of EC. It’s not clear to me why but I believe there’s a good reason for it. Anyway, thanks for your answer! Regards Matt On 18. 11. 2022, at 17:13, Kyle Hamilton wrote: X25519? On Mon, Nov 14, 2022, 05:23 ORNEST Matej - Contractor via openssl-users mailto:openssl-users@openssl.org>> wrote: Hi all, I need to implement support for X52219/X448 for DH key exchange (and Ed52219/Ed448 for DSA) elliptic curves in our project. I need to export public key for DH exchange in form of DER encoded chunk in form tag+X-coordinate+Y-coordinate. Thus I need to get EC_POINT from EVP_PKEY and encode it as needed. I understand that those key types differs from EC types in way that I need just X coordinate and a flag bit to reconstruct the key, but still, how do I get the X coordinate? My solution works for all other EC types such as SecpX and Brainpool families, but not for X52219/X448 keys and I do not completely understand why. Specifically when I decode public key previously encoded with i2d_PUBKEY() to EVP_PEKY and try to get EC_KEY by calling EVP_PKEY_get0_EC_KEY(), it returns NULL and issues an error that it’s not an EC key… I’m using following code: EVP_PKEY *key = … // Decode from DER encoded public key if(key != nil) { EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(key); /// When X52219 or X448 key is passed, ecKey is NULL if(ecKey != NULL) { const EC_POINT *point = EC_KEY_get0_public_key(ecKey); const EC_GROUP *group = EC_KEY_get0_group(ecKey); if(point != NULL && group != NULL) { BIGNUM *bnX = BN_new(); BIGNUM *bnY = BN_new(); if(EC_POINT_get_affine_coordinates(group, point, bnX, bnY, NULL)) { char *hexX = BN_bn2hex(bnX); char *hexY = BN_bn2hex(bnY); // Convert to custom data structures … } BN_free(bnX); BN_free(bnY); } } } Is there any way how to export those key types in desired format? I’m using OpenSSL version 1.1.1q. Thank you very much for any hint Matt
Re: X52219/X448 export public key coordinates
X25519? On Mon, Nov 14, 2022, 05:23 ORNEST Matej - Contractor via openssl-users < openssl-users@openssl.org> wrote: > Hi all, > > > > I need to implement support for X52219/X448 for DH key exchange (and > Ed52219/Ed448 for DSA) elliptic curves in our project. I need to export > public key for DH exchange in form of DER encoded chunk in form > tag+X-coordinate+Y-coordinate. Thus I need to get EC_POINT from EVP_PKEY > and encode it as needed. I understand that those key types differs from EC > types in way that I need just X coordinate and a flag bit to reconstruct > the key, but still, how do I get the X coordinate? > > My solution works for all other EC types such as SecpX and Brainpool > families, but not for X52219/X448 keys and I do not completely understand > why. Specifically when I decode public key previously encoded with > i2d_PUBKEY() to EVP_PEKY and try to get EC_KEY by calling > EVP_PKEY_get0_EC_KEY(), it returns NULL and issues an error that it’s not > an EC key… > > > > I’m using following code: > > > > EVP_PKEY *key = … // Decode from DER encoded public key > > > > if(key != nil) { > > > > EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(key); > > /// When X52219 or X448 key is passed, ecKey is NULL > > if(ecKey != NULL) { > > const EC_POINT *point = EC_KEY_get0_public_key(ecKey); > > const EC_GROUP *group = EC_KEY_get0_group(ecKey); > > > > if(point != NULL && group != NULL) { > > BIGNUM *bnX = BN_new(); > > BIGNUM *bnY = BN_new(); > > > > if(EC_POINT_get_affine_coordinates(group, point, bnX, > bnY, NULL)) { > > char *hexX = BN_bn2hex(bnX); > > char *hexY = BN_bn2hex(bnY); > > > > // Convert to custom data structures > > … > > } > > > > BN_free(bnX); > > BN_free(bnY); > > } > > } > > } > > > > > > Is there any way how to export those key types in desired format? I’m > using OpenSSL version 1.1.1q. > > > > Thank you very much for any hint > > Matt >
OpenSSL 3.0.x iOS support
Can someone please suggest if we can build OpenSSL 3.0 for iOS platform? Don’t see iphoneos-cross under supported os/platform list. Regards, Madhu
Re: Regarding TLS call failure on Openssl3.0 with cipher : ECDH-ECDSA-AES256-SHA384
On 18/11/2022 05:53, Viktor Dukhovni wrote: On Fri, Nov 18, 2022 at 05:12:09AM +, Raman, Ina wrote: I was trying to test TLS call with cipher suite : tls_ecdh_ecdsa_with_aes_256_cbc_sha384 but it fails. You probably actually wanted "ecdhe" not "ecdh", but see below. Support for the ECDH version was removed from OpenSSL 1.1.0 and above: https://github.com/openssl/openssl/commit/ce0c1f2bb2fd296f10a2847844205df0ed95fb8e Matt It fails on SSL_set_cipher_list API. This API, and the cipher you had in mind apply only to TLS 1.2, with TLS 1.3 there is a separate API for setting the data encryption ciphers, which are configured separately from signature schemes, and key exchange "groups", but see below. The list contains the mentioned cipher but still it is failing to set that. Actually the list does not contain that cipher: - The available TLS 1.2 ciphers are ECDHE not ECDH. $ openssl ciphers -stdname -s -tls1_2 | awk '{print $1}' | grep ECDH TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CCM TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CCM TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - The standard names are "output only" when configuring ciphers you need to use the OpenSSL names. $ openssl ciphers -stdname -s -tls1_2 -v ECDHE-ECDSA-AES256-GCM-SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD $ openssl ciphers -stdname -s -tls1_2 -v TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Error in cipher list C0F16339DF7F:error:0AB9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl/ssl_lib.c:2746: - Cipher names are case-sensitive. $ openssl ciphers -stdname -s -tls1_2 -v $(echo ECDHE-ECDSA-AES256-GCM-SHA384 | tr A-Z a-z) Error in cipher list C0F1755DCB7F:error:0AB9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl/ssl_lib.c:2746: - TLS 1.3 uses none of the above: $ openssl ciphers -s -v -tls1_3 TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256)Mac=AEAD TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128)Mac=AEAD TLS_AES_128_CCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESCCM(128)Mac=AEAD I wanted to know if this cipher is supported with openssl 3.0 or not . Multiple mistakes: * Wrong API for TLS 1.3 * Desired cipher not applicable to TLS 1.3 anyway * Typo "ecdh" instead of "ecdhe" * Cipher name was lower case * Cipher name was the RFC name, not the OpenSSL name. Any one mistake it sufficient, but 5 is impressive. :-)