Skip to content

Commit 5dec311

Browse files
ssl functionality
1 parent 18c4f39 commit 5dec311

File tree

9 files changed

+3788
-35
lines changed

9 files changed

+3788
-35
lines changed

include/basic/sockets.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,7 @@ int64_t basic_sockaccept(struct basic_ctx* ctx);
193193
* @param ctx BASIC context.
194194
*/
195195
void sockflush_statement(struct basic_ctx* ctx);
196+
197+
int64_t basic_sslsockaccept(struct basic_ctx* ctx);
198+
199+
void sslconnect_statement(struct basic_ctx* ctx);

include/basic/tokenizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ typedef void (*keyword_handler_t)(struct basic_ctx*);
203203
T(ENVELOPE, STMT, envelope_statement) /* 131 */ \
204204
T(TONE, STMT, NULL) /* 132 */ \
205205
T(SCROLLREGION, STMT, scrollregion_statement) /* 133 */ \
206+
T(SSLCONNECT, STMT, sslconnect_statement) /* 134 */ \
206207

207208
GENERATE_ENUM_LIST(TOKEN, token_t)
208209

include/mbedtls/config.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,12 @@
142142
#define MBEDTLS_PK_PARSE_C
143143
#define MBEDTLS_X509_CRT_PARSE_C
144144
#define MBEDTLS_PEM_PARSE_C
145+
146+
#undef MBEDTLS_SSL_RENEGOTIATION
147+
148+
#define MBEDTLS_SSL_CLI_C
149+
#define MBEDTLS_SSL_SRV_C
150+
#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
151+
152+
#undef MBEDTLS_SSL_PROTO_TLS1
153+
#undef MBEDTLS_SSL_PROTO_TLS1_1

