Yes, chooseClientAlias returned null!

I think that may be a problem with my certificate.

I check it and let you know!
Marco

2012/8/24 Brian Carlstrom <[email protected]>

> yes, basically during the handshake if a client cert is requested, the
> chooseClientAlias is called to select one. the selected key is
> specified by the returned String alias. Then it calls back with that
> alias to lookup the private key and certs. Since you are receiving a
> null in getPrivateKey, that seems to imply that chooseClientAlias
> returned null. Can you confirm that?
>
> So the next question is why it can't choose one. the arguments are
> used to filter the KeyStore contents. so it will look for an RSA or
> DSA cert, issued by one of the specified issuers. I will say that the
> issuers list is concerning. typically servers don't actually send that
> and if the server is sending something bogus, it might be over
> constraining the chooseClientAlias function. However, you can of
> course workaround by having your proxy implement your own logic for
> selecting the alias to use from the KeyStore, even if you can't change
> the server configuration.
>
> -bri
>
> On Fri, Aug 24, 2012 at 3:04 AM, Marco Serioli <[email protected]> wrote:
> > I've tryed to implement X509KeyManager in my own MyX509KeyManager class:
> >
> > class MyX509KeyManager implements X509KeyManager {
> >
> > private X509KeyManager defaultKeyManager;
> > public MyX509KeyManager(KeyManager[] keyManagers){
> > for (KeyManager keyManager : keyManagers){
> > if (keyManager instanceof X509KeyManager){
> > defaultKeyManager = (X509KeyManager) keyManager;
> > }
> > }
> >
> > }
> > @Override
> > public String chooseClientAlias(String[] keyType, Principal[] issuers,
> > Socket socket) {
> > return defaultKeyManager.chooseClientAlias(keyType, issuers, socket);
> > }
> >
> > @Override
> > public String chooseServerAlias(String keyType, Principal[] issuers,
> Socket
> > socket) {
> > return defaultKeyManager.chooseServerAlias(keyType, issuers, socket);
> > }
> >
> > @Override
> > public X509Certificate[] getCertificateChain(String alias) {
> > return defaultKeyManager.getCertificateChain(alias);
> > }
> >
> > @Override
> > public String[] getClientAliases(String keyType, Principal[] issuers) {
> > return defaultKeyManager.getClientAliases(keyType, issuers);
> > }
> >
> > @Override
> > public PrivateKey getPrivateKey(String alias) {
> > return defaultKeyManager.getPrivateKey("tomcat");
> > }
> >
> > @Override
> > public String[] getServerAliases(String keyType, Principal[] issuers) {
> > return defaultKeyManager.getServerAliases(keyType, issuers);
> > }
> > }
> >
> >
> > And to do:
> >
> > final KeyManagerFactory kmf =
> > KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
> > kmf.init(keyStore, keyStorePassword.toCharArray());
> > KeyManager keyManager = new MyX509KeyManager(kmf.getKeyManagers());
> >
> > KeyManager[] keyManagerArray = kmf.getKeyManagers();
> > keyManagerArray[0] = keyManager;
> > sslCtx.init(keyManagerArray, tmf.getTrustManagers(), new SecureRandom());
> >
> > During debugging I can see that first call is on
> >
> > public String chooseClientAlias(String[] keyType, Principal[] issuers,
> > Socket socket)
> >
> > called with parameter
> >
> > keyType[0]="RSA"
> > keyType[1]="DSA"
> >
> > issuers[0] ->X500Principal -> toString() =
> > OID.1.2.840.113549.1.9.1=#16156D2E736572696F6C694063706D61706176652E6974,
> > CN=www.apaveitaliacpm.it, OU=IT, O=Apave Italia CPM, L=Bienno,
> ST=Brescia,
> > C=IT
> > issuers[1] ->X500Principal -> toString() = CN=Apave Italia CPM, OU=IT,
> > O=Apave Italia CPM, L=Bienno, ST=Brescia, C=IT
> >
> > socket = SSL socket over
> > Socket[addr=192.168.168.13/192.168.168.13,port=8443,localport=48330]
> >
> > The second method called is:
> >
> > public PrivateKey getPrivateKey(String alias)
> >
> >
> > where I have noticed that alias parameter is null.
> >
> > Could it be a problem?
> >
> > Il giorno venerdì 24 agosto 2012 07:49:19 UTC+2, Brian Carlstrom ha
> scritto:
> >>
> >> Well, the non-OpenSSL provider seems to be hitting another issue
> >>
> >> http://code.google.com/p/android/issues/detail?id=31903
> >>
> >> that is not fixed even it the 4.1 release. However, the nature of that
> >> bug seems to indicate the problem, that no client certificate was
> >> returned by the KeyManager.
> >>
> >> I'd advise writing a proxy X509KeyManager
> >> (
> http://developer.android.com/reference/javax/net/ssl/X509KeyManager.html)
> >> as a wrapper around the result returned from kmf.getKeyManagers().
> >> getKeyManagers is going to return a length 1 array with a
> >> X509KeyManager. Just replace the element with your own that implements
> >> each method by just logging and then calling through the original one.
> >> Then we can see if your key manager really is getting called. you can
> >> do the same with the SSLSocketFactory passed to setSSLSocketFactory to
> >> make sure that it really is calling your SSLSocketFactory.
> >>
> >> -bri
> >>
> >> On Thu, Aug 23, 2012 at 9:36 PM, Marco Serioli <[email protected]>
> wrote:
> >> > Thank you for your quick answer!
> >> >
> >> > I've tried to get the non-OpenSSL provider and then log the error
> >> > message.
> >> > Here is the result:
> >> >
> >> > java.lang.NullPointerException
> >> >   at
> >> >
> >> >
> org.apache.harmony.xnet.provider.jsse.ClientHandshakeImpl.processServerHelloDone(ClientHandshakeImpl.java:515)
> >> >   at
> >> >
> >> >
> org.apache.harmony.xnet.provider.jsse.ClientHandshakeImpl.unwrap(ClientHandshakeImpl.java:297)
> >> >   at
> >> >
> >> >
> org.apache.harmony.xnet.provider.jsse.SSLRecordProtocol.unwrap(SSLRecordProtocol.java:408)
> >> >   at
> >> >
> >> >
> org.apache.harmony.xnet.provider.jsse.SSLSocketImpl.doHandshake(SSLSocketImpl.java:737)
> >> >   at
> >> >
> >> >
> org.apache.harmony.xnet.provider.jsse.SSLSocketImpl.startHandshake(SSLSocketImpl.java:446)
> >> >   at
> >> >
> >> >
> org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.setupSecureSocket(HttpConnection.java:167)
> >> >   at
> >> >
> >> >
> org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:479)
> >> >   at
> >> >
> >> >
> org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeConnection(HttpsURLConnectionImpl.java:419)
> >> >   at
> >> >
> >> >
> org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:217)
> >> >   at
> >> >
> >> >
> org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:177)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:72)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:63)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:91)
> >> >   at
> >> >
> >> >
> it.cpmapave.mt.interceptors.MyClientHttpRequestInterceptor.intercept(MyClientHttpRequestInterceptor.java:29)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:81)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:67)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
> >> >   at
> >> >
> >> >
> org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:63)
> >> >   at
> >> >
> >> >
> org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:475)
> >> >   at
> >> >
> >> >
> org.springframework.web.client.RestTemplate.execute(RestTemplate.java:438)
> >> >   at
> >> >
> >> >
> org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:414)
> >> >   at
> >> >
> it.cpmapave.mt.rest.OrderRestClient_.getOrders(OrderRestClient_.java:58)
> >> >   at
> >> >
> >> >
> it.cpmapave.mt.ui.MainActivity$FetchSecuredResourceTask.doInBackground(MainActivity.java:144)
> >> >   at
> >> >
> >> >
> it.cpmapave.mt.ui.MainActivity$FetchSecuredResourceTask.doInBackground(MainActivity.java:1)
> >> >   at android.os.AsyncTask$2.call(AsyncTask.java:252)
> >> >   at
> java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
> >> >   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
> >> >   at
> >> >
> >> >
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
> >> >   at
> >> >
> >> >
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574)
> >> >   at java.lang.Thread.run(Thread.java:1020)
> >> >
> >> > Please let me know how to take a tcpdump of the SSL handshake if you
> >> > feel it
> >> > useful to solve the problem!
> >> >
> >> > Thank you!
> >> > Marco
> >> >
> >> > 2012/8/24 Brian Carlstrom <[email protected]>
> >> >>
> >> >> I'm responsible for the SSLSocket code and more recently for the
> >> >> HttpURLConnection code. That code does look right to me on a quick
> >> >> review. One thing you could try to see if you can get a better
> >> >> diagnostic using the non-OpenSSL provider by saying
> >> >> SSLContext.getInstance("TLS", "HarmonyJSSE");
> >> >>
> >> >> I'd also try to get a tcpdump of the handshake to see what might be
> >> >> going wrong in case the issue is just problem negotiating an cipher
> >> >> suite in common between both sides. I think the emulator might have
> >> >> tcpdump installed, I could provide some notes on how to run it.
> >> >>
> >> >> I might also log with Log.e(TAG, "message", e); so that it will print
> >> >> the full stack of the exception in case their is more detail, but i'm
> >> >> not expecting much here. I'm really hoping that the other SSLSocket
> >> >> impl which give more user friendly messages than OpenSSL
> >> >>
> >> >> -bri
> >> >>
> >> >> On Thu, Aug 23, 2012 at 4:21 AM, Marco Serioli <[email protected]>
> >> >> wrote:
> >> >> > I'm developing an android application on v13 target sdk and I'm
> >> >> > trying
> >> >> > to
> >> >> > secure connection from android device to my tomcat server v6 with
> SSL
> >> >> > enabling also clientAuth. I'm using self-signed certificates.
> >> >> >
> >> >> > Only for introduce my project (I think the error is not due to
> this):
> >> >> > I'm
> >> >> > using spring-android RestTemplate using a custom
> >> >> > ClientHttpRequestFactory.
> >> >> > Because of android sdk version I'm sure that spring will use
> >> >> > HttpUrlConnection and not HttpClient! So I'm extending
> >> >> > SimpleclientHttpRequestFactory and overriding the
> >> >> > openConnectionMethod.
> >> >> > I
> >> >> > need to do this to trust my self-signed certificates and to use my
> >> >> > client
> >> >> > authentication certificate!
> >> >> >
> >> >> > So I init my sslContext and set to HttpURLConnection in this way:
> >> >> >
> >> >> > private SSLSocketFactory getSSLSocketFactory() throws
> >> >> > KeyStoreException,
> >> >> > KeyManagementException, NoSuchAlgorithmException,
> >> >> > CertificateException,
> >> >> > IOException, UnrecoverableKeyException{
> >> >> >     final InputStream trustStoreLocation =
> >> >> > mContext.getResources().openRawResource(R.raw.trust_store);
> >> >> >     final String trustStorePassword = "........";
> >> >> >
> >> >> >     final InputStream keyStoreLocation =
> >> >> > mContext.getResources().openRawResource(R.raw.key_store);
> >> >> >     final String keyStorePassword = "........";
> >> >> >
> >> >> >     final KeyStore trustStore = KeyStore.getInstance("BKS");
> >> >> >     trustStore.load(trustStoreLocation,
> >> >> > trustStorePassword.toCharArray());
> >> >> >
> >> >> >     final KeyStore keyStore = KeyStore.getInstance("BKS");
> >> >> >     keyStore.load(keyStoreLocation,
> keyStorePassword.toCharArray());
> >> >> >
> >> >> >     final TrustManagerFactory tmf =
> >> >> >
> >> >> >
> >> >> >
> TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
> >> >> >     tmf.init(trustStore);
> >> >> >
> >> >> >     final KeyManagerFactory kmf =
> >> >> >
> >> >> >
> KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
> >> >> >     kmf.init(keyStore, keyStorePassword.toCharArray());
> >> >> >
> >> >> >     final SSLContext sslCtx = SSLContext.getInstance("TLS");
> >> >> >     sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new
> >> >> > SecureRandom());
> >> >> >
> >> >> >     return sslCtx.getSocketFactory();
> >> >> > }
> >> >> >
> >> >> > @Override
> >> >> > protected HttpURLConnection openConnection(URL url, Proxy proxy)
> >> >> > throws
> >> >> > IOException {
> >> >> >     final HttpURLConnection httpUrlConnection =
> >> >> > super.openConnection(url,
> >> >> > proxy);
> >> >> >     if (url.getProtocol().toLowerCase().equals("https")) {
> >> >> >         try {
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> ((HttpsURLConnection)httpUrlConnection).setSSLSocketFactory(getSSLSocketFactory());
> >> >> >
> >> >> > ((HttpsURLConnection)httpUrlConnection).setHostnameVerifier(new
> >> >> > NullHostnameVerifier());
> >> >> >         } catch (Exception e) {
> >> >> >             if (LogConfig.ERROR_LOGS_ENABLED){
> >> >> >                 Log.e(LOG_TAG, e.getMessage());
> >> >> >         }
> >> >> >
> >> >> >     }
> >> >> >     return httpUrlConnection;
> >> >> > }
> >> >> >
> >> >> > private static class NullHostnameVerifier implements
> HostnameVerifier
> >> >> > {
> >> >> >     public boolean verify(String hostname, SSLSession session) {
> >> >> >         return true;
> >> >> >     }
> >> >> > }
> >> >> >
> >> >> > When tomcat clientAuth is disabled it works fine.
> >> >> >
> >> >> > But when tomcat client authentication is enabled, trying to
> establish
> >> >> > connection from android device I got this exception:
> >> >> >
> >> >> > error:140943F2:SSL routines:SSL3_READ_BYTES:sslv3 alert unexpected
> >> >> > message
> >> >> > (external/openssl/ssl/s3_pkt.c:1232 0x19bf40:0x00000003); nested
> >> >> > exception
> >> >> > is javax.net.ssl.SSLProtocolException: SSL handshake terminated:
> >> >> > ssl=0x182c70: Failure in SSL library, usually a protocol error
> >> >> >
> >> >> > I've tryed to install the client certificate on my web browser for
> >> >> > testing
> >> >> > purpose and everything goes ok! So I think it's a problem of my
> >> >> > android
> >> >> > application!
> >> >> >
> >> >> > Have you ever got this kind of exception?
> >> >> >
> >> >> > --
> >> >> > You received this message because you are subscribed to the Google
> >> >> > Groups
> >> >> > "Android Security Discussions" group.
> >> >> > To view this discussion on the web visit
> >> >> >
> >> >> >
> https://groups.google.com/d/msg/android-security-discuss/-/82sSkozTixAJ.
> >> >> > To post to this group, send email to
> >> >> > [email protected].
> >> >> > To unsubscribe from this group, send email to
> >> >> > [email protected].
> >> >> > For more options, visit this group at
> >> >> > http://groups.google.com/group/android-security-discuss?hl=en.
> >> >
> >> >
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Android Security Discussions" group.
> > To view this discussion on the web visit
> > https://groups.google.com/d/msg/android-security-discuss/-/PT7WLNR-HJkJ.
> >
> > To post to this group, send email to
> > [email protected].
> > To unsubscribe from this group, send email to
> > [email protected].
> > For more options, visit this group at
> > http://groups.google.com/group/android-security-discuss?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Android Security Discussions" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/android-security-discuss?hl=en.

Reply via email to