我想在iOS应用程序中实现STARTTLS,但我无法从文档中找出如何执行此操作。
到目前为止,我有:
我使用CFStreamCreatePairWithSocketToHost
创建套接字并打开流:
CFStreamCreatePairWithSocketToHost(
NULL, (__bridge CFStringRef)host, port,
&read_stream, &write_stream
);
reader = objc_retainedObject(read_stream);
[ reader setDelegate:self ];
[ reader scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode ];
[ reader open ];
writer = objc_retainedObject(write_stream);
[ writer setDelegate:self ];
[ writer scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode ];
[ writer open ];
当数据在流上可用时,我得到了正确的回调,因此连接正常。
最终,服务器发送STARTTLS的前瞻:
. OK Begin TLS negotiation now.
现在是时候将套接字形式明文升级到TLS了。 接下来我该怎么做?
我认为我应该根据Apple's documentation执行此操作:
[ reader setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey ];
[ writer setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey ];
但这似乎没有做任何事情。我并不感到惊讶,因为文档非常清楚地表明它不起作用:
当然,在这种情况下,流必须已经打开,因为它用于进行明文STARTTLS协商!
我找不到任何关于如何将套接字从明文升级到SSL的文档,或者如何在一组输入和输出明文流之上层叠一组新的SSL加密流。
答案 0 :(得分:1)
我找不到使用高级CFStream API实现STARTTLS的任何方法。有CFStreamCreatePairWithSocket允许您连接自己的套接字,然后将TLS应用于它,但是没有办法让库根据证书主机名验证远程主机名。
唯一的方法就是使用这个低级别的库:Secure Transport Reference。