Get X509Certificates from smart card without authentication - java

I want to retrieve the list of X509Certificate from my smart card without logging in (without PIN).
My code is the following:
String conf = args[0];
Provider p = new sun.security.pkcs11.SunPKCS11(conf);
Security.addProvider(p);
KeyStore ks = KeyStore.getInstance("PKCS11");
1) ks.load(null, null);
2) ks.load(null, "".toCharArray());
The first test (1) fails with this StackTrace:
Exception in thread "main" java.io.IOException: load failed
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:763)
at java.security.KeyStore.load(Unknown Source)
at TestPKCS11.main(TestPKCS11.java:29)
Caused by: javax.security.auth.login.LoginException: no password provided, and n
o callback handler available for retrieving password
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1184)
at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:849)
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:751)
The second (2) fails with:
Exception in thread "main" java.io.IOException: load failed
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:763)
at java.security.KeyStore.load(Unknown Source)
at TestPKCS11.main(TestPKCS11.java:30)
Caused by: javax.security.auth.login.LoginException
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1238)
at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:849)
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:753)
... 2 more
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_PIN_INVALID
at sun.security.pkcs11.wrapper.PKCS11.C_Login(Native Method)
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1222)
My config is the following:
name=SmartCard
slotListIndex = 0
library=C:\gclib.dll
attributes(*,CKO_PUBLIC_KEY,*)={ CKA_TOKEN=true }
NB: I have a local tool (Classic Client ToolBox) that does not require the PIN to display the certificates.

Looks like Sun's provider always calls Login, no matter if you want to login or not. Frankly speaking, it can be that the only option is to change the approach, e.g. use some other way to access PKCS#11 devices (we have such mechanisms in our SecureBlackbox, for example).
On the other hand, possibility to retrieve information without logging in to the device, is a kind of information leak, and as such possibility to obtain the list or the certificates themselves depends on the particular device. What works on your device might not work on other devices.

Related

Elasticsearch high-level REST client fails to connect over https

I am trying to connect Elastic over https using high-level REST client. But the clients fails with below exception.
java.io.IOException: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:884)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:283)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:270)
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1632)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1617)
at org.elasticsearch.client.IndicesClient.exists(IndicesClient.java:974)
at org.me.elastic.ElasticSSLClient.createIndexes(ElasticSSLClient.java:70)
at org.me.elastic.ElasticSSLClient.main(ElasticSSLClient.java:34)
Caused by: javax.net.ssl.SSLException: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at org.apache.http.nio.reactor.ssl.SSLIOSession.convert(SSLIOSession.java:262)
at org.apache.http.nio.reactor.ssl.SSLIOSession.doWrap(SSLIOSession.java:269)
at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:305)
at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:523)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:120)
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.base/java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
at java.base/java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
at java.base/java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
at java.base/sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:99)
at java.base/sun.security.validator.Validator.getInstance(Validator.java:181)
at java.base/sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:300)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:176)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:246)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1334)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1231)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1174)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1074)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1008)
at org.apache.http.nio.reactor.ssl.SSLIOSession.doRunTask(SSLIOSession.java:285)
at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:345)
... 9 more
I have setup a git repo with java client code. I used the step mentioned on elasticsearch documentation to setup TLS and HTTPS on my Mac. Added below properties and elasticsearch startups fine.
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/elasticsearch/http.p12
xpack.security.http.ssl.truststore.path: certs/elasticsearch/http.p12
Also, used the code sample from elasticsearch docs. Something wrong with client code or HTTPS setup?
The reason for the error is the way Keystore instance is build. While creating the pkcs12 store, I did not use a password, hence I was passing a null while loading certificates.
KeyStore truststore = KeyStore.getInstance("pkcs12");
try (InputStream is = Files.newInputStream(trustStorePath)) {
truststore.load(is, null);
}
But when I changed is to a empty string, certificates were loaded and connected to the elasticsearch.
KeyStore truststore = KeyStore.getInstance("pkcs12");
try (InputStream is = Files.newInputStream(trustStorePath)) {
truststore.load(is, "".toCharArray());
}

How can I acquire JanusGraphManagement over a remote connection?

