code wiki / (root) / nx_tls13_server_session_app_data.nx

nx_tls13_server_session_app_data.nx source

↩ module page · 150 lines · 5494 B

1// nx_tls13_server_session_app_data.nx -- application-data layer for 2// a CONNECTED Tls13ServerSession. 3// 4// After the handshake completes (state CONNECTED), the session has 5// derived application traffic keys for both directions: 6// server_app_traffic_key + server_app_iv (for what WE send) 7// client_app_traffic_key + client_app_iv (for what we RECEIVE) 8// 9// Sequence numbers RESET to 0 for the app-data phase per RFC 8446 10// §5.3. This file ships: 11// 12// nx_tls13_server_session_app_send(session, payload, len, out, cap) 13// Encrypts payload as a TLS application_data record under 14// server_app_*; increments server_app_seq; returns bytes written. 15// 16// nx_tls13_server_session_app_recv(session, record, rec_len, out, cap) 17// Decrypts a TLS record under client_app_*; validates record type 18// is APPLICATION_DATA inside; writes plaintext to out; increments 19// client_app_seq; returns plaintext byte count. 20// 21// This is the substrate primitive HTTPS callers use after handshake 22// to actually serve request/response bytes. 23// 24// license_tier: ORIGINAL 25 26import "nx_syscalls.nx" 27import "nx_tls13.nx" 28import "nx_tls13_record.nx" 29import "nx_tls13_server_session.nx" 30 31const NX_TLS13_APP_REC_HEADER: i64 = 5 32const NX_TLS13_APP_REC_TAG: i64 = 16 33 34func nx_tls13_server_session_app_send( 35 session: *Tls13ServerSession, 36 payload: *u8, payload_len: i64, 37 out: *u8, out_cap: i64 38) -> i64 { 39 if (session as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 40 if (out as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 41 if (payload as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 42 if payload_len < 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 43 if session.state != NX_TLS13_SSTATE_CONNECTED { 44 return 0 - NX_TLS13_SSESSION_BAD_STATE 45 } 46 if (session.server_app_traffic_key as i64) == 0 { 47 return 0 - NX_TLS13_SSESSION_INTERNAL 48 } 49 50 let total_needed: i64 = NX_TLS13_APP_REC_HEADER + payload_len + 1 + NX_TLS13_APP_REC_TAG 51 if out_cap < total_needed { return 0 - NX_TLS13_SSESSION_BUF_OVERFLOW } 52 53 let header_buf: *u8 = sys_mmap(NX_TLS13_APP_REC_HEADER) 54 let ct_buf: *u8 = sys_mmap(payload_len + 17) 55 let tag_buf: *u8 = sys_mmap(NX_TLS13_APP_REC_TAG) 56 57 let rv: i64 = nx_tls13_record_encrypt_v2( 58 session.cipher_suite, 59 session.server_app_traffic_key, 60 session.server_app_iv, 61 session.server_app_seq, 62 payload, payload_len, 63 CT_APPLICATION_DATA, // inner type = application data 64 0, // no padding 65 header_buf, ct_buf, tag_buf) 66 if rv != NX_TLS13_REC_VERDICT_OK { 67 return 0 - NX_TLS13_SSESSION_INTERNAL 68 } 69 70 var w: i64 = 0 71 var hi: i64 = 0 72 while hi < NX_TLS13_APP_REC_HEADER { 73 out[w + hi] = header_buf[hi] 74 hi = hi + 1 75 } 76 w = w + NX_TLS13_APP_REC_HEADER 77 let ct_len: i64 = payload_len + 1 // payload + inner type byte 78 var ci: i64 = 0 79 while ci < ct_len { 80 out[w + ci] = ct_buf[ci] 81 ci = ci + 1 82 } 83 w = w + ct_len 84 var ti: i64 = 0 85 while ti < NX_TLS13_APP_REC_TAG { 86 out[w + ti] = tag_buf[ti] 87 ti = ti + 1 88 } 89 w = w + NX_TLS13_APP_REC_TAG 90 91 session.server_app_seq = session.server_app_seq + 1 92 return w 93} 94 95func nx_tls13_server_session_app_recv( 96 session: *Tls13ServerSession, 97 record: *u8, record_len: i64, 98 out: *u8, out_cap: i64 99) -> i64 { 100 if (session as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 101 if (record as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 102 if (out as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 103 if session.state != NX_TLS13_SSTATE_CONNECTED { 104 return 0 - NX_TLS13_SSESSION_BAD_STATE 105 } 106 if (session.client_app_traffic_key as i64) == 0 { 107 return 0 - NX_TLS13_SSESSION_INTERNAL 108 } 109 if record_len < NX_TLS13_APP_REC_HEADER + 1 + NX_TLS13_APP_REC_TAG { 110 return 0 - NX_TLS13_SSESSION_PROTOCOL_ERR 111 } 112 113 let header: *u8 = record 114 if header[0] != 0x17 { // app_data record wrapper type 115 return 0 - NX_TLS13_SSESSION_PROTOCOL_ERR 116 } 117 118 let body_len: i64 = ((header[3] as i64) << 8) | (header[4] as i64) 119 if NX_TLS13_APP_REC_HEADER + body_len > record_len { 120 return 0 - NX_TLS13_SSESSION_PROTOCOL_ERR 121 } 122 let ct_len: i64 = body_len - NX_TLS13_APP_REC_TAG 123 if ct_len < 1 { return 0 - NX_TLS13_SSESSION_PROTOCOL_ERR } 124 let ct: *u8 = (((record as i64) + NX_TLS13_APP_REC_HEADER)) as *u8 125 let tag: *u8 = (((record as i64) + NX_TLS13_APP_REC_HEADER + ct_len)) as *u8 126 127 if out_cap < ct_len { return 0 - NX_TLS13_SSESSION_BUF_OVERFLOW } 128 let real_ct_box: *i64 = sys_mmap(8) as *i64 129 let real_len_box: *i64 = sys_mmap(8) as *i64 130 131 let rv: i64 = nx_tls13_record_decrypt_v2( 132 session.cipher_suite, 133 session.client_app_traffic_key, 134 session.client_app_iv, 135 session.client_app_seq, 136 header, ct, ct_len, tag, 137 out, real_ct_box, real_len_box) 138 if rv != NX_TLS13_REC_VERDICT_OK { 139 return 0 - NX_TLS13_SSESSION_PROTOCOL_ERR 140 } 141 // Real content type should be APPLICATION_DATA per RFC 8446 §5.5. 142 // (Mid-stream handshake messages like KeyUpdate are possible but 143 // we don't handle them in v1.) 144 if *real_ct_box != CT_APPLICATION_DATA { 145 return 0 - NX_TLS13_SSESSION_PROTOCOL_ERR 146 } 147 148 session.client_app_seq = session.client_app_seq + 1 149 return *real_len_box 150}