1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10
11 #include <stdio.h>
12 #include <errno.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <sys/types.h>
17 #include <arpa/inet.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <gmssl/mem.h>
21 #include <gmssl/sm2.h>
22 #include <gmssl/tls.h>
23 #include <gmssl/error.h>
24
25
26 static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]";
27
tls13_server_main(int argc,char ** argv)28 int tls13_server_main(int argc , char **argv)
29 {
30 int ret = 1;
31 char *prog = argv[0];
32 int port = 443;
33 char *certfile = NULL;
34 char *keyfile = NULL;
35 char *pass = NULL;
36 char *cacertfile = NULL;
37
38 int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3, };
39 uint8_t verify_buf[4096];
40
41 TLS_CTX ctx;
42 TLS_CONNECT conn;
43 char buf[1600] = {0};
44 size_t len = sizeof(buf);
45
46 int sock;
47 struct sockaddr_in server_addr;
48 struct sockaddr_in client_addr;
49 socklen_t client_addrlen;
50 int conn_sock;
51
52
53 argc--;
54 argv++;
55
56 if (argc < 1) {
57 fprintf(stderr, "usage: %s %s\n", prog, options);
58 return 1;
59 }
60
61 while (argc > 0) {
62 if (!strcmp(*argv, "-help")) {
63 printf("usage: %s %s\n", prog, options);
64 return 0;
65 } else if (!strcmp(*argv, "-port")) {
66 if (--argc < 1) goto bad;
67 port = atoi(*(++argv));
68 } else if (!strcmp(*argv, "-cert")) {
69 if (--argc < 1) goto bad;
70 certfile = *(++argv);
71 } else if (!strcmp(*argv, "-key")) {
72 if (--argc < 1) goto bad;
73 keyfile = *(++argv);
74 } else if (!strcmp(*argv, "-pass")) {
75 if (--argc < 1) goto bad;
76 pass = *(++argv);
77 } else if (!strcmp(*argv, "-cacert")) {
78 if (--argc < 1) goto bad;
79 cacertfile = *(++argv);
80 } else {
81 fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
82 return 1;
83 bad:
84 fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv);
85 return 1;
86 }
87 argc--;
88 argv++;
89 }
90 if (!certfile) {
91 fprintf(stderr, "%s: '-cert' option required\n", prog);
92 return 1;
93 }
94 if (!keyfile) {
95 fprintf(stderr, "%s: '-key' option required\n", prog);
96 return 1;
97 }
98 if (!pass) {
99 fprintf(stderr, "%s: '-pass' option required\n", prog);
100 return 1;
101 }
102
103 memset(&ctx, 0, sizeof(ctx));
104 memset(&conn, 0, sizeof(conn));
105
106 if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_server_mode) != 1
107 || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1
108 || tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) {
109 error_print();
110 return -1;
111 }
112 if (cacertfile) {
113 if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) {
114 error_print();
115 return -1;
116 }
117 }
118
119 // Socket
120 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
121 error_print();
122 return 1;
123 }
124 server_addr.sin_family = AF_INET;
125 server_addr.sin_addr.s_addr = INADDR_ANY;
126 server_addr.sin_port = htons(port);
127 if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
128 error_print();
129 perror("tlcp_accept: bind: ");
130 goto end;
131 }
132 puts("start listen ...\n");
133 listen(sock, 1);
134
135
136
137 restart:
138
139 client_addrlen = sizeof(client_addr);
140 if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) {
141 error_print();
142 goto end;
143 }
144 puts("socket connected\n");
145
146 if (tls_init(&conn, &ctx) != 1
147 || tls_set_socket(&conn, conn_sock) != 1) {
148 error_print();
149 return -1;
150 }
151
152 if (tls_do_handshake(&conn) != 1) {
153 error_print(); // 为什么这个会触发呢?
154 return -1;
155 }
156
157 for (;;) {
158
159 int rv;
160 size_t sentlen;
161
162 do {
163 len = sizeof(buf);
164 if ((rv = tls13_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) {
165 if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog);
166 else fprintf(stderr, "%s: Disconnected by remote\n", prog);
167
168 //close(conn.sock);
169 tls_cleanup(&conn);
170 goto restart;
171 }
172 } while (!len);
173
174 if (tls13_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) {
175 fprintf(stderr, "%s: send failure, close connection\n", prog);
176 close(conn.sock);
177 goto end;
178 }
179 }
180
181
182 end:
183 return ret;
184 }
185