Openfire+Spark - Client X.509/PKI Certificate Support

Hi Daniel,

Note that Java expects DER-encoded CRLs, not PEM-encoded. I note your file is .pem (mine was originally… somewhere it complained about invalid CRL file and I was reminded). You can convert easily with openssl x509'... something likeopenssl x509 -inform pem -in crl.pem -outform der -out crl.der’. Also, make sure that the file is properly 'chown’d or 'chgrp’d to the right user – i.e., if it’s root:root 400, then the jabber server user probably can’t read it. If that’s all in place, not sure what else, except make sure the CRL file system property is correct.

Kevin

Hi Kevin,

Thank you for your advice, I finally managed to implement the CRL. But the problem is still there. The same one I’ve metioned above. In another thread I read that the “null certificate chain error” occurs, because the client does not send his certificate. Maybe slushpupie knows how to handle that?

regards

Daniel

Glad to hear you got a bit further, but yeah, the CRL isn’t the only problem.

Based on his advice, I could confirm that the server is not “offering” any CA Certificates on the connection. I’m presuming there’s some mis-configuraiton that is not allowing the Java SSL stack to trigger the client certificate portion, but I can’t figure out what it is. I have to guess that it’s some combination of settings that others have enabled and I’m missing, but I don’t know which ones they are.

I have been seeing the error about “no trustAnchors” (the trustAnchors parameter must be non-empty), which seems to imply it’s not actually reading the client.truststore file properly. But I haven’t had time to get back to it over the past couple of days. I’m afraid it’ll come down to further instrumenting the openfire server, or attempting to run it from a debugger.

Out of curiosity, what deployment package are you using? I’m deploying to RedHat EL5 via the RPM. I doubt that would be the problem, but…

