Hi Brian, 

every user of my app has its own client certificate installed: for example 
CN=N127391
These client certificates are signed by the root authority (This 
certificate is also installed on the device)
The problem is that I still get the *403 forbidden error* (authentication 
fails), when I connect with an android device.. 
With a windows device (for example with the internet explorer or chrom), it 
works. 

*first use case: authentication* (Single Sign On, so that android user does 
not have to type in his password)
The use case is that I want to authenticate the android clients to the 
server (WCF Service). 
In the WCF Service I can then extract the Number ("N127391") and use for 
example ASP Membership. 

So for the first use case I would need class which transfers the 
certificate to the server. In the google code I 
have found the SSLSocketFactory: 

 * SSLSocketFactory will enable client authentication when supplied with a
 * {@link KeyStore keystore} file containg a private key/public certificate
 * pair. The client secure socket will use the private key to authenticate
 * itself to the target HTTPS server during the SSL session handshake if
 * requested to do so by the server. The target HTTPS server will in its 
turn
 * verify the certificate presented by the client in order to establish 
client's
 * authenticity

So I guess I have to use this class for the authentication?

*seconde use case: encryption *
The traffic should be encrypted (SSL). That's why I need the server 
certificate. 

Is there a simple way how I can achieve these two use cases. 
I am new to android and I am trying to accomplish this for weeks :(. 

I hope you can help me. 

best regards, 
jens



Am Mittwoch, 28. November 2012 19:29:13 UTC+1 schrieb Brian Carlstrom:
>
> I don't recall the exact reasons why the Email code is the way it is. I 
> think the primary reason is that they don't know ahead of time if the 
> server is going to want a client cert, so they install a manager to record 
> the fact that a cert was requested, then do some UI to ask the user what 
> they want to use, then use a different one configured with the users 
> choice. 
>
> it's much simpler in an app where you know ahead of time what client cert 
> to use. is that your case? if so, I'd ignore the email example code as 
> overly convoluted for your use case.
>
> -bri
>
>
> On Wed, Nov 28, 2012 at 4:31 AM, Jens Hoffmann 
> <jenss...@gmail.com<javascript:>
> > wrote:
>
>> Hi Brian,
>> yes, I took a look at the SSLUtils.class. 
>> The class *TrackingKeyManager* (static class inside the SSLUtils) 
>> extends the class *StubKeyManager* which extends the class *
>> X509ExtendedKeyManager*.
>> But why do I need this class? I tried to use the 
>> SSLCertificateSocketFactory instead (It has *X509KeyManager* Object 
>> inside) . But unfortunately I got an 403 response, access forbidden. 
>>
>> It also throws an exception: 
>>
>> java.io.FileNotFoundException: 
>> https://nameoftheserver/MyService/Service.svc/rest/GetDNumber
>>
>>  
>>
>> I have tested the WCF Service with the Internet Explorer and it works 
>> just fine. 
>> Is my client certificate may be not transferred, so that the server does 
>> not get the public key?
>>  
>>
>> Code: 
>> SSLCertificateSocketFactory sslCertificateSocketFactory = null;
>> try {
>>     KeyManager keyManager = KeyChainKeyManager.fromAlias(
>>             getApplicationContext(), ht.mClientCertAlias);
>>  
>>
>>     sslCertificateSocketFactory = SSLUtils.getSSLSocketFactory(false); // 
>> use SSL
>>  
>>
>>     sslCertificateSocketFactory
>>             .setKeyManagers(new KeyManager[] { keyManager });
>>  
>>
>> } catch (CertificateException e1)..
>>  
>>
>> URL url = null;
>> try {
>>     url = new URL(this.url);
>> } catch (MalformedURLException e)..
>>  
>>
>> HttpsURLConnection urlConnection = null;
>> try {
>>     urlConnection = (HttpsURLConnection) url.openConnection();
>>     *urlConnection.setSSLSocketFactory(sslCertificateSocketFactory); *
>> } catch (IOException e)..
>>  
>>
>> try {
>>     iResponseCode =  urlConnection.getResponseCode();   
>>   *  if(iResponseCode == 403)*
>>     {
>>         Log.d(TAG, "Response Code is 403, Access forbidden.");
>>     }   
>>     InputStream in = urlConnection.getInputStream();
>> } catch (IOException e)..
>>  
>> I hope you can help me. Thanks in advance.
>>  
>> best regards, 
>>  jens
>>  
>>
>>
>>
>>
>> Am Dienstag, 27. November 2012 09:29:46 UTC+1 schrieb Jens Hoffmann:
>>
>>> Hi everybody,
>>>
>>> I am developing an android application which querys a WCF Webservice 
>>> (SSL + Authentication). 
>>> On this link (http://android-developers.**blogspot.de/2012/03/unifying-*
>>> *key-store-access-in-ics.html<http://android-developers.blogspot.de/2012/03/unifying-key-store-access-in-ics.html>)
>>>  
>>> I found the following: 
>>>
>>> "A common use of the private key is for SSL client authentication. This 
>>> can be implemented by 
>>> using an 
>>> HttpsURLConnection<http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html>with
>>>  a custom 
>>> X509KeyManager<http://developer.android.com/reference/javax/net/ssl/X509KeyManager.html>that
>>>  returns the PrivateKey 
>>> retrieved from the KeyChain API. The open source Email application for 
>>> ICS uses KeyChain 
>>> with an 
>>> X509ExtendedKeyManager<http://developer.android.com/reference/javax/net/ssl/X509ExtendedKeyManager.html>.
>>>  
>>> To learn more, have a look at the source code (in SSLUtils.java)."
>>>
>>> So I looked into this google code and tried to use the classes. But it 
>>> doesn't work. 
>>> I always get an 403 Error - Forbbiden. I really hope you can help me. 
>>>
>>> Here is some code:  
>>>
>>>
>>> Android:
>>>
>>> private void setHttpsAdvanced() {
>>> HostAuth ht = new HostAuth();
>>>  ht.mPort = 443;
>>> ht.mClientCertAlias = "jensZert";
>>>
>>> HttpParams params = getHttpParams();
>>>  MyThreadSafeClientConnManager ccm = MyThreadSafeClientConnManager
>>> .newInstance(params, true, 443); 
>>>
>>>  try {
>>> ccm.registerClientCert(**getApplicationContext(), ht);
>>> } catch (CertificateException e) {
>>>  e.printStackTrace();
>>> }
>>>
>>> this.httpclient = new DefaultHttpClient(ccm, params);
>>>
>>> connectionInfo = this.getConnectionInfo();
>>>
>>> this.url = String.format("%1$s://%2$s/%3$**s/%4$s",
>>>  connectionInfo.Protocol, connectionInfo.ServerName,
>>> connectionInfo.WebserviceName, connectionInfo.Path);
>>>
>>>  httpGet = new HttpGet(url);
>>> }
>>>
>>> private String callTheWebserviceCertificate() {
>>> this.setupClient();
>>>  String result = "";
>>>
>>> HttpResponse response = null;
>>> try {
>>>  response = (HttpResponse) this.httpclient.execute(**httpGet);
>>> result = EntityUtils.toString(response.**getEntity());
>>>
>>> } catch (ClientProtocolException e) {
>>>
>>> e.printStackTrace();
>>> } catch (IOException e) {
>>>  Log.d(TAG, result);
>>> }
>>> return result;
>>> } 
>>>
>>>
>>>
>>> My WCF Service web.config: 
>>>
>>> <behavior name="ServCertificatBehavior">
>>>   <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
>>>   <serviceDebug includeExceptionDetailInFaults**="true" />
>>>   <serviceAuthorization principalPermissionMode="**UseWindowsGroups" />
>>>   <serviceCredentials>
>>>  <clientCertificate>
>>>   <authentication certificateValidationMode="**PeerOrChainTrust" />
>>>  </clientCertificate>
>>> <serviceCertificate findValue="02 00 0b 30" storeLocation="LocalMachine" 
>>> storeName="My" x509FindType="**FindBySerialNumber" />
>>>   </serviceCredentials>
>>> </behavior>
>>>
>>> Best regards,
>>> jens
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>  -- 
>> 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/-/qKI0PaZewBoJ.
>>
>> To post to this group, send email to 
>> android-secu...@googlegroups.com<javascript:>
>> .
>> To unsubscribe from this group, send email to 
>> android-security-discuss+unsubscr...@googlegroups.com <javascript:>.
>> For more options, visit this group at 
>> http://groups.google.com/group/android-security-discuss?hl=en.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Android Security Discussions" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/android-security-discuss/-/mtzvEGj2YEAJ.
To post to this group, send email to android-security-discuss@googlegroups.com.
To unsubscribe from this group, send email to 
android-security-discuss+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/android-security-discuss?hl=en.

Reply via email to