Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide API to create bcrypt hash and salt #5113

Closed
gnunn1 opened this issue Nov 1, 2019 · 23 comments
Closed

Provide API to create bcrypt hash and salt #5113

gnunn1 opened this issue Nov 1, 2019 · 23 comments
Labels
area/security kind/enhancement New feature or request triage/wontfix This will not be worked on

Comments

@gnunn1
Copy link

gnunn1 commented Nov 1, 2019

Description
Quarkus provides a bcrypt password mapper for the elyton JDBC security provider but doesn't appear to offer a way to create a bcrypt salt and hash thus limiting it's usefulness. It is possible to do this using JARs from Wildfly however they will not compile natively.

Example using code from Wildfly, pom.xml:

    <dependency>
      <groupId>org.wildfly.security</groupId>
      <artifactId>wildfly-elytron-credential</artifactId>
      <version>1.10.3.Final</version>
    </dependency>

Code:

    public void setPasswordHash(String password) {
        byte[] salt = generateRandomSalt(BCRYPT_SALT_SIZE);
        int iterationCount = 10;

        try {
            PasswordFactory factory = PasswordFactory.getInstance(ALGORITHM_BCRYPT);
            BCryptPassword bCryptPassword = (BCryptPassword) factory.generatePassword(
                    new EncryptablePasswordSpec(password.toCharArray(), new IteratedSaltedPasswordAlgorithmSpec(iterationCount, salt))
            );
            this.passwordHash = Base64.getEncoder().encodeToString(bCryptPassword.getHash());
            this.salt = Base64.getEncoder().encodeToString(bCryptPassword.getSalt());
            this.iterations = bCryptPassword.getIterationCount();
            log.info("hash: " + this.passwordHash + ", salt:" + this.salt + ", iterations:" + this.iterations );
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("Password encryption failed, invalid key spec", e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Password encryption failed, no such algorithm", e);
        }
    }

    private static byte[] generateRandomSalt(int saltSize) {
        byte[] randomSalt = new byte[saltSize];
        ThreadLocalRandom.current().nextBytes(randomSalt);
        return randomSalt;
    }
@gnunn1 gnunn1 added the kind/enhancement New feature or request label Nov 1, 2019
@sberyozkin
Copy link
Member

@danielpetisme Hi Daniel, if you can find some time to check this one then it would be nice

@dmlloyd
Copy link
Member

dmlloyd commented Nov 1, 2019

It is possible to do this using JARs from Wildfly however they will not compile natively.

What do you mean by "they will not compile natively"? Is native image generation failing with these JARs, or...?

@gnunn1
Copy link
Author

gnunn1 commented Nov 1, 2019

Yes, native image generation is failing, below is full output:

mvn package -Pnative
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< com.redhat.demo:product-catalog >-------------------
[INFO] Building product-catalog 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ product-catalog ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ product-catalog ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ product-catalog ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/gnunn/Development/quarkus/quarkus-product-catalog/server/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ product-catalog ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.0:test (default-test) @ product-catalog ---
[INFO] No tests to run.
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ product-catalog ---
[INFO] Building jar: /home/gnunn/Development/quarkus/quarkus-product-catalog/server/target/product-catalog-1.0-SNAPSHOT.jar
[INFO] 
[INFO] --- quarkus-maven-plugin:0.25.0:build (default) @ product-catalog ---
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Beginning quarkus augmentation
[INFO] [org.jboss.threads] JBoss Threads version 3.0.0.Final
[INFO] [org.hibernate.jpa.boot.internal.PersistenceXmlParser] HHH000318: Could not find any META-INF/persistence.xml file in the classpath
[INFO] [org.hibernate.Version] HHH000412: Hibernate Core {5.4.6.Final}
[INFO] [io.quarkus.resteasy] Resteasy running without servlet container.
[INFO] [io.quarkus.resteasy] - Add quarkus-undertow to run Resteasy within a servlet container
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 1520ms
[INFO] [org.hibernate.bytecode.enhance.internal.bytebuddy.BiDirectionalAssociationHandler] Could not find bi-directional association for field [com.redhat.demo.model.Product#category]
[INFO] [io.quarkus.creator.phase.runnerjar.RunnerJarPhase] Building jar: /home/gnunn/Development/quarkus/quarkus-product-catalog/server/target/product-catalog-1.0-SNAPSHOT-runner.jar
[INFO] 
[INFO] --- quarkus-maven-plugin:0.25.0:native-image (default) @ product-catalog ---
[INFO] [io.quarkus.creator.phase.nativeimage.NativeImagePhase] Running Quarkus native-image plugin on OpenJDK 64-Bit Server VM
[INFO] [io.quarkus.creator.phase.nativeimage.NativeImagePhase] /opt/graalvm-ce-19.2.0.1/bin/native-image -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -J-Dio.netty.leakDetection.level=DISABLED -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Dio.netty.allocator.maxOrder=1 -J-Dvertx.disableDnsResolver=true --initialize-at-build-time= -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -jar product-catalog-1.0-SNAPSHOT-runner.jar -J-Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -H:+PrintAnalysisCallTree -H:-AddAllCharsets -H:EnableURLProtocols=http,https --enable-all-security-services -H:NativeLinkerOption=-no-pie -H:+JNI --no-server -H:-UseServiceLoaderFeature -H:+StackTrace
[product-catalog-1.0-SNAPSHOT-runner:10258]    classlist:  10,009.35 ms
[product-catalog-1.0-SNAPSHOT-runner:10258]        (cap):   1,168.96 ms
[product-catalog-1.0-SNAPSHOT-runner:10258]        setup:   3,216.06 ms
08:42:58,892 INFO  [org.hib.Version] HHH000412: Hibernate Core {5.4.6.Final}
08:42:58,924 INFO  [org.hib.ann.com.Version] HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
08:42:58,962 INFO  [org.hib.dia.Dialect] HHH000400: Using dialect: org.hibernate.dialect.MariaDB103Dialect
08:42:59,022 INFO  [org.hib.val.int.uti.Version] HV000001: Hibernate Validator 6.1.0.Alpha6
08:43:00,754 INFO  [org.jbo.threads] JBoss Threads version 3.0.0.Final
08:43:01,687 INFO  [com.arj.ats.arjuna] ARJUNA012170: TransactionStatusManager started on port 35555 and host 127.0.0.1 with service com.arjuna.ats.arjuna.recovery.ActionStatusService
[product-catalog-1.0-SNAPSHOT-runner:10258]     analysis:  26,263.09 ms
Printing call tree to /home/gnunn/Development/quarkus/quarkus-product-catalog/server/target/reports/call_tree_product-catalog-1.0-SNAPSHOT-runner_20191101_084333.txt
Printing list of used classes to /home/gnunn/Development/quarkus/quarkus-product-catalog/server/target/reports/used_classes_product-catalog-1.0-SNAPSHOT-runner_20191101_084336.txt
Printing list of used packages to /home/gnunn/Development/quarkus/quarkus-product-catalog/server/target/reports/used_packages_product-catalog-1.0-SNAPSHOT-runner_20191101_084336.txt
Error: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved method during parsing: char[].clone(). To diagnose the issue you can use the --allow-incomplete-classpath option. The missing method is then reported at run time when it is accessed the first time.
Detailed message:
Trace: 
	at parsing org.wildfly.security.password.interfaces.MaskedPassword.createRaw(MaskedPassword.java:224)
Call path from entry point to org.wildfly.security.password.interfaces.MaskedPassword.createRaw(String, char[], int, byte[], byte[], byte[]): 
	at org.wildfly.security.password.interfaces.MaskedPassword.createRaw(MaskedPassword.java:220)
	at org.wildfly.security.password.util.ModularCrypt.parseMaskedPasswordString(ModularCrypt.java:697)
	at org.wildfly.security.password.util.ModularCrypt.decode(ModularCrypt.java:356)
	at org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper.map(PasswordKeyMapper.java:258)
	at org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.getIdentity(JdbcSecurityRealm.java:229)
	at org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.verifyEvidence(JdbcSecurityRealm.java:175)
	at org.wildfly.security.auth.server.ServerAuthenticationContext$NameAssignedState.verifyEvidence(ServerAuthenticationContext.java:1978)
	at org.wildfly.security.auth.server.ServerAuthenticationContext.verifyEvidence(ServerAuthenticationContext.java:759)
	at org.wildfly.security.auth.server.SecurityDomain.authenticate(SecurityDomain.java:309)
	at org.wildfly.security.auth.server.SecurityDomain.authenticate(SecurityDomain.java:285)
	at io.quarkus.elytron.security.runtime.ElytronPasswordIdentityProvider$1.get(ElytronPasswordIdentityProvider.java:48)
	at io.quarkus.elytron.security.runtime.ElytronPasswordIdentityProvider$1.get(ElytronPasswordIdentityProvider.java:43)
	at io.quarkus.security.runtime.QuarkusIdentityProviderManagerImpl$AsyncAuthenticationRequestContext$1.run(QuarkusIdentityProviderManagerImpl.java:229)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:460)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
	at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)