include/tls.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,6 @@ int ssl_accept(int listen_fd, const uint8_t *cert_pem, size_t cert_len, const ui
221221
* @param fd Socket descriptor
222222
* @return opaque pointer, or NULL if not TLS
223223
*/
224-
struct tls_peer *tls_get(int fd);
224+
struct tls_peer *tls_get(int fd);
225+
226+
bool tls_ready_fd(int fd);

os/system/ssl/cacert.pem

Lines changed: 3556 additions & 0 deletions
Large diffs are not rendered by default.

src/basic/function.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct basic_int_fn builtin_int[] =
5050
{ basic_shiftkey, "SHIFTKEY" },
5151
{ basic_shr, "SHR" },
5252
{ basic_sockaccept, "SOCKACCEPT" },
53+
{ basic_sslsockaccept, "SSLSOCKACCEPT" },
5354
{ basic_socklisten, "SOCKLISTEN" },
5455
{ basic_sockstatus, "SOCKSTATUS" },
5556
{ basic_get_text_max_y, "TERMHEIGHT" },

src/basic/sockets.c

Lines changed: 150 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,33 @@ static spinlock_t udp_read_lock = 0;
1414
* Used by the scheduler to determine if the SOCKREAD statement
1515
* can resume execution. Returns true if still waiting.
1616
*
17-
* @param proc Process being checked
18-
* @param ptr Pointer containing the socket FD (cast from uintptr_t)
19-
* @return true if still waiting, false if ready
17+
* For TLS-backed sockets, this consults the TLS layer to see if
18+
* decrypted bytes are pending.
19+
*
20+
* @param proc Process being checked.
21+
* @param ptr Pointer containing the socket FD (cast from uintptr_t).
22+
* @return true if still waiting, false if ready.
2023
*/
21-
bool check_sockread_ready(process_t* proc, void* ptr) {
22-
int64_t fd = (int64_t)(uintptr_t)ptr;
24+
bool check_sockread_ready(process_t* proc, void* ptr)
25+
{
26+
int64_t fd;
27+
28+
(void) proc; /* unused */
29+
30+
fd = (int64_t)(uintptr_t) ptr;
31+
2332
if (basic_esc()) {
2433
return false;
2534
}
26-
return !sock_ready_to_read((int)fd);
35+
36+
if (tls_get(fd)) {
37+
return !tls_ready_fd(fd);
38+
}
39+
40+
return !sock_ready_to_read(fd);
2741
}
2842

43+
2944
/**
3045
* @brief Process SOCKREAD statement.
3146
*
@@ -35,26 +50,53 @@ bool check_sockread_ready(process_t* proc, void* ptr) {
3550
* data is available, the scheduler resumes the statement, which
3651
* reads and stores the value in a BASIC variable.
3752
*
38-
* @param ctx BASIC context
53+
* For TLS-backed sockets, bytes are pulled through the TLS layer.
54+
*
55+
* @param ctx BASIC context.
3956
*/
4057
void sockread_statement(struct basic_ctx* ctx)
4158
{
4259
char input[MAX_STRINGLEN];
43-
const char* var = NULL;
60+
const char* var;
61+
size_t var_length;
62+
int64_t fd;
63+
process_t* proc;
64+
int rv;
65+
66+
var = NULL;
4467

4568
accept_or_return(SOCKREAD, ctx);
4669

47-
size_t var_length;
48-
int64_t fd = basic_get_numeric_int_variable(tokenizer_variable_name(ctx, &var_length), ctx);
70+
fd = basic_get_numeric_int_variable(tokenizer_variable_name(ctx, &var_length), ctx);
4971
accept_or_return(VARIABLE, ctx);
5072
accept_or_return(COMMA, ctx);
5173

5274
var = tokenizer_variable_name(ctx, &var_length);
5375
accept_or_return(VARIABLE, ctx);
5476

55-
process_t* proc = proc_cur(logical_cpu_id());
77+
proc = proc_cur(logical_cpu_id());
78+
79+
if (tls_get(fd)) {
80+
int want;
81+
int out_n;
82+
bool ok;
83+
84+
want = 0;
85+
out_n = 0;
5686

57-
int rv = recv((int)fd, input, MAX_STRINGLEN, false, 100);
87+
ok = tls_read_fd(fd, input, MAX_STRINGLEN, &want, &out_n);
88+
if (ok) {
89+
rv = out_n;
90+
} else {
91+
if (want == 1) {
92+
rv = 0; /* WANT_READ → would block */
93+
} else {
94+
rv = TCP_ERROR_CONNECTION_FAILED; /* fatal TLS */
95+
}
96+
}
97+
} else {
98+
rv = recv(fd, input, MAX_STRINGLEN, false, 100);
99+
}
58100

59101
dprintf("sockread recv=%d\n", rv);
60102

@@ -66,7 +108,6 @@ void sockread_statement(struct basic_ctx* ctx)
66108
return;
67109
}
68110

69-
// Clear idle state if we're resuming from IO
70111
proc_set_idle(proc, NULL, NULL);
71112

72113
if (rv < 0) {
@@ -75,6 +116,9 @@ void sockread_statement(struct basic_ctx* ctx)
75116
return;
76117
}
77118

119+
if ((size_t) rv >= sizeof(input)) {
120+
rv = (int) (sizeof(input) - 1);
121+
}
78122
input[rv] = 0; // Null-terminate string
79123

80124
switch (var[var_length - 1]) {
@@ -98,7 +142,7 @@ void sockread_statement(struct basic_ctx* ctx)
98142

99143
void sockbinread_statement(struct basic_ctx* ctx)
100144
{
101-
accept_or_return(SOCKBINREAD, ctx);
145+
int rv;
102146
size_t var_length;
103147
int64_t fd = basic_get_numeric_int_variable(tokenizer_variable_name(ctx, &var_length), ctx);
104148
accept_or_return(VARIABLE, ctx);
@@ -113,7 +157,27 @@ void sockbinread_statement(struct basic_ctx* ctx)
113157

114158
process_t* proc = proc_cur(logical_cpu_id());
115159

116-
int rv = recv((int)fd, address, length, false, 100);
160+
if (tls_get(fd)) {
161+
int want;
162+
int out_n;
163+
bool ok;
164+
165+
want = 0;
166+
out_n = 0;
167+
168+
ok = tls_read_fd(fd, address, length, &want, &out_n);
169+
if (ok) {
170+
rv = out_n;
171+
} else {
172+
if (want == 1) {
173+
rv = 0; /* WANT_READ → would block */
174+
} else {
175+
rv = TCP_ERROR_CONNECTION_FAILED; /* fatal TLS */
176+
}
177+
}
178+
} else {
179+
rv = recv((int) fd, (void*) address, (uint32_t) length, false, 100);
180+
}
117181

118182
if (rv == 0) {
119183
// Not ready yet, yield and retry later
@@ -123,7 +187,6 @@ void sockbinread_statement(struct basic_ctx* ctx)
123187
return;
124188
}
125189

126-
// Clear idle state if we're resuming from IO
127190
proc_set_idle(proc, NULL, NULL);
128191

129192
if (rv < 0) {
@@ -136,8 +199,7 @@ void sockbinread_statement(struct basic_ctx* ctx)
136199
proc->state = PROC_RUNNING;
137200
}
138201

139-
void connect_statement(struct basic_ctx* ctx)
140-
{
202+
void connect_statement(struct basic_ctx* ctx) {
141203
char input[MAX_STRINGLEN];
142204
const char* fd_var = NULL, *ip = NULL;
143205
int64_t port;
@@ -173,8 +235,47 @@ void connect_statement(struct basic_ctx* ctx)
173235
}
174236
}
175237

176-
void sockclose_statement(struct basic_ctx* ctx)
177-
{
238+
void sslconnect_statement(struct basic_ctx* ctx) {
239+
char input[MAX_STRINGLEN];
240+
const char* fd_var = NULL, *ip = NULL, *sni = NULL;
241+
int64_t port;
242+
size_t var_length;
243+
244+
accept_or_return(CONNECT, ctx);
245+
fd_var = tokenizer_variable_name(ctx, &var_length);
246+
accept_or_return(VARIABLE, ctx);
247+
accept_or_return(COMMA, ctx);
248+
ip = str_expr(ctx);
249+
accept_or_return(COMMA, ctx);
250+
port = expr(ctx);
251+
accept_or_return(COMMA, ctx);
252+
sni = expr(ctx);
253+
254+
const char* ca = "";
255+
256+
int rv = ssl_connect(str_to_ip(ip), port, 0, true, sni, NULL, (const uint8_t*)ca, strlen(ca));
257+
258+
if (rv >= 0) {
259+
*(input + rv) = 0;
260+
switch (fd_var[var_length - 1]) {
261+
case '$':
262+
tokenizer_error_print(ctx, "Can't store socket descriptor in STRING");
263+
break;
264+
case '#':
265+
tokenizer_error_print(ctx, "Cannot store socket descriptor in REAL");
266+
break;
267+
default:
268+
basic_set_int_variable(fd_var, rv, ctx, false, false);
269+
break;
270+
}
271+
272+
accept_or_return(NEWLINE, ctx);
273+
} else {
274+
tokenizer_error_print(ctx, socket_error(rv));
275+
}
276+
}
277+
278+
void sockclose_statement(struct basic_ctx* ctx) {
178279
const char* fd_var = NULL;
179280
size_t var_length;
180281

@@ -233,15 +334,17 @@ int64_t basic_sslsockaccept(struct basic_ctx* ctx) {
233334
PARAMS_START;
234335
PARAMS_GET_ITEM(BIP_INT);
235336
int64_t server = intval;
337+
PARAMS_GET_ITEM(BIP_STRING);
338+
const char* cert = strval;
339+
PARAMS_GET_ITEM(BIP_INT);
340+
const char* key = strval;
236341
PARAMS_END("SSLSOCKACCEPT",-1);
237-
/*int rv = ssl_accept(server, cert_pem, cert_len, key_pem, key_len, NULL, true);
238-
if (rv == TCP_ERROR_WOULD_BLOCK) {
239-
return -1;
240-
} else if (rv < 0) {
342+
int rv = ssl_accept(server, (const uint8_t*)cert, strlen(cert), (const uint8_t*)key, strlen(key), NULL, true);
343+
if (rv < 0) {
241344
tokenizer_error_print(ctx, socket_error(rv));
242345
return -1;
243-
}*/
244-
return -1;
346+
}
347+
return rv;
245348
}
246349

247350
char* basic_insocket(struct basic_ctx* ctx) {
@@ -334,7 +437,16 @@ void sockwrite_statement(struct basic_ctx* ctx) {
334437
accept_or_return(COMMA, ctx);
335438
const char* out = printable_syntax(ctx);
336439
if (out) {
337-
send(fd, out, strlen(out));
440+
if (tls_get(fd)) {
441+
int want;
442+
int out_n;
443+
444+
want = 0;
445+
out_n = 0;
446+
tls_write_fd(fd, out, strlen(out), &want, &out_n);
447+
} else {
448+
send(fd, out, strlen(out));
449+
}
338450
}
339451
}
340452

@@ -353,9 +465,19 @@ void sockbinwrite_statement(struct basic_ctx* ctx) {
353465
}
354466

355467
if (buffer_pointer && length) {
356-
send(fd, buffer_pointer, length);
468+
if (tls_get(fd)) {
469+
int want;
470+
int out_n;
471+
472+
want = 0;
473+
out_n = 0;
474+
tls_write_fd(fd, (const void*) buffer_pointer, (size_t) length, &want, &out_n);
475+
} else {
476+
send(fd, buffer_pointer, length);
477+
}
357478
}
358479
}
480+
359481
static void basic_udp_handle_packet(uint32_t src_ip, uint16_t src_port, uint16_t dst_port, void* data, uint32_t length, void* opaque) {
360482
basic_ctx* ctx = (basic_ctx*)opaque;
361483
if (!opaque) {

src/net/tcp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,8 @@ void tcp_idle()
11891189
void tcp_init() {
11901190
tcb = hashmap_new(sizeof(tcp_conn_t), 0, 6, 28, tcp_conn_hash, tcp_conn_compare, NULL, NULL);
11911191
tls_fd_table_init(FD_MAX);
1192-
proc_register_idle(tcp_idle, IDLE_FOREGROUND, 1);
1192+
//proc_register_idle(tcp_idle, IDLE_FOREGROUND, 1);
1193+
proc_register_idle(tcp_idle, IDLE_BACKGROUND, 1);
11931194
}
11941195

11951196
/**

0 commit comments

Comments
 (0)