code wiki / (root) / nx_nss_certdata_parse_test.nx

nx_nss_certdata_parse_test.nx source

↩ module page · 156 lines · 7894 B

1// nx_nss_certdata_parse_test.nx -- KAT for the Mozilla NSS 2// certdata.txt parser. 3// 4// expect_exit: 0 5// license_tier: ORIGINAL 6 7import "nx_syscalls.nx" 8import "nx_nss_certdata_parse.nx" 9 10// Helper: write a string literal into buf at off. Returns bytes 11// written (= string length). 12func wstr(buf: *u8, off: i64, src: *u8, n: i64) -> i64 { 13 var i: i64 = 0 14 while i < n { 15 buf[off + i] = src[i] 16 i = i + 1 17 } 18 return n 19} 20 21// Quick string-helper: build "string" bytes inline since nx 22// string literals can't easily be cast to *u8 mid-expression. 23 24func main() -> i64 { 25 // ---- Test A: synthetic 1-cert certdata input ---- 26 // Build: 27 // # 28 // # Test cert 29 // # 30 // CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE 31 // CKA_LABEL UTF8 "Test" 32 // CKA_VALUE MULTILINE_OCTAL 33 // \101\102\103\104\105 34 // END 35 // 36 // Expected DER output: bytes 0x41 0x42 0x43 0x44 0x45 = "ABCDE". 37 let in_buf: *u8 = sys_mmap(256) 38 var p: i64 = 0 39 // "#\n" 40 in_buf[p]=0x23; in_buf[p+1]=0x0A; p = p + 2 41 // "# Test cert\n" 42 in_buf[p]=0x23; in_buf[p+1]=0x20; in_buf[p+2]=0x54; in_buf[p+3]=0x65 43 in_buf[p+4]=0x73; in_buf[p+5]=0x74; in_buf[p+6]=0x20; in_buf[p+7]=0x63 44 in_buf[p+8]=0x65; in_buf[p+9]=0x72; in_buf[p+10]=0x74; in_buf[p+11]=0x0A 45 p = p + 12 46 // "#\n" 47 in_buf[p]=0x23; in_buf[p+1]=0x0A; p = p + 2 48 // "CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n" -- 42 bytes 49 in_buf[p]=0x43; in_buf[p+1]=0x4B; in_buf[p+2]=0x41; in_buf[p+3]=0x5F // CKA_ 50 in_buf[p+4]=0x43; in_buf[p+5]=0x4C; in_buf[p+6]=0x41; in_buf[p+7]=0x53 // CLAS 51 in_buf[p+8]=0x53; in_buf[p+9]=0x20 // S<sp> 52 in_buf[p+10]=0x43; in_buf[p+11]=0x4B; in_buf[p+12]=0x5F // CK_ 53 in_buf[p+13]=0x4F; in_buf[p+14]=0x42; in_buf[p+15]=0x4A; in_buf[p+16]=0x45 // OBJE 54 in_buf[p+17]=0x43; in_buf[p+18]=0x54; in_buf[p+19]=0x5F // CT_ 55 in_buf[p+20]=0x43; in_buf[p+21]=0x4C; in_buf[p+22]=0x41; in_buf[p+23]=0x53 // CLAS 56 in_buf[p+24]=0x53; in_buf[p+25]=0x20 // S<sp> 57 in_buf[p+26]=0x43; in_buf[p+27]=0x4B; in_buf[p+28]=0x4F; in_buf[p+29]=0x5F // CKO_ 58 in_buf[p+30]=0x43; in_buf[p+31]=0x45; in_buf[p+32]=0x52; in_buf[p+33]=0x54 // CERT 59 in_buf[p+34]=0x49; in_buf[p+35]=0x46; in_buf[p+36]=0x49; in_buf[p+37]=0x43 // IFIC 60 in_buf[p+38]=0x41; in_buf[p+39]=0x54; in_buf[p+40]=0x45 // ATE 61 in_buf[p+41]=0x0A 62 p = p + 42 63 // "CKA_LABEL UTF8 \"Test\"\n" -- 22 bytes 64 in_buf[p]=0x43; in_buf[p+1]=0x4B; in_buf[p+2]=0x41; in_buf[p+3]=0x5F // CKA_ 65 in_buf[p+4]=0x4C; in_buf[p+5]=0x41; in_buf[p+6]=0x42; in_buf[p+7]=0x45 // LABE 66 in_buf[p+8]=0x4C; in_buf[p+9]=0x20 // L<sp> 67 in_buf[p+10]=0x55; in_buf[p+11]=0x54; in_buf[p+12]=0x46; in_buf[p+13]=0x38 // UTF8 68 in_buf[p+14]=0x20; in_buf[p+15]=0x22 // <sp>" 69 in_buf[p+16]=0x54; in_buf[p+17]=0x65; in_buf[p+18]=0x73; in_buf[p+19]=0x74 // Test 70 in_buf[p+20]=0x22; in_buf[p+21]=0x0A // "\n 71 p = p + 22 72 // "CKA_VALUE MULTILINE_OCTAL\n" -- 26 bytes 73 in_buf[p]=0x43; in_buf[p+1]=0x4B; in_buf[p+2]=0x41; in_buf[p+3]=0x5F // CKA_ 74 in_buf[p+4]=0x56; in_buf[p+5]=0x41; in_buf[p+6]=0x4C; in_buf[p+7]=0x55 // VALU 75 in_buf[p+8]=0x45; in_buf[p+9]=0x20 // E<sp> 76 in_buf[p+10]=0x4D; in_buf[p+11]=0x55; in_buf[p+12]=0x4C; in_buf[p+13]=0x54 // MULT 77 in_buf[p+14]=0x49; in_buf[p+15]=0x4C; in_buf[p+16]=0x49; in_buf[p+17]=0x4E // ILIN 78 in_buf[p+18]=0x45; in_buf[p+19]=0x5F // E_ 79 in_buf[p+20]=0x4F; in_buf[p+21]=0x43; in_buf[p+22]=0x54; in_buf[p+23]=0x41 // OCTA 80 in_buf[p+24]=0x4C; in_buf[p+25]=0x0A // L\n 81 p = p + 26 82 // "\\101\\102\\103\\104\\105\n" -- 21 bytes (5 escapes of 4 + \n) 83 in_buf[p]=0x5C; in_buf[p+1]=0x31; in_buf[p+2]=0x30; in_buf[p+3]=0x31 // \101 84 in_buf[p+4]=0x5C; in_buf[p+5]=0x31; in_buf[p+6]=0x30; in_buf[p+7]=0x32 // \102 85 in_buf[p+8]=0x5C; in_buf[p+9]=0x31; in_buf[p+10]=0x30; in_buf[p+11]=0x33 // \103 86 in_buf[p+12]=0x5C; in_buf[p+13]=0x31; in_buf[p+14]=0x30; in_buf[p+15]=0x34 // \104 87 in_buf[p+16]=0x5C; in_buf[p+17]=0x31; in_buf[p+18]=0x30; in_buf[p+19]=0x35 // \105 88 in_buf[p+20]=0x0A 89 p = p + 21 90 // "END\n" 91 in_buf[p]=0x45; in_buf[p+1]=0x4E; in_buf[p+2]=0x44; in_buf[p+3]=0x0A 92 p = p + 4 93 94 let in_len_total: i64 = p // 131 95 if in_len_total != 131 { return 1 } 96 97 let out_buf: *u8 = sys_mmap(256) 98 let n_p: *i64 = sys_mmap(16) as *i64 99 let v: i64 = nx_nss_certdata_parse(in_buf, in_len_total, out_buf, 256, n_p) 100 if v != NX_NSS_CD_OK { return 2 } 101 if *n_p != 1 { return 3 } 102 // out_buf header: 2-byte cert_count BE 103 if out_buf[0] != 0x00 { return 4 } 104 if out_buf[1] != 0x01 { return 5 } 105 // Cert entry: 3-byte len BE + 5 DER bytes 106 if out_buf[2] != 0x00 { return 6 } 107 if out_buf[3] != 0x00 { return 7 } 108 if out_buf[4] != 0x05 { return 8 } 109 if out_buf[5] != 0x41 { return 9 } // 'A' = 0x41 = octal 101 110 if out_buf[6] != 0x42 { return 10 } // 'B' = 0x42 = octal 102 111 if out_buf[7] != 0x43 { return 11 } // 'C' = 0x43 = octal 103 112 if out_buf[8] != 0x44 { return 12 } // 'D' = 0x44 = octal 104 113 if out_buf[9] != 0x45 { return 13 } // 'E' = 0x45 = octal 105 114 115 // ---- Test B: empty input -> NO_CERTS ---- 116 let empty_in: *u8 = sys_mmap(8) 117 if nx_nss_certdata_parse(empty_in, 0, out_buf, 256, n_p) != NX_NSS_CD_NO_CERTS { return 20 } 118 119 // ---- Test C: input with no CKO_CERTIFICATE marker -> NO_CERTS ---- 120 // Just a comment line 121 let no_certs: *u8 = sys_mmap(16) 122 no_certs[0]=0x23; no_certs[1]=0x20; no_certs[2]=0x68; no_certs[3]=0x69; no_certs[4]=0x0A // "# hi\n" 123 if nx_nss_certdata_parse(no_certs, 5, out_buf, 256, n_p) != NX_NSS_CD_NO_CERTS { return 21 } 124 125 // ---- Test D: output buffer too small -> OUTPUT_FULL ---- 126 // Re-run the Test A input but with out_cap = 5 (smaller than the 127 // 2-byte header + 3-byte cert_len + 5 DER = 10 needed). 128 let small_out: *u8 = sys_mmap(16) 129 if nx_nss_certdata_parse(in_buf, in_len_total, small_out, 5, n_p) != NX_NSS_CD_OUTPUT_FULL { return 22 } 130 131 // ---- Test E: bad octal escape (\189 has digit '9' which is non-octal) -> BAD_ESCAPE ---- 132 // Replace the first escape in Test A's value block with \189. 133 let bad_in: *u8 = sys_mmap(256) 134 var bi: i64 = 0 135 while bi < in_len_total { bad_in[bi] = in_buf[bi]; bi = bi + 1 } 136 // Octal line starts at offset 2+12+2+42+22+26 = 106 137 // First escape is at 106..110: \101 -> replace bytes 107,108,109 with "189" 138 bad_in[107] = 0x31 // '1' 139 bad_in[108] = 0x38 // '8' 140 bad_in[109] = 0x39 // '9' (non-octal) 141 if nx_nss_certdata_parse(bad_in, in_len_total, out_buf, 256, n_p) != NX_NSS_CD_BAD_ESCAPE { return 23 } 142 143 // ---- Test F: verdict gate ---- 144 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_OK) != 1 { return 30 } 145 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_TRUNCATED) != 1 { return 31 } 146 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_BAD_ESCAPE) != 1 { return 32 } 147 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_OUTPUT_FULL) != 1 { return 33 } 148 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_NO_CERTS) != 1 { return 34 } 149 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_TOO_MANY) != 1 { return 35 } 150 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_BAD_DER_SIZE) != 1 { return 36 } 151 if nx_nss_certdata_verdict_is_valid(NX_NSS_CD_VERDICT_N) != 0 { return 37 } 152 if nx_nss_certdata_verdict_is_valid(0) != 0 { return 38 } 153 if nx_nss_certdata_verdict_is_valid(0 - 1) != 0 { return 39 } 154 155 return 0 156}