On Fri, May 15, 2026 at 3:47 PM Mark Thomas <[email protected]> wrote: > > I'm seeing lots of failures with 3.5.5 > > The root cause appears to be: > > 15-May-2026 12:59:58.147 SEVERE [main] > org.apache.tomcat.util.net.openssl.panama.OpenSSLContext.logLastError > Error loading certificate: [error:0A0000F7:SSL routines::unknown > certificate type] > > and similar variations. > > Does PQC need to be explicitly enabled in the OpenSSL build?
Anything can happen I would say, some distributions also cut out QUIC support from everything, and so on. Rémy > Mark > > > On 15/05/2026 14:41, Dimitris Soumis wrote: > > OpenSSL-FFM tests did pass for me though with Openssl 3.5.4. Could you > > provide the failure logs if there are any pending or what version you are > > using that triggers those failures? > > > > On Fri, May 15, 2026 at 4:16 PM Dimitris Soumis <[email protected]> wrote: > > > >> Apologies for the noise. Indeed, it wasn't tested properly. Thanks for > >> fixing it. > >> > >> Dimitris > >> > >> On Fri, May 15, 2026 at 3:02 PM Mark Thomas <[email protected]> wrote: > >> > >>> On 13/05/2026 12:44, [email protected] wrote: > >>>> This is an automated email from the ASF dual-hosted git repository. > >>>> > >>>> dsoumis 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 7ff10fab8e Add unit tests for PQC features > >>>> 7ff10fab8e is described below > >>>> > >>>> commit 7ff10fab8ede061fe61524ef96b463fef637429f > >>>> Author: Dimitrios Soumis <[email protected]> > >>>> AuthorDate: Wed May 13 13:44:42 2026 +0200 > >>>> > >>>> Add unit tests for PQC features > >>> > >>> How well tested is this patch? And with which OpenSSL versions? > >>> > >>> The OpenSSL tests can never run because the version check is looking at > >>> the OpenSSLStatus rather than AprStatus. > >>> > >>> With the above fixed, the OpenSSL tests still won't run because the > >>> OpenSSL version isn't set until after the version check. > >>> > >>> With that fixed, most of the OpenSSL tests result in errors or failures. > >>> The OpenSSL-FFM tests have a similar failure rate. > >>> > >>> Mark > >>> > >>> > >>>> --- > >>>> test/org/apache/tomcat/util/net/TestPQC.java | 331 > >>> +++++++++++++++++++++ > >>>> .../tomcat/util/net/TesterKeystoreGenerator.java | 65 ++++ > >>>> 2 files changed, 396 insertions(+) > >>>> > >>>> diff --git a/test/org/apache/tomcat/util/net/TestPQC.java > >>> b/test/org/apache/tomcat/util/net/TestPQC.java > >>>> new file mode 100644 > >>>> index 0000000000..db3f53ff60 > >>>> --- /dev/null > >>>> +++ b/test/org/apache/tomcat/util/net/TestPQC.java > >>>> @@ -0,0 +1,331 @@ > >>>> +/* > >>>> + * 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; > >>>> + > >>>> +import java.io.File; > >>>> +import java.util.ArrayList; > >>>> +import java.util.Collection; > >>>> +import java.util.List; > >>>> +import java.util.Map; > >>>> +import java.util.concurrent.TimeUnit; > >>>> + > >>>> +import javax.net.ssl.SSLContext; > >>>> +import javax.net.ssl.SSLHandshakeException; > >>>> +import javax.net.ssl.TrustManager; > >>>> + > >>>> +import org.junit.Assert; > >>>> +import org.junit.Assume; > >>>> +import org.junit.Test; > >>>> +import org.junit.runner.RunWith; > >>>> +import org.junit.runners.Parameterized; > >>>> +import org.junit.runners.Parameterized.Parameter; > >>>> + > >>>> +import org.apache.catalina.Context; > >>>> +import org.apache.catalina.connector.Connector; > >>>> +import org.apache.catalina.startup.TesterServlet; > >>>> +import org.apache.catalina.startup.Tomcat; > >>>> +import org.apache.catalina.startup.TomcatBaseTest; > >>>> +import org.apache.tomcat.util.buf.ByteChunk; > >>>> +import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type; > >>>> +import org.apache.tomcat.util.net.openssl.OpenSSLStatus; > >>>> + > >>>> +@RunWith(Parameterized.class) > >>>> +public class TestPQC extends TomcatBaseTest { > >>>> + > >>>> + @Parameterized.Parameters(name = "{0}") > >>>> + public static Collection<Object[]> parameters() { > >>>> + List<Object[]> parameterSets = new ArrayList<>(); > >>>> + parameterSets.add(new Object[] { > >>>> + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net > >>> .jsse.JSSEImplementation"}); > >>>> + parameterSets.add(new Object[] { > >>>> + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net > >>> .openssl.OpenSSLImplementation"}); > >>>> + parameterSets.add(new Object[] { > >>>> + "OpenSSL-FFM", Boolean.TRUE, " > >>> org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation"}); > >>>> + return parameterSets; > >>>> + } > >>>> + > >>>> + @Parameter(0) > >>>> + public String connectorName; > >>>> + > >>>> + @Parameter(1) > >>>> + public boolean useOpenSSL; > >>>> + > >>>> + @Parameter(2) > >>>> + public String sslImplementationName; > >>>> + > >>>> + @Override > >>>> + public void setUp() throws Exception { > >>>> + super.setUp(); > >>>> + > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + Connector connector = tomcat.getConnector(); > >>>> + > >>>> + Assert.assertTrue(connector.setProperty("SSLEnabled", "true")); > >>>> + SSLHostConfig sslHostConfig = new SSLHostConfig(); > >>>> + sslHostConfig.setProtocols(Constants.SSL_PROTO_TLSv1_3); > >>>> + connector.addSslHostConfig(sslHostConfig); > >>>> + > >>>> + TesterSupport.configureSSLImplementation(tomcat, > >>> sslImplementationName, useOpenSSL); > >>>> + > >>>> + Context ctx = getProgrammaticRootContext(); > >>>> + Tomcat.addServlet(ctx, "TesterServlet", new TesterServlet()); > >>>> + ctx.addServletMappingDecoded("/*", "TesterServlet"); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testHostMLDSA44() throws Exception { > >>>> + File[] pqcFiles = configureHostMLDSA("ML-DSA-44"); > >>>> + doTestWithOpenSSLClient(pqcFiles[0].getAbsolutePath(), null, > >>> null, null); > >>>> + } > >>>> + > >>>> + > >>>> + @Test > >>>> + public void testHostMLDSA65() throws Exception { > >>>> + File[] pqcFiles = configureHostMLDSA("ML-DSA-65"); > >>>> + doTestWithOpenSSLClient(pqcFiles[0].getAbsolutePath(), null, > >>> null, null); > >>>> + } > >>>> + > >>>> + > >>>> + @Test > >>>> + public void testHostMLDSA87() throws Exception { > >>>> + File[] pqcFiles = configureHostMLDSA("ML-DSA-87"); > >>>> + doTestWithOpenSSLClient(pqcFiles[0].getAbsolutePath(), null, > >>> null, null); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testHostRSAandMLDSA() throws Exception { > >>>> + configureHostRSA(); > >>>> + configureHostMLDSA("ML-DSA-65"); > >>>> + doTest(); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testHostECandMLDSA() throws Exception { > >>>> + configureHostEC(); > >>>> + configureHostMLDSA("ML-DSA-65"); > >>>> + doTest(); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testHostRSAwithX25519MLKEM768() throws Exception { > >>>> + configureHostRSA(); > >>>> + configureHostWithGroup("X25519MLKEM768"); > >>>> + doTestWithOpenSSLClient(new > >>> File(TesterSupport.CA_CERT_PEM).getAbsolutePath(), > >>>> + "X25519MLKEM768", null, null); > >>>> + } > >>>> + > >>>> + > >>>> + @Test > >>>> + public void testHostRSAwithSecP256r1MLKEM768() throws Exception { > >>>> + configureHostRSA(); > >>>> + configureHostWithGroup("SecP256r1MLKEM768"); > >>>> + doTestWithOpenSSLClient(new > >>> File(TesterSupport.CA_CERT_PEM).getAbsolutePath(), > >>>> + "SecP256r1MLKEM768", null, null); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testHostRSAwithSecP384r1MLKEM1024() throws Exception { > >>>> + configureHostRSA(); > >>>> + configureHostWithGroup("SecP384r1MLKEM1024"); > >>>> + doTestWithOpenSSLClient(new > >>> File(TesterSupport.CA_CERT_PEM).getAbsolutePath(), > >>>> + "SecP384r1MLKEM1024", null, null); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testHostMLDSAwithX25519MLKEM768() throws Exception { > >>>> + File[] pqcFiles = configureHostMLDSA("ML-DSA-65"); > >>>> + configureHostWithGroup("X25519MLKEM768"); > >>>> + doTestWithOpenSSLClient(pqcFiles[0].getAbsolutePath(), > >>> "X25519MLKEM768", null, null); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testHostMLDSAwithSecP256r1MLKEM768() throws Exception { > >>>> + File[] pqcFiles = configureHostMLDSA("ML-DSA-65"); > >>>> + configureHostWithGroup("SecP256r1MLKEM768"); > >>>> + doTestWithOpenSSLClient(pqcFiles[0].getAbsolutePath(), > >>> "SecP256r1MLKEM768", null, null); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testClientMLDSA() throws Exception { > >>>> + configureHostRSA(); > >>>> + File[] clientFiles = > >>> TesterKeystoreGenerator.generatePQCCertificate("testuser", "ML-DSA-65", > >>>> + null, null); > >>>> + SSLHostConfig sslHostConfig = > >>> getTomcatInstance().getConnector().findSslHostConfigs()[0]; > >>>> + sslHostConfig.setCertificateVerification("required"); > >>>> + > >>> sslHostConfig.setCaCertificateFile(clientFiles[0].getAbsolutePath()); > >>>> + doTestWithOpenSSLClient(new > >>> File(TesterSupport.CA_CERT_PEM).getAbsolutePath(), null, > >>>> + clientFiles[0].getAbsolutePath(), > >>> clientFiles[1].getAbsolutePath()); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void testClientMLDSAwithMLDSAServer() throws Exception { > >>>> + File[] serverFiles = configureHostMLDSA("ML-DSA-65"); > >>>> + File[] clientFiles = > >>> TesterKeystoreGenerator.generatePQCCertificate("testuser", "ML-DSA-65", > >>>> + null, null); > >>>> + SSLHostConfig sslHostConfig = > >>> getTomcatInstance().getConnector().findSslHostConfigs()[0]; > >>>> + sslHostConfig.setCertificateVerification("required"); > >>>> + > >>> sslHostConfig.setCaCertificateFile(clientFiles[0].getAbsolutePath()); > >>>> + doTestWithOpenSSLClient(serverFiles[0].getAbsolutePath(), null, > >>>> + clientFiles[0].getAbsolutePath(), > >>> clientFiles[1].getAbsolutePath()); > >>>> + } > >>>> + > >>>> + @Test(expected = SSLHandshakeException.class) > >>>> + public void testHostMLDSAHandshakeFailure() throws Exception { > >>>> + assumePQCSupported(); > >>>> + configureHostMLDSA("ML-DSA-65"); > >>>> + > >>>> + SSLContext sc = > >>> SSLContext.getInstance(Constants.SSL_PROTO_TLSv1_2); > >>>> + sc.init(null, new TrustManager[] { new > >>> TesterSupport.TrustAllCerts() }, null); > >>>> + TesterSupport.ClientSSLSocketFactory clientSSLSocketFactory = > >>>> + new > >>> TesterSupport.ClientSSLSocketFactory(sc.getSocketFactory()); > >>>> + clientSSLSocketFactory.setProtocols(new String[] { > >>> Constants.SSL_PROTO_TLSv1_2 }); > >>>> + > >>> javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(clientSSLSocketFactory); > >>>> + > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + tomcat.start(); > >>>> + getUrl("https://localhost:" + getPort() + "/"); > >>>> + } > >>>> + > >>>> + > >>>> + private void assumePQCSupported() { > >>>> + if (!useOpenSSL) { > >>>> + Assume.assumeTrue("JSSE does not yet support PQC", false); > >>>> + } > >>>> + > >>>> + Assume.assumeTrue("PQC requires OpenSSL 3.5+", > >>>> + OpenSSLStatus.getMajorVersion() > 3 || > >>>> + OpenSSLStatus.getMajorVersion() == 3 && > >>> OpenSSLStatus.getMinorVersion() >= 5); > >>>> + } > >>>> + > >>>> + private File[] configureHostMLDSA(String algorithm) throws > >>> Exception { > >>>> + File[] pqcFiles = > >>> TesterKeystoreGenerator.generatePQCCertificate("localhost", algorithm, > >>>> + new String[] { "localhost" }, null); > >>>> + > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + Connector connector = tomcat.getConnector(); > >>>> + SSLHostConfig sslHostConfig = > >>> connector.findSslHostConfigs()[0]; > >>>> + > >>>> + SSLHostConfigCertificate cert = new > >>> SSLHostConfigCertificate(sslHostConfig, Type.MLDSA); > >>>> + cert.setCertificateFile(pqcFiles[0].getAbsolutePath()); > >>>> + cert.setCertificateKeyFile(pqcFiles[1].getAbsolutePath()); > >>>> + sslHostConfig.addCertificate(cert); > >>>> + > >>>> + return pqcFiles; > >>>> + } > >>>> + > >>>> + private void configureHostRSA() { > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + Connector connector = tomcat.getConnector(); > >>>> + SSLHostConfig sslHostConfig = > >>> connector.findSslHostConfigs()[0]; > >>>> + > >>>> + SSLHostConfigCertificate cert = new > >>> SSLHostConfigCertificate(sslHostConfig, Type.RSA); > >>>> + cert.setCertificateFile(new > >>> File(TesterSupport.LOCALHOST_RSA_CERT_PEM).getAbsolutePath()); > >>>> + cert.setCertificateKeyFile(new > >>> File(TesterSupport.LOCALHOST_RSA_KEY_PEM).getAbsolutePath()); > >>>> + cert.setCertificateKeyPassword(TesterSupport.JKS_PASS); > >>>> + sslHostConfig.addCertificate(cert); > >>>> + } > >>>> + > >>>> + private void configureHostEC() { > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + Connector connector = tomcat.getConnector(); > >>>> + SSLHostConfig sslHostConfig = > >>> connector.findSslHostConfigs()[0]; > >>>> + > >>>> + SSLHostConfigCertificate cert = new > >>> SSLHostConfigCertificate(sslHostConfig, Type.EC); > >>>> + cert.setCertificateFile(new > >>> File(TesterSupport.LOCALHOST_EC_CERT_PEM).getAbsolutePath()); > >>>> + cert.setCertificateKeyFile(new > >>> File(TesterSupport.LOCALHOST_EC_KEY_PEM).getAbsolutePath()); > >>>> + sslHostConfig.addCertificate(cert); > >>>> + } > >>>> + > >>>> + private void configureHostWithGroup(String groupName) { > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + Connector connector = tomcat.getConnector(); > >>>> + SSLHostConfig sslHostConfig = > >>> connector.findSslHostConfigs()[0]; > >>>> + sslHostConfig.setGroups(groupName); > >>>> + } > >>>> + > >>>> + private void doTest() throws Exception { > >>>> + assumePQCSupported(); > >>>> + SSLContext sc = > >>> SSLContext.getInstance(Constants.SSL_PROTO_TLSv1_3); > >>>> + sc.init(null, new TrustManager[] { new > >>> TesterSupport.TrustAllCerts() }, null); > >>>> + > >>> javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + tomcat.start(); > >>>> + ByteChunk res = getUrl("https://localhost:" + getPort() + > >>> "/"); > >>>> + Assert.assertEquals("OK", res.toString()); > >>>> + } > >>>> + > >>>> + private void doTestWithOpenSSLClient(String caFile, String groups, > >>>> + String clientCert, String clientKey) throws Exception { > >>>> + assumePQCSupported(); > >>>> + > >>>> + Tomcat tomcat = getTomcatInstance(); > >>>> + tomcat.start(); > >>>> + > >>>> + String openSSLPath = > >>> System.getProperty("tomcat.test.openssl.path"); > >>>> + String openSSLLibPath = null; > >>>> + if (openSSLPath == null || openSSLPath.length() == 0) { > >>>> + openSSLPath = "openssl"; > >>>> + } else { > >>>> + openSSLLibPath = openSSLPath.substring(0, > >>> openSSLPath.lastIndexOf('/')); > >>>> + openSSLLibPath = openSSLLibPath + "/../:" + openSSLLibPath > >>> + "/../lib:" + openSSLLibPath + "/../lib64"; > >>>> + } > >>>> + > >>>> + List<String> cmd = new ArrayList<>(); > >>>> + cmd.add(openSSLPath); > >>>> + cmd.add("s_client"); > >>>> + cmd.add("-connect"); > >>>> + cmd.add("localhost:" + getPort()); > >>>> + cmd.add("-CAfile"); > >>>> + cmd.add(caFile); > >>>> + cmd.add("-tls1_3"); > >>>> + if (groups != null) { > >>>> + cmd.add("-groups"); > >>>> + cmd.add(groups); > >>>> + } > >>>> + if (clientCert != null) { > >>>> + cmd.add("-cert"); > >>>> + cmd.add(clientCert); > >>>> + cmd.add("-key"); > >>>> + cmd.add(clientKey); > >>>> + } > >>>> + > >>>> + ProcessBuilder pb = new ProcessBuilder(cmd); > >>>> + > >>>> + if (openSSLLibPath != null) { > >>>> + Map<String,String> env = pb.environment(); > >>>> + String libraryPath = env.get("LD_LIBRARY_PATH"); > >>>> + if (libraryPath == null) { > >>>> + libraryPath = openSSLLibPath; > >>>> + } else { > >>>> + libraryPath = libraryPath + ":" + openSSLLibPath; > >>>> + } > >>>> + env.put("LD_LIBRARY_PATH", libraryPath); > >>>> + } > >>>> + > >>>> + pb.redirectErrorStream(true); > >>>> + Process p = pb.start(); > >>>> + > >>>> + p.getOutputStream().write("GET / HTTP/1.0\r\nHost: > >>> localhost\r\n\r\n".getBytes()); > >>>> + p.getOutputStream().flush(); > >>>> + > >>>> + String output = new String(p.getInputStream().readAllBytes()); > >>>> + > >>>> + Assert.assertTrue("Process did not complete in time", > >>> p.waitFor(10, TimeUnit.SECONDS)); > >>>> + Assert.assertTrue("TLS handshake failed:\n" + output, > >>> output.contains("HTTP/1.")); > >>>> + Assert.assertTrue("Unexpected response body:\n" + output, > >>> output.contains("OK")); > >>>> + } > >>>> +} > >>>> diff --git > >>> a/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java > >>> b/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java > >>>> index 9fd4affde6..00f1772fcc 100644 > >>>> --- a/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java > >>>> +++ b/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java > >>>> @@ -19,6 +19,7 @@ package org.apache.tomcat.util.net; > >>>> > >>>> import java.io.File; > >>>> import java.io.FileOutputStream; > >>>> +import java.io.FileWriter; > >>>> import java.math.BigInteger; > >>>> import java.security.KeyPair; > >>>> import java.security.KeyPairGenerator; > >>>> @@ -33,6 +34,8 @@ import org.bouncycastle.asn1.x509.GeneralNames; > >>>> import org.bouncycastle.cert.X509v3CertificateBuilder; > >>>> import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; > >>>> import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; > >>>> +import org.bouncycastle.jce.provider.BouncyCastleProvider; > >>>> +import org.bouncycastle.openssl.jcajce.JcaPEMWriter; > >>>> import org.bouncycastle.operator.ContentSigner; > >>>> import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; > >>>> > >>>> @@ -100,4 +103,66 @@ public final class TesterKeystoreGenerator { > >>>> > >>>> return keystoreFile; > >>>> } > >>>> + > >>>> + /** > >>>> + * Generate temporary PEM files containing a self-signed PQC > >>> certificate and private key. > >>>> + * > >>>> + * @param cn the Common Name for the certificate subject > >>>> + * @param algorithm the PQC algorithm name, e.g. {@code > >>> "ML-DSA-44"}, {@code "ML-DSA-65"}, > >>>> + * or {@code "ML-DSA-87"} > >>>> + * @param sanNames DNS Subject Alternative Names to include, or > >>> {@code null} for none > >>>> + * @param customizer callback to add extensions to the > >>> certificate, or {@code null} for none > >>>> + * > >>>> + * @return a two-element array: {@code [0]} is the certificate PEM > >>> file, {@code [1]} is the > >>>> + * private key PEM file > >>>> + * > >>>> + * @throws Exception if certificate generation fails > >>>> + */ > >>>> + public static File[] generatePQCCertificate(String cn, String > >>> algorithm, String[] sanNames, > >>>> + > >>> CertificateExtensionsCustomizer customizer) throws Exception { > >>>> + BouncyCastleProvider bouncyCastleProvider = new > >>> BouncyCastleProvider(); > >>>> + > >>>> + KeyPairGenerator keyPairGenerator = > >>> KeyPairGenerator.getInstance(algorithm, bouncyCastleProvider); > >>>> + KeyPair keyPair = keyPairGenerator.generateKeyPair(); > >>>> + > >>>> + X500Name subject = new X500Name("CN=" + cn); > >>>> + BigInteger serial = > >>> BigInteger.valueOf(System.currentTimeMillis()); > >>>> + long oneDay = 86400000L; > >>>> + Date notBefore = new Date(System.currentTimeMillis() - oneDay); > >>>> + Date notAfter = new Date(System.currentTimeMillis() + 365L * > >>> oneDay); > >>>> + > >>>> + X509v3CertificateBuilder certBuilder = new > >>> JcaX509v3CertificateBuilder(subject, serial, notBefore, > >>>> + notAfter, subject, keyPair.getPublic()); > >>>> + > >>>> + if (sanNames != null && sanNames.length > 0) { > >>>> + GeneralName[] generalNames = new > >>> GeneralName[sanNames.length]; > >>>> + for (int i = 0; i < sanNames.length; i++) { > >>>> + generalNames[i] = new GeneralName(GeneralName.dNSName, > >>> sanNames[i]); > >>>> + } > >>>> + certBuilder.addExtension(Extension.subjectAlternativeName, > >>> false, new GeneralNames(generalNames)); > >>>> + } > >>>> + > >>>> + if (customizer != null) { > >>>> + customizer.customize(keyPair, certBuilder); > >>>> + } > >>>> + > >>>> + ContentSigner signer = new > >>> JcaContentSignerBuilder(algorithm).setProvider(bouncyCastleProvider) > >>>> + .build(keyPair.getPrivate()); > >>>> + X509Certificate certificate = new > >>> JcaX509CertificateConverter().setProvider(bouncyCastleProvider) > >>>> + .getCertificate(certBuilder.build(signer)); > >>>> + > >>>> + File certFile = File.createTempFile("test-pqc-cert-", ".pem"); > >>>> + certFile.deleteOnExit(); > >>>> + try (JcaPEMWriter writer = new JcaPEMWriter(new > >>> FileWriter(certFile))) { > >>>> + writer.writeObject(certificate); > >>>> + } > >>>> + > >>>> + File keyFile = File.createTempFile("test-pqc-key-", ".pem"); > >>>> + keyFile.deleteOnExit(); > >>>> + try (JcaPEMWriter writer = new JcaPEMWriter(new > >>> FileWriter(keyFile))) { > >>>> + writer.writeObject(keyPair.getPrivate()); > >>>> + } > >>>> + > >>>> + return new File[] { certFile, keyFile }; > >>>> + } > >>>> } > >>>> > >>>> > >>>> --------------------------------------------------------------------- > >>>> To unsubscribe, e-mail: [email protected] > >>>> For additional commands, e-mail: [email protected] > >>>> > >>> > >>> > >>> --------------------------------------------------------------------- > >>> To unsubscribe, e-mail: [email protected] > >>> For additional commands, e-mail: [email protected] > >>> > >>> > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