I have a docker container running the gremlin-server.
It was started via:
./bin/gremlin-server.sh conf/gremlin-server/gremlin-server.yaml
From within a docker container, running this image:
https://hub.docker.com/r/janusgraph/janusgraph
The server is up and is listening at port 8182
$ docker ps
6019adda6081 janusgraph/janusgraph "docker-entrypoint.s…" 2 days ago Up 26 hours 0.0.0.0:8182->8182/tcp
I am interested in using a schema and indexes.
Janus offers this here: https://docs.janusgraph.org/basics/schema/
The following Is the configuration I use to attempt to connect to the gremlin-server:
AbstractConfiguration config = new BaseConfiguration();
config.setListDelimiter('/');
// contents of conf/remote-graph.properties
config.setProperty("gremlin.remote.driver.sourceName", "g");
config.setProperty("gremlin.remote.remoteConnectionClass", "org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection");
// contents of conf/remote-objects.yaml:
config.setProperty("clusterConfiguration.hosts", databaseUrl);
config.setProperty("clusterConfiguration.port", 8182);
config.setProperty("clusterConfiguration.serializer.className", "org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0/");
config.setProperty("storage.backend", "cql");
config.setProperty("clusterConfiguration.serializer.config.ioRegistries", "org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry");
When I call
GraphTraversalSource g = traversal().withRemote(config);
I get a traversal source and everything seems fine. However, to use the management stuff that Janus provides, I seem to need a JanusGraphManagement object. I cannot get the generic Graph object above and cast it to a JanusGraph. The docs suggest using a JanusGraphFactory: https://docs.janusgraph.org/basics/configuration/#janusgraphfactory
So I call
JanusGraph janusGraph = JanusGraphFactory.open(config);
I get the following stack trace:
Exception in thread "main" java.lang.IllegalArgumentException: Could not find implementation class: org.janusgraph.diskstorage.cql.CQLStoreManager
at org.janusgraph.util.system.ConfigurationUtil.instantiate(ConfigurationUtil.java:60)
at org.janusgraph.diskstorage.Backend.getImplementationClass(Backend.java:440)
at org.janusgraph.diskstorage.Backend.getStorageManager(Backend.java:411)
at org.janusgraph.graphdb.configuration.builder.GraphDatabaseConfigurationBuilder.build(GraphDatabaseConfigurationBuilder.java:50)
at org.janusgraph.core.JanusGraphFactory.open(JanusGraphFactory.java:161)
at org.janusgraph.core.JanusGraphFactory.open(JanusGraphFactory.java:132)
at org.janusgraph.core.JanusGraphFactory.open(JanusGraphFactory.java:112)
at com.activitystream.database.GraphMigration.migrateDatabase(GraphMigration.java:69)
at com.activitystream.runners.persistence.DataStores.migrateDatabase(DataStores.java:27)
at com.activitystream.runners.persistence.EntityPersistenceRunner.main(EntityPersistenceRunner.java:23)
Caused by: java.lang.ClassNotFoundException: org.janusgraph.diskstorage.cql.CQLStoreManager
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:315)
at org.janusgraph.util.system.ConfigurationUtil.instantiate(ConfigurationUtil.java:56)
... 9 more
Is it possible to modify the schema over a remote connection?
If it is not possible, how can one modify the schema?
Any insight would be appreciated.
You basically have two choices - either:
Interact with your JanusGraphManagement object by way of scripts sent to Gremlin Server (typically by way of a session but I guess you could package an entire "management script" together and submit it as one request) or
Bypass Gremlin Server and instantiation your JanusGraphManagement object locally as directed in the JanusGraph documentation.
There is no way to have return a JanusGraphManagement to your client as it is not a serializable object that can be sent back from the server.

SSL Exceptions Seemingly caused by Apache Axis2

