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 >> >> > "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.
