Bundle Protocol Security (RFC 9172) - authentication and encryption for DTN
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

test(space): expand test suites for CCSDS and space protocol packages

+149 -1
+149 -1
test/test_bpsec.ml
··· 97 97 Alcotest.(check int) "context matches" bib.context_id decoded.context_id 98 98 | Error e -> Alcotest.failf "decode failed: %a" Bpsec.pp_error e 99 99 100 + (* {1 Multiple Security Targets Tests} *) 101 + 102 + let test_bib_multiple_targets () = 103 + (* RFC 9172 Section 3.3: a security block can protect multiple targets *) 104 + let targets = [ 1; 3; 5 ] in 105 + let target_data = [ "Block 1 data"; "Block 3 data"; "Block 5 data" ] in 106 + let bib = 107 + Bpsec.bib ~key:test_key_256 ~source:test_source ~targets ~target_data () 108 + in 109 + Alcotest.(check int) "three targets" 3 (List.length bib.targets); 110 + Alcotest.(check (list int)) "target numbers" [ 1; 3; 5 ] bib.targets; 111 + Alcotest.(check int) "three result sets" 3 (List.length bib.results); 112 + (* Verification should succeed *) 113 + let verified = Bpsec.verify_bib ~key:test_key_256 bib ~target_data in 114 + Alcotest.(check bool) "multi-target verify succeeds" true verified 115 + 116 + let test_bib_multiple_targets_partial_tamper () = 117 + (* Tampering with one target's data should fail verification *) 118 + let targets = [ 1; 2 ] in 119 + let target_data = [ "Block 1"; "Block 2" ] in 120 + let bib = 121 + Bpsec.bib ~key:test_key_256 ~source:test_source ~targets ~target_data () 122 + in 123 + let tampered = [ "Block 1"; "Tampered" ] in 124 + let verified = Bpsec.verify_bib ~key:test_key_256 bib ~target_data:tampered in 125 + Alcotest.(check bool) "partial tamper detected" false verified 126 + 127 + let test_bcb_multiple_targets () = 128 + (* BCB protecting multiple blocks *) 129 + let targets = [ 1; 2 ] in 130 + let target_data = [ "Payload block"; "Extension block" ] in 131 + let bcb, encrypted = 132 + Bpsec.bcb ~key:test_key_256 ~source:test_source ~targets ~target_data () 133 + in 134 + Alcotest.(check int) "two targets" 2 (List.length bcb.targets); 135 + Alcotest.(check int) "two ciphertexts" 2 (List.length encrypted); 136 + (* All ciphertexts should differ from plaintext *) 137 + List.iter2 138 + (fun plain cipher -> 139 + Alcotest.(check bool) "ciphertext differs" false (plain = cipher)) 140 + target_data encrypted; 141 + (* Decryption should recover all plaintexts *) 142 + let decrypted = 143 + or_fail "multi-target decrypt" 144 + (Bpsec.decrypt_bcb ~key:test_key_256 bcb ~ciphertext:encrypted) 145 + in 146 + List.iter2 147 + (fun expected actual -> 148 + Alcotest.(check string) "decrypted matches" expected actual) 149 + target_data decrypted 150 + 151 + (* {1 Security Context ID Tests} *) 152 + 153 + let test_security_context_ids () = 154 + (* RFC 9173: standard security context identifiers *) 155 + Alcotest.(check int) "BIB-HMAC-SHA2 is 1" 1 Bpsec.bib_hmac_sha2; 156 + Alcotest.(check int) "BCB-AES-GCM is 2" 2 Bpsec.bcb_aes_gcm 157 + 158 + let test_block_type_numbers () = 159 + (* RFC 9172 Section 3.2: BIB is block type 11, BCB is block type 12 *) 160 + Alcotest.(check int) "BIB block type is 11" 11 Bpsec.bib_block_type; 161 + Alcotest.(check int) "BCB block type is 12" 12 Bpsec.bcb_block_type 162 + 163 + (* {1 BIB SHA Variant Tests} *) 164 + 165 + let test_bib_sha256_default () = 166 + (* Default SHA variant should be SHA-256 (variant 5) *) 167 + let targets = [ 1 ] in 168 + let target_data = [ "test data" ] in 169 + let bib = 170 + Bpsec.bib ~key:test_key_256 ~source:test_source ~targets ~target_data () 171 + in 172 + (* Should have parameters with SHA variant *) 173 + Alcotest.(check bool) 174 + "parameters present" true bib.context_flags.parameters_present; 175 + let has_sha_variant = 176 + List.exists 177 + (function Bpsec.Bib_param (Bpsec.SHA_variant _) -> true | _ -> false) 178 + bib.parameters 179 + in 180 + Alcotest.(check bool) "has SHA variant param" true has_sha_variant 181 + 182 + (* {1 BIB Empty Data Test} *) 183 + 184 + let test_bib_empty_data () = 185 + (* Integrity protection of empty payload *) 186 + let targets = [ 1 ] in 187 + let target_data = [ "" ] in 188 + let bib = 189 + Bpsec.bib ~key:test_key_256 ~source:test_source ~targets ~target_data () 190 + in 191 + let verified = Bpsec.verify_bib ~key:test_key_256 bib ~target_data in 192 + Alcotest.(check bool) "empty data verifies" true verified 193 + 194 + (* {1 BCB Empty Data Test} *) 195 + 196 + let test_bcb_empty_data () = 197 + (* Encryption of empty payload *) 198 + let targets = [ 1 ] in 199 + let target_data = [ "" ] in 200 + let bcb, encrypted = 201 + Bpsec.bcb ~key:test_key_256 ~source:test_source ~targets ~target_data () 202 + in 203 + let decrypted = 204 + or_fail "empty decrypt" 205 + (Bpsec.decrypt_bcb ~key:test_key_256 bcb ~ciphertext:encrypted) 206 + in 207 + Alcotest.(check string) "empty roundtrip" "" (List.hd decrypted) 208 + 209 + (* {1 Security Source Tests} *) 210 + 211 + let test_security_source_preserved () = 212 + (* The security source EID should survive CBOR roundtrip *) 213 + let source = Bundle.Dtn "//security-node/bpa" in 214 + let targets = [ 1 ] in 215 + let target_data = [ "payload" ] in 216 + let bib = Bpsec.bib ~key:test_key_256 ~source ~targets ~target_data () in 217 + let cbor = Bpsec.security_block_to_cbor bib in 218 + match Bpsec.security_block_of_cbor cbor with 219 + | Ok decoded -> 220 + Alcotest.(check (of_pp Bundle.pp_eid)) 221 + "source preserved" source decoded.source 222 + | Error e -> Alcotest.failf "decode failed: %a" Bpsec.pp_error e 223 + 224 + (* {1 Context Flags Tests} *) 225 + 226 + let test_context_flags_default () = 227 + (* Default context flags *) 228 + let flags = Bpsec.context_flags_default in 229 + Alcotest.(check bool) 230 + "default parameters_present" false flags.parameters_present 231 + 100 232 (* Test Suites *) 101 233 102 234 let bib_tests = ··· 105 237 Alcotest.test_case "verify" `Quick test_bib_verify; 106 238 Alcotest.test_case "tamper detection" `Quick test_bib_tamper_detection; 107 239 Alcotest.test_case "wrong key" `Quick test_bib_wrong_key; 240 + Alcotest.test_case "multiple targets" `Quick test_bib_multiple_targets; 241 + Alcotest.test_case "multiple targets partial tamper" `Quick 242 + test_bib_multiple_targets_partial_tamper; 243 + Alcotest.test_case "SHA-256 default" `Quick test_bib_sha256_default; 244 + Alcotest.test_case "empty data" `Quick test_bib_empty_data; 108 245 ] 109 246 110 247 let bcb_tests = 111 248 [ 112 249 Alcotest.test_case "roundtrip" `Quick test_bcb_roundtrip; 113 250 Alcotest.test_case "wrong key" `Quick test_bcb_wrong_key; 251 + Alcotest.test_case "multiple targets" `Quick test_bcb_multiple_targets; 252 + Alcotest.test_case "empty data" `Quick test_bcb_empty_data; 114 253 ] 115 254 116 255 let cbor_tests = 117 256 [ 118 257 Alcotest.test_case "security block roundtrip" `Quick 119 258 test_security_block_cbor_roundtrip; 259 + Alcotest.test_case "security source preserved" `Quick 260 + test_security_source_preserved; 120 261 ] 121 262 122 - let suite = ("bpsec", bib_tests @ bcb_tests @ cbor_tests) 263 + let spec_tests = 264 + [ 265 + Alcotest.test_case "security context IDs" `Quick test_security_context_ids; 266 + Alcotest.test_case "block type numbers" `Quick test_block_type_numbers; 267 + Alcotest.test_case "context flags default" `Quick test_context_flags_default; 268 + ] 269 + 270 + let suite = ("bpsec", bib_tests @ bcb_tests @ cbor_tests @ spec_tests)