From 7e3da7d5840247114401d7f029696ac20101dd99 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 10 Mar 2026 10:28:35 +0100 Subject: [PATCH 01/43] Remove BouncyCastle security provider registration --- .../com/oracle/graal/python/BouncyCastleFeature.java | 11 ----------- .../objects/ssl/LazyBouncyCastleProvider.java | 2 -- 2 files changed, 13 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java index a076b1625d..a2237e5f0c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java @@ -66,17 +66,6 @@ public void afterRegistration(AfterRegistrationAccess access) { if (!PythonImageBuildOptions.WITHOUT_SSL) { RuntimeClassInitializationSupport support = ImageSingletons.lookup(RuntimeClassInitializationSupport.class); - if (INITIALIZE_AT_RUNTIME) { - // Verify at build time, but reinitialize at runtime - support.initializeAtRunTime("org.bouncycastle", "security provider"); - Security.addProvider(new BouncyCastleProvider()); - } else { - support.initializeAtBuildTime("org.bouncycastle", "security provider"); - support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$Default", "RNG"); - support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$NonceAndIV", "RNG"); - LazyBouncyCastleProvider.initProvider(); - } - // SSLBasicKeyDerivation looks up the classes below reflectively since jdk-25+23 // See https://github.com/openjdk/jdk/pull/24393 String[] reflectiveClasses = new String[]{ diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java index a4e15fc0d1..5561b9c3b5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java @@ -41,7 +41,6 @@ package com.oracle.graal.python.builtins.objects.ssl; import java.security.Provider; -import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -51,7 +50,6 @@ public final class LazyBouncyCastleProvider { public static synchronized Provider initProvider() { if (securityProvider == null) { securityProvider = new BouncyCastleProvider(); - Security.addProvider(securityProvider); } return securityProvider; } From fcfd47c8d41b30cc1207cb001185b2666d8e5b88 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 10 Mar 2026 13:34:55 +0100 Subject: [PATCH 02/43] Remove stale BouncyCastleFeature imports --- .../src/com/oracle/graal/python/BouncyCastleFeature.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java index a2237e5f0c..56438e65c7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java @@ -42,13 +42,11 @@ import java.security.Security; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; -import com.oracle.graal.python.builtins.objects.ssl.LazyBouncyCastleProvider; import com.oracle.graal.python.runtime.PythonImageBuildOptions; public class BouncyCastleFeature implements Feature { From 92b66b24864dff5fbad82cec57df6ce23ef19ffa Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 10 Mar 2026 15:22:57 +0100 Subject: [PATCH 03/43] Update copyright years for BouncyCastle files --- .../src/com/oracle/graal/python/BouncyCastleFeature.java | 2 +- .../python/builtins/objects/ssl/LazyBouncyCastleProvider.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java index 56438e65c7..ebc294b795 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java index 5561b9c3b5..135c4f9dec 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 From d00d09c0679f403da6dd175cad2f047e3fb0edb3 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 14:15:44 +0100 Subject: [PATCH 04/43] Stop eager BouncyCastle provider initialization --- .../graal/python/builtins/modules/SSLModuleBuiltins.java | 4 +--- .../builtins/modules/hashlib/HashlibModuleBuiltins.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java index 3d9ec855b6..e1bd7cb2dc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -79,7 +79,6 @@ import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.ssl.CertUtils; -import com.oracle.graal.python.builtins.objects.ssl.LazyBouncyCastleProvider; import com.oracle.graal.python.builtins.objects.ssl.SSLCipher; import com.oracle.graal.python.builtins.objects.ssl.SSLCipherSelector; import com.oracle.graal.python.builtins.objects.ssl.SSLErrorCode; @@ -219,7 +218,6 @@ private static boolean tryProtocolAvailability(SSLContext context, SSLProtocol p @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - LazyBouncyCastleProvider.initProvider(); loadDefaults(core.getContext()); PythonModule module = core.lookupBuiltinModule(T__SSL); module.setAttribute(tsLiteral("OPENSSL_VERSION_NUMBER"), 0); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index 5817b3427f..6564adb562 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -88,7 +88,6 @@ import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.ssl.LazyBouncyCastleProvider; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; @@ -172,7 +171,6 @@ public void postInitialize(Python3Core core) { PythonLanguage language = core.getLanguage(); PythonModule self = core.lookupBuiltinModule(T_HASHLIB); EconomicMapStorage storage = EconomicMapStorage.create(); - LazyBouncyCastleProvider.initProvider(); ArrayList digests = new ArrayList<>(); for (var provider : Security.getProviders()) { for (var service : provider.getServices()) { From 0fd053ecfa13c6228e8f74f504f2c29b325c28cd Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 14:22:27 +0100 Subject: [PATCH 05/43] Use JDK certificate parsing for PEM certs --- .../builtins/modules/SSLModuleBuiltins.java | 4 +- .../builtins/objects/ssl/CertUtils.java | 101 +++++++++++++++--- .../objects/ssl/SSLContextBuiltins.java | 12 +-- 3 files changed, 95 insertions(+), 22 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java index e1bd7cb2dc..b5782d298c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java @@ -67,8 +67,6 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; -import org.bouncycastle.util.encoders.DecoderException; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.Builtin; @@ -441,7 +439,7 @@ private Object decode(Node inliningTarget, PConstructAndRaiseNode.Lazy construct throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(null, SSL_ERR_DECODING_PEM_FILE_UNEXPECTED_S, cert.getClass().getName()); } return CertUtils.decodeCertificate(inliningTarget, constructAndRaiseNode, (X509Certificate) certs.get(0), PythonLanguage.get(null)); - } catch (IOException | DecoderException ex) { + } catch (IOException ex) { throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(null, SSL_CANT_OPEN_FILE_S, ex.toString()); } catch (CertificateException | CRLException ex) { throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(null, SSL_ERR_DECODING_PEM_FILE_S, ex.toString()); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 7cffee1acc..e2f05021f3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -81,14 +81,13 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.cert.X509CRLHolder; -import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; @@ -142,6 +141,17 @@ public NeedsPasswordException() { } } + public static final class BadBase64Exception extends IOException { + private static final long serialVersionUID = -8554489203372180057L; + + public BadBase64Exception(Throwable cause) { + super(cause); + } + } + + private record PemBlock(String type, byte[] content) { + } + /** * openssl v3_purp.c#check_ca */ @@ -609,22 +619,87 @@ public static List getCertificates(BufferedReader r) throws IOException, @TruffleBoundary public static List getCertificates(BufferedReader r, boolean onlyCertificates) throws IOException, CertificateException, CRLException { List l = new ArrayList<>(); - PEMParser pemParser = new PEMParser(r); CertificateFactory factory = CertificateFactory.getInstance("X.509"); - Object object; - while ((object = pemParser.readObject()) != null) { - if (object instanceof X509CertificateHolder) { - // TODO use the X509CertificateHolder directly without conversion - l.add(factory.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder) object).getEncoded()))); - } - if (!onlyCertificates && object instanceof X509CRLHolder) { - // TODO use the X509CRLHolder directly without conversion - l.add(factory.generateCRL(new ByteArrayInputStream(((X509CRLHolder) object).getEncoded()))); + for (PemBlock block : readPemBlocks(r)) { + if ("CERTIFICATE".equals(block.type())) { + l.add(factory.generateCertificate(new ByteArrayInputStream(block.content()))); + } else if (!onlyCertificates && ("X509 CRL".equals(block.type()) || "CRL".equals(block.type()))) { + l.add(factory.generateCRL(new ByteArrayInputStream(block.content()))); } } return l; } + private static List readPemBlocks(BufferedReader reader) throws IOException { + StringBuilder text = new StringBuilder(); + char[] buffer = new char[8192]; + int read; + while ((read = reader.read(buffer)) != -1) { + text.append(buffer, 0, read); + } + + String data = text.toString(); + List blocks = new ArrayList<>(); + int fromIndex = 0; + while (true) { + int begin = data.indexOf("-----BEGIN ", fromIndex); + if (begin < 0) { + return blocks; + } + int typeStart = begin + "-----BEGIN ".length(); + int typeEnd = data.indexOf("-----", typeStart); + if (typeEnd < 0) { + throw new IOException("Malformed PEM header"); + } + String type = data.substring(typeStart, typeEnd); + int contentStart = typeEnd + "-----".length(); + if (contentStart < data.length() && data.charAt(contentStart) == '\r') { + contentStart++; + } + if (contentStart < data.length() && data.charAt(contentStart) == '\n') { + contentStart++; + } + + String endMarker = "-----END " + type + "-----"; + int end = data.indexOf(endMarker, contentStart); + if (end < 0) { + throw new IOException("Missing PEM footer"); + } + + String content = data.substring(contentStart, end); + if (isCertificatePemType(type)) { + blocks.add(new PemBlock(type, decodePemContent(content))); + } + fromIndex = end + endMarker.length(); + } + } + + private static boolean isCertificatePemType(String type) { + return "CERTIFICATE".equals(type) || "X509 CRL".equals(type) || "CRL".equals(type); + } + + private static byte[] decodePemContent(String content) throws IOException { + StringBuilder base64 = new StringBuilder(content.length()); + for (String line : content.split("\\R")) { + String trimmed = line.trim(); + if (trimmed.isEmpty()) { + continue; + } + if (trimmed.indexOf(':') >= 0) { + throw new IOException("Unexpected PEM headers"); + } + base64.append(trimmed); + } + if (base64.length() == 0) { + throw new IOException("Empty PEM content"); + } + try { + return Base64.getMimeDecoder().decode(base64.toString()); + } catch (IllegalArgumentException e) { + throw new BadBase64Exception(e); + } + } + // No BoundaryCallContext: constructs and raises only builtin errors @TruffleBoundary static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PConstructAndRaiseNode.Lazy raiseNode, BufferedReader reader, char[] password, X509Certificate cert) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java index 21df03c257..e80848b09e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -76,7 +76,7 @@ import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; -import org.bouncycastle.util.encoders.DecoderException; +import com.oracle.graal.python.builtins.objects.ssl.CertUtils.BadBase64Exception; import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; @@ -637,7 +637,7 @@ private void setBoundary(PSSLContext self, PyUnicodeFSDecoderNode asPath) { LOGGER.fine(() -> String.format("set_default_verify_paths file: %s. path: %s", file != null ? file.getPath() : "None", path != null ? path.getPath() : "None")); try { self.setCAEntries(CertUtils.loadVerifyLocations(file, path)); - } catch (IOException | DecoderException | GeneralSecurityException | NoCertificateFoundException ex) { + } catch (IOException | GeneralSecurityException | NoCertificateFoundException ex) { // do not raise any errors LOGGER.log(Level.FINER, "", ex); } @@ -756,7 +756,7 @@ Object load(VirtualFrame frame, PSSLContext self, Object cafile, Object capath, self.setCAEntries(CertUtils.loadVerifyLocations(file, path)); } catch (NoCertificateFoundException e) { throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_NO_CERTIFICATE_OR_CRL_FOUND, ErrorMessages.NO_CERTIFICATE_OR_CRL_FOUND); - } catch (IOException | DecoderException e) { + } catch (IOException e) { throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.X509_PEM_LIB); } } @@ -792,7 +792,7 @@ private static List getCertificates(Node inliningTarget, PConstructAndRa throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_NO_START_LINE, ErrorMessages.SSL_PEM_NO_START_LINE); } return certificates; - } catch (DecoderException e) { + } catch (BadBase64Exception e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_BAD_BASE64_DECODE, ErrorMessages.BAD_BASE64_DECODE); } catch (IOException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); @@ -889,7 +889,7 @@ private static Object load(PythonContext context, Node inliningTarget, PConstruc if (certs.length == 0) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } - } catch (IOException | DecoderException e) { + } catch (IOException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } // if keyReader and certReader are from the same file, key is expected to come first From 31307c611712a3b27f8f320252142ab6a78d85c9 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 14:52:05 +0100 Subject: [PATCH 06/43] Use JDK PKCS8 key parsing for SSL --- .../builtins/objects/ssl/CertUtils.java | 196 +++++++++++++++--- 1 file changed, 168 insertions(+), 28 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index e2f05021f3..4ac21999a5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -61,12 +61,15 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; +import java.security.GeneralSecurityException; import java.security.InvalidKeyException; +import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; +import java.security.Security; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; @@ -76,6 +79,8 @@ import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -85,7 +90,9 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PEMEncryptedKeyPair; @@ -99,6 +106,11 @@ import org.bouncycastle.pkcs.PKCSException; import org.bouncycastle.util.encoders.DecoderException; +import javax.crypto.EncryptedPrivateKeyInfo; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; @@ -152,6 +164,9 @@ public BadBase64Exception(Throwable cause) { private record PemBlock(String type, byte[] content) { } + private record KeyPemBlock(String type, byte[] content, Map headers) { + } + /** * openssl v3_purp.c#check_ca */ @@ -704,41 +719,26 @@ private static byte[] decodePemContent(String content) throws IOException { @TruffleBoundary static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PConstructAndRaiseNode.Lazy raiseNode, BufferedReader reader, char[] password, X509Certificate cert) throws NeedsPasswordException { - PEMParser pemParser = new PEMParser(reader); - JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); - Provider provider = LazyBouncyCastleProvider.initProvider(); - converter.setProvider(provider); PrivateKey privateKey = null; + String algorithm = cert.getPublicKey().getAlgorithm(); try { - Object object; - while ((object = pemParser.readObject()) != null) { - PrivateKeyInfo pkInfo; - if (object instanceof PEMKeyPair) { - pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); - } else if (object instanceof PEMEncryptedKeyPair) { + String pemText = readText(reader); + for (KeyPemBlock block : readPrivateKeyPemBlocks(new BufferedReader(new java.io.StringReader(pemText)))) { + if ("PRIVATE KEY".equals(block.type())) { + privateKey = decodePrivateKey(algorithm, block.content()); + break; + } else if ("ENCRYPTED PRIVATE KEY".equals(block.type())) { if (password == null) { throw new NeedsPasswordException(); } - JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder(); - decryptor.setProvider(provider); - PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); - pkInfo = keyPair.getPrivateKeyInfo(); - } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { - if (password == null) { - throw new NeedsPasswordException(); - } - JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder(); - decryptor.setProvider(provider); - pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); - } else if (object instanceof PrivateKeyInfo) { - pkInfo = (PrivateKeyInfo) object; - } else { - continue; + privateKey = decodeEncryptedPrivateKey(algorithm, block.content(), password); + break; } - privateKey = converter.getPrivateKey(pkInfo); - break; } - } catch (IOException | DecoderException | OperatorCreationException | PKCSException e) { + if (privateKey == null) { + privateKey = getPrivateKeyWithBC(inliningTarget, raiseNode, password, cert, pemText); + } + } catch (IOException | DecoderException | GeneralSecurityException | OperatorCreationException | PKCSException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } if (privateKey == null) { @@ -749,6 +749,146 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon return privateKey; } + private static List readPrivateKeyPemBlocks(BufferedReader reader) throws IOException { + String data = readText(reader); + List blocks = new ArrayList<>(); + int fromIndex = 0; + while (true) { + int begin = data.indexOf("-----BEGIN ", fromIndex); + if (begin < 0) { + return blocks; + } + int typeStart = begin + "-----BEGIN ".length(); + int typeEnd = data.indexOf("-----", typeStart); + if (typeEnd < 0) { + throw new IOException("Malformed PEM header"); + } + String type = data.substring(typeStart, typeEnd); + int contentStart = typeEnd + "-----".length(); + if (contentStart < data.length() && data.charAt(contentStart) == '\r') { + contentStart++; + } + if (contentStart < data.length() && data.charAt(contentStart) == '\n') { + contentStart++; + } + String endMarker = "-----END " + type + "-----"; + int end = data.indexOf(endMarker, contentStart); + if (end < 0) { + throw new IOException("Missing PEM footer"); + } + String content = data.substring(contentStart, end); + blocks.add(decodePrivateKeyPemBlock(type, content)); + fromIndex = end + endMarker.length(); + } + } + + private static KeyPemBlock decodePrivateKeyPemBlock(String type, String content) throws IOException { + Map headers = new LinkedHashMap<>(); + StringBuilder base64 = new StringBuilder(content.length()); + boolean seenBase64 = false; + for (String line : content.split("\\R")) { + String trimmed = line.trim(); + if (trimmed.isEmpty()) { + continue; + } + int colon = trimmed.indexOf(':'); + if (!seenBase64 && colon >= 0) { + headers.put(trimmed.substring(0, colon).trim(), trimmed.substring(colon + 1).trim()); + } else { + if (colon >= 0) { + throw new IOException("Malformed PEM content"); + } + seenBase64 = true; + base64.append(trimmed); + } + } + if (base64.length() == 0) { + throw new IOException("Empty PEM content"); + } + try { + return new KeyPemBlock(type, Base64.getMimeDecoder().decode(base64.toString()), headers); + } catch (IllegalArgumentException e) { + throw new BadBase64Exception(e); + } + } + + private static String readText(BufferedReader reader) throws IOException { + StringBuilder text = new StringBuilder(); + char[] buffer = new char[8192]; + int read; + while ((read = reader.read(buffer)) != -1) { + text.append(buffer, 0, read); + } + return text.toString(); + } + + private static PrivateKey decodePrivateKey(String algorithm, byte[] encoded) throws NoSuchAlgorithmException, InvalidKeySpecException { + return getKeyFactory(algorithm).generatePrivate(new PKCS8EncodedKeySpec(encoded)); + } + + private static PrivateKey decodeEncryptedPrivateKey(String algorithm, byte[] encoded, char[] password) throws IOException, GeneralSecurityException { + EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(encoded); + SecretKeyFactory secretKeyFactory = getSecretKeyFactory(encryptedPrivateKeyInfo.getAlgName()); + SecretKey secretKey = secretKeyFactory.generateSecret(new PBEKeySpec(password)); + Provider provider = getPreferredSecurityProvider(); + PKCS8EncodedKeySpec keySpec = provider != null ? encryptedPrivateKeyInfo.getKeySpec(secretKey, provider) : encryptedPrivateKeyInfo.getKeySpec(secretKey); + return getKeyFactory(algorithm).generatePrivate(keySpec); + } + + private static KeyFactory getKeyFactory(String algorithm) throws NoSuchAlgorithmException { + Provider provider = getPreferredSecurityProvider(); + return provider != null ? KeyFactory.getInstance(algorithm, provider) : KeyFactory.getInstance(algorithm); + } + + private static SecretKeyFactory getSecretKeyFactory(String algorithm) throws NoSuchAlgorithmException { + Provider provider = getPreferredSecurityProvider(); + return provider != null ? SecretKeyFactory.getInstance(algorithm, provider) : SecretKeyFactory.getInstance(algorithm); + } + + private static Provider getPreferredSecurityProvider() { + String providerName = System.getProperty("python.security.provider"); + if (providerName == null || providerName.isEmpty()) { + return null; + } + return Security.getProvider(providerName); + } + + private static PrivateKey getPrivateKeyWithBC(Node inliningTarget, PConstructAndRaiseNode.Lazy raiseNode, char[] password, X509Certificate cert, String pemText) + throws IOException, NeedsPasswordException, DecoderException, OperatorCreationException, PKCSException, GeneralSecurityException { + PEMParser pemParser = new PEMParser(new java.io.StringReader(pemText)); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); + Provider provider = LazyBouncyCastleProvider.initProvider(); + converter.setProvider(provider); + Object object; + while ((object = pemParser.readObject()) != null) { + PrivateKeyInfo pkInfo; + if (object instanceof PEMKeyPair) { + pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); + } else if (object instanceof PEMEncryptedKeyPair) { + if (password == null) { + throw new NeedsPasswordException(); + } + JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder(); + decryptor.setProvider(provider); + PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); + pkInfo = keyPair.getPrivateKeyInfo(); + } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { + if (password == null) { + throw new NeedsPasswordException(); + } + JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder(); + decryptor.setProvider(provider); + pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); + } else if (object instanceof PrivateKeyInfo) { + pkInfo = (PrivateKeyInfo) object; + } else { + continue; + } + return converter.getPrivateKey(pkInfo); + } + return null; + } + private static void checkPrivateKey(Node inliningTarget, PConstructAndRaiseNode.Lazy raiseNode, PythonContext context, PrivateKey privateKey, PublicKey publicKey) { /* * Check that the private key matches the public key by signing and verifying a short piece From 5e86953bdc4810a11b25647d0c99f3e217eb5b79 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 14:57:26 +0100 Subject: [PATCH 07/43] Decode PKCS1 RSA keys without BC provider --- .../builtins/objects/ssl/CertUtils.java | 83 +++++++++++++++---- 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 4ac21999a5..4a08fdb1b7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -81,6 +81,7 @@ import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -340,6 +341,7 @@ private static PTuple parseSubjectAltName(X509Certificate certificate, PythonLan // private static private static final class DerValue { + private static final byte INTEGER = 0x02; private static final byte OCTET_STRING = 0x04; private static final byte OBJECT_IDENTIFIER = 0x06; private static final byte SEQUENCE = 0x10; @@ -405,6 +407,31 @@ byte[] getRawData() { return Arrays.copyOfRange(data, contentStart, contentStart + contentLen); } + BigInteger getInteger() throws CertificateParsingException { + if (contentTag != INTEGER) { + throw new CertificateParsingException(ERROR_MESSAGE); + } + return new BigInteger(getRawData()); + } + + List getSequenceElements() throws CertificateParsingException { + if (contentTag != SEQUENCE) { + throw new CertificateParsingException(ERROR_MESSAGE); + } + ArrayList values = new ArrayList<>(); + int offset = contentStart; + int end = contentStart + contentLen; + while (offset < end) { + DerValue value = new DerValue(data, offset, end); + values.add(value); + offset = value.contentStart + value.contentLen; + } + if (offset != end) { + throw new CertificateParsingException(ERROR_MESSAGE); + } + return values; + } + DerValue getObjectIdentifier() throws CertificateParsingException { if (contentTag != OBJECT_IDENTIFIER) { return null; @@ -456,14 +483,6 @@ String getGeneralNameURI() { } } - List getSequenceElements() throws CertificateParsingException { - List result = new ArrayList<>(); - iterateSequence((e, r) -> { - result.add(e); - }, result); - return result; - } - @FunctionalInterface private interface DerSequenceConsumer { abstract void accept(A a, B b) throws CertificateParsingException; @@ -733,11 +752,18 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon } privateKey = decodeEncryptedPrivateKey(algorithm, block.content(), password); break; + } else if ("RSA PRIVATE KEY".equals(block.type())) { + if (block.headers().isEmpty()) { + privateKey = decodeRsaPrivateKey(block.content()); + } else { + if (password == null) { + throw new NeedsPasswordException(); + } + privateKey = getPrivateKeyWithBC(password, pemText); + } + break; } } - if (privateKey == null) { - privateKey = getPrivateKeyWithBC(inliningTarget, raiseNode, password, cert, pemText); - } } catch (IOException | DecoderException | GeneralSecurityException | OperatorCreationException | PKCSException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } @@ -835,6 +861,33 @@ private static PrivateKey decodeEncryptedPrivateKey(String algorithm, byte[] enc return getKeyFactory(algorithm).generatePrivate(keySpec); } + private static PrivateKey decodeRsaPrivateKey(byte[] encoded) throws InvalidKeySpecException, NoSuchAlgorithmException { + try { + DerValue sequence = new DerValue(encoded).getSequence(); + List values = sequence.getSequenceElements(); + if (values.size() < 9) { + throw new InvalidKeySpecException("Invalid RSA private key"); + } + BigInteger version = values.get(0).getInteger(); + if (!BigInteger.ZERO.equals(version) && !BigInteger.ONE.equals(version)) { + throw new InvalidKeySpecException("Unsupported RSA private key version"); + } + RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec( + values.get(1).getInteger(), + values.get(2).getInteger(), + values.get(3).getInteger(), + values.get(4).getInteger(), + values.get(5).getInteger(), + values.get(6).getInteger(), + values.get(7).getInteger(), + values.get(8).getInteger()); + return getKeyFactory("RSA").generatePrivate(keySpec); + } catch (CertificateParsingException e) { + throw new InvalidKeySpecException("Invalid RSA private key", e); + } + } + + private static KeyFactory getKeyFactory(String algorithm) throws NoSuchAlgorithmException { Provider provider = getPreferredSecurityProvider(); return provider != null ? KeyFactory.getInstance(algorithm, provider) : KeyFactory.getInstance(algorithm); @@ -853,12 +906,10 @@ private static Provider getPreferredSecurityProvider() { return Security.getProvider(providerName); } - private static PrivateKey getPrivateKeyWithBC(Node inliningTarget, PConstructAndRaiseNode.Lazy raiseNode, char[] password, X509Certificate cert, String pemText) - throws IOException, NeedsPasswordException, DecoderException, OperatorCreationException, PKCSException, GeneralSecurityException { + private static PrivateKey getPrivateKeyWithBC(char[] password, String pemText) + throws IOException, NeedsPasswordException, DecoderException, OperatorCreationException, PKCSException { PEMParser pemParser = new PEMParser(new java.io.StringReader(pemText)); JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); - Provider provider = LazyBouncyCastleProvider.initProvider(); - converter.setProvider(provider); Object object; while ((object = pemParser.readObject()) != null) { PrivateKeyInfo pkInfo; @@ -869,7 +920,6 @@ private static PrivateKey getPrivateKeyWithBC(Node inliningTarget, PConstructAnd throw new NeedsPasswordException(); } JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder(); - decryptor.setProvider(provider); PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); pkInfo = keyPair.getPrivateKeyInfo(); } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { @@ -877,7 +927,6 @@ private static PrivateKey getPrivateKeyWithBC(Node inliningTarget, PConstructAnd throw new NeedsPasswordException(); } JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder(); - decryptor.setProvider(provider); pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); } else if (object instanceof PrivateKeyInfo) { pkInfo = (PrivateKeyInfo) object; From ddfa7336a32d1f91c8ceee68a807e2d2098692d6 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 15:10:19 +0100 Subject: [PATCH 08/43] Clean BC native-image reachability hooks --- .../python-language/native-image.properties | 2 +- .../python-language/reflect-config.json | 2851 ----------------- ...stleFeature.java => SSLCryptoFeature.java} | 14 +- .../objects/ssl/LazyBouncyCastleProvider.java | 56 - 4 files changed, 2 insertions(+), 2921 deletions(-) rename graalpython/com.oracle.graal.python/src/com/oracle/graal/python/{BouncyCastleFeature.java => SSLCryptoFeature.java} (86%) delete mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties index 5a301fcffd..4bbba3b546 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties @@ -1,6 +1,6 @@ # This file contains native-image arguments needed to build graalpython Args = -H:MaxRuntimeCompileMethods=20000 \ --initialize-at-build-time=com.oracle.graal.python,com.oracle.truffle.regex \ - --features=com.oracle.graal.python.BouncyCastleFeature \ + --features=com.oracle.graal.python.SSLCryptoFeature \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=org.graalvm.py \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json index 01c0e6128f..df04bb22ae 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json @@ -73,2856 +73,5 @@ "parameterTypes": [] } ] - }, - { - "name": "com.sun.crypto.provider.AESCipher$General", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.AESKeyGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.ARCFOURCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DESCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DESedeCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DHParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.GaloisCounterMode$AESGCM", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.HmacCore$HmacSHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsKeyMaterialGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsMasterSecretGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsPrfGenerator$V12", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.KeyStoreSpi", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.cert.PKIXRevocationChecker", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.DSAPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.DSAPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.ECPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.ECPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.RSAPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.RSAPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.spec.DSAParameterSpec", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "javax.crypto.spec.GCMParameterSpec", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.CompositeSignatures$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.DSTU4145$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.Dilithium$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ECGOST$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.EXTERNAL$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.EdEC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ElGamal$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.Falcon$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.GM$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.GOST$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.IES$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.LMS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.NTRU$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.SPHINCSPlus$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$ECDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi$ecDSA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s128", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Blake3_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest288", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD4$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD4$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD5$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA1$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA224$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA256$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash128_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash256_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake128_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake256_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash128_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash256_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA384$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA512$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SM3$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SM3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_1024", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_128", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_128", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.drbg.DRBG$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.keystore.BC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.keystore.BCFKS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.AES$AlgParams", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.AES$ECB", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.AES$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.ARIA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.CAST5$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.CAST6$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Camellia$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.ChaCha$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.DES$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.DSTU7624$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.GOST28147$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.GOST3412_2015$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Grain128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Grainv1$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.HC128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.HC256$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.IDEA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Noekeon$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.OpenSSLPBKDF$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF1$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$PBKDF2withSHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Poly1305$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.RC5$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.RC6$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Rijndael$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SCRYPT$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SEED$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SM4$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Salsa20$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Serpent$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Shacal2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Skipjack$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.TEA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.TLSKDF$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Threefish$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.VMPC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.VMPCKSA3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.XSalsa20$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.XTEA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Zuc$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.BIKE$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.CMCE$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Dilithium$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Falcon$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Frodo$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.HQC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Kyber$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.LMS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.NH$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.NTRU$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.NTRUPrime$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Picnic$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Rainbow$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.SABER$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCSPlus$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.XMSS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.pkcs12.PKCS12KeyStore", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA1withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA224withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA256withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSAKeyFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSAParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.JavaKeyStore$DualFormatJKS", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.JavaKeyStore$JKS", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.MD2", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.MD5", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.NativePRNG", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.SecureRandomParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.NativePRNG$NonBlocking", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.SecureRandomParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA2$SHA224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA2$SHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512_224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.X509Factory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.CollectionCertStore", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.cert.CertStoreParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.PKIXCertPathValidator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.SunCertPathBuilder", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.PSSParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSAKeyFactory$Legacy", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSAPSSSignature", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$MD5withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$SHA224withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$SHA256withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.KeyManagerFactoryImpl$SunX509", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.SSLContextImpl$TLSContext", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.AuthorityInfoAccessExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.AuthorityKeyIdentifierExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.BasicConstraintsExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CRLDistributionPointsExtension", - "fields": [ - { - "name": "NAME" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CRLNumberExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CertificatePoliciesExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.ExtendedKeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.IssuerAlternativeNameExtension", - "fields": [ - { - "name": "NAME" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.KeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.NetscapeCertTypeExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.PrivateKeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.SubjectAlternativeNameExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.SubjectKeyIdentifierExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } } ] diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/SSLCryptoFeature.java similarity index 86% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/SSLCryptoFeature.java index ebc294b795..a04aeb8cc1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/SSLCryptoFeature.java @@ -42,28 +42,16 @@ import java.security.Security; -import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; -import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; import com.oracle.graal.python.runtime.PythonImageBuildOptions; -public class BouncyCastleFeature implements Feature { - - /* - * Will soon be default in native image. We'll still need the old way to support older - * native-image in JDK 21. I guess then it would be something like: - * - * INITIALIZE_AT_RUNTIME = Runtime.version().feature() >= 26; - */ - private static final boolean INITIALIZE_AT_RUNTIME = false; +public class SSLCryptoFeature implements Feature { @Override public void afterRegistration(AfterRegistrationAccess access) { if (!PythonImageBuildOptions.WITHOUT_SSL) { - RuntimeClassInitializationSupport support = ImageSingletons.lookup(RuntimeClassInitializationSupport.class); - // SSLBasicKeyDerivation looks up the classes below reflectively since jdk-25+23 // See https://github.com/openjdk/jdk/pull/24393 String[] reflectiveClasses = new String[]{ diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java deleted file mode 100644 index 135c4f9dec..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.ssl; - -import java.security.Provider; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -public final class LazyBouncyCastleProvider { - private static Provider securityProvider; - - public static synchronized Provider initProvider() { - if (securityProvider == null) { - securityProvider = new BouncyCastleProvider(); - } - return securityProvider; - } -} From b051df9a526f14c0fa79895fa82bee39f6e365b1 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 15:46:16 +0100 Subject: [PATCH 09/43] Restore BC native-image metadata for SSL fallback --- .../python-language/native-image.properties | 3 +- .../python-language/reflect-config.json | 2851 +++++++++++++++++ ...oFeature.java => BouncyCastleFeature.java} | 14 +- .../objects/ssl/LazyBouncyCastleProvider.java | 56 + 4 files changed, 2922 insertions(+), 2 deletions(-) rename graalpython/com.oracle.graal.python/src/com/oracle/graal/python/{SSLCryptoFeature.java => BouncyCastleFeature.java} (86%) create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties index 4bbba3b546..d686685cc4 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties @@ -1,6 +1,7 @@ # This file contains native-image arguments needed to build graalpython Args = -H:MaxRuntimeCompileMethods=20000 \ --initialize-at-build-time=com.oracle.graal.python,com.oracle.truffle.regex \ - --features=com.oracle.graal.python.SSLCryptoFeature \ + --initialize-at-run-time=org.bouncycastle \ + --features=com.oracle.graal.python.BouncyCastleFeature \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=org.graalvm.py \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json index df04bb22ae..01c0e6128f 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json @@ -73,5 +73,2856 @@ "parameterTypes": [] } ] + }, + { + "name": "com.sun.crypto.provider.AESCipher$General", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.AESKeyGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.ARCFOURCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.DESCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.DESedeCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.DHParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.GaloisCounterMode$AESGCM", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.HmacCore$HmacSHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.TlsKeyMaterialGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.TlsPrfGenerator$V12", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.KeyStoreSpi", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.cert.PKIXRevocationChecker", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.DSAPrivateKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.DSAPublicKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.ECPrivateKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.ECPublicKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.RSAPrivateKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.RSAPublicKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.spec.DSAParameterSpec", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "javax.crypto.spec.GCMParameterSpec", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.CompositeSignatures$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.DSTU4145$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.Dilithium$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ECGOST$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.EXTERNAL$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.EdEC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ElGamal$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.Falcon$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.GM$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.GOST$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.IES$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.LMS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.NTRU$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.SPHINCSPlus$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$ECDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi$ecDSA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s128", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Blake3_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest288", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD4$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD4$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD5$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA1$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA224$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA256$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash128_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash256_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake128_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake256_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash128_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash256_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA384$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA512$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SM3$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SM3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_1024", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_128", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_128", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.drbg.DRBG$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.keystore.BC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.keystore.BCFKS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$AlgParams", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$ECB", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.ARIA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.CAST5$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.CAST6$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Camellia$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.ChaCha$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.DES$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.DSTU7624$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.GOST28147$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.GOST3412_2015$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Grain128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Grainv1$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.HC128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.HC256$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.IDEA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Noekeon$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.OpenSSLPBKDF$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF1$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$PBKDF2withSHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Poly1305$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.RC5$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.RC6$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Rijndael$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SCRYPT$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SEED$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SM4$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Salsa20$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Serpent$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Shacal2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Skipjack$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.TEA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.TLSKDF$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Threefish$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.VMPC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.VMPCKSA3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.XSalsa20$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.XTEA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Zuc$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.BIKE$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.CMCE$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Dilithium$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Falcon$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Frodo$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.HQC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Kyber$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.LMS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.NH$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.NTRU$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.NTRUPrime$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Picnic$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Rainbow$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.SABER$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCSPlus$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.XMSS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.pkcs12.PKCS12KeyStore", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSA$SHA1withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSA$SHA224withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSA$SHA256withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSAKeyFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSAParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.JavaKeyStore$DualFormatJKS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.JavaKeyStore$JKS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.MD2", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.MD5", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.NativePRNG", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.NativePRNG$NonBlocking", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA2$SHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA2$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA512_224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA512_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.X509Factory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.certpath.CollectionCertStore", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.cert.CertStoreParameters" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.certpath.PKIXCertPathValidator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.certpath.SunCertPathBuilder", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.PSSParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSAKeyFactory$Legacy", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSAPSSSignature", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSASignature$MD5withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSASignature$SHA224withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSASignature$SHA256withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.ssl.SSLContextImpl$TLSContext", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.AuthorityInfoAccessExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.AuthorityKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.BasicConstraintsExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.CRLDistributionPointsExtension", + "fields": [ + { + "name": "NAME" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.CRLNumberExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.CertificatePoliciesExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.ExtendedKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.IssuerAlternativeNameExtension", + "fields": [ + { + "name": "NAME" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.KeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.NetscapeCertTypeExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.PrivateKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.SubjectAlternativeNameExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.SubjectKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } } ] diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/SSLCryptoFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java similarity index 86% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/SSLCryptoFeature.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java index a04aeb8cc1..ebc294b795 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/SSLCryptoFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java @@ -42,16 +42,28 @@ import java.security.Security; +import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; +import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; import com.oracle.graal.python.runtime.PythonImageBuildOptions; -public class SSLCryptoFeature implements Feature { +public class BouncyCastleFeature implements Feature { + + /* + * Will soon be default in native image. We'll still need the old way to support older + * native-image in JDK 21. I guess then it would be something like: + * + * INITIALIZE_AT_RUNTIME = Runtime.version().feature() >= 26; + */ + private static final boolean INITIALIZE_AT_RUNTIME = false; @Override public void afterRegistration(AfterRegistrationAccess access) { if (!PythonImageBuildOptions.WITHOUT_SSL) { + RuntimeClassInitializationSupport support = ImageSingletons.lookup(RuntimeClassInitializationSupport.class); + // SSLBasicKeyDerivation looks up the classes below reflectively since jdk-25+23 // See https://github.com/openjdk/jdk/pull/24393 String[] reflectiveClasses = new String[]{ diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java new file mode 100644 index 0000000000..135c4f9dec --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.ssl; + +import java.security.Provider; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +public final class LazyBouncyCastleProvider { + private static Provider securityProvider; + + public static synchronized Provider initProvider() { + if (securityProvider == null) { + securityProvider = new BouncyCastleProvider(); + } + return securityProvider; + } +} From 50e80ac9065930d5730364191c7967f4ab83f9b7 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 16:34:05 +0100 Subject: [PATCH 10/43] Add optional BC support SPI for SSL --- ...uiltins.objects.ssl.SSLBouncyCastleSupport | 1 + .../BCSSLBouncyCastleSupport.java | 97 +++++++++++++++++++ .../objects/ssl/SSLBouncyCastleSupport.java | 51 ++++++++++ .../ssl/SSLBouncyCastleSupportProvider.java | 81 ++++++++++++++++ mx.graalpython/suite.py | 31 ++++++ 5 files changed, 261 insertions(+) create mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport create mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupport.java create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport new file mode 100644 index 0000000000..9fb6b3689f --- /dev/null +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport @@ -0,0 +1 @@ +com.oracle.graal.python.bouncycastle.BCSSLBouncyCastleSupport diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java new file mode 100644 index 0000000000..9904bc5b76 --- /dev/null +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.bouncycastle; + +import java.io.IOException; +import java.io.StringReader; +import java.security.GeneralSecurityException; +import java.security.PrivateKey; + +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.openssl.PEMEncryptedKeyPair; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; +import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; +import org.bouncycastle.pkcs.PKCSException; + +import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException; +import com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport; + +public final class BCSSLBouncyCastleSupport implements SSLBouncyCastleSupport { + @Override + public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { + try (PEMParser pemParser = new PEMParser(new StringReader(pemText))) { + JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); + Object object; + while ((object = pemParser.readObject()) != null) { + PrivateKeyInfo pkInfo; + if (object instanceof PEMKeyPair) { + pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); + } else if (object instanceof PEMEncryptedKeyPair) { + if (password == null) { + throw new NeedsPasswordException(); + } + JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder(); + PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); + pkInfo = keyPair.getPrivateKeyInfo(); + } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { + if (password == null) { + throw new NeedsPasswordException(); + } + JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder(); + pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); + } else if (object instanceof PrivateKeyInfo) { + pkInfo = (PrivateKeyInfo) object; + } else { + continue; + } + return converter.getPrivateKey(pkInfo); + } + return null; + } catch (OperatorCreationException | PKCSException e) { + throw new GeneralSecurityException(e); + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupport.java new file mode 100644 index 0000000000..4e0fbd19d9 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupport.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.ssl; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.PrivateKey; + +import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException; + +public interface SSLBouncyCastleSupport { + PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException; +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java new file mode 100644 index 0000000000..08a9fc7d3a --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.ssl; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.PrivateKey; +import java.util.Iterator; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; + +import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException; + +public final class SSLBouncyCastleSupportProvider { + public static final String MISSING_MESSAGE = "Encrypted legacy PEM private keys require BouncyCastle support; add the GraalPy BC support module and BouncyCastle jars to the classpath or modulepath, or convert the key to PKCS#8."; + + private SSLBouncyCastleSupportProvider() { + } + + public static PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { + return getSupport().loadPrivateKey(password, pemText); + } + + private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleException { + try { + Iterator iterator = ServiceLoader.load(SSLBouncyCastleSupport.class, SSLBouncyCastleSupport.class.getClassLoader()).iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } + } catch (ServiceConfigurationError | LinkageError e) { + throw new MissingBouncyCastleException(e); + } + throw new MissingBouncyCastleException(null); + } + + public static final class MissingBouncyCastleException extends GeneralSecurityException { + private static final long serialVersionUID = 1L; + + MissingBouncyCastleException(Throwable cause) { + super(MISSING_MESSAGE, cause); + } + } +} diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 7a2d973fca..ef1cd55df1 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -414,6 +414,29 @@ "spotbugsIgnoresGenerated": True, }, + "com.oracle.graal.python.bouncycastle": { + "subDir": "graalpython", + "sourceDirs": ["src"], + "dependencies": [ + "com.oracle.graal.python", + "BOUNCYCASTLE-PROVIDER", + "BOUNCYCASTLE-PKIX", + "BOUNCYCASTLE-UTIL", + ], + "requires": [ + "java.logging", + "java.management", + "jdk.management", + "jdk.unsupported", + "jdk.security.auth", + ], + "jacoco": "include", + "checkstyle": "com.oracle.graal.python", + "javaCompliance": "17+", + "workingSets": "Truffle,Python", + "spotbugsIgnoresGenerated": True, + }, + # GRAALPYTHON_UNIT_TESTS "com.oracle.graal.python.test": { "subDir": "graalpython", @@ -1036,6 +1059,14 @@ ], }, + "GRAALPYTHON_BOUNCYCASTLE": { + "dependencies": [ + "com.oracle.graal.python.bouncycastle", + ], + "description": "Optional GraalPy BouncyCastle integration.", + "maven": False, + }, + "GRAALPYTHON": { "moduleInfo": { "name": "org.graalvm.py", From 936419cc664dcf4de3a49263d475ed0d08230364 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 17:10:24 +0100 Subject: [PATCH 11/43] Make SSL BouncyCastle support optional --- .../native-image.properties | 3 + .../python-bouncycastle/reflect-config.json | 2853 +++++++++++++++++ .../BCSSLBouncyCastleSupport.java | 3 + .../bouncycastle}/BouncyCastleFeature.java | 64 +- .../objects/ssl/LazyBouncyCastleProvider.java | 0 .../python-language/native-image.properties | 2 - .../python-language/reflect-config.json | 2851 ---------------- .../builtins/objects/ssl/CertUtils.java | 49 +- mx.graalpython/suite.py | 22 +- 9 files changed, 2908 insertions(+), 2939 deletions(-) create mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties create mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json rename graalpython/{com.oracle.graal.python/src/com/oracle/graal/python => com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle}/BouncyCastleFeature.java (53%) rename graalpython/{com.oracle.graal.python => com.oracle.graal.python.bouncycastle}/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java (100%) diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties new file mode 100644 index 0000000000..ed243d5034 --- /dev/null +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties @@ -0,0 +1,3 @@ +# Additional native-image arguments for optional GraalPy BouncyCastle support +Args = --initialize-at-run-time=org.bouncycastle \ + --features=com.oracle.graal.python.bouncycastle.BouncyCastleFeature diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json new file mode 100644 index 0000000000..d80bfdcc76 --- /dev/null +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json @@ -0,0 +1,2853 @@ +[ + { + "name": "com.sun.crypto.provider.AESCipher$General", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.AESKeyGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.ARCFOURCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.DESCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.DESedeCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.DHParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.GaloisCounterMode$AESGCM", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.HmacCore$HmacSHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.TlsKeyMaterialGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "com.sun.crypto.provider.TlsPrfGenerator$V12", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.KeyStoreSpi", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.cert.PKIXRevocationChecker", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.DSAPrivateKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.DSAPublicKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.ECPrivateKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.ECPublicKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.RSAPrivateKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.interfaces.RSAPublicKey", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "java.security.spec.DSAParameterSpec", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "javax.crypto.spec.GCMParameterSpec", + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.CompositeSignatures$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.DSTU4145$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.Dilithium$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ECGOST$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.EXTERNAL$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.EdEC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ElGamal$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.Falcon$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.GM$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.GOST$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.IES$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.LMS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.NTRU$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.SPHINCSPlus$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$ECDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi$ecDSA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s128", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Blake3_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest288", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD4$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD4$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.MD5$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA1$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA224$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA256$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash128_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash256_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake128_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake256_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash128_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash256_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA384$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SHA512$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SM3$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.SM3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_1024", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_128", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_128", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_160", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Skein$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Digest", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.drbg.DRBG$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.keystore.BC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.keystore.BCFKS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$AlgParams", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$ECB", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.ARIA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.CAST5$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.CAST6$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Camellia$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.ChaCha$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.DES$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.DSTU7624$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.GOST28147$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.GOST3412_2015$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Grain128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Grainv1$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.HC128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.HC256$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.IDEA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Noekeon$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.OpenSSLPBKDF$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF1$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$PBKDF2withSHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Poly1305$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.RC5$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.RC6$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Rijndael$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SCRYPT$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SEED$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SM4$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Salsa20$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Serpent$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Shacal2$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash128$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Skipjack$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.TEA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.TLSKDF$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Threefish$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.VMPC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.VMPCKSA3$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.XSalsa20$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.XTEA$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.Zuc$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.BIKE$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.CMCE$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Dilithium$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Falcon$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Frodo$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.HQC$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Kyber$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.LMS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.NH$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.NTRU$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.NTRUPrime$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Picnic$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.Rainbow$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.SABER$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCSPlus$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.pqc.jcajce.provider.XMSS$Mappings", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.pkcs12.PKCS12KeyStore", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSA$SHA1withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSA$SHA224withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSA$SHA256withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSAKeyFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.DSAParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.JavaKeyStore$DualFormatJKS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.JavaKeyStore$JKS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.MD2", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.MD5", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.NativePRNG", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.NativePRNG$NonBlocking", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA2$SHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA2$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA3$SHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA512_224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.SHA5$SHA512_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.X509Factory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.certpath.CollectionCertStore", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.cert.CertStoreParameters" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.certpath.PKIXCertPathValidator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.provider.certpath.SunCertPathBuilder", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.PSSParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSAKeyFactory$Legacy", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSAPSSSignature", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSASignature$MD5withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSASignature$SHA224withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.rsa.RSASignature$SHA256withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.ssl.SSLContextImpl$TLSContext", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.AuthorityInfoAccessExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.AuthorityKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.BasicConstraintsExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.CRLDistributionPointsExtension", + "fields": [ + { + "name": "NAME" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.CRLNumberExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.CertificatePoliciesExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.ExtendedKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.IssuerAlternativeNameExtension", + "fields": [ + { + "name": "NAME" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.KeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.NetscapeCertTypeExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.PrivateKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.SubjectAlternativeNameExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "sun.security.x509.SubjectKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + } +] diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java index 9904bc5b76..5314206e88 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java @@ -46,6 +46,7 @@ import java.security.PrivateKey; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; @@ -60,6 +61,8 @@ import com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport; public final class BCSSLBouncyCastleSupport implements SSLBouncyCastleSupport { + @SuppressWarnings("unused") private static final Class PROVIDER_CLASS = BouncyCastleProvider.class; + @Override public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { try (PEMParser pemParser = new PEMParser(new StringReader(pemText))) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java similarity index 53% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java rename to graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java index ebc294b795..6e9c3f4efd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java @@ -38,57 +38,41 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python; +package com.oracle.graal.python.bouncycastle; import java.security.Security; -import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; -import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; - -import com.oracle.graal.python.runtime.PythonImageBuildOptions; public class BouncyCastleFeature implements Feature { - /* - * Will soon be default in native image. We'll still need the old way to support older - * native-image in JDK 21. I guess then it would be something like: - * - * INITIALIZE_AT_RUNTIME = Runtime.version().feature() >= 26; - */ - private static final boolean INITIALIZE_AT_RUNTIME = false; - @Override public void afterRegistration(AfterRegistrationAccess access) { - if (!PythonImageBuildOptions.WITHOUT_SSL) { - RuntimeClassInitializationSupport support = ImageSingletons.lookup(RuntimeClassInitializationSupport.class); - - // SSLBasicKeyDerivation looks up the classes below reflectively since jdk-25+23 - // See https://github.com/openjdk/jdk/pull/24393 - String[] reflectiveClasses = new String[]{ - "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA256", - "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA384", - "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA512", - "sun.security.pkcs11.P11HKDF", - }; - for (String name : reflectiveClasses) { - try { - Class.forName(name); - } catch (SecurityException | ClassNotFoundException e) { - return; - } + // SSLBasicKeyDerivation looks up the classes below reflectively since jdk-25+23 + // See https://github.com/openjdk/jdk/pull/24393 + String[] reflectiveClasses = new String[]{ + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA256", + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA384", + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA512", + "sun.security.pkcs11.P11HKDF", + }; + for (String name : reflectiveClasses) { + try { + Class.forName(name); + } catch (SecurityException | ClassNotFoundException e) { + return; } - // For backwards compatibility with older JDKs, we only do this if we found - // all those classes - Security.addProvider(Security.getProvider("SunJCE")); - for (String name : reflectiveClasses) { - try { - RuntimeReflection.register(Class.forName(name)); - RuntimeReflection.register(Class.forName(name).getConstructors()); - } catch (SecurityException | ClassNotFoundException e) { - throw new RuntimeException("Could not register " + name + " for reflective access!", e); - } + } + // For backwards compatibility with older JDKs, we only do this if we found + // all those classes + Security.addProvider(Security.getProvider("SunJCE")); + for (String name : reflectiveClasses) { + try { + RuntimeReflection.register(Class.forName(name)); + RuntimeReflection.register(Class.forName(name).getConstructors()); + } catch (SecurityException | ClassNotFoundException e) { + throw new RuntimeException("Could not register " + name + " for reflective access!", e); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java similarity index 100% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java rename to graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties index d686685cc4..b1fc50dd1e 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties @@ -1,7 +1,5 @@ # This file contains native-image arguments needed to build graalpython Args = -H:MaxRuntimeCompileMethods=20000 \ --initialize-at-build-time=com.oracle.graal.python,com.oracle.truffle.regex \ - --initialize-at-run-time=org.bouncycastle \ - --features=com.oracle.graal.python.BouncyCastleFeature \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=org.graalvm.py \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json index 01c0e6128f..df04bb22ae 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json @@ -73,2856 +73,5 @@ "parameterTypes": [] } ] - }, - { - "name": "com.sun.crypto.provider.AESCipher$General", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.AESKeyGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.ARCFOURCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DESCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DESedeCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DHParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.GaloisCounterMode$AESGCM", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.HmacCore$HmacSHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsKeyMaterialGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsMasterSecretGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsPrfGenerator$V12", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.KeyStoreSpi", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.cert.PKIXRevocationChecker", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.DSAPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.DSAPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.ECPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.ECPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.RSAPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.RSAPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.spec.DSAParameterSpec", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "javax.crypto.spec.GCMParameterSpec", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.CompositeSignatures$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.DSTU4145$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.Dilithium$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ECGOST$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.EXTERNAL$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.EdEC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ElGamal$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.Falcon$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.GM$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.GOST$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.IES$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.LMS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.NTRU$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.SPHINCSPlus$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.X509$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$ECDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi$ecDSA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Blake2b512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2b$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s128", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Blake2s256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake2s$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Blake3_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Blake3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Digest512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.DSTU7564$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Digest2012_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Digest512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Haraka$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest288", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Digest512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Keccak$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD4$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD4$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.MD5$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD160$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD256$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.RIPEMD320$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA1$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA224$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA256$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash128_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestParallelHash256_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake128_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestShake256_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash128_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$DigestTupleHash256_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA384$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SHA512$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SM3$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.SM3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_1024", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_1024_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_128", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_256_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_128", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_160", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Digest_512_512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Skein$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Tiger$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Digest", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.digest.Whirlpool$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.drbg.DRBG$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.keystore.BC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.keystore.BCFKS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.keystore.PKCS12$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.AES$AlgParams", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.AES$ECB", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.AES$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.ARIA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Blowfish$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.CAST5$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.CAST6$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Camellia$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.ChaCha$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.DES$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.DSTU7624$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.GOST28147$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.GOST3412_2015$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Grain128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Grainv1$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.HC128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.HC256$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.IDEA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Noekeon$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.OpenSSLPBKDF$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF1$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$PBKDF2withSHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Poly1305$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.RC5$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.RC6$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Rijndael$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SCRYPT$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SEED$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SM4$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Salsa20$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Serpent$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Shacal2$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.SipHash128$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Skipjack$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.TEA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.TLSKDF$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Threefish$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.VMPC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.VMPCKSA3$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.XSalsa20$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.XTEA$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.jcajce.provider.symmetric.Zuc$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.BIKE$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.CMCE$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Dilithium$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Falcon$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Frodo$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.HQC$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Kyber$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.LMS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.NH$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.NTRU$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.NTRUPrime$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Picnic$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.Rainbow$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.SABER$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.SPHINCSPlus$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "org.bouncycastle.pqc.jcajce.provider.XMSS$Mappings", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.pkcs12.PKCS12KeyStore", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA1withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA224withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA256withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSAKeyFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSAParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.JavaKeyStore$DualFormatJKS", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.JavaKeyStore$JKS", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.MD2", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.MD5", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.NativePRNG", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.SecureRandomParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.NativePRNG$NonBlocking", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.SecureRandomParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA2$SHA224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA2$SHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512_224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.X509Factory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.CollectionCertStore", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.cert.CertStoreParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.PKIXCertPathValidator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.SunCertPathBuilder", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.PSSParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSAKeyFactory$Legacy", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSAPSSSignature", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$MD5withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$SHA224withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$SHA256withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.KeyManagerFactoryImpl$SunX509", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.SSLContextImpl$TLSContext", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.AuthorityInfoAccessExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.AuthorityKeyIdentifierExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.BasicConstraintsExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CRLDistributionPointsExtension", - "fields": [ - { - "name": "NAME" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CRLNumberExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CertificatePoliciesExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.ExtendedKeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.IssuerAlternativeNameExtension", - "fields": [ - { - "name": "NAME" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.KeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.NetscapeCertTypeExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.PrivateKeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.SubjectAlternativeNameExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.SubjectKeyIdentifierExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } } ] diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 4a08fdb1b7..158147fe88 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -95,17 +95,6 @@ import java.util.List; import java.util.Map; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.openssl.PEMEncryptedKeyPair; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; -import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; -import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; -import org.bouncycastle.pkcs.PKCSException; -import org.bouncycastle.util.encoders.DecoderException; import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKey; @@ -759,12 +748,14 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon if (password == null) { throw new NeedsPasswordException(); } - privateKey = getPrivateKeyWithBC(password, pemText); + privateKey = SSLBouncyCastleSupportProvider.loadPrivateKey(password, pemText); } break; } } - } catch (IOException | DecoderException | GeneralSecurityException | OperatorCreationException | PKCSException e) { + } catch (SSLBouncyCastleSupportProvider.MissingBouncyCastleException e) { + throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL, toTruffleStringUncached(e.getMessage())); + } catch (IOException | GeneralSecurityException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } if (privateKey == null) { @@ -906,38 +897,6 @@ private static Provider getPreferredSecurityProvider() { return Security.getProvider(providerName); } - private static PrivateKey getPrivateKeyWithBC(char[] password, String pemText) - throws IOException, NeedsPasswordException, DecoderException, OperatorCreationException, PKCSException { - PEMParser pemParser = new PEMParser(new java.io.StringReader(pemText)); - JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); - Object object; - while ((object = pemParser.readObject()) != null) { - PrivateKeyInfo pkInfo; - if (object instanceof PEMKeyPair) { - pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); - } else if (object instanceof PEMEncryptedKeyPair) { - if (password == null) { - throw new NeedsPasswordException(); - } - JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder(); - PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); - pkInfo = keyPair.getPrivateKeyInfo(); - } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { - if (password == null) { - throw new NeedsPasswordException(); - } - JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder(); - pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); - } else if (object instanceof PrivateKeyInfo) { - pkInfo = (PrivateKeyInfo) object; - } else { - continue; - } - return converter.getPrivateKey(pkInfo); - } - return null; - } - private static void checkPrivateKey(Node inliningTarget, PConstructAndRaiseNode.Lazy raiseNode, PythonContext context, PrivateKey privateKey, PublicKey publicKey) { /* * Check that the private key matches the public key by signing and verifying a short piece diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index ef1cd55df1..d1ac1986ee 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -418,7 +418,7 @@ "subDir": "graalpython", "sourceDirs": ["src"], "dependencies": [ - "com.oracle.graal.python", + "GRAALPYTHON", "BOUNCYCASTLE-PROVIDER", "BOUNCYCASTLE-PKIX", "BOUNCYCASTLE-UTIL", @@ -1063,6 +1063,25 @@ "dependencies": [ "com.oracle.graal.python.bouncycastle", ], + "distDependencies": [ + "GRAALPYTHON", + "truffle:TRUFFLE_API", + "tools:TRUFFLE_PROFILER", + "regex:TREGEX", + "sdk:POLYGLOT", + "sdk:NATIVEIMAGE", + "sdk:COLLECTIONS", + "truffle:TRUFFLE_NFI", + "truffle:TRUFFLE_NFI_LIBFFI", + "truffle:TRUFFLE_NFI_PANAMA", + "truffle:TRUFFLE_ICU4J", + "truffle:TRUFFLE_XZ", + ], + "exclude": [ + "BOUNCYCASTLE-PROVIDER", + "BOUNCYCASTLE-PKIX", + "BOUNCYCASTLE-UTIL", + ], "description": "Optional GraalPy BouncyCastle integration.", "maven": False, }, @@ -1459,6 +1478,7 @@ "distDependencies": [ "graalpython:GRAALPYTHON-LAUNCHER", "graalpython:GRAALPYTHON", + "graalpython:GRAALPYTHON_BOUNCYCASTLE", "graalpython:BOUNCYCASTLE-PROVIDER", "graalpython:BOUNCYCASTLE-PKIX", "graalpython:BOUNCYCASTLE-UTIL", From d8ad8af1f89c2b16215ae3dbeb0fd1f310bbd902 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 18:08:47 +0100 Subject: [PATCH 12/43] Use JDK PBKDF2 implementation in hashlib --- .../hashlib/HashlibModuleBuiltins.java | 81 +++++++++++++------ mx.graalpython/suite.py | 6 +- 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index 6564adb562..37dddfbd99 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -56,6 +56,7 @@ import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; +import java.nio.ByteBuffer; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -67,11 +68,6 @@ import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.jcajce.provider.util.DigestFactory; import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; @@ -104,7 +100,6 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -479,10 +474,8 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password @Cached TruffleString.ToJavaStringNode toJavaStringNode, @Cached PRaiseNode raiseNode) { try { - Digest digest = getDigest(toJavaStringNode.execute(hashName)); - if (digest == null) { - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, UNSUPPORTED_HASH_TYPE, hashName); - } + String javaHashName = toJavaStringNode.execute(hashName); + Mac mac = createPbkdf2Mac(javaHashName); if (iterations < 1) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ITERATION_VALUE_MUST_BE_GREATER_THAN_ZERO); } @@ -491,11 +484,10 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password } long dklen; if (noDklenProfile.profile(inliningTarget, PGuards.isPNone(dklenObj))) { - dklen = digest.getDigestSize(); + dklen = mac.getMacLength(); } else { dklen = asLongNode.execute(frame, inliningTarget, dklenObj); } - dklen *= Byte.SIZE; if (dklen < 1) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, KEY_LENGTH_MUST_BE_GREATER_THAN_ZERO); } @@ -504,7 +496,9 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password } byte[] passwordBytes = passwordLib.getInternalOrCopiedExactByteArray(password); byte[] saltBytes = saltLib.getInternalOrCopiedExactByteArray(salt); - return PFactory.createBytes(language, generate(digest, passwordBytes, saltBytes, (int) iterations, (int) dklen)); + return PFactory.createBytes(language, generate(javaHashName, mac, passwordBytes, saltBytes, (int) iterations, (int) dklen)); + } catch (java.security.GeneralSecurityException e) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, UNSUPPORTED_HASH_TYPE, hashName); } finally { passwordLib.release(password); saltLib.release(salt); @@ -512,20 +506,61 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password } @TruffleBoundary - private static Digest getDigest(String name) { - name = name.toLowerCase(); - return DigestFactory.getDigest(NAME_MAPPINGS.getOrDefault(name, name)); + private static Mac createPbkdf2Mac(String name) { + String algorithm = getPbkdf2Algorithm(name); + if (algorithm == null) { + return null; + } + try { + return Mac.getInstance(algorithm); + } catch (NoSuchAlgorithmException e) { + return null; + } + } + + private static String getPbkdf2Algorithm(String name) { + return switch (name.toLowerCase()) { + case "sha1" -> "HmacSHA1"; + case "sha224" -> "HmacSHA224"; + case "sha256" -> "HmacSHA256"; + case "sha384" -> "HmacSHA384"; + case "sha512" -> "HmacSHA512"; + default -> null; + }; } @TruffleBoundary - private static byte[] generate(Digest digest, byte[] password, byte[] salt, int iterations, int dklen) { - PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(digest); - generator.init(password, salt, iterations); - CipherParameters cipherParameters = generator.generateDerivedParameters(dklen); - if (!(cipherParameters instanceof KeyParameter keyParameter)) { - throw CompilerDirectives.shouldNotReachHere("unexpected cipher parameters"); + private static byte[] generate(String hashName, Mac mac, byte[] password, byte[] salt, int iterations, int dklen) throws java.security.GeneralSecurityException { + try { + String algorithm = mac.getAlgorithm(); + mac.init(new SecretKeySpec(password, algorithm)); + int digestLength = mac.getMacLength(); + byte[] derivedKey = new byte[dklen]; + byte[] block = new byte[digestLength]; + byte[] u = new byte[digestLength]; + byte[] blockIndex = new byte[Integer.BYTES]; + int blockCount = (dklen + digestLength - 1) / digestLength; + for (int i = 1; i <= blockCount; i++) { + ByteBuffer.wrap(blockIndex).putInt(i); + mac.update(salt); + mac.update(blockIndex); + byte[] initial = mac.doFinal(); + System.arraycopy(initial, 0, block, 0, digestLength); + System.arraycopy(initial, 0, u, 0, digestLength); + for (int j = 1; j < iterations; j++) { + u = mac.doFinal(u); + for (int k = 0; k < digestLength; k++) { + block[k] ^= u[k]; + } + } + int offset = (i - 1) * digestLength; + int length = Math.min(digestLength, dklen - offset); + System.arraycopy(block, 0, derivedKey, offset, length); + } + return derivedKey; + } catch (InvalidKeyException e) { + throw new IllegalStateException(e); } - return keyParameter.getKey(); } } } diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index d1ac1986ee..66fc4021e6 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -1083,7 +1083,11 @@ "BOUNCYCASTLE-UTIL", ], "description": "Optional GraalPy BouncyCastle integration.", - "maven": False, + "maven": { + "artifactId": "python-bouncycastle-support", + "groupId": "org.graalvm.python", + "tag": ["public"], + }, }, "GRAALPYTHON": { From 0173e9000bda9e0d09a469c6a6aee0be6f054e77 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 18:17:53 +0100 Subject: [PATCH 13/43] Replace _imp source hash SipHash dependency --- .../src/tests/test_imports.py | 5 ++ .../builtins/modules/ImpModuleBuiltins.java | 71 ++++++++++++++++--- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py b/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py index fd5420b03d..dc0c9ce19d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py @@ -146,6 +146,11 @@ def func(x): assert code.co_filename == old_name + '_more_path' +def test_imp_source_hash(): + import _imp + assert _imp.source_hash(123456789, b'hello!').hex() == '04e61e229a23a446' + + def test_recursive_import_from(): if sys.version_info.minor >= 6: import package.recpkg diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java index 448b0f3051..c1c044aee6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java @@ -54,7 +54,7 @@ import static com.oracle.graal.python.nodes.StringLiterals.T_EXT_SO; import static com.oracle.graal.python.nodes.StringLiterals.T_NAME; import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError; -import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR; +import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR_LE; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.internString; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; @@ -64,9 +64,6 @@ import java.util.List; import java.util.concurrent.locks.ReentrantLock; -import org.bouncycastle.crypto.macs.SipHash; -import org.bouncycastle.crypto.params.KeyParameter; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; @@ -744,16 +741,68 @@ static PBytes run(long magicNumber, Object sourceBuffer, @TruffleBoundary public static byte[] hashSource(long magicNumber, byte[] bytes, int length) { - SipHash sipHash = new SipHash(1, 3); - byte[] key = new byte[16]; - ARRAY_ACCESSOR.putLong(key, 0, magicNumber); - sipHash.init(new KeyParameter(key)); - sipHash.update(bytes, 0, length); - byte[] out = new byte[sipHash.getMacSize()]; - sipHash.doFinal(out, 0); + long hash = sipHash13(magicNumber, 0, bytes, length); + byte[] out = new byte[Long.BYTES]; + ARRAY_ACCESSOR_LE.putLong(out, 0, hash); return out; } + private static long sipHash13(long k0, long k1, byte[] src, int length) { + long b = ((long) length) << 56; + long v0 = k0 ^ 0x736f6d6570736575L; + long v1 = k1 ^ 0x646f72616e646f6dL; + long v2 = k0 ^ 0x6c7967656e657261L; + long v3 = k1 ^ 0x7465646279746573L; + int offset = 0; + while (length - offset >= Long.BYTES) { + long mi = ARRAY_ACCESSOR_LE.getLong(src, offset); + offset += Long.BYTES; + v3 ^= mi; + long[] state = singleRound(v0, v1, v2, v3); + v0 = state[0]; + v1 = state[1]; + v2 = state[2]; + v3 = state[3]; + v0 ^= mi; + } + long tail = 0; + int remaining = length - offset; + for (int i = 0; i < remaining; i++) { + tail |= ((long) src[offset + i] & 0xffL) << (Byte.SIZE * i); + } + b |= tail; + v3 ^= b; + long[] state = singleRound(v0, v1, v2, v3); + v0 = state[0]; + v1 = state[1]; + v2 = state[2]; + v3 = state[3]; + v0 ^= b; + v2 ^= 0xff; + for (int i = 0; i < 3; i++) { + state = singleRound(v0, v1, v2, v3); + v0 = state[0]; + v1 = state[1]; + v2 = state[2]; + v3 = state[3]; + } + return (v0 ^ v1) ^ (v2 ^ v3); + } + + private static long[] singleRound(long v0, long v1, long v2, long v3) { + v0 += v1; + v2 += v3; + v1 = Long.rotateLeft(v1, 13) ^ v0; + v3 = Long.rotateLeft(v3, 16) ^ v2; + v0 = Long.rotateLeft(v0, 32); + v2 += v1; + v0 += v3; + v1 = Long.rotateLeft(v1, 17) ^ v2; + v3 = Long.rotateLeft(v3, 21) ^ v0; + v2 = Long.rotateLeft(v2, 32); + return new long[]{v0, v1, v2, v3}; + } + @Override protected ArgumentClinicProvider getArgumentClinic() { return ImpModuleBuiltinsClinicProviders.SourceHashNodeClinicProviderGen.INSTANCE; From 1118295d2e77f9c2f322479057c06ef94e8fa4b1 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 18:24:35 +0100 Subject: [PATCH 14/43] Drop core BouncyCastle dependencies --- mx.graalpython/suite.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 66fc4021e6..b407382d5f 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -390,9 +390,6 @@ "truffle:TRUFFLE_XZ", "truffle:TRUFFLE_ICU4J", "regex:TREGEX", - "BOUNCYCASTLE-PROVIDER", - "BOUNCYCASTLE-PKIX", - "BOUNCYCASTLE-UTIL", ], "requires": [ "java.logging", @@ -1124,11 +1121,6 @@ "jdk.unsupported", "jdk.security.auth", ], - "exclude": [ - "BOUNCYCASTLE-PROVIDER", - "BOUNCYCASTLE-PKIX", - "BOUNCYCASTLE-UTIL", - ], "description": "GraalPy, a high-performance embeddable Python 3 runtime. This artifact includes the core language runtime without standard libraries. It is not recommended to depend on the artifact directly. Instead, use \'org.graalvm.polyglot:python\' or \'org.graalvm.polyglot:python-community\' to ensure all dependencies are pulled in correctly.", "maven": { "artifactId": "python-language", From 981861f110c82911cc185400aeac954a4be3fb37 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 19:48:32 +0100 Subject: [PATCH 15/43] Remove unused BouncyCastle util dependency --- mx.graalpython/suite.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index b407382d5f..9391dcea1a 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -418,7 +418,6 @@ "GRAALPYTHON", "BOUNCYCASTLE-PROVIDER", "BOUNCYCASTLE-PKIX", - "BOUNCYCASTLE-UTIL", ], "requires": [ "java.logging", @@ -1077,7 +1076,6 @@ "exclude": [ "BOUNCYCASTLE-PROVIDER", "BOUNCYCASTLE-PKIX", - "BOUNCYCASTLE-UTIL", ], "description": "Optional GraalPy BouncyCastle integration.", "maven": { @@ -1477,7 +1475,6 @@ "graalpython:GRAALPYTHON_BOUNCYCASTLE", "graalpython:BOUNCYCASTLE-PROVIDER", "graalpython:BOUNCYCASTLE-PKIX", - "graalpython:BOUNCYCASTLE-UTIL", "sdk:TOOLS_FOR_STANDALONE", ], "dynamicDistDependencies": "graalpy_standalone_deps", From 208238096bb663e063cdc3b0fea352bb0e750b20 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 20:34:12 +0100 Subject: [PATCH 16/43] Fix style --- .../src/tests/test_imports.py | 8 ++++---- .../builtins/modules/hashlib/HashlibModuleBuiltins.java | 1 - .../graal/python/builtins/objects/ssl/CertUtils.java | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py b/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py index dc0c9ce19d..dc7bd6d7eb 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_imports.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -181,16 +181,16 @@ def test_circular_import_valid(): import time as package25274 #has to be in global space for the next test def test_local_property_25274(): - + def mytest(): assert len(locals()) == 0 import package25274.sub25274 assert 'package25274' in locals() assert package25274.top_property == 10 assert package25274.sub25274.sub_property == 20 - + mytest() assert hasattr(package25274, 'tzname') - + diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index 37dddfbd99..a77e28efa4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -68,7 +68,6 @@ import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.Builtin; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 158147fe88..08b9ec73b0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -95,7 +95,6 @@ import java.util.List; import java.util.Map; - import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; @@ -878,7 +877,6 @@ private static PrivateKey decodeRsaPrivateKey(byte[] encoded) throws InvalidKeyS } } - private static KeyFactory getKeyFactory(String algorithm) throws NoSuchAlgorithmException { Provider provider = getPreferredSecurityProvider(); return provider != null ? KeyFactory.getInstance(algorithm, provider) : KeyFactory.getInstance(algorithm); From 75e01015e79453366059cc6ab81ab1ecee1edb86 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 21:02:00 +0100 Subject: [PATCH 17/43] Remove unused lazy BouncyCastle provider helper --- .../objects/ssl/LazyBouncyCastleProvider.java | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java deleted file mode 100644 index 135c4f9dec..0000000000 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/builtins/objects/ssl/LazyBouncyCastleProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.ssl; - -import java.security.Provider; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -public final class LazyBouncyCastleProvider { - private static Provider securityProvider; - - public static synchronized Provider initProvider() { - if (securityProvider == null) { - securityProvider = new BouncyCastleProvider(); - } - return securityProvider; - } -} From 34061146f196a10b20f73f33897dc7c10355ca75 Mon Sep 17 00:00:00 2001 From: stepan Date: Fri, 20 Feb 2026 17:45:37 +0100 Subject: [PATCH 18/43] Update Bouncy Castle artifacts to 1.83 --- mx.graalpython/suite.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 9391dcea1a..337399923f 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -110,32 +110,32 @@ "digest": "sha512:bd77164795b5cbfbe864f64021e67e37f39cb9aba9abdd894d53fbb6857abe074923808918d1dc3bb0706253e726b2b9704cd0c3bc744d70e220c7356fa4995e", }, "BOUNCYCASTLE-PROVIDER": { - "digest": "sha512:fb10c3c089921c8173ad285329f730e0e78de175d1b50b9bdd79c6a85a265af9b3331caa0c1ed57e5f47047319ce3b0f3bb5def0a3db9cccf2755cc95e145e52", - "sourceDigest": "sha512:7b06374b75040a1dba9419e17be29a155f01b14961521adcb8e980397b6ac7e2de55958e74ad41ba94766c4e992935abbd94fb964dbf806445a63a7346c0ae2e", + "digest": "sha512:e51cc843ca130ad4a15ff667360063bbb583af3f22e14193840a734da6665b470ba1855ce975f88a94ddd6419aa020d3a9966980bc1deb7514f92a7215d6e229", + "sourceDigest": "sha512:a2fe72266afcffce846dde5735d0fa28935942177375dd1c29bac819c1163f2da967e0b893d33d43868b6cdb8aa469e05fa460543d5448fa1e34155dcf86b0b7", "maven": { "groupId": "org.bouncycastle", "artifactId": "bcprov-jdk18on", - "version": "1.78.1", + "version": "1.83", }, "moduleName": "org.bouncycastle.provider", }, "BOUNCYCASTLE-PKIX": { - "digest": "sha512:d71a45844a7946b6a70315254e82a335d2df5e402b2d5a3b496fa69b355184338011b49c5f1c76026764a76f62f2bc140c25db2881bca91dde9677a25c6d587b", - "sourceDigest": "sha512:8508e9b26c60cc2fd3219d8ab0d3928891ecc42926e7c862c0fbf9940a4bcffe35c4a76c3934b33ed4311817dbf3b0b50068482f7c5f550261a50cc97879923a", + "digest": "sha512:9c67d990a56a5c448f9bb9edbb8b99dc15971e16de7e6f10c3eab129a1389eef4882c5a5d910ac4ddc27d44f7bc9fa4054c7f56dc031154c131bccc50ebd67b9", + "sourceDigest": "sha512:f24ad816393ed53d737db3c976ef37e4e009c2a366a1b97f80dace063320336ed1463b526eb6913cd1d462c2be18debd43ac1cab415639f900706e8e4fc13fe1", "maven": { "groupId": "org.bouncycastle", "artifactId": "bcpkix-jdk18on", - "version": "1.78.1", + "version": "1.83", }, "moduleName": "org.bouncycastle.pkix", }, "BOUNCYCASTLE-UTIL": { - "digest": "sha512:6a338c50d662993c9f00bba23f98443c923b9a95ff61dc653906f51857f8afaecc57a536bfaf6848ac8e7e9ce0a21f84ec068815853261268f97e951526bc766", - "sourceDigest": "sha512:852a1679a9c690f97c4ed175272b04ebedc89b9e4aa0322f32a799f619fd71602f89545fc02bb1093750ad7d796500fdd116203862ccecb3085af40aadcccea6", + "digest": "sha512:e19831d4afc0a709fd57694f33bfe3a8e881cba287c34fb076a44ef436e56e6bdf49299ca9525028a4de9bf5fadeaa254654d0e527855f1f5659c5a7be538576", + "sourceDigest": "sha512:bc4195692721827b41e21eaa14f9cf14dffe6f141ddfb8ac26d2a89f4ead3f1611671f8b6d39ec4be479c2ccf6e4bf33176123474f852910dc7dcc23485bd036", "maven": { "groupId": "org.bouncycastle", "artifactId": "bcutil-jdk18on", - "version": "1.78.1", + "version": "1.83", }, "moduleName": "org.bouncycastle.util", }, From adc7e3c76716a8d119de12f535973305caf47712 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 21:15:24 +0100 Subject: [PATCH 19/43] Split core and BouncyCastle native-image config --- .../native-image.properties | 3 +- .../python-bouncycastle/reflect-config.json | 859 ------------------ .../python-language/native-image.properties | 3 +- .../python-language/reflect-config.json | 643 +++++++++++++ .../python/runtime/PythonCryptoFeature.java} | 30 +- 5 files changed, 660 insertions(+), 878 deletions(-) rename graalpython/{com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java => com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java} (73%) diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties index ed243d5034..aa8c1eebd7 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties @@ -1,3 +1,2 @@ # Additional native-image arguments for optional GraalPy BouncyCastle support -Args = --initialize-at-run-time=org.bouncycastle \ - --features=com.oracle.graal.python.bouncycastle.BouncyCastleFeature +Args = --initialize-at-run-time=org.bouncycastle diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json index d80bfdcc76..4fbca1c6cf 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json @@ -1,208 +1,4 @@ [ - { - "name": "com.sun.crypto.provider.AESCipher$General", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.AESKeyGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.ARCFOURCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DESCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DESedeCipher", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.DHParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.GaloisCounterMode$AESGCM", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.HmacCore$HmacSHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsKeyMaterialGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsMasterSecretGenerator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "com.sun.crypto.provider.TlsPrfGenerator$V12", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.KeyStoreSpi", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.cert.PKIXRevocationChecker", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.DSAPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.DSAPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.ECPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.ECPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.RSAPrivateKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.interfaces.RSAPublicKey", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "java.security.spec.DSAParameterSpec", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "javax.crypto.spec.GCMParameterSpec", - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, { "name": "org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE$Mappings", "methods": [ @@ -2194,660 +1990,5 @@ "condition": { "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" } - }, - { - "name": "sun.security.pkcs12.PKCS12KeyStore", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA1withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA224withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSA$SHA256withDSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSAKeyFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.DSAParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.JavaKeyStore$DualFormatJKS", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.JavaKeyStore$JKS", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.MD2", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.MD5", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.NativePRNG", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.SecureRandomParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.NativePRNG$NonBlocking", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.SecureRandomParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA2$SHA224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA2$SHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA3$SHA512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA384", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512_224", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.SHA5$SHA512_256", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.X509Factory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.CollectionCertStore", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.security.cert.CertStoreParameters" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.PKIXCertPathValidator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.provider.certpath.SunCertPathBuilder", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.PSSParameters", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSAKeyFactory$Legacy", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSAPSSSignature", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$MD5withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$SHA224withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.rsa.RSASignature$SHA256withRSA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.KeyManagerFactoryImpl$SunX509", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.SSLContextImpl$TLSContext", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.AuthorityInfoAccessExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.AuthorityKeyIdentifierExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.BasicConstraintsExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CRLDistributionPointsExtension", - "fields": [ - { - "name": "NAME" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CRLNumberExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.CertificatePoliciesExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.ExtendedKeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.IssuerAlternativeNameExtension", - "fields": [ - { - "name": "NAME" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.KeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.NetscapeCertTypeExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.PrivateKeyUsageExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.SubjectAlternativeNameExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } - }, - { - "name": "sun.security.x509.SubjectKeyIdentifierExtension", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.Boolean", - "java.lang.Object" - ] - } - ], - "condition": { - "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" - } } ] diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties index b1fc50dd1e..a06ea7e9d1 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties @@ -2,4 +2,5 @@ Args = -H:MaxRuntimeCompileMethods=20000 \ --initialize-at-build-time=com.oracle.graal.python,com.oracle.truffle.regex \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=org.graalvm.py \ - --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED + --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED \ + --features=com.oracle.graal.python.runtime.PythonCryptoFeature diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json index df04bb22ae..83f2445116 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/reflect-config.json @@ -73,5 +73,648 @@ "parameterTypes": [] } ] + }, + { + "name": "com.sun.crypto.provider.AESCipher$General", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.AESKeyGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.ARCFOURCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.DESCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.DESedeCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.DHParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.GaloisCounterMode$AESGCM", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.HmacCore$HmacSHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.TlsKeyMaterialGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.TlsPrfGenerator$V12", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "java.security.KeyStoreSpi" + }, + { + "name": "java.security.cert.PKIXRevocationChecker" + }, + { + "name": "java.security.interfaces.DSAPrivateKey" + }, + { + "name": "java.security.interfaces.DSAPublicKey" + }, + { + "name": "java.security.interfaces.ECPrivateKey" + }, + { + "name": "java.security.interfaces.ECPublicKey" + }, + { + "name": "java.security.interfaces.RSAPrivateKey" + }, + { + "name": "java.security.interfaces.RSAPublicKey" + }, + { + "name": "java.security.spec.DSAParameterSpec" + }, + { + "name": "javax.crypto.spec.GCMParameterSpec" + }, + { + "name": "sun.security.pkcs12.PKCS12KeyStore", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.DSA$SHA1withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.DSA$SHA224withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.DSA$SHA256withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.DSAKeyFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.DSAParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.JavaKeyStore$DualFormatJKS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.JavaKeyStore$JKS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.MD2", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.MD5", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.NativePRNG", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ] + }, + { + "name": "sun.security.provider.NativePRNG$NonBlocking", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ] + }, + { + "name": "sun.security.provider.SHA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA2$SHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA2$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA3$SHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA3$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA3$SHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA3$SHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA5$SHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA5$SHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA5$SHA512_224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA5$SHA512_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.X509Factory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.certpath.CollectionCertStore", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.cert.CertStoreParameters" + ] + } + ] + }, + { + "name": "sun.security.provider.certpath.PKIXCertPathValidator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.certpath.SunCertPathBuilder", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.rsa.PSSParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.rsa.RSAKeyFactory$Legacy", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.rsa.RSAPSSSignature", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.rsa.RSASignature$MD5withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.rsa.RSASignature$SHA224withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.rsa.RSASignature$SHA256withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.ssl.SSLContextImpl$TLSContext", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.x509.AuthorityInfoAccessExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.AuthorityKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.BasicConstraintsExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.CRLDistributionPointsExtension", + "fields": [ + { + "name": "NAME" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.CRLNumberExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.CertificatePoliciesExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.ExtendedKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.IssuerAlternativeNameExtension", + "fields": [ + { + "name": "NAME" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.KeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.NetscapeCertTypeExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.PrivateKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.SubjectAlternativeNameExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.security.x509.SubjectKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] } ] diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java similarity index 73% rename from graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java index 6e9c3f4efd..4ebb9fcfde 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java @@ -38,39 +38,37 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.bouncycastle; +package com.oracle.graal.python.runtime; import java.security.Security; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; -public class BouncyCastleFeature implements Feature { +public final class PythonCryptoFeature implements Feature { + + private static final String[] HKDF_REFLECTIVE_CLASSES = { + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA256", + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA384", + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA512", + "sun.security.pkcs11.P11HKDF", + }; @Override public void afterRegistration(AfterRegistrationAccess access) { - // SSLBasicKeyDerivation looks up the classes below reflectively since jdk-25+23 - // See https://github.com/openjdk/jdk/pull/24393 - String[] reflectiveClasses = new String[]{ - "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA256", - "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA384", - "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA512", - "sun.security.pkcs11.P11HKDF", - }; - for (String name : reflectiveClasses) { + for (String name : HKDF_REFLECTIVE_CLASSES) { try { Class.forName(name); } catch (SecurityException | ClassNotFoundException e) { return; } } - // For backwards compatibility with older JDKs, we only do this if we found - // all those classes Security.addProvider(Security.getProvider("SunJCE")); - for (String name : reflectiveClasses) { + for (String name : HKDF_REFLECTIVE_CLASSES) { try { - RuntimeReflection.register(Class.forName(name)); - RuntimeReflection.register(Class.forName(name).getConstructors()); + Class clazz = Class.forName(name); + RuntimeReflection.register(clazz); + RuntimeReflection.register(clazz.getConstructors()); } catch (SecurityException | ClassNotFoundException e) { throw new RuntimeException("Could not register " + name + " for reflective access!", e); } From c885b3eaa3464f19cc37c9eeacd7e83b0176989b Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 11 Mar 2026 21:28:05 +0100 Subject: [PATCH 20/43] Remove unused BouncyCastle provider anchor --- .../graal/python/bouncycastle/BCSSLBouncyCastleSupport.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java index 5314206e88..9904bc5b76 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java @@ -46,7 +46,6 @@ import java.security.PrivateKey; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; @@ -61,8 +60,6 @@ import com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport; public final class BCSSLBouncyCastleSupport implements SSLBouncyCastleSupport { - @SuppressWarnings("unused") private static final Class PROVIDER_CLASS = BouncyCastleProvider.class; - @Override public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { try (PEMParser pemParser = new PEMParser(new StringReader(pemText))) { From dcccc4ed6e225c9c8397baf9a88ad6a839c10d6c Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 07:24:55 +0100 Subject: [PATCH 21/43] Fix BC standalone service loading --- .../bouncycastle/BCPrivateKeyLoader.java | 100 ++++++++++++++ .../BCSSLBouncyCastleSupport.java | 61 +++++---- .../builtins/objects/ssl/CertUtils.java | 122 +++++++++++------- .../ssl/SSLBouncyCastleSupportProvider.java | 33 ++++- .../python/runtime/PythonCryptoFeature.java | 27 ++++ mx.graalpython/mx_graalpython.py | 1 + mx.graalpython/suite.py | 10 ++ 7 files changed, 280 insertions(+), 74 deletions(-) create mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java new file mode 100644 index 0000000000..77106e86ce --- /dev/null +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.bouncycastle; + +import java.io.IOException; +import java.io.StringReader; +import java.security.GeneralSecurityException; +import java.security.PrivateKey; + +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMEncryptedKeyPair; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; +import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; +import org.bouncycastle.pkcs.PKCSException; + +public final class BCPrivateKeyLoader { + private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider(); + + public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { + try (PEMParser pemParser = new PEMParser(new StringReader(pemText))) { + JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(PROVIDER); + Object object; + while ((object = pemParser.readObject()) != null) { + PrivateKeyInfo pkInfo; + if (object instanceof PEMKeyPair) { + pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); + } else if (object instanceof PEMEncryptedKeyPair) { + if (password == null) { + throw new NeedsPasswordException(); + } + JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder().setProvider(PROVIDER); + PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); + pkInfo = keyPair.getPrivateKeyInfo(); + } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { + if (password == null) { + throw new NeedsPasswordException(); + } + JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider(PROVIDER); + pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); + } else if (object instanceof PrivateKeyInfo) { + pkInfo = (PrivateKeyInfo) object; + } else { + continue; + } + return converter.getPrivateKey(pkInfo); + } + return null; + } catch (OperatorCreationException | PKCSException e) { + throw new GeneralSecurityException(e); + } + } + + public static final class NeedsPasswordException extends GeneralSecurityException { + private static final long serialVersionUID = 1L; + } +} diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java index 9904bc5b76..6a7fd502a8 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java @@ -44,8 +44,11 @@ import java.io.StringReader; import java.security.GeneralSecurityException; import java.security.PrivateKey; +import java.security.Provider; +import java.security.Security; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; @@ -60,38 +63,50 @@ import com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport; public final class BCSSLBouncyCastleSupport implements SSLBouncyCastleSupport { + private static Provider getProvider() { + Provider provider = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); + return provider != null ? provider : new BouncyCastleProvider(); + } + @Override public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { try (PEMParser pemParser = new PEMParser(new StringReader(pemText))) { - JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); + Provider provider = getProvider(); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(provider); Object object; while ((object = pemParser.readObject()) != null) { - PrivateKeyInfo pkInfo; - if (object instanceof PEMKeyPair) { - pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); - } else if (object instanceof PEMEncryptedKeyPair) { - if (password == null) { - throw new NeedsPasswordException(); + try { + PrivateKeyInfo pkInfo; + if (object instanceof PEMKeyPair) { + pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); + } else if (object instanceof PEMEncryptedKeyPair) { + if (password == null) { + throw new NeedsPasswordException(); + } + JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder().setProvider(provider); + PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); + pkInfo = keyPair.getPrivateKeyInfo(); + } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { + if (password == null) { + throw new NeedsPasswordException(); + } + JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider(provider); + pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); + } else if (object instanceof PrivateKeyInfo) { + pkInfo = (PrivateKeyInfo) object; + } else { + continue; } - JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder(); - PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); - pkInfo = keyPair.getPrivateKeyInfo(); - } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { - if (password == null) { - throw new NeedsPasswordException(); + PrivateKey privateKey = converter.getPrivateKey(pkInfo); + if (privateKey == null) { + throw new RuntimeException("BC converter returned null for " + object.getClass().getName()); } - JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder(); - pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); - } else if (object instanceof PrivateKeyInfo) { - pkInfo = (PrivateKeyInfo) object; - } else { - continue; + return privateKey; + } catch (OperatorCreationException | PKCSException e) { + throw new RuntimeException("BC failed for " + object.getClass().getName(), e); } - return converter.getPrivateKey(pkInfo); } - return null; - } catch (OperatorCreationException | PKCSException e) { - throw new GeneralSecurityException(e); + throw new RuntimeException("BC found no supported key objects"); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 08b9ec73b0..8f1b1c5201 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -156,6 +156,9 @@ private record PemBlock(String type, byte[] content) { private record KeyPemBlock(String type, byte[] content, Map headers) { } + private record PemBlockWithContent(String type, String content, int nextIndex) { + } + /** * openssl v3_purp.c#check_ca */ @@ -730,7 +733,11 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon String algorithm = cert.getPublicKey().getAlgorithm(); try { String pemText = readText(reader); - for (KeyPemBlock block : readPrivateKeyPemBlocks(new BufferedReader(new java.io.StringReader(pemText)))) { + int fromIndex = 0; + PemBlockWithContent rawBlock; + while ((rawBlock = findNextPemBlock(pemText, fromIndex)) != null) { + fromIndex = rawBlock.nextIndex(); + KeyPemBlock block = decodePrivateKeyPemBlock(rawBlock.type(), rawBlock.content()); if ("PRIVATE KEY".equals(block.type())) { privateKey = decodePrivateKey(algorithm, block.content()); break; @@ -765,37 +772,30 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon return privateKey; } - private static List readPrivateKeyPemBlocks(BufferedReader reader) throws IOException { - String data = readText(reader); - List blocks = new ArrayList<>(); - int fromIndex = 0; - while (true) { - int begin = data.indexOf("-----BEGIN ", fromIndex); - if (begin < 0) { - return blocks; - } - int typeStart = begin + "-----BEGIN ".length(); - int typeEnd = data.indexOf("-----", typeStart); - if (typeEnd < 0) { - throw new IOException("Malformed PEM header"); - } - String type = data.substring(typeStart, typeEnd); - int contentStart = typeEnd + "-----".length(); - if (contentStart < data.length() && data.charAt(contentStart) == '\r') { - contentStart++; - } - if (contentStart < data.length() && data.charAt(contentStart) == '\n') { - contentStart++; - } - String endMarker = "-----END " + type + "-----"; - int end = data.indexOf(endMarker, contentStart); - if (end < 0) { - throw new IOException("Missing PEM footer"); - } - String content = data.substring(contentStart, end); - blocks.add(decodePrivateKeyPemBlock(type, content)); - fromIndex = end + endMarker.length(); + private static PemBlockWithContent findNextPemBlock(String data, int fromIndex) throws IOException { + int begin = data.indexOf("-----BEGIN ", fromIndex); + if (begin < 0) { + return null; + } + int typeStart = begin + "-----BEGIN ".length(); + int typeEnd = data.indexOf("-----", typeStart); + if (typeEnd < 0) { + throw new IOException("Malformed PEM header"); } + String type = data.substring(typeStart, typeEnd); + int contentStart = typeEnd + "-----".length(); + if (contentStart < data.length() && data.charAt(contentStart) == '\r') { + contentStart++; + } + if (contentStart < data.length() && data.charAt(contentStart) == '\n') { + contentStart++; + } + String endMarker = "-----END " + type + "-----"; + int end = data.indexOf(endMarker, contentStart); + if (end < 0) { + throw new IOException("Missing PEM footer"); + } + return new PemBlockWithContent(type, data.substring(contentStart, end), end + endMarker.length()); } private static KeyPemBlock decodePrivateKeyPemBlock(String type, String content) throws IOException { @@ -853,7 +853,7 @@ private static PrivateKey decodeEncryptedPrivateKey(String algorithm, byte[] enc private static PrivateKey decodeRsaPrivateKey(byte[] encoded) throws InvalidKeySpecException, NoSuchAlgorithmException { try { - DerValue sequence = new DerValue(encoded).getSequence(); + DerValue sequence = new DerValue(encoded); List values = sequence.getSequenceElements(); if (values.size() < 9) { throw new InvalidKeySpecException("Invalid RSA private key"); @@ -900,31 +900,61 @@ private static void checkPrivateKey(Node inliningTarget, PConstructAndRaiseNode. * Check that the private key matches the public key by signing and verifying a short piece * of data. */ + byte[] data = new byte[128]; + context.getSecureRandom().nextBytes(data); try { - Signature sign; + String signatureAlgorithm = privateKey.getAlgorithm(); + if ("EC".equals(signatureAlgorithm)) { + signatureAlgorithm = "ECDSA"; + } try { - sign = Signature.getInstance(String.format("SHA256with%s", privateKey.getAlgorithm())); + if (checkPrivateKey("SHA256with%s".formatted(signatureAlgorithm), privateKey, publicKey, data)) { + return; + } } catch (NoSuchAlgorithmException e) { - sign = Signature.getInstance(String.format("SHA1with%s", privateKey.getAlgorithm())); - } - sign.initSign(privateKey); - byte[] data = new byte[128]; - context.getSecureRandom().nextBytes(data); - sign.update(data); - byte[] signature = sign.sign(); - sign.initVerify(publicKey); - sign.update(data); - if (sign.verify(signature)) { - return; + if (checkPrivateKey("SHA1with%s".formatted(signatureAlgorithm), privateKey, publicKey, data)) { + return; + } } } catch (NoSuchAlgorithmException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL, e); - } catch (SignatureException | InvalidKeyException e) { + } catch (SignatureException e) { // fallthrough } throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_KEY_VALUES_MISMATCH, ErrorMessages.KEY_VALUES_MISMATCH); } + private static boolean checkPrivateKey(String signatureAlgorithm, PrivateKey privateKey, PublicKey publicKey, byte[] data) throws NoSuchAlgorithmException, SignatureException { + Provider preferredProvider = getPreferredSecurityProvider(); + if (preferredProvider != null && checkPrivateKey(signatureAlgorithm, preferredProvider, privateKey, publicKey, data)) { + return true; + } + Provider[] providers = Security.getProviders("Signature." + signatureAlgorithm); + if (providers != null) { + for (Provider provider : providers) { + if ((preferredProvider == null || !preferredProvider.getName().equals(provider.getName())) && checkPrivateKey(signatureAlgorithm, provider, privateKey, publicKey, data)) { + return true; + } + } + } + return checkPrivateKey(signatureAlgorithm, (Provider) null, privateKey, publicKey, data); + } + + private static boolean checkPrivateKey(String signatureAlgorithm, Provider provider, PrivateKey privateKey, PublicKey publicKey, byte[] data) throws NoSuchAlgorithmException, SignatureException { + try { + Signature signature = provider != null ? Signature.getInstance(signatureAlgorithm, provider) : Signature.getInstance(signatureAlgorithm); + signature.initSign(privateKey); + signature.update(data); + byte[] signed = signature.sign(); + signature.initVerify(publicKey); + signature.update(data); + boolean verified = signature.verify(signed); + return verified; + } catch (InvalidKeyException e) { + return false; + } + } + @TruffleBoundary static Collection generateCertificates(byte[] bytes) throws CertificateException { // test_load_verify_cadata appends an extra byte to a valid certificate and expects diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java index 08a9fc7d3a..b1637a8337 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java @@ -41,6 +41,7 @@ package com.oracle.graal.python.builtins.objects.ssl; import java.io.IOException; +import java.lang.ModuleLayer; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.util.Iterator; @@ -60,15 +61,37 @@ public static PrivateKey loadPrivateKey(char[] password, String pemText) throws } private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleException { + Throwable failure = null; try { - Iterator iterator = ServiceLoader.load(SSLBouncyCastleSupport.class, SSLBouncyCastleSupport.class.getClassLoader()).iterator(); - if (iterator.hasNext()) { - return iterator.next(); + SSLBouncyCastleSupport support = getSupport(ServiceLoader.load(ModuleLayer.boot(), SSLBouncyCastleSupport.class)); + if (support != null) { + return support; } } catch (ServiceConfigurationError | LinkageError e) { - throw new MissingBouncyCastleException(e); + failure = e; } - throw new MissingBouncyCastleException(null); + try { + SSLBouncyCastleSupport support = getSupport(ServiceLoader.load(SSLBouncyCastleSupport.class)); + if (support != null) { + return support; + } + } catch (ServiceConfigurationError | LinkageError e) { + failure = e; + } + try { + SSLBouncyCastleSupport support = getSupport(ServiceLoader.load(SSLBouncyCastleSupport.class, SSLBouncyCastleSupportProvider.class.getClassLoader())); + if (support != null) { + return support; + } + } catch (ServiceConfigurationError | LinkageError e) { + failure = e; + } + throw new MissingBouncyCastleException(failure); + } + + private static SSLBouncyCastleSupport getSupport(ServiceLoader serviceLoader) { + Iterator iterator = serviceLoader.iterator(); + return iterator.hasNext() ? iterator.next() : null; } public static final class MissingBouncyCastleException extends GeneralSecurityException { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java index 4ebb9fcfde..fe7b9b2b03 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java @@ -40,10 +40,13 @@ */ package com.oracle.graal.python.runtime; +import java.io.IOException; +import java.io.InputStream; import java.security.Security; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; +import org.graalvm.nativeimage.hosted.RuntimeResourceAccess; public final class PythonCryptoFeature implements Feature { @@ -53,9 +56,16 @@ public final class PythonCryptoFeature implements Feature { "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA512", "sun.security.pkcs11.P11HKDF", }; + private static final String BC_SSL_SUPPORT_CLASS = "com.oracle.graal.python.bouncycastle.BCSSLBouncyCastleSupport"; + private static final String BC_SSL_SERVICE_RESOURCE = "META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport"; @Override public void afterRegistration(AfterRegistrationAccess access) { + registerHkdfReflection(); + registerOptionalBouncyCastleSupport(); + } + + private static void registerHkdfReflection() { for (String name : HKDF_REFLECTIVE_CLASSES) { try { Class.forName(name); @@ -74,4 +84,21 @@ public void afterRegistration(AfterRegistrationAccess access) { } } } + + private static void registerOptionalBouncyCastleSupport() { + try { + Class clazz = Class.forName(BC_SSL_SUPPORT_CLASS); + RuntimeReflection.register(clazz); + RuntimeReflection.register(clazz.getConstructors()); + try (InputStream stream = clazz.getClassLoader().getResourceAsStream(BC_SSL_SERVICE_RESOURCE)) { + if (stream != null) { + RuntimeResourceAccess.addResource(clazz.getModule(), BC_SSL_SERVICE_RESOURCE, stream.readAllBytes()); + } + } + } catch (ClassNotFoundException e) { + return; + } catch (SecurityException | IOException e) { + throw new RuntimeException("Could not register optional BouncyCastle SSL support for native image.", e); + } + } } diff --git a/mx.graalpython/mx_graalpython.py b/mx.graalpython/mx_graalpython.py index c94f524966..0b5f451b7b 100644 --- a/mx.graalpython/mx_graalpython.py +++ b/mx.graalpython/mx_graalpython.py @@ -2231,6 +2231,7 @@ def bytecode_dsl_build_args(prefix=''): ], truffle_jars=[ 'graalpython:GRAALPYTHON', + 'graalpython:GRAALPYTHON_BOUNCYCASTLE', 'graalpython:BOUNCYCASTLE-PROVIDER', 'graalpython:BOUNCYCASTLE-PKIX', 'graalpython:BOUNCYCASTLE-UTIL', diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 337399923f..e668797288 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -418,6 +418,7 @@ "GRAALPYTHON", "BOUNCYCASTLE-PROVIDER", "BOUNCYCASTLE-PKIX", + "BOUNCYCASTLE-UTIL", ], "requires": [ "java.logging", @@ -881,6 +882,7 @@ "default_vm_args": [ "--vm.Xss16777216", # request 16M of stack '--vm.-enable-native-access=org.graalvm.shadowed.jline', + '--vm.-add-modules=graalpython.bouncycastle,org.bouncycastle.provider,org.bouncycastle.pkix,org.bouncycastle.util', ], "multitarget": [ {"os": ["linux"], "libc": ["glibc", "default"], "compiler": ["llvm-toolchain", "host", "*"]}, @@ -900,6 +902,8 @@ "build_args": [ # From mx.graalpython/native-image.properties "--add-exports", "org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED", + "--add-exports", "org.graalvm.py/com.oracle.graal.python.builtins.objects.ssl=ALL-UNNAMED", + "-H:AdditionalSecurityProviders=org.bouncycastle.jce.provider.BouncyCastleProvider", "-R:StackSize=16777216", "-H:+AddAllCharsets", "-H:IncludeLocales=no,be,ro,ru,es,se,in,ka,hu,hr,bg,is,mk,da,nn,cs,sq,fr,pl,fo,bs,kl,fa,sv,it,uk,af,tg,ps,de", @@ -1076,6 +1080,7 @@ "exclude": [ "BOUNCYCASTLE-PROVIDER", "BOUNCYCASTLE-PKIX", + "BOUNCYCASTLE-UTIL", ], "description": "Optional GraalPy BouncyCastle integration.", "maven": { @@ -1090,6 +1095,10 @@ "name": "org.graalvm.py", "exports": [ "com.oracle.graal.python.* to org.graalvm.py.enterprise", + "com.oracle.graal.python.builtins.objects.ssl to graalpython.bouncycastle", + ], + "uses": [ + "com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport", ], }, "useModulePath": True, @@ -1475,6 +1484,7 @@ "graalpython:GRAALPYTHON_BOUNCYCASTLE", "graalpython:BOUNCYCASTLE-PROVIDER", "graalpython:BOUNCYCASTLE-PKIX", + "graalpython:BOUNCYCASTLE-UTIL", "sdk:TOOLS_FOR_STANDALONE", ], "dynamicDistDependencies": "graalpy_standalone_deps", From 7468db527b6cc8084f13f710a07900e8dd73cf53 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 07:27:56 +0100 Subject: [PATCH 22/43] Update skill to check PR gates --- .agents/skills/pr-gate-check/SKILL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.agents/skills/pr-gate-check/SKILL.md b/.agents/skills/pr-gate-check/SKILL.md index 932b1b4a1f..e5b99c0399 100644 --- a/.agents/skills/pr-gate-check/SKILL.md +++ b/.agents/skills/pr-gate-check/SKILL.md @@ -22,6 +22,8 @@ git rev-list --all --parents | rg ' ( |$)' ``` Pick the merge commit where one parent is `` and the other is the target branch tip at merge time. +If you cannot find it this way, another heuristic is to take the branch name and append `_gate` - that usually has the merge commit we want as tip. + 3. Check builds on that merge commit: ```bash gdev-cli bitbucket get-builds --commit= --all --format=key,state,url From 79342618d7cd46c8915896b20eca95ddda29cc7c Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 08:47:07 +0100 Subject: [PATCH 23/43] Normalize SSL PEM and pre-handshake errors --- .../python/builtins/objects/ssl/SSLContextBuiltins.java | 6 +++--- .../graal/python/builtins/objects/ssl/SSLOperationNode.java | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java index e80848b09e..d1f6df16fc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java @@ -756,7 +756,7 @@ Object load(VirtualFrame frame, PSSLContext self, Object cafile, Object capath, self.setCAEntries(CertUtils.loadVerifyLocations(file, path)); } catch (NoCertificateFoundException e) { throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_NO_CERTIFICATE_OR_CRL_FOUND, ErrorMessages.NO_CERTIFICATE_OR_CRL_FOUND); - } catch (IOException e) { + } catch (IOException | CertificateException | CRLException e) { throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.X509_PEM_LIB); } } @@ -794,7 +794,7 @@ private static List getCertificates(Node inliningTarget, PConstructAndRa return certificates; } catch (BadBase64Exception e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_BAD_BASE64_DECODE, ErrorMessages.BAD_BASE64_DECODE); - } catch (IOException e) { + } catch (IOException | CertificateException | CRLException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } } @@ -889,7 +889,7 @@ private static Object load(PythonContext context, Node inliningTarget, PConstruc if (certs.length == 0) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } - } catch (IOException e) { + } catch (IOException | CertificateException | CRLException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); } // if keyReader and certReader are from the same file, key is expected to come first diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java index 6a0b34fbf8..d32667b235 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java @@ -554,6 +554,10 @@ private static PException handleSSLException(Node inliningTarget, SSLException e if (e.getCause() instanceof CertificateException) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_CERT_VERIFICATION, ErrorMessages.CERTIFICATE_VERIFY_FAILED, e.toString()); } - throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL, toTruffleStringUncached(e.toString())); + String message = e.toString(); + if (message.contains("Unrecognized SSL message, plaintext connection?")) { + message = "before TLS handshake with data"; + } + throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL, toTruffleStringUncached(message)); } } From 4a7627588f86792d534221d52bfffe5a40c3de05 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 09:04:54 +0100 Subject: [PATCH 24/43] Support @SECLEVEL=1 in SSL cipher strings --- .../src/tests/test_ssl.py | 2 ++ .../builtins/objects/ssl/SSLCipherSelector.java | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py index 1a701cb126..db518a6443 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py @@ -426,3 +426,5 @@ def test_error(self): get_cipher_list("ALL:!ALL:ADH") with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): get_cipher_list("ALL:@XXX") + with self.assertRaisesRegex(NotImplementedError, "only @SECLEVEL=1 is supported"): + get_cipher_list("@SECLEVEL=2:ALL") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java index 341a460e0f..9be3fec7a9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java @@ -118,7 +118,7 @@ private static void selectSingle(Node node, String cipherString, List if (cipherString.startsWith("@STRENGTH")) { selected.sort(Comparator.comparingInt(SSLCipher::getStrengthBits).reversed()); } else if (cipherString.startsWith("@SECLEVEL=")) { - throw PRaiseNode.raiseStatic(node, NotImplementedError, toTruffleStringUncached("@SECLEVEL not implemented")); + handleSecurityLevel(node, cipherString); } else { EncapsulatingNodeReference nodeRef = EncapsulatingNodeReference.getCurrent(); Node prev = nodeRef.set(node); @@ -140,6 +140,21 @@ private static void selectSingle(Node node, String cipherString, List } } + private static void handleSecurityLevel(Node node, String cipherString) { + String levelString = cipherString.substring("@SECLEVEL=".length()); + if ("1".equals(levelString)) { + return; + } + if (levelString.isEmpty() || levelString.chars().anyMatch(ch -> ch < '0' || ch > '9')) { + throw PRaiseNode.raiseStatic(node, + NotImplementedError, + toTruffleStringUncached("Unsupported OpenSSL cipher string directive: " + cipherString)); + } + throw PRaiseNode.raiseStatic(node, + NotImplementedError, + toTruffleStringUncached("Unsupported OpenSSL security level @SECLEVEL=" + levelString + "; only @SECLEVEL=1 is supported")); + } + private static List getCiphersForCipherString(Node node, String cipherString) { List result = null; for (String component : cipherString.split("\\+")) { From a06543e3fa69589349acd6735a187db3870273a7 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 09:24:53 +0100 Subject: [PATCH 25/43] Add Truffle boundary to marshal serializer --- .../graal/python/builtins/modules/MarshalModuleBuiltins.java | 1 + 1 file changed, 1 insertion(+) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java index df6c6d2861..d71bf7174c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java @@ -1677,6 +1677,7 @@ public PBytecodeDSLSerializer(PythonLanguage language) { this.language = language; } + @TruffleBoundary public void serialize(SerializerContext context, DataOutput buffer, Object object) throws IOException { /* * NB: Since the deserializer uses a fresh Marshal instance for each object (see below) From 2efd1acd2b79e588be606a7964593dce82e59dd2 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 09:35:24 +0100 Subject: [PATCH 26/43] Move pbkdf2 JCA work behind Truffle boundaries --- .../hashlib/HashlibModuleBuiltins.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index a77e28efa4..8f12b0ca99 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -474,7 +474,6 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password @Cached PRaiseNode raiseNode) { try { String javaHashName = toJavaStringNode.execute(hashName); - Mac mac = createPbkdf2Mac(javaHashName); if (iterations < 1) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ITERATION_VALUE_MUST_BE_GREATER_THAN_ZERO); } @@ -483,7 +482,7 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password } long dklen; if (noDklenProfile.profile(inliningTarget, PGuards.isPNone(dklenObj))) { - dklen = mac.getMacLength(); + dklen = getPbkdf2MacLength(javaHashName); } else { dklen = asLongNode.execute(frame, inliningTarget, dklenObj); } @@ -495,7 +494,7 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password } byte[] passwordBytes = passwordLib.getInternalOrCopiedExactByteArray(password); byte[] saltBytes = saltLib.getInternalOrCopiedExactByteArray(salt); - return PFactory.createBytes(language, generate(javaHashName, mac, passwordBytes, saltBytes, (int) iterations, (int) dklen)); + return PFactory.createBytes(language, generate(javaHashName, passwordBytes, saltBytes, (int) iterations, (int) dklen)); } catch (java.security.GeneralSecurityException e) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, UNSUPPORTED_HASH_TYPE, hashName); } finally { @@ -505,16 +504,24 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password } @TruffleBoundary - private static Mac createPbkdf2Mac(String name) { + private static int getPbkdf2MacLength(String name) throws NoSuchAlgorithmException { + return switch (name.toLowerCase()) { + case "sha1" -> 20; + case "sha224" -> 28; + case "sha256" -> 32; + case "sha384" -> 48; + case "sha512" -> 64; + default -> throw new NoSuchAlgorithmException(name); + }; + } + + @TruffleBoundary + private static Mac createPbkdf2Mac(String name) throws NoSuchAlgorithmException { String algorithm = getPbkdf2Algorithm(name); if (algorithm == null) { - return null; - } - try { - return Mac.getInstance(algorithm); - } catch (NoSuchAlgorithmException e) { - return null; + throw new NoSuchAlgorithmException(name); } + return Mac.getInstance(algorithm); } private static String getPbkdf2Algorithm(String name) { @@ -529,7 +536,8 @@ private static String getPbkdf2Algorithm(String name) { } @TruffleBoundary - private static byte[] generate(String hashName, Mac mac, byte[] password, byte[] salt, int iterations, int dklen) throws java.security.GeneralSecurityException { + private static byte[] generate(String hashName, byte[] password, byte[] salt, int iterations, int dklen) throws java.security.GeneralSecurityException { + Mac mac = createPbkdf2Mac(hashName); try { String algorithm = mac.getAlgorithm(); mac.init(new SecretKeySpec(password, algorithm)); From f34065c1cfcc168ecdb2a4d63efe042bfefdcf22 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 09:49:32 +0100 Subject: [PATCH 27/43] Remove stream usage from SSL security-level parsing --- .../builtins/objects/ssl/SSLCipherSelector.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java index 9be3fec7a9..7ef9826faa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java @@ -145,7 +145,7 @@ private static void handleSecurityLevel(Node node, String cipherString) { if ("1".equals(levelString)) { return; } - if (levelString.isEmpty() || levelString.chars().anyMatch(ch -> ch < '0' || ch > '9')) { + if (!isDecimalDigits(levelString)) { throw PRaiseNode.raiseStatic(node, NotImplementedError, toTruffleStringUncached("Unsupported OpenSSL cipher string directive: " + cipherString)); @@ -155,6 +155,19 @@ private static void handleSecurityLevel(Node node, String cipherString) { toTruffleStringUncached("Unsupported OpenSSL security level @SECLEVEL=" + levelString + "; only @SECLEVEL=1 is supported")); } + private static boolean isDecimalDigits(String value) { + if (value.isEmpty()) { + return false; + } + for (int i = 0; i < value.length(); i++) { + char ch = value.charAt(i); + if (ch < '0' || ch > '9') { + return false; + } + } + return true; + } + private static List getCiphersForCipherString(Node node, String cipherString) { List result = null; for (String component : cipherString.split("\\+")) { From 1cd5a779692fe866ac31885f59b377b279d0b6b1 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 13:45:58 +0100 Subject: [PATCH 28/43] Guard graalpy specific ssl test --- .../com.oracle.graal.python.test/src/tests/test_ssl.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py index db518a6443..931cc80592 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -426,5 +426,7 @@ def test_error(self): get_cipher_list("ALL:!ALL:ADH") with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): get_cipher_list("ALL:@XXX") - with self.assertRaisesRegex(NotImplementedError, "only @SECLEVEL=1 is supported"): - get_cipher_list("@SECLEVEL=2:ALL") + import sys + if sys.implementation.name == "graalpy": + with self.assertRaisesRegex(NotImplementedError, "only @SECLEVEL=1 is supported"): + get_cipher_list("@SECLEVEL=2:ALL") From f8ffc82b0f27072ee8c657fa3219bd98428a757a Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 13:46:17 +0100 Subject: [PATCH 29/43] Remove dead code --- .../bouncycastle/BCPrivateKeyLoader.java | 100 ------------------ 1 file changed, 100 deletions(-) delete mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java deleted file mode 100644 index 77106e86ce..0000000000 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCPrivateKeyLoader.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.bouncycastle; - -import java.io.IOException; -import java.io.StringReader; -import java.security.GeneralSecurityException; -import java.security.PrivateKey; - -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openssl.PEMEncryptedKeyPair; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; -import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; -import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; -import org.bouncycastle.pkcs.PKCSException; - -public final class BCPrivateKeyLoader { - private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider(); - - public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { - try (PEMParser pemParser = new PEMParser(new StringReader(pemText))) { - JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(PROVIDER); - Object object; - while ((object = pemParser.readObject()) != null) { - PrivateKeyInfo pkInfo; - if (object instanceof PEMKeyPair) { - pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); - } else if (object instanceof PEMEncryptedKeyPair) { - if (password == null) { - throw new NeedsPasswordException(); - } - JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder().setProvider(PROVIDER); - PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); - pkInfo = keyPair.getPrivateKeyInfo(); - } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { - if (password == null) { - throw new NeedsPasswordException(); - } - JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider(PROVIDER); - pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); - } else if (object instanceof PrivateKeyInfo) { - pkInfo = (PrivateKeyInfo) object; - } else { - continue; - } - return converter.getPrivateKey(pkInfo); - } - return null; - } catch (OperatorCreationException | PKCSException e) { - throw new GeneralSecurityException(e); - } - } - - public static final class NeedsPasswordException extends GeneralSecurityException { - private static final long serialVersionUID = 1L; - } -} From fc89659c19693fdad7e4a95572dde51ab93d666b Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 13:56:17 +0100 Subject: [PATCH 30/43] Fix style --- .../builtins/objects/ssl/SSLBouncyCastleSupportProvider.java | 1 - 1 file changed, 1 deletion(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java index b1637a8337..e0f64e85a0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java @@ -41,7 +41,6 @@ package com.oracle.graal.python.builtins.objects.ssl; import java.io.IOException; -import java.lang.ModuleLayer; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.util.Iterator; From b830e3e5bdbfcfa5eaef89747d561c75072b9c8b Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 13:58:59 +0100 Subject: [PATCH 31/43] Report suppressed exceptions --- .../objects/ssl/SSLBouncyCastleSupportProvider.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java index e0f64e85a0..92d39df3b4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java @@ -75,6 +75,9 @@ private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleExc return support; } } catch (ServiceConfigurationError | LinkageError e) { + if (failure != null) { + e.addSuppressed(failure); + } failure = e; } try { @@ -83,6 +86,9 @@ private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleExc return support; } } catch (ServiceConfigurationError | LinkageError e) { + if (failure != null) { + e.addSuppressed(failure); + } failure = e; } throw new MissingBouncyCastleException(failure); From 60f483c09a987ff647aad6e194cdc85a0189509f Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 14:24:26 +0100 Subject: [PATCH 32/43] Fix style --- .../graal/python/builtins/objects/ssl/SSLCipherSelector.java | 2 +- .../graal/python/builtins/objects/ssl/SSLOperationNode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java index 7ef9826faa..506c496a2a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java index d32667b235..e871e14fac 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 From 8d219b23a15cd5ba9b26337b12e9827f4a1e6b55 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 12 Mar 2026 15:03:26 +0100 Subject: [PATCH 33/43] Restore BC feature-based provider registration --- .../native-image.properties | 2 +- .../BCSSLBouncyCastleSupport.java | 50 +++++++-------- .../bouncycastle/BouncyCastleFeature.java | 61 +++++++++++++++++++ mx.graalpython/suite.py | 1 - 4 files changed, 84 insertions(+), 30 deletions(-) create mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties index aa8c1eebd7..13a0ad90d1 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties @@ -1,2 +1,2 @@ # Additional native-image arguments for optional GraalPy BouncyCastle support -Args = --initialize-at-run-time=org.bouncycastle +Args = --features=com.oracle.graal.python.bouncycastle.BouncyCastleFeature diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java index 6a7fd502a8..ea45e8bda6 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java @@ -75,38 +75,32 @@ public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOExcep JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(provider); Object object; while ((object = pemParser.readObject()) != null) { - try { - PrivateKeyInfo pkInfo; - if (object instanceof PEMKeyPair) { - pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); - } else if (object instanceof PEMEncryptedKeyPair) { - if (password == null) { - throw new NeedsPasswordException(); - } - JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder().setProvider(provider); - PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); - pkInfo = keyPair.getPrivateKeyInfo(); - } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { - if (password == null) { - throw new NeedsPasswordException(); - } - JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider(provider); - pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); - } else if (object instanceof PrivateKeyInfo) { - pkInfo = (PrivateKeyInfo) object; - } else { - continue; + PrivateKeyInfo pkInfo; + if (object instanceof PEMKeyPair) { + pkInfo = ((PEMKeyPair) object).getPrivateKeyInfo(); + } else if (object instanceof PEMEncryptedKeyPair) { + if (password == null) { + throw new NeedsPasswordException(); } - PrivateKey privateKey = converter.getPrivateKey(pkInfo); - if (privateKey == null) { - throw new RuntimeException("BC converter returned null for " + object.getClass().getName()); + JcePEMDecryptorProviderBuilder decryptor = new JcePEMDecryptorProviderBuilder().setProvider(provider); + PEMKeyPair keyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptor.build(password)); + pkInfo = keyPair.getPrivateKeyInfo(); + } else if (object instanceof PKCS8EncryptedPrivateKeyInfo) { + if (password == null) { + throw new NeedsPasswordException(); } - return privateKey; - } catch (OperatorCreationException | PKCSException e) { - throw new RuntimeException("BC failed for " + object.getClass().getName(), e); + JceOpenSSLPKCS8DecryptorProviderBuilder decryptor = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider(provider); + pkInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decryptor.build(password)); + } else if (object instanceof PrivateKeyInfo) { + pkInfo = (PrivateKeyInfo) object; + } else { + continue; } + return converter.getPrivateKey(pkInfo); } - throw new RuntimeException("BC found no supported key objects"); + return null; + } catch (OperatorCreationException | PKCSException e) { + throw new GeneralSecurityException(e); } } } diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java new file mode 100644 index 0000000000..e659675a35 --- /dev/null +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.bouncycastle; + +import java.security.Security; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; + +public final class BouncyCastleFeature implements Feature { + @Override + public void afterRegistration(AfterRegistrationAccess access) { + RuntimeClassInitializationSupport support = ImageSingletons.lookup(RuntimeClassInitializationSupport.class); + support.initializeAtBuildTime("org.bouncycastle", "security provider"); + support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$Default", "RNG"); + support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$NonceAndIV", "RNG"); + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } +} diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index e668797288..dcc7f69921 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -903,7 +903,6 @@ # From mx.graalpython/native-image.properties "--add-exports", "org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED", "--add-exports", "org.graalvm.py/com.oracle.graal.python.builtins.objects.ssl=ALL-UNNAMED", - "-H:AdditionalSecurityProviders=org.bouncycastle.jce.provider.BouncyCastleProvider", "-R:StackSize=16777216", "-H:+AddAllCharsets", "-H:IncludeLocales=no,be,ro,ru,es,se,in,ka,hu,hr,bg,is,mk,da,nn,cs,sq,fr,pl,fo,bs,kl,fa,sv,it,uk,af,tg,ps,de", From 53c4616c91a425fcf07063e5668f9cdd9d062c39 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Mon, 16 Mar 2026 17:33:04 +0100 Subject: [PATCH 34/43] Inline useless method that just replicates JDK code --- .../graal/python/builtins/objects/ssl/CertUtils.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 8f1b1c5201..396c633400 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -732,7 +732,7 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon PrivateKey privateKey = null; String algorithm = cert.getPublicKey().getAlgorithm(); try { - String pemText = readText(reader); + String pemText = reader.readAllAsString(); int fromIndex = 0; PemBlockWithContent rawBlock; while ((rawBlock = findNextPemBlock(pemText, fromIndex)) != null) { @@ -828,16 +828,6 @@ private static KeyPemBlock decodePrivateKeyPemBlock(String type, String content) } } - private static String readText(BufferedReader reader) throws IOException { - StringBuilder text = new StringBuilder(); - char[] buffer = new char[8192]; - int read; - while ((read = reader.read(buffer)) != -1) { - text.append(buffer, 0, read); - } - return text.toString(); - } - private static PrivateKey decodePrivateKey(String algorithm, byte[] encoded) throws NoSuchAlgorithmException, InvalidKeySpecException { return getKeyFactory(algorithm).generatePrivate(new PKCS8EncodedKeySpec(encoded)); } From 7baedc4e0cb1500808559a080974c0866553aec7 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Mon, 16 Mar 2026 17:43:14 +0100 Subject: [PATCH 35/43] Use import for GeneralSecurityException --- .../builtins/modules/hashlib/HashlibModuleBuiltins.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index 8f12b0ca99..68735e61c6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -57,6 +57,7 @@ import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.nio.ByteBuffer; +import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -495,7 +496,7 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password byte[] passwordBytes = passwordLib.getInternalOrCopiedExactByteArray(password); byte[] saltBytes = saltLib.getInternalOrCopiedExactByteArray(salt); return PFactory.createBytes(language, generate(javaHashName, passwordBytes, saltBytes, (int) iterations, (int) dklen)); - } catch (java.security.GeneralSecurityException e) { + } catch (GeneralSecurityException e) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, UNSUPPORTED_HASH_TYPE, hashName); } finally { passwordLib.release(password); @@ -536,7 +537,7 @@ private static String getPbkdf2Algorithm(String name) { } @TruffleBoundary - private static byte[] generate(String hashName, byte[] password, byte[] salt, int iterations, int dklen) throws java.security.GeneralSecurityException { + private static byte[] generate(String hashName, byte[] password, byte[] salt, int iterations, int dklen) throws GeneralSecurityException { Mac mac = createPbkdf2Mac(hashName); try { String algorithm = mac.getAlgorithm(); From 48294a06ea974d843228e36c957983b6dd0207ca Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Mon, 16 Mar 2026 17:51:39 +0100 Subject: [PATCH 36/43] Add tests and fallback to bouncycastle for more legacy certificate and private key formats --- .../BCSSLBouncyCastleSupport.java | 7 ++++- .../src/tests/ssldata/cert_dsa.pem | 26 +++++++++++++++++++ .../src/tests/ssldata/pk_dsa_legacy.pem | 20 ++++++++++++++ .../src/tests/ssldata/pk_ecc_legacy.pem | 6 +++++ .../src/tests/test_ssl.py | 12 +++++++++ .../builtins/objects/ssl/CertUtils.java | 16 +++++++++--- 6 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 graalpython/com.oracle.graal.python.test/src/tests/ssldata/cert_dsa.pem create mode 100644 graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_dsa_legacy.pem create mode 100644 graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_ecc_legacy.pem diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java index ea45e8bda6..80d2374d82 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java @@ -65,7 +65,12 @@ public final class BCSSLBouncyCastleSupport implements SSLBouncyCastleSupport { private static Provider getProvider() { Provider provider = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); - return provider != null ? provider : new BouncyCastleProvider(); + if (provider != null) { + return provider; + } + provider = new BouncyCastleProvider(); + Security.addProvider(provider); + return provider; } @Override diff --git a/graalpython/com.oracle.graal.python.test/src/tests/ssldata/cert_dsa.pem b/graalpython/com.oracle.graal.python.test/src/tests/ssldata/cert_dsa.pem new file mode 100644 index 0000000000..c9a8c010d7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/ssldata/cert_dsa.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEYzCCBBCgAwIBAgIUa4FezfhUiUvkPAwJQ2GNI7HJNCkwCwYJYIZIAWUDBAMC +MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yNjAzMTYxNjQ4NTBaFw0zNjAzMTMx +NjQ4NTBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCA0MwggI1BgcqhkjOOAQBMIIC +KAKCAQEAt93WIFjdg9j0JO4MIZzgnzgEQa1CJky7vLfS0S1YetqzE1tyXeWNx/Kj +sxm9OdL8Xvnb5LJKoLJbFZ0yV0/tOqnA1pNn/QH3Fh3p2l9yADu9V6GYcxmwo1U1 +PlZ+oHoj5IFIoQZeENSlPPrTWTj/y0WjGJNwzRlIVTNJpP3vUw5Shf6RmGPq1uJs +RPJRSPiBZ9fccXyffrOpOizrS4HfQpmAsva4/Ijlc1Hn7Ko1uRLMGARpeGmpzxis +tkD4Fns5YH5k21cL3+ZkNlCJAqRZgGwyL+M0WB/LEnk/mlhgt9s0WHLpoxoEPllc +UvPsJ+ZUKPnieijiP0wOMEIF9SvdwwIdANAJ0cXh8PGBvIfV6Wg+3p8Jz64Cz3g7 +McVpzuMCggEAaEER2Jrd9lmlQdDjkH21GaMkiwpNnSExwMwnAjprZe+n+3/9Xv6e +dNJKxK9ITx7xe+CCjfOl3M0m/Spo+hLoL9dLiJ/3ZfxfRkfDizWTxwbh6jDzEfh5 +vW0Xkx1aALRudGH8t6VnlBrSCjj0r6Ih7z3m0eTe/3PV47p9CrD0KLUiKS+GcDYT +rgglG/jLhKEaR22/T2jLP4VaE15Yi6Vc9LcFwQyLrKytDgqsChqaJzAl/72YWzob +tFkCUM94h0Jx7vMTlIwhBihxya4yAiERxZFKENhs1mhMLMu2fCk2K3BChMVm42fE +UFywxOvChj2DOQvYQTOuTNz/yyqONZEuxQOCAQYAAoIBAQCHmjdKyPjTSl5ErgvA +gG4+h1Z5NBty1dgORCB8JK8IkUojAre8nvZvExFSFBjyr5TCvLR6vDvB5sn16+zP +w7QNMDPvLNZ74lBjcnuNXkc9XAuJlj53zSLQy/jvi+Hf1UknAfnfrIXQ/v40Pmz5 +hyhRbLjOiF6azm56DzsFRdoi88cihRnI0pSDaaE09/sPJdZVEmWfLKEbFAQGSo55 +f5aoSOpFzUElFp/OdHAj8InuhxP8QXPFYx5xmUAvc1yyw47Qz9Fp6ewFZoE3LquC +GwuXfhMxFGVbD+f2hQhRHDHfOSMg+W6y3+7ZG5mYq+aRwM10/FA2TRL5efzaBuV7 +baTUo1MwUTAdBgNVHQ4EFgQUIbSBGsQPPVVo0LrkNC1f5viGw0owHwYDVR0jBBgw +FoAUIbSBGsQPPVVo0LrkNC1f5viGw0owDwYDVR0TAQH/BAUwAwEB/zALBglghkgB +ZQMEAwIDQAAwPQIcccMSDglufq9UQP3wfXaqW4GOtP5/Ph3R9q9X2gIdAJRsMoM9 +X6l+d5A6kXV+uaXweaZFnoZ9Mo6+JAI= +-----END CERTIFICATE----- diff --git a/graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_dsa_legacy.pem b/graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_dsa_legacy.pem new file mode 100644 index 0000000000..381ccf8c60 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_dsa_legacy.pem @@ -0,0 +1,20 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDTgIBAAKCAQEAt93WIFjdg9j0JO4MIZzgnzgEQa1CJky7vLfS0S1YetqzE1ty +XeWNx/Kjsxm9OdL8Xvnb5LJKoLJbFZ0yV0/tOqnA1pNn/QH3Fh3p2l9yADu9V6GY +cxmwo1U1PlZ+oHoj5IFIoQZeENSlPPrTWTj/y0WjGJNwzRlIVTNJpP3vUw5Shf6R +mGPq1uJsRPJRSPiBZ9fccXyffrOpOizrS4HfQpmAsva4/Ijlc1Hn7Ko1uRLMGARp +eGmpzxistkD4Fns5YH5k21cL3+ZkNlCJAqRZgGwyL+M0WB/LEnk/mlhgt9s0WHLp +oxoEPllcUvPsJ+ZUKPnieijiP0wOMEIF9SvdwwIdANAJ0cXh8PGBvIfV6Wg+3p8J +z64Cz3g7McVpzuMCggEAaEER2Jrd9lmlQdDjkH21GaMkiwpNnSExwMwnAjprZe+n ++3/9Xv6edNJKxK9ITx7xe+CCjfOl3M0m/Spo+hLoL9dLiJ/3ZfxfRkfDizWTxwbh +6jDzEfh5vW0Xkx1aALRudGH8t6VnlBrSCjj0r6Ih7z3m0eTe/3PV47p9CrD0KLUi +KS+GcDYTrgglG/jLhKEaR22/T2jLP4VaE15Yi6Vc9LcFwQyLrKytDgqsChqaJzAl +/72YWzobtFkCUM94h0Jx7vMTlIwhBihxya4yAiERxZFKENhs1mhMLMu2fCk2K3BC +hMVm42fEUFywxOvChj2DOQvYQTOuTNz/yyqONZEuxQKCAQEAh5o3Ssj400peRK4L +wIBuPodWeTQbctXYDkQgfCSvCJFKIwK3vJ72bxMRUhQY8q+Uwry0erw7webJ9evs +z8O0DTAz7yzWe+JQY3J7jV5HPVwLiZY+d80i0Mv474vh39VJJwH536yF0P7+ND5s ++YcoUWy4zohems5ueg87BUXaIvPHIoUZyNKUg2mhNPf7DyXWVRJlnyyhGxQEBkqO +eX+WqEjqRc1BJRafznRwI/CJ7ocT/EFzxWMecZlAL3NcssOO0M/RaensBWaBNy6r +ghsLl34TMRRlWw/n9oUIURwx3zkjIPlust/u2RuZmKvmkcDNdPxQNk0S+Xn82gbl +e22k1AIcANOj4eSn45Oi3o7NSpqU/LZ0PYo5tD1osrjZTA== +-----END DSA PRIVATE KEY----- diff --git a/graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_ecc_legacy.pem b/graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_ecc_legacy.pem new file mode 100644 index 0000000000..580e5ef888 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/ssldata/pk_ecc_legacy.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDBL2Y5JfpzbgHw+t4Q+c5SHhsZcD9ylEtUMg7OyF9xW6j+3VIVORGao +kcOtE0Z2Y5egBwYFK4EEACKhZANiAASzz/rInKUzonpxP5bLxmq8fmrtgRSS0jRP +UOU16XKX+KtifnLbmLHQtPrctdkRRROCxnURz2fBihQTJkXyBMSswNTRCs+4DUKb +MAfihigMVYgdWbZPFBDleo5aeFw4/FM= +-----END EC PRIVATE KEY----- diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py index 931cc80592..f39f880ed5 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl.py @@ -372,6 +372,18 @@ def test_private_key_pkcs1(self): def test_private_key_pkcs1_password(self): self.check_keypair("signed_cert_pkcs1_password.pem", "signing_ca.pem", password="password") + def test_private_key_ec_legacy(self): + server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + server_context.load_cert_chain(data_file("keycertecc.pem"), keyfile=data_file("pk_ecc_legacy.pem")) + client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + client_context.check_hostname = False + client_context.verify_mode = ssl.CERT_NONE + check_handshake(server_context, client_context) + + def test_private_key_dsa_legacy(self): + server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + server_context.load_cert_chain(data_file("cert_dsa.pem"), keyfile=data_file("pk_dsa_legacy.pem")) + def test_alpn(self): signed_cert = data_file("signed_cert.pem") server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 396c633400..a52c5cb732 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -747,14 +747,14 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon } privateKey = decodeEncryptedPrivateKey(algorithm, block.content(), password); break; - } else if ("RSA PRIVATE KEY".equals(block.type())) { - if (block.headers().isEmpty()) { + } else if (isLegacyPrivateKeyType(block.type())) { + if ("RSA PRIVATE KEY".equals(block.type()) && block.headers().isEmpty()) { privateKey = decodeRsaPrivateKey(block.content()); } else { - if (password == null) { + if (!block.headers().isEmpty() && password == null) { throw new NeedsPasswordException(); } - privateKey = SSLBouncyCastleSupportProvider.loadPrivateKey(password, pemText); + privateKey = SSLBouncyCastleSupportProvider.loadPrivateKey(password, pemBlockToText(rawBlock)); } break; } @@ -828,6 +828,14 @@ private static KeyPemBlock decodePrivateKeyPemBlock(String type, String content) } } + private static boolean isLegacyPrivateKeyType(String type) { + return "RSA PRIVATE KEY".equals(type) || "DSA PRIVATE KEY".equals(type) || "EC PRIVATE KEY".equals(type); + } + + private static String pemBlockToText(PemBlockWithContent block) { + return "-----BEGIN " + block.type() + "-----\n" + block.content() + "\n-----END " + block.type() + "-----\n"; + } + private static PrivateKey decodePrivateKey(String algorithm, byte[] encoded) throws NoSuchAlgorithmException, InvalidKeySpecException { return getKeyFactory(algorithm).generatePrivate(new PKCS8EncodedKeySpec(encoded)); } From 56e794fdc244ac981adfc4545db564ea1077e265 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 17 Mar 2026 14:48:01 +0100 Subject: [PATCH 37/43] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 276a85af44..ed4ac50792 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ language runtime. The main focus is on user-observable behavior of the engine. * Added a new `java` backend for the `pyexpat` module that uses a Java XML parser instead of the native `expat` library. It can be useful when running without native access or multiple-context scenarios. This backend is the default when embedding and can be switched back to native `expat` by setting `python.PyExpatModuleBackend` option to `native`. Standalone distribution still defaults to native expat backend. * Add a new context option `python.UnicodeCharacterDatabaseNativeFallback` to control whether the ICU database may fall back to the native unicode character database from CPython for features and characters not supported by ICU. This requires native access to be enabled and is disabled by default for embeddings. * Foreign temporal objects (dates, times, and timezones) are now given a Python class corresponding to their interop traits, i.e., `date`, `time`, `datetime`, or `tzinfo`. This allows any foreign objects with these traits to be used in place of the native Python types and Python methods available on these types work on the foreign types. +* Make BouncyCastle an optional dependency for embedding use cases. BouncyCastle is only needed for legacy RSA, DSA, and EC privat keys versions 0 and 1. To support these from Python embeddings, BouncyCastle must now be explicitly enabled by adding the `org.graalvm.python:python-bouncycastle-support` Maven artifact. ## Version 25.0.1 * Allow users to keep going on unsupported JDK/OS/ARCH combinations at their own risk by opting out of early failure using `-Dtruffle.UseFallbackRuntime=true`, `-Dpolyglot.engine.userResourceCache=/set/to/a/writeable/dir`, `-Dpolyglot.engine.allowUnsupportedPlatform=true`, and `-Dpolyglot.python.UnsupportedPlatformEmulates=[linux|macos|windows]` and `-Dorg.graalvm.python.resources.exclude=native.files`. From 008b6e30d9a6cb4aaf0faa66d090a7593af356b4 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 14 Apr 2026 16:04:06 +0200 Subject: [PATCH 38/43] [GR-64013] Make BC optional in standalone packaging --- mx.graalpython/mx_graalpython.py | 21 +++++++++++++++++++++ mx.graalpython/suite.py | 5 ----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/mx.graalpython/mx_graalpython.py b/mx.graalpython/mx_graalpython.py index 0b5f451b7b..c93f0ef81d 100644 --- a/mx.graalpython/mx_graalpython.py +++ b/mx.graalpython/mx_graalpython.py @@ -129,6 +129,8 @@ def get_boolean_env(name, default=False): WIN32 = sys.platform == "win32" BUILD_NATIVE_IMAGE_WITH_ASSERTIONS = get_boolean_env('BUILD_WITH_ASSERTIONS', CI) BYTECODE_DSL_INTERPRETER = get_boolean_env('BYTECODE_DSL_INTERPRETER', True) +GRAALPY_WITH_BOUNCYCASTLE = get_boolean_env("GRAALPY_WITH_BOUNCYCASTLE", mx.primary_suite() == SUITE or SUITE.dir == os.getcwd()) + mx_gate.add_jacoco_excludes([ "com.oracle.graal.python.pegparser.sst", @@ -160,6 +162,17 @@ def wants_debug_build(flags=os.environ.get("CFLAGS", "")): )) +if GRAALPY_WITH_BOUNCYCASTLE: + setattr(ThinLauncherProject, "_original_cflags_without_graalpy_bouncycastle", ThinLauncherProject.cflags) + def _flags_with_bc_args(self): + if "graalpy" in repr(self): + if dvmargs := getattr(self, "default_vm_args", None): + mx.log("Appending bouncycastle to GraalPy launcher -add-modules") + dvmargs.append('--vm.-add-modules=graalpython.bouncycastle,org.bouncycastle.provider,org.bouncycastle.pkix,org.bouncycastle.util') + return self._original_cflags_without_graalpy_bouncycastle + setattr(ThinLauncherProject, "cflags", property(_flags_with_bc_args)) + + if WIN32: # let's check if VS compilers are on the PATH if not os.environ.get("LIB"): @@ -246,6 +259,14 @@ def get_jdk(): def graalpy_standalone_deps(): include_truffle_runtime = not mx.env_var_to_bool("EXCLUDE_TRUFFLE_RUNTIME") deps = mx_truffle.resolve_truffle_dist_names(use_optimized_runtime=include_truffle_runtime) + if GRAALPY_WITH_BOUNCYCASTLE: + mx.log("Including bouncycastle with GraalPy standalone") + deps += [ + "graalpython:GRAALPYTHON_BOUNCYCASTLE", + "graalpython:BOUNCYCASTLE-PROVIDER", + "graalpython:BOUNCYCASTLE-PKIX", + "graalpython:BOUNCYCASTLE-UTIL", + ] return deps diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index dcc7f69921..4783db797c 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -882,7 +882,6 @@ "default_vm_args": [ "--vm.Xss16777216", # request 16M of stack '--vm.-enable-native-access=org.graalvm.shadowed.jline', - '--vm.-add-modules=graalpython.bouncycastle,org.bouncycastle.provider,org.bouncycastle.pkix,org.bouncycastle.util', ], "multitarget": [ {"os": ["linux"], "libc": ["glibc", "default"], "compiler": ["llvm-toolchain", "host", "*"]}, @@ -1480,10 +1479,6 @@ "distDependencies": [ "graalpython:GRAALPYTHON-LAUNCHER", "graalpython:GRAALPYTHON", - "graalpython:GRAALPYTHON_BOUNCYCASTLE", - "graalpython:BOUNCYCASTLE-PROVIDER", - "graalpython:BOUNCYCASTLE-PKIX", - "graalpython:BOUNCYCASTLE-UTIL", "sdk:TOOLS_FOR_STANDALONE", ], "dynamicDistDependencies": "graalpy_standalone_deps", From 376acbd08b0e6c91aa7409314e8728c8a8b86758 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 16 Apr 2026 09:24:00 +0200 Subject: [PATCH 39/43] [GR-64013] Unify optional BouncyCastle support --- ...uiltins.objects.ssl.SSLBouncyCastleSupport | 1 - ....python.runtime.crypto.BouncyCastleSupport | 1 + ...port.java => BouncyCastleSupportImpl.java} | 15 +++++--- .../hashlib/HashlibModuleBuiltins.java | 20 ++++++++++- .../builtins/objects/ssl/CertUtils.java | 5 +-- .../python/runtime/PythonCryptoFeature.java | 12 +++---- .../crypto/BouncyCastleSupport.java} | 8 +++-- .../crypto/BouncyCastleSupportProvider.java} | 34 +++++++++++++------ mx.graalpython/suite.py | 3 +- 9 files changed, 70 insertions(+), 29 deletions(-) delete mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport create mode 100644 graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.runtime.crypto.BouncyCastleSupport rename graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/{BCSSLBouncyCastleSupport.java => BouncyCastleSupportImpl.java} (92%) rename graalpython/com.oracle.graal.python/src/com/oracle/graal/python/{builtins/objects/ssl/SSLBouncyCastleSupport.java => runtime/crypto/BouncyCastleSupport.java} (90%) rename graalpython/com.oracle.graal.python/src/com/oracle/graal/python/{builtins/objects/ssl/SSLBouncyCastleSupportProvider.java => runtime/crypto/BouncyCastleSupportProvider.java} (70%) diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport deleted file mode 100644 index 9fb6b3689f..0000000000 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport +++ /dev/null @@ -1 +0,0 @@ -com.oracle.graal.python.bouncycastle.BCSSLBouncyCastleSupport diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.runtime.crypto.BouncyCastleSupport b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.runtime.crypto.BouncyCastleSupport new file mode 100644 index 0000000000..7bfca52a3e --- /dev/null +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/services/com.oracle.graal.python.runtime.crypto.BouncyCastleSupport @@ -0,0 +1 @@ +com.oracle.graal.python.bouncycastle.BouncyCastleSupportImpl diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleSupportImpl.java similarity index 92% rename from graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java rename to graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleSupportImpl.java index 80d2374d82..6b0c1cfb46 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BCSSLBouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleSupportImpl.java @@ -43,6 +43,8 @@ import java.io.IOException; import java.io.StringReader; import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; import java.security.Security; @@ -60,17 +62,15 @@ import org.bouncycastle.pkcs.PKCSException; import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException; -import com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport; +import com.oracle.graal.python.runtime.crypto.BouncyCastleSupport; -public final class BCSSLBouncyCastleSupport implements SSLBouncyCastleSupport { +public final class BouncyCastleSupportImpl implements BouncyCastleSupport { private static Provider getProvider() { Provider provider = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); if (provider != null) { return provider; } - provider = new BouncyCastleProvider(); - Security.addProvider(provider); - return provider; + return new BouncyCastleProvider(); } @Override @@ -108,4 +108,9 @@ public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOExcep throw new GeneralSecurityException(e); } } + + @Override + public MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException { + return MessageDigest.getInstance(algorithm, getProvider()); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index 68735e61c6..9d52fc10f1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -99,6 +99,7 @@ import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; +import com.oracle.graal.python.runtime.crypto.BouncyCastleSupportProvider; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -392,12 +393,29 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassTy @TruffleBoundary private static MessageDigest createDigest(String name, byte[] bytes, int bytesLen) throws NoSuchAlgorithmException { - MessageDigest digest = MessageDigest.getInstance(name); + MessageDigest digest; + try { + digest = MessageDigest.getInstance(name); + } catch (NoSuchAlgorithmException primary) { + if (!isBouncyCastleDigest(name)) { + throw primary; + } + try { + digest = BouncyCastleSupportProvider.createDigest(name); + } catch (NoSuchAlgorithmException secondary) { + primary.addSuppressed(secondary); + throw primary; + } + } if (bytes != null) { digest.update(bytes, 0, bytesLen); } return digest; } + + private static boolean isBouncyCastleDigest(String name) { + return name.startsWith("BLAKE2B-") || name.startsWith("BLAKE2S-"); + } } @Builtin(name = "new", minNumOfPositionalArgs = 1, parameterNames = {"name", "string"}, keywordOnlyNames = {"usedforsecurity"}) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index a52c5cb732..2638f53153 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -108,6 +108,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.crypto.BouncyCastleSupportProvider; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleFile; @@ -754,12 +755,12 @@ static PrivateKey getPrivateKey(PythonContext context, Node inliningTarget, PCon if (!block.headers().isEmpty() && password == null) { throw new NeedsPasswordException(); } - privateKey = SSLBouncyCastleSupportProvider.loadPrivateKey(password, pemBlockToText(rawBlock)); + privateKey = BouncyCastleSupportProvider.loadPrivateKey(password, pemBlockToText(rawBlock)); } break; } } - } catch (SSLBouncyCastleSupportProvider.MissingBouncyCastleException e) { + } catch (BouncyCastleSupportProvider.MissingBouncyCastleException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL, toTruffleStringUncached(e.getMessage())); } catch (IOException | GeneralSecurityException e) { throw raiseNode.get(inliningTarget).raiseSSLError(null, SSLErrorCode.ERROR_SSL_PEM_LIB, ErrorMessages.SSL_PEM_LIB); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java index fe7b9b2b03..8f0bb49409 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonCryptoFeature.java @@ -56,8 +56,8 @@ public final class PythonCryptoFeature implements Feature { "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA512", "sun.security.pkcs11.P11HKDF", }; - private static final String BC_SSL_SUPPORT_CLASS = "com.oracle.graal.python.bouncycastle.BCSSLBouncyCastleSupport"; - private static final String BC_SSL_SERVICE_RESOURCE = "META-INF/services/com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport"; + private static final String BC_SUPPORT_CLASS = "com.oracle.graal.python.bouncycastle.BouncyCastleSupportImpl"; + private static final String BC_SUPPORT_SERVICE_RESOURCE = "META-INF/services/com.oracle.graal.python.runtime.crypto.BouncyCastleSupport"; @Override public void afterRegistration(AfterRegistrationAccess access) { @@ -87,18 +87,18 @@ private static void registerHkdfReflection() { private static void registerOptionalBouncyCastleSupport() { try { - Class clazz = Class.forName(BC_SSL_SUPPORT_CLASS); + Class clazz = Class.forName(BC_SUPPORT_CLASS); RuntimeReflection.register(clazz); RuntimeReflection.register(clazz.getConstructors()); - try (InputStream stream = clazz.getClassLoader().getResourceAsStream(BC_SSL_SERVICE_RESOURCE)) { + try (InputStream stream = clazz.getClassLoader().getResourceAsStream(BC_SUPPORT_SERVICE_RESOURCE)) { if (stream != null) { - RuntimeResourceAccess.addResource(clazz.getModule(), BC_SSL_SERVICE_RESOURCE, stream.readAllBytes()); + RuntimeResourceAccess.addResource(clazz.getModule(), BC_SUPPORT_SERVICE_RESOURCE, stream.readAllBytes()); } } } catch (ClassNotFoundException e) { return; } catch (SecurityException | IOException e) { - throw new RuntimeException("Could not register optional BouncyCastle SSL support for native image.", e); + throw new RuntimeException("Could not register optional BouncyCastle support for native image.", e); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupport.java similarity index 90% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupport.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupport.java index 4e0fbd19d9..6bb97ee3f2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupport.java @@ -38,14 +38,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.ssl; +package com.oracle.graal.python.runtime.crypto; import java.io.IOException; import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException; -public interface SSLBouncyCastleSupport { +public interface BouncyCastleSupport { PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException; + + MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupportProvider.java similarity index 70% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupportProvider.java index 92d39df3b4..9b29f713e2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLBouncyCastleSupportProvider.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupportProvider.java @@ -38,10 +38,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.ssl; +package com.oracle.graal.python.runtime.crypto; import java.io.IOException; import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.util.Iterator; import java.util.ServiceConfigurationError; @@ -49,20 +51,30 @@ import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException; -public final class SSLBouncyCastleSupportProvider { - public static final String MISSING_MESSAGE = "Encrypted legacy PEM private keys require BouncyCastle support; add the GraalPy BC support module and BouncyCastle jars to the classpath or modulepath, or convert the key to PKCS#8."; +public final class BouncyCastleSupportProvider { + public static final String MISSING_PRIVATE_KEY_MESSAGE = "Encrypted legacy PEM private keys require BouncyCastle support; add the GraalPy BC support module and BouncyCastle jars to the classpath or modulepath, or convert the key to PKCS#8."; - private SSLBouncyCastleSupportProvider() { + private BouncyCastleSupportProvider() { } public static PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { return getSupport().loadPrivateKey(password, pemText); } - private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleException { + public static MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException { + try { + return getSupport().createDigest(algorithm); + } catch (MissingBouncyCastleException e) { + NoSuchAlgorithmException wrapped = new NoSuchAlgorithmException(algorithm + " MessageDigest not available"); + wrapped.initCause(e); + throw wrapped; + } + } + + private static BouncyCastleSupport getSupport() throws MissingBouncyCastleException { Throwable failure = null; try { - SSLBouncyCastleSupport support = getSupport(ServiceLoader.load(ModuleLayer.boot(), SSLBouncyCastleSupport.class)); + BouncyCastleSupport support = getSupport(ServiceLoader.load(ModuleLayer.boot(), BouncyCastleSupport.class)); if (support != null) { return support; } @@ -70,7 +82,7 @@ private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleExc failure = e; } try { - SSLBouncyCastleSupport support = getSupport(ServiceLoader.load(SSLBouncyCastleSupport.class)); + BouncyCastleSupport support = getSupport(ServiceLoader.load(BouncyCastleSupport.class)); if (support != null) { return support; } @@ -81,7 +93,7 @@ private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleExc failure = e; } try { - SSLBouncyCastleSupport support = getSupport(ServiceLoader.load(SSLBouncyCastleSupport.class, SSLBouncyCastleSupportProvider.class.getClassLoader())); + BouncyCastleSupport support = getSupport(ServiceLoader.load(BouncyCastleSupport.class, BouncyCastleSupportProvider.class.getClassLoader())); if (support != null) { return support; } @@ -94,8 +106,8 @@ private static SSLBouncyCastleSupport getSupport() throws MissingBouncyCastleExc throw new MissingBouncyCastleException(failure); } - private static SSLBouncyCastleSupport getSupport(ServiceLoader serviceLoader) { - Iterator iterator = serviceLoader.iterator(); + private static BouncyCastleSupport getSupport(ServiceLoader serviceLoader) { + Iterator iterator = serviceLoader.iterator(); return iterator.hasNext() ? iterator.next() : null; } @@ -103,7 +115,7 @@ public static final class MissingBouncyCastleException extends GeneralSecurityEx private static final long serialVersionUID = 1L; MissingBouncyCastleException(Throwable cause) { - super(MISSING_MESSAGE, cause); + super(MISSING_PRIVATE_KEY_MESSAGE, cause); } } } diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 4783db797c..d37aae176c 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -1094,9 +1094,10 @@ "exports": [ "com.oracle.graal.python.* to org.graalvm.py.enterprise", "com.oracle.graal.python.builtins.objects.ssl to graalpython.bouncycastle", + "com.oracle.graal.python.runtime.crypto to graalpython.bouncycastle", ], "uses": [ - "com.oracle.graal.python.builtins.objects.ssl.SSLBouncyCastleSupport", + "com.oracle.graal.python.runtime.crypto.BouncyCastleSupport", ], }, "useModulePath": True, From 1a5ba3081c1160177991c953df0f6c01e62e7f18 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 16 Apr 2026 09:48:50 +0200 Subject: [PATCH 40/43] [GR-64013] Stop globally installing BouncyCastle --- .../graal/python/bouncycastle/BouncyCastleFeature.java | 6 ------ mx.graalpython/suite.py | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java index e659675a35..61a752eb4e 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java @@ -40,9 +40,6 @@ */ package com.oracle.graal.python.bouncycastle; -import java.security.Security; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; @@ -54,8 +51,5 @@ public void afterRegistration(AfterRegistrationAccess access) { support.initializeAtBuildTime("org.bouncycastle", "security provider"); support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$Default", "RNG"); support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$NonceAndIV", "RNG"); - if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { - Security.addProvider(new BouncyCastleProvider()); - } } } diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index d37aae176c..0e73ca0c89 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -1094,7 +1094,7 @@ "exports": [ "com.oracle.graal.python.* to org.graalvm.py.enterprise", "com.oracle.graal.python.builtins.objects.ssl to graalpython.bouncycastle", - "com.oracle.graal.python.runtime.crypto to graalpython.bouncycastle", + "com.oracle.graal.python.runtime.crypto", ], "uses": [ "com.oracle.graal.python.runtime.crypto.BouncyCastleSupport", From 25d81a7a990753e0f4bbcafd865857ad704638cb Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 16 Apr 2026 10:06:33 +0200 Subject: [PATCH 41/43] Revert "[GR-64013] Make BC optional in standalone packaging" This reverts commit 008b6e30d9a6cb4aaf0faa66d090a7593af356b4. --- mx.graalpython/mx_graalpython.py | 21 --------------------- mx.graalpython/suite.py | 5 +++++ 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/mx.graalpython/mx_graalpython.py b/mx.graalpython/mx_graalpython.py index c93f0ef81d..0b5f451b7b 100644 --- a/mx.graalpython/mx_graalpython.py +++ b/mx.graalpython/mx_graalpython.py @@ -129,8 +129,6 @@ def get_boolean_env(name, default=False): WIN32 = sys.platform == "win32" BUILD_NATIVE_IMAGE_WITH_ASSERTIONS = get_boolean_env('BUILD_WITH_ASSERTIONS', CI) BYTECODE_DSL_INTERPRETER = get_boolean_env('BYTECODE_DSL_INTERPRETER', True) -GRAALPY_WITH_BOUNCYCASTLE = get_boolean_env("GRAALPY_WITH_BOUNCYCASTLE", mx.primary_suite() == SUITE or SUITE.dir == os.getcwd()) - mx_gate.add_jacoco_excludes([ "com.oracle.graal.python.pegparser.sst", @@ -162,17 +160,6 @@ def wants_debug_build(flags=os.environ.get("CFLAGS", "")): )) -if GRAALPY_WITH_BOUNCYCASTLE: - setattr(ThinLauncherProject, "_original_cflags_without_graalpy_bouncycastle", ThinLauncherProject.cflags) - def _flags_with_bc_args(self): - if "graalpy" in repr(self): - if dvmargs := getattr(self, "default_vm_args", None): - mx.log("Appending bouncycastle to GraalPy launcher -add-modules") - dvmargs.append('--vm.-add-modules=graalpython.bouncycastle,org.bouncycastle.provider,org.bouncycastle.pkix,org.bouncycastle.util') - return self._original_cflags_without_graalpy_bouncycastle - setattr(ThinLauncherProject, "cflags", property(_flags_with_bc_args)) - - if WIN32: # let's check if VS compilers are on the PATH if not os.environ.get("LIB"): @@ -259,14 +246,6 @@ def get_jdk(): def graalpy_standalone_deps(): include_truffle_runtime = not mx.env_var_to_bool("EXCLUDE_TRUFFLE_RUNTIME") deps = mx_truffle.resolve_truffle_dist_names(use_optimized_runtime=include_truffle_runtime) - if GRAALPY_WITH_BOUNCYCASTLE: - mx.log("Including bouncycastle with GraalPy standalone") - deps += [ - "graalpython:GRAALPYTHON_BOUNCYCASTLE", - "graalpython:BOUNCYCASTLE-PROVIDER", - "graalpython:BOUNCYCASTLE-PKIX", - "graalpython:BOUNCYCASTLE-UTIL", - ] return deps diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 0e73ca0c89..7546a5d707 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -882,6 +882,7 @@ "default_vm_args": [ "--vm.Xss16777216", # request 16M of stack '--vm.-enable-native-access=org.graalvm.shadowed.jline', + '--vm.-add-modules=graalpython.bouncycastle,org.bouncycastle.provider,org.bouncycastle.pkix,org.bouncycastle.util', ], "multitarget": [ {"os": ["linux"], "libc": ["glibc", "default"], "compiler": ["llvm-toolchain", "host", "*"]}, @@ -1480,6 +1481,10 @@ "distDependencies": [ "graalpython:GRAALPYTHON-LAUNCHER", "graalpython:GRAALPYTHON", + "graalpython:GRAALPYTHON_BOUNCYCASTLE", + "graalpython:BOUNCYCASTLE-PROVIDER", + "graalpython:BOUNCYCASTLE-PKIX", + "graalpython:BOUNCYCASTLE-UTIL", "sdk:TOOLS_FOR_STANDALONE", ], "dynamicDistDependencies": "graalpy_standalone_deps", From 40be5a538ec4d9fa3ba190f6642b6e298fe362df Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 16 Apr 2026 13:26:32 +0200 Subject: [PATCH 42/43] Fix optional BC SSL support to cover both Blake2 hashes and older ssl crypt --- .../native-image.properties | 2 +- .../python-bouncycastle/reflect-config.json | 72 +++++++++++++++++++ .../bouncycastle/BouncyCastleFeature.java | 4 ++ .../bouncycastle/BouncyCastleSupportImpl.java | 8 ++- .../builtins/objects/ssl/CertUtils.java | 17 +++++ .../runtime/crypto/BouncyCastleSupport.java | 3 + .../crypto/BouncyCastleSupportProvider.java | 11 +++ 7 files changed, 115 insertions(+), 2 deletions(-) diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties index 13a0ad90d1..8292f15daa 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties @@ -1,2 +1,2 @@ # Additional native-image arguments for optional GraalPy BouncyCastle support -Args = --features=com.oracle.graal.python.bouncycastle.BouncyCastleFeature +Args = --features=com.oracle.graal.python.bouncycastle.BouncyCastleFeature -H:AdditionalSecurityProviders=org.bouncycastle.jce.provider.BouncyCastleProvider diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json index 4fbca1c6cf..fb104aeb8d 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/reflect-config.json @@ -263,6 +263,18 @@ "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" } }, + { + "name": "org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, { "name": "org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi", "methods": [ @@ -1223,6 +1235,66 @@ "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" } }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$CBC", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$CBC128", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$CBC192", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$CBC256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, + { + "name": "org.bouncycastle.jcajce.provider.symmetric.AES$PBEWithMD5And256BitAESCBCOpenSSL", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ], + "condition": { + "typeReachable": "org.bouncycastle.jce.provider.BouncyCastleProvider" + } + }, { "name": "org.bouncycastle.jcajce.provider.symmetric.AES$Mappings", "methods": [ diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java index 61a752eb4e..38d78e7b49 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.bouncycastle; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; @@ -51,5 +52,8 @@ public void afterRegistration(AfterRegistrationAccess access) { support.initializeAtBuildTime("org.bouncycastle", "security provider"); support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$Default", "RNG"); support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$NonceAndIV", "RNG"); + // Force provider mappings to be initialized during image generation without registering BC + // globally at runtime startup. + new BouncyCastleProvider().getServices(); } } diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleSupportImpl.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleSupportImpl.java index 6b0c1cfb46..3c5ad556fa 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleSupportImpl.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleSupportImpl.java @@ -48,6 +48,7 @@ import java.security.PrivateKey; import java.security.Provider; import java.security.Security; +import java.security.Signature; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -75,8 +76,8 @@ private static Provider getProvider() { @Override public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException { + Provider provider = getProvider(); try (PEMParser pemParser = new PEMParser(new StringReader(pemText))) { - Provider provider = getProvider(); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(provider); Object object; while ((object = pemParser.readObject()) != null) { @@ -113,4 +114,9 @@ public PrivateKey loadPrivateKey(char[] password, String pemText) throws IOExcep public MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException { return MessageDigest.getInstance(algorithm, getProvider()); } + + @Override + public Signature createSignature(String algorithm) throws NoSuchAlgorithmException { + return Signature.getInstance(algorithm, getProvider()); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java index 2638f53153..98eca6f85d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java @@ -936,6 +936,9 @@ private static boolean checkPrivateKey(String signatureAlgorithm, PrivateKey pri } } } + if (checkPrivateKeyWithBouncyCastle(signatureAlgorithm, privateKey, publicKey, data)) { + return true; + } return checkPrivateKey(signatureAlgorithm, (Provider) null, privateKey, publicKey, data); } @@ -954,6 +957,20 @@ private static boolean checkPrivateKey(String signatureAlgorithm, Provider provi } } + private static boolean checkPrivateKeyWithBouncyCastle(String signatureAlgorithm, PrivateKey privateKey, PublicKey publicKey, byte[] data) throws NoSuchAlgorithmException, SignatureException { + try { + Signature signature = BouncyCastleSupportProvider.createSignature(signatureAlgorithm); + signature.initSign(privateKey); + signature.update(data); + byte[] signed = signature.sign(); + signature.initVerify(publicKey); + signature.update(data); + return signature.verify(signed); + } catch (InvalidKeyException e) { + return false; + } + } + @TruffleBoundary static Collection generateCertificates(byte[] bytes) throws CertificateException { // test_load_verify_cadata appends an extra byte to a valid certificate and expects diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupport.java index 6bb97ee3f2..3db586ef22 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupport.java @@ -45,6 +45,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.Signature; import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException; @@ -52,4 +53,6 @@ public interface BouncyCastleSupport { PrivateKey loadPrivateKey(char[] password, String pemText) throws IOException, NeedsPasswordException, GeneralSecurityException; MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException; + + Signature createSignature(String algorithm) throws NoSuchAlgorithmException; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupportProvider.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupportProvider.java index 9b29f713e2..dc904d9af7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupportProvider.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/crypto/BouncyCastleSupportProvider.java @@ -45,6 +45,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.Signature; import java.util.Iterator; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; @@ -71,6 +72,16 @@ public static MessageDigest createDigest(String algorithm) throws NoSuchAlgorith } } + public static Signature createSignature(String algorithm) throws NoSuchAlgorithmException { + try { + return getSupport().createSignature(algorithm); + } catch (MissingBouncyCastleException e) { + NoSuchAlgorithmException wrapped = new NoSuchAlgorithmException(algorithm + " Signature not available"); + wrapped.initCause(e); + throw wrapped; + } + } + private static BouncyCastleSupport getSupport() throws MissingBouncyCastleException { Throwable failure = null; try { From c29cab6209f8f970cc45a4e6038f80d145b6ed8c Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Fri, 17 Apr 2026 10:40:27 +0200 Subject: [PATCH 43/43] Fix BC usage in native images --- .../python-bouncycastle/native-image.properties | 2 +- .../graal/python/bouncycastle/BouncyCastleFeature.java | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties index 8292f15daa..13a0ad90d1 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/META-INF/native-image/org.graalvm.python/python-bouncycastle/native-image.properties @@ -1,2 +1,2 @@ # Additional native-image arguments for optional GraalPy BouncyCastle support -Args = --features=com.oracle.graal.python.bouncycastle.BouncyCastleFeature -H:AdditionalSecurityProviders=org.bouncycastle.jce.provider.BouncyCastleProvider +Args = --features=com.oracle.graal.python.bouncycastle.BouncyCastleFeature diff --git a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java index 38d78e7b49..e659675a35 100644 --- a/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python.bouncycastle/src/com/oracle/graal/python/bouncycastle/BouncyCastleFeature.java @@ -40,6 +40,8 @@ */ package com.oracle.graal.python.bouncycastle; +import java.security.Security; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; @@ -52,8 +54,8 @@ public void afterRegistration(AfterRegistrationAccess access) { support.initializeAtBuildTime("org.bouncycastle", "security provider"); support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$Default", "RNG"); support.initializeAtRunTime("org.bouncycastle.jcajce.provider.drbg.DRBG$NonceAndIV", "RNG"); - // Force provider mappings to be initialized during image generation without registering BC - // globally at runtime startup. - new BouncyCastleProvider().getServices(); + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } } }