如何做一个用于测试SSL版本的客户端

最近由于工作的需要,需要升级建链过程中SSL的版本,因此有了这篇博文。

科普:

  版本排序,从小到大:SSLv2, SSLv3, TLSv1, TLSv1.1 and TLSv1.2

SSL_CTX_new:creates a new SSL_CTX object as framework to establish TLS/SSL enabled connections.
 #include <openssl/ssl.h>

 SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);

其中,要想知道 SSL_METHOD有多少个可以用的方法,参见:http://openssl.cs.utah.edu/docs/ssl/SSL_CTX_new.html

SSL_CTX_set_options() or SSL_set_options():该方法是用来禁止使用什么协议来建链的。其中有以下选项可以填写:

SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1 and SSL_OP_NO_TLSv1_2

通过字面意思,我们可以知道其用法。

Demo

  1 #include <sys/socket.h>
  2 #include <resolv.h>
  3 #include <netdb.h>
  4 #include <netinet/in.h>
  5 #include <arpa/inet.h>
  6 #include <string.h>
  7
  8 #include <openssl/bio.h>
  9 #include <openssl/ssl.h>
 10 #include <openssl/err.h>
 11 #include <openssl/pem.h>
 12 #include <openssl/x509.h>
 13 #include <openssl/x509_vfy.h>
 14
 15 int create_socket(char[], BIO *);
 16
 17 int main() {
 18
 19     char dest_url[] = "https://www.baidu.com";
 20     BIO *certbio = NULL;
 21     BIO *outbio = NULL;
 22     X509 *cert = NULL;
 23     X509_NAME *certname = NULL;
 24     const SSL_METHOD *method;
 25     SSL_CTX *ctx;
 26     SSL *ssl;
 27     int server = 0;
 28     int ret, i;
 29
 30     /* ---------------------------------------------------------- *
 31      * 初始化OpenSSL                                                *
 32      * ---------------------------------------------------------- */
 33     OpenSSL_add_all_algorithms();
 34     ERR_load_BIO_strings();
 35     ERR_load_crypto_strings();
 36     SSL_load_error_strings();
 37
 38     /* ---------------------------------------------------------- *
 39      * 创建一个BIO的输入和输出.                                   *
 40      * ---------------------------------------------------------- */
 41     certbio = BIO_new(BIO_s_file());
 42     outbio = BIO_new_fp(stdout, BIO_NOCLOSE);
 43
 44     /* ---------------------------------------------------------- *
 45      * 初始化SSL库和注册算法                                      *
 46      * ---------------------------------------------------------- */
 47     if (SSL_library_init() < 0)
 48         BIO_printf(outbio, "Could not initialize the OpenSSL library !\n");
 49
 50     /* ---------------------------------------------------------- *
 51      * 发送SSL2 SSL3 TLS 1.0 TLS 2.0 TLS 3.0 与服务器建链         *
 52      * ---------------------------------------------------------- */
 53     method = SSLv23_client_method();
 54
 55     /* ---------------------------------------------------------- *
 56      * 创建一个新的SSL上下文                                      *
 57      * ---------------------------------------------------------- */
 58     if ((ctx = SSL_CTX_new(method)) == NULL)
 59         BIO_printf(outbio, "Unable to create a new SSL context structure.\n");
 60
 61     /* ---------------------------------------------------------- *
 62      * 禁止使用SSLv3建链                                          *
 63      * ---------------------------------------------------------- */
 64     SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
 65
 66     /* ---------------------------------------------------------- *
 67      * 创建一个新的SSL的状态                                      *
 68      * ---------------------------------------------------------- */
 69     ssl = SSL_new(ctx);
 70
 71     /* ---------------------------------------------------------- *
 72      * 创建一个优先的SSL TCP 链接                                 *
 73      * ---------------------------------------------------------- */
 74     server = create_socket(dest_url, outbio);
 75     if (server != 0)
 76         BIO_printf(outbio, "Successfully made the TCP connection to: %s.\n",
 77                 dest_url);
 78
 79     /* ---------------------------------------------------------- *
 80      * 关联socket的会话                                           *
 81      * ---------------------------------------------------------- */
 82     SSL_set_fd(ssl, server);
 83
 84     /* ---------------------------------------------------------- *
 85      * 建立SSL 链接,返回1成功                                    *
 86      * ---------------------------------------------------------- */
 87     if (SSL_connect(ssl) != 1)
 88         BIO_printf(outbio, "Error: Could not build a SSL session to: %s.\n",
 89                 dest_url);
 90     else
 91         BIO_printf(outbio, "Successfully enabled SSL/TLS session to: %s.\n",
 92                 dest_url);
 93
 94     /* ---------------------------------------------------------- *
 95      * 得到服务端的证书到X509结构体                               *
 96      * ---------------------------------------------------------- */
 97     cert = SSL_get_peer_certificate(ssl);
 98     if (cert == NULL)
 99         BIO_printf(outbio, "Error: Could not get a certificate from: %s.\n",
100                 dest_url);
101     else
102         BIO_printf(outbio, "Retrieved the server‘s certificate from: %s.\n",
103                 dest_url);
104
105     /* ---------------------------------------------------------- *
106      * 提取各种证书信息                    *
107      * -----------------------------------------------------------*/
108     certname = X509_NAME_new();
109     certname = X509_get_subject_name(cert);
110
111     /* ---------------------------------------------------------- *
112      * 这里显示证书的主题                                         *
113      * -----------------------------------------------------------*/
114     BIO_printf(outbio, "Displaying the certificate subject data:\n");
115     X509_NAME_print_ex(outbio, certname, 0, 0);
116     BIO_printf(outbio, "\n");
117
118     /* ---------------------------------------------------------- *
119      * 释放不再使用的结构体                  *
120      * -----------------------------------------------------------*/
121     SSL_free(ssl);
122     close(server);
123     X509_free(cert);
124     SSL_CTX_free(ctx);
125     BIO_printf(outbio, "Finished SSL/TLS connection with server: %s.\n",
126             dest_url);
127     return (0);
128 }
129
130 /* ---------------------------------------------------------- *
131  * create_socket() 和服务端建立TCP的socket链接                *
132  * ---------------------------------------------------------- */
133 int create_socket(char url_str[], BIO *out) {
134     int sockfd;
135     char hostname[256] = "";
136     char portnum[6] = "443";
137     char proto[6] = "";
138     char *tmp_ptr = NULL;
139     int port;
140     struct hostent *host;
141     struct sockaddr_in dest_addr;
142
143     /* ---------------------------------------------------------- *
144      * 移除url_str的末尾 /                                        *
145      * ---------------------------------------------------------- */
146     if (url_str[strlen(url_str)] == ‘/‘)
147         url_str[strlen(url_str)] = ‘\0‘;
148
149     /* ---------------------------------------------------------- *
150      * the first : ends the protocol string, i.e. http            *
151      * ---------------------------------------------------------- */
152     strncpy(proto, url_str, (strchr(url_str, ‘:‘) - url_str));
153
154     /* ---------------------------------------------------------- *
155      * the hostname starts after the "://" part                   *
156      * ---------------------------------------------------------- */
157     strncpy(hostname, strstr(url_str, "://") + 3, sizeof(hostname));
158
159     /* ---------------------------------------------------------- *
160      * if the hostname contains a colon :, we got a port number   *
161      * ---------------------------------------------------------- */
162     if (strchr(hostname, ‘:‘)) {
163         tmp_ptr = strchr(hostname, ‘:‘);
164         /* the last : starts the port number, if avail, i.e. 8443 */
165         strncpy(portnum, tmp_ptr + 1, sizeof(portnum));
166         *tmp_ptr = ‘\0‘;
167     }
168
169     port = atoi(portnum);
170
171     if ((host = gethostbyname(hostname)) == NULL) {
172         BIO_printf(out, "Error: Cannot resolve hostname %s.\n", hostname);
173         abort();
174     }
175
176     /* ---------------------------------------------------------- *
177      * create the basic TCP socket                                *
178      * ---------------------------------------------------------- */
179     sockfd = socket(AF_INET, SOCK_STREAM, 0);
180
181     dest_addr.sin_family = AF_INET;
182     dest_addr.sin_port = htons(port);
183     dest_addr.sin_addr.s_addr = *(long*) (host->h_addr);
184
185     /* ---------------------------------------------------------- *
186      * Zeroing the rest of the struct                             *
187      * ---------------------------------------------------------- */
188     memset(&(dest_addr.sin_zero), ‘\0‘, 8);
189
190     tmp_ptr = inet_ntoa(dest_addr.sin_addr);
191
192     /* ---------------------------------------------------------- *
193      * Try to make the host connect here                          *
194      * ---------------------------------------------------------- */
195     if (connect(sockfd, (struct sockaddr *) &dest_addr, sizeof(struct sockaddr))
196             == -1) {
197         BIO_printf(out, "Error: Cannot connect to host %s [%s] on port %d.\n",
198                 hostname, tmp_ptr, port);
199     }
200
201     return sockfd;
202 }