--------------------------------------------------------------------------------------------
-- WARNING: The above stack trace is not a real stack trace, it is a theoretical call tree---
-- If an interface has multiple implementations SVM will just display one potential call  ---
-- path to the interface. This is often meaningless, and what you actually need to know is---
-- the path to the constructor of the object that implements this interface.              ---
-- Quarkus has attempted to generate a more meaningful call flow analysis below          ---
---------------------------------------------------------------------------------------------

Possible path to org.wildfly.security.password.interfaces.MaskedPassword.createRaw(java.lang.String, char[], int, byte[], byte[], byte[]):o
	org.wildfly.security.password.interfaces.MaskedPassword.createRaw(java.lang.String, char[], int, byte[], byte[], byte[]):o
	org.wildfly.security.password.util.ModularCrypt.parseMaskedPasswordString(char[]):o
	org.wildfly.security.password.util.ModularCrypt.decode(char[]):o
	org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper.map(java.sql.ResultSet, java.util.function.Supplier):o
	org.wildfly.security.auth.realm.jdbc.KeyMapper.map(java.sql.ResultSet, java.util.function.Supplier):o
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.getIdentity():o
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.verifyEvidence(org.wildfly.security.evidence.Evidence):b
This is an implementation of org.wildfly.security.auth.server.RealmIdentity printing path to constructors of org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity


