-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.cpp
132 lines (113 loc) · 5.06 KB
/
client.cpp
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
#include "common.h"
void print_help(const std::string& binary_name) {
std::cout << "Usage: " << binary_name << " [options]\n";
std::cout << "Options:\n";
std::cout << " --server <address> Server address (required)\n";
std::cout << " --ca-certificate <file> CA certificate file (required)\n";
std::cout << " --certificate <file> Client certificate file (required)\n";
std::cout << " --private-key <file> Client private key file (required)\n";
std::cout << " -p <port> Port to connect to (default: 4433)\n";
std::cout << " -v, -vv, -vvv, -vvvv Set verbosity level (default: 0)\n";
std::cout << " -h, --help Show this help message\n";
}
int main(int argc, char *argv[]) {
mbedtls_net_context server_fd;
mbedtls_ssl_context ssl;
mbedtls_ssl_config ssl_conf;
mbedtls_x509_crt cacert;
mbedtls_pk_context key;
mbedtls_x509_crt cert;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
int ret;
int verbosity = 0;
std::string server_addr;
std::string port = DEFAULT_PORT;
std::string ca_cert_file;
std::string client_cert_file;
std::string client_key_file;
// Get binary name for print_help
std::string binary_name = argv[0];
// Parse command-line arguments
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "-h" || arg == "--help") {
print_help(binary_name);
return 0;
} else if (arg == "-v") {
verbosity = 1;
} else if (arg == "-vv") {
verbosity = 2;
} else if (arg == "-vvv") {
verbosity = 3;
} else if (arg == "-vvvv") {
verbosity = 4;
} else if (arg == "-p" && i + 1 < argc) {
port = argv[++i];
} else if (arg == "--server" && i + 1 < argc) {
server_addr = argv[++i];
} else if (arg == "--ca-certificate" && i + 1 < argc) {
ca_cert_file = argv[++i];
} else if (arg == "--certificate" && i + 1 < argc) {
client_cert_file = argv[++i];
} else if (arg == "--private-key" && i + 1 < argc) {
client_key_file = argv[++i];
} else {
std::cerr << "Unexpected argument: " << arg << std::endl;
print_help(binary_name);
return 1;
}
}
if (server_addr.empty() || ca_cert_file.empty() || client_cert_file.empty() || client_key_file.empty()) {
std::cerr << "Required argument missing.\n";
print_help(binary_name);
return 1;
}
initialize_mbedtls(ssl, ssl_conf, cacert, key, cert, ctr_drbg, entropy);
// Initialize RNG
std::cout << "Initializing seed CTR-DRBG..." << std::endl;
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
handle_error(ret, "Failed to seed CTR-DRBG.");
std::cout << "Loading CA certificate..." << std::endl;
ret = mbedtls_x509_crt_parse_file(&cacert, ca_cert_file.c_str());
handle_error(ret, "Failed to parse CA certificate.");
std::cout << "Loading client certificate..." << std::endl;
ret = mbedtls_x509_crt_parse_file(&cert, client_cert_file.c_str());
handle_error(ret, "Failed to parse client certificate.");
std::cout << "Loading client private key..." << std::endl;
ret = mbedtls_pk_parse_keyfile(&key, client_key_file.c_str(), NULL);
handle_error(ret, "Failed to parse client private key.");
std::cout << "Setting up SSL configuration..." << std::endl;
ret = mbedtls_ssl_config_defaults(&ssl_conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
handle_error(ret, "Failed to configure SSL.");
mbedtls_ssl_conf_authmode(&ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&ssl_conf, &cacert, NULL);
mbedtls_ssl_conf_own_cert(&ssl_conf, &cert, &key);
mbedtls_ssl_conf_rng(&ssl_conf, mbedtls_ctr_drbg_random, &ctr_drbg); // Set RNG
// Set debug callback and verbosity level
mbedtls_ssl_conf_dbg(&ssl_conf, debug_callback, &verbosity);
mbedtls_debug_set_threshold(verbosity);
std::cout << "Setting up SSL context..." << std::endl;
ret = mbedtls_ssl_setup(&ssl, &ssl_conf);
handle_error(ret, "Failed to set up SSL context.");
std::cout << "Connecting to server..." << std::endl;
mbedtls_net_init(&server_fd);
ret = mbedtls_net_connect(&server_fd, server_addr.c_str(), port.c_str(), MBEDTLS_NET_PROTO_TCP);
handle_error(ret, "Failed to connect to server.");
std::cout << "Starting handshake..." << std::endl;
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
ret = mbedtls_ssl_handshake(&ssl);
if (ret != 0) {
std::cerr << "Handshake failed. Error code: " << ret << std::endl;
std::cerr << get_ssl_verify_result(ssl) << std::endl;
} else {
std::cout << "Handshake successful!" << std::endl;
}
mbedtls_ssl_close_notify(&ssl);
mbedtls_net_free(&server_fd);
cleanup_mbedtls(ssl, ssl_conf, cacert, key, cert, ctr_drbg, entropy);
return 0;
}