Now I have followed this tutorial for generate clientAuth keys:

http://www.maximporges.com/2009/11/18/configuring-tomcat-ssl-clientserver-authentication/

The only difference is that I don't use the same store for both key and
trust store.

Now, with this new certificate alias isn't null, I got "clientkey" as alias.

Executing your method I got the following log:

alias=clientkey
privatekey=RSA
cert subject=CN=MT Tablet Client, OU=IT, O=CPMAPAVE, L=Bienno, ST=BS, C=IT
cert issuer =CN=MT Tablet Client, OU=IT, O=CPMAPAVE, L=Bienno, ST=BS, C=IT
 --------------------------------
alias=servercert
cert subject=CN=MT Tablet Server, OU=IT, O=CPMAPAVE, L=Bienno, ST=BS, C=IT
cert issuer =CN=MT Tablet Server, OU=IT, O=CPMAPAVE, L=Bienno, ST=BS, C=IT


But now I got  I/O error: Fatal alert received bad_certificate; nested
exception is javax.net.ssl.SSLException: Fatal alert received
bad_certificate




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

> I would use something like this to dump information from your KeyStore
> instance. you could also just print the toString of the certs for more
> general info, or just the "getSigAlgName" to see what algorithm was
> used.
>
> -bri
>
>         Enumeration<String> e = keyStore.aliases();
>         while (e.hasMoreElements()) {
>             String alias = e.nextElement();
>             System.out.println("--------------------------------");
>             System.out.println("alias=" + alias);
>             if (keyStore.entryInstanceOf(alias,
> KeyStore.PrivateKeyEntry.class)) {
>                 System.out.println("privatekey=" +
> keyStore.getKey(alias, keyStorePassword).getAlgorithm());
>                 for (Certificate certificate :
> keyStore.getCertificateChain(alias)) {
>                     X509Certificate cert = (X509Certificate) certificate;
>                     System.out.println("cert subject=" +
> cert.getSubjectX500Principal());
>                     System.out.println("cert issuer =" +
> cert.getIssuerX500Principal());
>                 }
>             } else if (keyStore.entryInstanceOf(alias,
> KeyStore.SecretKeyEntry.class)) {
>                 System.out.println("secretkey=" +
> keyStore.getKey(alias, keyStorePassword).getAlgorithm());
>             } else if (keyStore.entryInstanceOf(alias,
> KeyStore.TrustedCertificateEntry.class)) {
>                 Certificate certificate = keyStore.getCertificate(alias);
>                 X509Certificate cert = (X509Certificate) certificate;
>                 System.out.println("cert subject=" +
> cert.getSubjectX500Principal());
>                 System.out.println("cert issuer =" +
> cert.getIssuerX500Principal());
>             }
>         }
>
>
> On Sun, Aug 26, 2012 at 11:38 PM, Marco Serioli <[email protected]>
> wrote:
> > 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