mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Fix TLS Alert
Alert, ChangeCipherSpec record should be encrypted after handshake
This commit is contained in:
@@ -70,6 +70,7 @@ int tlcp_client_main(int argc, char *argv[])
|
||||
size_t len = sizeof(buf);
|
||||
char send_buf[1024] = {0};
|
||||
size_t sentlen;
|
||||
int read_stdin = 1;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
@@ -130,24 +131,19 @@ bad:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(hp = gethostbyname(host))) {
|
||||
fprintf(stderr, "%s: invalid hostname '%s'\n", prog, host);
|
||||
goto end;
|
||||
}
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
memset(&conn, 0, sizeof(conn));
|
||||
|
||||
server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]);
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
|
||||
|
||||
if (tls_socket_create(&sock, AF_INET, SOCK_STREAM, 0) != 1) {
|
||||
fprintf(stderr, "%s: open socket error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(hp = gethostbyname(host))) {
|
||||
fprintf(stderr, "%s: invalid hostname '%s'\n", prog, host);
|
||||
goto end;
|
||||
}
|
||||
server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]);
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
|
||||
if (tls_socket_connect(sock, &server) != 1) {
|
||||
fprintf(stderr, "%s: socket connect error\n", prog);
|
||||
goto end;
|
||||
@@ -158,19 +154,30 @@ bad:
|
||||
fprintf(stderr, "%s: context init error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cacertfile) {
|
||||
if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) {
|
||||
fprintf(stderr, "%s: context init error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (certfile) {
|
||||
if (!keyfile) {
|
||||
fprintf(stderr, "%s: option '-key' should be assigned with '-cert'\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!pass) {
|
||||
fprintf(stderr, "%s: option '-pass' should be assigned with '-pass'\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) {
|
||||
fprintf(stderr, "%s: context init error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (quiet || get) {
|
||||
|
||||
if (quiet) {
|
||||
ctx.quiet = 1;
|
||||
}
|
||||
|
||||
@@ -196,6 +203,9 @@ bad:
|
||||
fclose(outcertsfp);
|
||||
}
|
||||
|
||||
// tls_shutdown(&conn);
|
||||
// return 0;
|
||||
|
||||
if (get) {
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = TIMEOUT_SECONDS;
|
||||
@@ -208,6 +218,7 @@ bad:
|
||||
goto end;
|
||||
}
|
||||
|
||||
// use timeout to close the HTTP connection
|
||||
if (setsockopt(conn.sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)) != 0) {
|
||||
perror("setsockopt");
|
||||
fprintf(stderr, "%s: set socket timeout error\n", prog);
|
||||
@@ -215,100 +226,84 @@ bad:
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
if ((ret = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) {
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "%s: TLCP connection is closed by remote host\n", prog);
|
||||
} else if (ret != -EAGAIN) {
|
||||
fprintf(stderr, "%s: recv error\n", prog);
|
||||
}
|
||||
break;
|
||||
int rv;
|
||||
|
||||
rv = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len);
|
||||
|
||||
if (rv == 1) {
|
||||
fwrite(buf, 1, len, stdout);
|
||||
fflush(stdout);
|
||||
} else if (rv == 0) {
|
||||
fprintf(stderr, "%s: TLCP connection is closed by remote host\n", prog);
|
||||
goto end;
|
||||
} else if (rv == -EAGAIN) {
|
||||
// when timeout, tls_recv return -EAGAIN (-11)
|
||||
tls_shutdown(&conn);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else {
|
||||
fprintf(stderr, "%s: tls_recv error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
fwrite(buf, 1, len, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
tls_shutdown(&conn);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
for (;;) {
|
||||
fd_set fds;
|
||||
|
||||
if (!fgets(send_buf, sizeof(send_buf), stdin)) {
|
||||
if (feof(stdin)) {
|
||||
tls_shutdown(&conn);
|
||||
goto end;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) {
|
||||
fprintf(stderr, "%s: send error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(conn.sock, &fds);
|
||||
#ifdef WIN32
|
||||
#else
|
||||
FD_SET(fileno(stdin), &fds); //FD_SET(STDIN_FILENO, &fds); // NOT allowed in winsock2 !!!
|
||||
#endif
|
||||
if (read_stdin)
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
|
||||
if (select((int)(conn.sock + 1), // WinSock2 select() ignore this arg
|
||||
&fds, NULL, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "%s: select failed\n", prog);
|
||||
#ifdef WIN32
|
||||
fprintf(stderr, "WSAGetLastError = %u\n", WSAGetLastError());
|
||||
#endif
|
||||
if (select(conn.sock + 1, &fds, NULL, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "%s: select error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (read_stdin && FD_ISSET(STDIN_FILENO, &fds)) {
|
||||
|
||||
if (fgets(buf, sizeof(buf), stdin)) {
|
||||
if (tls_send(&conn, (uint8_t *)buf, strlen(buf), &len) != 1) {
|
||||
fprintf(stderr, "%s: send error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (!feof(stdin)) {
|
||||
fprintf(stderr, "%s: length of input line exceeds buffer size\n", prog);
|
||||
goto end;
|
||||
}
|
||||
read_stdin = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(conn.sock, &fds)) {
|
||||
for (;;) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) {
|
||||
goto end;
|
||||
}
|
||||
int rv;
|
||||
|
||||
rv = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len);
|
||||
|
||||
if (rv == 1) {
|
||||
fwrite(buf, 1, len, stdout);
|
||||
fflush(stdout);
|
||||
|
||||
// 应该调整tls_recv 逻辑、API或者其他方式
|
||||
if (conn.datalen == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef WIN32
|
||||
#else
|
||||
if (FD_ISSET(fileno(stdin), &fds)) {
|
||||
fprintf(stderr, "recv from stdin\n");
|
||||
|
||||
memset(send_buf, 0, sizeof(send_buf));
|
||||
|
||||
if (!fgets(send_buf, sizeof(send_buf), stdin)) {
|
||||
if (feof(stdin)) {
|
||||
tls_shutdown(&conn);
|
||||
goto end;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) {
|
||||
fprintf(stderr, "%s: send error\n", prog);
|
||||
} else if (rv == 0) {
|
||||
fprintf(stderr, "Connection closed by remote host\n");
|
||||
goto end;
|
||||
} else if (rv == -EAGAIN) {
|
||||
// should not happen
|
||||
error_print();
|
||||
goto end;
|
||||
} else {
|
||||
error_print();
|
||||
fprintf(stderr, "%s: tls_recv error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "end of this round\n");
|
||||
}
|
||||
|
||||
end:
|
||||
// FIXME: clean ctx and connection ASAP, as Ctrl-C is not handled
|
||||
if (sock != -1) tls_socket_close(sock);
|
||||
tls_ctx_cleanup(&ctx);
|
||||
tls_cleanup(&conn);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user