Update TLCP

This commit is contained in:
Zhi Guan
2022-06-11 23:50:54 +08:00
parent f754b1222d
commit 5eaab7033d
9 changed files with 1263 additions and 759 deletions

View File

@@ -47,21 +47,27 @@
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <gmssl/tls.h>
#include <gmssl/error.h>
static int client_ciphers[] = { TLCP_cipher_ecc_sm4_cbc_sm3, };
static const char *http_get =
"GET / HTTP/1.1\r\n"
"Hostname: aaa\r\n"
"\r\n\r\n";
// 虽然服务器可以用双证书,但是客户端只能使用一个证书,也就是签名证书
static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file [-pass str]]";
static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]";
int tlcp_client_main(int argc, char *argv[])
{
@@ -69,28 +75,25 @@ int tlcp_client_main(int argc, char *argv[])
char *prog = argv[0];
char *host = NULL;
int port = 443;
char *cacertfile = NULL;
char *certfile = NULL;
char *keyfile = NULL;
char *pass = NULL;
struct sockaddr_in server;
int sock;
TLS_CTX ctx;
TLS_CONNECT conn;
char buf[100] = {0};
size_t len = sizeof(buf);
char send_buf[1024] = {0};
size_t send_len;
char *file;
FILE *cacertfp = NULL;
FILE *certfp = NULL;
FILE *keyfp = NULL;
SM2_KEY sign_key;
if (argc < 2) {
argc--;
argv++;
if (argc < 1) {
fprintf(stderr, "usage: %s %s\n", prog, options);
return 1;
}
argc--;
argv++;
while (argc >= 1) {
if (!strcmp(*argv, "-help")) {
printf("usage: %s %s\n", prog, options);
@@ -103,25 +106,13 @@ int tlcp_client_main(int argc, char *argv[])
port = atoi(*(++argv));
} else if (!strcmp(*argv, "-cacert")) {
if (--argc < 1) goto bad;
file = *(++argv);
if (!(cacertfp = fopen(file, "r"))) {
error_print();
return -1;
}
cacertfile = *(++argv);
} else if (!strcmp(*argv, "-cert")) {
if (--argc < 1) goto bad;
file = *(++argv);
if (!(certfp = fopen(file, "r"))) {
error_print();
return -1;
}
certfile = *(++argv);
} else if (!strcmp(*argv, "-key")) {
if (--argc < 1) goto bad;
file = *(++argv);
if (!(keyfp = fopen(file, "r"))) {
error_print();
return -1;
}
keyfile = *(++argv);
} else if (!strcmp(*argv, "-pass")) {
if (--argc < 1) goto bad;
pass = *(++argv);
@@ -137,35 +128,45 @@ bad:
}
if (!host) {
error_print();
fprintf(stderr, "%s: '-in' option required\n", prog);
return -1;
}
if (certfp) {
if (!keyfp) {
error_print();
return -1;
}
if (!pass) {
pass = getpass("Password : ");
}
if (sm2_private_key_info_decrypt_from_pem(&sign_key, pass, keyfp) != 1) {
error_print();
return -1;
}
}
memset(&ctx, 0, sizeof(ctx));
memset(&conn, 0, sizeof(conn));
if (tlcp_connect(&conn, host, port, cacertfp, certfp, &sign_key) != 1) {
error_print();
return -1;
server.sin_addr.s_addr = inet_addr(host);
server.sin_family = AF_INET;
server.sin_port = htons(port);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno));
goto end;
}
if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) {
fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno));
goto end;
}
if (tls_ctx_init(&ctx, TLS_version_tlcp, TLS_client_mode) != 1
|| tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1
|| tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1
|| tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) {
fprintf(stderr, "%s: context init error\n", prog);
goto end;
}
if (tls_init(&conn, &ctx) != 1
|| tls_set_socket(&conn, sock) != 1
|| tls_do_handshake(&conn) != 1) {
fprintf(stderr, "%s: error\n", prog);
goto end;
}
for (;;) {
size_t sentlen;
memset(send_buf, 0, sizeof(send_buf));
if (!fgets(send_buf, sizeof(send_buf), stdin)) {
if (feof(stdin)) {
tls_shutdown(&conn);
@@ -174,28 +175,26 @@ bad:
continue;
}
}
if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf)) != 1) {
error_print();
return -1;
if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) {
fprintf(stderr, "%s: send error\n", prog);
goto end;
}
for (;;) {
{
memset(buf, 0, sizeof(buf));
len = sizeof(buf);
if (tls_recv(&conn, (uint8_t *)buf, &len) != 1) {
error_print();
return -1;
}
if (len > 0) {
printf("%s\n", buf);
break;
if (tls_recv(&conn, (uint8_t *)buf, sizeof(len), &len) != 1) {
goto end;
}
buf[len] = 0;
printf("%s\n", buf);
}
}
end:
close(sock);
tls_ctx_cleanup(&ctx);
tls_cleanup(&conn);
return 0;
}