Possible path to org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.<init>(org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm, java.lang.String):v
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.<init>(org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm, java.lang.String):v
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm.getRealmIdentity(java.security.Principal):o
	org.wildfly.security.auth.server.SecurityRealm.getRealmIdentity(java.security.Principal):o
	org.wildfly.security.auth.server.SecurityRealm.getRealmIdentity(org.wildfly.security.evidence.Evidence):o
This is an implementation of org.wildfly.security.auth.server.SecurityRealm printing path to constructors of org.wildfly.security.auth.server.SecurityRealm




com.oracle.svm.core.util.UserError$UserException: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved method during parsing: char[].clone(). To diagnose the issue you can use the --allow-incomplete-classpath option. The missing method is then reported at run time when it is accessed the first time.
Detailed message:
Trace: 
	at parsing org.wildfly.security.password.interfaces.MaskedPassword.createRaw(MaskedPassword.java:224)
Call path from entry point to org.wildfly.security.password.interfaces.MaskedPassword.createRaw(String, char[], int, byte[], byte[], byte[]): 
	at org.wildfly.security.password.interfaces.MaskedPassword.createRaw(MaskedPassword.java:220)
	at org.wildfly.security.password.util.ModularCrypt.parseMaskedPasswordString(ModularCrypt.java:697)
	at org.wildfly.security.password.util.ModularCrypt.decode(ModularCrypt.java:356)
	at org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper.map(PasswordKeyMapper.java:258)
	at org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.getIdentity(JdbcSecurityRealm.java:229)
	at org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.verifyEvidence(JdbcSecurityRealm.java:175)
	at org.wildfly.security.auth.server.ServerAuthenticationContext$NameAssignedState.verifyEvidence(ServerAuthenticationContext.java:1978)
	at org.wildfly.security.auth.server.ServerAuthenticationContext.verifyEvidence(ServerAuthenticationContext.java:759)
	at org.wildfly.security.auth.server.SecurityDomain.authenticate(SecurityDomain.java:309)
	at org.wildfly.security.auth.server.SecurityDomain.authenticate(SecurityDomain.java:285)
	at io.quarkus.elytron.security.runtime.ElytronPasswordIdentityProvider$1.get(ElytronPasswordIdentityProvider.java:48)
	at io.quarkus.elytron.security.runtime.ElytronPasswordIdentityProvider$1.get(ElytronPasswordIdentityProvider.java:43)
	at io.quarkus.security.runtime.QuarkusIdentityProviderManagerImpl$AsyncAuthenticationRequestContext$1.run(QuarkusIdentityProviderManagerImpl.java:229)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:460)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
	at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)