So, I just installed the .deb on a debian system (obviously), and reconfigured things from scratch using Openfire 3.6.3 and the beta2 of Spark 2.6.0. There’s nothing really all that different from an end-point situation, but I do see the server indicating acceptible client CA certificates when using `openssl s_client’:

openssl s_client -connect localhost:5223 -prexit -showcerts -debug -CAfile ~/certificates/ca/cacert.pem
[…]

Acceptable client certificate CA names
[CA 1]
[CA 2]

SSL handshake has read 2494 bytes and written 231 bytes

So maybe I’ll go back and try to not use the RPM on the other system and see if the .tar.gz, for instance works better, although clearly there are bigger system differences in play as well.

Again, Spark never tried anything with the keystore as far as I could tell, no UI-based callback or anything. I don’t have my simple Smack test-client here, so I can’t play around with that, but at least the server is offering.

Well I’m using Windows and a simple .exe file to install Openfire. I thing you’re right, the server offers his certificate properly the only thing which is missing is the client’s certificate which likely is not offered by the client. At least I think this is the problem. On client side the TLS Handshake works fine until the server closes the socket. So obviously the server doesn’t get something he needs to have.

I forgot, right befor the socket gets closed, on server side (Closing session due to exception: (SOCKET, R: /192.168.0.135:2395, L: /192.168.0.135:5222, S: 0.0.0.0/0.0.0.0:5222)), there is an disallowed character exception in the warnlog.

Caused by: java.lang.Exception: Disallowed character
at org.jivesoftware.openfire.nio.XMLLightweightParser.read(XMLLightweightParser.ja va:211)
at org.jivesoftware.openfire.nio.XMPPDecoder.doDecode(XMPPDecoder.java:32)
at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtoco lDecoder.java:133)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecF ilter.java:163)
… 9 more

So maybe the client trys to send something which the server doesn’t understand?

By the way is there a way to display the … 9 more error lines?

If you got it to work with Debian, then I would take a very careful look at your settings in the database and config file. The only difference between the two packages is the packaging (the code dosnt change based on distro or anything).

Again, Spark will not prompt for any certs/keystores if the server dosnt say which CA’s are acceptable. Thats not a bug in Spark (what is arguably a bug is not giving a useful message to the user, however, but thats different)

The server must say which CA’s it will accept before the client offers any certificates. So when the server gets no certificate from the client during the handshake, it closes the connection.

However, the errors you posted seem different. Its like someone is trying SSL on a non-SSL port. Is your client set to use SSL or TLS? And what port number is it connecting to?

Right, but i got the debian-based installation to advertise CA’s – the same one I have a key/certificate in my keystore (under ‘mykey’ alias), but I do not get any sort of prompting. So, the server is definititely advertising (at least to s_client), but no callback is showing up.

And actually, I’m not sure if it matters if the keystore has a certificate signed by an advertised CA in terms of getting the callback… in theory the keystore isn’t opened until the passphrase is provided, so the code can’t know whether there is/n’t a reasonable candidate until after such a callback happens, right?

Well, on port 5223 of the Openfire Sever the OpenSSL connection test says:

openssl s_client -prexit -connect localhost:5223
CONNECTED(00000778)
depth=1 /C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=ca/emailAddress=none
verify error:num=19:self signed certificate in certificate chain
verify return:0

Certificate chain
0 s:/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=server
i:/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=ca/emailAddress=none
1 s:/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=ca/emailAddress=none
i:/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=ca/emailAddress=none

Server certificate
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
subject=/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=server
issuer=/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=ca/emailAddress=none

No client certificate CA names sent

SSL handshake has read 2819 bytes and written 282 bytes

New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : EDH-RSA-DES-CBC3-SHA
Session-ID: 49F5566FAD6B64E016B2577ABEA283CFB759583D564F8A1115D4476B8C92CB4
Session-ID-ctx:
Master-Key: CCB3E58B0F8A7FF98B9E7404C595BB8C2B45B8ADDBC717C93A5EECB31F4DDD73
3D7E89C7E480B6C75099FAC632DE06DA
Key-Arg : None
Start Time: 1240815215
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)

</stream:stream>closed

Certificate chain
0 s:/C=DE/ST=State/L=Country/O=Organisation/OU=DANE/CN=pc03
i:/C=DE/ST=State/L=Country/O=Organisation/OU=DANE/CN=xmpp-ca/emailAddress=none
1 s:/C=DE/ST=State/L=Country/O=Organisation/OU=DANE/CN=xmpp-ca/emailAddress=none
i:/C=DE/ST=State/L=Country/O=Organisation/OU=DANE/CN=xmpp-ca/emailAddress=none

Server certificate
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
subject=/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=server
issuer=/C=DE/ST=State/L=Country/O=Organisation/OU=OU/CN=ca/emailAddress=none

No client certificate CA names sent

SSL handshake has read 2893 bytes and written 311 bytes

New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : EDH-RSA-DES-CBC3-SHA
Session-ID: 49F5566FAD6B64E016B2577ABEA283CFB759583D564F8A1115D4476B8C92CB41
Session-ID-ctx:
Master-Key: CCB3E58B0F8A7FF98B9E7404C595BB8C2B45B8ADDBC717C93A5EECB31F4DDD73
3D7E89C7E480B6C75099FAC632DE06DA
Key-Arg : None
Start Time: 1240815215
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
on port 5222 no certificates are offered:

openssl s_client -prexit -connect localho
st:5222
Loading ‘screen’ into random state - done
CONNECTED(00000778)
2052:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:.\ssl\s23_lib.c:188:

no peer certificate available

No client certificate CA names sent

SSL handshake has read 0 bytes and written 124 bytes

New, (NONE), Cipher is (NONE)
Compression: NONE
Expansion: NONE

Anyway on both ports I’m not able to connect to the Server. I’ve already postet the Errors on port 5222, here are the errors on port 5223:

Server debug:

2009.04.27 09:07:39 ConnectionHandler:
javax.net.ssl.SSLHandshakeException: SSL handshake failed.

Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

Client (Smack):

Connection failed. No response from server.

Is there a way to tell Smack to connect via TLS or SSL? I thought the SASLMechanism handles that?

Daniel

My experience has seen similar on the ‘regular’ TLS (5222) – it doesn’t actually do proper TLS as far as client auth at all, even when the SSL (5223) side does. That seems pretty odd, but I’m sure there are reasons for it the way the code is structured.

However, again, the client-side never realizes it and responds with anything. I’ve tried to use smack and spark both, to no avail. Trying smack on :5223 yeilds the same two errors you were seeing:

==> logs/debug.log <==
2009.04.27 09:13:12 ConnectionHandler:
javax.net.ssl.SSLHandshakeException: SSL handshake failed.
at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:416)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(Ab stractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilt erChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceive d(AbstractIoFilterChain.java:648)
at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived (AbstractIoFilterChain.java:499)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(Ab stractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(Abstra ctIoFilterChain.java:293)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.j ava:228)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcesso r.java:198)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$400(SocketIoProce ssor.java:45)
at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProce ssor.java:485)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java: 886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
at com.sun.net.ssl.internal.ssl.EngineInputRecord.bytesInCompletePacket(EngineInpu tRecord.java:152)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:771 )
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:686)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:607)
at org.apache.mina.filter.support.SSLHandler.unwrap0(SSLHandler.java:658)
at org.apache.mina.filter.support.SSLHandler.unwrapHandshake(SSLHandler.java:614)
at org.apache.mina.filter.support.SSLHandler.handshake(SSLHandler.java:493)
at org.apache.mina.filter.support.SSLHandler.messageReceived(SSLHandler.java:306)
at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:392)
… 14 more

I have:

    config.setSecurityMode(SecurityMode.enabled);

and I tried:
config.setSecurityMode(SecurityMode.required);

with no change.

Just a note on SASL – as I understand it, SASL is just authentication, which doesn’t /really/ include the SSL/TLS stuff. I.e., SASL can be made to look at the results of the Handshake and use information from the client-authentication portion, but the TLS stuff all happens before SASL gets invoked. I could easily be wrong.

Did anybody found something out? I’m still trying to fix this problem up. In case this will not work, does anybody have alternative ideas? I need to implement an encrpted and authenticated connection.

Thanks in advance

Daniel

OK, it’s hard to be sure, but I think I’ve got it “working.”

I could not get my simple login smack client working on :5223. Scanning through other forum postings noted that the Socket might not be right – try using the default SSL Socket:

   config.setSocketFactory(SSLSocketFactory.getDefault());

This moved me forward. However, the

So, with an empty client.truststore:

SocketAcceptorIoProcessor-1.0, fatal error: 80: problem unwrapping net record
java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
SocketAcceptorIoProcessor-1.0, SEND TLSv1 ALERT: fatal, description = internal_error
SocketAcceptorIoProcessor-1.0, WRITE: TLSv1 Alert, length = 2

valid client.truststore:

successful login; see client certificate in server’s debug output

HOWEVER The callback stuff appears not to be working – if I disable setting the default keystorePassword property, but have a CallbackHandler set, I still get:

Logging into tester@localhost
XMPPError connecting to localhost:5223.: remote-server-error(502) XMPPError connecting to localhost:5223.
– caused by: java.net.SocketException: password can’t be null
at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection. java:900)
at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1415)
at TestClient.main(TestClient.java:60)
Nested Exception:
java.net.SocketException: password can’t be null
at javax.net.ssl.DefaultSSLSocketFactory.createSocket(SSLSocketFactory.java:156)
at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection. java:888)
at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1415)
at TestClient.main(TestClient.java:60)

Presumably this is because the default SSLSocketFactory is not passing out to callbacks. However, I’ve been completely unsuccessful finding any more useful documentation regarding what SSLSocketFactory to use with Smack. Is there an openfire specific SocketFactory? One that works with TLS as well?

Likewise, trying to use TLS (instead of SSL) on :5222 (or even :5223, which probably isn’t expected to work) totally as we’ve seen before:

javax.net.ssl.SSLProtocolException: Handshake message sequence violation, 2
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.j ava:86)

So, at this point, nothing has really worked:
o The RPM installed a somehow-broken implementation such that the server would not even advertize valid CAs;
- the tar.gz (and .deb) did, but
o none of the clients really work with the callback stuff.
- since there’s some other stuff going on in Spark, it seems impossible to do anything but rely on the (broken?) callback handling.
o Of course, none of it works with TLS, only old-style SSL on :5223.

I still have to believe there is some other trick going on – or are the PCKS#11 handling class(es) different from the JKS handling ones? I.e., could there be a difference in the callback propogation code in the JKS-handling one(s)?


Also: why it’s trying to dial home:

2009.05.01 07:33:59 Retrying request
2009.05.01 07:33:59 Open connection to www.igniterealtime.org:80
2009.05.01 07:33:59 Closing the connection.
2009.05.01 07:33:59 Method retry handler returned false. Automatic recovery will not be attempted

I’m not sure. Can this be killed? Is it just the ‘check for updates’ piece?


My client is as follows, minus setting the properties to things like ‘tester’ and ‘localhost’:

public static void main(String[] args) {

    System.setProperty("javax.net.ssl.keyStore", KEYSTORE_PATH);
    System.setProperty("javax.net.ssl.trustStore", TRUSTSTORE_PATH);
    System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
    System.setProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);

    ConnectionConfiguration config = new ConnectionConfiguration(SERVER, 5222);
    config.setSASLAuthenticationEnabled(true);

// config.setSASLAuthenticationEnabled(false);
config.setKeystorePath(KEYSTORE_PATH);
config.setKeystoreType(“jks”);
config.setTruststorePath(TRUSTSTORE_PATH);
config.setTruststorePassword(TRUSTSTORE_PASSWORD);
config.setTruststoreType(“jks”);

    config.setCallbackHandler(new CallbackHandler());

    config.setSecurityMode(SecurityMode.enabled);

// config.setSecurityMode(SecurityMode.required);

    SASLAuthentication.supportSASLMechanism("PLAIN", 0);
    SASLAuthentication.supportSASLMechanism("DIGEST-MD5", 1);
    SASLAuthentication.supportSASLMechanism("EXTERNAL", 2);

// config.setSocketFactory(SSLSocketFactory.getDefault());

    System.out.println("Logging into " + USERNAME + "@" + SERVER);
    try {
        XMPPConnection conn1 = new XMPPConnection(config, new CallbackHandler());
        conn1.connect();
        String usingTLS = (conn1.isUsingTLS() == true) ? "" : " *NOT* ";
        String secure = (conn1.isSecureConnection() == true) ? "" : " *NOT* ";
        System.out.println("Connection is "
            + usingTLS
            + "using TLS and therefore is: "
            + secure
            + "secure.");

Thread.sleep(3 * 1000); // Something about timing in the forums
conn1.login(USERNAME, PASSWORD, “smack test client”);
System.out.println(“Logged " + USERNAME + “@” + SERVER + " in.”);
Thread.sleep(15 * 1000); //leave it connected for a bit, then disconnect.
conn1.disconnect();
System.out.println("Disconnected " + USERNAME + “@” + SERVER);
} catch (XMPPException xe) {
// TODO Auto-generated catch block
xe.printStackTrace();
} catch (InterruptedException ie) {
// TODO Auto-generated catch block
ie.printStackTrace();
}
}

Ive not done any work on Spark/Smack in quite a while, and others have. Its entirely possible the changes others have made broke the callback handling. Ive been pretty busy lately so I dont know if Ill have time to look at it soon either. As far as SSL vs TLS goes, its the same path through the code as far as the SSL negotiation is, so there should be no difference.

The difference between a JKS and a PKCS11 keystore to the client is none, since its using the pure keystore interface. The only real difference is where you get it from.

Sorry Ive not been much help lately, I just have not had the time to work on any of this.

I pulled down SVN an hour ago. I think the problem comes in around here:

[PacketReader:467]
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals(“starttls”)) {
// Confirm the server that we want to use TLS
*I added this—> startTLSRequired = true;
connection.startTLSReceived(startTLSRequired);
}
else if (parser.getName().equals(“required”) && startTLSReceived) {
startTLSRequired = true;
}

I’m betting ‘starttls’ comes in as ‘’ not ‘’ – or some other similar construction that doesn’t kick startTLSRequired ‘high’ before proceeding. Thus TLS never gets initialized. Presumably that’s a bug: either the server isn’t sending the right thing, or the client isn’t implementing spec. `s_client’ tells me that the server isn’t sending anything inside :

