Note that there are some explanatory texts on larger screens.

plurals
  1. POTwo way SSL with NSURLConnection on iOS 5
    primarykey
    data
    text
    <p>First I would like to apologize about the length of this question, but I'm having problems for two nights straight and trying to document the problem clearly.</p> <p>I'm trying to have a UIWebView accessing an https website requesting a client certificate for two way SSL. My starting point has been Apple documentation: <a href="http://developer.apple.com/library/ios/#DOCUMENTATION/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW13">Certificate, Key, and Trust Services Programming Guide</a> There is also plenty of help on stackoverflow.</p> <p>I came up with the following code to answer the authentication challenge, loading the p12 identity file and the crt intermediates certs, and then presenting them.</p> <pre class="lang-c prettyprint-override"><code>-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { NSLog(@"Auth method: %@", challenge.protectionSpace.authenticationMethod); if([challenge previousFailureCount] &lt;5) { NSURLProtectionSpace *protectionSpace = [challenge protectionSpace]; NSString *authMethod = [protectionSpace authenticationMethod]; if(authMethod == NSURLAuthenticationMethodServerTrust ) { NSLog(@"Verifying The Trust"); [[challenge sender] useCredential:[NSURLCredential credentialForTrust:[protectionSpace serverTrust]] forAuthenticationChallenge:challenge]; } else if(authMethod == NSURLAuthenticationMethodClientCertificate ) { NSLog(@"Getting client certificate"); SecIdentityRef identity = [self getClientCertificate:@"mycert" withPassword:@"password"]; SecCertificateRef intermediateCert = [self getCertificate:@"intermediatecert"]; SecCertificateRef rootCA = [self getCertificate:@"cacert"]; NSMutableArray *combinedCerts = [NSMutableArray array]; [combinedCerts addObject:(__bridge id)intermediateCert]; [combinedCerts addObject:(__bridge id)rootCA]; NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:combinedCerts persistence:NSURLCredentialPersistencePermanent]; NSLog(@"Sending credential"); [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; } else { NSLog(@"Not dealing with challenge %@",authMethod); } } else { NSLog(@"Auth Challenge Failed"); [[challenge sender] cancelAuthenticationChallenge:challenge]; } } </code></pre> <p>The results are, well... not really good. The call is finishing with an handshake failure. Calling the website with chrome and the same cert is actually working fine, which led me to check in Wireshark what is the difference between the two calls.</p> <p>With Chrome, everything looks fine, the way it should for a TLS handshake.</p> <p>iOS is going with TLSv1 and Chrome with SSLv3: this shouldn't be a problem. What is more intriguing is my program sending for some reason and empty certificate handshake msg:</p> <pre><code>Frame 102: 66 bytes on wire (528 bits), 66 bytes captured (528 bits) Ethernet II, Src: Apple_XX:XX:XX (XX:XX:XX:XX:XX:XX), Dst: Cisco-Li_3d:96:d0 (XX:XX:XX:XX:XX:XX) Internet Protocol Version 4, Src: imac.local (192.168.1.9), Dst: xxx.xxx.xxx (xxx.xxx.xxx.xxx) Transmission Control Protocol, Src Port: 63324 (63324), Dst Port: https (443), Seq: 187, Ack: 4244, Len: 12 Secure Sockets Layer TLSv1 Record Layer: Handshake Protocol: Certificate Content Type: Handshake (22) Version: TLS 1.0 (0x0301) Length: 7 Handshake Protocol: Certificate Handshake Type: Certificate (11) Length: 3 Certificates Length: 0 </code></pre> <p>and then a second one with the proper content:</p> <pre><code>Frame 108: 248 bytes on wire (1984 bits), 248 bytes captured (1984 bits) Ethernet II, Src: Apple_XX:XX:XX (XX:XX:XX:XX:XX:XX), Dst: Cisco-Li_XX:XX:XX (XX:XX:XX:XX:XX) Internet Protocol Version 4, Src: imac.local (192.168.1.9), Dst: xxx.xxx.xxx (xxx.xxx.xxx.xxx) Transmission Control Protocol, Src Port: 63325 (63325), Dst Port: https (443), Seq: 2947, Ack: 4244, Len: 194 [3 Reassembled TCP Segments (2954 bytes): #106(1380), #107(1380), #108(194)] Secure Sockets Layer TLSv1 Record Layer: Handshake Protocol: Certificate Content Type: Handshake (22) Version: TLS 1.0 (0x0301) Length: 2949 Handshake Protocol: Certificate Handshake Type: Certificate (11) Length: 2945 Certificates Length: 2942 Certificates (2942 bytes) Certificate Length: 1024 Certificate (id-at-organizationName=XX,id-at-organizationalUnitName=XX,id-at-serialNumber=XX,id-at-countryName=XX,id-at-commonName=XXXXXX) Certificate Length: 995 Certificate (id-at-serialNumber=XX,id-at-commonName=XXXX,id-at-countryName=XX) Certificate Length: 914 Certificate (id-at-commonName=XXXX,id-at-countryName=XX) </code></pre> <p>Did anybody ever see something like that?</p> <p>I'm pretty sure I made some really stupid mistake somewhere as it seems some other people with pretty much the same code are managing to achieve what I've been trying to do for some days now...</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload