SSL linux C 客户端如何验证服务器发来的证书

wzw_xavier 2017-08-25 02:57:56
我想用SSL给客户端和服务器之间的通讯进行加密,但是不知道如何进行代码实现,有具体的接口函数吗?这是我的程序流程,但这个貌似没有对服务器发来的证书进行验证

[cpp] view plain copy
1. #include <string.h>
2. #include <errno.h>
3. #include <sys/socket.h>
4. #include <resolv.h>
5. #include <stdlib.h>
6. #include <netinet/in.h>
7. #include <arpa/inet.h>
8. #include <unistd.h>
9. #include <openssl/ssl.h>
10. #include <openssl/err.h>
11.
12. #define MAXBUF 1024
13.
14. void ShowCerts(SSL * ssl)
15. {
16. X509 *cert;
17. char *line;
18.
19. cert = SSL_get_peer_certificate(ssl);
20. if (cert != NULL) {
21. printf("数字证书信息:\n");
22. line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
23. printf("证书: %s\n", line);
24. free(line);
25. line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
26. printf("颁发者: %s\n", line);
27. free(line);
28. X509_free(cert);
29. } else
30. printf("无证书信息!\n");
31. }
32. /************关于本文档********************************************
33. *filename: ssl-client.c
34. *purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是客户端例子
35. *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
36. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
37. *date time:2007-02-02 20:10
38. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
39. * 但请遵循GPL
40. *Thanks to:Google
41. *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
42. * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
43. *********************************************************************/
44. int main(int argc, char **argv)
45. {
46. int sockfd, len;
47. struct sockaddr_in dest;
48. char buffer[MAXBUF + 1];
49. SSL_CTX *ctx;
50. SSL *ssl;

60. /* SSL 库初始化,参看 ssl-server.c 代码 */
61. SSL_library_init();
62. OpenSSL_add_all_algorithms();
63. SSL_load_error_strings();
64. ctx = SSL_CTX_new(SSLv23_client_method());
65. if (ctx == NULL) {
66. ERR_print_errors_fp(stdout);
67. exit(1);
68. }
69.
70. /* 创建一个 socket 用于 tcp 通信 */
71. if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
72. perror("Socket");
73. exit(errno);
74. }
75. printf("socket created\n");
76.
77. /* 初始化服务器端(对方)的地址和端口信息 */
78. bzero(&dest, sizeof(dest));
79. dest.sin_family = AF_INET;
80. dest.sin_port = htons(atoi(argv[2]));
81. if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
82. perror(argv[1]);
83. exit(errno);
84. }
85. printf("address created\n");
86.
87. /* 连接服务器 */
88. if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
89. perror("Connect ");
90. exit(errno);
91. }
92. printf("server connected\n");
93.
94. /* 基于 ctx 产生一个新的 SSL */
95. ssl = SSL_new(ctx);
96. SSL_set_fd(ssl, sockfd);
97. /* 建立 SSL 连接 */
98. if (SSL_connect(ssl) == -1)
99. ERR_print_errors_fp(stderr);
100. else {
101. printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
102. ShowCerts(ssl);
103. }
104.
105. /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
106. bzero(buffer, MAXBUF + 1);
107. /* 接收服务器来的消息 */
108. len = SSL_read(ssl, buffer, MAXBUF);
109. if (len > 0)
110. printf("接收消息成功:'%s',共%d个字节的数据\n",
111. buffer, len);
112. else {
113. printf
114. ("消息接收失败!错误代码是%d,错误信息是'%s'\n",
115. errno, strerror(errno));
116. goto finish;
117. }
118. bzero(buffer, MAXBUF + 1);
119. strcpy(buffer, "from client->server");
120. /* 发消息给服务器 */
121. len = SSL_write(ssl, buffer, strlen(buffer));
122. if (len < 0)
123. printf
124. ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",
125. buffer, errno, strerror(errno));
126. else
127. printf("消息'%s'发送成功,共发送了%d个字节!\n",
128. buffer, len);
129.
130. finish:
131. /* 关闭连接 */
132. SSL_shutdown(ssl);
133. SSL_free(ssl);
134. close(sockfd);
135. SSL_CTX_free(ctx);
136. return 0;
137. }
...全文
458 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
wzw_xavier 2017-08-30
  • 打赏
  • 举报
回复


现在我也是无法进行握手


void ShowCerts(SSL * ssl)
15. {
16. X509 *cert;
17. char *line;
18.
19. cert = SSL_get_peer_certificate(ssl);
20. if (cert != NULL) {
21. printf("数字证书信息:\n");
22. line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
23. printf("证书: %s\n", line);
24. free(line);
25. line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
26. printf("颁发者: %s\n", line);
27. free(line);
28. X509_free(cert);
29. } else
30. printf("无证书信息!\n");
31. }

但是我通过这个函数获得了证书信息,是不是可以排除没有证书的可能呢?

自己想确认是不是自己的接口函数用的不正确?
希望大神快来翻我的牌
谢谢~
wzw_xavier 2017-08-30
  • 打赏
  • 举报
回复
95. ssl = SSL_new(ctx); 96. SSL_set_fd(ssl, sockfd); 我在这后面增加了SSL_CTX_set_verify(ssl,SSL_VERIFY_PEER,NULL); 后面的SSL_connect();函数就执行不了了。
wzw_xavier 2017-08-30
  • 打赏
  • 举报
回复



现在基本确认是这两个接口函数,但是问题是SSL_CTX_load_verify_locations();它的CA文件和路径不知道,从服务器直接下载下来的路径默认存放在哪的?

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