Skip to content

Commit e8f2aee

Browse files
committed
add TLS options: don't allow other than custom cert + don't bypass on TLS parse problem
1 parent bdf25ee commit e8f2aee

File tree

4 files changed

+80
-16
lines changed

4 files changed

+80
-16
lines changed

Diff for: sslcom.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ struct SSLComOptionsCert {
115115

116116
bool mitm_cert_sni_search = false; // allow search based on SNI
117117
bool mitm_cert_ip_search = false; // allow search based on SNI
118+
bool mitm_cert_searched_only = false; // if SNI or IP cert is not found, don't use default spoofed mitm certificate
118119
};
119120

120121
struct SSLComOptionsOcsp {
@@ -140,6 +141,7 @@ struct SSLComOptions {
140141
// Certificate Transparency support
141142
bool ct_enable = true;
142143
bool alpn_block = false;
144+
bool no_fallback_bypass = false;
143145

144146
SSLComCryptoFeatures left;
145147
SSLComCryptoFeatures right;

Diff for: sslcom.tpp

+60-16
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ void baseSSLCom<L4Proto>::init(baseHostCX* owner) {
109109
template <class L4Proto>
110110
std::string baseSSLCom<L4Proto>::to_string(int verbosity) const {
111111
mp::stringstream ss;
112+
112113
ss << "SSLCom[" << ( is_server() ? "server] <-" : "client] ->" );
113114
ss << "sni:" << get_sni() << " alpn: " << sslcom_alpn_;
114115

115116
if(opt.bypass) ss << " bypassed";
117+
if(opt.no_fallback_bypass) ss << " no_fallback_bypass";
116118

117119
return ss.str().c_str();
118120
}
@@ -1748,7 +1750,15 @@ void baseSSLCom<L4Proto>::init_server() {
17481750
_dia("SSLCom::init_server: using custom context 0x%x", sslcom_ctx);
17491751
}
17501752
else if(not sslcom_ctx) {
1751-
sslcom_ctx = factory()->default_tls_server_cx();
1753+
1754+
if(not opt.cert.mitm_cert_searched_only) {
1755+
sslcom_ctx = factory()->default_tls_server_cx();
1756+
}
1757+
else {
1758+
_dia("using default tls context is prohibited");
1759+
error(baseCom::ERROR_UNSPEC);
1760+
return;
1761+
}
17521762
}
17531763

17541764

@@ -2014,6 +2024,9 @@ void baseSSLCom<L4Proto>::accept_socket (int sockfd) {
20142024
counters.prof_accept_bypass_cnt++;
20152025
return;
20162026
}
2027+
if(not sslcom_ssl) {
2028+
return;
2029+
}
20172030

20182031

20192032
if (l4_proto() == SOCK_DGRAM) {
@@ -2147,6 +2160,12 @@ int baseSSLCom<L4Proto>::handshake_server() {
21472160
}
21482161

21492162
ERR_clear_error();
2163+
if(not sslcom_ssl) {
2164+
_dia("SSLCom::handshake: socket not upgraded, failing");
2165+
error(ERROR_UNSPEC);
2166+
return -1;
2167+
}
2168+
21502169
sslcom_ret = SSL_accept(sslcom_ssl);
21512170

21522171
if(sslcom_ret == 1) {
@@ -2329,15 +2348,23 @@ ret_handshake baseSSLCom<L4Proto>::handshake() {
23292348
op_code = handshake_server();
23302349
}
23312350

2332-
int err = SSL_get_error(sslcom_ssl, op_code);
2333-
unsigned long err2 = ERR_get_error();
23342351

2335-
_dia("SSLCom::handshake: %s on socket %d: r=%d, err=%d, err2=%d", op_descr, socket(), op_code, err, err2);
2352+
2353+
_dia("SSLCom::handshake: %s on socket %d: r=%d", op_descr, socket(), op_code);
23362354

23372355
// general error handling code - both accept and connect yield the same errors
23382356
if (op_code < 0) {
2357+
2358+
if(error()) {
2359+
return ret_handshake::FATAL;
2360+
}
2361+
2362+
int err = SSL_get_error(sslcom_ssl, op_code);
2363+
unsigned long err2 = ERR_get_error();
23392364
// potentially OK if non-blocking socket
23402365

2366+
_dia("SSLCom::handshake: %s on socket %d: ret=%d, err=%d, err2=%d", op_descr, socket(), op_code, err, err2);
2367+
23412368
if (err == SSL_ERROR_WANT_READ) {
23422369
_dia("SSLCom::handshake: SSL_%s[%d]: pending on want_read", op_descr , socket());
23432370

@@ -2390,15 +2417,19 @@ ret_handshake baseSSLCom<L4Proto>::handshake() {
23902417
else {
23912418
// any other error < 0 is considered as BAD thing.
23922419

2393-
_dia("SSLCom::handshake: SSL_%s: error: %d:%d",op_descr , err, err2);
2420+
_dia("SSLCom::handshake: SSL_%s: ret=0, err=%d, err2=%d", op_descr, err, err2);
23942421
handshake_dia_error2(op_code, err, err2);
23952422
sslcom_waiting = true;
23962423
return ret_handshake::ERROR;
23972424
}
23982425

23992426
} else if (op_code == 0) {
2427+
2428+
int err = SSL_get_error(sslcom_ssl, op_code);
2429+
unsigned long err2 = ERR_get_error();
2430+
24002431
// positively handshake error signalled by SSL_connect or SSL_accept
2401-
_dia("SSLCom::handshake: SSL_%s: error: %d:%d",op_descr , err, err2);
2432+
_dia("SSLCom::handshake: SSL_%s: ret=0, err=%d, err2=%d", op_descr, err, err2);
24022433
handshake_dia_error2(op_code, err, err2);
24032434

24042435
// shutdown OK, but connection failed
@@ -2407,12 +2438,18 @@ ret_handshake baseSSLCom<L4Proto>::handshake() {
24072438
}
24082439
else if (op_code == 2) {
24092440

2410-
// our internal signalling for bypass
2411-
opt.bypass = true;
2412-
verify_reset(verify_status_t::VRF_OK);
2413-
_dia("SSLCom::handshake: bypassed.");
2441+
if(opt.no_fallback_bypass) {
2442+
error(ERROR_UNSPEC);
2443+
return ret_handshake::FATAL;
2444+
}
2445+
else {
2446+
// our internal signalling for bypass
2447+
opt.bypass = true;
2448+
verify_reset(verify_status_t::VRF_OK);
2449+
_dia("SSLCom::handshake: bypassed.");
24142450

2415-
return ret_handshake::AGAIN;
2451+
return ret_handshake::AGAIN;
2452+
}
24162453
}
24172454

24182455

@@ -2676,11 +2713,18 @@ bool baseSSLCom<L4Proto>::waiting_peer_hello() {
26762713
_dia("SSLCom::waiting_peer_hello: analysis failed");
26772714
_dia("SSLCom::waiting_peer_hello: failed ClientHello data:\r\n%s",
26782715
hex_dump(sslcom_peer_hello_buffer.data(),sslcom_peer_hello_buffer.size(), 4, 0, true).c_str());
2679-
2680-
if(bypass_me_and_peer()) {
2681-
_inf("bypassing non-TLS connection");
2682-
log.event(INF, "[%s] cannot read ClientHello: bypassed", peer_scom->to_string(iINF).c_str());
2683-
return false;
2716+
2717+
if (not opt.no_fallback_bypass) {
2718+
_inf("fallback bypass disabled!");
2719+
log.event(INF, "[%s] cannot read ClientHello: bypass disabled",
2720+
peer_scom->to_string(iINF).c_str());
2721+
2722+
if (bypass_me_and_peer()) {
2723+
_inf("bypassing non-TLS connection");
2724+
log.event(INF, "[%s] cannot read ClientHello: bypassed",
2725+
peer_scom->to_string(iINF).c_str());
2726+
return false;
2727+
}
26842728
}
26852729

26862730
error_flag_ = ERROR_UNSPEC; // peer nullptr or its com() is not SSLCom

Diff for: sslmitmcom.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class baseSSLMitmCom : public SSLProto {
3939

4040
bool check_cert(const char*) override;
4141
virtual bool spoof_cert(X509* cert_orig, SpoofOptions& spo);
42+
virtual bool use_cert_null();
4243
virtual bool use_cert_sni(SpoofOptions &spo);
4344
virtual bool use_cert_ip(SpoofOptions &spo);
4445
virtual bool use_cert_mitm(X509* cert_orig, SpoofOptions& spo);

Diff for: sslmitmcom.tpp

+17
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,17 @@ bool baseSSLMitmCom<SSLProto>::check_cert(const char* peer_name) {
198198
return r;
199199
}
200200

201+
template <class SSLProto>
202+
bool baseSSLMitmCom<SSLProto>::use_cert_null() {
203+
auto const& log = log::mitm();
204+
205+
_dia("SSLMitmCom::use_cert_null: unsetting certifiace key-pair");
206+
this->sslcom_pref_cert = nullptr;
207+
this->sslcom_pref_key = nullptr;
208+
209+
return false;
210+
}
211+
201212

202213
template <class SSLProto>
203214
bool baseSSLMitmCom<SSLProto>::use_cert_sni(SpoofOptions &spo) {
@@ -320,6 +331,12 @@ bool baseSSLMitmCom<SSLProto>::spoof_cert(X509* cert_orig, SpoofOptions& spo) {
320331

321332
if(this->opt.cert.mitm_cert_ip_search && this->use_cert_ip(spo)) return true;
322333

334+
if(this->opt.cert.mitm_cert_searched_only) {
335+
use_cert_null();
336+
this->error(baseCom::ERROR_UNSPEC);
337+
return false;
338+
}
339+
323340
return use_cert_mitm(cert_orig, spo);
324341
}
325342

0 commit comments

Comments
 (0)