如何为SSL握手配置CFStream(或NSStream)?

问题描述:

我正在使用CFStream/NSStream进行http连接。 我希望能够检测到一个SSL握手三种情况将失败:如何为SSL握手配置CFStream(或NSStream)?

  • 情况答:服务器不被信任
  • 情况下,B:服务器是可信的,但要求客户证书
  • 情况下,C:服务器不被信任,并要求客户端证书

今天没有在我的CFStream的SSL性能做anithing,我得到:

  • 情况A:错误-9807
  • 情况B:没有错误,但服务器拒绝连接(误差500)
  • 情况C:错误9807

是否有配置CFStream正确区分这些方式3例?或者在SSL握手期间有一些回调?

感谢您的帮助。

前段时间我用CFSockets使用SSL运行同样的事情。 CFStream处理所有的握手内容。我为NSStream写了一个小类(基本代码来自Apple,不再有链接,如果我找到它,我会添加它)。这对我来说很有用。

接口

@interface NSStream (FSNetworkAdditions) 

+ (void)qNetworkAdditions_getStreamsToHostNamed:(NSString *)hostName 
              port:(NSInteger)port 
            inputStream:(out NSInputStream **)inputStreamPtr 
            outputStream:(out NSOutputStream **)outputStreamPtr; 

@end 

与实现

#import "FSNetworkAdditions.h" 

@implementation NSStream (FSNetworkAdditions) 

+ (void)qNetworkAdditions_getStreamsToHostNamed:(NSString *)hostName 
              port:(NSInteger)port 
            inputStream:(out NSInputStream **)inputStreamPtr 
            outputStream:(out NSOutputStream **)outputStreamPtr 
{ 
    CFReadStreamRef  readStream; 
    CFWriteStreamRef writeStream; 

    assert(hostName != nil); 
    assert((port > 0) && (port < 65536)); 
    assert((inputStreamPtr != NULL) || (outputStreamPtr != NULL)); 

    readStream = NULL; 
    writeStream = NULL; 

    CFStreamCreatePairWithSocketToHost(
             NULL, 
             (CFStringRef) hostName, 
             port, 
             ((inputStreamPtr != NULL) ? &readStream : NULL), 
             ((outputStreamPtr != NULL) ? &writeStream : NULL) 
             ); 

    NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys: 
           [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates, 
           [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot, 
           [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots, 
           [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain, 
           //kCFNull,kCFStreamSSLPeerName, 
           kCFStreamSocketSecurityLevelSSLv3, kCFStreamSSLLevel, 
           [NSNumber numberWithBool:YES], kCFStreamPropertyShouldCloseNativeSocket, 
           nil]; 

    if (readStream) { 
     CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); 
    } 

    if (writeStream) { 
     CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); 
    } 

    if (inputStreamPtr != NULL) { 
     *inputStreamPtr = CFBridgingRelease(readStream); 
    } 
    if (outputStreamPtr != NULL) { 
     *outputStreamPtr = CFBridgingRelease(writeStream); 
    } 


} 

@end 

这就是它不是你可以连接到这样的服务器:

NSInputStream *inputStream; 
NSOutputStream *outputStream; 
[NSStream qNetworkAdditions_getStreamsToHostNamed:host 
              port:port 
             inputStream:&inputStream 
            outputStream:&outputStream]; 

     inputStream.delegate = self; 
     outputStream.delegate = self; 

其中 “自我” 符合NSStreamDelegate协议。

我希望这些代码片段有所帮助。

+1

下面是Arndt引用的Apple文档的链接:https://developer.apple.com/library/ios/qa/qa1652/_index.html – Fletch