This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push:
new 80293fe2d5 Avoid deprecated OpenSSL APIs
80293fe2d5 is described below
commit 80293fe2d556d82a2c332e1ce5291220bfdae5c0
Author: remm <[email protected]>
AuthorDate: Fri Sep 1 12:43:53 2023 +0200
Avoid deprecated OpenSSL APIs
Not sure if this is fully identical to the previous code. A few oddities
to investigate (EC with keystore ? DH auto use ?).
Based on the mod_ssl rev 1908537.
https://svn.apache.org/viewvc?view=revision&revision=1908537
Use @Deprecated in the generated classes to spot calls. Will be removed
when regenerating, unfortunately.
Since there is no rush, leave in the OpenSSL < 3.0 code for now.
Verified with org.apache.tomcat.util.net.TestSSLHostConfigCompat
---
.../ciphers/OpenSSLCipherConfigurationParser.java | 11 ++-
.../util/net/openssl/panama/OpenSSLContext.java | 101 ++++++++++++++++-----
.../util/net/openssl/panama/OpenSSLLibrary.java | 22 ++---
.../org/apache/tomcat/util/openssl/openssl_h.java | 14 +++
.../net/openssl/panama/LocalStrings.properties | 2 +
5 files changed, 113 insertions(+), 37 deletions(-)
diff --git
a/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
b/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
index 13be8d5eae..90d0eaca7e 100644
---
a/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
+++
b/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
@@ -712,7 +712,16 @@ public class OpenSSLCipherConfigurationParser {
init();
}
String[] elements = expression.split(SEPARATOR);
- // TODO: Handle PROFILE= using OpenSSL (if present, otherwise warn),
then replace elements with that
+ // Handle PROFILE= using OpenSSL (if present, otherwise warn), then
replace elements with that
+ if (elements.length == 1 && elements[0].startsWith("PROFILE=")) {
+ // Only use with Panama and if OpenSSL has been successfully
loaded before
+ /* FIXME: Merge OpenSSL code first
+ if (JreCompat.isJre22Available() &&
OpenSSLStatus.isLibraryInitialized()) {
+ List<String> cipherList =
OpenSSLLibrary.findCiphers(elements[0]);
+ // Replace the original list with the profile contents
+ elements = cipherList.toArray(new String[0]);
+ }*/
+ }
LinkedHashSet<Cipher> ciphers = new LinkedHashSet<>();
Set<Cipher> removedCiphers = new HashSet<>();
for (String element : elements) {
diff --git
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
index c482025a79..343efb13a1 100644
---
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
+++
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -22,6 +22,7 @@ import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -1113,32 +1114,65 @@ public class OpenSSLContext implements
org.apache.tomcat.util.net.SSLContext {
// Try to read DH parameters from the (first) SSLCertificateFile
if (index == SSL_AIDX_RSA) {
bio = BIO_new_file(certificateFileNative,
localArena.allocateFrom("r"));
- var dh = PEM_read_bio_DHparams(bio, MemorySegment.NULL,
MemorySegment.NULL, MemorySegment.NULL);
- BIO_free(bio);
- // # define SSL_CTX_set_tmp_dh(sslCtx,dh) \
- // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_DH,0,(char
*)(dh))
- if (!MemorySegment.NULL.equals(dh)) {
- SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_DH(), 0, dh);
- DH_free(dh);
+ if (OpenSSL_version_num() < 0x3000000fL) {
+ var dh = PEM_read_bio_DHparams(bio, MemorySegment.NULL,
MemorySegment.NULL, MemorySegment.NULL);
+ BIO_free(bio);
+ // # define SSL_CTX_set_tmp_dh(sslCtx,dh) \
+ //
SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh))
+ if (!MemorySegment.NULL.equals(dh)) {
+ SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_DH(), 0,
dh);
+ DH_free(dh);
+ }
+ } else {
+ var pkey = PEM_read_bio_Parameters(bio,
MemorySegment.NULL);
+ if (!MemorySegment.NULL.equals(pkey)) {
+ int numBits = EVP_PKEY_get_bits(pkey);
+ if (SSL_CTX_set0_tmp_dh_pkey(state.sslCtx, pkey) <= 0)
{
+ EVP_PKEY_free(pkey);
+ } else {
+
log.debug(sm.getString("openssl.setCustomDHParameters", numBits,
certificate.getCertificateFile()));
+ }
+ } else {
+ SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_DH_AUTO(), 1,
MemorySegment.NULL);
+ }
}
}
// Similarly, try to read the ECDH curve name from
SSLCertificateFile...
bio = BIO_new_file(certificateFileNative,
localArena.allocateFrom("r"));
- var ecparams = PEM_read_bio_ECPKParameters(bio,
MemorySegment.NULL, MemorySegment.NULL, MemorySegment.NULL);
- BIO_free(bio);
- if (!MemorySegment.NULL.equals(ecparams)) {
- int nid = EC_GROUP_get_curve_name(ecparams);
- var eckey = EC_KEY_new_by_curve_name(nid);
- // # define SSL_CTX_set_tmp_ecdh(sslCtx,ecdh) \
- // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_ECDH,0,(char
*)(ecdh))
- SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_ECDH(), 0, eckey);
- EC_KEY_free(eckey);
- EC_GROUP_free(ecparams);
+ if (OpenSSL_version_num() < 0x3000000fL) {
+ var ecparams = PEM_read_bio_ECPKParameters(bio,
MemorySegment.NULL, MemorySegment.NULL, MemorySegment.NULL);
+ BIO_free(bio);
+ if (!MemorySegment.NULL.equals(ecparams)) {
+ int nid = EC_GROUP_get_curve_name(ecparams);
+ var eckey = EC_KEY_new_by_curve_name(nid);
+ // # define SSL_CTX_set_tmp_ecdh(sslCtx,ecdh) \
+ //
SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh))
+ SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_ECDH(), 0,
eckey);
+ EC_KEY_free(eckey);
+ EC_GROUP_free(ecparams);
+ }
+ // Set callback for DH parameters
+ var openSSLCallbackTmpDH =
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
+ openSSLCallbackTmpDHFunctionDescriptor, contextArena);
+ SSL_CTX_set_tmp_dh_callback(state.sslCtx,
openSSLCallbackTmpDH);
+ } else {
+ var d2i_ECPKParameters =
SymbolLookup.loaderLookup().find("d2i_ECPKParameters").get();
+ var ecparams = PEM_ASN1_read_bio(d2i_ECPKParameters,
+ PEM_STRING_ECPARAMETERS(), bio, MemorySegment.NULL,
MemorySegment.NULL, MemorySegment.NULL);
+ BIO_free(bio);
+ if (!MemorySegment.NULL.equals(ecparams)) {
+ int curveNid = EC_GROUP_get_curve_name(ecparams);
+ var curveNidAddress =
localArena.allocateFrom(ValueLayout.JAVA_INT, curveNid);
+ // SSL_CTX_set1_curves(state.sslCtx, &curveNid, 1)
+ if (SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_GROUPS(), 1,
curveNidAddress) <= 0) {
+ curveNid = 0;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("openssl.setECDHCurve",
curveNid, certificate.getCertificateFile()));
+ }
+ EC_GROUP_free(ecparams);
+ }
}
- // Set callback for DH parameters
- var openSSLCallbackTmpDH =
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
- openSSLCallbackTmpDHFunctionDescriptor, contextArena);
- SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
// Set certificate chain file
if (certificate.getCertificateChainFile() != null) {
var certificateChainFileNative =
@@ -1223,10 +1257,27 @@ public class OpenSSLContext implements
org.apache.tomcat.util.net.SSLContext {
logLastError(localArena, "openssl.errorPrivateKeyCheck");
return;
}
- // Set callback for DH parameters
- var openSSLCallbackTmpDH =
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
- openSSLCallbackTmpDHFunctionDescriptor, contextArena);
- SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
+ if (OpenSSL_version_num() < 0x3000000fL) {
+ // Set callback for DH parameters
+ var openSSLCallbackTmpDH =
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
+ openSSLCallbackTmpDHFunctionDescriptor, contextArena);
+ SSL_CTX_set_tmp_dh_callback(state.sslCtx,
openSSLCallbackTmpDH);
+ } else {
+ bio = BIO_new(BIO_s_mem());
+ BIO_write(bio, rawKey, (int) rawKey.byteSize());
+ var pkey = PEM_read_bio_Parameters(bio, MemorySegment.NULL);
+ if (!MemorySegment.NULL.equals(pkey)) {
+ int numBits = EVP_PKEY_get_bits(pkey);
+ if (SSL_CTX_set0_tmp_dh_pkey(state.sslCtx, pkey) <= 0) {
+ EVP_PKEY_free(pkey);
+ } else {
+
log.debug(sm.getString("openssl.setCustomDHParameters", numBits,
certificate.getCertificateFile()));
+ }
+ } else {
+ SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_DH_AUTO(), 1,
MemorySegment.NULL);
+ }
+ BIO_free(bio);
+ }
for (int i = 1; i < chain.length; i++) {
//SSLContext.addChainCertificateRaw(state.ctx,
chain[i].getEncoded());
var rawCertificateChain =
localArena.allocateFrom(ValueLayout.JAVA_BYTE, chain[i].getEncoded());
diff --git
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
index 43da3c13c9..ba3a1007ff 100644
---
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
+++
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
@@ -39,8 +39,6 @@ import org.apache.tomcat.util.res.StringManager;
* configuration parameters.
* Using this from a listener is completely optional, but is needed for
* configuration and full cleanup of a few native memory allocations.
- * FIXME: OpenSSL 3 deprecation resolutions for the equivalent code:
- * https://svn.apache.org/viewvc?view=revision&revision=1908537
*/
public class OpenSSLLibrary {
@@ -178,9 +176,12 @@ public class OpenSSLLibrary {
// Main library init
initLibrary();
+ // OpenSSL 3 onwards uses providers
+ boolean usingProviders = (OpenSSL_version_num() >=
0x3000000fL);
+
// Setup engine
String engineName = "on".equalsIgnoreCase(SSLEngine) ? null :
SSLEngine;
- if (engineName != null) {
+ if (!usingProviders && engineName != null) {
if ("auto".equals(engineName)) {
ENGINE_register_all_complete();
} else {
@@ -224,10 +225,9 @@ public class OpenSSLLibrary {
RAND_seed(memorySession.allocateFrom(ValueLayout.JAVA_BYTE, randomBytes), 128);
}
- initDHParameters();
-
- // OpenSSL 3 onwards uses providers
- boolean usingProviders = (OpenSSL_version_num() >=
0x3000000fL);
+ if (!usingProviders) {
+ initDHParameters();
+ }
if (usingProviders || !(null == FIPSMode ||
"off".equalsIgnoreCase(FIPSMode))) {
fipsModeActive = false;
@@ -335,11 +335,11 @@ public class OpenSSLLibrary {
OpenSSLStatus.setAvailable(false);
try {
- freeDHParameters();
- if (!MemorySegment.NULL.equals(enginePointer)) {
- ENGINE_free(enginePointer);
- }
if (OpenSSL_version_num() < 0x3000000fL) {
+ freeDHParameters();
+ if (!MemorySegment.NULL.equals(enginePointer)) {
+ ENGINE_free(enginePointer);
+ }
FIPS_mode_set(0);
}
} finally {
diff --git
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
index 978e7551c4..fc5ad10d81 100644
---
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
+++
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -1226,6 +1226,7 @@ public class openssl_h {
* EC_KEY* EC_KEY_new_by_curve_name(int nid);
* }
*/
+ @Deprecated
public static MemorySegment EC_KEY_new_by_curve_name(int nid) {
var mh$ = EC_KEY_new_by_curve_name$MH();
try {
@@ -1242,6 +1243,7 @@ public class openssl_h {
* void EC_KEY_free(EC_KEY* key);
* }
*/
+ @Deprecated
public static void EC_KEY_free(MemorySegment key) {
var mh$ = EC_KEY_free$MH();
try {
@@ -1258,6 +1260,7 @@ public class openssl_h {
* DH* DH_new();
* }
*/
+ @Deprecated
public static MemorySegment DH_new() {
var mh$ = DH_new$MH();
try {
@@ -1274,6 +1277,7 @@ public class openssl_h {
* void DH_free(DH* dh);
* }
*/
+ @Deprecated
public static void DH_free(MemorySegment dh) {
var mh$ = DH_free$MH();
try {
@@ -1290,6 +1294,7 @@ public class openssl_h {
* int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g);
* }
*/
+ @Deprecated
public static int DH_set0_pqg(MemorySegment dh, MemorySegment p,
MemorySegment q, MemorySegment g) {
var mh$ = DH_set0_pqg$MH();
try {
@@ -1642,6 +1647,7 @@ public class openssl_h {
* EC_GROUP* PEM_read_bio_ECPKParameters(BIO* out, EC_GROUP** x,
pem_password_cb* cb, void* u);
* }
*/
+ @Deprecated
public static MemorySegment PEM_read_bio_ECPKParameters(MemorySegment out,
MemorySegment x, MemorySegment cb, MemorySegment u) {
var mh$ = PEM_read_bio_ECPKParameters$MH();
try {
@@ -1658,6 +1664,7 @@ public class openssl_h {
* DH* PEM_read_bio_DHparams(BIO* out, DH** x, pem_password_cb* cb, void*
u);
* }
*/
+ @Deprecated
public static MemorySegment PEM_read_bio_DHparams(MemorySegment out,
MemorySegment x, MemorySegment cb, MemorySegment u) {
var mh$ = PEM_read_bio_DHparams$MH();
try {
@@ -2746,6 +2753,7 @@ public class openssl_h {
* void SSL_CTX_set_tmp_dh_callback(SSL_CTX* ctx, DH* (*dh)(SSL*,int,int));
* }
*/
+ @Deprecated
public static void SSL_CTX_set_tmp_dh_callback(MemorySegment ctx,
MemorySegment dh) {
var mh$ = SSL_CTX_set_tmp_dh_callback$MH();
try {
@@ -3066,6 +3074,7 @@ public class openssl_h {
* ENGINE* ENGINE_by_id(char* id);
* }
*/
+ @Deprecated
public static MemorySegment ENGINE_by_id(MemorySegment id) {
var mh$ = ENGINE_by_id$MH();
try {
@@ -3082,6 +3091,7 @@ public class openssl_h {
* int ENGINE_register_all_complete();
* }
*/
+ @Deprecated
public static int ENGINE_register_all_complete() {
var mh$ = ENGINE_register_all_complete$MH();
try {
@@ -3098,6 +3108,7 @@ public class openssl_h {
* int ENGINE_ctrl_cmd_string(ENGINE* e, char* cmd_name, char* arg, int
cmd_optional);
* }
*/
+ @Deprecated
public static int ENGINE_ctrl_cmd_string(MemorySegment e, MemorySegment
cmd_name, MemorySegment arg, int cmd_optional) {
var mh$ = ENGINE_ctrl_cmd_string$MH();
try {
@@ -3114,6 +3125,7 @@ public class openssl_h {
* int ENGINE_free(ENGINE* e);
* }
*/
+ @Deprecated
public static int ENGINE_free(MemorySegment e) {
var mh$ = ENGINE_free$MH();
try {
@@ -3130,6 +3142,7 @@ public class openssl_h {
* EVP_PKEY* ENGINE_load_private_key(ENGINE* e, char* key_id, UI_METHOD*
ui_method, void* callback_data);
* }
*/
+ @Deprecated
public static MemorySegment ENGINE_load_private_key(MemorySegment e,
MemorySegment key_id, MemorySegment ui_method, MemorySegment callback_data) {
var mh$ = ENGINE_load_private_key$MH();
try {
@@ -3146,6 +3159,7 @@ public class openssl_h {
* int ENGINE_set_default(ENGINE* e, unsigned int flags);
* }
*/
+ @Deprecated
public static int ENGINE_set_default(MemorySegment e, int flags) {
var mh$ = ENGINE_set_default$MH();
try {
diff --git
a/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
b/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
index b8b108272b..f1bff0a31a 100644
---
a/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
+++
b/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
@@ -61,6 +61,8 @@ openssl.noCACerts=No CA certificates were configured
openssl.nonJsseCertificate=The certificate [{0}] or its private key [{1}]
could not be processed using a JSSE key manager and will be given directly to
OpenSSL
openssl.nonJsseChain=The certificate chain [{0}] was not specified or was not
valid and JSSE requires a valid certificate chain so attempting to use OpenSSL
directly
openssl.passwordTooLong=The certificate password is too long
+openssl.setCustomDHParameters=Setting custom DH parameters ([{0}] bits) for
the key [{1}]
+openssl.setECDHCurve=Setting ECDH curve ([{0}]) for the key [{1}]
openssl.trustManagerMissing=No trust manager found
opensslconf.applyCommand=OpenSSLConf applying command (name [{0}], value [{1}])
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]