--------------------------------------------------------------------------------------------
-- WARNING: The above stack trace is not a real stack trace, it is a theoretical call tree---
-- If an interface has multiple implementations SVM will just display one potential call  ---
-- path to the interface. This is often meaningless, and what you actually need to know is---
-- the path to the constructor of the object that implements this interface.              ---
-- Quarkus has attempted to generate a more meaningful call flow analysis below          ---
---------------------------------------------------------------------------------------------

Possible path to org.wildfly.security.password.interfaces.MaskedPassword.createRaw(java.lang.String, char[], int, byte[], byte[], byte[]):o
	org.wildfly.security.password.interfaces.MaskedPassword.createRaw(java.lang.String, char[], int, byte[], byte[], byte[]):o
	org.wildfly.security.password.util.ModularCrypt.parseMaskedPasswordString(char[]):o
	org.wildfly.security.password.util.ModularCrypt.decode(char[]):o
	org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper.map(java.sql.ResultSet, java.util.function.Supplier):o
	org.wildfly.security.auth.realm.jdbc.KeyMapper.map(java.sql.ResultSet, java.util.function.Supplier):o
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.getIdentity():o
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.verifyEvidence(org.wildfly.security.evidence.Evidence):b
This is an implementation of org.wildfly.security.auth.server.RealmIdentity printing path to constructors of org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity


Possible path to org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.<init>(org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm, java.lang.String):v
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.<init>(org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm, java.lang.String):v
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm.getRealmIdentity(java.security.Principal):o
	org.wildfly.security.auth.server.SecurityRealm.getRealmIdentity(java.security.Principal):o
	org.wildfly.security.auth.server.SecurityRealm.getRealmIdentity(org.wildfly.security.evidence.Evidence):o
This is an implementation of org.wildfly.security.auth.server.SecurityRealm printing path to constructors of org.wildfly.security.auth.server.SecurityRealm




	at com.oracle.svm.core.util.UserError.abort(UserError.java:75)
	at com.oracle.svm.hosted.FallbackFeature.reportAsFallback(FallbackFeature.java:223)
	at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:737)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:526)
	at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:444)
	at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved method during parsing: char[].clone(). To diagnose the issue you can use the --allow-incomplete-classpath option. The missing method is then reported at run time when it is accessed the first time.
Detailed message:
Trace: 
	at parsing org.wildfly.security.password.interfaces.MaskedPassword.createRaw(MaskedPassword.java:224)
