-
Notifications
You must be signed in to change notification settings - Fork 1
/
ssl-client.c
136 lines (132 loc) · 3.69 KB
/
ssl-client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define MAXBUF 1024
void ShowCerts(SSL * ssl)
{
X509 * cert;
char * line;
cert = SSL_get_peer_certificate(ssl);
if (cert != NULL)
{
printf("数字证书信息:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("证书: %s\n", line);
free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("颁发者: %s\n", line);
free(line);
X509_free(cert);
}
else
{
printf("无证书信息!\n");
}
}
int main(int argc, char * *argv)
{
int sockfd, len;
struct sockaddr_in dest;
char buffer[MAXBUF + 1];
SSL_CTX * ctx;
SSL * ssl;
if (argc != 3)
{
printf("参数格式错误!正确用法如下:\n\t\t%s IP 地址端口\n\t 比如:\t%s 127.0.0.1 80\n 此程序用来从某个IP 地址的服务器某个端口接收最多MAXBUF 个字节的消息",
argv[0], argv[0]);
exit(0);
}
/* SSL 库初始化*/
SSL_library_init();
/* 载入所有SSL 算法*/
OpenSSL_add_all_algorithms();
/* 载入所有SSL 错误消息*/
SSL_load_error_strings();
/* 以SSL V2 和V3 标准兼容方式产生一个SSL_CTX ,即SSL Content Text */
ctx = SSL_CTX_new(SSLv23_client_method());
if (ctx == NULL)
{
ERR_print_errors_fp(stdout);
exit(1);
}
/* 创建一个socket 用于tcp 通信*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Socket");
exit(errno);
}
printf("socket created\n");
/* 初始化服务器端(对方)的地址和端口信息*/
bzero( &dest, sizeof(dest));
dest.sin_family = AF_INET;
//设置连接的端口
dest.sin_port = htons(atoi(argv[2]));
//设置连接的IP地址
if (inet_aton(argv[1], (struct in_addr * ) &dest.sin_addr.s_addr) == 0)
{
perror(argv[1]);
exit(errno);
}
printf("address created\n");
/* 连接服务器*/
if (connect(sockfd, (struct sockaddr * ) &dest, sizeof(dest)) != 0)
{
perror("Connect ");
exit(errno);
}
printf("server connected\n");
/* 基于ctx 产生一个新的SSL */
ssl = SSL_new(ctx);
/* 将新连接的socket 加入到SSL */
SSL_set_fd(ssl, sockfd);
/* 建立SSL 连接*/
if (SSL_connect(ssl) == -1)
{
ERR_print_errors_fp(stderr);
}
else
{
printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
ShowCerts(ssl);
}
/* 接收对方发过来的消息,最多接收MAXBUF 个字节*/
bzero(buffer, MAXBUF + 1);
/* 接收服务器来的消息*/
len = SSL_read(ssl, buffer, MAXBUF);
if (len > 0)
{
printf("接收消息成功:'%s',共%d 个字节的数据\n", buffer, len);
}
else
{
printf("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno));
goto finish;
}
bzero(buffer, MAXBUF + 1);
strcpy(buffer, "from client->server");
/* 发消息给服务器*/
len = SSL_write(ssl, buffer, strlen(buffer));
if (len < 0)
{
printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n", buffer, errno, strerror(errno));
}
else
{
printf("消息'%s'发送成功,共发送了%d 个字节!\n", buffer, len);
}
finish:
/* 关闭连接*/
SSL_shutdown(ssl);
SSL_free(ssl);
close(sockfd);
SSL_CTX_free(ctx);
return 0;
}