On Wed, Oct 3, 2012 at 9:58 PM, Marco Serioli <[email protected]> wrote:
> I think that in your prepareConnection you should call:
>
> ((HttpsURLConnection)httpUrlConnection).setSSLSocketFactory(getSSLSocketFactory());
>
> where getSSLSocketFactory() looks something like this:
>
> private SSLSocketFactory getSSLSocketFactory() throws KeyStoreException,
> KeyManagementException, NoSuchAlgorithmException, CertificateException,
> IOException, UnrecoverableKeyException, NoSuchProviderException{
> final InputStream trustStoreLocation =
> mContext.getResources().openRawResource(R.raw.server);
> final String trustStorePassword = "pwd";
> final InputStream keyStoreLocation =
> mContext.getResources().openRawResource(R.raw.client);
> final String keyStorePassword = "pwd";
> final KeyStore trustStore = KeyStore.getInstance("BKS");
> trustStore.load(trustStoreLocation, trustStorePassword.toCharArray());
> final KeyStore keyStore = KeyStore.getInstance("BKS");
> keyStore.load(keyStoreLocation, keyStorePassword.toCharArray());
Instead of using a BKS file a resource, you could include the
X509Certificate as a PEM or DER encoded file and then use
CertificateFactory.getInstance("X.509") to load it from a resource,
then create a KeyStore from that on the file. or just embed the PEM as
a java.lang.String or DER as a byte[].
>
> 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();
> }
>
> In this case you have to use same password for certificate/keystore!!! I'm
> using also client authentication.. if you don't use it I think you can pass
> null as TrustManager:
>
> sslCtx.init(kmf.getKeyManagers(), null, new SecureRandom());
just to clarify, this is backwards. TrustManger is for establishing
server trust, KeyManager is source of private keys for identifying
yourself to the peer. so if not using client certificates, leave out
the KeyManager.
I try to mention this in the docs:
http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html
>
> So when you instantiate the RestTemplateObject:
>
> restTemplate = new RestTemplate(new MyClientHttpRequestFactory(context));
>
> Hope it helps!
> Bye
> Marco
>
> 2012/10/3 Brian Carlstrom <[email protected]>
>>
>> Anand,
>>
>> We have some doc here:
>>
>> http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html
>>
>> the main thing is to make a custom TrustManager that trusts your
>> self-signed cert. you seem to just be disabling hostname verification
>> which is unnecessary if your cert's CN value matches your server
>> hostname (and a bit dangerous in general)
>>
>> -bri
>>
>> On Wed, Oct 3, 2012 at 11:22 AM, Anand <[email protected]> wrote:
>> > Hi Brian/Marco,
>> >
>> > I am looking do to a similar thing for our Android application. Access a
>> > server that has a self signed certificate with Android Rest Template, on
>> > Android 2.3. I tried to using the similar code that Marco used. This
>> > however
>> > does not do the job for me. Any suggestions would be really appreciated
>> > because I am stuck.
>> >
>> > public class NullHostNameVerifier implements HostnameVerifier {
>> >
>> > public boolean verify(String hostname, SSLSession session) {
>> > return true;
>> > }
>> > }
>> >
>> > public class MySimpleClientHttpRequestFactory extends
>> > SimpleClientHttpRequestFactory {
>> >
>> > private final HostnameVerifier verifier;
>> >
>> > public MySimpleClientHttpRequestFactory(HostnameVerifier verifier) {
>> > this.verifier = verifier;
>> > }
>> >
>> > @Override
>> > protected void prepareConnection(HttpURLConnection connection, String
>> > httpMethod) throws IOException {
>> > if (connection instanceof HttpsURLConnection) {
>> > ((HttpsURLConnection) connection).setHostnameVerifier(verifier);
>> > }
>> > super.prepareConnection(connection, httpMethod);
>> > }
>> >
>> > }
>> >
>> > HostnameVerifier nullVerifier = new NullHostNameVerifier();
>> > requestFactory = new MySimpleClientHttpRequestFactory(nullVerifier);
>> > }
>> >
>> >
>> > RestTemplate restTemplate = new RestTemplate(requestFactory);
>> > restTemplate.setRequestFactory(requestFactory);
>> >
>> >
>> >
>> >
>> > On Friday, August 31, 2012 3:20:47 PM UTC-5, Brian Carlstrom wrote:
>> >>
>> >> I believe it will work with different store and key passwords if you
>> >> supply the key password as the second argument to
>> >> KeyManagerFactory.init, instead of the store password as you are doing
>> >> here:
>> >>
>> >> kmf.init(keyStore, keyStorePassword.toCharArray())
>> >>
>> >> you already have supplied to the keyStorePassword when creating the
>> >> keyStore, so its already decrypted, you need to give the second
>> >> password to decrypt the individual key entry. note if you give
>> >> different passwords to different keys, it has to be the password
>> >> needed by the key returned by chooseClientAlias
>> >>
>> >> -bri
>> >>
>> >> On Fri, Aug 31, 2012 at 1:10 PM, Marco Serioli <[email protected]>
>> >> wrote:
>> >> > I've tried some test case and I found that I have problems when I try
>> >> > to
>> >> > generate certificates with keypass != storepass.
>> >> >
>> >> > In the first attempt I've made, I've used default SSL provider with
>> >> > keypass
>> >> > != storepass and I get:
>> >> >
>> >> >
>> >> > 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
>> >> >
>> >> >
>> >> > In the second attempt I've used HarmonyJSSE with keypass != storepass
>> >> > and I
>> >> > get:
>> >> > at java.lang.Thread.run(Thread.java:1020)
>> >> >
>> >> >
>> >> > In third attempt I have tried to create new certificates, and
>> >> > casually I
>> >> > have used keypass == storepass with HarmonyJSSE. It gives me:
>> >> >
>> >> > I/O error: Fatal alert received bad_certificate; nested exception is
>> >> > javax.net.ssl.SSLException: Fatal alert received bad_certificate
>> >> >
>> >> >
>> >> > In the last attempt, using keypass == storepass and removing
>> >> > HarmonyJSSE
>> >> > it
>> >> > works!
>> >> >
>> >> > I've also find in tomcat 6 documentation:
>> >> >
>> >> > Note: your private key password and keystore password should be the
>> >> > same. If
>> >> > they differ, you will get an error along the lines of
>> >> > java.io.IOException:
>> >> > Cannot recover key, as documented in Bugzilla issue 38217, which
>> >> > contains
>> >> > further references for this issue.
>> >> >
>> >> >
>> >> > Thank you for helping me!!
>> >> > you've been very kind
>> >> >
>> >> > 2012/8/31 Brian Carlstrom <[email protected]>
>> >> >>
>> >> >> That is good to hear. There have been some client cert fixes for the
>> >> >> non-default provider post 4.1, so I'm not entirely surprised it is
>> >> >> not
>> >> >> working.
>> >> >>
>> >> >> -bri
>> >> >>
>> >> >>
>> >> >> On Fri, Aug 31, 2012 at 2:41 AM, Marco Serioli <[email protected]>
>> >> >> wrote:
>> >> >>>
>> >> >>> Using default provider... it works :D
>> >> >>>
>> >> >>>
>> >> >>> 2012/8/29 Brian Carlstrom <[email protected]>
>> >> >>>>
>> >> >>>> In wireshark, I select the first packet, right click, "Decode
>> >> >>>> As..."
>> >> >>>> select "Transport" tab and "SSL" from the list
>> >> >>>>
>> >> >>>> then looking at the Protocol SSL and SSLv3 packets, i'll focus on
>> >> >>>> the
>> >> >>>> ones that might help identify the issue (there is some description
>> >> >>>> of
>> >> >>>> all
>> >> >>>> this that might be helpful at
>> >> >>>> http://en.wikipedia.org/wiki/Transport_Layer_Security)
>> >> >>>>
>> >> >>>> #4 is Client Hello from client to server
>> >> >>>>
>> >> >>>> #7 has 4 things from server to client
>> >> >>>> Server Hello
>> >> >>>> Certificate
>> >> >>>> Certificate Request
>> >> >>>> Server Hello Done
>> >> >>>>
>> >> >>>> select #7 and expanding the Secure Socket Layer messages at the
>> >> >>>> bottom,
>> >> >>>> you can see the Certificate Request contains the info being passed
>> >> >>>> to
>> >> >>>> the
>> >> >>>> KeyManager include the types of RSA and RSA and same issuer
>> >> >>>> repeated
>> >> >>>> twice
>> >> >>>>
>> >> >>>> #10 has 3 things from client to server
>> >> >>>> Certificate
>> >> >>>> Client Key Exchange
>> >> >>>> Certificate verify.
>> >> >>>>
>> >> >>>> selecting #10 and expanding the Certificate (that is the client
>> >> >>>> certificate being sent to the server), we see it is certificate
>> >> >>>> with
>> >> >>>> Common
>> >> >>>> Name (CN) as "MT Tablet Client"
>> >> >>>>
>> >> >>>> #12 is Change Cipher Spec from client to server
>> >> >>>>
>> >> >>>> #14 is Encrypted Handshake Message from client to server
>> >> >>>>
>> >> >>>> #16 is a fatal Alert about a Bad Certificate from the server to
>> >> >>>> the
>> >> >>>> client. that is resulting in your "Fatal alert received
>> >> >>>> bad_certificate;
>> >> >>>> nested exception is javax.net.ssl.SSLException: Fatal alert
>> >> >>>> received
>> >> >>>> bad_certificate". The server doesn't like what you sent. maybe
>> >> >>>> because you
>> >> >>>> aren't sending a certificate chain by returning a result from
>> >> >>>> getCertificateChain above? But if I recall correctly, these were
>> >> >>>> self
>> >> >>>> signed, so there would be no chain.
>> >> >>>>
>> >> >>>> In any case, the " "Fatal alert received bad_certificate; nested
>> >> >>>> exception is javax.net.ssl.SSLException: Fatal alert received
>> >> >>>> bad_certificate"." is from the HarmonyJSSE provider, I'd try going
>> >> >>>> back to
>> >> >>>> the default provider to see what happens. I'd also do a similar
>> >> >>>> tcpdump and
>> >> >>>> compare with what is being sent in the chrome case, since clearly
>> >> >>>> it
>> >> >>>> is
>> >> >>>> something it doesn't like about the "Certificate" message being
>> >> >>>> sent
>> >> >>>> from
>> >> >>>> the client to the server.
>> >> >>>>
>> >> >>>> -bri
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>> On Wed, Aug 29, 2012 at 2:44 AM, Marco Serioli <[email protected]>
>> >> >>>> wrote:
>> >> >>>>>
>> >> >>>>> Here is the dump!
>> >> >>>>>
>> >> >>>>> Thank you!
>> >> >>>>> Marco
>> >> >>>>>
>> >> >>>>>
>> >> >>>>> 2012/8/28 Brian Carlstrom <[email protected]>
>> >> >>>>>>
>> >> >>>>>> feel free to attach the tcpdump and I can summarize what it
>> >> >>>>>> contains.
>> >> >>>>>>
>> >> >>>>>> -bri
>> >> >>>>>>
>> >> >>>>>> On Tue, Aug 28, 2012 at 1:00 AM, Marco Serioli
>> >> >>>>>> <[email protected]>
>> >> >>>>>> wrote:
>> >> >>>>>> > Thank you for quick replies!
>> >> >>>>>> >
>> >> >>>>>> > I have the tcpdump of connection, now I just have to figure
>> >> >>>>>> > out
>> >> >>>>>> > how
>> >> >>>>>> > to
>> >> >>>>>> > interpret it :)
>> >> >>>>>> >
>> >> >>>>>> > But I do not understand why with chrome client authentication
>> >> >>>>>> > works,
>> >> >>>>>> > while
>> >> >>>>>> > with Android not!
>> >> >>>>>> >
>> >> >>>>>> > 2012/8/27 Brian Carlstrom <[email protected]>
>> >> >>>>>> >>
>> >> >>>>>> >> I think the "bad_certificate" is just the server telling you
>> >> >>>>>> >> it
>> >> >>>>>> >> doesn't like your certificate. It seems odd that the client
>> >> >>>>>> >> certificate is self signed. the server is presumably trying
>> >> >>>>>> >> to
>> >> >>>>>> >> confirm
>> >> >>>>>> >> that the client certificate is trusted by it's trust manager,
>> >> >>>>>> >> but
>> >> >>>>>> >> does
>> >> >>>>>> >> it really have the client's certificate in it's trust
>> >> >>>>>> >> manager's
>> >> >>>>>> >> key
>> >> >>>>>> >> store? usually you would have one or more trusted CA issue
>> >> >>>>>> >> both
>> >> >>>>>> >> the
>> >> >>>>>> >> client and server certs and just trust the CAs on both sides.
>> >> >>>>>> >>
>> >> >>>>>> >> if you want to confirm this really is just a "bad
>> >> >>>>>> >> certificate"
>> >> >>>>>> >> message
>> >> >>>>>> >> from the server, you can use tcpdump. I realize I forgot to
>> >> >>>>>> >> include
>> >> >>>>>> >> the instructions before, so I'll append some notes before. I
>> >> >>>>>> >> did
>> >> >>>>>> >> check
>> >> >>>>>> >> and it is in the emulator.
>> >> >>>>>> >>
>> >> >>>>>> >> -bri
>> >> >>>>>> >>
>> >> >>>>>> >> TCPDUMP
>> >> >>>>>> >> - To start capturing to tcpdump.pck (interrupt when done)
>> >> >>>>>> >> adb remount
>> >> >>>>>> >> adb shell tcpdump -s 0 -w /sdcard/tcpdump.pck
>> >> >>>>>> >> - add "host foo" after options for host filtering
>> >> >>>>>> >> - To pull from device to host and examine with wireshark UI
>> >> >>>>>> >> tool
>> >> >>>>>> >> adb pull /sdcard/tcpdump.pck /tmp/tcpdump.pck
>> >> >>>>>> >> wireshark /tmp/tcpdump.pck
>> >> >>>>>> >>
>> >> >>>>>> >>
>> >> >>>>>> >> On Mon, Aug 27, 2012 at 2:52 AM, Marco Serioli
>> >> >>>>>> >> <[email protected]>
>> >> >>>>>> >> wrote:
>> >> >>>>>> >> > 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
>> >> >>>>>> >> >> >>
--
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.