Call path from entry point to org.wildfly.security.password.interfaces.MaskedPassword.createRaw(String, char[], int, byte[], byte[], byte[]): 
	at org.wildfly.security.password.interfaces.MaskedPassword.createRaw(MaskedPassword.java:220)
	at org.wildfly.security.password.util.ModularCrypt.parseMaskedPasswordString(ModularCrypt.java:697)
	at org.wildfly.security.password.util.ModularCrypt.decode(ModularCrypt.java:356)
	at org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper.map(PasswordKeyMapper.java:258)
	at org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.getIdentity(JdbcSecurityRealm.java:229)
	at org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.verifyEvidence(JdbcSecurityRealm.java:175)
	at org.wildfly.security.auth.server.ServerAuthenticationContext$NameAssignedState.verifyEvidence(ServerAuthenticationContext.java:1978)
	at org.wildfly.security.auth.server.ServerAuthenticationContext.verifyEvidence(ServerAuthenticationContext.java:759)
	at org.wildfly.security.auth.server.SecurityDomain.authenticate(SecurityDomain.java:309)
	at org.wildfly.security.auth.server.SecurityDomain.authenticate(SecurityDomain.java:285)
	at io.quarkus.elytron.security.runtime.ElytronPasswordIdentityProvider$1.get(ElytronPasswordIdentityProvider.java:48)
	at io.quarkus.elytron.security.runtime.ElytronPasswordIdentityProvider$1.get(ElytronPasswordIdentityProvider.java:43)
	at io.quarkus.security.runtime.QuarkusIdentityProviderManagerImpl$AsyncAuthenticationRequestContext$1.run(QuarkusIdentityProviderManagerImpl.java:229)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:460)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
	at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)
--------------------------------------------------------------------------------------------
-- WARNING: The above stack trace is not a real stack trace, it is a theoretical call tree---
-- If an interface has multiple implementations SVM will just display one potential call  ---
-- path to the interface. This is often meaningless, and what you actually need to know is---
-- the path to the constructor of the object that implements this interface.              ---
-- Quarkus has attempted to generate a more meaningful call flow analysis below          ---
---------------------------------------------------------------------------------------------

Possible path to org.wildfly.security.password.interfaces.MaskedPassword.createRaw(java.lang.String, char[], int, byte[], byte[], byte[]):o
	org.wildfly.security.password.interfaces.MaskedPassword.createRaw(java.lang.String, char[], int, byte[], byte[], byte[]):o
	org.wildfly.security.password.util.ModularCrypt.parseMaskedPasswordString(char[]):o
	org.wildfly.security.password.util.ModularCrypt.decode(char[]):o
	org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper.map(java.sql.ResultSet, java.util.function.Supplier):o
	org.wildfly.security.auth.realm.jdbc.KeyMapper.map(java.sql.ResultSet, java.util.function.Supplier):o
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.getIdentity():o
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.verifyEvidence(org.wildfly.security.evidence.Evidence):b
This is an implementation of org.wildfly.security.auth.server.RealmIdentity printing path to constructors of org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity


Possible path to org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.<init>(org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm, java.lang.String):v
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm$JdbcRealmIdentity.<init>(org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm, java.lang.String):v
	org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm.getRealmIdentity(java.security.Principal):o
	org.wildfly.security.auth.server.SecurityRealm.getRealmIdentity(java.security.Principal):o
	org.wildfly.security.auth.server.SecurityRealm.getRealmIdentity(org.wildfly.security.evidence.Evidence):o
This is an implementation of org.wildfly.security.auth.server.SecurityRealm printing path to constructors of org.wildfly.security.auth.server.SecurityRealm




	at com.oracle.graal.pointsto.constraints.UnsupportedFeatures.report(UnsupportedFeatures.java:130)
	at com.oracle.graal.pointsto.BigBang.finish(BigBang.java:565)
	at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:688)
	... 7 more
