java.security.KeyStoreException: Uninitialized keystore
at java.security.KeyStore.aliases(KeyStore.java:941)
at com.sun.net.ssl.internal.ssl.SunX509KeyManagerImpl.(SunX509KeyManagerImpl.java:106)
at com.sun.net.ssl.internal.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:41)
at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:192)

...

So I really want to know if is possible to use to key-pairs in one socket connection or solve this in a different way that I can't see or deal with.

EDIT 1

Bruno, could you give me an entire or complete example please?

Because is not clear for me....

I tried two things:

One solutions is put the two keys inside a private keystore following a previous suggestion... but doesn't work and I received the message bellow:

Really you have advanced knowledge about this subject, java and ssh and I appreciate your
help. All this information is help me understand better this issue while is showing for me the way... Thx a lot

But for the client that need to use the second trust store do this verification and it's a reason because I need to deal with to key-pair certificates...

EDIT5

I'd like to know how I can implement a server socket to let it able to identify and use
correct certificate according with the certificate being used by client to proceed
handshake communication with the server.

Explaining better, in the server side is:

AppServerSideSocket.jar

private keystore: privateKeyApp (type JKS, generated with keytool)

public keystore : publicKeyApp (type JKS, shared with all clients)

And in the client side ...

AppClientSideSocket.jar
- public keystore : publicKeyApp

The AppServerSideSocket.jar listening clients requests and once received process
information sent by clients

The AppClientSideSocket.jar connect with the server using SSL using publicKeyAppwithout
verify server hostname and after handshake send information for the AppServerSideSocket application.

Now I've another client application, AppClientSideSocketNEW.jar, and this verify server hostname to make
communication with the server. In this case, the CN used in the public certificate on the client side
must be match with the hostname where AppServerSideSocket.jar are.

Originally the connection was configured in this way on the server side:

All the clients received the same publicKeyApp and connect with the server without verify hostname, so doesn't matter
if the server where server socket application (AppServerSideSocket.jar) is installed in the server with hostname is
badServer1.com and the CN of key in privateKeyApp and publicKeyApp is setted with goodServer1.com, because all the
clients don't verify hostname or the CN attribute of the key.

But the new client (AppClientSideSocketNEW.jar) do this verification obligatorily, now is necessary provide a new certificate
for this client with new value for CN attribute reflecting the correct hostname CN where the server socket is.

I don't have access to second client and I'm sure that it do hostname verification.

So I created two new key-pair certificates (privateKeyAppNew and publicKeyAppNew) and apparently the communications happened
with success between the server using this new key-pair and new client using this new public publicKeyAppNew key, after configured the server to use this new key-pair of course.

But I need continue to use the old key-pair for old clients. I'd like to know how can I deal with this.

Using a keymanager let me able to verify the client certificate on the server app when client try to connect and
choose the appropriate and do the handshake using the correct certificate?

Or I need distinct ssl socket connection in different ports for which kind of clients?

I think you really need to improve your question. It was messy to start with, but it hasn't become any better. Please specify your error messages and on which side you get them (client or server). Don't try extra things that are bound to cause you additional unrelated problems (e.g. "I'm using code for Java 6 on a Java 5 JRE"). Perhaps use more meaningful log messages (your "reverting to ..." messages don't really mean anything where they are, since you're not "reverting" to anything there), log remoteAddress.getHostAddress() to make sure it's what you'd expect, and which branch it takes.
–
BrunoFeb 13 '12 at 21:43

Bruno, I'm work hard to solve this issue and the solution can save my skin in this week :-D If you need more information I would give more details...but I tried to explain better this problem in the way that you ask me.
–
BeraFeb 14 '12 at 14:06

Whether you want to use a single keystore or load your key/cert from two keystores doesn't matter that much: if you really want to, you can certainly implement getPrivateKey and getCertificateChain so that they load the keys/certs from two distinct keystores depending in the alias. It would be unnecessarily complicated, though. You will still have to do something based on the alias selection anyway, so you might as well load both keys/certificates from a single key store, using different aliases.

From the server point of view, the only way to choose one alias (and therefore key/cert pair) is to use what's available in the socket (or engine if you're using an X509ExtendedKeyManager). Since Java 7 doesn't support Server Name Indication (which would let the client tell which host name it's requesting ahead of this selection process), you may have to do this based on the client IP address, or on which of your server IP addresses is being used (if you have more than one).

Using two private keys (keystore) and two public keys (truststore)

You seem to be confused about what the keystore and the truststore are. Unless you're planning to use client-certificate authentication, you can ignore the trust store settings on the server. You can used the default (null) as the second parameter of your SSLContext.init(...). Your "keystore (keystore)" is the information used by the local party (your server in this case), the "truststore (keystore)" is used to determine which remote party to trust.

The public key (or, to be precised, the certificate) you're going to present to the client is also in your keystore, associated with your private key, not in the truststore.

Thrown if an application tries to call a specified method of a class
(either static or instance), and that class no longer has a definition
of that method.

Normally, this error is caught by the compiler; this error can only
occur at run time if the definition of a class has incompatibly
changed.

This has nothing to do with your SSL settings. Not sure what you've done here, but it looks like you may be using code for Java 6 on a Java 5 JRE (Java 6 did not have a setDefault on SSLContext). More importantly, there's something wrong about the general way you seem to be using Java here.

javax.net.ssl.SSLException:

No available certificate or key corresponds to the SSL cipher suites
which are enabled.

That could very well be explained by the fact you didn't seem to be using the SSLContexts you had initialised at all...

If you have two pairs of private keys/certificates in your keystore.

My answer here still stands. I'll try to make it a bit more explicit. I'm assuming here that one of your cert/private key is using alias1 and the other alias2. Find out using keyool -list if you're not sure. It's up to you to choose and set them up.

Do the same and, on top of this, in getCertificateChain(String alias), choose which of the two keystores to use depending on the alias, and use it to get the certificate chain. Same thing for getPrivateKey(...).

I can use client IP address to choose the correct certificate Bruno, for example... could't be easier make two SSL/Socket Connections instead?
–
BeraFeb 10 '12 at 14:15

@Bera, there was a typo in my example, chooseServerAlias was obviously (or perhaps not) overriding the defined method (first param being String), not defining a new overloaded method with String[] as first param. In addition, avoid the complex logic in getCertificateChain: just wrap the original key manager and use the alias (ultimately, it doesn't matter, but you've used the wrong parameter name, which may lead to more confusion).
–
BrunoFeb 13 '12 at 19:57

In addition to all this, you should know that the host name in the certificates presented by your clients (in Subject Alt Names or, if no SAN, in the CN), must match what's requested by the client.
–
BrunoFeb 13 '12 at 19:58

@Bera, you would get more help if you actually stated the exact error messages you see in your question. There have been so many edits it's hard to see. On "EDIT 5", it's not clear what kind of error you get...
–
BrunoFeb 23 '12 at 14:35