code wiki / (root) / nx_x509_validate_test.nx

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}