Java key store is not found when default SSL context is redefined -


suppose, want connections via ssl in java application ask user permission, when untrusted or expired server certificate encountered (like of web browsers do).

it seemed, natural way substitute default ssl context on application startup.

here minimal working example:

public class clientauthentication {     public static final string server_url = "https://my.test.server";      public static void main(string[] args) throws exception {         sslcontext defaultcontext = sslcontext.getinstance("tls");         defaultcontext.init(null, new trustmanager[]{new myx509trustmanager()}, null);         // defaultcontext.init(null, null, null);         sslcontext.setdefault(defaultcontext);         httpurlconnection connection = (httpurlconnection) new url(server_url).openconnection();         system.out.println(connection.getresponsecode());     }      private static class myx509trustmanager implements x509trustmanager {         @override         public void checkclienttrusted(x509certificate[] x509certificates, string s) throws certificateexception {             throw new unsupportedoperationexception("won't called client");         }          @override         public void checkservertrusted(x509certificate[] chain, string s) throws certificateexception {             if (useracceptscertificate(chain)) {                 system.out.format("certificate '%s' accepted%n", chain[0].getissuerx500principal().getname());             }         }          @override         public x509certificate[] getacceptedissuers() {             return new x509certificate[0];         }          private boolean useracceptscertificate(x509certificate[] x509certificates) {             // ...             return true;         }     } } 

unfortunately, doesn't work, when server requires client authentication. even, when key store containing client certificate specified via -djavax.net.ssl.keystore vm option, connection fails javax.net.ssl.sslhandshakeexception: received fatal alert: handshake_failure, because client certificate wasn't sent @ (traced in wireshark).

such behavior bit surprising, because javadoc sslcontext#init(keymanager[], trustmanager[], securerandom) states, passing null instead of either of key managers or trust managers means, default lookup procedure performed.

Сontradictorily, if pass null instead of array custom trust manager second argument init , specify jks trust store, containing server certificate, using
-djavax.net.ssl.truststore vm parameters, server certificate found there , accepted successfully.

so, can advise way redefine default ssl context, substituting trust manager , leaving default behavior regarding search of key managers? or may robust way find key manager specified via vm options.

notes

  1. if don't customize default ssl context @ all, connection successful, i.e. paths, password , store types correct in vm options.

  2. i can't in way call sslcontext.getdefault() or sslcontext.getinstance("default"), because default context can initialized once.

you've initialized context null key manager. means there no key manager. doesn't mean there default key manager. so, when functions of key manager requested, nothing happens. functions include supplying client certificate.

the javadoc wrong. ibm jsse behaves described there, sun/oracle jsse doesn't, , never has.


Comments

Popular posts from this blog

c++ - How to add Crypto++ library to Qt project -

jQuery Mobile app not scrolling in Firefox -

How to use vim as editor in Matlab GUI -