Caused by: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved method during parsing: char[].clone(). To diagnose the issue you can use the --allow-incomplete-classpath option. The missing method is then reported at run time when it is accessed the first time.
	at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.reportUnresolvedElement(SharedGraphBuilderPhase.java:238)
	at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedMethod(SharedGraphBuilderPhase.java:228)
	at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedInvoke(SharedGraphBuilderPhase.java:182)
	at org.graalvm.compiler.java.BytecodeParser.genInvokeVirtual(BytecodeParser.java:1612)
	at org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5123)
	at org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3267)
	at org.graalvm.compiler.java.BytecodeParser.processBlock(BytecodeParser.java:3074)
	at org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:976)
	at org.graalvm.compiler.java.BytecodeParser.buildRootMethod(BytecodeParser.java:870)
	at org.graalvm.compiler.java.GraphBuilderPhase$Instance.run(GraphBuilderPhase.java:84)
	at org.graalvm.compiler.phases.Phase.run(Phase.java:49)
	at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:197)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:42)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:38)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:221)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:340)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.doParse(MethodTypeFlow.java:310)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureParsed(MethodTypeFlow.java:300)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.addContext(MethodTypeFlow.java:107)
	at com.oracle.graal.pointsto.flow.StaticInvokeTypeFlow.update(InvokeTypeFlow.java:346)
	at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:510)
	at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:171)
	at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
	... 4 more
Error: Image build request failed with exit status 1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  59.852 s
[INFO] Finished at: 2019-11-01T08:43:39-04:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:0.25.0:native-image (default) on project product-catalog: Failed to generate a native image: Failed to build native image: Image generation failed -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

@dmlloyd
Copy link
Member

dmlloyd commented Nov 1, 2019

Ah! I can't believe this bug isn't fixed yet in GraalVM. I'll make a note of it.

@pedroigor
Copy link
Contributor

@dmlloyd is this issue related ?

@dmlloyd
Copy link
Member

dmlloyd commented Nov 1, 2019

Yes I think that's the same issue.

@danielpetisme
Copy link
Contributor

I do agree with @gnunn1 without a way to generate bcrypted password the usage of the bcrypt-mapper is limited.
It looks we are stuck because of a graal issue and personally I can't event think of a resolution date (are we talking about days or months).
As for now, the option I can see are
1- Clearly mention in the Quarkus Elytron JDBC doc that bcrypt is not supported yet and reference this issue.
2- Contribute with a fix to graal (thing I don't feel competent enough to do)
3- Find another Graal-friendly Bcrypt lib

Thoughts?

@dmlloyd
Copy link
Member

dmlloyd commented Nov 5, 2019

The short-term fix would be to @Substitute the clone call with Arrays.copyOf.

@FroMage
Copy link
Member

FroMage commented Nov 19, 2019

I've been using this one in prod for years: https://github.com/jeremyh/jBCrypt/blob/master/src/main/java/org/mindrot/BCrypt.java

Probably it compiles to native, due to not using exotic stuff?

@dmlloyd
Copy link
Member

dmlloyd commented Nov 19, 2019

I don't think char[].clone() is considered exotic. :)

@FroMage
Copy link
Member

FroMage commented Nov 19, 2019

Ah, I didn't look properly :)

@FroMage
Copy link
Member

FroMage commented Nov 21, 2019

Actually, for #5660 I need more than this, I need a real Modular Crypt Format implementation to get all iteration/salt/hash in one standard bCrypt string, as documented in https://en.wikipedia.org/wiki/Bcrypt

@FroMage
Copy link
Member

FroMage commented Nov 21, 2019

Generally, I think our security extensions simply lack support for MCF encoding and always separate the parts, which is less than ideal. I'll open an issue around that.

@dmlloyd
Copy link
Member

dmlloyd commented Nov 21, 2019

The Elytron password library has complete support for MCF.

@FroMage
Copy link
Member

FroMage commented Nov 21, 2019

Done: #5667

@FroMage
Copy link
Member

FroMage commented Nov 21, 2019

@FroMage
Copy link
Member

FroMage commented Nov 21, 2019

OK, fine, it works great :)

