在同一插座上安全且不安全的连接

时间:2011-01-06 14:25:16

标签: cocoa sockets ssl

我有一些Python代码,我正在尝试翻译成Obj-C / Cocoa。它需要网络连接;初始化字符串以明文形式发送,然后连接得到保护。 基本上,它的工作原理如下:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host,port))
sock.send( ... )
sock.recv( ... )
sslSock = ssl.wrap_socket(sock)
sslSock.send( ... )
sslSock.recv( ...)

到目前为止,我有以下内容。首先,我创建套接字连接和R / W流:

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)HOST, PORT, &readStream, &writeStream);

inputStream = (NSInputStream *)readStream;
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

outputStream = (NSOutputStream *)writeStream;
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[inputStream open];
[outputStream open];

发送NSStreamEventOpenCompleted时,我存储本机套接字句柄:

NSSocketNativeHandle *socketHandle = [[outputStream propertyForKey:(NSString *)kCFStreamPropertySocketNativeHandle] bytes];

我会根据需要处理NSStreamEventHasBytesAvailableNSStreamEventHasSpaceAvailable事件。然后从存储的套接字句柄创建两个新流,并设置SSL属性:

[inputStream close];
[outputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

CFStreamCreatePairWithSocket(kCFAllocatorDefault, *socketHandle, &readStream, &writeStream);

inputStream = (NSInputStream *)readStream;
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];

outputStream = (NSOutputStream *)writeStream;
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];

[inputStream open];
[outputStream open];

这就是我得到的。在两个新流上都会调用NSStreamEventOpenCompleted事件,但永远不会引发NSStreamEventHasBytesAvailableNSStreamEventHasSpaceAvailable个事件。我有什么想法吗?

1 个答案:

答案 0 :(得分:1)

看起来我的问题是双重的。

  1. 通过CFStreamCreatePairWithSocketToHost创建连接时,kCFStreamPropertyShouldCloseNativeSocket属性会自动设置为TRUE。它应该是假的。

    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)HOST, PORT, &readStream, &writeStream);
    inputStream = (NSInputStream *)readStream;
    [inputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyShouldCloseNativeSocket];
    
  2. 我没有正确设置SSL。

    NSMutableDictionary *sslSettings = [[NSMutableDictionary alloc] init];
    [sslSettings setObject:NSStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString *)kCFStreamSSLLevel];
    [sslSettings setObject:(id)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
    [sslSettings setObject:HOST forKey:(NSString *)kCFStreamSSLPeerName];
    [inputStream setProperty:sslSettings forKey:(NSString *)kCFStreamPropertySSLSettings];
    [inputStream open];