nx_x509_validate_test.nx source
↩ module page · 140 lines · 5298 B
1// nx_x509_validate_test.nx -- self-signed Ed25519 cert validation KAT.
2//
3// We don't construct a full RFC 5280 DER cert here -- that requires
4// a DER encoder (queued). Instead we synthesise the minimum
5// structure x509_verify_signature_ed25519 needs: a contiguous
6// byte buffer holding [tbs || pubkey || sig], and a manually-set
7// X509Cert struct pointing at the right offsets.
8//
9// The signature is REAL: signed with ed25519_sign_full at test
10// time using RFC 8032 §7.1 TEST 1 priv -> pub. This proves the
11// full chain: ed25519_sign produces a sig, x509_verify accepts it
12// when given the right pubkey, rejects it when:
13// - any tbs byte flipped
14// - any sig byte flipped
15// - signer_pubkey is wrong
16//
17// expect_exit: 0
18// license_tier: ORIGINAL
19
20import "nx_syscalls.nx"
21import "nx_x509.nx"
22import "nx_ed25519_signature.nx"
23import "nx_x509_validate.nx"
24
25func main() -> i64 {
26 // ---- RFC 8032 §7.1 TEST 1 priv + pub ----
27 let priv: *u8 = sys_mmap(64)
28 priv[0]=0x9d; priv[1]=0x61; priv[2]=0xb1; priv[3]=0x9d
29 priv[4]=0xef; priv[5]=0xfd; priv[6]=0x5a; priv[7]=0x60
30 priv[8]=0xba; priv[9]=0x84; priv[10]=0x4a; priv[11]=0xf4
31 priv[12]=0x92; priv[13]=0xec; priv[14]=0x2c; priv[15]=0xc4
32 priv[16]=0x44; priv[17]=0x49; priv[18]=0xc5; priv[19]=0x69
33 priv[20]=0x7b; priv[21]=0x32; priv[22]=0x69; priv[23]=0x19
34 priv[24]=0x70; priv[25]=0x3b; priv[26]=0xac; priv[27]=0x03
35 priv[28]=0x1c; priv[29]=0xae; priv[30]=0x7f; priv[31]=0x60
36
37 let pub: *u8 = sys_mmap(64)
38 pub[0]=0xd7; pub[1]=0x5a; pub[2]=0x98; pub[3]=0x01
39 pub[4]=0x82; pub[5]=0xb1; pub[6]=0x0a; pub[7]=0xb7
40 pub[8]=0xd5; pub[9]=0x4b; pub[10]=0xfe; pub[11]=0xd3
41 pub[12]=0xc9; pub[13]=0x64; pub[14]=0x07; pub[15]=0x3a
42 pub[16]=0x0e; pub[17]=0xe1; pub[18]=0x72; pub[19]=0xf3
43 pub[20]=0xda; pub[21]=0xa6; pub[22]=0x23; pub[23]=0x25
44 pub[24]=0xaf; pub[25]=0x02; pub[26]=0x1a; pub[27]=0x68
45 pub[28]=0xf7; pub[29]=0x07; pub[30]=0x51; pub[31]=0x1a
46
47 // ---- Synthesise tbs (arbitrary 100-byte blob) ----
48 let TBS_LEN: i64 = 100
49 let buf: *u8 = sys_mmap(512)
50 var i: i64 = 0
51 while i < TBS_LEN {
52 buf[i] = 0x40 + (i & 0x1f)
53 i = i + 1
54 }
55 // ---- Append pubkey at offset TBS_LEN ----
56 var pi: i64 = 0
57 while pi < 32 {
58 buf[TBS_LEN + pi] = pub[pi]
59 pi = pi + 1
60 }
61 // ---- Sign tbs, write sig at offset TBS_LEN+32 ----
62 let sig: *u8 = sys_mmap(128)
63 ed25519_sign_full(priv, buf, TBS_LEN, sig)
64 var si: i64 = 0
65 while si < 64 {
66 buf[TBS_LEN + 32 + si] = sig[si]
67 si = si + 1
68 }
69 let total: i64 = TBS_LEN + 32 + 64 // 196 bytes
70
71 // ---- Build a manual X509Cert pointing into buf ----
72 let cert_raw: *u8 = sys_mmap(256)
73 let cert: *X509Cert = cert_raw as *X509Cert
74 cert.tbs_off = 0
75 cert.tbs_len = TBS_LEN
76 cert.serial_off = 0; cert.serial_len = 0
77 cert.sig_alg_off = 0; cert.sig_alg_len = 0
78 cert.spki_off = 0; cert.spki_len = 0
79 cert.sig_off = TBS_LEN + 32
80 cert.sig_len = 64
81 cert.pubkey_off = TBS_LEN
82 cert.pubkey_len = 32
83 cert.pubkey_alg_off = 0; cert.pubkey_alg_len = 0
84 cert.validity_off = 0; cert.validity_len = 0
85 cert.extensions_off = 0 - 1
86 cert.extensions_len = 0
87
88 // ---- Test A: self-signed cert validates ----
89 let v1: i64 = x509_verify_signature_ed25519(buf, cert, pub)
90 if v1 != NX_X509_VAL_OK { return 1 }
91
92 // ---- Test B: wrong signer pubkey rejects ----
93 let wrong_pub: *u8 = sys_mmap(64)
94 var wi: i64 = 0
95 while wi < 32 {
96 wrong_pub[wi] = pub[wi]
97 wi = wi + 1
98 }
99 wrong_pub[10] = wrong_pub[10] ^ 0x01
100 let v2: i64 = x509_verify_signature_ed25519(buf, cert, wrong_pub)
101 if v2 != NX_X509_VAL_BAD_SIG { return 2 }
102
103 // ---- Test C: tampered tbs byte rejects ----
104 let saved: i64 = buf[50] & 0xff
105 buf[50] = saved ^ 0x40
106 let v3: i64 = x509_verify_signature_ed25519(buf, cert, pub)
107 if v3 != NX_X509_VAL_BAD_SIG { return 3 }
108 buf[50] = saved // restore
109
110 // ---- Test D: tampered sig byte rejects ----
111 let sig_byte: i64 = buf[TBS_LEN + 32 + 10] & 0xff
112 buf[TBS_LEN + 32 + 10] = sig_byte ^ 0x20
113 let v4: i64 = x509_verify_signature_ed25519(buf, cert, pub)
114 if v4 != NX_X509_VAL_BAD_SIG { return 4 }
115 buf[TBS_LEN + 32 + 10] = sig_byte // restore
116
117 // ---- Test E: original cert still validates after restore ----
118 let v5: i64 = x509_verify_signature_ed25519(buf, cert, pub)
119 if v5 != NX_X509_VAL_OK { return 5 }
120
121 // ---- Test F: malformed cert (sig_len != 64) rejected ----
122 cert.sig_len = 32
123 let v6: i64 = x509_verify_signature_ed25519(buf, cert, pub)
124 if v6 != NX_X509_VAL_BAD_SIG_LEN { return 6 }
125 cert.sig_len = 64
126
127 // ---- Test G: malformed cert (tbs_len <= 0) rejected ----
128 cert.tbs_len = 0
129 let v7: i64 = x509_verify_signature_ed25519(buf, cert, pub)
130 if v7 != NX_X509_VAL_BAD_TBS { return 7 }
131 cert.tbs_len = TBS_LEN
132
133 // ---- Test H: verdict gate ----
134 if nx_x509_val_verdict_is_valid(NX_X509_VAL_OK) != 1 { return 8 }
135 if nx_x509_val_verdict_is_valid(NX_X509_VAL_BAD_SIG) != 1 { return 9 }
136 if nx_x509_val_verdict_is_valid(NX_X509_VAL_BAD_TBS) != 1 { return 10 }
137 if nx_x509_val_verdict_is_valid(100) != 0 { return 11 }
138
139 return 0
140}