So my question is this: does axis2 create / override a global SSL factory that would impact other parts of a project that are communicating without using axis2?
I have a method making http calls out to an external page using org.apache.commons.httpclient.HttpClient (Below). It works. I send things out, and get responses back, everything is awesome.
PostMethod method = new PostMethod(url);
method.addRequestHeader("Content-Type", "application/json");
method.addRequestHeader("Authorization", "Bearer "+accessToken);
method.setRequestEntity(new StringRequestEntity(requestAsString, "application/json", "UTF-8"));
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
int rCode = client.executeMethod(method);
I also have database connections using com.microsoft.sqlserver.jdbc. It works. Everything is still awesome.
The problems start with another service within the same project that uses axis2 (org.apache.axis2-1.6.2). After I attempt any communication using the axis 2 stub both the jdbc connection and the HttpClient connection both begin failing (The errors are below). Everything works fine up until axis2 gets involved.
I know axis2 is based on commons-httpclient-3.1 so the impact to the HttpClient piece isn't entirely unexpected but I cannot for the life of me figure out why I am seeing this behavior.
My assumption is that axis2 is setting some sort of global variable that is impacting ssl connections but having read the documentation and stepped through the source code, I can't find that happening anywhere.
The HttpClient error:
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1917)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1874)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1857)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1783)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:128)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at org.apache.commons.httpclient.methods.StringRequestEntity.writeRequest(StringRequestEntity.java:146)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
... 10 more
Caused by: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:79)
at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:696)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:277)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:936)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:871)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
... 16 more
Caused by: java.security.InvalidAlgorithmParameterException: parameter object not a ECParameterSpec
at org.bouncycastle.jce.provider.JDKKeyPairGenerator$EC.initialize(JDKKeyPairGenerator.java:345)
at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:74)
... 24 more
The jdbc error:
ERROR 13:27:33,321 [Thread-24] PID- M- TID- DAConnectionMgr_MSSQL -DB connection unavaliable to [master] as [Dev_User] failed on attempt [2], will automatically retry
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:a67d09bf-be47-4910-9d8c-fd040468a1cb".
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1667)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1668)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1323)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at com.company.util.da.DAConnectionMgr_MSSQL.getConnection(DAConnectionMgr_MSSQL.java:299)
at com.company.baseserver.da.payments.product.productSSQL.openConnection(Product10DAMSSQL.java:499)
at com.company.baseserver.payments.product.ProductProcessor.process(ProductPaymentProcessor.java:988)
at com.company.baseserver.message.ProjectFunction.process(ProjectFunction.java:108)
at com.company.base.ClientProcessor.run(ClientProcessor.java:93)
at com.company.util.thread.PooledExecutor$Worker.run(PooledExecutor.java:774)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:a67d09bf-be47-4910-9d8c-fd040468a1cb
at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.ensureSSLPayload(IOBuffer.java:651)
at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.readInternal(IOBuffer.java:708)
at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.read(IOBuffer.java:700)
at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.readInternal(IOBuffer.java:895)
at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.read(IOBuffer.java:883)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1618)
... 13 more

Using Apache Rampart for Signature with JKS and Binary Security Token key identifier

