如何为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协议。
我希望这些代码片段有所帮助。
下面是Arndt引用的Apple文档的链接:https://developer.apple.com/library/ios/qa/qa1652/_index.html – Fletch