时间: 2024-10-18 15:37:12

如何做一个用于测试SSL版本的客户端的相关文章

[electron 工具] 使用 electron、vue 和 nodejs 做一个 SOAP 测试工具之一 ( 简介 )

(简介直接将主页的介绍复制过来好了) Soap-Sender 主页 1.0.1 更新记录 优化基本设置页面判断 IP 和密码的响应时间 保存基本设置页面的设置 历史记录添加 Response Time 的排序 历史记录添加删除按钮 历史记录添加导入数据到发送页面 历史记录添加 Response Code 0 和非 0 的颜色区分 添加检查新版本 使用说明: 下载和使用 1-1. 软件下载后 .zip 后缀,解压缩后得到一个 exe 自解压文件.双击 exe 文件解压后得到一个文件夹.运行文件夹里

express创建一个工程测试

创建一个工程 现在已经有express 键入:express myapp (myapp是随意起的工程名称) 你会发现多了一个 C:\Program Files\nodejs\myapp 目录 默认情况下:里会自动创建 这几个文件,不做解释,相信有过开发经验的同学都能一眼明了. 复制node_modules到myapp下面 环境搭建到此完工,下面做一个demo测试! 在myapp下新建helloworld.js复制代码 代码如下: var http = require("http");h

我的2015测试之路 ——做一个很有想法的测试

