设置支持SNI的TLS1.2连接

我们正在尝试设置TLS1.2连接。 已经在Macbook下载了最新的OpenSSL。 使用此代码创buildTLS1.2连接。
但是,这个特定的线路可能会导致问题。 它使用TLSv1。

/* ---------------------------------------------------------- * * Set SSLv2 client hello, also announce SSLv3 and TLSv1 * * ---------------------------------------------------------- */ method = SSLv23_client_method(); 

尝试了TLSv1_2_client_method()方法,但它给出了下面的链接错误:

体系结构x86_64的未定义符号:“_TLSv1_2_client_method”,引用来自:sslconnect-7aa462.o中的_main

如果有人可以协助创buildTLS1.2连接,然后从目标C调用(如果需要对套接字编程进行一些特殊处理),那将是非常有帮助的。

[请注意,我不是一个iOS的人。 我正在帮助一个团队解决问题。 也是自己的socket编程新手,虽然团队有一些经验。

尝试了TLSv1_2_client_method()方法,但它给出了下面的链接错误:

体系结构x86_64的未定义符号:“_TLSv1_2_client_method”,引用来自:sslconnect-7aa462.o中的_main

好吧,这听起来像你正在连接到x86_64 ,但你需要iOS。 您可以使用以下两个命令validation架构:

 xcrun -sdk iphoneos lipo -info libcrypto.a xcrun -sdk iphoneos lipo -info libssl.a 

例如:

 $ xcrun -sdk iphoneos lipo -info /usr/local/ssl/ios/lib/libcrypto.a Architectures in the fat file: /usr/local/ssl/ios/lib/libcrypto.a are: armv7 armv7s arm64 i386 

前三个架构是自我解释的; 而i386是iOSdebugging器。

注意/usr/local/ssl/ios/是我在安装OpenSSL for iOS之后创build的。 苹果不提供它。

如果你没有四个iOS架构,那么你有两个select。 首先,您可以基于“OpenSSL FIPS对象模块用户指南” (第122页,附录E.2)中的iOS过程进行构build。

其次是从GitHub下载预build版本。 这是一个由OpenSSL 1.0.1h使用OpenSSL的程序构build的noloader的GitHub。 这里有另一个来自Stefan Arentz ,似乎很受欢迎,但它的OpenSSL 1.0.1g。


然后从目标C调用

C和Objective C一起工作得很好。调用它没什么特别的。


…支持iPhone应用程序的SNI

在客户端上,您将需要使用SSL_set_tlsext_host_name设置服务器名称。

在服务器上,因为处理callback而涉及更多。 有关示例,请参阅使用SNI在一个框中提供多个域 。


快速评论一下:

method = SSLv23_client_method();

尝试了TLSv1_2_client_method()方法

理想情况下,你是这样的:

 SSL_library_init(); SSL_load_error_strings(); const SSL_METHOD* method = SSLv23_method(); if(NULL == method) handleFailure(); SSL_CTX* ctx = SSL_CTX_new(method); if(ctx == NULL) handleFailure(); /* Cannot fail ??? */ const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION; SSL_CTX_set_options(ctx, flags); ... 

SSLv23_method得到你SSLv2及以上。 然后你删除你不想要的,如SSLv2,SSLv3和压缩。 这让你的TLS 1.0及以上(TLS 1.3即将到来,所以你得到它没有源代码的变化)。 您将获得服务器支持的最高协议(例如,TL​​S 1.2)。

另一方面,这只会让你只有TLS 1.2:

 SSL_library_init(); SSL_load_error_strings(); const SSL_METHOD* method = TLSv1_2_client_method(); if(NULL == method) handleFailure(); 

这意味着您将无法连接到运行TLS 1.0的服务器(如许多IIS服务器)。 如果您使用ECC连接到Google服务器,则需要确保禁用压缩。 否则,你会失败,因为谷歌有一个奇怪的要求,即在使用带有ECC的TLS 1.2时必须禁用压缩。

在你的评论的情况下:

 /* ---------------------------------------------------------- * * Set SSLv2 client hello, also announce SSLv3 and TLSv1 * * ---------------------------------------------------------- */ 

你会使用以下,但我不推荐它:

 long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_TLS1_1 | SSL_OP_NO_TLS1_2; 

我不推荐它,因为它禁用了TLS 1.2和TLS 1.1; 它启用SSLv3。 2014年没有SSLv3的理由。


还有一点意见….

请务必使用SSL_CTX_set_cipher_list设置您的密码套件。 select你最喜欢的16个左右,并忽略其余的。 对于它的文档(以及DHE-RSA-AES256-SHA等密码套件的名称),请参阅SSL_CTX_set_cipher_list(3)ciphers(1)

select16个左右的密码套件实现了两个目标。 首先,它确保你得到你想要的。 其次,它确保像F5或IronPort这样的旧设备不会窒息。 较旧的设备使用固定大小的缓冲区,对于具有80多个密码套件的ClientHello ,该缓冲区太小。 ClientHello通过,如果有16或20密码套件。


最后一点评论

1.1.0之前的OpenSSL 不会执行主机名匹配。 但是,它确实执行了其他的习惯性检查。 所以如果你是1.0.2或更低,你将不得不执行主机名匹配。 有关检查的信息,请参阅OpenSSL wiki上的SSL / TLS客户端 。