[…]

00c0 - 74 72 65 61 6d 3a 66 65-61 74 75 72 65 73 3e 3c tream:features><
00d0 - 73 74 61 72 74 74 6c 73-20 78 6d 6c 6e 73 3d 22 starttls xmlns="
00e0 - 75 72 6e 3a 69 65 74 66-3a 70 61 72 61 6d 73 3a urn:ietf:params:
00f0 - 78 6d 6c 3a 6e 73 3a 78-6d 70 70 2d 74 6c 73 22 xml:ns:xmpp-tls"
0100 - 3e 3c 2f 73 74 61 72 74-74 6c 73 3e 3c 6d 65 63 ><mec

[…]

So, somewhere down the line things were adjusted. In any event, it finally gets into the Callback Code in XMPPConnection! It doesn’t work, but it gets there! For some reason, it’s invoking PasswordCallback#getPassword(); which has nothing to do with the CallbackHandler I set with #setCallbackHandler – is in, my callbackHandler doesn’t get invoked.

And it turns out that’s because… yup; that’s reverse ordered, too:

[XMPPClient:1221]

            ks = KeyStore.getInstance(configuration.getKeystoreType());
             try {
                 ks.load(new FileInputStream(configuration.getKeystorePath()), pcb.getPassword());
                 pcb = new PasswordCallback("Keystore Password: ",false);
                 callbackHandler.handle(new Callback[]{pcb});

reversing the order – so the Callback actually gets called:

                 callbackHandler.handle(new Callback[]{pcb});
                 ks.load(new FileInputStream(configuration.getKeystorePath()), pcb.getPassword());
                 pcb = new PasswordCallback("Keystore Password: ",false);

fires off my CallbackHandler as expected.

I’m going to see if i can build a .jar and push this out into Spark as a replacement smack.jar and see what happens. I’m thinking it’ll go better now, though.

Err, sorry this is the right ordering for the callback. The first shall be last…

smack> svn diff source/org/jivesoftware/smack/XMPPConnection.java
Index: source/org/jivesoftware/smack/XMPPConnection.java

— source/org/jivesoftware/smack/XMPPConnection.java (revision 11005)
+++ source/org/jivesoftware/smack/XMPPConnection.java (working copy)
@@ -1219,9 +1219,9 @@
else {
ks = KeyStore.getInstance(configuration.getKeystoreType());
try {

  •                ks.load(new FileInputStream(configuration.getKeystorePath()), pcb.getPassword());
                   pcb = new PasswordCallback("Keystore Password: ",false);
                   callbackHandler.handle(new Callback[]{pcb});
    
  •                ks.load(new FileInputStream(configuration.getKeystorePath()), pcb.getPassword());
               }
               catch(Exception e) {
                   ks = null;
    

Still no joy with Spark, though. But my Smack client is doing everything right and getting in under TLS on :5222

Logging into tester@localhost:5222
Callbacks: [Ljavax.security.auth.callback.Callback;@1f6f0bf
!!! Callback invoked!!!
Connection is using TLS and therefore is: secure.
Logged tester@localhost in.
Disconnected tester@localhost

Not sure why Spark isn’t doing the right thing with an updated smack.jar.

Some other things I forgot to mention:

o config.setCallbackHandler() doesn’t work; you have to provide it on the connect() for it to work.

So the real patch for XMPPConnection is:

smack> svn diff source/org/jivesoftware/smack/XMPPConnection.java
Index: source/org/jivesoftware/smack/XMPPConnection.java

— source/org/jivesoftware/smack/XMPPConnection.java (revision 11005)
+++ source/org/jivesoftware/smack/XMPPConnection.java (working copy)
@@ -226,7 +226,7 @@
config.setSASLAuthenticationEnabled(true);
config.setDebuggerEnabled(DEBUG_ENABLED);
this.configuration = config;

  •    this.callbackHandler = null;
    
  •    this.callbackHandler = config.getCallbackHandler();
    

    }

    /**
    @@ -240,7 +240,7 @@
    */
    public XMPPConnection(ConnectionConfiguration config) {
    this.configuration = config;

  •    this.callbackHandler = null;
    
  •    this.callbackHandler = config.getCallbackHandler();
    

    }

    /**
    @@ -1219,9 +1219,9 @@
    else {
    ks = KeyStore.getInstance(configuration.getKeystoreType());
    try {

  •                ks.load(new FileInputStream(configuration.getKeystorePath()), pcb.getPassword());
                   pcb = new PasswordCallback("Keystore Password: ",false);
                   callbackHandler.handle(new Callback[]{pcb});
    
  •                ks.load(new FileInputStream(configuration.getKeystorePath()), pcb.getPassword());
               }
               catch(Exception e) {
                   ks = null;
    

And it looks like the CallbackHandler isn’t set right in any event:
[XMPPConnection(Config,CBH)] Callback handler: org.jivesoftware.LoginDialog$LoginPanel[,0,188,244x200,layout=java.awt.GridBagL ayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumS ize=,preferredSize=]

OOOOOOOOOOH. I bet… Yup. That’s pointing to the PasswordCallback/CallbackHandler in the login pane… meaning they’re assuming that the keystore and the account have the same password!

Mmmhmm. That works. Completely invalid assumption, but it works when I make them the same. Of course the other hidden caveat is that they’re looking for key under the alias of the username. I haven’t checked fall-back – i.e., does it try “” then “mykey”, but one might presume. So that’s a reasonable thing to do but setting the passwords the same is probably not. There should be a pop-up dialog… or try the original, then pop-up, would be best.

However, now:

Exception in thread “Thread-1” java.lang.NoSuchMethodError: org.jivesoftware.smack.XMPPConnection.login(Ljava/lang/String;Ljava/lang/String ;Ljava/lang/String;Z)V
at org.jivesoftware.LoginDialog$LoginPanel.login(LoginDialog.java:860)
at org.jivesoftware.LoginDialog$LoginPanel.access$400(LoginDialog.java:200)
at org.jivesoftware.LoginDialog$LoginPanel$1.construct(LoginDialog.java:606)
at org.jivesoftware.spark.util.SwingWorker$2.run(SwingWorker.java:131)
at java.lang.Thread.run(Thread.java:595)

But I presume that’s an SVN vs. RC/Beta-2 versioning thing:


r10846 | gato | 2008-10-24 01:17:50 -0400 (Fri, 24 Oct 2008) | 1 line

Simplified list of #login methods in XMPPConnection.

Once i point #login(String,String,String,boolean) -> #login(String,String,String); it logs in perfectly!

That’s with the latest 2.6.0-beta, not using the provided JRE. With another copy of the stock Spark (I think?), the certificate gets sent without the extra login(S,S,S,b) in there, but it gets “stuck” right here:

01E0: 72 65 73 73 69 6F 6E 3E 3C 61 75 74 68 20 78 6D ression><auth xm
01F0: 6C 6E 73 3D 22 68 74 74 70 3A 2F 2F 6A 61 62 62 lns=“http://jabb
0200: 65 72 2E 6F 72 67 2F 66 65 61 74 75 72 65 73 2F er.org/features/
0210: 69 71 2D 61 75 74 68 22 2F 3E 3C 72 65 67 69 73 iq-auth”/><regis
0220: 74 65 72 20 78 6D 6C 6E 73 3D 22 68 74 74 70 3A ter xmlns=“http:
0230: 2F 2F 6A 61 62 62 65 72 2E 6F 72 67 2F 66 65 61 //jabber.org/fea
0240: 74 75 72 65 73 2F 69 71 2D 72 65 67 69 73 74 65 tures/iq-registe
0250: 72 22 2F 3E 3C 2F 73 74 72 65 61 6D 3A 66 65 61 r”/></stream:fea
0260: 74 75 72 65 73 3E 98 E4 3B 39 92 A1 70 90 38 2D tures>…;9…p.8-
0270: FB 9D 16 18 4B 74 …Kt

and eventually disconnects.


The other change was:

smack> svn diff source/org/jivesoftware/smack/PacketReader.java
Index: source/org/jivesoftware/smack/PacketReader.java

— source/org/jivesoftware/smack/PacketReader.java (revision 11005)
+++ source/org/jivesoftware/smack/PacketReader.java (working copy)
@@ -467,6 +467,7 @@
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals(“starttls”)) {
// Confirm the server that we want to use TLS

  •                startTLSRequired = true;
                   connection.startTLSReceived(startTLSRequired);
               }
               else if (parser.getName().equals("required") && startTLSReceived) {
    

which isn’t very robust, but at least it does the right thing.

So the end of the day:

  1. Spark 2.6.0-beta2 – stock – might still be broken, but for some other random reason where the connection hangs (provided JRE?)

  2. After applying the above patches to smack (also attached), and redeploying an updated lib/smack.jar, Spark 2.6.0b2 (1.5 JRE) should work for you provided:

  3. Your keystore’s password has:

a) a key+certificate with an alias the same as the user logging in

b) the password for the keystore and the key are the same,

c) the password you enter to login in the dialog is the same as (3.b).

I think that’s all the non-obvious required conditions – in addition to all of the regular openfire setup, and not to use the RPM, which apparently is broken. I’ve not even thought about looking at the diff between .tar.gz and rpm-based installations.

Can these patches be applied to SVN, please? And maybe a document defining everything put together separate from the forums?

If i get some time – and I don’t think I will – I’ll look into what’s breaking beta2

Thanks!
PacketReader-TLS-patch.diff (684 Bytes)
XMPPConnection-Callback-patch.diff (1369 Bytes)

Well this isn’t the best solution, but at least it’s kind of working.

@slushpupie: Is this Problem scheduled to be fixed?

Daniel

I doubt any of the other people with svn access understand this well enough to fix it (anyone who does dev work in PKI certainly understands how rare it is) and Im stretched a bit thin with other commitments at the moment. So no, its not really in a timeline anywhere. Ill try to get on the community group chat today- perhaps we can all discuss it then.

Thanks slushpuppie. The patches are quite limited, so applying them should be very obvious, I don’t think it’s going to require any PKI-specific knowledge to see, e.g., that you must register the callback handler, before calling it back.

However, I do have more to report: apparently I was mistaken regarding the RPM – you were right, there was no difference.

Apparently the crl and client truststore properties (xmpp.client.certificate.crl and xmpp.socket.ssl.client.truststore) only admit of relative URLs. I.e., “/opt/openfire/resources/security/client.truststore” won’t work… “resources/security/client.truststore” will work. That’s a tidy bit of info. Of course, I could not ever verify until I’d patched my Spark client per the above, but that’s probably a critical piece of information for folks to be aware of. I’ll try to add a note to the other thread where you laid out the basic properties.

Anyway, I’d be happy to file a ticket in JIRA, but it’s not open to the public. Could you at least create a ticket, if you have access? And attach the patches, etc? Oddly, I do see that the RPM-based 3.6.3 server is showing <required=“true”>, so I’m not sure what the deal is there, or if I’m looking in the wrong place.

Okay, im getting closer. Your solution seems to work. The only thing which prevents me from connection to the Server is this error:

2009.05.07 10:30:18 Closing session due to exception: (SOCKET, R: /192.168.0.135:2003, L: /192.168.0.135:5222, S: 0.0.0.0/0.0.0.0:5222)
org.apache.mina.filter.codec.ProtocolDecoderException: java.lang.Exception: Disallowed character (Hexdump: 80 62 01 03 01 00 39 00 00 00 20 00 00 04 01 00 80 00 00 05 00 00 2F 00 00 33 00 00 32 00 00 0A 07 00 C0 00 00 16 00 00 13 00 00 09 06 00 40 00 00 15 00 00 12 00 00 03 02 00 80 00 00 08 00 00 14 00 00 11 4A 02 9C 1A 68 7A 1F 9D 31 7C DC DD 0D FF FF 1E E5 52 5F 47 0A 50 7F 13 E5 60 84 F4 EA 0E 19 52)

This occures while TLS handshaking. i think theres someting wrong with my certificates but i dont know what, any idea? is the character ‘-’ disallowed in certificate names?

Daniel