From c0dc62540d40494f392bb252fc3a9e7938cb41a5 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Mon, 24 Jan 2022 16:56:34 +0000 Subject: [PATCH] Support BouncyCastle ECDSA KeyPairGenerator and AES/CBC/PKCS7Padding Cipher --- .../nativeimage/AutoFeatureAugmentor.java | 7 +++ ...iveImageAutoFeatureAugmentorBuildItem.java | 19 ++++++++ .../steps/NativeImageAutoFeatureStep.java | 7 +++ .../deployment/SecurityProcessor.java | 44 ++++++++++++++++++- .../bouncycastle/BouncyCastleJsseITCase.java | 2 - .../it/bouncycastle/BouncyCastleEndpoint.java | 16 +++++++ .../it/bouncycastle/BouncyCastleTestCase.java | 20 +++++++++ 7 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/AutoFeatureAugmentor.java create mode 100644 core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageAutoFeatureAugmentorBuildItem.java diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/AutoFeatureAugmentor.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/AutoFeatureAugmentor.java new file mode 100644 index 00000000000000..c7a9fdf9861965 --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/AutoFeatureAugmentor.java @@ -0,0 +1,7 @@ +package io.quarkus.deployment.builditem.nativeimage; + +import io.quarkus.gizmo.TryBlock; + +public interface AutoFeatureAugmentor { + void augment(TryBlock overallCatch); +} diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageAutoFeatureAugmentorBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageAutoFeatureAugmentorBuildItem.java new file mode 100644 index 00000000000000..0b5c5efb3e42f6 --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageAutoFeatureAugmentorBuildItem.java @@ -0,0 +1,19 @@ +package io.quarkus.deployment.builditem.nativeimage; + +import io.quarkus.builder.item.MultiBuildItem; +import io.quarkus.gizmo.TryBlock; + +/** + * A build item that can be used to augment the generated AutoFeature + */ +public final class NativeImageAutoFeatureAugmentorBuildItem extends MultiBuildItem { + AutoFeatureAugmentor autoFeatureAugmentor; + + public NativeImageAutoFeatureAugmentorBuildItem(AutoFeatureAugmentor autoFeatureAugmentor) { + this.autoFeatureAugmentor = autoFeatureAugmentor; + } + + public void augment(TryBlock overallCatch) { + autoFeatureAugmentor.augment(overallCatch); + } +} diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageAutoFeatureStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageAutoFeatureStep.java index 9e7a72807f66ef..7ad83d20a3b97d 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageAutoFeatureStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageAutoFeatureStep.java @@ -28,6 +28,7 @@ import io.quarkus.deployment.builditem.GeneratedResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.ForceNonWeakReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.JniRuntimeAccessBuildItem; +import io.quarkus.deployment.builditem.nativeimage.NativeImageAutoFeatureAugmentorBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem; @@ -114,6 +115,7 @@ void generateFeature(BuildProducer nativeIma List proxies, List resourcePatterns, List resourceBundles, + List augmentors, List reflectiveMethods, List reflectiveFields, List reflectiveClassBuildItems, @@ -337,6 +339,11 @@ public void write(String s, byte[] bytes) { //c.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), c.getCaughtException()); } } + + for (NativeImageAutoFeatureAugmentorBuildItem augmentor : augmentors) { + augmentor.augment(overallCatch); + } + int count = 0; final Map reflectiveClasses = new LinkedHashMap<>(); diff --git a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java index 657a8f65f898aa..179b446a2ab2f0 100644 --- a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java +++ b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java @@ -1,5 +1,7 @@ package io.quarkus.security.deployment; +import static io.quarkus.security.runtime.SecurityProviderUtils.findProviderIndex; + import java.io.IOException; import java.lang.reflect.Modifier; import java.net.MalformedURLException; @@ -42,12 +44,15 @@ import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.nativeimage.AutoFeatureAugmentor; import io.quarkus.deployment.builditem.nativeimage.JPMSExportBuildItem; +import io.quarkus.deployment.builditem.nativeimage.NativeImageAutoFeatureAugmentorBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem; import io.quarkus.gizmo.MethodDescriptor; import io.quarkus.gizmo.ResultHandle; +import io.quarkus.gizmo.TryBlock; import io.quarkus.runtime.RuntimeValue; import io.quarkus.security.runtime.IdentityProviderManagerCreator; import io.quarkus.security.runtime.SecurityBuildTimeConfig; @@ -149,10 +154,15 @@ private static void prepareBouncyCastleProvider(BuildProducer additionalProviders, + BuildProducer autoFeatureAugmentors, List bouncyCastleProviders, List bouncyCastleJsseProviders) { Optional bouncyCastleJsseProvider = getOne(bouncyCastleJsseProviders); if (bouncyCastleJsseProvider.isPresent()) { additionalProviders.produce( new NativeImageSecurityProviderBuildItem(SecurityProviderUtils.BOUNCYCASTLE_JSSE_PROVIDER_CLASS_NAME)); - final String providerName = bouncyCastleJsseProvider.get().isInFipsMode() + final String commonProviderName = bouncyCastleJsseProvider.get().isInFipsMode() ? SecurityProviderUtils.BOUNCYCASTLE_FIPS_PROVIDER_CLASS_NAME : SecurityProviderUtils.BOUNCYCASTLE_PROVIDER_CLASS_NAME; - additionalProviders.produce(new NativeImageSecurityProviderBuildItem(providerName)); + additionalProviders.produce(new NativeImageSecurityProviderBuildItem(commonProviderName)); + + autoFeatureAugmentors.produce(new NativeImageAutoFeatureAugmentorBuildItem(new AutoFeatureAugmentor() { + @Override + public void augment(TryBlock overallCatch) { + final int sunJsseIndex = findProviderIndex(SecurityProviderUtils.SUN_JSSE_PROVIDER_NAME); + + ResultHandle bcCommonProvider = overallCatch + .newInstance(MethodDescriptor.ofConstructor(commonProviderName)); + ResultHandle bcJsseProvider = overallCatch.newInstance( + MethodDescriptor.ofConstructor(SecurityProviderUtils.BOUNCYCASTLE_JSSE_PROVIDER_CLASS_NAME)); + + overallCatch.invokeStaticMethod( + MethodDescriptor.ofMethod(Security.class, "insertProviderAt", int.class, Provider.class, int.class), + bcCommonProvider, overallCatch.load(sunJsseIndex)); + overallCatch.invokeStaticMethod( + MethodDescriptor.ofMethod(Security.class, "insertProviderAt", int.class, Provider.class, int.class), + bcJsseProvider, overallCatch.load(sunJsseIndex + 1)); + } + })); } else { Optional bouncyCastleProvider = getOne(bouncyCastleProviders); if (bouncyCastleProvider.isPresent()) { @@ -239,6 +269,16 @@ void addBouncyCastleProvidersToNativeImage(BuildProducer