You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2023/06/07 13:58:01 UTC
[tomcat] branch main updated: Add Panama module for Java 21
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 873051516c Add Panama module for Java 21
873051516c is described below
commit 873051516c2ad91b1bbff1ff4f6a68e4a775fccb
Author: remm <re...@apache.org>
AuthorDate: Wed Jun 7 15:57:33 2023 +0200
Add Panama module for Java 21
Panama is still a preview API in Java 21 (up from incubating in Java
17), so the code needs to specifically target it and be compiled with
the specific Java version.
I plan to remove the Java 17 version once Java 21 is released.
openssl-foreign will continue to track the most recent API changes until
it is no longer preview (at which point it would be merged into the main
Tomcat code).
---
modules/openssl-java21/LICENSE | 201 ++
modules/openssl-java21/README.md | 90 +
modules/openssl-java21/addlicense.sh | 22 +
modules/openssl-java21/license.header | 17 +
modules/openssl-java21/openssl-tomcat.conf | 357 ++
modules/openssl-java21/openssl.h | 31 +
modules/openssl-java21/pom.xml | 98 +
.../util/net/openssl/panama/OpenSSLContext.java | 1406 ++++++++
.../util/net/openssl/panama/OpenSSLEngine.java | 1797 ++++++++++
.../net/openssl/panama/OpenSSLImplementation.java | 51 +
.../openssl/panama/OpenSSLLifecycleListener.java | 463 +++
.../net/openssl/panama/OpenSSLSessionContext.java | 163 +
.../net/openssl/panama/OpenSSLSessionStats.java | 128 +
.../util/net/openssl/panama/OpenSSLStatus.java | 60 +
.../util/net/openssl/panama/OpenSSLUtil.java | 128 +
.../net/openssl/panama/OpenSSLX509Certificate.java | 192 ++
.../apache/tomcat/util/openssl/Constants$root.java | 42 +
.../apache/tomcat/util/openssl/RuntimeHelper.java | 258 ++
.../SSL_CTX_set_cert_verify_callback$cb.java | 50 +
.../openssl/SSL_CTX_set_tmp_dh_callback$dh.java | 50 +
.../util/openssl/SSL_set_info_callback$cb.java | 50 +
.../apache/tomcat/util/openssl/constants$0.java | 76 +
.../apache/tomcat/util/openssl/constants$1.java | 78 +
.../apache/tomcat/util/openssl/constants$10.java | 85 +
.../apache/tomcat/util/openssl/constants$11.java | 82 +
.../apache/tomcat/util/openssl/constants$12.java | 76 +
.../apache/tomcat/util/openssl/constants$13.java | 78 +
.../apache/tomcat/util/openssl/constants$14.java | 80 +
.../apache/tomcat/util/openssl/constants$15.java | 80 +
.../apache/tomcat/util/openssl/constants$16.java | 82 +
.../apache/tomcat/util/openssl/constants$17.java | 82 +
.../apache/tomcat/util/openssl/constants$18.java | 73 +
.../apache/tomcat/util/openssl/constants$19.java | 77 +
.../apache/tomcat/util/openssl/constants$2.java | 76 +
.../apache/tomcat/util/openssl/constants$20.java | 77 +
.../apache/tomcat/util/openssl/constants$21.java | 84 +
.../apache/tomcat/util/openssl/constants$22.java | 76 +
.../apache/tomcat/util/openssl/constants$23.java | 76 +
.../apache/tomcat/util/openssl/constants$24.java | 81 +
.../apache/tomcat/util/openssl/constants$25.java | 79 +
.../apache/tomcat/util/openssl/constants$26.java | 82 +
.../apache/tomcat/util/openssl/constants$27.java | 82 +
.../apache/tomcat/util/openssl/constants$28.java | 76 +
.../apache/tomcat/util/openssl/constants$29.java | 34 +
.../apache/tomcat/util/openssl/constants$3.java | 75 +
.../apache/tomcat/util/openssl/constants$4.java | 77 +
.../apache/tomcat/util/openssl/constants$5.java | 75 +
.../apache/tomcat/util/openssl/constants$6.java | 77 +
.../apache/tomcat/util/openssl/constants$7.java | 77 +
.../apache/tomcat/util/openssl/constants$8.java | 77 +
.../apache/tomcat/util/openssl/constants$9.java | 84 +
.../tomcat/util/openssl/openssl_compat_h.java | 121 +
.../org/apache/tomcat/util/openssl/openssl_h.java | 3447 ++++++++++++++++++++
.../net/openssl/panama/LocalStrings.properties | 97 +
54 files changed, 11633 insertions(+)
diff --git a/modules/openssl-java21/LICENSE b/modules/openssl-java21/LICENSE
new file mode 100644
index 0000000000..261eeb9e9f
--- /dev/null
+++ b/modules/openssl-java21/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/modules/openssl-java21/README.md b/modules/openssl-java21/README.md
new file mode 100644
index 0000000000..f3e61f6282
--- /dev/null
+++ b/modules/openssl-java21/README.md
@@ -0,0 +1,90 @@
+# OpenSSL support for Apache Tomcat
+
+## This module is experimental
+
+It uses the JEP 442 API. More details on this API are available
+at `https://openjdk.java.net/jeps/442`.
+
+## Building
+
+The module can be built using Java 21. This will be the only Java version that
+is supported as the JEP 442 API is a preview API and will continue to evolve.
+It can be built and run with Apache Tomcat 9.0 or newer.
+
+## Running
+
+The module uses the OpenSSL 3.0 API. It requires an API compatible version of
+OpenSSL or a compatible alternative library, that can be loaded from the JVM
+library path. OpenSSL 1.1 is also supported.
+
+Copy `tomcat-coyote-openssl-java21-1.0.jar` to the Apache Tomcat `lib` folder.
+
+Remove `AprLifecycleListener` from `server.xml`. The
+`org.apache.tomcat.util.net.openssl.panama.OpenSSLLifecycleListener` can be
+used as a replacement with the same configuration options (such as FIPS)
+and shutdown cleanup, but is not required.
+
+Define a `Connector` using the value
+`org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation` for the
+`sslImplementationName` attribute.
+
+Example connector:
+```
+ <Connector port="8443" protocol="HTTP/1.1"
+ SSLEnabled="true" scheme="https" secure="true"
+ socket.directBuffer="true" socket.directSslBuffer="true"
+ sslImplementationName="org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation">
+ <SSLHostConfig certificateVerification="none">
+ <Certificate certificateKeyFile="${catalina.home}/conf/localhost-rsa-key.pem"
+ certificateFile="${catalina.home}/conf/localhost-rsa-cert.pem"
+ certificateChainFile="${catalina.home}/conf/localhost-rsa-chain.pem"
+ type="RSA" />
+ </SSLHostConfig>
+ <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
+ </Connector>
+```
+
+Run Tomcat using the additional Java options that allow access to the API and
+native code:
+```
+export JAVA_OPTS="--enable-preview --enable-native-access=ALL-UNNAMED"
+```
+
+## Generating the OpenSSL API code using jextract (optional)
+
+jextract is now available in its own standalone repository. Clone
+`https://github.com/openjdk/jextract` in some location and
+checkout the branch that supports Java 21. Please refer to the
+instructions from the repository for building. It should be the
+`panama` branch.
+
+This step is only useful to be able to use additional native APIs from OpenSSL
+or stdlib.
+
+Find include paths using `gcc -xc -E -v -`, on Fedora it is
+`/usr/lib/gcc/x86_64-redhat-linux/12/include`. Edit `openssl-tomcat.conf`
+accordingly to set the appropriate path.
+
+```
+export JEXTRACT_HOME=<pathto>/jextract/build/jextract
+$JEXTRACT_HOME/bin/jextract @openssl-tomcat.conf openssl.h
+```
+Note: The build path for the JDK will be different on other platforms.
+
+The code included was generated using OpenSSL 3.0. As long as things remain
+API compatible, the generated code will still work.
+
+The `openssl-tomcat.conf` will generate a trimmed down OpenSSL API. When
+developing new features, the full API can be generated instead using:
+```
+$JEXTRACT_HOME/bin/jextract --source -t org.apache.tomcat.util.openssl -lssl -I /usr/lib/gcc/x86_64-redhat-linux/12/include openssl.h --output src/main/java
+```
+
+The `openssl.conf` file lists all the API calls and constants that can be
+generated using jextract, as a reference to what is available. Some macros are
+not supported and have to be reproduced in code.
+
+Before committing updated generated files, they need to have the license header
+added. The `addlicense.sh` script can do that and process all Java source files
+in the `src/main/java/org/apache/tomcat/util/openssl` directory.
+
diff --git a/modules/openssl-java21/addlicense.sh b/modules/openssl-java21/addlicense.sh
new file mode 100755
index 0000000000..6349703675
--- /dev/null
+++ b/modules/openssl-java21/addlicense.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+for generated in src/main/java/org/apache/tomcat/util/openssl/*.java; do
+ cat license.header $generated >> $generated.$$
+ mv $generated.$$ $generated
+ echo Updated $generated
+done
diff --git a/modules/openssl-java21/license.header b/modules/openssl-java21/license.header
new file mode 100644
index 0000000000..4b326ae5c2
--- /dev/null
+++ b/modules/openssl-java21/license.header
@@ -0,0 +1,17 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
diff --git a/modules/openssl-java21/openssl-tomcat.conf b/modules/openssl-java21/openssl-tomcat.conf
new file mode 100644
index 0000000000..cd512210ee
--- /dev/null
+++ b/modules/openssl-java21/openssl-tomcat.conf
@@ -0,0 +1,357 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+--source
+-t org.apache.tomcat.util.openssl
+-lssl
+# Configure include path
+-I /usr/lib/gcc/x86_64-redhat-linux/12/include
+--output src/main/java
+
+#### Extracted from: /usr/include/openssl/asn1.h
+
+--include-function ASN1_STRING_get0_data # header: /usr/include/openssl/asn1.h
+--include-function ASN1_STRING_length # header: /usr/include/openssl/asn1.h
+
+#### Extracted from: /usr/include/openssl/bio.h
+
+--include-function BIO_ctrl # header: /usr/include/openssl/bio.h
+--include-function BIO_ctrl_pending # header: /usr/include/openssl/bio.h
+--include-function BIO_free # header: /usr/include/openssl/bio.h
+--include-function BIO_new # header: /usr/include/openssl/bio.h
+--include-function BIO_new_bio_pair # header: /usr/include/openssl/bio.h
+--include-function BIO_new_file # header: /usr/include/openssl/bio.h
+--include-function BIO_read # header: /usr/include/openssl/bio.h
+--include-function BIO_s_bio # header: /usr/include/openssl/bio.h
+--include-function BIO_s_file # header: /usr/include/openssl/bio.h
+--include-function BIO_s_mem # header: /usr/include/openssl/bio.h
+--include-function BIO_write # header: /usr/include/openssl/bio.h
+--include-constant BIO_CLOSE # header: /usr/include/openssl/bio.h
+--include-constant BIO_CTRL_RESET # header: /usr/include/openssl/bio.h
+--include-constant BIO_C_SET_FILENAME # header: /usr/include/openssl/bio.h
+--include-constant BIO_FP_READ # header: /usr/include/openssl/bio.h
+
+#### Extracted from: /usr/include/openssl/bn.h
+
+--include-function BN_get_rfc2409_prime_1024 # header: /usr/include/openssl/bn.h
+--include-function BN_get_rfc2409_prime_768 # header: /usr/include/openssl/bn.h
+--include-function BN_get_rfc3526_prime_1536 # header: /usr/include/openssl/bn.h
+--include-function BN_get_rfc3526_prime_2048 # header: /usr/include/openssl/bn.h
+--include-function BN_get_rfc3526_prime_3072 # header: /usr/include/openssl/bn.h
+--include-function BN_get_rfc3526_prime_4096 # header: /usr/include/openssl/bn.h
+--include-function BN_get_rfc3526_prime_6144 # header: /usr/include/openssl/bn.h
+--include-function BN_get_rfc3526_prime_8192 # header: /usr/include/openssl/bn.h
+--include-function BN_new # header: /usr/include/openssl/bn.h
+--include-function BN_set_word # header: /usr/include/openssl/bn.h
+
+#### Extracted from: /usr/include/openssl/crypto.h
+
+--include-function CRYPTO_free # header: /usr/include/openssl/crypto.h
+--include-function OpenSSL_version # header: /usr/include/openssl/crypto.h
+--include-function OpenSSL_version_num # header: /usr/include/openssl/crypto.h
+--include-constant OPENSSL_INIT_ENGINE_ALL_BUILTIN # header: /usr/include/openssl/crypto.h
+
+#### Extracted from: /usr/include/openssl/dh.h
+
+--include-function DH_free # header: /usr/include/openssl/dh.h
+--include-function DH_new # header: /usr/include/openssl/dh.h
+--include-function DH_set0_pqg # header: /usr/include/openssl/dh.h
+
+#### Extracted from: /usr/include/openssl/ec.h
+
+--include-function EC_GROUP_free # header: /usr/include/openssl/ec.h
+--include-function EC_GROUP_get_curve_name # header: /usr/include/openssl/ec.h
+--include-function EC_KEY_free # header: /usr/include/openssl/ec.h
+--include-function EC_KEY_new_by_curve_name # header: /usr/include/openssl/ec.h
+
+#### Extracted from: /usr/include/openssl/engine.h
+
+--include-function ENGINE_by_id # header: /usr/include/openssl/engine.h
+--include-function ENGINE_ctrl_cmd_string # header: /usr/include/openssl/engine.h
+--include-function ENGINE_free # header: /usr/include/openssl/engine.h
+--include-function ENGINE_load_private_key # header: /usr/include/openssl/engine.h
+--include-function ENGINE_register_all_complete # header: /usr/include/openssl/engine.h
+--include-function ENGINE_set_default # header: /usr/include/openssl/engine.h
+--include-constant ENGINE_METHOD_ALL # header: /usr/include/openssl/engine.h
+
+#### Extracted from: /usr/include/openssl/err.h
+
+--include-function ERR_clear_error # header: /usr/include/openssl/err.h
+--include-function ERR_error_string # header: /usr/include/openssl/err.h
+--include-function ERR_get_error # header: /usr/include/openssl/err.h
+--include-function ERR_peek_last_error # header: /usr/include/openssl/err.h
+
+#### Extracted from: /usr/include/openssl/evp.h
+
+--include-function EVP_MD_fetch # header: /usr/include/openssl/evp.h
+--include-function EVP_MD_free # header: /usr/include/openssl/evp.h
+--include-function EVP_MD_get0_provider # header: /usr/include/openssl/evp.h
+--include-function EVP_PKEY_get_base_id # header: /usr/include/openssl/evp.h
+--include-function EVP_PKEY_get_bits # header: /usr/include/openssl/evp.h
+--include-constant EVP_PKEY_DSA # header: /usr/include/openssl/evp.h
+--include-constant EVP_PKEY_NONE # header: /usr/include/openssl/evp.h
+--include-constant EVP_PKEY_RSA # header: /usr/include/openssl/evp.h
+
+#### Extracted from: /usr/include/openssl/obj_mac.h
+
+--include-constant NID_info_access # header: /usr/include/openssl/obj_mac.h
+
+#### Extracted from: /usr/include/openssl/ocsp.h
+
+--include-function OCSP_BASICRESP_free # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_CERTID_free # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_REQUEST_free # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_REQUEST_new # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_RESPONSE_free # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_cert_to_id # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_request_add0_id # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_response_get1_basic # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_response_status # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_resp_find # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_resp_get0 # header: /usr/include/openssl/ocsp.h
+--include-function OCSP_single_get0_status # header: /usr/include/openssl/ocsp.h
+--include-function d2i_OCSP_RESPONSE # header: /usr/include/openssl/ocsp.h
+--include-function i2d_OCSP_REQUEST # header: /usr/include/openssl/ocsp.h
+--include-constant OCSP_RESPONSE_STATUS_SUCCESSFUL # header: /usr/include/openssl/ocsp.h
+--include-constant V_OCSP_CERTSTATUS_GOOD # header: /usr/include/openssl/ocsp.h
+--include-constant V_OCSP_CERTSTATUS_REVOKED # header: /usr/include/openssl/ocsp.h
+--include-constant V_OCSP_CERTSTATUS_UNKNOWN # header: /usr/include/openssl/ocsp.h
+
+#### Extracted from: /usr/include/openssl/opensslconf-x86_64.h
+
+--include-constant OPENSSL_API_COMPAT # header: /usr/include/openssl/opensslconf-x86_64.h
+--include-constant OPENSSL_FILE # header: /usr/include/openssl/opensslconf-x86_64.h
+--include-constant OPENSSL_LINE # header: /usr/include/openssl/opensslconf-x86_64.h
+--include-constant OPENSSL_MIN_API # header: /usr/include/openssl/opensslconf-x86_64.h
+
+#### Extracted from: /usr/include/openssl/pem.h
+
+--include-function PEM_read_bio_DHparams # header: /usr/include/openssl/pem.h
+--include-function PEM_read_bio_ECPKParameters # header: /usr/include/openssl/pem.h
+--include-function PEM_read_bio_PrivateKey # header: /usr/include/openssl/pem.h
+--include-function PEM_read_bio_X509_AUX # header: /usr/include/openssl/pem.h
+
+#### Extracted from: /usr/include/openssl/pemerr.h
+
+--include-constant PEM_R_NO_START_LINE # header: /usr/include/openssl/pemerr.h
+
+#### Extracted from: /usr/include/openssl/pkcs12.h
+
+--include-function PKCS12_free # header: /usr/include/openssl/pkcs12.h
+--include-function PKCS12_parse # header: /usr/include/openssl/pkcs12.h
+--include-function PKCS12_verify_mac # header: /usr/include/openssl/pkcs12.h
+--include-function d2i_PKCS12_bio # header: /usr/include/openssl/pkcs12.h
+
+#### Extracted from: /usr/include/openssl/provider.h
+
+--include-function OSSL_PROVIDER_get0_name # header: /usr/include/openssl/provider.h
+
+#### Extracted from: /usr/include/openssl/rand.h
+
+--include-function RAND_load_file # header: /usr/include/openssl/rand.h
+--include-function RAND_seed # header: /usr/include/openssl/rand.h
+
+#### Extracted from: /usr/include/openssl/ssl.h
+
+--include-function OPENSSL_init_ssl # header: /usr/include/openssl/ssl.h
+--include-function SSL_CIPHER_get_auth_nid # header: /usr/include/openssl/ssl.h
+--include-function SSL_CIPHER_get_kx_nid # header: /usr/include/openssl/ssl.h
+--include-function SSL_CIPHER_get_name # header: /usr/include/openssl/ssl.h
+--include-function SSL_CONF_CTX_finish # header: /usr/include/openssl/ssl.h
+--include-function SSL_CONF_CTX_free # header: /usr/include/openssl/ssl.h
+--include-function SSL_CONF_CTX_new # header: /usr/include/openssl/ssl.h
+--include-function SSL_CONF_CTX_set_flags # header: /usr/include/openssl/ssl.h
+--include-function SSL_CONF_CTX_set_ssl_ctx # header: /usr/include/openssl/ssl.h
+--include-function SSL_CONF_cmd # header: /usr/include/openssl/ssl.h
+--include-function SSL_CONF_cmd_value_type # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_add_client_CA # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_check_private_key # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_clear_options # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_ctrl # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_free # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_get_cert_store # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_get_ciphers # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_get_client_CA_list # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_get_options # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_get_timeout # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_load_verify_locations # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_new # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_alpn_select_cb # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_cert_verify_callback # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_cipher_list # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_ciphersuites # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_client_CA_list # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_default_passwd_cb # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_default_verify_paths # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_options # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_session_id_context # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_timeout # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_tmp_dh_callback # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_set_verify # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_use_certificate # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_use_certificate_chain_file # header: /usr/include/openssl/ssl.h
+--include-function SSL_CTX_use_PrivateKey # header: /usr/include/openssl/ssl.h
+--include-function SSL_SESSION_get_id # header: /usr/include/openssl/ssl.h
+--include-function SSL_SESSION_get_time # header: /usr/include/openssl/ssl.h
+--include-function SSL_add_file_cert_subjects_to_stack # header: /usr/include/openssl/ssl.h
+--include-function SSL_do_handshake # header: /usr/include/openssl/ssl.h
+--include-function SSL_free # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_ciphers # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_current_cipher # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_ex_data_X509_STORE_CTX_idx # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_options # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_peer_cert_chain # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_privatekey # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_session # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_shutdown # header: /usr/include/openssl/ssl.h
+--include-function SSL_get_version # header: /usr/include/openssl/ssl.h
+--include-function SSL_get0_alpn_selected # header: /usr/include/openssl/ssl.h
+--include-function SSL_get1_peer_certificate # header: /usr/include/openssl/ssl.h
+--include-function SSL_in_init # header: /usr/include/openssl/ssl.h
+--include-function SSL_load_client_CA_file # header: /usr/include/openssl/ssl.h
+--include-function SSL_new # header: /usr/include/openssl/ssl.h
+--include-function SSL_pending # header: /usr/include/openssl/ssl.h
+--include-function SSL_read # header: /usr/include/openssl/ssl.h
+--include-function SSL_renegotiate # header: /usr/include/openssl/ssl.h
+--include-function SSL_renegotiate_pending # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_accept_state # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_bio # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_cipher_list # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_connect_state # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_info_callback # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_options # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_verify # header: /usr/include/openssl/ssl.h
+--include-function SSL_set_verify_result # header: /usr/include/openssl/ssl.h
+--include-function SSL_shutdown # header: /usr/include/openssl/ssl.h
+--include-function SSL_verify_client_post_handshake # header: /usr/include/openssl/ssl.h
+--include-function SSL_write # header: /usr/include/openssl/ssl.h
+--include-function TLS_server_method # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CB_HANDSHAKE_DONE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CONF_FLAG_CERTIFICATE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CONF_FLAG_FILE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CONF_FLAG_SERVER # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CONF_FLAG_SHOW_ERRORS # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CONF_TYPE_DIR # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CONF_TYPE_FILE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CONF_TYPE_UNKNOWN # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_CHAIN_CERT # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_GET_SESS_CACHE_MODE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_GET_SESS_CACHE_SIZE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_ACCEPT # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_ACCEPT_GOOD # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_ACCEPT_RENEGOTIATE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_CACHE_FULL # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_CB_HIT # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_CONNECT # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_CONNECT_GOOD # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_CONNECT_RENEGOTIATE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_HIT # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_MISSES # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_NUMBER # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SESS_TIMEOUTS # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SET_MAX_PROTO_VERSION # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SET_MIN_PROTO_VERSION # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SET_SESS_CACHE_MODE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SET_SESS_CACHE_SIZE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SET_TLSEXT_TICKET_KEYS # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SET_TMP_DH # header: /usr/include/openssl/ssl.h
+--include-constant SSL_CTRL_SET_TMP_ECDH # header: /usr/include/openssl/ssl.h
+--include-constant SSL_ERROR_NONE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_ALL # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_CIPHER_SERVER_PREFERENCE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_COMPRESSION # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_SSLv2 # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_SSLv3 # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_TICKET # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_TLSv1 # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_TLSv1_1 # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_TLSv1_2 # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_NO_TLSv1_3 # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_SINGLE_DH_USE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_OP_SINGLE_ECDH_USE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_RECEIVED_SHUTDOWN # header: /usr/include/openssl/ssl.h
+--include-constant SSL_SENT_SHUTDOWN # header: /usr/include/openssl/ssl.h
+--include-constant SSL_SESS_CACHE_OFF # header: /usr/include/openssl/ssl.h
+--include-constant SSL_SESS_CACHE_SERVER # header: /usr/include/openssl/ssl.h
+--include-constant SSL_VERIFY_FAIL_IF_NO_PEER_CERT # header: /usr/include/openssl/ssl.h
+--include-constant SSL_VERIFY_NONE # header: /usr/include/openssl/ssl.h
+--include-constant SSL_VERIFY_PEER # header: /usr/include/openssl/ssl.h
+
+#### Extracted from: /usr/include/openssl/ssl2.h
+
+--include-constant SSL2_VERSION # header: /usr/include/openssl/ssl2.h
+
+#### Extracted from: /usr/include/openssl/ssl3.h
+
+--include-constant SSL3_VERSION # header: /usr/include/openssl/ssl3.h
+
+#### Extracted from: /usr/include/openssl/tls1.h
+
+--include-constant SSL_TLSEXT_ERR_NOACK # header: /usr/include/openssl/tls1.h
+--include-constant SSL_TLSEXT_ERR_OK # header: /usr/include/openssl/tls1.h
+--include-constant TLS1_1_VERSION # header: /usr/include/openssl/tls1.h
+--include-constant TLS1_2_VERSION # header: /usr/include/openssl/tls1.h
+--include-constant TLS1_3_VERSION # header: /usr/include/openssl/tls1.h
+--include-constant TLS1_VERSION # header: /usr/include/openssl/tls1.h
+
+#### Extracted from: /usr/include/openssl/stack.h
+
+--include-function OPENSSL_sk_num # header: /usr/include/openssl/stack.h
+--include-function OPENSSL_sk_value # header: /usr/include/openssl/stack.h
+
+#### Extracted from: /usr/include/openssl/x509.h
+
+--include-function i2d_X509 # header: /usr/include/openssl/x509.h
+--include-function d2i_X509 # header: /usr/include/openssl/x509.h
+--include-function d2i_X509_bio # header: /usr/include/openssl/x509.h
+--include-function X509_EXTENSION_get_data # header: /usr/include/openssl/x509.h
+--include-function X509_free # header: /usr/include/openssl/x509.h
+--include-function X509_get_ext # header: /usr/include/openssl/x509.h
+--include-function X509_get_ext_by_NID # header: /usr/include/openssl/x509.h
+--include-constant X509_FILETYPE_PEM # header: /usr/include/openssl/x509.h
+
+#### Extracted from: /usr/include/openssl/x509v3.h
+
+--include-function X509_check_issued # header: /usr/include/openssl/x509v3.h
+
+#### Extracted from: /usr/include/openssl/x509_vfy.h
+
+--include-function X509_LOOKUP_ctrl # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_LOOKUP_file # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_LOOKUP_hash_dir # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_add_lookup # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_get_current_cert # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_get_error # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_get_error_depth # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_get_ex_data # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_get0_current_issuer # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_get0_untrusted # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_set_error # header: /usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_set_flags # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_L_ADD_DIR # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_L_FILE_LOAD # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_ERR_APPLICATION_VERIFICATION # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_ERR_CERT_UNTRUSTED # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_ERR_CRL_HAS_EXPIRED # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_FLAG_CRL_CHECK # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_FLAG_CRL_CHECK_ALL # header: /usr/include/openssl/x509_vfy.h
+--include-constant X509_V_OK # header: /usr/include/openssl/x509_vfy.h
+
diff --git a/modules/openssl-java21/openssl.h b/modules/openssl-java21/openssl.h
new file mode 100644
index 0000000000..e31fad9e1b
--- /dev/null
+++ b/modules/openssl-java21/openssl.h
@@ -0,0 +1,31 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <openssl/opensslv.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include <openssl/engine.h>
+#include <openssl/ocsp.h>
+#include <openssl/provider.h>
diff --git a/modules/openssl-java21/pom.xml b/modules/openssl-java21/pom.xml
new file mode 100644
index 0000000000..d0f2569256
--- /dev/null
+++ b/modules/openssl-java21/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>27</version>
+ </parent>
+
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-coyote-openssl-java21</artifactId>
+ <name>Apache Tomcat OpenSSL support for Java 21</name>
+ <description>OpenSSL support using the Panama JEP 442 API included in Java 21</description>
+ <version>0.1-SNAPSHOT</version>
+
+ <properties>
+ <tomcat.version>9.0.73</tomcat.version>
+ <project.build.outputTimestamp>2021-12-02T12:00:00Z</project.build.outputTimestamp>
+ </properties>
+
+ <scm>
+ <connection>scm:git:https://gitbox.apache.org/repos/asf/tomcat.git</connection>
+ <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/tomcat.git</developerConnection>
+ <url>https://gitbox.apache.org/repos/asf?p=tomcat.git</url>
+ <tag>HEAD</tag>
+ </scm>
+
+ <mailingLists>
+ <mailingList>
+ <name>Development List</name>
+ <subscribe>dev-subscribe@tomcat.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@tomcat.apache.org</unsubscribe>
+ <post>dev@tomcat.apache.org</post>
+ </mailingList>
+ <mailingList>
+ <name>Users List</name>
+ <subscribe>users-subscribe@tomcat.apache.org</subscribe>
+ <unsubscribe>users-unsubscribe@tomcat.apache.org</unsubscribe>
+ <post>users@tomcat.apache.org</post>
+ </mailingList>
+ </mailingLists>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-catalina</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-coyote</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>21</source>
+ <target>21</target>
+ <compilerArgs>
+ <arg>--enable-preview</arg>
+ </compilerArgs>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <source>19</source>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
new file mode 100644
index 0000000000..61d953a1c4
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -0,0 +1,1406 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+import java.io.File;
+import java.lang.foreign.Arena;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.Linker;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.ValueLayout;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.ref.Cleaner;
+import java.lang.ref.Cleaner.Cleanable;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+
+import static org.apache.tomcat.util.openssl.openssl_compat_h.*;
+import static org.apache.tomcat.util.openssl.openssl_h.*;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.net.AbstractEndpoint;
+import org.apache.tomcat.util.net.Constants;
+import org.apache.tomcat.util.net.SSLHostConfig;
+import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification;
+import org.apache.tomcat.util.net.SSLHostConfigCertificate;
+import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type;
+import org.apache.tomcat.util.net.openssl.OpenSSLConf;
+import org.apache.tomcat.util.net.openssl.OpenSSLConfCmd;
+import org.apache.tomcat.util.res.StringManager;
+
+public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
+
+ private static final Log log = LogFactory.getLog(OpenSSLContext.class);
+
+ private static final StringManager netSm = StringManager.getManager(AbstractEndpoint.class);
+ private static final StringManager sm = StringManager.getManager(OpenSSLContext.class);
+
+ private static final Cleaner cleaner = Cleaner.create();
+
+ private static final String defaultProtocol = "TLS";
+
+ private static final int SSL_AIDX_RSA = 0;
+ private static final int SSL_AIDX_DSA = 1;
+ private static final int SSL_AIDX_ECC = 3;
+ private static final int SSL_AIDX_MAX = 4;
+
+ public static final int SSL_PROTOCOL_NONE = 0;
+ public static final int SSL_PROTOCOL_SSLV2 = (1<<0);
+ public static final int SSL_PROTOCOL_SSLV3 = (1<<1);
+ public static final int SSL_PROTOCOL_TLSV1 = (1<<2);
+ public static final int SSL_PROTOCOL_TLSV1_1 = (1<<3);
+ public static final int SSL_PROTOCOL_TLSV1_2 = (1<<4);
+ public static final int SSL_PROTOCOL_TLSV1_3 = (1<<5);
+ public static final int SSL_PROTOCOL_ALL = (SSL_PROTOCOL_TLSV1 | SSL_PROTOCOL_TLSV1_1 | SSL_PROTOCOL_TLSV1_2 |
+ SSL_PROTOCOL_TLSV1_3);
+
+ private static final String BEGIN_KEY = "-----BEGIN PRIVATE KEY-----\n";
+ private static final Object END_KEY = "\n-----END PRIVATE KEY-----";
+
+ private static final byte[] HTTP_11_PROTOCOL =
+ new byte[] { 'h', 't', 't', 'p', '/', '1', '.', '1' };
+
+ private static final byte[] DEFAULT_SESSION_ID_CONTEXT =
+ new byte[] { 'd', 'e', 'f', 'a', 'u', 'l', 't' };
+
+ static final CertificateFactory X509_CERT_FACTORY;
+ static {
+ try {
+ X509_CERT_FACTORY = CertificateFactory.getInstance("X.509");
+ } catch (CertificateException e) {
+ throw new IllegalStateException(sm.getString("openssl.X509FactoryError"), e);
+ }
+ }
+
+ private static final MethodHandle openSSLCallbackVerifyHandle;
+ private static final MethodHandle openSSLCallbackPasswordHandle;
+ private static final MethodHandle openSSLCallbackCertVerifyHandle;
+ private static final MethodHandle openSSLCallbackAlpnSelectProtoHandle;
+ private static final MethodHandle openSSLCallbackTmpDHHandle;
+
+ private static final FunctionDescriptor openSSLCallbackVerifyFunctionDescriptor =
+ FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
+ private static final FunctionDescriptor openSSLCallbackPasswordFunctionDescriptor =
+ FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_INT,
+ ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
+ private static final FunctionDescriptor openSSLCallbackCertVerifyFunctionDescriptor =
+ FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
+ private static final FunctionDescriptor openSSLCallbackAlpnSelectProtoFunctionDescriptor =
+ FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS,
+ ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS,
+ ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
+ private static final FunctionDescriptor openSSLCallbackTmpDHFunctionDescriptor =
+ FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS,
+ ValueLayout.JAVA_INT, ValueLayout.JAVA_INT);
+
+ static {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ try {
+ openSSLCallbackVerifyHandle = lookup.findStatic(OpenSSLContext.class, "openSSLCallbackVerify",
+ MethodType.methodType(int.class, int.class, MemorySegment.class));
+ openSSLCallbackPasswordHandle = lookup.findStatic(OpenSSLContext.class, "openSSLCallbackPassword",
+ MethodType.methodType(int.class, MemorySegment.class, int.class, int.class, MemorySegment.class));
+ openSSLCallbackCertVerifyHandle = lookup.findStatic(OpenSSLContext.class, "openSSLCallbackCertVerify",
+ MethodType.methodType(int.class, MemorySegment.class, MemorySegment.class));
+ openSSLCallbackAlpnSelectProtoHandle = lookup.findStatic(OpenSSLContext.class, "openSSLCallbackAlpnSelectProto",
+ MethodType.methodType(int.class, MemorySegment.class, MemorySegment.class,
+ MemorySegment.class, MemorySegment.class, int.class, MemorySegment.class));
+ openSSLCallbackTmpDHHandle = lookup.findStatic(OpenSSLContext.class, "openSSLCallbackTmpDH",
+ MethodType.methodType(MemorySegment.class, MemorySegment.class, int.class, int.class));
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ static final boolean OPENSSL_3 = (OpenSSL_version_num() >= 0x3000000fL);
+
+ private final SSLHostConfig sslHostConfig;
+ private final SSLHostConfigCertificate certificate;
+ private final boolean alpn;
+ private final int minTlsVersion;
+ private final int maxTlsVersion;
+
+ private OpenSSLSessionContext sessionContext;
+ private String enabledProtocol;
+ private boolean initialized = false;
+
+ private boolean noOcspCheck = false;
+
+ // Password callback
+ private final MemorySegment openSSLCallbackPassword;
+
+ private static final ConcurrentHashMap<Long, ContextState> states = new ConcurrentHashMap<>();
+
+ static ContextState getState(MemorySegment ctx) {
+ return states.get(Long.valueOf(ctx.address()));
+ }
+
+ private final ContextState state;
+ private final Arena contextArena;
+ private final Cleanable cleanable;
+
+ private static String[] getCiphers(MemorySegment sslCtx) {
+ MemorySegment sk = SSL_CTX_get_ciphers(sslCtx);
+ int len = OPENSSL_sk_num(sk);
+ if (len <= 0) {
+ return null;
+ }
+ ArrayList<String> ciphers = new ArrayList<>(len);
+ for (int i = 0; i < len; i++) {
+ MemorySegment cipher = OPENSSL_sk_value(sk, i);
+ MemorySegment cipherName = SSL_CIPHER_get_name(cipher);
+ ciphers.add(cipherName.getUtf8String(0));
+ }
+ return ciphers.toArray(new String[0]);
+ }
+
+ public OpenSSLContext(SSLHostConfigCertificate certificate, List<String> negotiableProtocols)
+ throws SSLException {
+
+ // Check that OpenSSL was initialized
+ if (!OpenSSLStatus.isInitialized()) {
+ try {
+ OpenSSLLifecycleListener.init();
+ } catch (Exception e) {
+ throw new SSLException(e);
+ }
+ }
+
+ this.sslHostConfig = certificate.getSSLHostConfig();
+ this.certificate = certificate;
+ contextArena = Arena.ofAuto();
+
+ MemorySegment sslCtx = MemorySegment.NULL;
+ MemorySegment confCtx = MemorySegment.NULL;
+ List<byte[]> negotiableProtocolsBytes = null;
+ boolean success = false;
+ try {
+ // Create OpenSSLConfCmd context if used
+ OpenSSLConf openSslConf = sslHostConfig.getOpenSslConf();
+ if (openSslConf != null) {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("openssl.makeConf"));
+ }
+ confCtx = SSL_CONF_CTX_new();
+ long errCode = ERR_get_error();
+ if (errCode != 0) {
+ try (var localArena = Arena.ofConfined()) {
+ var buf = localArena.allocateArray(ValueLayout.JAVA_BYTE, new byte[128]);
+ ERR_error_string(errCode, buf);
+ log.error(sm.getString("openssl.errorLoadingCertificate", buf.getUtf8String(0)));
+ }
+ }
+ SSL_CONF_CTX_set_flags(confCtx, SSL_CONF_FLAG_FILE() |
+ SSL_CONF_FLAG_SERVER() |
+ SSL_CONF_FLAG_CERTIFICATE() |
+ SSL_CONF_FLAG_SHOW_ERRORS());
+ } catch (Exception e) {
+ throw new SSLException(sm.getString("openssl.errMakeConf"), e);
+ }
+ }
+
+ // SSL protocol
+ sslCtx = SSL_CTX_new(TLS_server_method());
+
+ int protocol = SSL_PROTOCOL_NONE;
+ for (String enabledProtocol : sslHostConfig.getEnabledProtocols()) {
+ if (Constants.SSL_PROTO_SSLv2Hello.equalsIgnoreCase(enabledProtocol)) {
+ // NO-OP. OpenSSL always supports SSLv2Hello
+ } else if (Constants.SSL_PROTO_SSLv2.equalsIgnoreCase(enabledProtocol)) {
+ protocol |= SSL_PROTOCOL_SSLV2;
+ } else if (Constants.SSL_PROTO_SSLv3.equalsIgnoreCase(enabledProtocol)) {
+ protocol |= SSL_PROTOCOL_SSLV3;
+ } else if (Constants.SSL_PROTO_TLSv1.equalsIgnoreCase(enabledProtocol)) {
+ protocol |= SSL_PROTOCOL_TLSV1;
+ } else if (Constants.SSL_PROTO_TLSv1_1.equalsIgnoreCase(enabledProtocol)) {
+ protocol |= SSL_PROTOCOL_TLSV1_1;
+ } else if (Constants.SSL_PROTO_TLSv1_2.equalsIgnoreCase(enabledProtocol)) {
+ protocol |= SSL_PROTOCOL_TLSV1_2;
+ } else if (Constants.SSL_PROTO_TLSv1_3.equalsIgnoreCase(enabledProtocol)) {
+ protocol |= SSL_PROTOCOL_TLSV1_3;
+ } else if (Constants.SSL_PROTO_ALL.equalsIgnoreCase(enabledProtocol)) {
+ protocol |= SSL_PROTOCOL_ALL;
+ } else {
+ // Should not happen since filtering to build
+ // enabled protocols removes invalid values.
+ throw new Exception(netSm.getString(
+ "endpoint.apr.invalidSslProtocol", enabledProtocol));
+ }
+ }
+ // Set maximum and minimum protocol versions
+ int prot = SSL2_VERSION();
+ if ((protocol & SSL_PROTOCOL_TLSV1_3) > 0) {
+ prot = TLS1_3_VERSION();
+ } else if ((protocol & SSL_PROTOCOL_TLSV1_2) > 0) {
+ prot = TLS1_2_VERSION();
+ } else if ((protocol & SSL_PROTOCOL_TLSV1_1) > 0) {
+ prot = TLS1_1_VERSION();
+ } else if ((protocol & SSL_PROTOCOL_TLSV1) > 0) {
+ prot = TLS1_VERSION();
+ } else if ((protocol & SSL_PROTOCOL_SSLV3) > 0) {
+ prot = SSL3_VERSION();
+ }
+ maxTlsVersion = prot;
+ // # define SSL_CTX_set_max_proto_version(sslCtx, version) \
+ // SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
+ SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_MAX_PROTO_VERSION(), prot, MemorySegment.NULL);
+ if (prot == TLS1_3_VERSION() && (protocol & SSL_PROTOCOL_TLSV1_2) > 0) {
+ prot = TLS1_2_VERSION();
+ }
+ if (prot == TLS1_2_VERSION() && (protocol & SSL_PROTOCOL_TLSV1_1) > 0) {
+ prot = TLS1_1_VERSION();
+ }
+ if (prot == TLS1_1_VERSION() && (protocol & SSL_PROTOCOL_TLSV1) > 0) {
+ prot = TLS1_VERSION();
+ }
+ if (prot == TLS1_VERSION() && (protocol & SSL_PROTOCOL_SSLV3) > 0) {
+ prot = SSL3_VERSION();
+ }
+ minTlsVersion = prot;
+ //# define SSL_CTX_set_min_proto_version(sslCtx, version) \
+ // SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
+ SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_MIN_PROTO_VERSION(), prot, MemorySegment.NULL);
+
+ // Disable compression, usually unsafe
+ SSL_CTX_set_options(sslCtx, SSL_OP_NO_COMPRESSION());
+
+ // Disallow a session from being resumed during a renegotiation,
+ // so that an acceptable cipher suite can be negotiated.
+ SSL_CTX_set_options(sslCtx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION());
+
+ SSL_CTX_set_options(sslCtx, SSL_OP_SINGLE_DH_USE());
+ SSL_CTX_set_options(sslCtx, SSL_OP_SINGLE_ECDH_USE());
+
+ // Default session context id and cache size
+ // # define SSL_CTX_sess_set_cache_size(sslCtx,t) \
+ // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
+ SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_SESS_CACHE_SIZE(), 256, MemorySegment.NULL);
+
+ // Session cache is disabled by default
+ // # define SSL_CTX_set_session_cache_mode(sslCtx,m) \
+ // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
+ SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_SESS_CACHE_MODE(), SSL_SESS_CACHE_OFF(), MemorySegment.NULL);
+
+ // Longer session timeout
+ SSL_CTX_set_timeout(sslCtx, 14400);
+
+ // From SSLContext.make, possibly set ssl_callback_ServerNameIndication
+ // From SSLContext.make, possibly set ssl_callback_ClientHello
+ // Probably not needed
+
+ // Set int pem_password_cb(char *buf, int size, int rwflag, void *u) callback
+ openSSLCallbackPassword =
+ Linker.nativeLinker().upcallStub(openSSLCallbackPasswordHandle,
+ openSSLCallbackPasswordFunctionDescriptor, contextArena);
+ SSL_CTX_set_default_passwd_cb(sslCtx, openSSLCallbackPassword);
+
+ alpn = (negotiableProtocols != null && negotiableProtocols.size() > 0);
+ if (alpn) {
+ negotiableProtocolsBytes = new ArrayList<>(negotiableProtocols.size() + 1);
+ for (String negotiableProtocol : negotiableProtocols) {
+ negotiableProtocolsBytes.add(negotiableProtocol.getBytes(StandardCharsets.ISO_8859_1));
+ }
+ negotiableProtocolsBytes.add(HTTP_11_PROTOCOL);
+ }
+
+ success = true;
+ } catch(Exception e) {
+ throw new SSLException(sm.getString("openssl.errorSSLCtxInit"), e);
+ } finally {
+ state = new ContextState(sslCtx, confCtx, negotiableProtocolsBytes);
+ /*
+ * When an SSLHostConfig is replaced at runtime, it is not possible to
+ * call destroy() on the associated OpenSSLContext since it is likely
+ * that there will be in-progress connections using the OpenSSLContext.
+ * A reference chain has been deliberately established (see
+ * OpenSSLSessionContext) to ensure that the OpenSSLContext remains
+ * ineligible for GC while those connections are alive. Once those
+ * connections complete, the OpenSSLContext will become eligible for GC
+ * and the memory session will ensure that the associated native
+ * resources are cleaned up.
+ */
+ cleanable = cleaner.register(this, state);
+
+ if (!success) {
+ destroy();
+ }
+ }
+ }
+
+
+ public String getEnabledProtocol() {
+ return enabledProtocol;
+ }
+
+
+ public void setEnabledProtocol(String protocol) {
+ enabledProtocol = (protocol == null) ? defaultProtocol : protocol;
+ }
+
+
+ @Override
+ public void destroy() {
+ cleanable.clean();
+ }
+
+
+ private boolean checkConf(OpenSSLConf conf) throws Exception {
+ boolean result = true;
+ OpenSSLConfCmd cmd;
+ String name;
+ String value;
+ int rc;
+ for (OpenSSLConfCmd command : conf.getCommands()) {
+ cmd = command;
+ name = cmd.getName();
+ value = cmd.getValue();
+ if (name == null) {
+ log.error(sm.getString("opensslconf.noCommandName", value));
+ result = false;
+ continue;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("opensslconf.checkCommand", name, value));
+ }
+ try (var localArena = Arena.ofConfined()) {
+ // rc = SSLConf.check(confCtx, name, value);
+ if (name.equals("NO_OCSP_CHECK")) {
+ rc = 1;
+ } else {
+ int code = SSL_CONF_cmd_value_type(state.confCtx, localArena.allocateUtf8String(name));
+ rc = 1;
+ long errCode = ERR_get_error();
+ if (errCode != 0) {
+ var buf = localArena.allocateArray(ValueLayout.JAVA_BYTE, new byte[128]);
+ ERR_error_string(errCode, buf);
+ log.error(sm.getString("opensslconf.checkFailed", buf.getUtf8String(0)));
+ rc = 0;
+ }
+ if (code == SSL_CONF_TYPE_UNKNOWN()) {
+ log.error(sm.getString("opensslconf.typeUnknown", name));
+ rc = 0;
+ }
+ if (code == SSL_CONF_TYPE_FILE()) {
+ // Check file
+ File file = new File(value);
+ if (!file.isFile() && !file.canRead()) {
+ log.error(sm.getString("opensslconf.badFile", name, value));
+ rc = 0;
+ }
+ }
+ if (code == SSL_CONF_TYPE_DIR()) {
+ // Check dir
+ File file = new File(value);
+ if (!file.isDirectory()) {
+ log.error(sm.getString("opensslconf.badDirectory", name, value));
+ rc = 0;
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error(sm.getString("opensslconf.checkFailed", e.getLocalizedMessage()));
+ return false;
+ }
+ if (rc <= 0) {
+ log.error(sm.getString("opensslconf.failedCommand", name, value,
+ Integer.toString(rc)));
+ result = false;
+ } else if (log.isDebugEnabled()) {
+ log.debug(sm.getString("opensslconf.resultCommand", name, value,
+ Integer.toString(rc)));
+ }
+ }
+ if (!result) {
+ log.error(sm.getString("opensslconf.checkFailed"));
+ }
+ return result;
+ }
+
+
+ private boolean applyConf(OpenSSLConf conf) throws Exception {
+ boolean result = true;
+ // SSLConf.assign(confCtx, sslCtx);
+ SSL_CONF_CTX_set_ssl_ctx(state.confCtx, state.sslCtx);
+ OpenSSLConfCmd cmd;
+ String name;
+ String value;
+ int rc;
+ for (OpenSSLConfCmd command : conf.getCommands()) {
+ cmd = command;
+ name = cmd.getName();
+ value = cmd.getValue();
+ if (name == null) {
+ log.error(sm.getString("opensslconf.noCommandName", value));
+ result = false;
+ continue;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("opensslconf.applyCommand", name, value));
+ }
+ try (var localArena = Arena.ofConfined()) {
+ // rc = SSLConf.apply(confCtx, name, value);
+ if (name.equals("NO_OCSP_CHECK")) {
+ noOcspCheck = Boolean.valueOf(value);
+ rc = 1;
+ } else {
+ rc = SSL_CONF_cmd(state.confCtx, localArena.allocateUtf8String(name),
+ localArena.allocateUtf8String(value));
+ long errCode = ERR_get_error();
+ if (rc <= 0 || errCode != 0) {
+ var buf = localArena.allocateArray(ValueLayout.JAVA_BYTE, new byte[128]);
+ ERR_error_string(errCode, buf);
+ log.error(sm.getString("opensslconf.commandError", name, value, buf.getUtf8String(0)));
+ rc = 0;
+ }
+ }
+ } catch (Exception e) {
+ log.error(sm.getString("opensslconf.applyFailed"));
+ return false;
+ }
+ if (rc <= 0) {
+ log.error(sm.getString("opensslconf.failedCommand", name, value,
+ Integer.toString(rc)));
+ result = false;
+ } else if (log.isDebugEnabled()) {
+ log.debug(sm.getString("opensslconf.resultCommand", name, value,
+ Integer.toString(rc)));
+ }
+ }
+ // rc = SSLConf.finish(confCtx);
+ rc = SSL_CONF_CTX_finish(state.confCtx);
+ if (rc <= 0) {
+ log.error(sm.getString("opensslconf.finishFailed", Integer.toString(rc)));
+ result = false;
+ }
+ if (!result) {
+ log.error(sm.getString("opensslconf.applyFailed"));
+ }
+ return result;
+ }
+
+ private static final int OPTIONAL_NO_CA = 3;
+
+ /**
+ * Setup the SSL_CTX.
+ *
+ * @param kms Must contain a KeyManager of the type
+ * {@code OpenSSLKeyManager}
+ * @param tms Must contain a TrustManager of the type
+ * {@code X509TrustManager}
+ * @param sr Is not used for this implementation.
+ */
+ @Override
+ public synchronized void init(KeyManager[] kms, TrustManager[] tms, SecureRandom sr) {
+ if (initialized) {
+ log.warn(sm.getString("openssl.doubleInit"));
+ return;
+ }
+ try (var localArena = Arena.ofConfined()) {
+ if (sslHostConfig.getInsecureRenegotiation()) {
+ SSL_CTX_set_options(state.sslCtx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
+ } else {
+ SSL_CTX_clear_options(state.sslCtx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
+ }
+
+ // Use server's preference order for ciphers (rather than
+ // client's)
+ if (sslHostConfig.getHonorCipherOrder()) {
+ SSL_CTX_set_options(state.sslCtx, SSL_OP_CIPHER_SERVER_PREFERENCE());
+ } else {
+ SSL_CTX_clear_options(state.sslCtx, SSL_OP_CIPHER_SERVER_PREFERENCE());
+ }
+
+ // Disable compression if requested
+ if (sslHostConfig.getDisableCompression()) {
+ SSL_CTX_set_options(state.sslCtx, SSL_OP_NO_COMPRESSION());
+ } else {
+ SSL_CTX_clear_options(state.sslCtx, SSL_OP_NO_COMPRESSION());
+ }
+
+ // Disable TLS Session Tickets (RFC4507) to protect perfect forward secrecy
+ if (sslHostConfig.getDisableSessionTickets()) {
+ SSL_CTX_set_options(state.sslCtx, SSL_OP_NO_TICKET());
+ } else {
+ SSL_CTX_clear_options(state.sslCtx, SSL_OP_NO_TICKET());
+ }
+
+ // List the ciphers that the client is permitted to negotiate
+ if (minTlsVersion <= TLS1_2_VERSION()) {
+ if (SSL_CTX_set_cipher_list(state.sslCtx,
+ localArena.allocateUtf8String(sslHostConfig.getCiphers())) <= 0) {
+ log.warn(sm.getString("engine.failedCipherList", sslHostConfig.getCiphers()));
+ }
+ }
+ if (maxTlsVersion >= TLS1_3_VERSION() && (sslHostConfig.getCiphers() != SSLHostConfig.DEFAULT_TLS_CIPHERS)) {
+ if (SSL_CTX_set_ciphersuites(state.sslCtx,
+ localArena.allocateUtf8String(sslHostConfig.getCiphers())) <= 0) {
+ log.warn(sm.getString("engine.failedCipherSuite", sslHostConfig.getCiphers()));
+ }
+ }
+
+ if (certificate.getCertificateFile() == null) {
+ certificate.setCertificateKeyManager(OpenSSLUtil.chooseKeyManager(kms));
+ }
+
+ addCertificate(certificate, localArena);
+
+ // Client certificate verification
+ int value = 0;
+ switch (sslHostConfig.getCertificateVerification()) {
+ case NONE:
+ value = SSL_VERIFY_NONE();
+ break;
+ case OPTIONAL:
+ value = SSL_VERIFY_PEER();
+ break;
+ case OPTIONAL_NO_CA:
+ value = OPTIONAL_NO_CA;
+ break;
+ case REQUIRED:
+ value = SSL_VERIFY_FAIL_IF_NO_PEER_CERT();
+ break;
+ }
+
+ // SSLContext.setVerify(state.ctx, value, sslHostConfig.getCertificateVerificationDepth());
+ if (SSL_CTX_set_default_verify_paths(state.sslCtx) > 0) {
+ var store = SSL_CTX_get_cert_store(state.sslCtx);
+ X509_STORE_set_flags(store, 0);
+ }
+
+ // Set int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) callback
+ var openSSLCallbackVerify =
+ Linker.nativeLinker().upcallStub(openSSLCallbackVerifyHandle,
+ openSSLCallbackVerifyFunctionDescriptor, contextArena);
+ // Leave this just in case but in Tomcat this is always set again by the engine
+ SSL_CTX_set_verify(state.sslCtx, value, openSSLCallbackVerify);
+
+ // Trust and certificate verification
+ if (tms != null) {
+ // Client certificate verification based on custom trust managers
+ state.x509TrustManager = chooseTrustManager(tms);
+ var openSSLCallbackCertVerify =
+ Linker.nativeLinker().upcallStub(openSSLCallbackCertVerifyHandle,
+ openSSLCallbackCertVerifyFunctionDescriptor, contextArena);
+ SSL_CTX_set_cert_verify_callback(state.sslCtx, openSSLCallbackCertVerify, state.sslCtx);
+
+ // Pass along the DER encoded certificates of the accepted client
+ // certificate issuers, so that their subjects can be presented
+ // by the server during the handshake to allow the client choosing
+ // an acceptable certificate
+ for (X509Certificate caCert : state.x509TrustManager.getAcceptedIssuers()) {
+ //SSLContext.addClientCACertificateRaw(state.ctx, caCert.getEncoded());
+ var rawCACertificate = localArena.allocateArray(ValueLayout.JAVA_BYTE, caCert.getEncoded());
+ var rawCACertificatePointer = localArena.allocate(ValueLayout.ADDRESS, rawCACertificate);
+ var x509CACert = d2i_X509(MemorySegment.NULL, rawCACertificatePointer, rawCACertificate.byteSize());
+ if (MemorySegment.NULL.equals(x509CACert)) {
+ logLastError(localArena, "openssl.errorLoadingCertificate");
+ } else if (SSL_CTX_add_client_CA(state.sslCtx, x509CACert) <= 0) {
+ logLastError(localArena, "openssl.errorAddingCertificate");
+ } else if (log.isDebugEnabled()) {
+ log.debug(sm.getString("openssl.addedClientCaCert", caCert.toString()));
+ }
+ }
+ } else {
+ // Client certificate verification based on trusted CA files and dirs
+ //SSLContext.setCACertificate(state.ctx,
+ // SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()),
+ // SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath()));
+ MemorySegment caCertificateFileNative = sslHostConfig.getCaCertificateFile() != null
+ ? localArena.allocateUtf8String(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile())) : null;
+ MemorySegment caCertificatePathNative = sslHostConfig.getCaCertificatePath() != null
+ ? localArena.allocateUtf8String(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath())) : null;
+ if ((sslHostConfig.getCaCertificateFile() != null || sslHostConfig.getCaCertificatePath() != null)
+ && SSL_CTX_load_verify_locations(state.sslCtx,
+ caCertificateFileNative == null ? MemorySegment.NULL : caCertificateFileNative,
+ caCertificatePathNative == null ? MemorySegment.NULL : caCertificatePathNative) <= 0) {
+ logLastError(localArena, "openssl.errorConfiguringLocations");
+ } else {
+ var caCerts = SSL_CTX_get_client_CA_list(state.sslCtx);
+ if (MemorySegment.NULL.equals(caCerts)) {
+ caCerts = SSL_load_client_CA_file(caCertificateFileNative == null ? MemorySegment.NULL : caCertificateFileNative);
+ if (!MemorySegment.NULL.equals(caCerts)) {
+ SSL_CTX_set_client_CA_list(state.sslCtx, caCerts);
+ }
+ } else {
+ if (SSL_add_file_cert_subjects_to_stack(caCerts,
+ caCertificateFileNative == null ? MemorySegment.NULL : caCertificateFileNative) <= 0) {
+ caCerts = MemorySegment.NULL;
+ }
+ }
+ if (MemorySegment.NULL.equals(caCerts)) {
+ log.warn(sm.getString("openssl.noCACerts"));
+ }
+ }
+ }
+
+ if (state.negotiableProtocols != null && state.negotiableProtocols.size() > 0) {
+ // int openSSLCallbackAlpnSelectProto(MemoryAddress ssl, MemoryAddress out, MemoryAddress outlen,
+ // MemoryAddress in, int inlen, MemoryAddress arg
+ var openSSLCallbackAlpnSelectProto =
+ Linker.nativeLinker().upcallStub(openSSLCallbackAlpnSelectProtoHandle,
+ openSSLCallbackAlpnSelectProtoFunctionDescriptor, contextArena);
+ SSL_CTX_set_alpn_select_cb(state.sslCtx, openSSLCallbackAlpnSelectProto, state.sslCtx);
+ }
+
+ // Apply OpenSSLConfCmd if used
+ OpenSSLConf openSslConf = sslHostConfig.getOpenSslConf();
+ if (openSslConf != null && !MemorySegment.NULL.equals(state.confCtx)) {
+ // Check OpenSSLConfCmd if used
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("openssl.checkConf"));
+ }
+ try {
+ if (!checkConf(openSslConf)) {
+ log.error(sm.getString("openssl.errCheckConf"));
+ throw new Exception(sm.getString("openssl.errCheckConf"));
+ }
+ } catch (Exception e) {
+ throw new Exception(sm.getString("openssl.errCheckConf"), e);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("openssl.applyConf"));
+ }
+ try {
+ if (!applyConf(openSslConf)) {
+ log.error(sm.getString("openssl.errApplyConf"));
+ throw new SSLException(sm.getString("openssl.errApplyConf"));
+ }
+ } catch (Exception e) {
+ throw new SSLException(sm.getString("openssl.errApplyConf"), e);
+ }
+ // Reconfigure the enabled protocols
+ long opts = SSL_CTX_get_options(state.sslCtx);
+ List<String> enabled = new ArrayList<>();
+ // Seems like there is no way to explicitly disable SSLv2Hello
+ // in OpenSSL so it is always enabled
+ enabled.add(Constants.SSL_PROTO_SSLv2Hello);
+ if ((opts & SSL_OP_NO_TLSv1()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1);
+ }
+ if ((opts & SSL_OP_NO_TLSv1_1()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1_1);
+ }
+ if ((opts & SSL_OP_NO_TLSv1_2()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1_2);
+ }
+ if ((opts & SSL_OP_NO_TLSv1_3()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1_3);
+ }
+ if ((opts & SSL_OP_NO_SSLv2()) == 0) {
+ enabled.add(Constants.SSL_PROTO_SSLv2);
+ }
+ if ((opts & SSL_OP_NO_SSLv3()) == 0) {
+ enabled.add(Constants.SSL_PROTO_SSLv3);
+ }
+ sslHostConfig.setEnabledProtocols(
+ enabled.toArray(new String[0]));
+ // Reconfigure the enabled ciphers
+ sslHostConfig.setEnabledCiphers(getCiphers(state.sslCtx));
+ }
+
+ sessionContext = new OpenSSLSessionContext(this);
+ // If client authentication is being used, OpenSSL requires that
+ // this is set so always set it in case an app is configured to
+ // require it
+ sessionContext.setSessionIdContext(DEFAULT_SESSION_ID_CONTEXT);
+ sslHostConfig.setOpenSslContext(state.sslCtx.address());
+ initialized = true;
+ } catch (Exception e) {
+ log.warn(sm.getString("openssl.errorSSLCtxInit"), e);
+ destroy();
+ }
+ }
+
+
+ public MemorySegment getSSLContext() {
+ return state.sslCtx;
+ }
+
+ // DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength)
+ public static MemorySegment openSSLCallbackTmpDH(MemorySegment ssl, int isExport, int keylength) {
+ var pkey = SSL_get_privatekey(ssl);
+ int type = (MemorySegment.NULL.equals(pkey)) ? EVP_PKEY_NONE()
+ : (OPENSSL_3 ? EVP_PKEY_get_base_id(pkey) : EVP_PKEY_base_id(pkey));
+ /*
+ * OpenSSL will call us with either keylen == 512 or keylen == 1024
+ * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
+ * Adjust the DH parameter length according to the size of the
+ * RSA/DSA private key used for the current connection, and always
+ * use at least 1024-bit parameters.
+ * Note: This may cause interoperability issues with implementations
+ * which limit their DH support to 1024 bit - e.g. Java 7 and earlier.
+ * In this case, SSLCertificateFile can be used to specify fixed
+ * 1024-bit DH parameters (with the effect that OpenSSL skips this
+ * callback).
+ */
+ int keylen = 0;
+ if ((type == EVP_PKEY_RSA()) || (type == EVP_PKEY_DSA())) {
+ keylen = (OPENSSL_3 ? EVP_PKEY_get_bits(pkey) : EVP_PKEY_bits(pkey));
+ }
+ for (int i = 0; i < OpenSSLLifecycleListener.dhParameters.length; i++) {
+ if (keylen >= OpenSSLLifecycleListener.dhParameters[i].min) {
+ return OpenSSLLifecycleListener.dhParameters[i].dh;
+ }
+ }
+ return MemorySegment.NULL;
+ }
+
+ // int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned char *outlen,
+ // const unsigned char *in, unsigned int inlen, void *arg)
+ public static int openSSLCallbackAlpnSelectProto(MemorySegment ssl, MemorySegment out, MemorySegment outlen,
+ MemorySegment in, int inlen, MemorySegment arg) {
+ ContextState state = getState(arg);
+ if (state == null) {
+ log.warn(sm.getString("context.noSSL", Long.valueOf(arg.address())));
+ return SSL_TLSEXT_ERR_NOACK();
+ }
+ try (var localArena = Arena.ofConfined()) {
+ MemorySegment inSeg = in.reinterpret(inlen, localArena, null);
+ byte[] advertisedBytes = inSeg.toArray(ValueLayout.JAVA_BYTE);
+ for (byte[] negotiableProtocolBytes : state.negotiableProtocols) {
+ for (int i = 0; i <= advertisedBytes.length - negotiableProtocolBytes.length; i++) {
+ if (advertisedBytes[i] == negotiableProtocolBytes[0]) {
+ for (int j = 0; j < negotiableProtocolBytes.length; j++) {
+ if (advertisedBytes[i + j] == negotiableProtocolBytes[j]) {
+ if (j == negotiableProtocolBytes.length - 1) {
+ // Match
+ MemorySegment outSeg = out.reinterpret(ValueLayout.ADDRESS.byteSize(), localArena, null);
+ outSeg.set(ValueLayout.ADDRESS, 0, inSeg.asSlice(i));
+ MemorySegment outlenSeg = outlen.reinterpret(ValueLayout.JAVA_BYTE.byteSize(), localArena, null);
+ outlenSeg.set(ValueLayout.JAVA_BYTE, 0, (byte) negotiableProtocolBytes.length);
+ return SSL_TLSEXT_ERR_OK();
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return SSL_TLSEXT_ERR_NOACK();
+ }
+
+ public static int openSSLCallbackVerify(int preverify_ok, MemorySegment /*X509_STORE_CTX*/ x509ctx) {
+ return OpenSSLEngine.openSSLCallbackVerify(preverify_ok, x509ctx);
+ }
+
+
+ public static int openSSLCallbackCertVerify(MemorySegment /*X509_STORE_CTX*/ x509_ctx, MemorySegment param) {
+ if (log.isDebugEnabled()) {
+ log.debug("Certificate verification");
+ }
+ if (MemorySegment.NULL.equals(param)) {
+ return 0;
+ }
+ ContextState state = getState(param);
+ if (state == null) {
+ log.warn(sm.getString("context.noSSL", Long.valueOf(param.address())));
+ return 0;
+ }
+ MemorySegment ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+ MemorySegment /*STACK_OF(X509)*/ sk = X509_STORE_CTX_get0_untrusted(x509_ctx);
+ int len = OPENSSL_sk_num(sk);
+ byte[][] certificateChain = new byte[len][];
+ try (var localArena = Arena.ofConfined()) {
+ for (int i = 0; i < len; i++) {
+ MemorySegment/*(X509*)*/ x509 = OPENSSL_sk_value(sk, i);
+ MemorySegment bufPointer = localArena.allocate(ValueLayout.ADDRESS, MemorySegment.NULL);
+ int length = i2d_X509(x509, bufPointer);
+ if (length < 0) {
+ certificateChain[i] = new byte[0];
+ continue;
+ }
+ MemorySegment buf = bufPointer.get(ValueLayout.ADDRESS, 0);
+ certificateChain[i] = buf.reinterpret(length, localArena, null).toArray(ValueLayout.JAVA_BYTE);
+ CRYPTO_free(buf, MemorySegment.NULL, 0); // OPENSSL_free macro
+ }
+ MemorySegment cipher = SSL_get_current_cipher(ssl);
+ String authMethod = (MemorySegment.NULL.equals(cipher)) ? "UNKNOWN"
+ : getCipherAuthenticationMethod(SSL_CIPHER_get_auth_nid(cipher), SSL_CIPHER_get_kx_nid(cipher));
+ X509Certificate[] peerCerts = certificates(certificateChain);
+ try {
+ state.x509TrustManager.checkClientTrusted(peerCerts, authMethod);
+ return 1;
+ } catch (Exception e) {
+ log.debug(sm.getString("openssl.certificateVerificationFailed"), e);
+ }
+ }
+ return 0;
+ }
+
+ private static final int NID_kx_rsa = 1037/*NID_kx_rsa()*/;
+ //private static final int NID_kx_dhe = NID_kx_dhe();
+ //private static final int NID_kx_ecdhe = NID_kx_ecdhe();
+
+ //private static final int NID_auth_rsa = NID_auth_rsa();
+ //private static final int NID_auth_dss = NID_auth_dss();
+ //private static final int NID_auth_null = NID_auth_null();
+ //private static final int NID_auth_ecdsa = NID_auth_ecdsa();
+
+ //private static final int SSL_kRSA = 1;
+ private static final int SSL_kDHr = 2;
+ private static final int SSL_kDHd = 4;
+ private static final int SSL_kEDH = 8;
+ private static final int SSL_kDHE = SSL_kEDH;
+ private static final int SSL_kKRB5 = 10;
+ private static final int SSL_kECDHr = 20;
+ private static final int SSL_kECDHe = 40;
+ private static final int SSL_kEECDH = 80;
+ private static final int SSL_kECDHE = SSL_kEECDH;
+ //private static final int SSL_kPSK = 100;
+ //private static final int SSL_kGOST = 200;
+ //private static final int SSL_kSRP = 400;
+
+ private static final int SSL_aRSA = 1;
+ private static final int SSL_aDSS = 2;
+ private static final int SSL_aNULL = 4;
+ //private static final int SSL_aDH = 8;
+ //private static final int SSL_aECDH = 10;
+ //private static final int SSL_aKRB5 = 20;
+ private static final int SSL_aECDSA = 40;
+ //private static final int SSL_aPSK = 80;
+ //private static final int SSL_aGOST94 = 100;
+ //private static final int SSL_aGOST01 = 200;
+ //private static final int SSL_aSRP = 400;
+
+ private static final String SSL_TXT_RSA = "RSA";
+ private static final String SSL_TXT_DH = "DH";
+ private static final String SSL_TXT_DSS = "DSS";
+ private static final String SSL_TXT_KRB5 = "KRB5";
+ private static final String SSL_TXT_ECDH = "ECDH";
+ private static final String SSL_TXT_ECDSA = "ECDSA";
+
+ private static String getCipherAuthenticationMethod(int auth, int kx) {
+ switch (kx) {
+ case NID_kx_rsa:
+ return SSL_TXT_RSA;
+ case SSL_kDHr:
+ return SSL_TXT_DH + "_" + SSL_TXT_RSA;
+ case SSL_kDHd:
+ return SSL_TXT_DH + "_" + SSL_TXT_DSS;
+ case SSL_kDHE:
+ switch (auth) {
+ case SSL_aDSS:
+ return "DHE_" + SSL_TXT_DSS;
+ case SSL_aRSA:
+ return "DHE_" + SSL_TXT_RSA;
+ case SSL_aNULL:
+ return SSL_TXT_DH + "_anon";
+ default:
+ return "UNKNOWN";
+ }
+ case SSL_kKRB5:
+ return SSL_TXT_KRB5;
+ case SSL_kECDHr:
+ return SSL_TXT_ECDH + "_" + SSL_TXT_RSA;
+ case SSL_kECDHe:
+ return SSL_TXT_ECDH + "_" + SSL_TXT_ECDSA;
+ case SSL_kECDHE:
+ switch (auth) {
+ case SSL_aECDSA:
+ return "ECDHE_" + SSL_TXT_ECDSA;
+ case SSL_aRSA:
+ return "ECDHE_" + SSL_TXT_RSA;
+ case SSL_aNULL:
+ return SSL_TXT_ECDH + "_anon";
+ default:
+ return "UNKNOWN";
+ }
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ private static ThreadLocal<String> callbackPasswordTheadLocal = new ThreadLocal<>();
+
+ public static int openSSLCallbackPassword(MemorySegment /*char **/ buf, int bufsiz, int verify, MemorySegment /*void **/ cb) {
+ if (log.isDebugEnabled()) {
+ log.debug("Return password for certificate");
+ }
+ String callbackPassword = callbackPasswordTheadLocal.get();
+ if (callbackPassword != null && callbackPassword.length() > 0) {
+ try (var localArena = Arena.ofConfined()) {
+ MemorySegment callbackPasswordNative = localArena.allocateUtf8String(callbackPassword);
+ if (callbackPasswordNative.byteSize() > bufsiz) {
+ // The password is too long
+ log.error(sm.getString("openssl.passwordTooLong"));
+ } else {
+ MemorySegment bufSegment = buf.reinterpret(bufsiz, localArena, null);
+ bufSegment.copyFrom(callbackPasswordNative);
+ return (int) callbackPasswordNative.byteSize();
+ }
+ }
+ }
+ return 0;
+ }
+
+
+ private void addCertificate(SSLHostConfigCertificate certificate, Arena localArena) throws Exception {
+ int index = getCertificateIndex(certificate);
+ // Load Server key and certificate
+ if (certificate.getCertificateFile() != null) {
+ // Set certificate
+ //SSLContext.setCertificate(state.ctx,
+ // SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()),
+ // SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()),
+ // certificate.getCertificateKeyPassword(), getCertificateIndex(certificate));
+ var certificateFileNative = localArena.allocateUtf8String(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()));
+ var certificateKeyFileNative = (certificate.getCertificateKeyFile() == null) ? certificateFileNative
+ : localArena.allocateUtf8String(SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()));
+ MemorySegment bio;
+ MemorySegment cert = MemorySegment.NULL;
+ MemorySegment key = MemorySegment.NULL;
+ if (certificate.getCertificateFile().endsWith(".pkcs12")) {
+ // Load pkcs12
+ bio = BIO_new(BIO_s_file());
+ //# define BIO_read_filename(b,name)
+ // (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
+ if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
+ BIO_free(bio);
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[0]:" + certificate.getCertificateFile()));
+ return;
+ }
+ MemorySegment p12 = d2i_PKCS12_bio(bio, MemorySegment.NULL);
+ BIO_free(bio);
+ if (MemorySegment.NULL.equals(p12)) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[1]:" + certificate.getCertificateFile()));
+ return;
+ }
+ MemorySegment passwordAddress = MemorySegment.NULL;
+ int passwordLength = 0;
+ String callbackPassword = certificate.getCertificateKeyPassword();
+ if (callbackPassword != null && callbackPassword.length() > 0) {
+ passwordAddress = localArena.allocateUtf8String(callbackPassword);
+ passwordLength = (int) (passwordAddress.byteSize() - 1);
+ }
+ if (PKCS12_verify_mac(p12, passwordAddress, passwordLength) <= 0) {
+ // Bad password
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[2]:" + certificate.getCertificateFile()));
+ PKCS12_free(p12);
+ return;
+ }
+ MemorySegment certPointer = localArena.allocate(ValueLayout.ADDRESS);
+ MemorySegment keyPointer = localArena.allocate(ValueLayout.ADDRESS);
+ if (PKCS12_parse(p12, passwordAddress, keyPointer, certPointer, MemorySegment.NULL) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[3]:" + certificate.getCertificateFile()));
+ PKCS12_free(p12);
+ return;
+ }
+ PKCS12_free(p12);
+ cert = certPointer.get(ValueLayout.ADDRESS, 0);
+ key = keyPointer.get(ValueLayout.ADDRESS, 0);
+ } else {
+ // Load key
+ bio = BIO_new(BIO_s_file());
+ //# define BIO_read_filename(b,name)
+ // (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
+ if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateKeyFileNative) <= 0) {
+ BIO_free(bio);
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
+ return;
+ }
+ key = MemorySegment.NULL;
+ for (int i = 0; i < 3; i++) {
+ try {
+ callbackPasswordTheadLocal.set(certificate.getCertificateKeyPassword());
+ key = PEM_read_bio_PrivateKey(bio, MemorySegment.NULL, openSSLCallbackPassword, MemorySegment.NULL);
+ } finally {
+ callbackPasswordTheadLocal.set(null);
+ }
+ if (!MemorySegment.NULL.equals(key)) {
+ break;
+ }
+ BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemorySegment.NULL);
+ }
+ BIO_free(bio);
+ if (MemorySegment.NULL.equals(key)) {
+ if (!MemorySegment.NULL.equals(OpenSSLLifecycleListener.enginePointer)) {
+ key = ENGINE_load_private_key(OpenSSLLifecycleListener.enginePointer, certificateKeyFileNative,
+ MemorySegment.NULL, MemorySegment.NULL);
+ }
+ }
+ if (MemorySegment.NULL.equals(key)) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
+ return;
+ }
+ // Load certificate
+ bio = BIO_new(BIO_s_file());
+ if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
+ BIO_free(bio);
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
+ return;
+ }
+ try {
+ callbackPasswordTheadLocal.set(certificate.getCertificateKeyPassword());
+ cert = PEM_read_bio_X509_AUX(bio, MemorySegment.NULL, openSSLCallbackPassword, MemorySegment.NULL);
+ } finally {
+ callbackPasswordTheadLocal.set(null);
+ }
+ if (MemorySegment.NULL.equals(cert) &&
+ // Missing ERR_GET_REASON(ERR_peek_last_error())
+ /*int ERR_GET_REASON(unsigned long errcode) {
+ * if (ERR_SYSTEM_ERROR(errcode))
+ * return errcode & ERR_SYSTEM_MASK;
+ * return errcode & ERR_REASON_MASK;
+ *}
+ *# define ERR_SYSTEM_ERROR(errcode) (((errcode) & ERR_SYSTEM_FLAG) != 0)
+ *# define ERR_SYSTEM_FLAG ((unsigned int)INT_MAX + 1)
+ *# define ERR_SYSTEM_MASK ((unsigned int)INT_MAX)
+ *# define ERR_REASON_MASK 0X7FFFFF
+ */
+ ((ERR_peek_last_error() & 0X7FFFFF) == PEM_R_NO_START_LINE())) {
+ ERR_clear_error();
+ BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemorySegment.NULL);
+ cert = d2i_X509_bio(bio, MemorySegment.NULL);
+ }
+ BIO_free(bio);
+ if (MemorySegment.NULL.equals(cert)) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
+ return;
+ }
+ }
+ if (SSL_CTX_use_certificate(state.sslCtx, cert) <= 0) {
+ logLastError(localArena, "openssl.errorLoadingCertificate");
+ return;
+ }
+ if (SSL_CTX_use_PrivateKey(state.sslCtx, key) <= 0) {
+ logLastError(localArena, "openssl.errorLoadingPrivateKey");
+ return;
+ }
+ if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
+ logLastError(localArena, "openssl.errorPrivateKeyCheck");
+ return;
+ }
+ // Try to read DH parameters from the (first) SSLCertificateFile
+ if (index == SSL_AIDX_RSA) {
+ bio = BIO_new_file(certificateFileNative, localArena.allocateUtf8String("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);
+ }
+ }
+ // Similarly, try to read the ECDH curve name from SSLCertificateFile...
+ bio = BIO_new_file(certificateFileNative, localArena.allocateUtf8String("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);
+ }
+ // 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 =
+ localArena.allocateUtf8String(SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()));
+ // SSLContext.setCertificateChainFile(state.ctx,
+ // SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false);
+ if (SSL_CTX_use_certificate_chain_file(state.sslCtx, certificateChainFileNative) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateChainFile()));
+ }
+ }
+ // Set revocation
+ //SSLContext.setCARevocation(state.ctx,
+ // SSLHostConfig.adjustRelativePath(
+ // sslHostConfig.getCertificateRevocationListFile()),
+ // SSLHostConfig.adjustRelativePath(
+ // sslHostConfig.getCertificateRevocationListPath()));
+ MemorySegment certificateStore = SSL_CTX_get_cert_store(state.sslCtx);
+ if (sslHostConfig.getCertificateRevocationListFile() != null) {
+ MemorySegment x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_file());
+ var certificateRevocationListFileNative =
+ localArena.allocateUtf8String(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()));
+ //X509_LOOKUP_ctrl(lookup,X509_L_FILE_LOAD,file,type,NULL)
+ if (X509_LOOKUP_ctrl(x509Lookup, X509_L_FILE_LOAD(), certificateRevocationListFileNative,
+ X509_FILETYPE_PEM(), MemorySegment.NULL) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListFile()));
+ }
+ }
+ if (sslHostConfig.getCertificateRevocationListPath() != null) {
+ MemorySegment x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_hash_dir());
+ var certificateRevocationListPathNative =
+ localArena.allocateUtf8String(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()));
+ //X509_LOOKUP_ctrl(lookup,X509_L_ADD_DIR,path,type,NULL)
+ if (X509_LOOKUP_ctrl(x509Lookup, X509_L_ADD_DIR(), certificateRevocationListPathNative,
+ X509_FILETYPE_PEM(), MemorySegment.NULL) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListPath()));
+ }
+ }
+ X509_STORE_set_flags(certificateStore, X509_V_FLAG_CRL_CHECK() | X509_V_FLAG_CRL_CHECK_ALL());
+ } else {
+ String alias = certificate.getCertificateKeyAlias();
+ X509KeyManager x509KeyManager = certificate.getCertificateKeyManager();
+ if (alias == null) {
+ alias = "tomcat";
+ }
+ X509Certificate[] chain = x509KeyManager.getCertificateChain(alias);
+ if (chain == null) {
+ alias = findAlias(x509KeyManager, certificate);
+ chain = x509KeyManager.getCertificateChain(alias);
+ }
+ PrivateKey key = x509KeyManager.getPrivateKey(alias);
+ StringBuilder sb = new StringBuilder(BEGIN_KEY);
+ sb.append(Base64.getMimeEncoder(64, new byte[] {'\n'}).encodeToString(key.getEncoded()));
+ sb.append(END_KEY);
+ //SSLContext.setCertificateRaw(state.ctx, chain[0].getEncoded(),
+ // sb.toString().getBytes(StandardCharsets.US_ASCII),
+ // getCertificateIndex(certificate));
+ var rawCertificate = localArena.allocateArray(ValueLayout.JAVA_BYTE, chain[0].getEncoded());
+ var rawCertificatePointer = localArena.allocate(ValueLayout.ADDRESS, rawCertificate);
+ var rawKey = localArena.allocateArray(ValueLayout.JAVA_BYTE, sb.toString().getBytes(StandardCharsets.US_ASCII));
+ var x509cert = d2i_X509(MemorySegment.NULL, rawCertificatePointer, rawCertificate.byteSize());
+ if (MemorySegment.NULL.equals(x509cert)) {
+ logLastError(localArena, "openssl.errorLoadingCertificate");
+ return;
+ }
+ var bio = BIO_new(BIO_s_mem());
+ BIO_write(bio, rawKey, (int) rawKey.byteSize());
+ MemorySegment privateKeyAddress = PEM_read_bio_PrivateKey(bio, MemorySegment.NULL, MemorySegment.NULL, MemorySegment.NULL);
+ BIO_free(bio);
+ if (MemorySegment.NULL.equals(privateKeyAddress)) {
+ logLastError(localArena, "openssl.errorLoadingPrivateKey");
+ return;
+ }
+ if (SSL_CTX_use_certificate(state.sslCtx, x509cert) <= 0) {
+ logLastError(localArena, "openssl.errorLoadingCertificate");
+ return;
+ }
+ if (SSL_CTX_use_PrivateKey(state.sslCtx, privateKeyAddress) <= 0) {
+ logLastError(localArena, "openssl.errorLoadingPrivateKey");
+ return;
+ }
+ if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
+ 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);
+ for (int i = 1; i < chain.length; i++) {
+ //SSLContext.addChainCertificateRaw(state.ctx, chain[i].getEncoded());
+ var rawCertificateChain = localArena.allocateArray(ValueLayout.JAVA_BYTE, chain[i].getEncoded());
+ var rawCertificateChainPointer = localArena.allocate(ValueLayout.ADDRESS, rawCertificateChain);
+ var x509certChain = d2i_X509(MemorySegment.NULL, rawCertificateChainPointer, rawCertificateChain.byteSize());
+ if (MemorySegment.NULL.equals(x509certChain)) {
+ logLastError(localArena, "openssl.errorLoadingCertificate");
+ return;
+ }
+ // # define SSL_CTX_add0_chain_cert(sslCtx,x509) SSL_CTX_ctrl(sslCtx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
+ if (SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_CHAIN_CERT(), 0, x509certChain) <= 0) {
+ logLastError(localArena, "openssl.errorAddingCertificate");
+ return;
+ }
+ }
+ }
+ }
+
+
+ private static int getCertificateIndex(SSLHostConfigCertificate certificate) {
+ int result = -1;
+ // If the type is undefined there will only be one certificate (enforced
+ // in SSLHostConfig) so use the RSA slot.
+ if (certificate.getType() == Type.RSA || certificate.getType() == Type.UNDEFINED) {
+ result = SSL_AIDX_RSA;
+ } else if (certificate.getType() == Type.EC) {
+ result = SSL_AIDX_ECC;
+ } else if (certificate.getType() == Type.DSA) {
+ result = SSL_AIDX_DSA;
+ } else {
+ result = SSL_AIDX_MAX;
+ }
+ return result;
+ }
+
+
+ /*
+ * Find a valid alias when none was specified in the config.
+ */
+ private static String findAlias(X509KeyManager keyManager,
+ SSLHostConfigCertificate certificate) {
+
+ Type type = certificate.getType();
+ String result = null;
+
+ List<Type> candidateTypes = new ArrayList<>();
+ if (Type.UNDEFINED.equals(type)) {
+ // Try all types to find an suitable alias
+ candidateTypes.addAll(Arrays.asList(Type.values()));
+ candidateTypes.remove(Type.UNDEFINED);
+ } else {
+ // Look for the specific type to find a suitable alias
+ candidateTypes.add(type);
+ }
+
+ Iterator<Type> iter = candidateTypes.iterator();
+ while (result == null && iter.hasNext()) {
+ result = keyManager.chooseServerAlias(iter.next().toString(), null, null);
+ }
+
+ return result;
+ }
+
+ private static X509TrustManager chooseTrustManager(TrustManager[] managers) {
+ for (TrustManager m : managers) {
+ if (m instanceof X509TrustManager) {
+ return (X509TrustManager) m;
+ }
+ }
+ throw new IllegalStateException(sm.getString("openssl.trustManagerMissing"));
+ }
+
+ private static X509Certificate[] certificates(byte[][] chain) {
+ X509Certificate[] peerCerts = new X509Certificate[chain.length];
+ for (int i = 0; i < peerCerts.length; i++) {
+ peerCerts[i] = new OpenSSLX509Certificate(chain[i]);
+ }
+ return peerCerts;
+ }
+
+
+ private static void logLastError(SegmentAllocator allocator, String string) {
+ var buf = allocator.allocateArray(ValueLayout.JAVA_BYTE, new byte[128]);
+ ERR_error_string(ERR_get_error(), buf);
+ String err = buf.getUtf8String(0);
+ log.error(sm.getString(string, err));
+ }
+
+
+ @Override
+ public SSLSessionContext getServerSessionContext() {
+ return sessionContext;
+ }
+
+ @Override
+ public synchronized SSLEngine createSSLEngine() {
+ return new OpenSSLEngine(cleaner, state.sslCtx, defaultProtocol, false, sessionContext,
+ alpn, initialized,
+ sslHostConfig.getCertificateVerificationDepth(),
+ sslHostConfig.getCertificateVerification() == CertificateVerification.OPTIONAL_NO_CA,
+ noOcspCheck);
+ }
+
+ @Override
+ public SSLServerSocketFactory getServerSocketFactory() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SSLParameters getSupportedSSLParameters() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public X509Certificate[] getCertificateChain(String alias) {
+ X509Certificate[] chain = null;
+ X509KeyManager x509KeyManager = certificate.getCertificateKeyManager();
+ if (x509KeyManager != null) {
+ if (alias == null) {
+ alias = "tomcat";
+ }
+ chain = x509KeyManager.getCertificateChain(alias);
+ if (chain == null) {
+ alias = findAlias(x509KeyManager, certificate);
+ chain = x509KeyManager.getCertificateChain(alias);
+ }
+ }
+
+ return chain;
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ X509Certificate[] acceptedCerts = null;
+ if (state.x509TrustManager != null) {
+ acceptedCerts = state.x509TrustManager.getAcceptedIssuers();
+ }
+ return acceptedCerts;
+ }
+
+
+ private static class ContextState implements Runnable {
+
+ private final Arena stateArena = Arena.ofShared();
+ private final MemorySegment sslCtx;
+ private final MemorySegment confCtx;
+ private final List<byte[]> negotiableProtocols;
+
+ private X509TrustManager x509TrustManager = null;
+
+ private ContextState(MemorySegment sslCtx, MemorySegment confCtx, List<byte[]> negotiableProtocols) {
+ states.put(Long.valueOf(sslCtx.address()), this);
+ this.negotiableProtocols = negotiableProtocols;
+ // Use another arena to avoid keeping a reference through segments
+ // This also allows making further accesses to the main pointers safer
+ this.sslCtx = sslCtx.reinterpret(ValueLayout.ADDRESS.byteSize(), stateArena, null);
+ if (!MemorySegment.NULL.equals(confCtx)) {
+ this.confCtx = confCtx.reinterpret(ValueLayout.ADDRESS.byteSize(), stateArena, null);
+ } else {
+ this.confCtx = null;
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ states.remove(Long.valueOf(sslCtx.address()));
+ SSL_CTX_free(sslCtx);
+ if (confCtx != null) {
+ SSL_CONF_CTX_free(confCtx);
+ }
+ } finally {
+ stateArena.close();
+ }
+ }
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
new file mode 100644
index 0000000000..b7e6c15578
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -0,0 +1,1797 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.lang.foreign.Arena;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.Linker;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.ValueLayout;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.ref.Cleaner;
+import java.lang.ref.Cleaner.Cleanable;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSessionContext;
+
+import static org.apache.tomcat.util.openssl.openssl_compat_h.*;
+import static org.apache.tomcat.util.openssl.openssl_h.*;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.buf.Asn1Parser;
+import org.apache.tomcat.util.net.Constants;
+import org.apache.tomcat.util.net.SSLUtil;
+import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser;
+import org.apache.tomcat.util.res.StringManager;
+
+/**
+ * Implements a {@link SSLEngine} using
+ * <a href="https://www.openssl.org/docs/crypto/BIO_s_bio.html#EXAMPLE">OpenSSL
+ * BIO abstractions</a>.
+ */
+public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolInfo {
+
+ private static final Log log = LogFactory.getLog(OpenSSLEngine.class);
+ private static final StringManager sm = StringManager.getManager(OpenSSLEngine.class);
+
+ private static final Certificate[] EMPTY_CERTIFICATES = new Certificate[0];
+
+ public static final Set<String> AVAILABLE_CIPHER_SUITES;
+
+ public static final Set<String> IMPLEMENTED_PROTOCOLS_SET;
+
+ private static final MethodHandle openSSLCallbackInfoHandle;
+ private static final MethodHandle openSSLCallbackVerifyHandle;
+
+ private static final FunctionDescriptor openSSLCallbackInfoFunctionDescriptor =
+ FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT);
+ private static final FunctionDescriptor openSSLCallbackVerifyFunctionDescriptor =
+ FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
+
+ static {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ try {
+ openSSLCallbackInfoHandle = lookup.findStatic(OpenSSLEngine.class, "openSSLCallbackInfo",
+ MethodType.methodType(void.class, MemorySegment.class, int.class, int.class));
+ openSSLCallbackVerifyHandle = lookup.findStatic(OpenSSLEngine.class, "openSSLCallbackVerify",
+ MethodType.methodType(int.class, int.class, MemorySegment.class));
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ OpenSSLLifecycleListener.initLibrary();
+
+ final Set<String> availableCipherSuites = new LinkedHashSet<>(128);
+ try (var localArena = Arena.ofConfined()) {
+ var sslCtx = SSL_CTX_new(TLS_server_method());
+ try {
+ SSL_CTX_set_options(sslCtx, SSL_OP_ALL());
+ SSL_CTX_set_cipher_list(sslCtx, localArena.allocateUtf8String("ALL"));
+ var ssl = SSL_new(sslCtx);
+ SSL_set_accept_state(ssl);
+ try {
+ for (String c : getCiphers(ssl)) {
+ // Filter out bad input.
+ if (c == null || c.length() == 0 || availableCipherSuites.contains(c)) {
+ continue;
+ }
+ availableCipherSuites.add(OpenSSLCipherConfigurationParser.openSSLToJsse(c));
+ }
+ } finally {
+ SSL_free(ssl);
+ }
+ } finally {
+ SSL_CTX_free(sslCtx);
+ }
+ } catch (Exception e) {
+ log.warn(sm.getString("engine.ciphersFailure"), e);
+ }
+ AVAILABLE_CIPHER_SUITES = Collections.unmodifiableSet(availableCipherSuites);
+
+ HashSet<String> protocols = new HashSet<>();
+ protocols.add(Constants.SSL_PROTO_SSLv2Hello);
+ protocols.add(Constants.SSL_PROTO_SSLv2);
+ protocols.add(Constants.SSL_PROTO_SSLv3);
+ protocols.add(Constants.SSL_PROTO_TLSv1);
+ protocols.add(Constants.SSL_PROTO_TLSv1_1);
+ protocols.add(Constants.SSL_PROTO_TLSv1_2);
+ protocols.add(Constants.SSL_PROTO_TLSv1_3);
+ IMPLEMENTED_PROTOCOLS_SET = Collections.unmodifiableSet(protocols);
+ }
+
+ private static String[] getCiphers(MemorySegment ssl) {
+ MemorySegment sk = SSL_get_ciphers(ssl);
+ int len = OPENSSL_sk_num(sk);
+ if (len <= 0) {
+ return null;
+ }
+ ArrayList<String> ciphers = new ArrayList<>(len);
+ for (int i = 0; i < len; i++) {
+ MemorySegment cipher = OPENSSL_sk_value(sk, i);
+ MemorySegment cipherName = SSL_CIPHER_get_name(cipher);
+ ciphers.add(cipherName.getUtf8String(0));
+ }
+ return ciphers.toArray(new String[0]);
+ }
+
+ private static final int MAX_PLAINTEXT_LENGTH = 16 * 1024; // 2^14
+ private static final int MAX_COMPRESSED_LENGTH = MAX_PLAINTEXT_LENGTH + 1024;
+ private static final int MAX_CIPHERTEXT_LENGTH = MAX_COMPRESSED_LENGTH + 1024;
+
+ // Protocols
+ static final int VERIFY_DEPTH = 10;
+
+ // Header (5) + Data (2^14) + Compression (1024) + Encryption (1024) + MAC (20) + Padding (256)
+ static final int MAX_ENCRYPTED_PACKET_LENGTH = MAX_CIPHERTEXT_LENGTH + 5 + 20 + 256;
+
+ static final int MAX_ENCRYPTION_OVERHEAD_LENGTH = MAX_ENCRYPTED_PACKET_LENGTH - MAX_PLAINTEXT_LENGTH;
+
+ enum ClientAuthMode {
+ NONE,
+ OPTIONAL,
+ REQUIRE,
+ }
+
+ private static final String INVALID_CIPHER = "SSL_NULL_WITH_NULL_NULL";
+
+ private static final ConcurrentHashMap<Long, EngineState> states = new ConcurrentHashMap<>();
+ private static EngineState getState(MemorySegment ssl) {
+ return states.get(Long.valueOf(ssl.address()));
+ }
+
+ private final EngineState state;
+ private final Arena engineArena;
+ private final Cleanable cleanable;
+ private MemorySegment bufSegment = null;
+
+ private enum Accepted { NOT, IMPLICIT, EXPLICIT }
+ private Accepted accepted = Accepted.NOT;
+ private enum PHAState { NONE, START, COMPLETE }
+ private boolean handshakeFinished;
+ private int currentHandshake;
+ private boolean receivedShutdown;
+ private volatile boolean destroyed;
+
+ // Use an invalid cipherSuite until the handshake is completed
+ // See http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLEngine.html#getSession()
+ private volatile String version;
+ private volatile String cipher;
+ private volatile String applicationProtocol;
+
+ private volatile Certificate[] peerCerts;
+ private volatile ClientAuthMode clientAuth = ClientAuthMode.NONE;
+
+ // SSL Engine status variables
+ private boolean isInboundDone;
+ private boolean isOutboundDone;
+ private boolean engineClosed;
+ private boolean sendHandshakeError = false;
+
+ private final boolean clientMode;
+ private final String fallbackApplicationProtocol;
+ private final OpenSSLSessionContext sessionContext;
+ private final boolean alpn;
+ private final boolean initialized;
+ private final boolean certificateVerificationOptionalNoCA;
+
+ private String selectedProtocol = null;
+
+ private final OpenSSLSession session;
+
+ /**
+ * Creates a new instance
+ *
+ * @param sslCtx an OpenSSL {@code SSL_CTX} object
+ * @param fallbackApplicationProtocol the fallback application protocol
+ * @param clientMode {@code true} if this is used for clients, {@code false}
+ * otherwise
+ * @param sessionContext the {@link OpenSSLSessionContext} this
+ * {@link SSLEngine} belongs to.
+ * @param alpn {@code true} if alpn should be used, {@code false}
+ * otherwise
+ * @param initialized {@code true} if this instance gets its protocol,
+ * cipher and client verification from the {@code SSL_CTX} {@code sslCtx}
+ * @param certificateVerificationDepth Certificate verification depth
+ * @param certificateVerificationOptionalNoCA Skip CA verification in
+ * optional mode
+ */
+ OpenSSLEngine(Cleaner cleaner, MemorySegment sslCtx, String fallbackApplicationProtocol,
+ boolean clientMode, OpenSSLSessionContext sessionContext, boolean alpn,
+ boolean initialized, int certificateVerificationDepth,
+ boolean certificateVerificationOptionalNoCA, boolean noOcspCheck) {
+ if (sslCtx == null) {
+ throw new IllegalArgumentException(sm.getString("engine.noSSLContext"));
+ }
+ engineArena = Arena.ofAuto();
+ bufSegment = engineArena.allocate(MAX_ENCRYPTED_PACKET_LENGTH);
+ session = new OpenSSLSession();
+ var ssl = SSL_new(sslCtx);
+ // Set ssl_info_callback
+ var openSSLCallbackInfo = Linker.nativeLinker().upcallStub(openSSLCallbackInfoHandle,
+ openSSLCallbackInfoFunctionDescriptor, engineArena);
+ SSL_set_info_callback(ssl, openSSLCallbackInfo);
+ if (clientMode) {
+ SSL_set_connect_state(ssl);
+ } else {
+ SSL_set_accept_state(ssl);
+ }
+ SSL_set_verify_result(ssl, X509_V_OK());
+ try (var localArena = Arena.ofConfined()) {
+ var internalBIOPointer = localArena.allocate(ValueLayout.ADDRESS);
+ var networkBIOPointer = localArena.allocate(ValueLayout.ADDRESS);
+ BIO_new_bio_pair(internalBIOPointer, 0, networkBIOPointer, 0);
+ var internalBIO = internalBIOPointer.get(ValueLayout.ADDRESS, 0);
+ var networkBIO = networkBIOPointer.get(ValueLayout.ADDRESS, 0);
+ SSL_set_bio(ssl, internalBIO, internalBIO);
+ state = new EngineState(ssl, networkBIO, certificateVerificationDepth, noOcspCheck);
+ }
+ this.fallbackApplicationProtocol = fallbackApplicationProtocol;
+ this.clientMode = clientMode;
+ this.sessionContext = sessionContext;
+ this.alpn = alpn;
+ this.initialized = initialized;
+ this.certificateVerificationOptionalNoCA = certificateVerificationOptionalNoCA;
+ cleanable = cleaner.register(this, state);
+ }
+
+ @Override
+ public String getNegotiatedProtocol() {
+ return selectedProtocol;
+ }
+
+ /**
+ * Destroys this engine.
+ */
+ public synchronized void shutdown() {
+ if (!destroyed) {
+ destroyed = true;
+ cleanable.clean();
+ // internal errors can cause shutdown without marking the engine closed
+ isInboundDone = isOutboundDone = engineClosed = true;
+ bufSegment = null;
+ }
+ }
+
+ /**
+ * Write plain text data to the OpenSSL internal BIO
+ *
+ * Calling this function with src.remaining == 0 is undefined.
+ * @throws SSLException if the OpenSSL error check fails
+ */
+ private int writePlaintextData(final MemorySegment ssl, final ByteBuffer src) throws SSLException {
+ clearLastError();
+ final int pos = src.position();
+ final int len = Math.min(src.remaining(), MAX_PLAINTEXT_LENGTH);
+ MemorySegment srcSegment = src.isDirect() ? MemorySegment.ofBuffer(src) : bufSegment;
+ if (!src.isDirect()) {
+ MemorySegment.copy(src.array(), pos, bufSegment, ValueLayout.JAVA_BYTE, 0, len);
+ }
+ final int sslWrote = SSL_write(ssl, srcSegment, len);
+ if (sslWrote > 0) {
+ src.position(pos + sslWrote);
+ return sslWrote;
+ } else {
+ checkLastError();
+ }
+ return 0;
+ }
+
+ /**
+ * Write encrypted data to the OpenSSL network BIO.
+ * @throws SSLException if the OpenSSL error check fails
+ */
+ private int writeEncryptedData(final MemorySegment networkBIO, final ByteBuffer src) throws SSLException {
+ clearLastError();
+ final int pos = src.position();
+ final int len = src.remaining();
+ MemorySegment srcSegment = src.isDirect() ? MemorySegment.ofBuffer(src) : bufSegment;
+ if (!src.isDirect()) {
+ MemorySegment.copy(src.array(), pos, bufSegment, ValueLayout.JAVA_BYTE, 0, len);
+ }
+ final int netWrote = BIO_write(networkBIO, srcSegment, len);
+ if (netWrote > 0) {
+ src.position(pos + netWrote);
+ return netWrote;
+ } else {
+ checkLastError();
+ }
+ return 0;
+ }
+
+ /**
+ * Read plain text data from the OpenSSL internal BIO
+ * @throws SSLException if the OpenSSL error check fails
+ */
+ private int readPlaintextData(final MemorySegment ssl, final ByteBuffer dst) throws SSLException {
+ clearLastError();
+ final int pos = dst.position();
+ final int len = Math.min(dst.remaining(), MAX_ENCRYPTED_PACKET_LENGTH);
+ MemorySegment dstSegment = dst.isDirect() ? MemorySegment.ofBuffer(dst) : bufSegment;
+ final int sslRead = SSL_read(ssl, dstSegment, len);
+ if (sslRead > 0) {
+ if (!dst.isDirect()) {
+ MemorySegment.copy(dstSegment, ValueLayout.JAVA_BYTE, 0, dst.array(), pos, sslRead);
+ }
+ dst.position(pos + sslRead);
+ return sslRead;
+ } else {
+ checkLastError();
+ }
+ return 0;
+ }
+
+ /**
+ * Read encrypted data from the OpenSSL network BIO
+ * @throws SSLException if the OpenSSL error check fails
+ */
+ private int readEncryptedData(final MemorySegment networkBIO, final ByteBuffer dst, final int pending) throws SSLException {
+ clearLastError();
+ final int pos = dst.position();
+ MemorySegment dstSegment = dst.isDirect() ? MemorySegment.ofBuffer(dst) : bufSegment;
+ final int bioRead = BIO_read(networkBIO, dstSegment, pending);
+ if (bioRead > 0) {
+ if (!dst.isDirect()) {
+ MemorySegment.copy(dstSegment, ValueLayout.JAVA_BYTE, 0, dst.array(), pos, bioRead);
+ }
+ dst.position(pos + bioRead);
+ return bioRead;
+ } else {
+ checkLastError();
+ }
+ return 0;
+ }
+
+ @Override
+ public synchronized SSLEngineResult wrap(final ByteBuffer[] srcs, final int offset, final int length, final ByteBuffer dst) throws SSLException {
+ // Check to make sure the engine has not been closed
+ if (destroyed) {
+ return new SSLEngineResult(SSLEngineResult.Status.CLOSED, SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0);
+ }
+
+ // Throw required runtime exceptions
+ if (srcs == null || dst == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullBuffer"));
+ }
+ if (offset >= srcs.length || offset + length > srcs.length) {
+ throw new IndexOutOfBoundsException(sm.getString("engine.invalidBufferArray",
+ Integer.toString(offset), Integer.toString(length),
+ Integer.toString(srcs.length)));
+ }
+ if (dst.isReadOnly()) {
+ throw new ReadOnlyBufferException();
+ }
+ // Prepare OpenSSL to work in server mode and receive handshake
+ if (accepted == Accepted.NOT) {
+ beginHandshakeImplicitly();
+ }
+
+ // In handshake or close_notify stages, check if call to wrap was made
+ // without regard to the handshake status.
+ SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
+
+ if ((!handshakeFinished || engineClosed) && handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
+ return new SSLEngineResult(getEngineStatus(), SSLEngineResult.HandshakeStatus.NEED_UNWRAP, 0, 0);
+ }
+
+ int bytesProduced = 0;
+ int pendingNet;
+
+ // Check for pending data in the network BIO
+ pendingNet = (int) BIO_ctrl_pending(state.networkBIO);
+ if (pendingNet > 0) {
+ // Do we have enough room in destination to write encrypted data?
+ int capacity = dst.remaining();
+ if (capacity < pendingNet) {
+ return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW, handshakeStatus, 0, 0);
+ }
+
+ // Write the pending data from the network BIO into the dst buffer
+ try {
+ bytesProduced = readEncryptedData(state.networkBIO, dst, pendingNet);
+ } catch (Exception e) {
+ throw new SSLException(e);
+ }
+
+ // If isOutboundDone is set, then the data from the network BIO
+ // was the close_notify message -- we are not required to wait
+ // for the receipt the peer's close_notify message -- shutdown.
+ if (isOutboundDone) {
+ shutdown();
+ }
+
+ return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(), 0, bytesProduced);
+ }
+
+ // There was no pending data in the network BIO -- encrypt any application data
+ int bytesConsumed = 0;
+ int endOffset = offset + length;
+ for (int i = offset; i < endOffset; ++i) {
+ final ByteBuffer src = srcs[i];
+ if (src == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullBufferInArray"));
+ }
+ while (src.hasRemaining()) {
+
+ int bytesWritten = 0;
+ // Write plain text application data to the SSL engine
+ try {
+ bytesWritten = writePlaintextData(state.ssl, src);
+ bytesConsumed += bytesWritten;
+ } catch (Exception e) {
+ throw new SSLException(e);
+ }
+
+ if (bytesWritten == 0) {
+ throw new IllegalStateException(sm.getString("engine.failedToWriteBytes"));
+ }
+
+ // Check to see if the engine wrote data into the network BIO
+ pendingNet = (int) BIO_ctrl_pending(state.networkBIO);
+ if (pendingNet > 0) {
+ // Do we have enough room in dst to write encrypted data?
+ int capacity = dst.remaining();
+ if (capacity < pendingNet) {
+ return new SSLEngineResult(
+ SSLEngineResult.Status.BUFFER_OVERFLOW, getHandshakeStatus(), bytesConsumed, bytesProduced);
+ }
+
+ // Write the pending data from the network BIO into the dst buffer
+ try {
+ bytesProduced += readEncryptedData(state.networkBIO, dst, pendingNet);
+ } catch (Exception e) {
+ throw new SSLException(e);
+ }
+
+ return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(), bytesConsumed, bytesProduced);
+ }
+ }
+ }
+
+ return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(), bytesConsumed, bytesProduced);
+ }
+
+ @Override
+ public synchronized SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException {
+ // Check to make sure the engine has not been closed
+ if (destroyed) {
+ return new SSLEngineResult(SSLEngineResult.Status.CLOSED, SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0);
+ }
+
+ // Throw required runtime exceptions
+ if (src == null || dsts == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullBuffer"));
+ }
+ if (offset >= dsts.length || offset + length > dsts.length) {
+ throw new IndexOutOfBoundsException(sm.getString("engine.invalidBufferArray",
+ Integer.toString(offset), Integer.toString(length),
+ Integer.toString(dsts.length)));
+ }
+ int capacity = 0;
+ final int endOffset = offset + length;
+ for (int i = offset; i < endOffset; i++) {
+ ByteBuffer dst = dsts[i];
+ if (dst == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullBufferInArray"));
+ }
+ if (dst.isReadOnly()) {
+ throw new ReadOnlyBufferException();
+ }
+ capacity += dst.remaining();
+ }
+
+ // Prepare OpenSSL to work in server mode and receive handshake
+ if (accepted == Accepted.NOT) {
+ beginHandshakeImplicitly();
+ }
+
+ // In handshake or close_notify stages, check if call to unwrap was made
+ // without regard to the handshake status.
+ SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
+ if ((!handshakeFinished || engineClosed) && handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
+ return new SSLEngineResult(getEngineStatus(), SSLEngineResult.HandshakeStatus.NEED_WRAP, 0, 0);
+ }
+
+ int len = src.remaining();
+
+ // protect against protocol overflow attack vector
+ if (len > MAX_ENCRYPTED_PACKET_LENGTH) {
+ isInboundDone = true;
+ isOutboundDone = true;
+ engineClosed = true;
+ shutdown();
+ throw new SSLException(sm.getString("engine.oversizedPacket"));
+ }
+
+ // Write encrypted data to network BIO
+ int written = 0;
+ try {
+ written = writeEncryptedData(state.networkBIO, src);
+ } catch (Exception e) {
+ throw new SSLException(e);
+ }
+
+ // There won't be any application data until we're done handshaking
+ //
+ // We first check handshakeFinished to eliminate the overhead of extra JNI call if possible.
+ int pendingApp = pendingReadableBytesInSSL();
+ if (!handshakeFinished) {
+ pendingApp = 0;
+ }
+ int bytesProduced = 0;
+ int idx = offset;
+ // Do we have enough room in dsts to write decrypted data?
+ if (capacity == 0) {
+ return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW, getHandshakeStatus(), written, 0);
+ }
+
+ while (pendingApp > 0) {
+ if (idx == endOffset) {
+ // Destination buffer state changed (no remaining space although
+ // capacity is still available), so break loop with an error
+ throw new IllegalStateException(sm.getString("engine.invalidDestinationBuffersState"));
+ }
+ // Write decrypted data to dsts buffers
+ while (idx < endOffset) {
+ ByteBuffer dst = dsts[idx];
+ if (!dst.hasRemaining()) {
+ idx++;
+ continue;
+ }
+
+ if (pendingApp <= 0) {
+ break;
+ }
+
+ int bytesRead;
+ try {
+ bytesRead = readPlaintextData(state.ssl, dst);
+ } catch (Exception e) {
+ throw new SSLException(e);
+ }
+
+ if (bytesRead == 0) {
+ // This should not be possible. pendingApp is positive
+ // therefore the read should have read at least one byte.
+ throw new IllegalStateException(sm.getString("engine.failedToReadAvailableBytes"));
+ }
+
+ bytesProduced += bytesRead;
+ pendingApp -= bytesRead;
+ capacity -= bytesRead;
+
+ if (!dst.hasRemaining()) {
+ idx++;
+ }
+ }
+ if (capacity == 0) {
+ break;
+ } else if (pendingApp == 0) {
+ pendingApp = pendingReadableBytesInSSL();
+ }
+ }
+
+ // Check to see if we received a close_notify message from the peer
+ if (!receivedShutdown && (SSL_get_shutdown(state.ssl) & SSL_RECEIVED_SHUTDOWN()) == SSL_RECEIVED_SHUTDOWN()) {
+ receivedShutdown = true;
+ closeOutbound();
+ closeInbound();
+ }
+
+ if (bytesProduced == 0 && (written == 0 || (written > 0 && !src.hasRemaining() && handshakeFinished))) {
+ return new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW, getHandshakeStatus(), written, 0);
+ } else {
+ return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(), written, bytesProduced);
+ }
+ }
+
+ private int pendingReadableBytesInSSL()
+ throws SSLException {
+ // NOTE: Calling a fake read is necessary before calling pendingReadableBytesInSSL because
+ // SSL_pending will return 0 if OpenSSL has not started the current TLS record
+ // See https://www.openssl.org/docs/manmaster/man3/SSL_pending.html
+ clearLastError();
+ int lastPrimingReadResult = SSL_read(state.ssl, MemorySegment.NULL, 0); // priming read
+ // check if SSL_read returned <= 0. In this case we need to check the error and see if it was something
+ // fatal.
+ if (lastPrimingReadResult <= 0) {
+ checkLastError();
+ }
+ int pendingReadableBytesInSSL = SSL_pending(state.ssl);
+
+ // TLS 1.0 needs additional handling
+ if (Constants.SSL_PROTO_TLSv1.equals(version) && lastPrimingReadResult == 0 &&
+ pendingReadableBytesInSSL == 0) {
+ // Perform another priming read
+ lastPrimingReadResult = SSL_read(state.ssl, MemorySegment.NULL, 0);
+ if (lastPrimingReadResult <= 0) {
+ checkLastError();
+ }
+ pendingReadableBytesInSSL = SSL_pending(state.ssl);
+ }
+
+ return pendingReadableBytesInSSL;
+ }
+
+ @Override
+ public Runnable getDelegatedTask() {
+ // Currently, we do not delegate SSL computation tasks
+ return null;
+ }
+
+ @Override
+ public synchronized void closeInbound() throws SSLException {
+ if (isInboundDone) {
+ return;
+ }
+
+ isInboundDone = true;
+ engineClosed = true;
+
+ shutdown();
+
+ if (accepted != Accepted.NOT && !receivedShutdown) {
+ throw new SSLException(sm.getString("engine.inboundClose"));
+ }
+ }
+
+ @Override
+ public synchronized boolean isInboundDone() {
+ return isInboundDone || engineClosed;
+ }
+
+ @Override
+ public synchronized void closeOutbound() {
+ if (isOutboundDone) {
+ return;
+ }
+
+ isOutboundDone = true;
+ engineClosed = true;
+
+ if (accepted != Accepted.NOT && !destroyed) {
+ int mode = SSL_get_shutdown(state.ssl);
+ if ((mode & SSL_SENT_SHUTDOWN()) != SSL_SENT_SHUTDOWN()) {
+ SSL_shutdown(state.ssl);
+ }
+ } else {
+ // engine closing before initial handshake
+ shutdown();
+ }
+ }
+
+ @Override
+ public synchronized boolean isOutboundDone() {
+ return isOutboundDone;
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ Set<String> availableCipherSuites = AVAILABLE_CIPHER_SUITES;
+ return availableCipherSuites.toArray(new String[0]);
+ }
+
+ @Override
+ public synchronized String[] getEnabledCipherSuites() {
+ if (destroyed) {
+ return new String[0];
+ }
+ String[] enabled = getCiphers(state.ssl);
+ if (enabled == null) {
+ return new String[0];
+ } else {
+ for (int i = 0; i < enabled.length; i++) {
+ String mapped = OpenSSLCipherConfigurationParser.openSSLToJsse(enabled[i]);
+ if (mapped != null) {
+ enabled[i] = mapped;
+ }
+ }
+ return enabled;
+ }
+ }
+
+ @Override
+ public synchronized void setEnabledCipherSuites(String[] cipherSuites) {
+ if (initialized) {
+ return;
+ }
+ if (cipherSuites == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullCipherSuite"));
+ }
+ if (destroyed) {
+ return;
+ }
+ final StringBuilder buf = new StringBuilder();
+ for (String cipherSuite : cipherSuites) {
+ if (cipherSuite == null) {
+ break;
+ }
+ String converted = OpenSSLCipherConfigurationParser.jsseToOpenSSL(cipherSuite);
+ if (!AVAILABLE_CIPHER_SUITES.contains(cipherSuite)) {
+ log.debug(sm.getString("engine.unsupportedCipher", cipherSuite, converted));
+ }
+ if (converted != null) {
+ cipherSuite = converted;
+ }
+
+ buf.append(cipherSuite);
+ buf.append(':');
+ }
+
+ if (buf.length() == 0) {
+ throw new IllegalArgumentException(sm.getString("engine.emptyCipherSuite"));
+ }
+ buf.setLength(buf.length() - 1);
+
+ final String cipherSuiteSpec = buf.toString();
+ try (var localArena = Arena.ofConfined()) {
+ SSL_set_cipher_list(state.ssl, localArena.allocateUtf8String(cipherSuiteSpec));
+ } catch (Exception e) {
+ throw new IllegalStateException(sm.getString("engine.failedCipherSuite", cipherSuiteSpec), e);
+ }
+ }
+
+ @Override
+ public String[] getSupportedProtocols() {
+ return IMPLEMENTED_PROTOCOLS_SET.toArray(new String[0]);
+ }
+
+ @Override
+ public synchronized String[] getEnabledProtocols() {
+ if (destroyed) {
+ return new String[0];
+ }
+ List<String> enabled = new ArrayList<>();
+ // Seems like there is no way to explicitly disable SSLv2Hello in OpenSSL so it is always enabled
+ enabled.add(Constants.SSL_PROTO_SSLv2Hello);
+ long opts = SSL_get_options(state.ssl);
+ if ((opts & SSL_OP_NO_TLSv1()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1);
+ }
+ if ((opts & SSL_OP_NO_TLSv1_1()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1_1);
+ }
+ if ((opts & SSL_OP_NO_TLSv1_2()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1_2);
+ }
+ if ((opts & SSL_OP_NO_TLSv1_3()) == 0) {
+ enabled.add(Constants.SSL_PROTO_TLSv1_3);
+ }
+ if ((opts & SSL_OP_NO_SSLv2()) == 0) {
+ enabled.add(Constants.SSL_PROTO_SSLv2);
+ }
+ if ((opts & SSL_OP_NO_SSLv3()) == 0) {
+ enabled.add(Constants.SSL_PROTO_SSLv3);
+ }
+ int size = enabled.size();
+ if (size == 0) {
+ return new String[0];
+ } else {
+ return enabled.toArray(new String[size]);
+ }
+ }
+
+ @Override
+ public synchronized void setEnabledProtocols(String[] protocols) {
+ if (initialized) {
+ return;
+ }
+ if (protocols == null) {
+ // This is correct from the API docs
+ throw new IllegalArgumentException();
+ }
+ if (destroyed) {
+ return;
+ }
+ boolean sslv2 = false;
+ boolean sslv3 = false;
+ boolean tlsv1 = false;
+ boolean tlsv1_1 = false;
+ boolean tlsv1_2 = false;
+ boolean tlsv1_3 = false;
+ for (String p : protocols) {
+ if (!IMPLEMENTED_PROTOCOLS_SET.contains(p)) {
+ throw new IllegalArgumentException(sm.getString("engine.unsupportedProtocol", p));
+ }
+ if (p.equals(Constants.SSL_PROTO_SSLv2)) {
+ sslv2 = true;
+ } else if (p.equals(Constants.SSL_PROTO_SSLv3)) {
+ sslv3 = true;
+ } else if (p.equals(Constants.SSL_PROTO_TLSv1)) {
+ tlsv1 = true;
+ } else if (p.equals(Constants.SSL_PROTO_TLSv1_1)) {
+ tlsv1_1 = true;
+ } else if (p.equals(Constants.SSL_PROTO_TLSv1_2)) {
+ tlsv1_2 = true;
+ } else if (p.equals(Constants.SSL_PROTO_TLSv1_3)) {
+ tlsv1_3 = true;
+ }
+ }
+ // Enable all and then disable what we not want
+ SSL_set_options(state.ssl, SSL_OP_ALL());
+
+ if (!sslv2) {
+ SSL_set_options(state.ssl, SSL_OP_NO_SSLv2());
+ }
+ if (!sslv3) {
+ SSL_set_options(state.ssl, SSL_OP_NO_SSLv3());
+ }
+ if (!tlsv1) {
+ SSL_set_options(state.ssl, SSL_OP_NO_TLSv1());
+ }
+ if (!tlsv1_1) {
+ SSL_set_options(state.ssl, SSL_OP_NO_TLSv1_1());
+ }
+ if (!tlsv1_2) {
+ SSL_set_options(state.ssl, SSL_OP_NO_TLSv1_2());
+ }
+ if (!tlsv1_3) {
+ SSL_set_options(state.ssl, SSL_OP_NO_TLSv1_3());
+ }
+ }
+
+ @Override
+ public SSLSession getSession() {
+ return session;
+ }
+
+ @Override
+ public synchronized void beginHandshake() throws SSLException {
+ if (engineClosed || destroyed) {
+ throw new SSLException(sm.getString("engine.engineClosed"));
+ }
+ switch (accepted) {
+ case NOT:
+ handshake();
+ accepted = Accepted.EXPLICIT;
+ break;
+ case IMPLICIT:
+ // A user did not start handshake by calling this method by themselves,
+ // but handshake has been started already by wrap() or unwrap() implicitly.
+ // Because it's the user's first time to call this method, it is unfair to
+ // raise an exception. From the user's standpoint, they never asked for
+ // renegotiation.
+
+ accepted = Accepted.EXPLICIT; // Next time this method is invoked by the user, we should raise an exception.
+ break;
+ case EXPLICIT:
+ renegotiate();
+ break;
+ }
+ }
+
+ private byte[] getPeerCertificate() {
+ try (var localArena = Arena.ofConfined()) {
+ MemorySegment/*(X509*)*/ x509 = (OpenSSLContext.OPENSSL_3 ? SSL_get1_peer_certificate(state.ssl) : SSL_get_peer_certificate(state.ssl));
+ MemorySegment bufPointer = localArena.allocate(ValueLayout.ADDRESS, MemorySegment.NULL);
+ int length = i2d_X509(x509, bufPointer);
+ if (length <= 0) {
+ return null;
+ }
+ MemorySegment buf = bufPointer.get(ValueLayout.ADDRESS, 0);
+ byte[] certificate = buf.reinterpret(length, localArena, null).toArray(ValueLayout.JAVA_BYTE);
+ X509_free(x509);
+ CRYPTO_free(buf, MemorySegment.NULL, 0); // OPENSSL_free macro
+ return certificate;
+ }
+ }
+
+ private byte[][] getPeerCertChain() {
+ MemorySegment/*STACK_OF(X509)*/ sk = SSL_get_peer_cert_chain(state.ssl);
+ int len = OPENSSL_sk_num(sk);
+ if (len <= 0) {
+ return null;
+ }
+ byte[][] certificateChain = new byte[len][];
+ try (var localArena = Arena.ofConfined()) {
+ for (int i = 0; i < len; i++) {
+ MemorySegment/*(X509*)*/ x509 = OPENSSL_sk_value(sk, i);
+ MemorySegment bufPointer = localArena.allocate(ValueLayout.ADDRESS, MemorySegment.NULL);
+ int length = i2d_X509(x509, bufPointer);
+ if (length < 0) {
+ certificateChain[i] = new byte[0];
+ continue;
+ }
+ MemorySegment buf = bufPointer.get(ValueLayout.ADDRESS, 0);
+ byte[] certificate = buf.reinterpret(length, localArena, null).toArray(ValueLayout.JAVA_BYTE);
+ certificateChain[i] = certificate;
+ CRYPTO_free(buf, MemorySegment.NULL, 0); // OPENSSL_free macro
+ }
+ return certificateChain;
+ }
+ }
+
+ private String getProtocolNegotiated() {
+ try (var localArena = Arena.ofConfined()) {
+ MemorySegment lenAddress = localArena.allocate(ValueLayout.JAVA_INT, 0);
+ MemorySegment protocolPointer = localArena.allocate(ValueLayout.ADDRESS, MemorySegment.NULL);
+ SSL_get0_alpn_selected(state.ssl, protocolPointer, lenAddress);
+ if (MemorySegment.NULL.equals(protocolPointer)) {
+ return null;
+ }
+ int length = lenAddress.get(ValueLayout.JAVA_INT, 0);
+ if (length == 0) {
+ return null;
+ }
+ MemorySegment protocolAddress = protocolPointer.get(ValueLayout.ADDRESS, 0);
+ byte[] name = protocolAddress.reinterpret(length, localArena, null).toArray(ValueLayout.JAVA_BYTE);
+ if (log.isDebugEnabled()) {
+ log.debug("Protocol negotiated [" + new String(name) + "]");
+ }
+ return new String(name);
+ }
+ }
+
+ private void beginHandshakeImplicitly() throws SSLException {
+ handshake();
+ accepted = Accepted.IMPLICIT;
+ }
+
+ private void handshake() throws SSLException {
+ currentHandshake = state.handshakeCount;
+ clearLastError();
+ int code = SSL_do_handshake(state.ssl);
+ if (code <= 0) {
+ checkLastError();
+ } else {
+ if (alpn) {
+ selectedProtocol = getProtocolNegotiated();
+ }
+ session.lastAccessedTime = System.currentTimeMillis();
+ // if SSL_do_handshake returns > 0 it means the handshake was finished. This means we can update
+ // handshakeFinished directly and so eliminate unnecessary calls to SSL.isInInit(...)
+ handshakeFinished = true;
+ }
+ }
+
+ private synchronized void renegotiate() throws SSLException {
+ if (log.isDebugEnabled()) {
+ log.debug("Start renegotiate");
+ }
+ clearLastError();
+ int code;
+ if (SSL_get_version(state.ssl).getUtf8String(0).equals(Constants.SSL_PROTO_TLSv1_3)) {
+ state.phaState = PHAState.START;
+ code = SSL_verify_client_post_handshake(state.ssl);
+ } else {
+ code = SSL_renegotiate(state.ssl);
+ }
+ if (code <= 0) {
+ checkLastError();
+ }
+ handshakeFinished = false;
+ peerCerts = null;
+ currentHandshake = state.handshakeCount;
+ int code2 = SSL_do_handshake(state.ssl);
+ if (code2 <= 0) {
+ checkLastError();
+ }
+ }
+
+ private void checkLastError() throws SSLException {
+ String sslError = getLastError();
+ if (sslError != null) {
+ // Many errors can occur during handshake and need to be reported
+ if (!handshakeFinished) {
+ sendHandshakeError = true;
+ } else {
+ throw new SSLException(sslError);
+ }
+ }
+ }
+
+
+ /**
+ * Clear out any errors, but log a warning.
+ */
+ private void clearLastError() {
+ getLastError();
+ }
+
+ /**
+ * Many calls to SSL methods do not check the last error. Those that do
+ * check the last error need to ensure that any previously ignored error is
+ * cleared prior to the method call else errors may be falsely reported.
+ * Ideally, before any SSL_read, SSL_write, clearLastError should always
+ * be called, and getLastError should be called after on any negative or
+ * zero result.
+ * @return the first error in the stack
+ */
+ private String getLastError() {
+ String sslError = null;
+ long error = ERR_get_error();
+ if (error != SSL_ERROR_NONE()) {
+ try (var localArena = Arena.ofConfined()) {
+ do {
+ // Loop until getLastErrorNumber() returns SSL_ERROR_NONE
+ var buf = localArena.allocateArray(ValueLayout.JAVA_BYTE, new byte[128]);
+ ERR_error_string(error, buf);
+ String err = buf.getUtf8String(0);
+ if (sslError == null) {
+ sslError = err;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("engine.openSSLError", Long.toString(error), err));
+ }
+ } while ((error = ERR_get_error()) != SSL_ERROR_NONE());
+ }
+ }
+ return sslError;
+ }
+
+ private SSLEngineResult.Status getEngineStatus() {
+ return engineClosed ? SSLEngineResult.Status.CLOSED : SSLEngineResult.Status.OK;
+ }
+
+ @Override
+ public synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() {
+ if (accepted == Accepted.NOT || destroyed) {
+ return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
+ }
+
+ // Check if we are in the initial handshake phase
+ if (!handshakeFinished) {
+
+ // There is pending data in the network BIO -- call wrap
+ if (sendHandshakeError || BIO_ctrl_pending(state.networkBIO) != 0) {
+ if (sendHandshakeError) {
+ // After a last wrap, consider it is going to be done
+ sendHandshakeError = false;
+ currentHandshake++;
+ }
+ return SSLEngineResult.HandshakeStatus.NEED_WRAP;
+ }
+
+ /*
+ * Tomcat Native stores a count of the completed handshakes in the
+ * SSL instance and increments it every time a handshake is
+ * completed. Comparing the handshake count when the handshake
+ * started to the current handshake count enables this code to
+ * detect when the handshake has completed.
+ *
+ * Obtaining client certificates after the connection has been
+ * established requires additional checks. We need to trigger
+ * additional reads until the certificates have been read but we
+ * don't know how many reads we will need as it depends on both
+ * client and network behaviour.
+ *
+ * The additional reads are triggered by returning NEED_UNWRAP
+ * rather than FINISHED. This allows the standard I/O code to be
+ * used.
+ *
+ * For TLSv1.2 and below, the handshake completes before the
+ * renegotiation. We therefore use SSL.renegotiatePending() to
+ * check on the current status of the renegotiation and return
+ * NEED_UNWRAP until it completes which means the client
+ * certificates will have been read from the client.
+ *
+ * For TLSv1.3, Tomcat Native sets a flag when post handshake
+ * authentication is started and updates it once the client
+ * certificate has been received. We therefore use
+ * SSL.getPostHandshakeAuthInProgress() to check the current status
+ * and return NEED_UNWRAP until that methods indicates that PHA is
+ * no longer in progress.
+ */
+
+ // No pending data to be sent to the peer
+ // Check to see if we have finished handshaking
+ if (state.handshakeCount != currentHandshake && SSL_renegotiate_pending(state.ssl) == 0 &&
+ (state.phaState != PHAState.START)) {
+ if (alpn) {
+ selectedProtocol = getProtocolNegotiated();
+ }
+ session.lastAccessedTime = System.currentTimeMillis();
+ version = SSL_get_version(state.ssl).getUtf8String(0);
+ handshakeFinished = true;
+ return SSLEngineResult.HandshakeStatus.FINISHED;
+ }
+
+ // No pending data
+ // Still handshaking / renegotiation / post-handshake auth pending
+ // Must be waiting on the peer to send more data
+ return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
+ }
+
+ // Check if we are in the shutdown phase
+ if (engineClosed) {
+ // Waiting to send the close_notify message
+ if (BIO_ctrl_pending(state.networkBIO) != 0) {
+ return SSLEngineResult.HandshakeStatus.NEED_WRAP;
+ }
+
+ // Must be waiting to receive the close_notify message
+ return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
+ }
+
+ return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
+ }
+
+ @Override
+ public void setUseClientMode(boolean clientMode) {
+ if (clientMode != this.clientMode) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public boolean getUseClientMode() {
+ return clientMode;
+ }
+
+ @Override
+ public void setNeedClientAuth(boolean b) {
+ setClientAuth(b ? ClientAuthMode.REQUIRE : ClientAuthMode.NONE);
+ }
+
+ @Override
+ public boolean getNeedClientAuth() {
+ return clientAuth == ClientAuthMode.REQUIRE;
+ }
+
+ @Override
+ public void setWantClientAuth(boolean b) {
+ setClientAuth(b ? ClientAuthMode.OPTIONAL : ClientAuthMode.NONE);
+ }
+
+ @Override
+ public boolean getWantClientAuth() {
+ return clientAuth == ClientAuthMode.OPTIONAL;
+ }
+
+ private static final int OPTIONAL_NO_CA = 3;
+
+ private void setClientAuth(ClientAuthMode mode) {
+ if (clientMode) {
+ return;
+ }
+ synchronized (this) {
+ if (clientAuth == mode) {
+ return;
+ }
+ state.certificateVerifyMode = switch (mode) {
+ case NONE -> SSL_VERIFY_NONE();
+ case REQUIRE -> SSL_VERIFY_FAIL_IF_NO_PEER_CERT();
+ case OPTIONAL -> certificateVerificationOptionalNoCA ? OPTIONAL_NO_CA : SSL_VERIFY_PEER();
+ };
+ // SSL.setVerify(state.ssl, value, certificateVerificationDepth);
+ // Set int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) callback
+ var openSSLCallbackVerify =
+ Linker.nativeLinker().upcallStub(openSSLCallbackVerifyHandle,
+ openSSLCallbackVerifyFunctionDescriptor, engineArena);
+ int value = switch (mode) {
+ case NONE -> SSL_VERIFY_NONE();
+ case REQUIRE -> SSL_VERIFY_PEER() | SSL_VERIFY_FAIL_IF_NO_PEER_CERT();
+ case OPTIONAL -> SSL_VERIFY_PEER();
+ };
+ SSL_set_verify(state.ssl, value, openSSLCallbackVerify);
+ clientAuth = mode;
+ }
+ }
+
+ public static void openSSLCallbackInfo(MemorySegment ssl, int where, int ret) {
+ EngineState state = getState(ssl);
+ if (state == null) {
+ log.warn(sm.getString("engine.noSSL", Long.valueOf(ssl.address())));
+ return;
+ }
+ if (0 != (where & SSL_CB_HANDSHAKE_DONE())) {
+ state.handshakeCount++;
+ }
+ }
+
+ public static int openSSLCallbackVerify(int preverify_ok, MemorySegment /*X509_STORE_CTX*/ x509ctx) {
+ MemorySegment ssl = X509_STORE_CTX_get_ex_data(x509ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+ EngineState state = getState(ssl);
+ if (state == null) {
+ log.warn(sm.getString("engine.noSSL", Long.valueOf(ssl.address())));
+ return 0;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Verification in engine with mode [" + state.certificateVerifyMode + "] for " + state.ssl);
+ }
+ int ok = preverify_ok;
+ int errnum = X509_STORE_CTX_get_error(x509ctx);
+ int errdepth = X509_STORE_CTX_get_error_depth(x509ctx);
+ state.phaState = PHAState.COMPLETE;
+ if (state.certificateVerifyMode == -1 /*SSL_CVERIFY_UNSET*/ || state.certificateVerifyMode == SSL_VERIFY_NONE()) {
+ return 1;
+ }
+ /*SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) -> ((errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
+ || (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)
+ || (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
+ || (errnum == X509_V_ERR_CERT_UNTRUSTED)
+ || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE))*/
+ boolean verifyErrorIsOptional = (errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT())
+ || (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN())
+ || (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY())
+ || (errnum == X509_V_ERR_CERT_UNTRUSTED())
+ || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE());
+ if (verifyErrorIsOptional && (state.certificateVerifyMode == OPTIONAL_NO_CA)) {
+ ok = 1;
+ SSL_set_verify_result(state.ssl, X509_V_OK());
+ }
+ /*
+ * Expired certificates vs. "expired" CRLs: by default, OpenSSL
+ * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
+ * SSL alert, but that's not really the message we should convey to the
+ * peer (at the very least, it's confusing, and in many cases, it's also
+ * inaccurate, as the certificate itself may very well not have expired
+ * yet). We set the X509_STORE_CTX error to something which OpenSSL's
+ * s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
+ * i.e. the peer will receive a "certificate_unknown(46)" alert.
+ * We do not touch errnum, though, so that later on we will still log
+ * the "real" error, as returned by OpenSSL.
+ */
+ if (ok == 0 && errnum == X509_V_ERR_CRL_HAS_EXPIRED()) {
+ X509_STORE_CTX_set_error(x509ctx, -1);
+ }
+
+ // OCSP
+ if (!state.noOcspCheck && (ok > 0)) {
+ /* If there was an optional verification error, it's not
+ * possible to perform OCSP validation since the issuer may be
+ * missing/untrusted. Fail in that case.
+ */
+ if (verifyErrorIsOptional) {
+ if (state.certificateVerifyMode != OPTIONAL_NO_CA) {
+ X509_STORE_CTX_set_error(x509ctx, X509_V_ERR_APPLICATION_VERIFICATION());
+ errnum = X509_V_ERR_APPLICATION_VERIFICATION();
+ ok = 0;
+ }
+ } else {
+ int ocspResponse = processOCSP(x509ctx);
+ if (ocspResponse == V_OCSP_CERTSTATUS_REVOKED()) {
+ ok = 0;
+ errnum = X509_STORE_CTX_get_error(x509ctx);
+ } else if (ocspResponse == V_OCSP_CERTSTATUS_UNKNOWN()) {
+ errnum = X509_STORE_CTX_get_error(x509ctx);
+ if (errnum <= 0) {
+ ok = 0;
+ }
+ }
+ }
+ }
+
+ if (errdepth > state.certificateVerificationDepth) {
+ // Certificate Verification: Certificate Chain too long
+ ok = 0;
+ }
+ return ok;
+ }
+
+ static int processOCSP(MemorySegment /*X509_STORE_CTX*/ x509ctx) {
+ int ocspResponse = V_OCSP_CERTSTATUS_UNKNOWN();
+ // ocspResponse = ssl_verify_OCSP(x509_ctx);
+ MemorySegment x509 = X509_STORE_CTX_get_current_cert(x509ctx);
+ if (!MemorySegment.NULL.equals(x509)) {
+ // No need to check cert->valid, because ssl_verify_OCSP() only
+ // is called if OpenSSL already successfully verified the certificate
+ // (parameter "ok" in SSL_callback_SSL_verify() must be true).
+ if (X509_check_issued(x509, x509) == X509_V_OK()) {
+ // don't do OCSP checking for valid self-issued certs
+ X509_STORE_CTX_set_error(x509ctx, X509_V_OK());
+ } else {
+ // If we can't get the issuer, we cannot perform OCSP verification
+ MemorySegment issuer = X509_STORE_CTX_get0_current_issuer(x509ctx);
+ if (!MemorySegment.NULL.equals(issuer)) {
+ // sslutils.c ssl_ocsp_request(x509, issuer, x509ctx);
+ int nid = X509_get_ext_by_NID(x509, NID_info_access(), -1);
+ if (nid >= 0) {
+ try (var localArenal = Arena.ofConfined()) {
+ MemorySegment ext = X509_get_ext(x509, nid);
+ MemorySegment os = X509_EXTENSION_get_data(ext);
+ int length = ASN1_STRING_length(os);
+ MemorySegment data = ASN1_STRING_get0_data(os);
+ // ocsp_urls = decode_OCSP_url(os);
+ byte[] asn1String = data.reinterpret(length, localArenal, null).toArray(ValueLayout.JAVA_BYTE);
+ Asn1Parser parser = new Asn1Parser(asn1String);
+ // Parse the byte sequence
+ ArrayList<String> urls = new ArrayList<>();
+ try {
+ parseOCSPURLs(parser, urls);
+ } catch (Exception e) {
+ log.error(sm.getString("engine.ocspParseError"), e);
+ }
+ if (!urls.isEmpty()) {
+ // Use OpenSSL to build OCSP request
+ for (String urlString : urls) {
+ try {
+ URL url = (new URI(urlString)).toURL();
+ ocspResponse = processOCSPRequest(url, issuer, x509, x509ctx, localArenal);
+ if (log.isDebugEnabled()) {
+ log.debug("OCSP response for URL: " + urlString + " was " + ocspResponse);
+ }
+ } catch (MalformedURLException | URISyntaxException e) {
+ log.warn(sm.getString("engine.invalidOCSPURL", urlString));
+ }
+ if (ocspResponse != V_OCSP_CERTSTATUS_UNKNOWN()) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return ocspResponse;
+ }
+
+ private static final int ASN1_SEQUENCE = 0x30;
+ private static final int ASN1_OID = 0x06;
+ private static final int ASN1_STRING = 0x86;
+ private static final byte[] OCSP_OID = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01};
+
+ private static void parseOCSPURLs(Asn1Parser parser, ArrayList<String> urls) {
+ while (!parser.eof()) {
+ int tag = parser.peekTag();
+ if (tag == ASN1_SEQUENCE) {
+ parser.parseTag(ASN1_SEQUENCE);
+ parser.parseFullLength();
+ } else if (tag == ASN1_OID) {
+ parser.parseTag(ASN1_OID);
+ int oidLen = parser.parseLength();
+ byte[] oid = new byte[oidLen];
+ parser.parseBytes(oid);
+ if (Arrays.compareUnsigned(oid, 0, OCSP_OID.length, OCSP_OID, 0, OCSP_OID.length) == 0) {
+ parser.parseTag(ASN1_STRING);
+ int urlLen = parser.parseLength();
+ byte[] url = new byte[urlLen];
+ parser.parseBytes(url);
+ urls.add(new String(url));
+ }
+ } else {
+ return;
+ }
+ }
+ }
+
+ private static int processOCSPRequest(URL url, MemorySegment issuer, MemorySegment x509,
+ MemorySegment /*X509_STORE_CTX*/ x509ctx, Arena localArena) {
+ MemorySegment ocspRequest = MemorySegment.NULL;
+ MemorySegment ocspResponse = MemorySegment.NULL;
+ MemorySegment id = MemorySegment.NULL;
+ MemorySegment ocspOneReq = MemorySegment.NULL;
+ HttpURLConnection connection = null;
+ MemorySegment basicResponse = MemorySegment.NULL;
+ MemorySegment certId = MemorySegment.NULL;
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ ocspRequest = OCSP_REQUEST_new();
+ if (MemorySegment.NULL.equals(ocspRequest)) {
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
+ id = OCSP_cert_to_id(MemorySegment.NULL, x509, issuer);
+ if (MemorySegment.NULL.equals(id)) {
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
+ ocspOneReq = OCSP_request_add0_id(ocspRequest, id);
+ if (MemorySegment.NULL.equals(ocspOneReq)) {
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
+ MemorySegment bufPointer = localArena.allocate(ValueLayout.ADDRESS, MemorySegment.NULL);
+ int requestLength = i2d_OCSP_REQUEST(ocspRequest, bufPointer);
+ if (requestLength <= 0) {
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
+ MemorySegment buf = bufPointer.get(ValueLayout.ADDRESS, 0);
+ // HTTP request with the following header
+ // POST urlPath HTTP/1.1
+ // Host: urlHost:urlPort
+ // Content-Type: application/ocsp-request
+ // Content-Length: ocspRequestData.length
+ byte[] ocspRequestData = buf.reinterpret(requestLength, localArena, null).toArray(ValueLayout.JAVA_BYTE);
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setDoInput(true);
+ connection.setDoOutput(true);
+ connection.setFixedLengthStreamingMode(requestLength);
+ connection.setRequestProperty("Content-Type", "application/ocsp-request");
+ connection.connect();
+ connection.getOutputStream().write(ocspRequestData);
+ int responseCode = connection.getResponseCode();
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
+ InputStream is = connection.getInputStream();
+ int read = 0;
+ byte[] responseBuf = new byte[1024];
+ while ((read = is.read(responseBuf)) > 0) {
+ baos.write(responseBuf, 0, read);
+ }
+ byte[] responseData = baos.toByteArray();
+ var nativeResponseData = localArena.allocateArray(ValueLayout.JAVA_BYTE, responseData);
+ var nativeResponseDataPointer = localArena.allocate(ValueLayout.ADDRESS, nativeResponseData);
+ ocspResponse = d2i_OCSP_RESPONSE(MemorySegment.NULL, nativeResponseDataPointer, responseData.length);
+ if (!MemorySegment.NULL.equals(ocspResponse)) {
+ if (OCSP_response_status(ocspResponse) == OCSP_RESPONSE_STATUS_SUCCESSFUL()) {
+ basicResponse = OCSP_response_get1_basic(ocspResponse);
+ certId = OCSP_cert_to_id(MemorySegment.NULL, x509, issuer);
+ if (MemorySegment.NULL.equals(certId)) {
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
+ // Find by serial number and get the matching response
+ MemorySegment singleResponse = OCSP_resp_get0(basicResponse, OCSP_resp_find(basicResponse, certId, -1));
+ return OCSP_single_get0_status(singleResponse, MemorySegment.NULL,
+ MemorySegment.NULL, MemorySegment.NULL, MemorySegment.NULL);
+ }
+ }
+ } catch (Exception e) {
+ log.warn(sm.getString("engine.ocspRequestError", url.toString()), e);
+ } finally {
+ if (MemorySegment.NULL.equals(ocspResponse)) {
+ // Failed to get a valid response
+ X509_STORE_CTX_set_error(x509ctx, X509_V_ERR_APPLICATION_VERIFICATION());
+ }
+ OCSP_CERTID_free(certId);
+ OCSP_BASICRESP_free(basicResponse);
+ OCSP_RESPONSE_free(ocspResponse);
+ OCSP_REQUEST_free(ocspRequest);
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
+
+ @Override
+ public void setEnableSessionCreation(boolean b) {
+ if (!b) {
+ String msg = sm.getString("engine.noRestrictSessionCreation");
+ throw new UnsupportedOperationException(msg);
+ }
+ }
+
+ @Override
+ public boolean getEnableSessionCreation() {
+ return true;
+ }
+
+
+ private class OpenSSLSession implements SSLSession {
+
+ // lazy init for memory reasons
+ private Map<String, Object> values;
+
+ // Last accessed time
+ private long lastAccessedTime = -1;
+
+ @Override
+ public byte[] getId() {
+ byte[] id = null;
+ synchronized (OpenSSLEngine.this) {
+ if (!destroyed) {
+ try (var localArena = Arena.ofConfined()) {
+ MemorySegment lenPointer = localArena.allocate(ValueLayout.ADDRESS);
+ var session = SSL_get_session(state.ssl);
+ if (MemorySegment.NULL.equals(session)) {
+ return new byte[0];
+ }
+ MemorySegment sessionId = SSL_SESSION_get_id(session, lenPointer);
+ int len = lenPointer.get(ValueLayout.JAVA_INT, 0);
+ id = (len == 0) ? new byte[0]
+ : sessionId.reinterpret(len, localArena, null).toArray(ValueLayout.JAVA_BYTE);
+ }
+ }
+ }
+
+ return id;
+ }
+
+ @Override
+ public SSLSessionContext getSessionContext() {
+ return sessionContext;
+ }
+
+ @Override
+ public long getCreationTime() {
+ // We need to multiply by 1000 as OpenSSL uses seconds and we need milliseconds.
+ long creationTime = 0;
+ synchronized (OpenSSLEngine.this) {
+ if (!destroyed) {
+ var session = SSL_get_session(state.ssl);
+ if (!MemorySegment.NULL.equals(session)) {
+ creationTime = SSL_SESSION_get_time(session);
+ }
+ }
+ }
+ return creationTime * 1000L;
+ }
+
+ @Override
+ public long getLastAccessedTime() {
+ return (lastAccessedTime > 0) ? lastAccessedTime : getCreationTime();
+ }
+
+ @Override
+ public void invalidate() {
+ // NOOP
+ }
+
+ @Override
+ public boolean isValid() {
+ return false;
+ }
+
+ @Override
+ public void putValue(String name, Object value) {
+ if (name == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullName"));
+ }
+ if (value == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullValue"));
+ }
+ Map<String, Object> values = this.values;
+ if (values == null) {
+ // Use size of 2 to keep the memory overhead small
+ values = this.values = new HashMap<>(2);
+ }
+ Object old = values.put(name, value);
+ if (value instanceof SSLSessionBindingListener) {
+ ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name));
+ }
+ notifyUnbound(old, name);
+ }
+
+ @Override
+ public Object getValue(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullName"));
+ }
+ if (values == null) {
+ return null;
+ }
+ return values.get(name);
+ }
+
+ @Override
+ public void removeValue(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException(sm.getString("engine.nullName"));
+ }
+ Map<String, Object> values = this.values;
+ if (values == null) {
+ return;
+ }
+ Object old = values.remove(name);
+ notifyUnbound(old, name);
+ }
+
+ @Override
+ public String[] getValueNames() {
+ Map<String, Object> values = this.values;
+ if (values == null || values.isEmpty()) {
+ return new String[0];
+ }
+ return values.keySet().toArray(new String[0]);
+ }
+
+ private void notifyUnbound(Object value, String name) {
+ if (value instanceof SSLSessionBindingListener) {
+ ((SSLSessionBindingListener) value).valueUnbound(new SSLSessionBindingEvent(this, name));
+ }
+ }
+
+ @Override
+ public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+ // these are lazy created to reduce memory overhead
+ Certificate[] c = peerCerts;
+ if (c == null) {
+ byte[] clientCert;
+ byte[][] chain;
+ synchronized (OpenSSLEngine.this) {
+ if (destroyed || SSL_in_init(state.ssl) != 0) {
+ throw new SSLPeerUnverifiedException(sm.getString("engine.unverifiedPeer"));
+ }
+ chain = getPeerCertChain();
+ if (!clientMode) {
+ // if used on the server side SSL_get_peer_cert_chain(...) will not include the remote peer certificate.
+ // We use SSL_get_peer_certificate to get it in this case and add it to our array later.
+ //
+ // See https://www.openssl.org/docs/ssl/SSL_get_peer_cert_chain.html
+ clientCert = getPeerCertificate();
+ } else {
+ clientCert = null;
+ }
+ }
+ if (chain == null && clientCert == null) {
+ return null;
+ }
+ int len = 0;
+ if (chain != null) {
+ len += chain.length;
+ }
+
+ int i = 0;
+ Certificate[] certificates;
+ if (clientCert != null) {
+ len++;
+ certificates = new Certificate[len];
+ certificates[i++] = new OpenSSLX509Certificate(clientCert);
+ } else {
+ certificates = new Certificate[len];
+ }
+ if (chain != null) {
+ int a = 0;
+ for (; i < certificates.length; i++) {
+ certificates[i] = new OpenSSLX509Certificate(chain[a++]);
+ }
+ }
+ c = peerCerts = certificates;
+ }
+ return c;
+ }
+
+ @Override
+ public Certificate[] getLocalCertificates() {
+ // FIXME (if possible): Not available in the OpenSSL API
+ return EMPTY_CERTIFICATES;
+ }
+
+ @Override
+ public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+ Certificate[] peer = getPeerCertificates();
+ if (peer == null || peer.length == 0) {
+ return null;
+ }
+ return principal(peer);
+ }
+
+ @Override
+ public Principal getLocalPrincipal() {
+ Certificate[] local = getLocalCertificates();
+ if (local == null || local.length == 0) {
+ return null;
+ }
+ return principal(local);
+ }
+
+ private Principal principal(Certificate[] certs) {
+ return ((java.security.cert.X509Certificate) certs[0]).getIssuerX500Principal();
+ }
+
+ @Override
+ public String getCipherSuite() {
+ if (cipher == null) {
+ String ciphers;
+ synchronized (OpenSSLEngine.this) {
+ if (!handshakeFinished) {
+ return INVALID_CIPHER;
+ }
+ if (destroyed) {
+ return INVALID_CIPHER;
+ }
+ ciphers = SSL_CIPHER_get_name(SSL_get_current_cipher(state.ssl)).getUtf8String(0);
+ }
+ String c = OpenSSLCipherConfigurationParser.openSSLToJsse(ciphers);
+ if (c != null) {
+ cipher = c;
+ }
+ }
+ return cipher;
+ }
+
+ @Override
+ public String getProtocol() {
+ String applicationProtocol = OpenSSLEngine.this.applicationProtocol;
+ if (applicationProtocol == null) {
+ applicationProtocol = fallbackApplicationProtocol;
+ if (applicationProtocol != null) {
+ OpenSSLEngine.this.applicationProtocol = applicationProtocol.replace(':', '_');
+ } else {
+ OpenSSLEngine.this.applicationProtocol = applicationProtocol = "";
+ }
+ }
+ String version = null;
+ synchronized (OpenSSLEngine.this) {
+ if (!destroyed) {
+ version = SSL_get_version(state.ssl).getUtf8String(0);
+ }
+ }
+ if (applicationProtocol.isEmpty()) {
+ return version;
+ } else {
+ return version + ':' + applicationProtocol;
+ }
+ }
+
+ @Override
+ public String getPeerHost() {
+ // Not available for now in Tomcat (needs to be passed during engine creation)
+ return null;
+ }
+
+ @Override
+ public int getPeerPort() {
+ // Not available for now in Tomcat (needs to be passed during engine creation)
+ return 0;
+ }
+
+ @Override
+ public int getPacketBufferSize() {
+ return MAX_ENCRYPTED_PACKET_LENGTH;
+ }
+
+ @Override
+ public int getApplicationBufferSize() {
+ return MAX_PLAINTEXT_LENGTH;
+ }
+
+ }
+
+ private static class EngineState implements Runnable {
+
+ private final Arena stateArena = Arena.ofShared();
+ private final MemorySegment ssl;
+ private final MemorySegment networkBIO;
+ private final int certificateVerificationDepth;
+ private final boolean noOcspCheck;
+
+ private PHAState phaState = PHAState.NONE;
+ private int certificateVerifyMode = 0;
+ private int handshakeCount = 0;
+
+ private EngineState(MemorySegment ssl, MemorySegment networkBIO,
+ int certificateVerificationDepth, boolean noOcspCheck) {
+ states.put(Long.valueOf(ssl.address()), this);
+ this.certificateVerificationDepth = certificateVerificationDepth;
+ this.noOcspCheck = noOcspCheck;
+ // Use another arena to avoid keeping a reference through segments
+ // This also allows making further accesses to the main pointers safer
+ this.ssl = ssl.reinterpret(ValueLayout.ADDRESS.byteSize(), stateArena, null);
+ this.networkBIO = networkBIO.reinterpret(ValueLayout.ADDRESS.byteSize(), stateArena, null);
+ }
+
+ @Override
+ public void run() {
+ try {
+ states.remove(Long.valueOf(ssl.address()));
+ BIO_free(networkBIO);
+ SSL_free(ssl);
+ } finally {
+ stateArena.close();
+ }
+ }
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLImplementation.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLImplementation.java
new file mode 100644
index 0000000000..28d7ae2b8f
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLImplementation.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.SSLSession;
+
+import org.apache.tomcat.util.net.SSLHostConfigCertificate;
+import org.apache.tomcat.util.net.SSLImplementation;
+import org.apache.tomcat.util.net.SSLSupport;
+import org.apache.tomcat.util.net.SSLUtil;
+import org.apache.tomcat.util.net.jsse.JSSESupport;
+
+public class OpenSSLImplementation extends SSLImplementation {
+
+ @Deprecated
+ public SSLSupport getSSLSupport(SSLSession session) {
+ return new JSSESupport(session, null);
+ }
+
+ @Override
+ public SSLSupport getSSLSupport(SSLSession session, Map<String, List<String>> additionalAttributes) {
+ return new JSSESupport(session, additionalAttributes);
+ }
+
+ @Override
+ public SSLUtil getSSLUtil(SSLHostConfigCertificate certificate) {
+ return new OpenSSLUtil(certificate);
+ }
+
+ public boolean isAlpnSupported() {
+ // OpenSSL supported ALPN
+ return true;
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLifecycleListener.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLifecycleListener.java
new file mode 100644
index 0000000000..3c2dbdda94
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLifecycleListener.java
@@ -0,0 +1,463 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.ValueLayout;
+import java.security.SecureRandom;
+
+import static org.apache.tomcat.util.openssl.openssl_compat_h.FIPS_mode;
+import static org.apache.tomcat.util.openssl.openssl_compat_h.FIPS_mode_set;
+import static org.apache.tomcat.util.openssl.openssl_h.*;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Server;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.ExceptionUtils;
+import org.apache.tomcat.util.res.StringManager;
+
+
+
+/**
+ * Implementation of <code>LifecycleListener</code> that will do the global
+ * initialization of OpenSSL according to specified configuration parameters.
+ * Using the listener is completely optional, but is needed for configuration
+ * and full cleanup of a few native memory allocations.
+ */
+public class OpenSSLLifecycleListener implements LifecycleListener {
+
+ private static final Log log = LogFactory.getLog(OpenSSLLifecycleListener.class);
+
+ /**
+ * The string manager for this package.
+ */
+ protected static final StringManager sm = StringManager.getManager(OpenSSLLifecycleListener.class);
+
+
+ // ---------------------------------------------- Properties
+ protected static String SSLEngine = "on"; //default on
+ protected static String FIPSMode = "off"; // default off, valid only when SSLEngine="on"
+ protected static String SSLRandomSeed = "builtin";
+ protected static boolean fipsModeActive = false;
+
+ /**
+ * The "FIPS mode" level that we use as the argument to OpenSSL method
+ * <code>FIPS_mode_set()</code> to enable FIPS mode and that we expect as
+ * the return value of <code>FIPS_mode()</code> when FIPS mode is enabled.
+ * <p>
+ * In the future the OpenSSL library might grow support for different
+ * non-zero "FIPS" modes that specify different allowed subsets of ciphers
+ * or whatever, but nowadays only "1" is the supported value.
+ * </p>
+ * @see <a href="http://wiki.openssl.org/index.php/FIPS_mode_set%28%29">OpenSSL method FIPS_mode_set()</a>
+ * @see <a href="http://wiki.openssl.org/index.php/FIPS_mode%28%29">OpenSSL method FIPS_mode()</a>
+ */
+ private static final int FIPS_ON = 1;
+
+ private static final int FIPS_OFF = 0;
+
+ protected static final Object lock = new Object();
+
+ public static boolean isAvailable() {
+ if (OpenSSLStatus.isInstanceCreated()) {
+ synchronized (lock) {
+ init();
+ }
+ }
+ return OpenSSLStatus.isAvailable();
+ }
+
+ public OpenSSLLifecycleListener() {
+ OpenSSLStatus.setInstanceCreated(true);
+ }
+
+ // ---------------------------------------------- LifecycleListener Methods
+
+ /**
+ * Primary entry point for startup and shutdown events.
+ *
+ * @param event The event that has occurred
+ */
+ @Override
+ public void lifecycleEvent(LifecycleEvent event) {
+
+ boolean initError = false;
+ if (Lifecycle.BEFORE_INIT_EVENT.equals(event.getType())) {
+ if (!(event.getLifecycle() instanceof Server)) {
+ log.warn(sm.getString("listener.notServer",
+ event.getLifecycle().getClass().getSimpleName()));
+ }
+ try {
+ init();
+ } catch (Throwable t) {
+ t = ExceptionUtils.unwrapInvocationTargetException(t);
+ ExceptionUtils.handleThrowable(t);
+ log.error(sm.getString("listener.sslInit"), t);
+ initError = true;
+ }
+ // Failure to initialize FIPS mode is fatal
+ if (!(null == FIPSMode || "off".equalsIgnoreCase(FIPSMode)) && !isFIPSModeActive()) {
+ String errorMessage = sm.getString("listener.initializeFIPSFailed");
+ Error e = new Error(errorMessage);
+ // Log here, because thrown error might be not logged
+ log.fatal(errorMessage, e);
+ initError = true;
+ }
+ }
+ if (initError || Lifecycle.AFTER_DESTROY_EVENT.equals(event.getType())) {
+ // Note: Without the listener, destroy will never be called (which is not a significant problem)
+ try {
+ destroy();
+ } catch (Throwable t) {
+ t = ExceptionUtils.unwrapInvocationTargetException(t);
+ ExceptionUtils.handleThrowable(t);
+ log.info(sm.getString("listener.destroy"));
+ }
+ }
+
+ }
+
+ static MemorySegment enginePointer = MemorySegment.NULL;
+
+ static void initLibrary() {
+ synchronized (lock) {
+ if (OpenSSLStatus.isLibraryInitialized()) {
+ return;
+ }
+ OPENSSL_init_ssl(OPENSSL_INIT_ENGINE_ALL_BUILTIN(), MemorySegment.NULL);
+ OpenSSLStatus.setLibraryInitialized(true);
+ }
+ }
+
+ /*
+ { BN_get_rfc3526_prime_8192, NULL, 6145 },
+ { BN_get_rfc3526_prime_6144, NULL, 4097 },
+ { BN_get_rfc3526_prime_4096, NULL, 3073 },
+ { BN_get_rfc3526_prime_3072, NULL, 2049 },
+ { BN_get_rfc3526_prime_2048, NULL, 1025 },
+ { BN_get_rfc2409_prime_1024, NULL, 0 }
+ */
+ static final class DHParam {
+ final MemorySegment dh;
+ final int min;
+ private DHParam(MemorySegment dh, int min) {
+ this.dh = dh;
+ this.min = min;
+ }
+ }
+ static final DHParam[] dhParameters = new DHParam[6];
+
+ private static void initDHParameters() {
+ var dh = DH_new();
+ var p = BN_get_rfc3526_prime_8192(MemorySegment.NULL);
+ var g = BN_new();
+ BN_set_word(g, 2);
+ DH_set0_pqg(dh, p, MemorySegment.NULL, g);
+ dhParameters[0] = new DHParam(dh, 6145);
+ dh = DH_new();
+ p = BN_get_rfc3526_prime_6144(MemorySegment.NULL);
+ g = BN_new();
+ BN_set_word(g, 2);
+ DH_set0_pqg(dh, p, MemorySegment.NULL, g);
+ dhParameters[1] = new DHParam(dh, 4097);
+ dh = DH_new();
+ p = BN_get_rfc3526_prime_4096(MemorySegment.NULL);
+ g = BN_new();
+ BN_set_word(g, 2);
+ DH_set0_pqg(dh, p, MemorySegment.NULL, g);
+ dhParameters[2] = new DHParam(dh, 3073);
+ dh = DH_new();
+ p = BN_get_rfc3526_prime_3072(MemorySegment.NULL);
+ g = BN_new();
+ BN_set_word(g, 2);
+ DH_set0_pqg(dh, p, MemorySegment.NULL, g);
+ dhParameters[3] = new DHParam(dh, 2049);
+ dh = DH_new();
+ p = BN_get_rfc3526_prime_2048(MemorySegment.NULL);
+ g = BN_new();
+ BN_set_word(g, 2);
+ DH_set0_pqg(dh, p, MemorySegment.NULL, g);
+ dhParameters[4] = new DHParam(dh, 1025);
+ dh = DH_new();
+ p = BN_get_rfc2409_prime_1024(MemorySegment.NULL);
+ g = BN_new();
+ BN_set_word(g, 2);
+ DH_set0_pqg(dh, p, MemorySegment.NULL, g);
+ dhParameters[5] = new DHParam(dh, 0);
+ }
+
+ private static void freeDHParameters() {
+ for (int i = 0; i < dhParameters.length; i++) {
+ if (dhParameters[i] != null) {
+ MemorySegment dh = dhParameters[i].dh;
+ if (dh != null && !MemorySegment.NULL.equals(dh)) {
+ DH_free(dh);
+ dhParameters[i] = null;
+ }
+ }
+ }
+ }
+
+ static void init() {
+ synchronized (lock) {
+
+ if (OpenSSLStatus.isInitialized()) {
+ return;
+ }
+ OpenSSLStatus.setInitialized(true);
+
+ if ("off".equalsIgnoreCase(SSLEngine)) {
+ return;
+ }
+
+ try (var memorySession = Arena.ofConfined()) {
+
+ // Main library init
+ initLibrary();
+
+ // Setup engine
+ String engineName = "on".equalsIgnoreCase(SSLEngine) ? null : SSLEngine;
+ if (engineName != null) {
+ if ("auto".equals(engineName)) {
+ ENGINE_register_all_complete();
+ } else {
+ var engine = memorySession.allocateUtf8String(engineName);
+ enginePointer = ENGINE_by_id(engine);
+ if (MemorySegment.NULL.equals(enginePointer)) {
+ enginePointer = ENGINE_by_id(memorySession.allocateUtf8String("dynamic"));
+ if (enginePointer != null) {
+ if (ENGINE_ctrl_cmd_string(enginePointer, memorySession.allocateUtf8String("SO_PATH"), engine, 0) == 0
+ || ENGINE_ctrl_cmd_string(enginePointer, memorySession.allocateUtf8String("LOAD"),
+ MemorySegment.NULL, 0) == 0) {
+ // Engine load error
+ ENGINE_free(enginePointer);
+ enginePointer = MemorySegment.NULL;
+ }
+ }
+ }
+ if (!MemorySegment.NULL.equals(enginePointer)) {
+ if (ENGINE_set_default(enginePointer, ENGINE_METHOD_ALL()) == 0) {
+ // Engine load error
+ ENGINE_free(enginePointer);
+ enginePointer = MemorySegment.NULL;
+ }
+ }
+ if (MemorySegment.NULL.equals(enginePointer)) {
+ throw new IllegalStateException(sm.getString("listener.engineError"));
+ }
+ }
+ }
+
+ // Set the random seed, translated to the Java way
+ boolean seedDone = false;
+ if (SSLRandomSeed != null || SSLRandomSeed.length() != 0 || !"builtin".equals(SSLRandomSeed)) {
+ var randomSeed = memorySession.allocateUtf8String(SSLRandomSeed);
+ seedDone = RAND_load_file(randomSeed, 128) > 0;
+ }
+ if (!seedDone) {
+ // Use a regular random to get some bytes
+ SecureRandom random = new SecureRandom();
+ byte[] randomBytes = random.generateSeed(128);
+ RAND_seed(memorySession.allocateArray(ValueLayout.JAVA_BYTE, randomBytes), 128);
+ }
+
+ initDHParameters();
+
+ // OpenSSL 3 onwards uses providers
+ boolean usingProviders = (OpenSSL_version_num() >= 0x3000000fL);
+
+ if (usingProviders || !(null == FIPSMode || "off".equalsIgnoreCase(FIPSMode))) {
+ fipsModeActive = false;
+ final boolean enterFipsMode;
+ int fipsModeState = FIPS_OFF;
+ if (usingProviders) {
+ var md = EVP_MD_fetch(MemorySegment.NULL, memorySession.allocateUtf8String("SHA-512"), MemorySegment.NULL);
+ var provider = EVP_MD_get0_provider(md);
+ String name = OSSL_PROVIDER_get0_name(provider).getUtf8String(0);
+ EVP_MD_free(md);
+ if ("fips".equals(name)) {
+ fipsModeState = FIPS_ON;
+ }
+ } else {
+ fipsModeState = FIPS_mode();
+ }
+
+ if(log.isDebugEnabled()) {
+ log.debug(sm.getString("listener.currentFIPSMode", Integer.valueOf(fipsModeState)));
+ }
+
+ if (null == FIPSMode || "off".equalsIgnoreCase(FIPSMode)) {
+ if (fipsModeState == FIPS_ON) {
+ fipsModeActive = true;
+ }
+ enterFipsMode = false;
+ } else if ("on".equalsIgnoreCase(FIPSMode)) {
+ if (fipsModeState == FIPS_ON) {
+ if (!usingProviders) {
+ log.info(sm.getString("listener.skipFIPSInitialization"));
+ }
+ fipsModeActive = true;
+ enterFipsMode = false;
+ } else {
+ if (usingProviders) {
+ throw new IllegalStateException(sm.getString("listener.FIPSProviderNotDefault", FIPSMode));
+ } else {
+ enterFipsMode = true;
+ }
+ }
+ } else if ("require".equalsIgnoreCase(FIPSMode)) {
+ if (fipsModeState == FIPS_ON) {
+ fipsModeActive = true;
+ enterFipsMode = false;
+ } else {
+ if (usingProviders) {
+ throw new IllegalStateException(sm.getString("listener.FIPSProviderNotDefault", FIPSMode));
+ } else {
+ throw new IllegalStateException(sm.getString("listener.requireNotInFIPSMode"));
+ }
+ }
+ } else if ("enter".equalsIgnoreCase(FIPSMode)) {
+ if (fipsModeState == FIPS_OFF) {
+ if (usingProviders) {
+ throw new IllegalStateException(sm.getString("listener.FIPSProviderNotDefault", FIPSMode));
+ } else {
+ enterFipsMode = true;
+ }
+ } else {
+ if (usingProviders) {
+ fipsModeActive = true;
+ enterFipsMode = false;
+ } else {
+ throw new IllegalStateException(sm.getString(
+ "listener.enterAlreadyInFIPSMode", Integer.valueOf(fipsModeState)));
+ }
+ }
+ } else {
+ throw new IllegalArgumentException(sm.getString(
+ "listener.wrongFIPSMode", FIPSMode));
+ }
+
+ if (enterFipsMode) {
+ log.info(sm.getString("listener.initializingFIPS"));
+
+ fipsModeState = FIPS_mode_set(FIPS_ON);
+ if (fipsModeState != FIPS_ON) {
+ // This case should be handled by the native method,
+ // but we'll make absolutely sure, here.
+ String message = sm.getString("listener.initializeFIPSFailed");
+ log.error(message);
+ throw new IllegalStateException(message);
+ }
+
+ fipsModeActive = true;
+ log.info(sm.getString("listener.initializeFIPSSuccess"));
+ }
+
+ if (usingProviders && fipsModeActive) {
+ log.info(sm.getString("aprListener.usingFIPSProvider"));
+ }
+ }
+
+ log.info(sm.getString("listener.initializedOpenSSL", OpenSSL_version(0).getUtf8String(0)));
+ OpenSSLStatus.setAvailable(true);
+ }
+ }
+ }
+
+ static void destroy() {
+ synchronized (lock) {
+ if (!OpenSSLStatus.isInitialized()) {
+ return;
+ }
+ OpenSSLStatus.setAvailable(false);
+
+ try {
+ freeDHParameters();
+ if (!MemorySegment.NULL.equals(enginePointer)) {
+ ENGINE_free(enginePointer);
+ }
+ if (OpenSSL_version_num() < 0x3000000fL) {
+ FIPS_mode_set(0);
+ }
+ } finally {
+ OpenSSLStatus.setInitialized(false);
+ fipsModeActive = false;
+ }
+ }
+ }
+
+ public String getSSLEngine() {
+ return SSLEngine;
+ }
+
+ public void setSSLEngine(String SSLEngine) {
+ if (!SSLEngine.equals(OpenSSLLifecycleListener.SSLEngine)) {
+ // Ensure that the SSLEngine is consistent with that used for SSL init
+ if (OpenSSLStatus.isInitialized()) {
+ throw new IllegalStateException(
+ sm.getString("listener.tooLateForSSLEngine"));
+ }
+
+ OpenSSLLifecycleListener.SSLEngine = SSLEngine;
+ }
+ }
+
+ public String getSSLRandomSeed() {
+ return SSLRandomSeed;
+ }
+
+ public void setSSLRandomSeed(String SSLRandomSeed) {
+ if (!SSLRandomSeed.equals(OpenSSLLifecycleListener.SSLRandomSeed)) {
+ // Ensure that the random seed is consistent with that used for SSL init
+ if (OpenSSLStatus.isInitialized()) {
+ throw new IllegalStateException(
+ sm.getString("listener.tooLateForSSLRandomSeed"));
+ }
+
+ OpenSSLLifecycleListener.SSLRandomSeed = SSLRandomSeed;
+ }
+ }
+
+ public String getFIPSMode() {
+ return FIPSMode;
+ }
+
+ public void setFIPSMode(String FIPSMode) {
+ if (!FIPSMode.equals(OpenSSLLifecycleListener.FIPSMode)) {
+ // Ensure that the FIPS mode is consistent with that used for SSL init
+ if (OpenSSLStatus.isInitialized()) {
+ throw new IllegalStateException(
+ sm.getString("listener.tooLateForFIPSMode"));
+ }
+
+ OpenSSLLifecycleListener.FIPSMode = FIPSMode;
+ }
+ }
+
+ public boolean isFIPSModeActive() {
+ return fipsModeActive;
+ }
+
+ public static boolean isInstanceCreated() {
+ return OpenSSLStatus.isInstanceCreated();
+ }
+
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLSessionContext.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLSessionContext.java
new file mode 100644
index 0000000000..713bb88673
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLSessionContext.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.ValueLayout;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+
+import static org.apache.tomcat.util.openssl.openssl_h.*;
+import org.apache.tomcat.util.res.StringManager;
+
+/**
+ * OpenSSL specific {@link SSLSessionContext} implementation.
+ */
+public class OpenSSLSessionContext implements SSLSessionContext {
+ private static final StringManager sm = StringManager.getManager(OpenSSLSessionContext.class);
+ private static final Enumeration<byte[]> EMPTY = new EmptyEnumeration();
+
+ private static final int TICKET_KEYS_SIZE = 48;
+
+ private final OpenSSLSessionStats stats;
+ private final OpenSSLContext context;
+
+ OpenSSLSessionContext(OpenSSLContext context) {
+ this.context = context;
+ stats = new OpenSSLSessionStats(context.getSSLContext());
+ }
+
+ @Override
+ public SSLSession getSession(byte[] bytes) {
+ return null;
+ }
+
+ @Override
+ public Enumeration<byte[]> getIds() {
+ return EMPTY;
+ }
+
+ /**
+ * Sets the SSL session ticket keys of this context.
+ *
+ * @param keys The session ticket keys
+ */
+ public void setTicketKeys(byte[] keys) {
+ if (keys == null) {
+ throw new IllegalArgumentException(sm.getString("sessionContext.nullTicketKeys"));
+ }
+ if (keys.length != TICKET_KEYS_SIZE) {
+ throw new IllegalArgumentException(sm.getString("sessionContext.invalidTicketKeysLength", keys.length));
+ }
+ try (var memorySession = Arena.ofConfined()) {
+ var array = memorySession.allocateArray(ValueLayout.JAVA_BYTE, keys);
+ // #define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen)
+ // SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS, (keylen), (keys))
+ SSL_CTX_ctrl(context.getSSLContext(), SSL_CTRL_SET_TLSEXT_TICKET_KEYS(), TICKET_KEYS_SIZE, array);
+ }
+ }
+
+ /**
+ * Enable or disable caching of SSL sessions.
+ *
+ * @param enabled {@code true} to enable caching, {@code false} to disable
+ */
+ public void setSessionCacheEnabled(boolean enabled) {
+ long mode = enabled ? SSL_SESS_CACHE_SERVER() : SSL_SESS_CACHE_OFF();
+ // # define SSL_CTX_set_session_cache_mode(ctx,m) \
+ // SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
+ SSL_CTX_ctrl(context.getSSLContext(), SSL_CTRL_SET_SESS_CACHE_MODE(), mode, null);
+ }
+
+ /**
+ * @return {@code true} if caching of SSL sessions is enabled, {@code false}
+ * otherwise.
+ */
+ public boolean isSessionCacheEnabled() {
+ // # define SSL_CTX_get_session_cache_mode(ctx) \
+ // SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
+ return SSL_CTX_ctrl(context.getSSLContext(), SSL_CTRL_GET_SESS_CACHE_MODE(), 0, null) == SSL_SESS_CACHE_SERVER();
+ }
+
+ /**
+ * @return The statistics for this context.
+ */
+ public OpenSSLSessionStats stats() {
+ return stats;
+ }
+
+ @Override
+ public void setSessionTimeout(int seconds) {
+ if (seconds < 0) {
+ throw new IllegalArgumentException();
+ }
+ SSL_CTX_set_timeout(context.getSSLContext(), seconds);
+ }
+
+ @Override
+ public int getSessionTimeout() {
+ return (int) SSL_CTX_get_timeout(context.getSSLContext());
+ }
+
+ @Override
+ public void setSessionCacheSize(int size) {
+ if (size < 0) {
+ throw new IllegalArgumentException();
+ }
+ // # define SSL_CTX_sess_set_cache_size(ctx,t) \
+ // SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
+ SSL_CTX_ctrl(context.getSSLContext(), SSL_CTRL_SET_SESS_CACHE_SIZE(), size, null);
+ }
+
+ @Override
+ public int getSessionCacheSize() {
+ // # define SSL_CTX_sess_get_cache_size(ctx) \
+ // SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
+ return (int) SSL_CTX_ctrl(context.getSSLContext(), SSL_CTRL_GET_SESS_CACHE_SIZE(), 0, null);
+ }
+
+ /**
+ * Set the context within which session be reused (server side only)
+ * See <a href="http://www.openssl.org/docs/ssl/SSL_CTX_set_session_id_context.html">
+ * man SSL_CTX_set_session_id_context</a>
+ *
+ * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name
+ * of the application and/or the hostname and/or service name
+ * @return {@code true} if success, {@code false} otherwise.
+ */
+ public boolean setSessionIdContext(byte[] sidCtx) {
+ try (var memorySession = Arena.ofConfined()) {
+ var array = memorySession.allocateArray(ValueLayout.JAVA_BYTE, sidCtx);
+ return (SSL_CTX_set_session_id_context(context.getSSLContext(), array, sidCtx.length) == 1);
+ }
+ }
+
+ private static final class EmptyEnumeration implements Enumeration<byte[]> {
+ @Override
+ public boolean hasMoreElements() {
+ return false;
+ }
+
+ @Override
+ public byte[] nextElement() {
+ throw new NoSuchElementException();
+ }
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLSessionStats.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLSessionStats.java
new file mode 100644
index 0000000000..a63e524381
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLSessionStats.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+import java.lang.foreign.MemorySegment;
+
+import static org.apache.tomcat.util.openssl.openssl_h.*;
+
+/**
+ * Stats exposed by an OpenSSL session context.
+ *
+ * @see <a href="https://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html"><code>SSL_CTX_sess_number</code></a>
+ */
+public final class OpenSSLSessionStats {
+
+ private final MemorySegment ctx;
+
+ OpenSSLSessionStats(MemorySegment ctx) {
+ this.ctx = ctx;
+ }
+
+ /**
+ * @return The current number of sessions in the internal session cache.
+ */
+ public long number() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_NUMBER(), 0, null);
+ }
+
+ /**
+ * @return The number of started SSL/TLS handshakes in client mode.
+ */
+ public long connect() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_CONNECT() ,0, null);
+ }
+
+ /**
+ * @return The number of successfully established SSL/TLS sessions in client mode.
+ */
+ public long connectGood() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_CONNECT_GOOD() , 0, null);
+ }
+
+ /**
+ * @return The number of start renegotiations in client mode.
+ */
+ public long connectRenegotiate() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_CONNECT_RENEGOTIATE() , 0, null);
+ }
+
+ /**
+ * @return The number of started SSL/TLS handshakes in server mode.
+ */
+ public long accept() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_ACCEPT(), 0, null);
+ }
+
+ /**
+ * @return The number of successfully established SSL/TLS sessions in server mode.
+ */
+ public long acceptGood() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_ACCEPT_GOOD(), 0, null);
+ }
+
+ /**
+ * @return The number of start renegotiations in server mode.
+ */
+ public long acceptRenegotiate() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_ACCEPT_RENEGOTIATE(), 0, null);
+ }
+
+ /**
+ * @return The number of successfully reused sessions. In client mode, a
+ * session set with {@code SSL_set_session} successfully reused is
+ * counted as a hit. In server mode, a session successfully
+ * retrieved from internal or external cache is counted as a hit.
+ */
+ public long hits() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_HIT(), 0, null);
+ }
+
+ /**
+ * @return The number of successfully retrieved sessions from the external
+ * session cache in server mode.
+ */
+ public long cbHits() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_CB_HIT(), 0, null);
+ }
+
+ /**
+ * @return The number of sessions proposed by clients that were not found in
+ * the internal session cache in server mode.
+ */
+ public long misses() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_MISSES(), 0, null);
+ }
+
+ /**
+ * @return The number of sessions proposed by clients and either found in
+ * the internal or external session cache in server mode, but that
+ * were invalid due to timeout. These sessions are not included in
+ * the {@link #hits()} count.
+ */
+ public long timeouts() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_TIMEOUTS(), 0, null);
+ }
+
+ /**
+ * @return The number of sessions that were removed because the maximum
+ * session cache size was exceeded.
+ */
+ public long cacheFull() {
+ return SSL_CTX_ctrl(ctx, SSL_CTRL_SESS_CACHE_FULL(), 0, null);
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLStatus.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLStatus.java
new file mode 100644
index 0000000000..a45f442708
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLStatus.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+/**
+ * Holds OpenSSL status without the need to load other classes.
+ */
+public class OpenSSLStatus {
+ private static volatile boolean libraryInitialized = false;
+ private static volatile boolean initialized = false;
+ private static volatile boolean available = false;
+ private static volatile boolean instanceCreated = false;
+
+
+ public static boolean isLibraryInitialized() {
+ return libraryInitialized;
+ }
+
+ public static boolean isInitialized() {
+ return initialized;
+ }
+
+ public static boolean isAvailable() {
+ return available;
+ }
+
+ public static boolean isInstanceCreated() {
+ return instanceCreated;
+ }
+
+ public static void setLibraryInitialized(boolean libraryInitialized) {
+ OpenSSLStatus.libraryInitialized = libraryInitialized;
+ }
+
+ public static void setInitialized(boolean initialized) {
+ OpenSSLStatus.initialized = initialized;
+ }
+
+ public static void setAvailable(boolean available) {
+ OpenSSLStatus.available = available;
+ }
+
+ public static void setInstanceCreated(boolean instanceCreated) {
+ OpenSSLStatus.instanceCreated = instanceCreated;
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLUtil.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLUtil.java
new file mode 100644
index 0000000000..781dd4889a
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLUtil.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+import java.io.IOException;
+import java.security.KeyStoreException;
+import java.util.List;
+import java.util.Set;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.X509KeyManager;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.net.SSLContext;
+import org.apache.tomcat.util.net.SSLHostConfigCertificate;
+import org.apache.tomcat.util.net.SSLUtilBase;
+import org.apache.tomcat.util.net.jsse.JSSEKeyManager;
+import org.apache.tomcat.util.res.StringManager;
+
+public class OpenSSLUtil extends SSLUtilBase {
+
+ private static final Log log = LogFactory.getLog(OpenSSLUtil.class);
+ private static final StringManager sm = StringManager.getManager(OpenSSLUtil.class);
+
+
+ public OpenSSLUtil(SSLHostConfigCertificate certificate) {
+ super(certificate);
+ }
+
+
+ @Override
+ protected Log getLog() {
+ return log;
+ }
+
+
+ @Override
+ protected Set<String> getImplementedProtocols() {
+ return OpenSSLEngine.IMPLEMENTED_PROTOCOLS_SET;
+ }
+
+
+ @Override
+ protected Set<String> getImplementedCiphers() {
+ return OpenSSLEngine.AVAILABLE_CIPHER_SUITES;
+ }
+
+
+ @Override
+ protected boolean isTls13RenegAuthAvailable() {
+ // OpenSSL does support authentication after the initial handshake
+ return true;
+ }
+
+
+ @Override
+ public SSLContext createSSLContextInternal(List<String> negotiableProtocols) throws Exception {
+ return new OpenSSLContext(certificate, negotiableProtocols);
+ }
+
+
+ public static X509KeyManager chooseKeyManager(KeyManager[] managers) throws Exception {
+ if (managers == null) {
+ return null;
+ }
+ for (KeyManager manager : managers) {
+ if (manager instanceof JSSEKeyManager) {
+ return (JSSEKeyManager) manager;
+ }
+ }
+ for (KeyManager manager : managers) {
+ if (manager instanceof X509KeyManager) {
+ return (X509KeyManager) manager;
+ }
+ }
+ throw new IllegalStateException(sm.getString("openssl.keyManagerMissing"));
+ }
+
+
+ @Override
+ public KeyManager[] getKeyManagers() throws Exception {
+ try {
+ return super.getKeyManagers();
+ } catch (IllegalArgumentException e) {
+ // No (or invalid?) certificate chain was provided for the cert
+ String msg = sm.getString("openssl.nonJsseChain", certificate.getCertificateChainFile());
+ if (log.isDebugEnabled()) {
+ log.info(msg, e);
+ } else {
+ log.info(msg);
+ }
+ return null;
+ } catch (KeyStoreException | IOException e) {
+ // Depending on what is presented, JSSE may also throw
+ // KeyStoreException or IOException if it doesn't understand the
+ // provided file.
+ if (certificate.getCertificateFile() != null) {
+ String msg = sm.getString("openssl.nonJsseCertificate",
+ certificate.getCertificateFile(), certificate.getCertificateKeyFile());
+ if (log.isDebugEnabled()) {
+ log.info(msg, e);
+ } else {
+ log.info(msg);
+ }
+ // Assume JSSE processing of the certificate failed, try again with OpenSSL
+ // without a key manager
+ return null;
+ }
+ throw e;
+ }
+ }
+
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLX509Certificate.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLX509Certificate.java
new file mode 100644
index 0000000000..fc52abe8d6
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLX509Certificate.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.openssl.panama;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Set;
+
+final class OpenSSLX509Certificate extends X509Certificate {
+
+ private final byte[] bytes;
+ private X509Certificate wrapped;
+
+ OpenSSLX509Certificate(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ @Override
+ public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {
+ unwrap().checkValidity();
+ }
+
+ @Override
+ public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException {
+ unwrap().checkValidity(date);
+ }
+
+ @Override
+ public int getVersion() {
+ return unwrap().getVersion();
+ }
+
+ @Override
+ public BigInteger getSerialNumber() {
+ return unwrap().getSerialNumber();
+ }
+
+ @Override
+ @Deprecated
+ public Principal getIssuerDN() {
+ return unwrap().getIssuerDN();
+ }
+
+ @Override
+ @Deprecated
+ public Principal getSubjectDN() {
+ return unwrap().getSubjectDN();
+ }
+
+ @Override
+ public Date getNotBefore() {
+ return unwrap().getNotBefore();
+ }
+
+ @Override
+ public Date getNotAfter() {
+ return unwrap().getNotAfter();
+ }
+
+ @Override
+ public byte[] getTBSCertificate() throws CertificateEncodingException {
+ return unwrap().getTBSCertificate();
+ }
+
+ @Override
+ public byte[] getSignature() {
+ return unwrap().getSignature();
+ }
+
+ @Override
+ public String getSigAlgName() {
+ return unwrap().getSigAlgName();
+ }
+
+ @Override
+ public String getSigAlgOID() {
+ return unwrap().getSigAlgOID();
+ }
+
+ @Override
+ public byte[] getSigAlgParams() {
+ return unwrap().getSigAlgParams();
+ }
+
+ @Override
+ public boolean[] getIssuerUniqueID() {
+ return unwrap().getIssuerUniqueID();
+ }
+
+ @Override
+ public boolean[] getSubjectUniqueID() {
+ return unwrap().getSubjectUniqueID();
+ }
+
+ @Override
+ public boolean[] getKeyUsage() {
+ return unwrap().getKeyUsage();
+ }
+
+ @Override
+ public int getBasicConstraints() {
+ return unwrap().getBasicConstraints();
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ return bytes.clone();
+ }
+
+ @Override
+ public void verify(PublicKey key)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException {
+ unwrap().verify(key);
+ }
+
+ @Override
+ public void verify(PublicKey key, String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchProviderException, SignatureException {
+ unwrap().verify(key, sigProvider);
+ }
+
+ @Override
+ public String toString() {
+ return unwrap().toString();
+ }
+
+ @Override
+ public PublicKey getPublicKey() {
+ return unwrap().getPublicKey();
+ }
+
+ @Override
+ public boolean hasUnsupportedCriticalExtension() {
+ return unwrap().hasUnsupportedCriticalExtension();
+ }
+
+ @Override
+ public Set<String> getCriticalExtensionOIDs() {
+ return unwrap().getCriticalExtensionOIDs();
+ }
+
+ @Override
+ public Set<String> getNonCriticalExtensionOIDs() {
+ return unwrap().getNonCriticalExtensionOIDs();
+ }
+
+ @Override
+ public byte[] getExtensionValue(String oid) {
+ return unwrap().getExtensionValue(oid);
+ }
+
+ private X509Certificate unwrap() {
+ X509Certificate wrapped = this.wrapped;
+ if (wrapped == null) {
+ try {
+ wrapped = this.wrapped = (X509Certificate) OpenSSLContext.X509_CERT_FACTORY.generateCertificate(
+ new ByteArrayInputStream(bytes));
+ } catch (CertificateException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ return wrapped;
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/Constants$root.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/Constants$root.java
new file mode 100644
index 0000000000..2359448a3b
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/Constants$root.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class Constants$root {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private Constants$root() {}
+ static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN;
+ static final OfByte C_CHAR$LAYOUT = JAVA_BYTE;
+ static final OfShort C_SHORT$LAYOUT = JAVA_SHORT;
+ static final OfInt C_INT$LAYOUT = JAVA_INT;
+ static final OfLong C_LONG$LAYOUT = JAVA_LONG;
+ static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG;
+ static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT;
+ static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE;
+ static final AddressLayout C_POINTER$LAYOUT = ADDRESS.withByteAlignment(8).withTargetLayout(MemoryLayout.sequenceLayout(Constants$root.C_CHAR$LAYOUT));
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/RuntimeHelper.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/RuntimeHelper.java
new file mode 100644
index 0000000000..beab875552
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/RuntimeHelper.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.openssl;
+// Generated by jextract
+
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.Arena;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.ValueLayout;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static java.lang.foreign.Linker.*;
+import static java.lang.foreign.ValueLayout.*;
+
+final class RuntimeHelper {
+
+ private static final Linker LINKER = Linker.nativeLinker();
+ private static final ClassLoader LOADER = RuntimeHelper.class.getClassLoader();
+ private static final MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup();
+ private static final SymbolLookup SYMBOL_LOOKUP;
+ private static final SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); };
+
+ final static SegmentAllocator CONSTANT_ALLOCATOR =
+ (size, align) -> Arena.ofAuto().allocate(size, align);
+
+ static {
+ System.loadLibrary("ssl");
+ SymbolLookup loaderLookup = SymbolLookup.loaderLookup();
+ SYMBOL_LOOKUP = name -> loaderLookup.find(name).or(() -> LINKER.defaultLookup().find(name));
+ }
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private RuntimeHelper() {}
+
+ static <T> T requireNonNull(T obj, String symbolName) {
+ if (obj == null) {
+ throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName);
+ }
+ return obj;
+ }
+
+ static MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) {
+ return SYMBOL_LOOKUP.find(name)
+ .map(s -> s.reinterpret(layout.byteSize()))
+ .orElse(null);
+ }
+
+ static MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) {
+ return SYMBOL_LOOKUP.find(name).
+ map(addr -> LINKER.downcallHandle(addr, fdesc)).
+ orElse(null);
+ }
+
+ static MethodHandle downcallHandle(FunctionDescriptor fdesc) {
+ return LINKER.downcallHandle(fdesc);
+ }
+
+ static MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) {
+ return SYMBOL_LOOKUP.find(name).
+ map(addr -> VarargsInvoker.make(addr, fdesc)).
+ orElse(null);
+ }
+
+ static MethodHandle upcallHandle(Class<?> fi, String name, FunctionDescriptor fdesc) {
+ try {
+ return MH_LOOKUP.findVirtual(fi, name, fdesc.toMethodType());
+ } catch (Throwable ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+ static <Z> MemorySegment upcallStub(MethodHandle fiHandle, Z z, FunctionDescriptor fdesc, Arena scope) {
+ try {
+ fiHandle = fiHandle.bindTo(z);
+ return LINKER.upcallStub(fiHandle, fdesc, scope);
+ } catch (Throwable ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+ static MemorySegment asArray(MemorySegment addr, MemoryLayout layout, int numElements, Arena arena) {
+ return addr.reinterpret(numElements * layout.byteSize(), arena, null);
+ }
+
+ // Internals only below this point
+
+ private static final class VarargsInvoker {
+ private static final MethodHandle INVOKE_MH;
+ private final MemorySegment symbol;
+ private final FunctionDescriptor function;
+
+ private VarargsInvoker(MemorySegment symbol, FunctionDescriptor function) {
+ this.symbol = symbol;
+ this.function = function;
+ }
+
+ static {
+ try {
+ INVOKE_MH = MethodHandles.lookup().findVirtual(VarargsInvoker.class, "invoke", MethodType.methodType(Object.class, SegmentAllocator.class, Object[].class));
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) {
+ VarargsInvoker invoker = new VarargsInvoker(symbol, function);
+ MethodHandle handle = INVOKE_MH.bindTo(invoker).asCollector(Object[].class, function.argumentLayouts().size() + 1);
+ MethodType mtype = MethodType.methodType(function.returnLayout().isPresent() ? carrier(function.returnLayout().get(), true) : void.class);
+ for (MemoryLayout layout : function.argumentLayouts()) {
+ mtype = mtype.appendParameterTypes(carrier(layout, false));
+ }
+ mtype = mtype.appendParameterTypes(Object[].class);
+ boolean needsAllocator = function.returnLayout().isPresent() &&
+ function.returnLayout().get() instanceof GroupLayout;
+ if (needsAllocator) {
+ mtype = mtype.insertParameterTypes(0, SegmentAllocator.class);
+ } else {
+ handle = MethodHandles.insertArguments(handle, 0, THROWING_ALLOCATOR);
+ }
+ return handle.asType(mtype);
+ }
+
+ static Class<?> carrier(MemoryLayout layout, boolean ret) {
+ if (layout instanceof ValueLayout valueLayout) {
+ return valueLayout.carrier();
+ } else if (layout instanceof GroupLayout) {
+ return MemorySegment.class;
+ } else {
+ throw new AssertionError("Cannot get here!");
+ }
+ }
+
+ private Object invoke(SegmentAllocator allocator, Object[] args) throws Throwable {
+ // one trailing Object[]
+ int nNamedArgs = function.argumentLayouts().size();
+ assert(args.length == nNamedArgs + 1);
+ // The last argument is the array of vararg collector
+ Object[] unnamedArgs = (Object[]) args[args.length - 1];
+
+ int argsCount = nNamedArgs + unnamedArgs.length;
+ Class<?>[] argTypes = new Class<?>[argsCount];
+ MemoryLayout[] argLayouts = new MemoryLayout[nNamedArgs + unnamedArgs.length];
+
+ int pos = 0;
+ for (pos = 0; pos < nNamedArgs; pos++) {
+ argLayouts[pos] = function.argumentLayouts().get(pos);
+ }
+
+ assert pos == nNamedArgs;
+ for (Object o: unnamedArgs) {
+ argLayouts[pos] = variadicLayout(normalize(o.getClass()));
+ pos++;
+ }
+ assert pos == argsCount;
+
+ FunctionDescriptor f = (function.returnLayout().isEmpty()) ?
+ FunctionDescriptor.ofVoid(argLayouts) :
+ FunctionDescriptor.of(function.returnLayout().get(), argLayouts);
+ MethodHandle mh = LINKER.downcallHandle(symbol, f);
+ boolean needsAllocator = function.returnLayout().isPresent() &&
+ function.returnLayout().get() instanceof GroupLayout;
+ if (needsAllocator) {
+ mh = mh.bindTo(allocator);
+ }
+ // flatten argument list so that it can be passed to an asSpreader MH
+ Object[] allArgs = new Object[nNamedArgs + unnamedArgs.length];
+ System.arraycopy(args, 0, allArgs, 0, nNamedArgs);
+ System.arraycopy(unnamedArgs, 0, allArgs, nNamedArgs, unnamedArgs.length);
+
+ return mh.asSpreader(Object[].class, argsCount).invoke(allArgs);
+ }
+
+ private static Class<?> unboxIfNeeded(Class<?> clazz) {
+ if (clazz == Boolean.class) {
+ return boolean.class;
+ } else if (clazz == Void.class) {
+ return void.class;
+ } else if (clazz == Byte.class) {
+ return byte.class;
+ } else if (clazz == Character.class) {
+ return char.class;
+ } else if (clazz == Short.class) {
+ return short.class;
+ } else if (clazz == Integer.class) {
+ return int.class;
+ } else if (clazz == Long.class) {
+ return long.class;
+ } else if (clazz == Float.class) {
+ return float.class;
+ } else if (clazz == Double.class) {
+ return double.class;
+ } else {
+ return clazz;
+ }
+ }
+
+ private Class<?> promote(Class<?> c) {
+ if (c == byte.class || c == char.class || c == short.class || c == int.class) {
+ return long.class;
+ } else if (c == float.class) {
+ return double.class;
+ } else {
+ return c;
+ }
+ }
+
+ private Class<?> normalize(Class<?> c) {
+ c = unboxIfNeeded(c);
+ if (c.isPrimitive()) {
+ return promote(c);
+ }
+ if (c == MemorySegment.class) {
+ return MemorySegment.class;
+ }
+ throw new IllegalArgumentException("Invalid type for ABI: " + c.getTypeName());
+ }
+
+ private MemoryLayout variadicLayout(Class<?> c) {
+ if (c == long.class) {
+ return JAVA_LONG;
+ } else if (c == double.class) {
+ return JAVA_DOUBLE;
+ } else if (c == MemorySegment.class) {
+ return ADDRESS;
+ } else {
+ throw new IllegalArgumentException("Unhandled variadic argument class: " + c);
+ }
+ }
+ }
+}
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_CTX_set_cert_verify_callback$cb.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_CTX_set_cert_verify_callback$cb.java
new file mode 100644
index 0000000000..4686d04ca0
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_CTX_set_cert_verify_callback$cb.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+/**
+ * {@snippet :
+ * int (*SSL_CTX_set_cert_verify_callback$cb)(X509_STORE_CTX*,void*);
+ * }
+ */
+public interface SSL_CTX_set_cert_verify_callback$cb {
+
+ int apply(java.lang.foreign.MemorySegment _x0, java.lang.foreign.MemorySegment _x1);
+ static MemorySegment allocate(SSL_CTX_set_cert_verify_callback$cb fi, Arena scope) {
+ return RuntimeHelper.upcallStub(constants$15.SSL_CTX_set_cert_verify_callback$cb_UP$MH, fi, constants$15.SSL_CTX_set_cert_verify_callback$cb$FUNC, scope);
+ }
+ static SSL_CTX_set_cert_verify_callback$cb ofAddress(MemorySegment addr, Arena arena) {
+ MemorySegment symbol = addr.reinterpret(arena, null);
+ return (java.lang.foreign.MemorySegment __x0, java.lang.foreign.MemorySegment __x1) -> {
+ try {
+ return (int)constants$15.SSL_CTX_set_cert_verify_callback$cb_DOWN$MH.invokeExact(symbol, __x0, __x1);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ };
+ }
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_CTX_set_tmp_dh_callback$dh.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_CTX_set_tmp_dh_callback$dh.java
new file mode 100644
index 0000000000..77a68cda04
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_CTX_set_tmp_dh_callback$dh.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+/**
+ * {@snippet :
+ * DH* (*SSL_CTX_set_tmp_dh_callback$dh)(SSL*,int,int);
+ * }
+ */
+public interface SSL_CTX_set_tmp_dh_callback$dh {
+
+ java.lang.foreign.MemorySegment apply(java.lang.foreign.MemorySegment _x0, int _x1, int _x2);
+ static MemorySegment allocate(SSL_CTX_set_tmp_dh_callback$dh fi, Arena scope) {
+ return RuntimeHelper.upcallStub(constants$21.SSL_CTX_set_tmp_dh_callback$dh_UP$MH, fi, constants$21.SSL_CTX_set_tmp_dh_callback$dh$FUNC, scope);
+ }
+ static SSL_CTX_set_tmp_dh_callback$dh ofAddress(MemorySegment addr, Arena arena) {
+ MemorySegment symbol = addr.reinterpret(arena, null);
+ return (java.lang.foreign.MemorySegment __x0, int __x1, int __x2) -> {
+ try {
+ return (java.lang.foreign.MemorySegment)constants$22.SSL_CTX_set_tmp_dh_callback$dh_DOWN$MH.invokeExact(symbol, __x0, __x1, __x2);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ };
+ }
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_set_info_callback$cb.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_set_info_callback$cb.java
new file mode 100644
index 0000000000..16b7144980
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/SSL_set_info_callback$cb.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+/**
+ * {@snippet :
+ * void (*SSL_set_info_callback$cb)(const SSL*,int,int);
+ * }
+ */
+public interface SSL_set_info_callback$cb {
+
+ void apply(java.lang.foreign.MemorySegment _x0, int _x1, int _x2);
+ static MemorySegment allocate(SSL_set_info_callback$cb fi, Arena scope) {
+ return RuntimeHelper.upcallStub(constants$21.SSL_set_info_callback$cb_UP$MH, fi, constants$21.SSL_set_info_callback$cb$FUNC, scope);
+ }
+ static SSL_set_info_callback$cb ofAddress(MemorySegment addr, Arena arena) {
+ MemorySegment symbol = addr.reinterpret(arena, null);
+ return (java.lang.foreign.MemorySegment __x0, int __x1, int __x2) -> {
+ try {
+ constants$21.SSL_set_info_callback$cb_DOWN$MH.invokeExact(symbol, __x0, __x1, __x2);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ };
+ }
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$0.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$0.java
new file mode 100644
index 0000000000..60a76fd651
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$0.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$0 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$0() {}
+ static final FunctionDescriptor OPENSSL_sk_num$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OPENSSL_sk_num$MH = RuntimeHelper.downcallHandle(
+ "OPENSSL_sk_num",
+ constants$0.OPENSSL_sk_num$FUNC
+ );
+ static final FunctionDescriptor OPENSSL_sk_value$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle OPENSSL_sk_value$MH = RuntimeHelper.downcallHandle(
+ "OPENSSL_sk_value",
+ constants$0.OPENSSL_sk_value$FUNC
+ );
+ static final FunctionDescriptor OpenSSL_version_num$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT);
+ static final MethodHandle OpenSSL_version_num$MH = RuntimeHelper.downcallHandle(
+ "OpenSSL_version_num",
+ constants$0.OpenSSL_version_num$FUNC
+ );
+ static final FunctionDescriptor OpenSSL_version$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle OpenSSL_version$MH = RuntimeHelper.downcallHandle(
+ "OpenSSL_version",
+ constants$0.OpenSSL_version$FUNC
+ );
+ static final FunctionDescriptor CRYPTO_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle CRYPTO_free$MH = RuntimeHelper.downcallHandle(
+ "CRYPTO_free",
+ constants$0.CRYPTO_free$FUNC
+ );
+ static final FunctionDescriptor BIO_ctrl_pending$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BIO_ctrl_pending$MH = RuntimeHelper.downcallHandle(
+ "BIO_ctrl_pending",
+ constants$0.BIO_ctrl_pending$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$1.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$1.java
new file mode 100644
index 0000000000..55942ad213
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$1.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$1 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$1() {}
+ static final FunctionDescriptor BIO_s_file$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle BIO_s_file$MH = RuntimeHelper.downcallHandle(
+ "BIO_s_file",
+ constants$1.BIO_s_file$FUNC
+ );
+ static final FunctionDescriptor BIO_new_file$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BIO_new_file$MH = RuntimeHelper.downcallHandle(
+ "BIO_new_file",
+ constants$1.BIO_new_file$FUNC
+ );
+ static final FunctionDescriptor BIO_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BIO_new$MH = RuntimeHelper.downcallHandle(
+ "BIO_new",
+ constants$1.BIO_new$FUNC
+ );
+ static final FunctionDescriptor BIO_free$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BIO_free$MH = RuntimeHelper.downcallHandle(
+ "BIO_free",
+ constants$1.BIO_free$FUNC
+ );
+ static final FunctionDescriptor BIO_read$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle BIO_read$MH = RuntimeHelper.downcallHandle(
+ "BIO_read",
+ constants$1.BIO_read$FUNC
+ );
+ static final FunctionDescriptor BIO_write$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle BIO_write$MH = RuntimeHelper.downcallHandle(
+ "BIO_write",
+ constants$1.BIO_write$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$10.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$10.java
new file mode 100644
index 0000000000..dda8ba2ede
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$10.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$10 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$10() {}
+ static final FunctionDescriptor PEM_read_bio_ECPKParameters$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle PEM_read_bio_ECPKParameters$MH = RuntimeHelper.downcallHandle(
+ "PEM_read_bio_ECPKParameters",
+ constants$10.PEM_read_bio_ECPKParameters$FUNC
+ );
+ static final FunctionDescriptor PEM_read_bio_DHparams$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle PEM_read_bio_DHparams$MH = RuntimeHelper.downcallHandle(
+ "PEM_read_bio_DHparams",
+ constants$10.PEM_read_bio_DHparams$FUNC
+ );
+ static final FunctionDescriptor PEM_read_bio_PrivateKey$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle PEM_read_bio_PrivateKey$MH = RuntimeHelper.downcallHandle(
+ "PEM_read_bio_PrivateKey",
+ constants$10.PEM_read_bio_PrivateKey$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_get_options$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_get_options$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_get_options",
+ constants$10.SSL_CTX_get_options$FUNC
+ );
+ static final FunctionDescriptor SSL_get_options$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_options$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_options",
+ constants$10.SSL_get_options$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_clear_options$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_clear_options$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_clear_options",
+ constants$10.SSL_CTX_clear_options$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$11.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$11.java
new file mode 100644
index 0000000000..4e57c7f21a
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$11.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$11 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$11() {}
+ static final FunctionDescriptor SSL_CTX_set_options$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_options$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_options",
+ constants$11.SSL_CTX_set_options$FUNC
+ );
+ static final FunctionDescriptor SSL_set_options$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle SSL_set_options$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_options",
+ constants$11.SSL_set_options$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_alpn_select_cb$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_alpn_select_cb$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_alpn_select_cb",
+ constants$11.SSL_CTX_set_alpn_select_cb$FUNC
+ );
+ static final FunctionDescriptor SSL_get0_alpn_selected$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get0_alpn_selected$MH = RuntimeHelper.downcallHandle(
+ "SSL_get0_alpn_selected",
+ constants$11.SSL_get0_alpn_selected$FUNC
+ );
+ static final FunctionDescriptor SSL_in_init$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_in_init$MH = RuntimeHelper.downcallHandle(
+ "SSL_in_init",
+ constants$11.SSL_in_init$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_cipher_list$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_cipher_list$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_cipher_list",
+ constants$11.SSL_CTX_set_cipher_list$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$12.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$12.java
new file mode 100644
index 0000000000..1fa3c12a0b
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$12.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$12 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$12() {}
+ static final FunctionDescriptor SSL_CTX_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_new$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_new",
+ constants$12.SSL_CTX_new$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_free$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_free",
+ constants$12.SSL_CTX_free$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_timeout$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_timeout$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_timeout",
+ constants$12.SSL_CTX_set_timeout$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_get_timeout$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_get_timeout$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_get_timeout",
+ constants$12.SSL_CTX_get_timeout$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_get_cert_store$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_get_cert_store$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_get_cert_store",
+ constants$12.SSL_CTX_get_cert_store$FUNC
+ );
+ static final FunctionDescriptor SSL_get_current_cipher$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_current_cipher$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_current_cipher",
+ constants$12.SSL_get_current_cipher$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$13.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$13.java
new file mode 100644
index 0000000000..bcab07b600
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$13.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$13 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$13() {}
+ static final FunctionDescriptor SSL_CIPHER_get_name$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CIPHER_get_name$MH = RuntimeHelper.downcallHandle(
+ "SSL_CIPHER_get_name",
+ constants$13.SSL_CIPHER_get_name$FUNC
+ );
+ static final FunctionDescriptor SSL_CIPHER_get_kx_nid$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CIPHER_get_kx_nid$MH = RuntimeHelper.downcallHandle(
+ "SSL_CIPHER_get_kx_nid",
+ constants$13.SSL_CIPHER_get_kx_nid$FUNC
+ );
+ static final FunctionDescriptor SSL_CIPHER_get_auth_nid$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CIPHER_get_auth_nid$MH = RuntimeHelper.downcallHandle(
+ "SSL_CIPHER_get_auth_nid",
+ constants$13.SSL_CIPHER_get_auth_nid$FUNC
+ );
+ static final FunctionDescriptor SSL_pending$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_pending$MH = RuntimeHelper.downcallHandle(
+ "SSL_pending",
+ constants$13.SSL_pending$FUNC
+ );
+ static final FunctionDescriptor SSL_set_bio$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_set_bio$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_bio",
+ constants$13.SSL_set_bio$FUNC
+ );
+ static final FunctionDescriptor SSL_set_cipher_list$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_set_cipher_list$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_cipher_list",
+ constants$13.SSL_set_cipher_list$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$14.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$14.java
new file mode 100644
index 0000000000..b36fcb3ade
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$14.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$14 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$14() {}
+ static final FunctionDescriptor SSL_CTX_set_ciphersuites$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_ciphersuites$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_ciphersuites",
+ constants$14.SSL_CTX_set_ciphersuites$FUNC
+ );
+ static final FunctionDescriptor SSL_set_verify$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_set_verify$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_verify",
+ constants$14.SSL_set_verify$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_use_certificate_chain_file$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_use_certificate_chain_file$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_use_certificate_chain_file",
+ constants$14.SSL_CTX_use_certificate_chain_file$FUNC
+ );
+ static final FunctionDescriptor SSL_load_client_CA_file$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_load_client_CA_file$MH = RuntimeHelper.downcallHandle(
+ "SSL_load_client_CA_file",
+ constants$14.SSL_load_client_CA_file$FUNC
+ );
+ static final FunctionDescriptor SSL_add_file_cert_subjects_to_stack$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_add_file_cert_subjects_to_stack$MH = RuntimeHelper.downcallHandle(
+ "SSL_add_file_cert_subjects_to_stack",
+ constants$14.SSL_add_file_cert_subjects_to_stack$FUNC
+ );
+ static final FunctionDescriptor SSL_SESSION_get_time$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_SESSION_get_time$MH = RuntimeHelper.downcallHandle(
+ "SSL_SESSION_get_time",
+ constants$14.SSL_SESSION_get_time$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$15.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$15.java
new file mode 100644
index 0000000000..a3a26ec317
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$15.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$15 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$15() {}
+ static final FunctionDescriptor SSL_SESSION_get_id$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_SESSION_get_id$MH = RuntimeHelper.downcallHandle(
+ "SSL_SESSION_get_id",
+ constants$15.SSL_SESSION_get_id$FUNC
+ );
+ static final FunctionDescriptor SSL_get1_peer_certificate$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get1_peer_certificate$MH = RuntimeHelper.downcallHandle(
+ "SSL_get1_peer_certificate",
+ constants$15.SSL_get1_peer_certificate$FUNC
+ );
+ static final FunctionDescriptor SSL_get_peer_cert_chain$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_peer_cert_chain$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_peer_cert_chain",
+ constants$15.SSL_get_peer_cert_chain$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_verify$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_verify$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_verify",
+ constants$15.SSL_CTX_set_verify$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_cert_verify_callback$cb$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final FunctionDescriptor SSL_CTX_set_cert_verify_callback$cb_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_cert_verify_callback$cb_UP$MH = RuntimeHelper.upcallHandle(SSL_CTX_set_cert_verify_callback$cb.class, "apply", constants$15.SSL_CTX_set_cert_verify_callback$cb_UP$FUNC);
+ static final FunctionDescriptor SSL_CTX_set_cert_verify_callback$cb_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_cert_verify_callback$cb_DOWN$MH = RuntimeHelper.downcallHandle(
+ constants$15.SSL_CTX_set_cert_verify_callback$cb_DOWN$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$16.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$16.java
new file mode 100644
index 0000000000..c2d5833d2d
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$16.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$16 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$16() {}
+ static final FunctionDescriptor SSL_CTX_set_cert_verify_callback$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_cert_verify_callback$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_cert_verify_callback",
+ constants$16.SSL_CTX_set_cert_verify_callback$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_use_PrivateKey$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_use_PrivateKey$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_use_PrivateKey",
+ constants$16.SSL_CTX_use_PrivateKey$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_use_certificate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_use_certificate$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_use_certificate",
+ constants$16.SSL_CTX_use_certificate$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_default_passwd_cb$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_default_passwd_cb$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_default_passwd_cb",
+ constants$16.SSL_CTX_set_default_passwd_cb$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_check_private_key$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_check_private_key$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_check_private_key",
+ constants$16.SSL_CTX_check_private_key$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_session_id_context$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_session_id_context$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_session_id_context",
+ constants$16.SSL_CTX_set_session_id_context$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$17.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$17.java
new file mode 100644
index 0000000000..0d56bb9da5
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$17.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$17 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$17() {}
+ static final FunctionDescriptor SSL_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_new$MH = RuntimeHelper.downcallHandle(
+ "SSL_new",
+ constants$17.SSL_new$FUNC
+ );
+ static final FunctionDescriptor SSL_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_free$MH = RuntimeHelper.downcallHandle(
+ "SSL_free",
+ constants$17.SSL_free$FUNC
+ );
+ static final FunctionDescriptor SSL_read$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_read$MH = RuntimeHelper.downcallHandle(
+ "SSL_read",
+ constants$17.SSL_read$FUNC
+ );
+ static final FunctionDescriptor SSL_write$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_write$MH = RuntimeHelper.downcallHandle(
+ "SSL_write",
+ constants$17.SSL_write$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_ctrl$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_ctrl$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_ctrl",
+ constants$17.SSL_CTX_ctrl$FUNC
+ );
+ static final FunctionDescriptor SSL_get_version$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_version$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_version",
+ constants$17.SSL_get_version$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$18.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$18.java
new file mode 100644
index 0000000000..e80b1c1201
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$18.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$18 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$18() {}
+ static final FunctionDescriptor TLS_server_method$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle TLS_server_method$MH = RuntimeHelper.downcallHandle(
+ "TLS_server_method",
+ constants$18.TLS_server_method$FUNC
+ );
+ static final FunctionDescriptor SSL_get_ciphers$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_ciphers$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_ciphers",
+ constants$18.SSL_get_ciphers$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_get_ciphers$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_get_ciphers$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_get_ciphers",
+ constants$18.SSL_CTX_get_ciphers$FUNC
+ );
+ static final FunctionDescriptor SSL_do_handshake$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_do_handshake$MH = RuntimeHelper.downcallHandle(
+ "SSL_do_handshake",
+ constants$18.SSL_do_handshake$FUNC
+ );
+ static final FunctionDescriptor SSL_renegotiate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_renegotiate$MH = RuntimeHelper.downcallHandle(
+ "SSL_renegotiate",
+ constants$18.SSL_renegotiate$FUNC
+ );
+ static final FunctionDescriptor SSL_renegotiate_pending$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_renegotiate_pending$MH = RuntimeHelper.downcallHandle(
+ "SSL_renegotiate_pending",
+ constants$18.SSL_renegotiate_pending$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$19.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$19.java
new file mode 100644
index 0000000000..d213369fd8
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$19.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$19 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$19() {}
+ static final FunctionDescriptor SSL_shutdown$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_shutdown$MH = RuntimeHelper.downcallHandle(
+ "SSL_shutdown",
+ constants$19.SSL_shutdown$FUNC
+ );
+ static final FunctionDescriptor SSL_verify_client_post_handshake$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_verify_client_post_handshake$MH = RuntimeHelper.downcallHandle(
+ "SSL_verify_client_post_handshake",
+ constants$19.SSL_verify_client_post_handshake$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_client_CA_list$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_client_CA_list$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_client_CA_list",
+ constants$19.SSL_CTX_set_client_CA_list$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_get_client_CA_list$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_get_client_CA_list$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_get_client_CA_list",
+ constants$19.SSL_CTX_get_client_CA_list$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_add_client_CA$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_add_client_CA$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_add_client_CA",
+ constants$19.SSL_CTX_add_client_CA$FUNC
+ );
+ static final FunctionDescriptor SSL_set_connect_state$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_set_connect_state$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_connect_state",
+ constants$19.SSL_set_connect_state$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$2.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$2.java
new file mode 100644
index 0000000000..4966508649
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$2.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$2 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$2() {}
+ static final FunctionDescriptor BIO_ctrl$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BIO_ctrl$MH = RuntimeHelper.downcallHandle(
+ "BIO_ctrl",
+ constants$2.BIO_ctrl$FUNC
+ );
+ static final FunctionDescriptor BIO_s_mem$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle BIO_s_mem$MH = RuntimeHelper.downcallHandle(
+ "BIO_s_mem",
+ constants$2.BIO_s_mem$FUNC
+ );
+ static final FunctionDescriptor BIO_s_bio$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle BIO_s_bio$MH = RuntimeHelper.downcallHandle(
+ "BIO_s_bio",
+ constants$2.BIO_s_bio$FUNC
+ );
+ static final FunctionDescriptor BIO_new_bio_pair$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle BIO_new_bio_pair$MH = RuntimeHelper.downcallHandle(
+ "BIO_new_bio_pair",
+ constants$2.BIO_new_bio_pair$FUNC
+ );
+ static final FunctionDescriptor BN_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle BN_new$MH = RuntimeHelper.downcallHandle(
+ "BN_new",
+ constants$2.BN_new$FUNC
+ );
+ static final FunctionDescriptor BN_set_word$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle BN_set_word$MH = RuntimeHelper.downcallHandle(
+ "BN_set_word",
+ constants$2.BN_set_word$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$20.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$20.java
new file mode 100644
index 0000000000..7c0f69a470
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$20.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$20 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$20() {}
+ static final FunctionDescriptor SSL_set_accept_state$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_set_accept_state$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_accept_state",
+ constants$20.SSL_set_accept_state$FUNC
+ );
+ static final FunctionDescriptor SSL_get_privatekey$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_privatekey$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_privatekey",
+ constants$20.SSL_get_privatekey$FUNC
+ );
+ static final FunctionDescriptor SSL_get_shutdown$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_shutdown$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_shutdown",
+ constants$20.SSL_get_shutdown$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_default_verify_paths$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_default_verify_paths$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_default_verify_paths",
+ constants$20.SSL_CTX_set_default_verify_paths$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_load_verify_locations$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_load_verify_locations$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_load_verify_locations",
+ constants$20.SSL_CTX_load_verify_locations$FUNC
+ );
+ static final FunctionDescriptor SSL_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_get_session$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_session",
+ constants$20.SSL_get_session$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$21.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$21.java
new file mode 100644
index 0000000000..0832c55217
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$21.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$21 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$21() {}
+ static final FunctionDescriptor SSL_set_info_callback$cb$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final FunctionDescriptor SSL_set_info_callback$cb_UP$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_set_info_callback$cb_UP$MH = RuntimeHelper.upcallHandle(SSL_set_info_callback$cb.class, "apply", constants$21.SSL_set_info_callback$cb_UP$FUNC);
+ static final FunctionDescriptor SSL_set_info_callback$cb_DOWN$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_set_info_callback$cb_DOWN$MH = RuntimeHelper.downcallHandle(
+ constants$21.SSL_set_info_callback$cb_DOWN$FUNC
+ );
+ static final FunctionDescriptor SSL_set_info_callback$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_set_info_callback$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_info_callback",
+ constants$21.SSL_set_info_callback$FUNC
+ );
+ static final FunctionDescriptor SSL_set_verify_result$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle SSL_set_verify_result$MH = RuntimeHelper.downcallHandle(
+ "SSL_set_verify_result",
+ constants$21.SSL_set_verify_result$FUNC
+ );
+ static final FunctionDescriptor SSL_get_ex_data_X509_STORE_CTX_idx$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
+ static final MethodHandle SSL_get_ex_data_X509_STORE_CTX_idx$MH = RuntimeHelper.downcallHandle(
+ "SSL_get_ex_data_X509_STORE_CTX_idx",
+ constants$21.SSL_get_ex_data_X509_STORE_CTX_idx$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_tmp_dh_callback$dh$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final FunctionDescriptor SSL_CTX_set_tmp_dh_callback$dh_UP$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_tmp_dh_callback$dh_UP$MH = RuntimeHelper.upcallHandle(SSL_CTX_set_tmp_dh_callback$dh.class, "apply", constants$21.SSL_CTX_set_tmp_dh_callback$dh_UP$FUNC);
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$22.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$22.java
new file mode 100644
index 0000000000..6b2c032610
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$22.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$22 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$22() {}
+ static final FunctionDescriptor SSL_CTX_set_tmp_dh_callback$dh_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_tmp_dh_callback$dh_DOWN$MH = RuntimeHelper.downcallHandle(
+ constants$22.SSL_CTX_set_tmp_dh_callback$dh_DOWN$FUNC
+ );
+ static final FunctionDescriptor SSL_CTX_set_tmp_dh_callback$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CTX_set_tmp_dh_callback$MH = RuntimeHelper.downcallHandle(
+ "SSL_CTX_set_tmp_dh_callback",
+ constants$22.SSL_CTX_set_tmp_dh_callback$FUNC
+ );
+ static final FunctionDescriptor SSL_CONF_CTX_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle SSL_CONF_CTX_new$MH = RuntimeHelper.downcallHandle(
+ "SSL_CONF_CTX_new",
+ constants$22.SSL_CONF_CTX_new$FUNC
+ );
+ static final FunctionDescriptor SSL_CONF_CTX_finish$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CONF_CTX_finish$MH = RuntimeHelper.downcallHandle(
+ "SSL_CONF_CTX_finish",
+ constants$22.SSL_CONF_CTX_finish$FUNC
+ );
+ static final FunctionDescriptor SSL_CONF_CTX_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CONF_CTX_free$MH = RuntimeHelper.downcallHandle(
+ "SSL_CONF_CTX_free",
+ constants$22.SSL_CONF_CTX_free$FUNC
+ );
+ static final FunctionDescriptor SSL_CONF_CTX_set_flags$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle SSL_CONF_CTX_set_flags$MH = RuntimeHelper.downcallHandle(
+ "SSL_CONF_CTX_set_flags",
+ constants$22.SSL_CONF_CTX_set_flags$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$23.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$23.java
new file mode 100644
index 0000000000..234851e93c
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$23.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$23 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$23() {}
+ static final FunctionDescriptor SSL_CONF_CTX_set_ssl_ctx$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CONF_CTX_set_ssl_ctx$MH = RuntimeHelper.downcallHandle(
+ "SSL_CONF_CTX_set_ssl_ctx",
+ constants$23.SSL_CONF_CTX_set_ssl_ctx$FUNC
+ );
+ static final FunctionDescriptor SSL_CONF_cmd$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CONF_cmd$MH = RuntimeHelper.downcallHandle(
+ "SSL_CONF_cmd",
+ constants$23.SSL_CONF_cmd$FUNC
+ );
+ static final FunctionDescriptor SSL_CONF_cmd_value_type$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle SSL_CONF_cmd_value_type$MH = RuntimeHelper.downcallHandle(
+ "SSL_CONF_cmd_value_type",
+ constants$23.SSL_CONF_cmd_value_type$FUNC
+ );
+ static final FunctionDescriptor OPENSSL_init_ssl$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OPENSSL_init_ssl$MH = RuntimeHelper.downcallHandle(
+ "OPENSSL_init_ssl",
+ constants$23.OPENSSL_init_ssl$FUNC
+ );
+ static final FunctionDescriptor ERR_get_error$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT);
+ static final MethodHandle ERR_get_error$MH = RuntimeHelper.downcallHandle(
+ "ERR_get_error",
+ constants$23.ERR_get_error$FUNC
+ );
+ static final FunctionDescriptor ERR_peek_last_error$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT);
+ static final MethodHandle ERR_peek_last_error$MH = RuntimeHelper.downcallHandle(
+ "ERR_peek_last_error",
+ constants$23.ERR_peek_last_error$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$24.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$24.java
new file mode 100644
index 0000000000..a8a2e4201c
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$24.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$24 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$24() {}
+ static final FunctionDescriptor ERR_clear_error$FUNC = FunctionDescriptor.ofVoid();
+ static final MethodHandle ERR_clear_error$MH = RuntimeHelper.downcallHandle(
+ "ERR_clear_error",
+ constants$24.ERR_clear_error$FUNC
+ );
+ static final FunctionDescriptor ERR_error_string$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle ERR_error_string$MH = RuntimeHelper.downcallHandle(
+ "ERR_error_string",
+ constants$24.ERR_error_string$FUNC
+ );
+ static final FunctionDescriptor PKCS12_verify_mac$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle PKCS12_verify_mac$MH = RuntimeHelper.downcallHandle(
+ "PKCS12_verify_mac",
+ constants$24.PKCS12_verify_mac$FUNC
+ );
+ static final FunctionDescriptor PKCS12_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle PKCS12_free$MH = RuntimeHelper.downcallHandle(
+ "PKCS12_free",
+ constants$24.PKCS12_free$FUNC
+ );
+ static final FunctionDescriptor PKCS12_parse$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle PKCS12_parse$MH = RuntimeHelper.downcallHandle(
+ "PKCS12_parse",
+ constants$24.PKCS12_parse$FUNC
+ );
+ static final FunctionDescriptor d2i_PKCS12_bio$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle d2i_PKCS12_bio$MH = RuntimeHelper.downcallHandle(
+ "d2i_PKCS12_bio",
+ constants$24.d2i_PKCS12_bio$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$25.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$25.java
new file mode 100644
index 0000000000..7eae50ad67
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$25.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$25 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$25() {}
+ static final FunctionDescriptor RAND_seed$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle RAND_seed$MH = RuntimeHelper.downcallHandle(
+ "RAND_seed",
+ constants$25.RAND_seed$FUNC
+ );
+ static final FunctionDescriptor RAND_load_file$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle RAND_load_file$MH = RuntimeHelper.downcallHandle(
+ "RAND_load_file",
+ constants$25.RAND_load_file$FUNC
+ );
+ static final FunctionDescriptor X509_check_issued$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_check_issued$MH = RuntimeHelper.downcallHandle(
+ "X509_check_issued",
+ constants$25.X509_check_issued$FUNC
+ );
+ static final FunctionDescriptor ENGINE_by_id$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle ENGINE_by_id$MH = RuntimeHelper.downcallHandle(
+ "ENGINE_by_id",
+ constants$25.ENGINE_by_id$FUNC
+ );
+ static final FunctionDescriptor ENGINE_register_all_complete$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
+ static final MethodHandle ENGINE_register_all_complete$MH = RuntimeHelper.downcallHandle(
+ "ENGINE_register_all_complete",
+ constants$25.ENGINE_register_all_complete$FUNC
+ );
+ static final FunctionDescriptor ENGINE_ctrl_cmd_string$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle ENGINE_ctrl_cmd_string$MH = RuntimeHelper.downcallHandle(
+ "ENGINE_ctrl_cmd_string",
+ constants$25.ENGINE_ctrl_cmd_string$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$26.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$26.java
new file mode 100644
index 0000000000..685a84ec1c
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$26.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$26 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$26() {}
+ static final FunctionDescriptor ENGINE_free$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle ENGINE_free$MH = RuntimeHelper.downcallHandle(
+ "ENGINE_free",
+ constants$26.ENGINE_free$FUNC
+ );
+ static final FunctionDescriptor ENGINE_load_private_key$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle ENGINE_load_private_key$MH = RuntimeHelper.downcallHandle(
+ "ENGINE_load_private_key",
+ constants$26.ENGINE_load_private_key$FUNC
+ );
+ static final FunctionDescriptor ENGINE_set_default$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle ENGINE_set_default$MH = RuntimeHelper.downcallHandle(
+ "ENGINE_set_default",
+ constants$26.ENGINE_set_default$FUNC
+ );
+ static final FunctionDescriptor OCSP_cert_to_id$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_cert_to_id$MH = RuntimeHelper.downcallHandle(
+ "OCSP_cert_to_id",
+ constants$26.OCSP_cert_to_id$FUNC
+ );
+ static final FunctionDescriptor OCSP_request_add0_id$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_request_add0_id$MH = RuntimeHelper.downcallHandle(
+ "OCSP_request_add0_id",
+ constants$26.OCSP_request_add0_id$FUNC
+ );
+ static final FunctionDescriptor OCSP_response_status$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_response_status$MH = RuntimeHelper.downcallHandle(
+ "OCSP_response_status",
+ constants$26.OCSP_response_status$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$27.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$27.java
new file mode 100644
index 0000000000..d6a8d897c9
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$27.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$27 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$27() {}
+ static final FunctionDescriptor OCSP_response_get1_basic$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_response_get1_basic$MH = RuntimeHelper.downcallHandle(
+ "OCSP_response_get1_basic",
+ constants$27.OCSP_response_get1_basic$FUNC
+ );
+ static final FunctionDescriptor OCSP_resp_get0$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle OCSP_resp_get0$MH = RuntimeHelper.downcallHandle(
+ "OCSP_resp_get0",
+ constants$27.OCSP_resp_get0$FUNC
+ );
+ static final FunctionDescriptor OCSP_resp_find$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle OCSP_resp_find$MH = RuntimeHelper.downcallHandle(
+ "OCSP_resp_find",
+ constants$27.OCSP_resp_find$FUNC
+ );
+ static final FunctionDescriptor OCSP_single_get0_status$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_single_get0_status$MH = RuntimeHelper.downcallHandle(
+ "OCSP_single_get0_status",
+ constants$27.OCSP_single_get0_status$FUNC
+ );
+ static final FunctionDescriptor OCSP_BASICRESP_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_BASICRESP_free$MH = RuntimeHelper.downcallHandle(
+ "OCSP_BASICRESP_free",
+ constants$27.OCSP_BASICRESP_free$FUNC
+ );
+ static final FunctionDescriptor OCSP_RESPONSE_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_RESPONSE_free$MH = RuntimeHelper.downcallHandle(
+ "OCSP_RESPONSE_free",
+ constants$27.OCSP_RESPONSE_free$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$28.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$28.java
new file mode 100644
index 0000000000..4df680b449
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$28.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$28 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$28() {}
+ static final FunctionDescriptor d2i_OCSP_RESPONSE$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle d2i_OCSP_RESPONSE$MH = RuntimeHelper.downcallHandle(
+ "d2i_OCSP_RESPONSE",
+ constants$28.d2i_OCSP_RESPONSE$FUNC
+ );
+ static final FunctionDescriptor OCSP_CERTID_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_CERTID_free$MH = RuntimeHelper.downcallHandle(
+ "OCSP_CERTID_free",
+ constants$28.OCSP_CERTID_free$FUNC
+ );
+ static final FunctionDescriptor OCSP_REQUEST_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle OCSP_REQUEST_new$MH = RuntimeHelper.downcallHandle(
+ "OCSP_REQUEST_new",
+ constants$28.OCSP_REQUEST_new$FUNC
+ );
+ static final FunctionDescriptor OCSP_REQUEST_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OCSP_REQUEST_free$MH = RuntimeHelper.downcallHandle(
+ "OCSP_REQUEST_free",
+ constants$28.OCSP_REQUEST_free$FUNC
+ );
+ static final FunctionDescriptor i2d_OCSP_REQUEST$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle i2d_OCSP_REQUEST$MH = RuntimeHelper.downcallHandle(
+ "i2d_OCSP_REQUEST",
+ constants$28.i2d_OCSP_REQUEST$FUNC
+ );
+ static final FunctionDescriptor OSSL_PROVIDER_get0_name$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle OSSL_PROVIDER_get0_name$MH = RuntimeHelper.downcallHandle(
+ "OSSL_PROVIDER_get0_name",
+ constants$28.OSSL_PROVIDER_get0_name$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$29.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$29.java
new file mode 100644
index 0000000000..71ff4b643e
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$29.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$29 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$29() {}
+ static final MemorySegment OPENSSL_FILE$SEGMENT = RuntimeHelper.CONSTANT_ALLOCATOR.allocateUtf8String("/tmp/jextract$5975327931591344605.h");
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$3.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$3.java
new file mode 100644
index 0000000000..cae0beeb17
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$3.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$3 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$3() {}
+ static final FunctionDescriptor BN_get_rfc2409_prime_768$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc2409_prime_768$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc2409_prime_768",
+ constants$3.BN_get_rfc2409_prime_768$FUNC
+ );
+ static final FunctionDescriptor BN_get_rfc2409_prime_1024$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc2409_prime_1024$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc2409_prime_1024",
+ constants$3.BN_get_rfc2409_prime_1024$FUNC
+ );
+ static final FunctionDescriptor BN_get_rfc3526_prime_1536$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc3526_prime_1536$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc3526_prime_1536",
+ constants$3.BN_get_rfc3526_prime_1536$FUNC
+ );
+ static final FunctionDescriptor BN_get_rfc3526_prime_2048$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc3526_prime_2048$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc3526_prime_2048",
+ constants$3.BN_get_rfc3526_prime_2048$FUNC
+ );
+ static final FunctionDescriptor BN_get_rfc3526_prime_3072$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc3526_prime_3072$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc3526_prime_3072",
+ constants$3.BN_get_rfc3526_prime_3072$FUNC
+ );
+ static final FunctionDescriptor BN_get_rfc3526_prime_4096$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc3526_prime_4096$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc3526_prime_4096",
+ constants$3.BN_get_rfc3526_prime_4096$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$4.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$4.java
new file mode 100644
index 0000000000..d4a247d5f7
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$4.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$4 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$4() {}
+ static final FunctionDescriptor BN_get_rfc3526_prime_6144$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc3526_prime_6144$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc3526_prime_6144",
+ constants$4.BN_get_rfc3526_prime_6144$FUNC
+ );
+ static final FunctionDescriptor BN_get_rfc3526_prime_8192$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle BN_get_rfc3526_prime_8192$MH = RuntimeHelper.downcallHandle(
+ "BN_get_rfc3526_prime_8192",
+ constants$4.BN_get_rfc3526_prime_8192$FUNC
+ );
+ static final FunctionDescriptor ASN1_STRING_length$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle ASN1_STRING_length$MH = RuntimeHelper.downcallHandle(
+ "ASN1_STRING_length",
+ constants$4.ASN1_STRING_length$FUNC
+ );
+ static final FunctionDescriptor ASN1_STRING_get0_data$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle ASN1_STRING_get0_data$MH = RuntimeHelper.downcallHandle(
+ "ASN1_STRING_get0_data",
+ constants$4.ASN1_STRING_get0_data$FUNC
+ );
+ static final FunctionDescriptor EVP_MD_get0_provider$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EVP_MD_get0_provider$MH = RuntimeHelper.downcallHandle(
+ "EVP_MD_get0_provider",
+ constants$4.EVP_MD_get0_provider$FUNC
+ );
+ static final FunctionDescriptor EVP_MD_fetch$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EVP_MD_fetch$MH = RuntimeHelper.downcallHandle(
+ "EVP_MD_fetch",
+ constants$4.EVP_MD_fetch$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$5.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$5.java
new file mode 100644
index 0000000000..67fb9fc829
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$5.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$5 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$5() {}
+ static final FunctionDescriptor EVP_MD_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EVP_MD_free$MH = RuntimeHelper.downcallHandle(
+ "EVP_MD_free",
+ constants$5.EVP_MD_free$FUNC
+ );
+ static final FunctionDescriptor EVP_PKEY_get_base_id$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EVP_PKEY_get_base_id$MH = RuntimeHelper.downcallHandle(
+ "EVP_PKEY_get_base_id",
+ constants$5.EVP_PKEY_get_base_id$FUNC
+ );
+ static final FunctionDescriptor EVP_PKEY_get_bits$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EVP_PKEY_get_bits$MH = RuntimeHelper.downcallHandle(
+ "EVP_PKEY_get_bits",
+ constants$5.EVP_PKEY_get_bits$FUNC
+ );
+ static final FunctionDescriptor EC_GROUP_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EC_GROUP_free$MH = RuntimeHelper.downcallHandle(
+ "EC_GROUP_free",
+ constants$5.EC_GROUP_free$FUNC
+ );
+ static final FunctionDescriptor EC_GROUP_get_curve_name$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EC_GROUP_get_curve_name$MH = RuntimeHelper.downcallHandle(
+ "EC_GROUP_get_curve_name",
+ constants$5.EC_GROUP_get_curve_name$FUNC
+ );
+ static final FunctionDescriptor EC_KEY_new_by_curve_name$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle EC_KEY_new_by_curve_name$MH = RuntimeHelper.downcallHandle(
+ "EC_KEY_new_by_curve_name",
+ constants$5.EC_KEY_new_by_curve_name$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$6.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$6.java
new file mode 100644
index 0000000000..76f2e37454
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$6.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$6 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$6() {}
+ static final FunctionDescriptor EC_KEY_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle EC_KEY_free$MH = RuntimeHelper.downcallHandle(
+ "EC_KEY_free",
+ constants$6.EC_KEY_free$FUNC
+ );
+ static final FunctionDescriptor DH_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle DH_new$MH = RuntimeHelper.downcallHandle(
+ "DH_new",
+ constants$6.DH_new$FUNC
+ );
+ static final FunctionDescriptor DH_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle DH_free$MH = RuntimeHelper.downcallHandle(
+ "DH_free",
+ constants$6.DH_free$FUNC
+ );
+ static final FunctionDescriptor DH_set0_pqg$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle DH_set0_pqg$MH = RuntimeHelper.downcallHandle(
+ "DH_set0_pqg",
+ constants$6.DH_set0_pqg$FUNC
+ );
+ static final FunctionDescriptor X509_STORE_set_flags$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle X509_STORE_set_flags$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_set_flags",
+ constants$6.X509_STORE_set_flags$FUNC
+ );
+ static final FunctionDescriptor X509_STORE_CTX_get0_untrusted$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_STORE_CTX_get0_untrusted$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_CTX_get0_untrusted",
+ constants$6.X509_STORE_CTX_get0_untrusted$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$7.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$7.java
new file mode 100644
index 0000000000..8fa95fdb6c
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$7.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$7 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$7() {}
+ static final FunctionDescriptor X509_STORE_add_lookup$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_STORE_add_lookup$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_add_lookup",
+ constants$7.X509_STORE_add_lookup$FUNC
+ );
+ static final FunctionDescriptor X509_LOOKUP_hash_dir$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle X509_LOOKUP_hash_dir$MH = RuntimeHelper.downcallHandle(
+ "X509_LOOKUP_hash_dir",
+ constants$7.X509_LOOKUP_hash_dir$FUNC
+ );
+ static final FunctionDescriptor X509_LOOKUP_file$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle X509_LOOKUP_file$MH = RuntimeHelper.downcallHandle(
+ "X509_LOOKUP_file",
+ constants$7.X509_LOOKUP_file$FUNC
+ );
+ static final FunctionDescriptor X509_LOOKUP_ctrl$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_LOOKUP_ctrl$MH = RuntimeHelper.downcallHandle(
+ "X509_LOOKUP_ctrl",
+ constants$7.X509_LOOKUP_ctrl$FUNC
+ );
+ static final FunctionDescriptor X509_STORE_CTX_get_ex_data$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle X509_STORE_CTX_get_ex_data$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_CTX_get_ex_data",
+ constants$7.X509_STORE_CTX_get_ex_data$FUNC
+ );
+ static final FunctionDescriptor X509_STORE_CTX_get_error$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_STORE_CTX_get_error$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_CTX_get_error",
+ constants$7.X509_STORE_CTX_get_error$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$8.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$8.java
new file mode 100644
index 0000000000..fc018122d2
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$8.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$8 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$8() {}
+ static final FunctionDescriptor X509_STORE_CTX_set_error$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle X509_STORE_CTX_set_error$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_CTX_set_error",
+ constants$8.X509_STORE_CTX_set_error$FUNC
+ );
+ static final FunctionDescriptor X509_STORE_CTX_get_error_depth$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_STORE_CTX_get_error_depth$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_CTX_get_error_depth",
+ constants$8.X509_STORE_CTX_get_error_depth$FUNC
+ );
+ static final FunctionDescriptor X509_STORE_CTX_get_current_cert$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_STORE_CTX_get_current_cert$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_CTX_get_current_cert",
+ constants$8.X509_STORE_CTX_get_current_cert$FUNC
+ );
+ static final FunctionDescriptor X509_STORE_CTX_get0_current_issuer$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_STORE_CTX_get0_current_issuer$MH = RuntimeHelper.downcallHandle(
+ "X509_STORE_CTX_get0_current_issuer",
+ constants$8.X509_STORE_CTX_get0_current_issuer$FUNC
+ );
+ static final FunctionDescriptor d2i_X509_bio$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle d2i_X509_bio$MH = RuntimeHelper.downcallHandle(
+ "d2i_X509_bio",
+ constants$8.d2i_X509_bio$FUNC
+ );
+ static final FunctionDescriptor X509_free$FUNC = FunctionDescriptor.ofVoid(
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_free$MH = RuntimeHelper.downcallHandle(
+ "X509_free",
+ constants$8.X509_free$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$9.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$9.java
new file mode 100644
index 0000000000..bc99139f11
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/constants$9.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+final class constants$9 {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private constants$9() {}
+ static final FunctionDescriptor d2i_X509$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_LONG_LONG$LAYOUT
+ );
+ static final MethodHandle d2i_X509$MH = RuntimeHelper.downcallHandle(
+ "d2i_X509",
+ constants$9.d2i_X509$FUNC
+ );
+ static final FunctionDescriptor i2d_X509$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle i2d_X509$MH = RuntimeHelper.downcallHandle(
+ "i2d_X509",
+ constants$9.i2d_X509$FUNC
+ );
+ static final FunctionDescriptor X509_get_ext_by_NID$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle X509_get_ext_by_NID$MH = RuntimeHelper.downcallHandle(
+ "X509_get_ext_by_NID",
+ constants$9.X509_get_ext_by_NID$FUNC
+ );
+ static final FunctionDescriptor X509_get_ext$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_INT$LAYOUT
+ );
+ static final MethodHandle X509_get_ext$MH = RuntimeHelper.downcallHandle(
+ "X509_get_ext",
+ constants$9.X509_get_ext$FUNC
+ );
+ static final FunctionDescriptor X509_EXTENSION_get_data$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle X509_EXTENSION_get_data$MH = RuntimeHelper.downcallHandle(
+ "X509_EXTENSION_get_data",
+ constants$9.X509_EXTENSION_get_data$FUNC
+ );
+ static final FunctionDescriptor PEM_read_bio_X509_AUX$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT
+ );
+ static final MethodHandle PEM_read_bio_X509_AUX$MH = RuntimeHelper.downcallHandle(
+ "PEM_read_bio_X509_AUX",
+ constants$9.PEM_read_bio_X509_AUX$FUNC
+ );
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/openssl_compat_h.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/openssl_compat_h.java
new file mode 100644
index 0000000000..499a15c77e
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/openssl_compat_h.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Methods used present in older OpenSSL versions but not in the current major version.
+ */
+public class openssl_compat_h {
+
+ // OpenSSL 1.1 FIPS_mode
+ static final FunctionDescriptor FIPS_mode$FUNC = FunctionDescriptor
+ .of(JAVA_INT);
+ static final MethodHandle FIPS_mode$MH = RuntimeHelper
+ .downcallHandle("FIPS_mode", FIPS_mode$FUNC);
+ public static MethodHandle FIPS_mode$MH() {
+ return RuntimeHelper.requireNonNull(FIPS_mode$MH, "FIPS_mode");
+ }
+ public static int FIPS_mode() {
+ var mh$ = RuntimeHelper.requireNonNull(FIPS_mode$MH, "FIPS_mode");
+ try {
+ return (int) mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+
+ // OpenSSL 1.1 FIPS_mode_set
+ static final FunctionDescriptor FIPS_mode_set$FUNC = FunctionDescriptor
+ .of(JAVA_INT, JAVA_INT);
+ static final MethodHandle FIPS_mode_set$MH = RuntimeHelper
+ .downcallHandle("FIPS_mode_set", FIPS_mode_set$FUNC);
+ public static MethodHandle FIPS_mode_set$MH() {
+ return RuntimeHelper.requireNonNull(FIPS_mode_set$MH, "FIPS_mode_set");
+ }
+ public static int FIPS_mode_set(int r) {
+ var mh$ = RuntimeHelper.requireNonNull(FIPS_mode_set$MH,
+ "FIPS_mode_set");
+ try {
+ return (int) mh$.invokeExact(r);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+
+ // OpenSSL 1.1 EVP_PKEY_base_id
+ static final FunctionDescriptor EVP_PKEY_base_id$FUNC = FunctionDescriptor
+ .of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle EVP_PKEY_base_id$MH = RuntimeHelper
+ .downcallHandle("EVP_PKEY_base_id", EVP_PKEY_base_id$FUNC);
+ public static MethodHandle EVP_PKEY_base_id$MH() {
+ return RuntimeHelper.requireNonNull(EVP_PKEY_base_id$MH,
+ "EVP_PKEY_base_id");
+ }
+ public static int EVP_PKEY_base_id(MemorySegment pkey) {
+ var mh$ = EVP_PKEY_base_id$MH();
+ try {
+ return (int) mh$.invokeExact(pkey);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+
+ // OpenSSL 1.1 EVP_PKEY_bits
+ static final FunctionDescriptor EVP_PKEY_bits$FUNC = FunctionDescriptor
+ .of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle EVP_PKEY_bits$MH = RuntimeHelper
+ .downcallHandle("EVP_PKEY_bits", EVP_PKEY_bits$FUNC);
+ public static MethodHandle EVP_PKEY_bits$MH() {
+ return RuntimeHelper.requireNonNull(EVP_PKEY_bits$MH, "EVP_PKEY_bits");
+ }
+ public static int EVP_PKEY_bits(MemorySegment pkey) {
+ var mh$ = EVP_PKEY_bits$MH();
+ try {
+ return (int) mh$.invokeExact(pkey);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+
+ // OpenSSL 1.1 SSL_get_peer_certificate
+ static final FunctionDescriptor SSL_get_peer_certificate$FUNC = FunctionDescriptor
+ .of(Constants$root.C_POINTER$LAYOUT,
+ Constants$root.C_POINTER$LAYOUT);
+ static final MethodHandle SSL_get_peer_certificate$MH = RuntimeHelper
+ .downcallHandle("SSL_get_peer_certificate",
+ SSL_get_peer_certificate$FUNC);
+ public static MethodHandle SSL_get_peer_certificate$MH() {
+ return RuntimeHelper.requireNonNull(SSL_get_peer_certificate$MH,
+ "SSL_get_peer_certificate");
+ }
+ public static MemorySegment SSL_get_peer_certificate(MemorySegment s) {
+ var mh$ = SSL_get_peer_certificate$MH();
+ try {
+ return (java.lang.foreign.MemorySegment) mh$.invokeExact(s);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+
+}
+
+
diff --git a/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
new file mode 100644
index 0000000000..ede1a779a5
--- /dev/null
+++ b/modules/openssl-java21/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -0,0 +1,3447 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by jextract
+
+package org.apache.tomcat.util.openssl;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
+public class openssl_h {
+
+ public static final OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT;
+ public static final OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT;
+ public static final OfInt C_INT = Constants$root.C_INT$LAYOUT;
+ public static final OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT;
+ public static final OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT;
+ public static final OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT;
+ public static final OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT;
+ public static final AddressLayout C_POINTER = Constants$root.C_POINTER$LAYOUT;
+ /**
+ * {@snippet :
+ * #define BIO_CLOSE 1
+ * }
+ */
+ public static int BIO_CLOSE() {
+ return (int)1L;
+ }
+ /**
+ * {@snippet :
+ * #define BIO_CTRL_RESET 1
+ * }
+ */
+ public static int BIO_CTRL_RESET() {
+ return (int)1L;
+ }
+ /**
+ * {@snippet :
+ * #define BIO_FP_READ 2
+ * }
+ */
+ public static int BIO_FP_READ() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define BIO_C_SET_FILENAME 108
+ * }
+ */
+ public static int BIO_C_SET_FILENAME() {
+ return (int)108L;
+ }
+ /**
+ * {@snippet :
+ * #define NID_info_access 177
+ * }
+ */
+ public static int NID_info_access() {
+ return (int)177L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_FILETYPE_PEM 1
+ * }
+ */
+ public static int X509_FILETYPE_PEM() {
+ return (int)1L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_L_FILE_LOAD 1
+ * }
+ */
+ public static int X509_L_FILE_LOAD() {
+ return (int)1L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_L_ADD_DIR 2
+ * }
+ */
+ public static int X509_L_ADD_DIR() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_OK 0
+ * }
+ */
+ public static int X509_V_OK() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_ERR_CRL_HAS_EXPIRED 12
+ * }
+ */
+ public static int X509_V_ERR_CRL_HAS_EXPIRED() {
+ return (int)12L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
+ * }
+ */
+ public static int X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT() {
+ return (int)18L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
+ * }
+ */
+ public static int X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN() {
+ return (int)19L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
+ * }
+ */
+ public static int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY() {
+ return (int)20L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
+ * }
+ */
+ public static int X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE() {
+ return (int)21L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_ERR_CERT_UNTRUSTED 27
+ * }
+ */
+ public static int X509_V_ERR_CERT_UNTRUSTED() {
+ return (int)27L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_ERR_APPLICATION_VERIFICATION 50
+ * }
+ */
+ public static int X509_V_ERR_APPLICATION_VERIFICATION() {
+ return (int)50L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_FLAG_CRL_CHECK 4
+ * }
+ */
+ public static int X509_V_FLAG_CRL_CHECK() {
+ return (int)4L;
+ }
+ /**
+ * {@snippet :
+ * #define X509_V_FLAG_CRL_CHECK_ALL 8
+ * }
+ */
+ public static int X509_V_FLAG_CRL_CHECK_ALL() {
+ return (int)8L;
+ }
+ /**
+ * {@snippet :
+ * #define PEM_R_NO_START_LINE 108
+ * }
+ */
+ public static int PEM_R_NO_START_LINE() {
+ return (int)108L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL3_VERSION 768
+ * }
+ */
+ public static int SSL3_VERSION() {
+ return (int)768L;
+ }
+ /**
+ * {@snippet :
+ * #define TLS1_VERSION 769
+ * }
+ */
+ public static int TLS1_VERSION() {
+ return (int)769L;
+ }
+ /**
+ * {@snippet :
+ * #define TLS1_1_VERSION 770
+ * }
+ */
+ public static int TLS1_1_VERSION() {
+ return (int)770L;
+ }
+ /**
+ * {@snippet :
+ * #define TLS1_2_VERSION 771
+ * }
+ */
+ public static int TLS1_2_VERSION() {
+ return (int)771L;
+ }
+ /**
+ * {@snippet :
+ * #define TLS1_3_VERSION 772
+ * }
+ */
+ public static int TLS1_3_VERSION() {
+ return (int)772L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_SENT_SHUTDOWN 1
+ * }
+ */
+ public static int SSL_SENT_SHUTDOWN() {
+ return (int)1L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_RECEIVED_SHUTDOWN 2
+ * }
+ */
+ public static int SSL_RECEIVED_SHUTDOWN() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_OP_SINGLE_ECDH_USE 0
+ * }
+ */
+ public static int SSL_OP_SINGLE_ECDH_USE() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_OP_SINGLE_DH_USE 0
+ * }
+ */
+ public static int SSL_OP_SINGLE_DH_USE() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_OP_NO_SSLv2 0
+ * }
+ */
+ public static int SSL_OP_NO_SSLv2() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CONF_FLAG_FILE 2
+ * }
+ */
+ public static int SSL_CONF_FLAG_FILE() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CONF_FLAG_SERVER 8
+ * }
+ */
+ public static int SSL_CONF_FLAG_SERVER() {
+ return (int)8L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CONF_FLAG_SHOW_ERRORS 16
+ * }
+ */
+ public static int SSL_CONF_FLAG_SHOW_ERRORS() {
+ return (int)16L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CONF_FLAG_CERTIFICATE 32
+ * }
+ */
+ public static int SSL_CONF_FLAG_CERTIFICATE() {
+ return (int)32L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CONF_TYPE_UNKNOWN 0
+ * }
+ */
+ public static int SSL_CONF_TYPE_UNKNOWN() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CONF_TYPE_FILE 2
+ * }
+ */
+ public static int SSL_CONF_TYPE_FILE() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CONF_TYPE_DIR 3
+ * }
+ */
+ public static int SSL_CONF_TYPE_DIR() {
+ return (int)3L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_SESS_CACHE_OFF 0
+ * }
+ */
+ public static int SSL_SESS_CACHE_OFF() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_SESS_CACHE_SERVER 2
+ * }
+ */
+ public static int SSL_SESS_CACHE_SERVER() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL2_VERSION 2
+ * }
+ */
+ public static int SSL2_VERSION() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_TLSEXT_ERR_OK 0
+ * }
+ */
+ public static int SSL_TLSEXT_ERR_OK() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_TLSEXT_ERR_NOACK 3
+ * }
+ */
+ public static int SSL_TLSEXT_ERR_NOACK() {
+ return (int)3L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CB_HANDSHAKE_DONE 32
+ * }
+ */
+ public static int SSL_CB_HANDSHAKE_DONE() {
+ return (int)32L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_VERIFY_NONE 0
+ * }
+ */
+ public static int SSL_VERIFY_NONE() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_VERIFY_PEER 1
+ * }
+ */
+ public static int SSL_VERIFY_PEER() {
+ return (int)1L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 2
+ * }
+ */
+ public static int SSL_VERIFY_FAIL_IF_NO_PEER_CERT() {
+ return (int)2L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_ERROR_NONE 0
+ * }
+ */
+ public static int SSL_ERROR_NONE() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SET_TMP_DH 3
+ * }
+ */
+ public static int SSL_CTRL_SET_TMP_DH() {
+ return (int)3L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SET_TMP_ECDH 4
+ * }
+ */
+ public static int SSL_CTRL_SET_TMP_ECDH() {
+ return (int)4L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_NUMBER 20
+ * }
+ */
+ public static int SSL_CTRL_SESS_NUMBER() {
+ return (int)20L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_CONNECT 21
+ * }
+ */
+ public static int SSL_CTRL_SESS_CONNECT() {
+ return (int)21L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_CONNECT_GOOD 22
+ * }
+ */
+ public static int SSL_CTRL_SESS_CONNECT_GOOD() {
+ return (int)22L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23
+ * }
+ */
+ public static int SSL_CTRL_SESS_CONNECT_RENEGOTIATE() {
+ return (int)23L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_ACCEPT 24
+ * }
+ */
+ public static int SSL_CTRL_SESS_ACCEPT() {
+ return (int)24L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_ACCEPT_GOOD 25
+ * }
+ */
+ public static int SSL_CTRL_SESS_ACCEPT_GOOD() {
+ return (int)25L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26
+ * }
+ */
+ public static int SSL_CTRL_SESS_ACCEPT_RENEGOTIATE() {
+ return (int)26L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_HIT 27
+ * }
+ */
+ public static int SSL_CTRL_SESS_HIT() {
+ return (int)27L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_CB_HIT 28
+ * }
+ */
+ public static int SSL_CTRL_SESS_CB_HIT() {
+ return (int)28L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_MISSES 29
+ * }
+ */
+ public static int SSL_CTRL_SESS_MISSES() {
+ return (int)29L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_TIMEOUTS 30
+ * }
+ */
+ public static int SSL_CTRL_SESS_TIMEOUTS() {
+ return (int)30L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SESS_CACHE_FULL 31
+ * }
+ */
+ public static int SSL_CTRL_SESS_CACHE_FULL() {
+ return (int)31L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SET_SESS_CACHE_SIZE 42
+ * }
+ */
+ public static int SSL_CTRL_SET_SESS_CACHE_SIZE() {
+ return (int)42L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_GET_SESS_CACHE_SIZE 43
+ * }
+ */
+ public static int SSL_CTRL_GET_SESS_CACHE_SIZE() {
+ return (int)43L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SET_SESS_CACHE_MODE 44
+ * }
+ */
+ public static int SSL_CTRL_SET_SESS_CACHE_MODE() {
+ return (int)44L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_GET_SESS_CACHE_MODE 45
+ * }
+ */
+ public static int SSL_CTRL_GET_SESS_CACHE_MODE() {
+ return (int)45L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59
+ * }
+ */
+ public static int SSL_CTRL_SET_TLSEXT_TICKET_KEYS() {
+ return (int)59L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_CHAIN_CERT 89
+ * }
+ */
+ public static int SSL_CTRL_CHAIN_CERT() {
+ return (int)89L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SET_MIN_PROTO_VERSION 123
+ * }
+ */
+ public static int SSL_CTRL_SET_MIN_PROTO_VERSION() {
+ return (int)123L;
+ }
+ /**
+ * {@snippet :
+ * #define SSL_CTRL_SET_MAX_PROTO_VERSION 124
+ * }
+ */
+ public static int SSL_CTRL_SET_MAX_PROTO_VERSION() {
+ return (int)124L;
+ }
+ /**
+ * {@snippet :
+ * #define OCSP_RESPONSE_STATUS_SUCCESSFUL 0
+ * }
+ */
+ public static int OCSP_RESPONSE_STATUS_SUCCESSFUL() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define V_OCSP_CERTSTATUS_GOOD 0
+ * }
+ */
+ public static int V_OCSP_CERTSTATUS_GOOD() {
+ return (int)0L;
+ }
+ /**
+ * {@snippet :
+ * #define V_OCSP_CERTSTATUS_REVOKED 1
+ * }
+ */
+ public static int V_OCSP_CERTSTATUS_REVOKED() {
+ return (int)1L;
+ }
+ /**
+ * {@snippet :
+ * #define V_OCSP_CERTSTATUS_UNKNOWN 2
+ * }
+ */
+ public static int V_OCSP_CERTSTATUS_UNKNOWN() {
+ return (int)2L;
+ }
+ public static MethodHandle OPENSSL_sk_num$MH() {
+ return RuntimeHelper.requireNonNull(constants$0.OPENSSL_sk_num$MH,"OPENSSL_sk_num");
+ }
+ /**
+ * {@snippet :
+ * int OPENSSL_sk_num(const OPENSSL_STACK*);
+ * }
+ */
+ public static int OPENSSL_sk_num(MemorySegment x0) {
+ var mh$ = OPENSSL_sk_num$MH();
+ try {
+ return (int)mh$.invokeExact(x0);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle OPENSSL_sk_value$MH() {
+ return RuntimeHelper.requireNonNull(constants$0.OPENSSL_sk_value$MH,"OPENSSL_sk_value");
+ }
+ /**
+ * {@snippet :
+ * void* OPENSSL_sk_value(const OPENSSL_STACK*, int);
+ * }
+ */
+ public static MemorySegment OPENSSL_sk_value(MemorySegment x0, int x1) {
+ var mh$ = OPENSSL_sk_value$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(x0, x1);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle OpenSSL_version_num$MH() {
+ return RuntimeHelper.requireNonNull(constants$0.OpenSSL_version_num$MH,"OpenSSL_version_num");
+ }
+ /**
+ * {@snippet :
+ * unsigned long OpenSSL_version_num();
+ * }
+ */
+ public static long OpenSSL_version_num() {
+ var mh$ = OpenSSL_version_num$MH();
+ try {
+ return (long)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle OpenSSL_version$MH() {
+ return RuntimeHelper.requireNonNull(constants$0.OpenSSL_version$MH,"OpenSSL_version");
+ }
+ /**
+ * {@snippet :
+ * char* OpenSSL_version(int type);
+ * }
+ */
+ public static MemorySegment OpenSSL_version(int type) {
+ var mh$ = OpenSSL_version$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(type);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle CRYPTO_free$MH() {
+ return RuntimeHelper.requireNonNull(constants$0.CRYPTO_free$MH,"CRYPTO_free");
+ }
+ /**
+ * {@snippet :
+ * void CRYPTO_free(void* ptr, char* file, int line);
+ * }
+ */
+ public static void CRYPTO_free(MemorySegment ptr, MemorySegment file, int line) {
+ var mh$ = CRYPTO_free$MH();
+ try {
+ mh$.invokeExact(ptr, file, line);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_ctrl_pending$MH() {
+ return RuntimeHelper.requireNonNull(constants$0.BIO_ctrl_pending$MH,"BIO_ctrl_pending");
+ }
+ /**
+ * {@snippet :
+ * size_t BIO_ctrl_pending(BIO* b);
+ * }
+ */
+ public static long BIO_ctrl_pending(MemorySegment b) {
+ var mh$ = BIO_ctrl_pending$MH();
+ try {
+ return (long)mh$.invokeExact(b);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_s_file$MH() {
+ return RuntimeHelper.requireNonNull(constants$1.BIO_s_file$MH,"BIO_s_file");
+ }
+ /**
+ * {@snippet :
+ * const BIO_METHOD* BIO_s_file();
+ * }
+ */
+ public static MemorySegment BIO_s_file() {
+ var mh$ = BIO_s_file$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_new_file$MH() {
+ return RuntimeHelper.requireNonNull(constants$1.BIO_new_file$MH,"BIO_new_file");
+ }
+ /**
+ * {@snippet :
+ * BIO* BIO_new_file(char* filename, char* mode);
+ * }
+ */
+ public static MemorySegment BIO_new_file(MemorySegment filename, MemorySegment mode) {
+ var mh$ = BIO_new_file$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(filename, mode);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_new$MH() {
+ return RuntimeHelper.requireNonNull(constants$1.BIO_new$MH,"BIO_new");
+ }
+ /**
+ * {@snippet :
+ * BIO* BIO_new(const BIO_METHOD* type);
+ * }
+ */
+ public static MemorySegment BIO_new(MemorySegment type) {
+ var mh$ = BIO_new$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(type);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_free$MH() {
+ return RuntimeHelper.requireNonNull(constants$1.BIO_free$MH,"BIO_free");
+ }
+ /**
+ * {@snippet :
+ * int BIO_free(BIO* a);
+ * }
+ */
+ public static int BIO_free(MemorySegment a) {
+ var mh$ = BIO_free$MH();
+ try {
+ return (int)mh$.invokeExact(a);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_read$MH() {
+ return RuntimeHelper.requireNonNull(constants$1.BIO_read$MH,"BIO_read");
+ }
+ /**
+ * {@snippet :
+ * int BIO_read(BIO* b, void* data, int dlen);
+ * }
+ */
+ public static int BIO_read(MemorySegment b, MemorySegment data, int dlen) {
+ var mh$ = BIO_read$MH();
+ try {
+ return (int)mh$.invokeExact(b, data, dlen);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_write$MH() {
+ return RuntimeHelper.requireNonNull(constants$1.BIO_write$MH,"BIO_write");
+ }
+ /**
+ * {@snippet :
+ * int BIO_write(BIO* b, void* data, int dlen);
+ * }
+ */
+ public static int BIO_write(MemorySegment b, MemorySegment data, int dlen) {
+ var mh$ = BIO_write$MH();
+ try {
+ return (int)mh$.invokeExact(b, data, dlen);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_ctrl$MH() {
+ return RuntimeHelper.requireNonNull(constants$2.BIO_ctrl$MH,"BIO_ctrl");
+ }
+ /**
+ * {@snippet :
+ * long BIO_ctrl(BIO* bp, int cmd, long larg, void* parg);
+ * }
+ */
+ public static long BIO_ctrl(MemorySegment bp, int cmd, long larg, MemorySegment parg) {
+ var mh$ = BIO_ctrl$MH();
+ try {
+ return (long)mh$.invokeExact(bp, cmd, larg, parg);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_s_mem$MH() {
+ return RuntimeHelper.requireNonNull(constants$2.BIO_s_mem$MH,"BIO_s_mem");
+ }
+ /**
+ * {@snippet :
+ * const BIO_METHOD* BIO_s_mem();
+ * }
+ */
+ public static MemorySegment BIO_s_mem() {
+ var mh$ = BIO_s_mem$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_s_bio$MH() {
+ return RuntimeHelper.requireNonNull(constants$2.BIO_s_bio$MH,"BIO_s_bio");
+ }
+ /**
+ * {@snippet :
+ * const BIO_METHOD* BIO_s_bio();
+ * }
+ */
+ public static MemorySegment BIO_s_bio() {
+ var mh$ = BIO_s_bio$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BIO_new_bio_pair$MH() {
+ return RuntimeHelper.requireNonNull(constants$2.BIO_new_bio_pair$MH,"BIO_new_bio_pair");
+ }
+ /**
+ * {@snippet :
+ * int BIO_new_bio_pair(BIO** bio1, size_t writebuf1, BIO** bio2, size_t writebuf2);
+ * }
+ */
+ public static int BIO_new_bio_pair(MemorySegment bio1, long writebuf1, MemorySegment bio2, long writebuf2) {
+ var mh$ = BIO_new_bio_pair$MH();
+ try {
+ return (int)mh$.invokeExact(bio1, writebuf1, bio2, writebuf2);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_new$MH() {
+ return RuntimeHelper.requireNonNull(constants$2.BN_new$MH,"BN_new");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_new();
+ * }
+ */
+ public static MemorySegment BN_new() {
+ var mh$ = BN_new$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_set_word$MH() {
+ return RuntimeHelper.requireNonNull(constants$2.BN_set_word$MH,"BN_set_word");
+ }
+ /**
+ * {@snippet :
+ * int BN_set_word(BIGNUM* a, unsigned long w);
+ * }
+ */
+ public static int BN_set_word(MemorySegment a, long w) {
+ var mh$ = BN_set_word$MH();
+ try {
+ return (int)mh$.invokeExact(a, w);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc2409_prime_768$MH() {
+ return RuntimeHelper.requireNonNull(constants$3.BN_get_rfc2409_prime_768$MH,"BN_get_rfc2409_prime_768");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc2409_prime_768(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc2409_prime_768(MemorySegment bn) {
+ var mh$ = BN_get_rfc2409_prime_768$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc2409_prime_1024$MH() {
+ return RuntimeHelper.requireNonNull(constants$3.BN_get_rfc2409_prime_1024$MH,"BN_get_rfc2409_prime_1024");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc2409_prime_1024(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc2409_prime_1024(MemorySegment bn) {
+ var mh$ = BN_get_rfc2409_prime_1024$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc3526_prime_1536$MH() {
+ return RuntimeHelper.requireNonNull(constants$3.BN_get_rfc3526_prime_1536$MH,"BN_get_rfc3526_prime_1536");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc3526_prime_1536(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc3526_prime_1536(MemorySegment bn) {
+ var mh$ = BN_get_rfc3526_prime_1536$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc3526_prime_2048$MH() {
+ return RuntimeHelper.requireNonNull(constants$3.BN_get_rfc3526_prime_2048$MH,"BN_get_rfc3526_prime_2048");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc3526_prime_2048(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc3526_prime_2048(MemorySegment bn) {
+ var mh$ = BN_get_rfc3526_prime_2048$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc3526_prime_3072$MH() {
+ return RuntimeHelper.requireNonNull(constants$3.BN_get_rfc3526_prime_3072$MH,"BN_get_rfc3526_prime_3072");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc3526_prime_3072(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc3526_prime_3072(MemorySegment bn) {
+ var mh$ = BN_get_rfc3526_prime_3072$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc3526_prime_4096$MH() {
+ return RuntimeHelper.requireNonNull(constants$3.BN_get_rfc3526_prime_4096$MH,"BN_get_rfc3526_prime_4096");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc3526_prime_4096(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc3526_prime_4096(MemorySegment bn) {
+ var mh$ = BN_get_rfc3526_prime_4096$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc3526_prime_6144$MH() {
+ return RuntimeHelper.requireNonNull(constants$4.BN_get_rfc3526_prime_6144$MH,"BN_get_rfc3526_prime_6144");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc3526_prime_6144(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc3526_prime_6144(MemorySegment bn) {
+ var mh$ = BN_get_rfc3526_prime_6144$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle BN_get_rfc3526_prime_8192$MH() {
+ return RuntimeHelper.requireNonNull(constants$4.BN_get_rfc3526_prime_8192$MH,"BN_get_rfc3526_prime_8192");
+ }
+ /**
+ * {@snippet :
+ * BIGNUM* BN_get_rfc3526_prime_8192(BIGNUM* bn);
+ * }
+ */
+ public static MemorySegment BN_get_rfc3526_prime_8192(MemorySegment bn) {
+ var mh$ = BN_get_rfc3526_prime_8192$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bn);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle ASN1_STRING_length$MH() {
+ return RuntimeHelper.requireNonNull(constants$4.ASN1_STRING_length$MH,"ASN1_STRING_length");
+ }
+ /**
+ * {@snippet :
+ * int ASN1_STRING_length(const ASN1_STRING* x);
+ * }
+ */
+ public static int ASN1_STRING_length(MemorySegment x) {
+ var mh$ = ASN1_STRING_length$MH();
+ try {
+ return (int)mh$.invokeExact(x);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle ASN1_STRING_get0_data$MH() {
+ return RuntimeHelper.requireNonNull(constants$4.ASN1_STRING_get0_data$MH,"ASN1_STRING_get0_data");
+ }
+ /**
+ * {@snippet :
+ * unsigned char* ASN1_STRING_get0_data(const ASN1_STRING* x);
+ * }
+ */
+ public static MemorySegment ASN1_STRING_get0_data(MemorySegment x) {
+ var mh$ = ASN1_STRING_get0_data$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(x);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EVP_MD_get0_provider$MH() {
+ return RuntimeHelper.requireNonNull(constants$4.EVP_MD_get0_provider$MH,"EVP_MD_get0_provider");
+ }
+ /**
+ * {@snippet :
+ * const OSSL_PROVIDER* EVP_MD_get0_provider(const EVP_MD* md);
+ * }
+ */
+ public static MemorySegment EVP_MD_get0_provider(MemorySegment md) {
+ var mh$ = EVP_MD_get0_provider$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(md);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EVP_MD_fetch$MH() {
+ return RuntimeHelper.requireNonNull(constants$4.EVP_MD_fetch$MH,"EVP_MD_fetch");
+ }
+ /**
+ * {@snippet :
+ * EVP_MD* EVP_MD_fetch(OSSL_LIB_CTX* ctx, char* algorithm, char* properties);
+ * }
+ */
+ public static MemorySegment EVP_MD_fetch(MemorySegment ctx, MemorySegment algorithm, MemorySegment properties) {
+ var mh$ = EVP_MD_fetch$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(ctx, algorithm, properties);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EVP_MD_free$MH() {
+ return RuntimeHelper.requireNonNull(constants$5.EVP_MD_free$MH,"EVP_MD_free");
+ }
+ /**
+ * {@snippet :
+ * void EVP_MD_free(EVP_MD* md);
+ * }
+ */
+ public static void EVP_MD_free(MemorySegment md) {
+ var mh$ = EVP_MD_free$MH();
+ try {
+ mh$.invokeExact(md);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EVP_PKEY_get_base_id$MH() {
+ return RuntimeHelper.requireNonNull(constants$5.EVP_PKEY_get_base_id$MH,"EVP_PKEY_get_base_id");
+ }
+ /**
+ * {@snippet :
+ * int EVP_PKEY_get_base_id(const EVP_PKEY* pkey);
+ * }
+ */
+ public static int EVP_PKEY_get_base_id(MemorySegment pkey) {
+ var mh$ = EVP_PKEY_get_base_id$MH();
+ try {
+ return (int)mh$.invokeExact(pkey);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EVP_PKEY_get_bits$MH() {
+ return RuntimeHelper.requireNonNull(constants$5.EVP_PKEY_get_bits$MH,"EVP_PKEY_get_bits");
+ }
+ /**
+ * {@snippet :
+ * int EVP_PKEY_get_bits(const EVP_PKEY* pkey);
+ * }
+ */
+ public static int EVP_PKEY_get_bits(MemorySegment pkey) {
+ var mh$ = EVP_PKEY_get_bits$MH();
+ try {
+ return (int)mh$.invokeExact(pkey);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EC_GROUP_free$MH() {
+ return RuntimeHelper.requireNonNull(constants$5.EC_GROUP_free$MH,"EC_GROUP_free");
+ }
+ /**
+ * {@snippet :
+ * void EC_GROUP_free(EC_GROUP* group);
+ * }
+ */
+ public static void EC_GROUP_free(MemorySegment group) {
+ var mh$ = EC_GROUP_free$MH();
+ try {
+ mh$.invokeExact(group);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EC_GROUP_get_curve_name$MH() {
+ return RuntimeHelper.requireNonNull(constants$5.EC_GROUP_get_curve_name$MH,"EC_GROUP_get_curve_name");
+ }
+ /**
+ * {@snippet :
+ * int EC_GROUP_get_curve_name(const EC_GROUP* group);
+ * }
+ */
+ public static int EC_GROUP_get_curve_name(MemorySegment group) {
+ var mh$ = EC_GROUP_get_curve_name$MH();
+ try {
+ return (int)mh$.invokeExact(group);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EC_KEY_new_by_curve_name$MH() {
+ return RuntimeHelper.requireNonNull(constants$5.EC_KEY_new_by_curve_name$MH,"EC_KEY_new_by_curve_name");
+ }
+ /**
+ * {@snippet :
+ * EC_KEY* EC_KEY_new_by_curve_name(int nid);
+ * }
+ */
+ public static MemorySegment EC_KEY_new_by_curve_name(int nid) {
+ var mh$ = EC_KEY_new_by_curve_name$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(nid);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle EC_KEY_free$MH() {
+ return RuntimeHelper.requireNonNull(constants$6.EC_KEY_free$MH,"EC_KEY_free");
+ }
+ /**
+ * {@snippet :
+ * void EC_KEY_free(EC_KEY* key);
+ * }
+ */
+ public static void EC_KEY_free(MemorySegment key) {
+ var mh$ = EC_KEY_free$MH();
+ try {
+ mh$.invokeExact(key);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle DH_new$MH() {
+ return RuntimeHelper.requireNonNull(constants$6.DH_new$MH,"DH_new");
+ }
+ /**
+ * {@snippet :
+ * DH* DH_new();
+ * }
+ */
+ public static MemorySegment DH_new() {
+ var mh$ = DH_new$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle DH_free$MH() {
+ return RuntimeHelper.requireNonNull(constants$6.DH_free$MH,"DH_free");
+ }
+ /**
+ * {@snippet :
+ * void DH_free(DH* dh);
+ * }
+ */
+ public static void DH_free(MemorySegment dh) {
+ var mh$ = DH_free$MH();
+ try {
+ mh$.invokeExact(dh);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle DH_set0_pqg$MH() {
+ return RuntimeHelper.requireNonNull(constants$6.DH_set0_pqg$MH,"DH_set0_pqg");
+ }
+ /**
+ * {@snippet :
+ * int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g);
+ * }
+ */
+ public static int DH_set0_pqg(MemorySegment dh, MemorySegment p, MemorySegment q, MemorySegment g) {
+ var mh$ = DH_set0_pqg$MH();
+ try {
+ return (int)mh$.invokeExact(dh, p, q, g);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_set_flags$MH() {
+ return RuntimeHelper.requireNonNull(constants$6.X509_STORE_set_flags$MH,"X509_STORE_set_flags");
+ }
+ /**
+ * {@snippet :
+ * int X509_STORE_set_flags(X509_STORE* ctx, unsigned long flags);
+ * }
+ */
+ public static int X509_STORE_set_flags(MemorySegment ctx, long flags) {
+ var mh$ = X509_STORE_set_flags$MH();
+ try {
+ return (int)mh$.invokeExact(ctx, flags);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_CTX_get0_untrusted$MH() {
+ return RuntimeHelper.requireNonNull(constants$6.X509_STORE_CTX_get0_untrusted$MH,"X509_STORE_CTX_get0_untrusted");
+ }
+ /**
+ * {@snippet :
+ * struct stack_st_X509* X509_STORE_CTX_get0_untrusted(const X509_STORE_CTX* ctx);
+ * }
+ */
+ public static MemorySegment X509_STORE_CTX_get0_untrusted(MemorySegment ctx) {
+ var mh$ = X509_STORE_CTX_get0_untrusted$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(ctx);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_add_lookup$MH() {
+ return RuntimeHelper.requireNonNull(constants$7.X509_STORE_add_lookup$MH,"X509_STORE_add_lookup");
+ }
+ /**
+ * {@snippet :
+ * X509_LOOKUP* X509_STORE_add_lookup(X509_STORE* v, X509_LOOKUP_METHOD* m);
+ * }
+ */
+ public static MemorySegment X509_STORE_add_lookup(MemorySegment v, MemorySegment m) {
+ var mh$ = X509_STORE_add_lookup$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(v, m);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_LOOKUP_hash_dir$MH() {
+ return RuntimeHelper.requireNonNull(constants$7.X509_LOOKUP_hash_dir$MH,"X509_LOOKUP_hash_dir");
+ }
+ /**
+ * {@snippet :
+ * X509_LOOKUP_METHOD* X509_LOOKUP_hash_dir();
+ * }
+ */
+ public static MemorySegment X509_LOOKUP_hash_dir() {
+ var mh$ = X509_LOOKUP_hash_dir$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_LOOKUP_file$MH() {
+ return RuntimeHelper.requireNonNull(constants$7.X509_LOOKUP_file$MH,"X509_LOOKUP_file");
+ }
+ /**
+ * {@snippet :
+ * X509_LOOKUP_METHOD* X509_LOOKUP_file();
+ * }
+ */
+ public static MemorySegment X509_LOOKUP_file() {
+ var mh$ = X509_LOOKUP_file$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact();
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_LOOKUP_ctrl$MH() {
+ return RuntimeHelper.requireNonNull(constants$7.X509_LOOKUP_ctrl$MH,"X509_LOOKUP_ctrl");
+ }
+ /**
+ * {@snippet :
+ * int X509_LOOKUP_ctrl(X509_LOOKUP* ctx, int cmd, char* argc, long argl, char** ret);
+ * }
+ */
+ public static int X509_LOOKUP_ctrl(MemorySegment ctx, int cmd, MemorySegment argc, long argl, MemorySegment ret) {
+ var mh$ = X509_LOOKUP_ctrl$MH();
+ try {
+ return (int)mh$.invokeExact(ctx, cmd, argc, argl, ret);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_CTX_get_ex_data$MH() {
+ return RuntimeHelper.requireNonNull(constants$7.X509_STORE_CTX_get_ex_data$MH,"X509_STORE_CTX_get_ex_data");
+ }
+ /**
+ * {@snippet :
+ * void* X509_STORE_CTX_get_ex_data(const X509_STORE_CTX* ctx, int idx);
+ * }
+ */
+ public static MemorySegment X509_STORE_CTX_get_ex_data(MemorySegment ctx, int idx) {
+ var mh$ = X509_STORE_CTX_get_ex_data$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(ctx, idx);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_CTX_get_error$MH() {
+ return RuntimeHelper.requireNonNull(constants$7.X509_STORE_CTX_get_error$MH,"X509_STORE_CTX_get_error");
+ }
+ /**
+ * {@snippet :
+ * int X509_STORE_CTX_get_error(const X509_STORE_CTX* ctx);
+ * }
+ */
+ public static int X509_STORE_CTX_get_error(MemorySegment ctx) {
+ var mh$ = X509_STORE_CTX_get_error$MH();
+ try {
+ return (int)mh$.invokeExact(ctx);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_CTX_set_error$MH() {
+ return RuntimeHelper.requireNonNull(constants$8.X509_STORE_CTX_set_error$MH,"X509_STORE_CTX_set_error");
+ }
+ /**
+ * {@snippet :
+ * void X509_STORE_CTX_set_error(X509_STORE_CTX* ctx, int s);
+ * }
+ */
+ public static void X509_STORE_CTX_set_error(MemorySegment ctx, int s) {
+ var mh$ = X509_STORE_CTX_set_error$MH();
+ try {
+ mh$.invokeExact(ctx, s);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_CTX_get_error_depth$MH() {
+ return RuntimeHelper.requireNonNull(constants$8.X509_STORE_CTX_get_error_depth$MH,"X509_STORE_CTX_get_error_depth");
+ }
+ /**
+ * {@snippet :
+ * int X509_STORE_CTX_get_error_depth(const X509_STORE_CTX* ctx);
+ * }
+ */
+ public static int X509_STORE_CTX_get_error_depth(MemorySegment ctx) {
+ var mh$ = X509_STORE_CTX_get_error_depth$MH();
+ try {
+ return (int)mh$.invokeExact(ctx);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_CTX_get_current_cert$MH() {
+ return RuntimeHelper.requireNonNull(constants$8.X509_STORE_CTX_get_current_cert$MH,"X509_STORE_CTX_get_current_cert");
+ }
+ /**
+ * {@snippet :
+ * X509* X509_STORE_CTX_get_current_cert(const X509_STORE_CTX* ctx);
+ * }
+ */
+ public static MemorySegment X509_STORE_CTX_get_current_cert(MemorySegment ctx) {
+ var mh$ = X509_STORE_CTX_get_current_cert$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(ctx);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_STORE_CTX_get0_current_issuer$MH() {
+ return RuntimeHelper.requireNonNull(constants$8.X509_STORE_CTX_get0_current_issuer$MH,"X509_STORE_CTX_get0_current_issuer");
+ }
+ /**
+ * {@snippet :
+ * X509* X509_STORE_CTX_get0_current_issuer(const X509_STORE_CTX* ctx);
+ * }
+ */
+ public static MemorySegment X509_STORE_CTX_get0_current_issuer(MemorySegment ctx) {
+ var mh$ = X509_STORE_CTX_get0_current_issuer$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(ctx);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle d2i_X509_bio$MH() {
+ return RuntimeHelper.requireNonNull(constants$8.d2i_X509_bio$MH,"d2i_X509_bio");
+ }
+ /**
+ * {@snippet :
+ * X509* d2i_X509_bio(BIO* bp, X509** x509);
+ * }
+ */
+ public static MemorySegment d2i_X509_bio(MemorySegment bp, MemorySegment x509) {
+ var mh$ = d2i_X509_bio$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(bp, x509);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_free$MH() {
+ return RuntimeHelper.requireNonNull(constants$8.X509_free$MH,"X509_free");
+ }
+ /**
+ * {@snippet :
+ * void X509_free(X509* a);
+ * }
+ */
+ public static void X509_free(MemorySegment a) {
+ var mh$ = X509_free$MH();
+ try {
+ mh$.invokeExact(a);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle d2i_X509$MH() {
+ return RuntimeHelper.requireNonNull(constants$9.d2i_X509$MH,"d2i_X509");
+ }
+ /**
+ * {@snippet :
+ * X509* d2i_X509(X509** a, unsigned char** in, long len);
+ * }
+ */
+ public static MemorySegment d2i_X509(MemorySegment a, MemorySegment in, long len) {
+ var mh$ = d2i_X509$MH();
+ try {
+ return (java.lang.foreign.MemorySegment)mh$.invokeExact(a, in, len);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle i2d_X509$MH() {
+ return RuntimeHelper.requireNonNull(constants$9.i2d_X509$MH,"i2d_X509");
+ }
+ /**
+ * {@snippet :
+ * int i2d_X509(const X509* a, unsigned char** out);
+ * }
+ */
+ public static int i2d_X509(MemorySegment a, MemorySegment out) {
+ var mh$ = i2d_X509$MH();
+ try {
+ return (int)mh$.invokeExact(a, out);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
+ }
+ }
+ public static MethodHandle X509_get_ext_by_NID$MH() {
+ return RuntimeHelper.requireNonNull(constants$9.X509_get_ext_by_NID$MH,"X509_get_ext_by_NID");
+ }
+ /**
+ * {@snippet :
+ * int X509_get_ext_by_NID(const X509* x, int nid, int lastpos);
+ * }
+ */
+ public static int X509_get_ext_by_NID(MemorySegment x, int nid, int lastpos) {
+ var mh$ = X509_get_ext_by_NID$MH();
+ try {
... 2031 lines suppressed ...
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org