Skip to content

Commit

Permalink
DEBUG DO NOT MERGE
Browse files Browse the repository at this point in the history
  • Loading branch information
kgiusti committed Sep 26, 2024
1 parent b120b37 commit 2c11a03
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 44 deletions.
7 changes: 7 additions & 0 deletions src/tls/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ struct qd_tls_session_t {

uint64_t encrypted_output_bytes;
uint64_t encrypted_input_bytes;
#if 0
#define KAG_WRITES 32
char *kag_last_ptr[KAG_WRITES];
size_t kag_last_n[KAG_WRITES];
int kag_last_index;
unsigned int kag_dummy;
#endif
};

/**
Expand Down
64 changes: 63 additions & 1 deletion src/tls/tls_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <inttypes.h>

size_t kag_error;

/*
* API for working with Proton Raw Connections running TLS
Expand Down Expand Up @@ -147,6 +148,11 @@ static inline qd_buffer_t *_pn_buf_desc_take_buffer(pn_raw_buffer_t *pn_desc)
return buffer;
}

static inline void ZAP(qd_buffer_t *buf)
{
//memset(qd_buffer_base(buf), 0xBF, 8);
}


int qd_tls_session_do_io(qd_tls_session_t *session,
pn_raw_connection_t *raw_conn,
Expand Down Expand Up @@ -174,6 +180,8 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
if (session->input_drained && session->output_flushed)
return QD_TLS_DONE;

//sys_mutex_lock(&session->proton_tls_cfg->lock);

do {
size_t capacity;
size_t taken;
Expand All @@ -196,8 +204,12 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
}
while (capacity > 0) {
_pn_buf_desc_give_buffer(&pn_buf_desc, qd_buffer());
ZAP((qd_buffer_t *)pn_buf_desc.context);
given = pn_tls_give_encrypt_output_buffers(session->pn_raw, &pn_buf_desc, 1);
(void) given;
if (given != 1) {
kag_error = given;
abort();
}
assert(given == 1);
capacity -= 1;
}
Expand All @@ -209,8 +221,13 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
}
while (capacity > 0) {
_pn_buf_desc_give_buffer(&pn_buf_desc, qd_buffer());
ZAP((qd_buffer_t *)pn_buf_desc.context);
given = pn_tls_give_decrypt_output_buffers(session->pn_raw, &pn_buf_desc, 1);
(void) given;
if (given != 1) {
kag_error = given;
abort();
}
assert(given == 1);
capacity -= 1;
}
Expand All @@ -222,6 +239,7 @@ int qd_tls_session_do_io(qd_tls_session_t *session,

while (pn_raw_connection_take_written_buffers(raw_conn, &pn_buf_desc, 1) == 1) {
qd_buffer_t *buf = (qd_buffer_t *) pn_buf_desc.context;
ZAP(buf);
qd_buffer_free(buf);
}

Expand All @@ -248,6 +266,10 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
DEQ_REMOVE_HEAD(ubufs);
_pn_buf_desc_give_buffer(&pn_buf_desc, abuf);
given = pn_tls_give_encrypt_input_buffers(session->pn_raw, &pn_buf_desc, 1);
if (given != 1) {
kag_error = given;
abort();
}
assert(given == 1);
abuf = DEQ_HEAD(ubufs);
}
Expand Down Expand Up @@ -297,11 +319,25 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
session->raw_read_drained = pn_raw_connection_is_read_closed(raw_conn);
break;
} else if (pn_buf_desc.size) {
#if 0
if (0) {
session->kag_last_ptr[session->kag_last_index] = pn_buf_desc.bytes;
session->kag_last_n[session->kag_last_index] = pn_buf_desc.size;
session->kag_last_index += 1;
session->kag_last_index %= KAG_WRITES;
}
#endif
total_octets += pn_buf_desc.size;
given = pn_tls_give_decrypt_input_buffers(session->pn_raw, &pn_buf_desc, 1);
if (given != 1) {
kag_error = given;
abort();
}

assert(given == 1);
++pushed;
} else {
ZAP((qd_buffer_t *)pn_buf_desc.context);
qd_buffer_free((qd_buffer_t *) pn_buf_desc.context);
}
}
Expand All @@ -325,10 +361,23 @@ int qd_tls_session_do_io(qd_tls_session_t *session,

if (!session->tls_error) {
const bool check_if_secure = session->on_secure_cb && !pn_tls_is_secure(session->pn_raw);

int err = pn_tls_process(session->pn_raw);

if (err) {
session->tls_error = true;
qd_log(log_module, QD_LOG_DEBUG, "[C%" PRIu64 "] pn_tls_process failed: error=%d", conn_id, err);

if (err == -2) {
char buf[1024];
if (pn_tls_get_session_error_string(session->pn_raw, buf, sizeof(buf))) {
if (strstr(buf, "bad decrypt") != NULL) {
abort();
}
}
}


} else if (check_if_secure && pn_tls_is_secure(session->pn_raw)) {
session->on_secure_cb(session, session->user_context);
session->on_secure_cb = 0; // one shot
Expand All @@ -350,6 +399,10 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
while (pushed < capacity && pn_tls_take_encrypt_output_buffers(session->pn_raw, &pn_buf_desc, 1) == 1) {
total_octets += pn_buf_desc.size;
given = pn_raw_connection_write_buffers(raw_conn, &pn_buf_desc, 1);
if (given != 1) {
kag_error = given;
abort();
}
assert(given == 1);
++pushed;
}
Expand All @@ -365,6 +418,7 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
taken = 0;
while (pn_tls_take_encrypt_output_buffers(session->pn_raw, &pn_buf_desc, 1) == 1) {
assert(pn_buf_desc.context);
ZAP((qd_buffer_t *)pn_buf_desc.context);
qd_buffer_free(_pn_buf_desc_take_buffer(&pn_buf_desc));
taken += 1;
}
Expand All @@ -391,6 +445,7 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
DEQ_INSERT_TAIL(*input_data, abuf);
++taken;
} else {
ZAP(abuf);
qd_buffer_free(abuf);
}
}
Expand All @@ -413,12 +468,14 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
while (pn_tls_take_encrypt_input_buffers(session->pn_raw, &pn_buf_desc, 1) == 1) {
qd_buffer_t *abuf = (qd_buffer_t *) pn_buf_desc.context;
assert(abuf);
ZAP(abuf);
qd_buffer_free(abuf);
++taken;
}
while (pn_tls_take_decrypt_input_buffers(session->pn_raw, &pn_buf_desc, 1) == 1) {
qd_buffer_t *abuf = (qd_buffer_t *) pn_buf_desc.context;
assert(abuf);
ZAP(abuf);
qd_buffer_free(abuf);
++taken;
}
Expand Down Expand Up @@ -446,6 +503,7 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
}
pn_raw_connection_close(raw_conn);
qd_log(log_module, QD_LOG_WARNING, "[C%" PRIu64 "] TLS connection failed: %s", conn_id, buf);
//sys_mutex_unlock(&session->proton_tls_cfg->lock);
return -1;
}

Expand Down Expand Up @@ -473,6 +531,7 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
pn_raw_connection_read_close(raw_conn);
}
while (pn_raw_connection_take_read_buffers(raw_conn, &pn_buf_desc, 1) == 1) {
ZAP((qd_buffer_t *)pn_buf_desc.context);
qd_buffer_free(_pn_buf_desc_take_buffer(&pn_buf_desc));
}
} else if (session->raw_read_drained && !pn_tls_is_decrypt_output_pending(session->pn_raw)) {
Expand All @@ -482,10 +541,13 @@ int qd_tls_session_do_io(qd_tls_session_t *session,
qd_log(log_module, QD_LOG_DEBUG, "[C%" PRIu64 "] TLS input closed", conn_id);
}

//sys_mutex_unlock(&session->proton_tls_cfg->lock);
return session->input_drained && session->output_flushed ? QD_TLS_DONE : 0;
}




bool qd_tls_session_is_error(const qd_tls_session_t *session)
{
if (!session || !session->pn_raw)
Expand Down
97 changes: 54 additions & 43 deletions tests/system_tests_tcp_adaptor_tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -870,23 +870,27 @@ def test_ssl_profile_update(self):
#

skmgr_a = self.router_qdra.sk_manager
skmgr_b = self.router_qdrb.sk_manager

with self.assertRaises(Exception) as emgr:
skmgr_a.update(SSL_PROFILE_TYPE, {'password': 'badpassword'},
name='listener-ssl-profile')
skmgr_a.update(SSL_PROFILE_TYPE, self.listener_profile_cfg, name='listener-ssl-profile')
skmgr_b.update(SSL_PROFILE_TYPE, self.connector_profile_cfg, name='connector-ssl-profile')

self.assertIn('Failed to set TLS certFile', str(emgr.exception))
# with self.assertRaises(Exception) as emgr:
# skmgr_a.update(SSL_PROFILE_TYPE, {'password': 'badpassword'},
# name='listener-ssl-profile')

# self.assertIn('Failed to set TLS certFile', str(emgr.exception))

#
# Restore the proper password and verify clients can connect
#

skmgr_a.update(SSL_PROFILE_TYPE, {'password':
SERVER_PRIVATE_KEY_PASSWORD},
name='listener-ssl-profile')
# skmgr_a.update(SSL_PROFILE_TYPE, {'password':
# SERVER_PRIVATE_KEY_PASSWORD},
# name='listener-ssl-profile')

out = skmgr_a.read(name='listener-ssl-profile')
self.assertEqual(SERVER_PRIVATE_KEY_PASSWORD, out['password'])
# out = skmgr_a.read(name='listener-ssl-profile')
# self.assertEqual(SERVER_PRIVATE_KEY_PASSWORD, out['password'])

out, error = self.opensslclient(port=self.router_listener_port,
ssl_info=client_ssl_info,
Expand All @@ -901,29 +905,29 @@ def test_ssl_profile_update(self):
# Now update the listener sslProfile with a valid config, but one that
# will not allow the client to connect
#
new_cfg = {'caCertFile': CA2_CERT,
'certFile': SERVER2_CERTIFICATE,
'privateKeyFile': SERVER2_PRIVATE_KEY,
'password': SERVER2_PRIVATE_KEY_PASSWORD}
skmgr_a.update(SSL_PROFILE_TYPE, new_cfg, name='listener-ssl-profile')

out, error = self.opensslclient(port=self.router_listener_port,
ssl_info=client_ssl_info,
data=b"The CA will not allow this!" + payload,
expect=Process.EXIT_FAIL,
cl_args=self.s_client_args)
self.router_qdra.wait_log_message(r'TLS connection failed')
# new_cfg = {'caCertFile': CA2_CERT,
# 'certFile': SERVER2_CERTIFICATE,
# 'privateKeyFile': SERVER2_PRIVATE_KEY,
# 'password': SERVER2_PRIVATE_KEY_PASSWORD}
# skmgr_a.update(SSL_PROFILE_TYPE, new_cfg, name='listener-ssl-profile')

# out, error = self.opensslclient(port=self.router_listener_port,
# ssl_info=client_ssl_info,
# data=b"The CA will not allow this!" + payload,
# expect=Process.EXIT_FAIL,
# cl_args=self.s_client_args)
# self.router_qdra.wait_log_message(r'TLS connection failed')

#
# Update the client ssl_info to use a compatible client cert and verify
# all is well:
#

client_ssl_info = dict()
client_ssl_info['CA_CERT'] = CA2_CERT
client_ssl_info['CLIENT_CERTIFICATE'] = CLIENT2_CERTIFICATE
client_ssl_info['CLIENT_PRIVATE_KEY'] = CLIENT2_PRIVATE_KEY
client_ssl_info['CLIENT_PRIVATE_KEY_PASSWORD'] = CLIENT2_PRIVATE_KEY_PASSWORD
# client_ssl_info = dict()
# client_ssl_info['CA_CERT'] = CA2_CERT
# client_ssl_info['CLIENT_CERTIFICATE'] = CLIENT2_CERTIFICATE
# client_ssl_info['CLIENT_PRIVATE_KEY'] = CLIENT2_PRIVATE_KEY
# client_ssl_info['CLIENT_PRIVATE_KEY_PASSWORD'] = CLIENT2_PRIVATE_KEY_PASSWORD
out, error = self.opensslclient(port=self.router_listener_port,
ssl_info=client_ssl_info,
data=b"Hey we recovered!" + payload,
Expand All @@ -944,11 +948,11 @@ def test_ssl_profile_update(self):
#

openssl_server.teardown()
server_ssl_info = dict()
server_ssl_info['CA_CERT'] = CA2_CERT
server_ssl_info['SERVER_CERTIFICATE'] = SERVER2_CERTIFICATE
server_ssl_info['SERVER_PRIVATE_KEY'] = SERVER2_PRIVATE_KEY
server_ssl_info['SERVER_PRIVATE_KEY_PASSWORD'] = SERVER2_PRIVATE_KEY_PASSWORD
# server_ssl_info = dict()
# server_ssl_info['CA_CERT'] = CA2_CERT
# server_ssl_info['SERVER_CERTIFICATE'] = SERVER2_CERTIFICATE
# server_ssl_info['SERVER_PRIVATE_KEY'] = SERVER2_PRIVATE_KEY
# server_ssl_info['SERVER_PRIVATE_KEY_PASSWORD'] = SERVER2_PRIVATE_KEY_PASSWORD
openssl_server = server_create(listening_port=self.openssl_server_listening_port,
ssl_info=server_ssl_info,
name="OpenSSLServerAuthPeer2",
Expand All @@ -958,21 +962,28 @@ def test_ssl_profile_update(self):
ssl_info=client_ssl_info,
data=b"The server conn must fail" + payload,
cl_args=self.s_client_args)
self.router_qdrb.wait_log_message(r'TLS connection failed')
with open(openssl_server.outfile_path, 'rt') as out_file:
self.assertFalse(is_pattern_present(out_file,
"The server conn must fail"),
"TLS connection did not fail")
self.assertIn(b"Verification: OK", out, f"{error}")
self.assertIn(b"Verify return code: 0 (ok)", out, f"{error}")
openssl_server.wait_out_message("The server conn must fail")

skmgr_a.update(SSL_PROFILE_TYPE, self.listener_profile_cfg, name='listener-ssl-profile')
skmgr_b.update(SSL_PROFILE_TYPE, self.connector_profile_cfg, name='connector-ssl-profile')

# self.router_qdrb.wait_log_message(r'TLS connection failed')
# with open(openssl_server.outfile_path, 'rt') as out_file:
# self.assertFalse(is_pattern_present(out_file,
# "The server conn must fail"),
# "TLS connection did not fail")

# Now update the connectors sslProfile with a compatible client cert
# and verify a new connection succeeds

new_cfg = {'caCertFile': CA2_CERT,
'certFile': CLIENT2_CERTIFICATE,
'privateKeyFile': CLIENT2_PRIVATE_KEY,
'password': CLIENT2_PRIVATE_KEY_PASSWORD}
skmgr_b = self.router_qdrb.sk_manager
skmgr_b.update(SSL_PROFILE_TYPE, new_cfg, name='connector-ssl-profile')
# new_cfg = {'caCertFile': CA2_CERT,
# 'certFile': CLIENT2_CERTIFICATE,
# 'privateKeyFile': CLIENT2_PRIVATE_KEY,
# 'password': CLIENT2_PRIVATE_KEY_PASSWORD}
# skmgr_b = self.router_qdrb.sk_manager
#skmgr_b.update(SSL_PROFILE_TYPE, new_cfg, name='connector-ssl-profile')
out, error = self.opensslclient(port=self.router_listener_port,
ssl_info=client_ssl_info,
data=b"The server conn must succeed!" + payload,
Expand Down Expand Up @@ -1114,7 +1125,7 @@ def test_ssl_profile_update_load(self):
clients = []

for test in range(10):
for c_index in range(2):
for c_index in range(4):
client_name = f"SslProfileEchoClient-{test}-{c_index}"
client_logger = Logger(title=client_name,
print_to_console=False,
Expand Down

0 comments on commit 2c11a03

Please sign in to comment.