如何在iOS上实现STARTTLS?

时间:2015-07-07 05:53:27

标签: ios objective-c ssl starttls

我想在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。
  • 最终,服务器发送STARTTLS的前瞻:

    . OK Begin TLS negotiation now.
    

现在是时候将套接字形式明文升级到TLS了。 接下来我该怎么做?

我认为我应该根据Apple's documentation执行此操作:

[ reader setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey ];
[ writer setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey ];

但这似乎没有做任何事情。我并不感到惊讶,因为文档非常清楚地表明它不起作用:

  

You must set the property before you open the stream.

当然,在这种情况下,流必须已经打开,因为它用于进行明文STARTTLS协商!

我找不到任何关于如何将套接字从明文升级到SSL的文档,或者如何在一组输入和输出明文流之上层叠一组新的SSL加密流。

1 个答案:

答案 0 :(得分:1)

我找不到使用高级CFStream API实现STARTTLS的任何方法。有CFStreamCreatePairWithSocket允许您连接自己的套接字,然后将TLS应用于它,但是没有办法让库根据证书主机名验证远程主机名。

唯一的方法就是使用这个低级别的库:Secure Transport Reference