我的2015测试之路 ——做一个很有想法的测试 不记得有多少次了,总是说等什么时候闲了,就回过头看看这一路跋涉.风尘仆仆的自己.可每次都只是想想而已,即使真的闲下来了,却又不太愿意剥开自己的心,怕看了会伤感.又怕看了会觉得失望,可能是我没有成为,当初那个我想要成为的样子吧.是该对自己说一句对不起了.对不起,我深爱的自己! 人们总是在歌谣里哀求时光慢些,不要再让亲人变老了.但它总也是不听话,于是2015年终究是被推进了历史.现在我们只能在回忆和指尖怀念2015了,诚然,2015对我们每个人来说都是

Selenium也是一个用于Web应用程序测试的工具

Selenium也是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mozilla Firefox.Mozilla Suite等.这个工具的主要功能包括:测试与浏览器的兼容性--测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上.测试系统功能--创建衰退测试检验软件功能和用户需求.支持自动录制动作和自动生成.Net.Java.Perl等不同语言的测试脚本.Selenium 是ThoughtWorks专门为Web

如何做一个简单的Chrome Extension用于网页截屏

Chrome extension是一个文件包,里面包含了一个配置文件manifest.json,以及一些用于Web开发的文件和资源 (HTML, JavaScript, CSS,等). Chrome Extension开发指南 Chrome Extension Overview Chrome Extension Debugging Chrome Extension Samples 如何实现网页截屏功能 看一下manifest文件: {       "name": "Scree

使用optimizely做A/B测试

摘要: optimizaly是一个提供A/B测试服务的网站,可以可视化地在线编辑测试内容和目标,简单方便.   1. A/B测试简介 所谓 A/B 测试,简单来说,就是为同一个目标制定两个方案(比如两个页面),让一部分用户使用 A 方案,另一部分用户使用 B 方案,记录下用户的使用情况,看哪个方案更符合设计目标.参考: http://oldj.net/article/ab-testing-basic-concept http://www.zhihu.com/question/20045543 h

微信测试工程师手把手教你做弱网络模拟测试

微信测试工程师手把手教你做弱网络模拟测试 Posted by 腾讯优测 | 3,152 views 小优有话说: app研发不同于实验室里做研究,哪里有"理想环境". 理想里,用户用着性能卓越的手机,连着畅通无阻的wifi网络. "哇塞!这个app好用到飞起!" 现实是,他们可能正用着你闻所未闻的机型,穿梭于地铁.公交.火车.乡间.大山-.. 信号"若隐若现,扑朔迷离" "我去!又crash了!" "唉,怎么又连不上

使用Multiplayer Networking做一个简单的多人游戏例子-2/3(Unity3D开发之二十六)

猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51007512 使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Networking做一个简单的多人游戏例子-3/3 7. 在网络中控制Player移动 上一篇中,玩家操

FreeSWITCH折腾笔记4——自己做一个TTS服务器

freeswitch原生支持的tts功能中文一般是使用的ekho,但是那合成的效果简直惨不忍睹,于是我想自己做一个TTS服务器. 首先是找到比较满意的TTS引擎,科大讯飞的效果当然是没话说,但是价格不菲,其他商业的引擎中文合成也不是很流畅,偶然发现windows7自带的合成引擎还算过得去,windows10带的合成引擎就更好了(有兴趣的可以先测试一下,直接在windows控制面板中的语音设置里面有测试,但是测试的中英文混读很蛋疼). 那么问题来了,怎么把这个引擎用到我的FS上边呢? 思路,deb