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.