@t1m0
Copy link

t1m0 commented Dec 25, 2019

Hi,
is there any update on this?
I tried elytron-security-jdbc and noticed there is no bean for the password generation.

Is the plan to include this as part of a future update in this module?
Or should I use the above mentioned wildfly-elytron-credential for this?

(I'm not planning to build a native image as of now)

@dmlloyd
Copy link
Member

dmlloyd commented Feb 21, 2020

FYI the upstream bug relating to char[].clone() has finally been fixed: oracle/graal#877 (comment)

@emmanuelbernard
Copy link
Member

@dmlloyd does that mean we can close this one?

@emmanuelbernard emmanuelbernard added the triage/consider-closing Bugs that are considered to be closed because too old. Using the label to do a mark and sweep proces label Apr 1, 2020
@dmlloyd
Copy link
Member

dmlloyd commented Apr 1, 2020

I think so.

@emmanuelbernard emmanuelbernard removed the triage/consider-closing Bugs that are considered to be closed because too old. Using the label to do a mark and sweep proces label Apr 1, 2020
@gsmet gsmet added the triage/wontfix This will not be worked on label Apr 7, 2020
@mahieddine
Copy link
Contributor

Unfortunately on my side i had another error when compiling to native (quarkus 1.10.5.Final), if i remove my code and the dependency it compiles without any error. I also tried to include wildfly-common but still having the same issue

building quarkus jar

20.1-java11: Pulling from quarkus/ubi-quarkus-mandrel
Digest: sha256:dddfeccc1a147b3c423325274d023d75486b0042033e040d196b2ba3a0260b2f
Status: Image is up to date for quay.io/quarkus/ubi-quarkus-mandrel:20.1-java11
quay.io/quarkus/ubi-quarkus-mandrel:20.1-java11
[test-service-0.1.0-SNAPSHOT-runner:52]    classlist:  56,576.56 ms,  0.93 GB
[test-service-0.1.0-SNAPSHOT-runner:52]        setup:   1,038.24 ms,  0.93 GB
Fatal error:java.lang.NoClassDefFoundError
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:603)
        at java.base/java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1006)
        at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:463)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:359)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:518)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:117)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:547)
**Caused by: java.lang.NoClassDefFoundError: org/wildfly/common/format/Printf**
        at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
        at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
        at java.base/java.lang.Class.getDeclaredMethod(Class.java:2473)
        at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.findOriginalMethod(AnnotationSubstitutionProcessor.java:624)
        at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.handleMethodInAliasClass(AnnotationSubstitutionProcessor.java:330)
        at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.handleAliasClass(AnnotationSubstitutionProcessor.java:302)
        at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.handleClass(AnnotationSubstitutionProcessor.java:274)
        at com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor.init(AnnotationSubstitutionProcessor.java:230)
        at com.oracle.svm.hosted.NativeImageGenerator.createDeclarativeSubstitutionProcessor(NativeImageGenerator.java:908)
        at com.oracle.svm.hosted.NativeImageGenerator.setupNativeImage(NativeImageGenerator.java:838)
        at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:536)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:451)
        at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: java.lang.ClassNotFoundException: org.wildfly.common.format.Printf
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        ... 18 more
Error: Image build request failed with exit status 1

@dmlloyd
Copy link
Member

dmlloyd commented Jan 4, 2021

You need to use version 1.5.4.Final-format-001 of wildfly-common. Some dependency has probably included a different unsupported version; the correct fix would be to exclude that dependency. Check mvn dependency:tree which might give a clue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/security kind/enhancement New feature or request triage/wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests