在iOS 5上使用NSURLConnection的双向SSL

时间:2012-04-02 21:47:05

标签: ios ssl nsurlconnection ssl-certificate

我正在尝试访问https网站的UIWebView,请求双向SSL的客户端证书。 我的出发点是Apple文档:Certificate, Key, and Trust Services Programming Guide stackoverflow上也有很多帮助。

我想出了以下代码来回答身份验证质询,加载p12身份文件和crt中间证书,然后展示它们。

-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(@"Auth method: %@", challenge.protectionSpace.authenticationMethod);
if([challenge previousFailureCount] <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];
}
}

结果很好......不太好。呼叫结束时握手失败。使用chrome和相同的证书调用网站实际上工作正常,这导致我检查Wireshark这两个调用之间的区别是什么。

使用Chrome,一切看起来都很好,就像TLS握手一样。

iOS使用TLSv1和Chrome使用SSLv3:这应该不是问题。 更有趣的是我的程序由于某种原因发送并且空的证书握手信息:

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

然后是第二个具有适当内容的人:

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)

有没有人见过这样的东西?

我很确定我在某个地方犯了一些非常愚蠢的错误,因为似乎其他一些拥有相同代码的人正在努力实现我几天来一直试图做的事情......

0 个答案:

没有答案