Open sberyozkin opened 3 years ago
@sberyozkin Actual behavior
final Provider prototype = Security.getProvider("SunPKCS11");
return prototype.configure("--" + configuration);
This function return null (exclusively with the native build)
How to Reproduce? Fot testing, I use SoftHSM2 ([Windows](choco install softhsm), Linux, Tutorial). Use this code to reproduce it:
final Provider prototype = Security.getProvider("SunPKCS11");
return prototype.configure("--" + configuration);
Example of configuration
name=SoftHSM2
library=D:\\Developpement\\prog\\SoftHSM2\\lib\\softhsm2-x64.dll
slotListIndex=0
description=JCA Provider for Datavault
Output of uname -a or ver
Linux FR-DEV-L-094 4.19.104-microsoft-standard #1 SMP Wed Feb 19 06:37:35 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
and
Windows 10 Pro 2004
Output of java -version
openjdk version "17" 2021-09-14
OpenJDK Runtime Environment Temurin-17+35 (build 17+35)
OpenJDK 64-Bit Server VM Temurin-17+35 (build 17+35, mixed mode, sharing)
GraalVM version (if different from Java)
openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment GraalVM CE 21.3.0 (build 17.0.1+12-jvmci-21.3-b05)
OpenJDK 64-Bit Server VM GraalVM CE 21.3.0 (build 17.0.1+12-jvmci-21.3-b05, mixed mode, sharing
Quarkus version or git rev
2.3.1.Final
Build tool (ie. output of mvnw --version or gradlew --version)
Apache Maven 3.8.3 (ff8e977a158738155dc465c6a97ffaf31982d739)
Additional information
@sberyozkin have you enough information?
@malys Thanks, this is sufficient, I think the problem is not confined to supporting this specific provider - if we can tune the code such that any 3rd party provider requiring no dedicated processing works in native then it will work for this provider as well
Hi Sorry to insist but have you found time to think about a solution? Is it possible to have some visibility about the priority of this fix because depending on your position, I will deliver jar or native file? Thanks @sberyozkin,
@malys Can you please try it with #25068 ?
I'll look at manually testing it with SoftHSM2
as well
I'm seeing https://github.com/oracle/graal/issues/2552 in native mode
@zakkak Hi Foivos, can you please comment on what can be done to avoid https://github.com/oracle/graal/issues/2552, see also #25068. This issue can be reproduced once #25068 is merged as follows:
brew install softhsm
. And then follow a linked tutorial to generate a config and replace there a token slot, if you install it with brew
then you should have something like this:name = SoftHSM
library = /home/linuxbrew/.linuxbrew/lib/softhsm/libsofthsm2.so
slot = <generated-slot-number-goes-here>
attributes(generate, *, *) = {
CKA_TOKEN = true
}
attributes(generate, CKO_CERTIFICATE, *) = {
CKA_PRIVATE = false
}
attributes(generate, CKO_PUBLIC_KEY, *) = {
CKA_PRIVATE = false
}
and then
quarkus.security.security-providers=SunPKCS11
and, in the endpoint code for now:
Provider configuredProvider = Security.getProvider("SunPKCS11").configure(pathToConfigFile);
Security.addProvider(configuredProvider);
will lead to https://github.com/oracle/graal/issues/2552.
Supporting it in native mode can make a difference for our FIPS story, likely to have providers like SunPKCS11-NSS-FIPS
configured. (#25068 makes it easy to do it at the config level but it won't work in native for now).
Have a look please when you get a chance, thanks
@zakkak FYI, just adding all the .pkcs11.wrapper
classes for Reflection did not help, I see from https://github.com/oracle/graal/issues/2552 (and linked PRs) that more has to be done, I wonder if we can optionally do something like that in Quarkus via an extra native build item such as requesting j2pkcs.so
be statically linked, etc. Ideally it would be done at the GraalVM level.
Also CC @galderz
Hi @sberyozkin, I was on vacation. Adding this to my todo list for next week!
@zakkak Hi Foivos, np at all, hope you've had a good time off; have a look please when you can have time, hopefully it can be an interesting issue to investigate
Hi @sberyozkin I finally got to have a look at this. And it indeed looks like something that needs to be solved on the GraalVM side.
It looks like someone already tried fixing the underlying issue in https://github.com/oracle/graal/pull/3625 but the PR slipped through the cracks... I took that branch and rebased it on the latest graal (see https://github.com/zakkak/mandrel/tree/pkcs11) and ran the above test. I confirm that it gets past the linkage error but I am now getting:
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_GENERAL_ERROR
at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_VARARGS_PKCS11Exception_constructor_6117b76b7b85ffaea12ee4430bf7e4d602688744(JNIJavaCallWrappers.java:0)
at sun.security.pkcs11.wrapper.PKCS11.C_Initialize(PKCS11.java)
at sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.C_Initialize(PKCS11.java:1631)
at sun.security.pkcs11.wrapper.PKCS11.getInstance(PKCS11.java:166)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:338)
... 35 more
Since I am not familiar with any of these I would prefer you or someone more familiar continuing the investigation.
To build graal from my branch you will need to run:
git clone https://github.com/graalvm/mx --depth 1
./mx/mx fetch-jdk
export JAVA_HOME=<path-indicated-by-the-above-command>
git clone https://github.com/zakkak/nandrel --depth 1 --branch pkcs11
cd graal
mx --primary-suite-path substratevm --components='Native Image',LibGraal --native-images=native-image,lib:jvmcicompiler build
Then once the above is done you can use it to run your quarkus tests as follows:
GRAALVM_HOME=~/code/graal/sdk/latest_graalvm_home ./mvnw -Dnative -pl integration-tests/bouncycastle -Dtest-containers -Dstart-containers -Dnative.surefire.skip -Dformat.skip -Dno-descriptor-tests -Dlog.clean verify
Please let me know if there is anyway I can further help you with this.
Note: If you end up with a version you are happy with I can then follow up on getting https://github.com/oracle/graal/pull/3625 merged.
Hi @zakkak Thanks for looking into it. Apologies I missed the comment. I'm not familiar with the C-level implementation details of Soft HSM, but it looks like it is exactly this error which is what you are seeing
Can you please give me a favor and try to re-run with
-Djava.security.debug=sunpkcs11
- it may show some more info and also try setting an env SOFTHSM2_CONF
to the config path location ? And if that does not help, replace Security.getProvider("SunPKCS11").configure(pathToConfigFile);
with Security.getProvider("SunPKCS11").configure("--" + contentOfConfigFile);
?
Np at all if you won't have time, I can try it as some point as well.
Cheers
Can you please give me a favor and try to re-run with
-Djava.security.debug=sunpkcs11
- it may show some more info and also try setting an envSOFTHSM2_CONF
to the config path location ?
Same issue
And if that does not help, replace
Security.getProvider("SunPKCS11").configure(pathToConfigFile);
withSecurity.getProvider("SunPKCS11").configure("--" + contentOfConfigFile);
?
I am not sure how to do that given that the config file is multiline. Shall I just seperate key=value pairs by space?
I tried
diff --git a/integration-tests/bouncycastle/src/main/java/io/quarkus/it/bouncycastle/BouncyCastleEndpoint.java b/integration-tests/bouncycastle/src/main/java/io/quarkus/it/bouncycastle/BouncyCastleEndpoint.java
index 2fc5053943..8bdb1efb93 100644
--- a/integration-tests/bouncycastle/src/main/java/io/quarkus/it/bouncycastle/BouncyCastleEndpoint.java
+++ b/integration-tests/bouncycastle/src/main/java/io/quarkus/it/bouncycastle/BouncyCastleEndpoint.java
@@ -4,6 +4,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.Provider;
import java.security.Security;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
@@ -25,6 +26,21 @@ public class BouncyCastleEndpoint {
@GET
@Path("listProviders")
public String listProviders() {
+ Provider configuredProvider = Security.getProvider("SunPKCS11")
+ .configure("--name = SoftHSM\n" +
+ "library = /usr/lib64/softhsm/libsofthsm.so\n" +
+ "slot = 1423586702\n" +
+ "attributes(generate, *, *) = {\n" +
+ " CKA_TOKEN = true\n" +
+ "}\n" +
+ "attributes(generate, CKO_CERTIFICATE, *) = {\n" +
+ " CKA_PRIVATE = false\n" +
+ "}\n" +
+ "attributes(generate, CKO_PUBLIC_KEY, *) = {\n" +
+ " CKA_PRIVATE = false\n" +
+ "}\n");
+ Security.addProvider(configuredProvider);
+
return Arrays.asList(Security.getProviders()).stream()
.filter(p -> (p.getName().equals("BC") || p.getName().equals("SunPKCS11")))
.map(p -> p.getName()).collect(Collectors.joining(","));
with no luck.
@sberyozkin can you please have a look at ^^ to see if we can push this forward?
Thanks
@sberyozkin ^
@sberyozkin ^ :-)
Describe the bug
The current security provider registration code is limited in what it can do - it can only work for the default Sun providers which are already available - and it only registers them for reflection.
It does not work for providers like
sun.security.pkcs11.SunPKCS11
Expected behavior
When a new provider is registered it should be added as a security provider if it is not already available - additionally it should be registered as an additional security provider in native image
Actual behavior
No response
How to Reproduce?
No response
Output of
uname -a
orver
No response
Output of
java -version
No response
GraalVM version (if different from Java)
No response
Quarkus version or git rev
No response
Build tool (ie. output of
mvnw --version
orgradlew --version
)No response
Additional information
No response