code wiki / _hdl_build / nx_opaque_login_tls_daemon.nx
nx_opaque_login_tls_daemon.nx source
↩ module page · 93 lines · 5169 B
1// nx_opaque_login_tls_daemon.nx -- R3-B: the no-cookie OPAQUE login served over SOVEREIGN TLS 1.3 (ECDSA
2// P-256, browser-trusted with the LE cert) on the real domain. Same route table as the plain daemon
3// (nx_opaque_login_routes.olg_route -- rule 15 DRY), wrapped per-connection in the team's own TLS stack:
4// nx_tls13_server_session_run (ECDSA) -> app_recv (decrypt) -> olg_route -> app_send (encrypt) -> write.
5// argv: [1]=port [2]=keys-path [3]=store-path [4]=budget [5]=cert.der [6]=ecdsa_key.bin(32B) [7]=argon2_m (opt).
6// Fresh server ECDHE + ServerHello random PER CONNECTION (forward secrecy). No shortcuts: full OPAQUE +
7// real TLS 1.3 + production argon2id default.
8import "nx_opaque_login_routes.nx" // olg_route + olg_ctx_setup + NxAuthContext (transitive)
9import "nx_tls13_server_session.nx" // Tls13ServerSession
10import "nx_tls13_server_session_run.nx" // nx_tls13_server_session_run (ECDSA)
11import "nx_tls13_server_session_app_data.nx" // nx_tls13_server_session_app_recv / app_send
12import "nx_csprng.nx" // nx_csprng_fill
13
14const OLT_PROD_M: i64 = 65536 // production argon2id m_cost (64 MiB)
15
16func olt_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c<48{return v} if c>57{return v} v=v*10+(c-48); i=i+1 } return v }
17
18func main(argc: i64, argv: *i64) -> i64 {
19 if argc < 7 {
20 sys_write(1, "usage: nx_opaque_login_tls_daemon <port> <keys> <store> <budget> <cert.der> <ecdsa_key.bin> [m_cost]\n" as *u8, 99)
21 sys_exit(2); return 2
22 }
23 let port: i64 = olt_atoi(argv[1] as *u8)
24 let keys_path: *u8 = argv[2] as *u8
25 let store_path: *u8 = argv[3] as *u8
26 let budget: i64 = olt_atoi(argv[4] as *u8)
27 let cert_path: *u8 = argv[5] as *u8
28 let key_path: *u8 = argv[6] as *u8
29 var m_cost: i64 = OLT_PROD_M
30 if argc > 7 { m_cost = olt_atoi(argv[7] as *u8) }
31
32 // ---- OPAQUE auth context ----
33 let ctx: *NxAuthContext = sys_mmap(256) as *NxAuthContext
34 if olg_ctx_setup(ctx, keys_path, store_path, "nishi_site_admin" as *u8, 16, "Nishi site admin" as *u8, 16, m_cost, 3, 4) != 0 {
35 sys_write(1, "CTX-INIT-FAIL\n" as *u8, 14); sys_exit(1); return 1
36 }
37
38 // ---- TLS cert + ECDSA P-256 private key (32-byte big-endian scalar) ----
39 let clen: *i64 = sys_mmap(8) as *i64; clen[0] = 0
40 let cert_der: *u8 = sys_read_file(cert_path, clen)
41 if (cert_der as i64) == 0 { sys_write(1, "CERT-LOAD-FAIL\n" as *u8, 15); sys_exit(1); return 1 }
42 let cert_der_len: i64 = clen[0]
43 let klen: *i64 = sys_mmap(8) as *i64; klen[0] = 0
44 let ecdsa_priv: *u8 = sys_read_file(key_path, klen)
45 if (ecdsa_priv as i64) == 0 { sys_write(1, "KEY-LOAD-FAIL\n" as *u8, 14); sys_exit(1); return 1 }
46 if klen[0] != 32 { sys_write(1, "KEY-NOT-32B\n" as *u8, 12); sys_exit(1); return 1 }
47
48 // ---- listen 0.0.0.0:port ----
49 let addr: *u8 = sys_mmap(16)
50 addr[0]=2 as u8; addr[1]=0 as u8
51 addr[2]=((port>>8)&0xff) as u8; addr[3]=(port&0xff) as u8
52 addr[4]=0 as u8; addr[5]=0 as u8; addr[6]=0 as u8; addr[7]=0 as u8
53 var zi: i64=8; while zi<16 { addr[zi]=0 as u8; zi=zi+1 }
54 let lfd: i64 = sys_socket(2, 1, 0)
55 if lfd < 0 { sys_write(1, "SOCKET-FAIL\n" as *u8, 12); sys_exit(1); return 1 }
56 let optv: *u8 = sys_mmap(4); optv[0]=1 as u8
57 sys_setsockopt(lfd, 1, 2, optv, 4)
58 if sys_bind(lfd, addr, 16) < 0 { sys_write(1, "BIND-FAIL\n" as *u8, 10); sys_exit(1); return 1 }
59 if sys_listen(lfd, 16) < 0 { sys_write(1, "LISTEN-FAIL\n" as *u8, 12); sys_exit(1); return 1 }
60 sys_write(1, "OPAQUE-TLS-UP\n" as *u8, 14)
61
62 var served: i64 = 0
63 while served < budget {
64 let cfd: i64 = sys_accept(lfd)
65 if cfd >= 0 {
66 sys_set_socket_timeout(cfd, 10)
67 // fresh server ECDHE + ServerHello random PER CONNECTION (forward secrecy)
68 let srv_rand: *u8 = sys_mmap(32); let srv_x: *u8 = sys_mmap(32)
69 nx_csprng_fill(srv_rand, 32); nx_csprng_fill(srv_x, 32)
70 let s_raw: i64 = nx_tls13_server_session_run(cfd, srv_rand, srv_x, cert_der, cert_der_len, ecdsa_priv)
71 if s_raw > 0 {
72 let s: *Tls13ServerSession = s_raw as *Tls13ServerSession
73 let rec: *u8 = sys_mmap(65536)
74 let rec_n: i64 = sys_read(cfd, rec, 65536)
75 if rec_n > 0 {
76 let plain: *u8 = sys_mmap(65536)
77 let plain_n: i64 = nx_tls13_server_session_app_recv(s, rec, rec_n, plain, 65536)
78 if plain_n > 0 {
79 let now: i64 = sys_now_realtime_sec()
80 let resp: *u8 = sys_mmap(262144)
81 let resp_n: i64 = olg_route(ctx, plain, plain_n, now, resp, 262144)
82 let out_rec: *u8 = sys_mmap(300000)
83 let out_n: i64 = nx_tls13_server_session_app_send(s, resp, resp_n, out_rec, 300000)
84 if out_n > 0 { sys_write(cfd, out_rec, out_n) }
85 }
86 }
87 }
88 sys_close(cfd)
89 }
90 served = served + 1
91 }
92 sys_close(lfd); sys_exit(0); return 0
93}