11package io .quarkus .security .runtime .graal ;
22
3+ import java .security .Provider ;
34import java .security .SecureRandom ;
5+ import java .security .Security ;
46import java .util .Arrays ;
57import java .util .Set ;
68import java .util .function .BooleanSupplier ;
911import com .oracle .svm .core .annotate .Alias ;
1012import com .oracle .svm .core .annotate .RecomputeFieldValue ;
1113
14+ import io .quarkus .security .runtime .SecurityProviderUtils ;
15+
1216final class BouncyCastlePackages {
1317 static final String ORG_BOUNCYCASTLE_CRYPTO_PACKAGE = "org.bouncycastle.crypto" ;
1418 static final String ORG_BOUNCYCASTLE_CRYPTO_FIPS_PACKAGE = "org.bouncycastle.crypto.fips" ;
1519 static final String ORG_BOUNCYCASTLE_CRYPTO_INTERNAL_PACKAGE = "org.bouncycastle.crypto.internal" ;
1620 static final String ORG_BOUNCYCASTLE_CRYPTO_GENERAL_PACKAGE = "org.bouncycastle.crypto.general" ;
21+ static final String ORG_BOUNCYCASTLE_OPENSSL_PACKAGE = "org.bouncycastle.openssl" ;
1722 static final Set <String > PACKAGES = Arrays .asList (Package .getPackages ()).stream ()
18- .map (p -> p .getName ()).filter (p -> p .startsWith (ORG_BOUNCYCASTLE_CRYPTO_PACKAGE )).collect (Collectors .toSet ());
23+ .map (Package ::getName )
24+ .filter (p -> p .startsWith (ORG_BOUNCYCASTLE_CRYPTO_PACKAGE ) || p .startsWith (ORG_BOUNCYCASTLE_OPENSSL_PACKAGE ))
25+ .collect (Collectors .toSet ());
1926}
2027
2128@ com .oracle .svm .core .annotate .TargetClass (className = "org.bouncycastle.crypto.general.DSA$1" , onlyWith = BouncyCastleCryptoGeneral .class )
@@ -104,6 +111,59 @@ final class Target_org_bouncycastle_math_ec_ECPoint {
104111 private static SecureRandom testRandom ;
105112}
106113
114+ // TODO: this should be removed when https://github.com/netty/netty/issues/14826 is addressed
115+ // this substitution can be removed when io.quarkus.it.bouncycastle.BouncyCastleITCase#loadNettySslContext passes
116+ @ com .oracle .svm .core .annotate .TargetClass (className = "io.netty.handler.ssl.BouncyCastlePemReader" , onlyWith = NettySslBountyCastleSupportRequired .class )
117+ final class Target_io_netty_handler_ssl_BouncyCastlePemReader {
118+ @ Alias
119+ private static volatile Provider bcProvider ;
120+ @ Alias
121+ private static volatile boolean attemptedLoading ;
122+ @ Alias
123+ private static volatile Throwable unavailabilityCause ;
124+
125+ @ com .oracle .svm .core .annotate .Substitute
126+ public static boolean isAvailable () {
127+ if (!attemptedLoading ) {
128+ // do what io.netty.handler.ssl.BouncyCastlePemReader.tryLoading does
129+ // however Netty creates a new provider instance that doesn't have all the services
130+ // while we take already created provider with all registered services
131+ bcProvider = Security .getProvider (SecurityProviderUtils .BOUNCYCASTLE_PROVIDER_NAME );
132+ if (bcProvider == null ) {
133+ bcProvider = Security .getProvider (SecurityProviderUtils .BOUNCYCASTLE_FIPS_PROVIDER_NAME );
134+ }
135+ if (bcProvider == null ) {
136+ tryLoading ();
137+ } else {
138+ attemptedLoading = true ;
139+ }
140+ }
141+ return unavailabilityCause == null ;
142+ }
143+
144+ @ Alias
145+ private static void tryLoading () {
146+
147+ }
148+ }
149+
150+ class NettySslBountyCastleSupportRequired implements BooleanSupplier {
151+ @ Override
152+ public boolean getAsBoolean () {
153+ // this package is used by the BouncyCastlePemReader and present in 'org.bouncycastle:bcpkix-jdk18on'
154+ if (BouncyCastlePackages .PACKAGES .contains (BouncyCastlePackages .ORG_BOUNCYCASTLE_OPENSSL_PACKAGE )) {
155+ try {
156+ Class .forName ("io.netty.handler.ssl.BouncyCastlePemReader" , false ,
157+ Thread .currentThread ().getContextClassLoader ());
158+ return true ;
159+ } catch (Throwable e ) {
160+ // class not available
161+ }
162+ }
163+ return false ;
164+ }
165+ }
166+
107167class BouncyCastleCryptoFips implements BooleanSupplier {
108168 @ Override
109169 public boolean getAsBoolean () {
@@ -123,4 +183,4 @@ class BouncyCastleCryptoInternal implements BooleanSupplier {
123183 public boolean getAsBoolean () {
124184 return BouncyCastlePackages .PACKAGES .contains (BouncyCastlePackages .ORG_BOUNCYCASTLE_CRYPTO_INTERNAL_PACKAGE );
125185 }
126- }
186+ }
0 commit comments