I have to call a web service that was provided by a customer (some information below is masked for this reason). I've been provided with a java keystore that contains the private key that I need to use to generate a signature to include in the WSSecurity header of my request.
Additionally, I've been sent a working SoapUI project that implements this service with the proper security configuration. The outgoing security configuration in soapUI has the "Key Identifier Type" set to "Binary Security Token"
I am trying to set this call up in my Java application using Apache Rampart. I noticed that there is no equivalent to "Binary Security Token" key identifier in the OutflowSecurity configuration, so I'm trying the following. Here is the relevant snippet from my axis2.xml file:
<module ref="rampart" />
<parameter name="OutflowSecurity">
<action>
<items>Signature</items>
<user>*******</user>
<passwordCallbackClass>*******.PWCBHandler</passwordCallbackClass>
<signaturePropFile>crypto.properties</signaturePropFile>
<signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
</action>
</parameter>
And here are the contents of my crypto.properties file:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.file=C:/rampart/*****.jks
org.apache.ws.security.crypto.merlin.keystore.alias=******
org.apache.ws.security.crypto.merlin.alias.password=**********
org.apache.ws.security.crypto.merlin.keystore.password=********* (same as above)
The issue is that when I try to execute the service with this configuration, I get the following error:
org.apache.axis2.AxisFault: Error during Signature:
at org.apache.rampart.handler.WSDoAllSender.processMessage(WSDoAllSender.java:75)
at org.apache.rampart.handler.WSDoAllHandler.invoke(WSDoAllHandler.java:72)
at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
at org.apache.axis2.engine.Phase.invoke(Phase.java:313)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:262)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:427)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
... (removed)
Caused by: org.apache.ws.security.WSSecurityException: Error during Signature:
at org.apache.ws.security.action.SignatureAction.execute(SignatureAction.java:64)
at org.apache.ws.security.handler.WSHandler.doSenderAction(WSHandler.java:202)
at org.apache.rampart.handler.WSDoAllSender.processBasic(WSDoAllSender.java:212)
at org.apache.rampart.handler.WSDoAllSender.processMessage(WSDoAllSender.java:72)
... 13 more
Caused by: org.apache.ws.security.WSSecurityException: Signature creation failed
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:558)
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:478)
at org.apache.ws.security.message.WSSecSignature.build(WSSecSignature.java:384)
at org.apache.ws.security.action.SignatureAction.execute(SignatureAction.java:61)
... 16 more
Caused by: org.apache.ws.security.WSSecurityException: General security error (The private key for the supplied alias does not exist in the keystore)
at org.apache.ws.security.components.crypto.Merlin.getPrivateKey(Merlin.java:725)
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:501)
... 19 more
Caused by: java.security.UnrecoverableKeyException: Cannot recover key
at sun.security.provider.KeyProtector.recover(Unknown Source)
at sun.security.provider.JavaKeyStore.engineGetKey(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineGetKey(Unknown Source)
at java.security.KeyStore.getKey(Unknown Source)
at org.apache.ws.security.components.crypto.Merlin.getPrivateKey(Merlin.java:711)
... 20 more
I've tried all of the different signatureKeyIdentifiers options without any luck. Could anyone help me perhaps figure out where to go from here to debug this issue?
Thank you!
I'm not sure about your overall configuration, but the obvious problem is that the alias that you use to load the key from keystore is invalid. Maybe you use alias of some public key instead of private? Rampart will use user as key alias when alias itself is not provided, so I would make sure that both, user in service configuration and alias in properties, are set to the same value.
You can verify which one to use by listing keystore contents using keytool from JDK:
JDK/bin/keytool -list -keystore path/to/keystore
It should print:
alias1, 13-May-2013, trustedCertEntry, (public key only, used to verify signature)
Certificate fingerprint (SHA1): *****
alias2, 13-May-2013, PrivateKeyEntry, (private/public key pair, used to sign messages)
Certificate fingerprint (SHA1): *****
Questions:
1. Do we need to make any other configurations other than the policy files.
2. If so, where we need to add it.
3. Can you review the policy file is fine for the requirement with binary security token.
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>***</ramp:user>
<ramp:passwordCallbackClass>com.sosnoski.ws.library.adb.PWCBHandler</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file">com/sosnoski/ws/library/adb/***.jks</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">******</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
Fixed. I had the wrong username in my password callback handler. It wasn't able to find the password to use to access the key.. Thanks for the help. Sorry for the late answer. I had it as a comment to the originating question before.

Java Authentication against Active Directory, authentication mismatch?

So I have some code which I'm testing to make sure it works nicely for authentication. It works fine against straight kerberos, so I figured there should only be some minor hiccups with AD. Unfortunately, I cannot get around a KrbException: KDC has no support for encryption type (14).
I know the error is an encryption type mismatch. But I can kinit just fine, it's only in the code that I hit an issue. I'm not setting anything, so I think it should be inheriting the same defaults as kinit, but that obviously isn't the case.
The code-
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("java.security.krb5.realm", "TEST.SQRRL.COM");
System.setProperty("java.security.krb5.kdc", "172.16.101.128");
System.setProperty("java.security.auth.login.config", "./conf/jaas.conf");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "true");
// "Client" references the JAAS configuration in the jaas.conf file.
LoginContext loginCtx = null;
loginCtx = new LoginContext("Server", new LoginCallbackHandler("test".toCharArray()));
loginCtx.login();
subject = loginCtx.getSubject();
and the jaas.conf
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=false
storeKey=true
useTicketCache=true
principal="accumulo#test.SQRRL.COM";
};
And, the stack trace-
>>>KRBError:
sTime is Tue Nov 27 18:16:36 EST 2012 1354058196000
suSec is 257213
error code is 14
error Message is KDC has no support for encryption type
realm is test.SQRRL.COM
sname is krbtgt/test.SQRRL.COM
msgType is 30
javax.security.auth.login.LoginException: KDC has no support for encryption type (14)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:696)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
at authenticators.KerberosAuthenticator.<init>(KerberosAuthenticator.java:37)
at main.ServerImpl.<init>(ServerImpl.java:91)
at main.PlugServer.run(PlugServer.java:22)
at main.PlugServer.main(PlugServer.java:42)
Caused by: KrbException: KDC has no support for encryption type (14)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:66)
at sun.security.krb5.KrbAsReq.getReply(KrbAsReq.java:446)
at sun.security.krb5.Credentials.sendASRequest(Credentials.java:401)
at sun.security.krb5.Credentials.acquireTGT(Credentials.java:373)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:662)
... 15 more
Caused by: KrbException: Identifier doesn't match expected value (906)
at sun.security.krb5.internal.KDCRep.init(KDCRep.java:133)
at sun.security.krb5.internal.ASRep.init(ASRep.java:58)
at sun.security.krb5.internal.ASRep.<init>(ASRep.java:53)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:50)
... 19 more
Exception in thread "main" java.lang.RuntimeException: javax.security.auth.login.LoginException: KDC has no support for encryption type (14)
at main.PlugServer.run(PlugServer.java:36)
at main.PlugServer.main(PlugServer.java:42)
Caused by: javax.security.auth.login.LoginException: KDC has no support for encryption type (14)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:696)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
at authenticators.KerberosAuthenticator.<init>(KerberosAuthenticator.java:37)
at main.ServerImpl.<init>(ServerImpl.java:91)
at main.PlugServer.run(PlugServer.java:22)
... 1 more
Caused by: KrbException: KDC has no support for encryption type (14)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:66)
at sun.security.krb5.KrbAsReq.getReply(KrbAsReq.java:446)
at sun.security.krb5.Credentials.sendASRequest(Credentials.java:401)
at sun.security.krb5.Credentials.acquireTGT(Credentials.java:373)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:662)
... 15 more
Caused by: KrbException: Identifier doesn't match expected value (906)
at sun.security.krb5.internal.KDCRep.init(KDCRep.java:133)
at sun.security.krb5.internal.ASRep.init(ASRep.java:58)
at sun.security.krb5.internal.ASRep.<init>(ASRep.java:53)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:50)
... 19 more
So, I got it past this stage. I can only guess that the DES support in active directory for Windows Server 2012 is broken, as I ended up tweaking my krb5.conf file and setting the two default ticket types and permitted types to just aes256-cts-hmac-sha1-96 and it worked for the one user. After enabling aes256 for other users in AD, it continued to work.
You need to access the user's account and check the 'use kerberos DES encryption types' checkbox.
You'll need to login to your DS as an admin to do this of course.
Looking at init() in KDCRep.java, the only part that looks it could be throwing your error is:
150 if ((subDer.getTag() & 0x1F) == 0x00) {
151 pvno = subDer.getData().getBigInteger().intValue();
152 if (pvno != Krb5.PVNO) {
153 throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
154 }
155 } else {
156 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
157 }
It does seem a bit odd that the error's being printed as a KrbException, but it could work since KrbApErrException is a subclass of KrbException. init() can't throw any other subclasses of KrbException, though.
Scratch that. A better possibility is that it's one of the Asn1Exceptions in there, since the constructor in KrbAsRep.java catches and rethrows those errors as KrbExceptions (with an appropriate initCause that would match up pretty well with the stack trace).
"Identifier doesn't match expected value (906)" leads me to believe it's throwing a Asn1Exception(Krb5.ASN1_BAD_ID), since Krb5.ASN1_BAD_ID has value 906. That's not overly helpful, since that seems to be the default error in init().
See if you can generate the DerValue corresponding to your configuration and inspect it manually, seeing where init() would reject it, then step backward from there, looking at what part of your configuration created the erroneous bits.
Upon further inspection, the message "KDC has no support for encryption type" leads me to believe Krb5.KDC_ERR_ETYPE_NOSUPP must have been used. But, as that's only used for the default instance of Etype, that might not mean much.

Categories