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]<javascript:>> 
> 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] <javascript:>> 
> >> 
> >> 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]<javascript:>> 
> 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] <javascript:>. 
> >> > To unsubscribe from this group, send email to 
> >> > [email protected] <javascript:>. 
> >> > 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.

Reply via email to