summaryrefslogtreecommitdiffstats
path: root/modules/libmar/tests
diff options
context:
space:
mode:
Diffstat (limited to 'modules/libmar/tests')
-rw-r--r--modules/libmar/tests/moz.build12
-rw-r--r--modules/libmar/tests/unit/data/0_sized.marbin0 -> 157 bytes
-rw-r--r--modules/libmar/tests/unit/data/0_sized_file0
-rw-r--r--modules/libmar/tests/unit/data/1_byte.marbin0 -> 157 bytes
-rw-r--r--modules/libmar/tests/unit/data/1_byte_file1
-rw-r--r--modules/libmar/tests/unit/data/binary_data.marbin0 -> 673 bytes
-rw-r--r--modules/libmar/tests/unit/data/binary_data_filebin0 -> 512 bytes
-rw-r--r--modules/libmar/tests/unit/data/cert9.dbbin0 -> 36864 bytes
-rw-r--r--modules/libmar/tests/unit/data/key4.dbbin0 -> 61440 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_backend_collision.marbin0 -> 210 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_frontend_collision.marbin0 -> 210 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_is_contained.marbin0 -> 210 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_is_container.marbin0 -> 210 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_multiple_collision.marbin0 -> 249 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_multiple_collision_first.marbin0 -> 249 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_multiple_collision_last.marbin0 -> 249 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_same_offset.marbin0 -> 210 bytes
-rw-r--r--modules/libmar/tests/unit/data/manipulated_signed.marbin0 -> 1194 bytes
-rw-r--r--modules/libmar/tests/unit/data/multiple_file.marbin0 -> 723 bytes
-rw-r--r--modules/libmar/tests/unit/data/multiple_signed_no_pib.marbin0 -> 2125 bytes
-rw-r--r--modules/libmar/tests/unit/data/multiple_signed_pib.marbin0 -> 2233 bytes
-rw-r--r--modules/libmar/tests/unit/data/multiple_signed_pib_2.marbin0 -> 2233 bytes
-rw-r--r--modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.011
-rw-r--r--modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.111
-rw-r--r--modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.211
-rw-r--r--modules/libmar/tests/unit/data/mycert.derbin0 -> 1189 bytes
-rw-r--r--modules/libmar/tests/unit/data/mycert2.derbin0 -> 1191 bytes
-rw-r--r--modules/libmar/tests/unit/data/mycert3.derbin0 -> 1191 bytes
-rw-r--r--modules/libmar/tests/unit/data/no_pib.marbin0 -> 553 bytes
-rw-r--r--modules/libmar/tests/unit/data/signed_no_pib.marbin0 -> 1085 bytes
-rw-r--r--modules/libmar/tests/unit/data/signed_pib.marbin0 -> 1193 bytes
-rw-r--r--modules/libmar/tests/unit/data/signed_pib_mar.signature.011
-rw-r--r--modules/libmar/tests/unit/data/signed_pib_mar.signature.mycert211
-rw-r--r--modules/libmar/tests/unit/data/signed_pib_with_mycert2.marbin0 -> 1193 bytes
-rw-r--r--modules/libmar/tests/unit/head_libmar.js162
-rw-r--r--modules/libmar/tests/unit/test_create.js112
-rw-r--r--modules/libmar/tests/unit/test_extract.js147
-rw-r--r--modules/libmar/tests/unit/test_sign_verify.js591
-rw-r--r--modules/libmar/tests/unit/xpcshell.toml10
39 files changed, 1090 insertions, 0 deletions
diff --git a/modules/libmar/tests/moz.build b/modules/libmar/tests/moz.build
new file mode 100644
index 0000000000..34e7677609
--- /dev/null
+++ b/modules/libmar/tests/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+if CONFIG["OS_TARGET"] != "Android" and CONFIG["COMPILE_ENVIRONMENT"]:
+ XPCSHELL_TESTS_MANIFESTS += ["unit/xpcshell.toml"]
+
+ TEST_HARNESS_FILES.xpcshell.modules.libmar.tests.unit += [
+ "!/dist/bin/signmar%s" % CONFIG["BIN_SUFFIX"],
+ ]
diff --git a/modules/libmar/tests/unit/data/0_sized.mar b/modules/libmar/tests/unit/data/0_sized.mar
new file mode 100644
index 0000000000..357eeb9a87
--- /dev/null
+++ b/modules/libmar/tests/unit/data/0_sized.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/0_sized_file b/modules/libmar/tests/unit/data/0_sized_file
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/modules/libmar/tests/unit/data/0_sized_file
diff --git a/modules/libmar/tests/unit/data/1_byte.mar b/modules/libmar/tests/unit/data/1_byte.mar
new file mode 100644
index 0000000000..a137f11adc
--- /dev/null
+++ b/modules/libmar/tests/unit/data/1_byte.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/1_byte_file b/modules/libmar/tests/unit/data/1_byte_file
new file mode 100644
index 0000000000..56a6051ca2
--- /dev/null
+++ b/modules/libmar/tests/unit/data/1_byte_file
@@ -0,0 +1 @@
+1 \ No newline at end of file
diff --git a/modules/libmar/tests/unit/data/binary_data.mar b/modules/libmar/tests/unit/data/binary_data.mar
new file mode 100644
index 0000000000..7fef469898
--- /dev/null
+++ b/modules/libmar/tests/unit/data/binary_data.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/binary_data_file b/modules/libmar/tests/unit/data/binary_data_file
new file mode 100644
index 0000000000..a0d7369e45
--- /dev/null
+++ b/modules/libmar/tests/unit/data/binary_data_file
Binary files differ
diff --git a/modules/libmar/tests/unit/data/cert9.db b/modules/libmar/tests/unit/data/cert9.db
new file mode 100644
index 0000000000..e0d6191e64
--- /dev/null
+++ b/modules/libmar/tests/unit/data/cert9.db
Binary files differ
diff --git a/modules/libmar/tests/unit/data/key4.db b/modules/libmar/tests/unit/data/key4.db
new file mode 100644
index 0000000000..85c9c5a215
--- /dev/null
+++ b/modules/libmar/tests/unit/data/key4.db
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_backend_collision.mar b/modules/libmar/tests/unit/data/manipulated_backend_collision.mar
new file mode 100644
index 0000000000..41d4f78482
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_backend_collision.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_frontend_collision.mar b/modules/libmar/tests/unit/data/manipulated_frontend_collision.mar
new file mode 100644
index 0000000000..582af58b59
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_frontend_collision.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_is_contained.mar b/modules/libmar/tests/unit/data/manipulated_is_contained.mar
new file mode 100644
index 0000000000..d51b23587d
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_is_contained.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_is_container.mar b/modules/libmar/tests/unit/data/manipulated_is_container.mar
new file mode 100644
index 0000000000..98b33ce9e5
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_is_container.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_multiple_collision.mar b/modules/libmar/tests/unit/data/manipulated_multiple_collision.mar
new file mode 100644
index 0000000000..7e0a3dd724
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_multiple_collision.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_multiple_collision_first.mar b/modules/libmar/tests/unit/data/manipulated_multiple_collision_first.mar
new file mode 100644
index 0000000000..a10d3eb53b
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_multiple_collision_first.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_multiple_collision_last.mar b/modules/libmar/tests/unit/data/manipulated_multiple_collision_last.mar
new file mode 100644
index 0000000000..bfbb9ba853
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_multiple_collision_last.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_same_offset.mar b/modules/libmar/tests/unit/data/manipulated_same_offset.mar
new file mode 100644
index 0000000000..1326d1afd8
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_same_offset.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/manipulated_signed.mar b/modules/libmar/tests/unit/data/manipulated_signed.mar
new file mode 100644
index 0000000000..df8b3b5dbb
--- /dev/null
+++ b/modules/libmar/tests/unit/data/manipulated_signed.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/multiple_file.mar b/modules/libmar/tests/unit/data/multiple_file.mar
new file mode 100644
index 0000000000..183493a368
--- /dev/null
+++ b/modules/libmar/tests/unit/data/multiple_file.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/multiple_signed_no_pib.mar b/modules/libmar/tests/unit/data/multiple_signed_no_pib.mar
new file mode 100644
index 0000000000..fb56eef98e
--- /dev/null
+++ b/modules/libmar/tests/unit/data/multiple_signed_no_pib.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/multiple_signed_pib.mar b/modules/libmar/tests/unit/data/multiple_signed_pib.mar
new file mode 100644
index 0000000000..3624436cf5
--- /dev/null
+++ b/modules/libmar/tests/unit/data/multiple_signed_pib.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/multiple_signed_pib_2.mar b/modules/libmar/tests/unit/data/multiple_signed_pib_2.mar
new file mode 100644
index 0000000000..edce42b854
--- /dev/null
+++ b/modules/libmar/tests/unit/data/multiple_signed_pib_2.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.0 b/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.0
new file mode 100644
index 0000000000..fa75b9f231
--- /dev/null
+++ b/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.0
@@ -0,0 +1,11 @@
+biW+t1VP/UUp/B+xnQNKRDib3r4ZYP/HX/O5ZVPaTalCIZJfeGjoGK8TAlNUQUPZ
+rHK/SZqr7rzsWlqb6rAGBWphnaZ3202luiaCBtb1Vi/MS7tPIssC6m2gvy5rwhMA
+xaSJr9Qyoj6AdMbBryG7ZEuV/HPw7CAs1djbHSa0KUsL8Xj1c5kk/zFgh3EEM7ap
+WBlfNRD7wggiWA4o/58gSWgjjqsFuiI5DH7cL3t3AisdBVAEI4A7h0tvX/9P5ipu
+0kthhZyg0lR6denEjQ8RMxTuLoa3KCuhrUC10oUb+ZhpdDEPCL6Dt2eb8FeB3rGd
+dzVzu2WVkBYU4JmDjOanGkOv8hSb8Efi7iZe4+9zEqqgymtCy0w4zzAYToTuaHK8
+1ryrtIzCt5AhGpcX7IJfC1Lc1TOzLa6/gigxj60wdxdWuP4d6tvraJMvSX47oIVM
+gB6Gu+G3LEPGS4Vcqun+G9sn2ee+4L2E/ZK4nh9kzAkpNR5COrzG6FxhuocIfpWa
+8F/sh3hZPJuuCopqd0lUfrkvwPe1hMd7RjMgPVTT0Mkol3YliMAW+kvUqrXZ/o6A
+6rLt2+t7V/FbYY1EJNhjISTlUYyWERPhTO6qMRbqUzNBd5/Dh6mRI7hxIf5KEQdu
+ZvJ8ORomD++TlXQsqcYCuYNZ5EM0npe/UfHU7JYuHo0= \ No newline at end of file
diff --git a/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.1 b/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.1
new file mode 100644
index 0000000000..3ab4cef5f4
--- /dev/null
+++ b/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.1
@@ -0,0 +1,11 @@
+UtzJoTa2NS5uBfNTCeVVEC6R8Iaad8vq/KNJwlYsn6V+20mp/vBJIXh+hmHSGNEA
+ynpbqD1KLgzPMSsBbF2Azc6eT0frVDdPlKc5FyhpkB9YniOSpt+oWiU8M7UMsVhG
+/+9ClLLXImVeq3oySxGodpMh04sYrzBUR136cdk6mb+dAT3523xKRXZM72+WlQFQ
+G1rfzGTEWWFJCIwDJisauYbQlipvl6mfZttdQ2a7hgVbAJmFbm7nUsYr7t1ezP0A
+Jy1WIrZY4l8OzoL0TZ3aM1bC2vFYxv+SuH6E51MdVt/mLc7JSGzVmqdP0C58xNSz
+zmkfYwj5fWh6jRa6XQAl7Au3jujdVPV22bSdZV05RlypgLQHZmlvi+yRd8OCPJZY
+NLU8K3xZQP4sGr5vePtUqoVslsMtkUh/LUSTAAmFF8qPotxEzMb1LFYokPH37e1R
+8EwZbyp4wXOy7KYx2rB90J+4PoGPYIUe8xERHGDmrCt9G+siFB6OOSQEQEj5XfLw
+MkJSI9K3ldMtzIiDFKikmSpkCyeBFmEQrb6/zgl1qUBcE52yPkrybZdtvwseGrhU
+43ZsKX1/1FSj8MOkXuCFTMLMFRDpXuGvLTNPy1DPA3nsa0XoYFzp8Sg4pjJd4KUL
+mhYiy+v/27LfonFX0ak9+HlANsV96ixf3mrkVz7Tfc4= \ No newline at end of file
diff --git a/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.2 b/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.2
new file mode 100644
index 0000000000..974a425137
--- /dev/null
+++ b/modules/libmar/tests/unit/data/multiple_signed_pib_mar.sig.2
@@ -0,0 +1,11 @@
+F6F1LmabkmheGolLdYlWkaSnM782EoJnZAiDYOszsetXWltFLCd/SrfKaAABBUJZ
+jPS5EeEAFtNK6INCs/ULujohnQwhiMWwcLm7f5CGEaC7UzKB4tP5ZvnBASTDhAMj
+BipU2798XYyA5+LmWL81S+LZKEhGXdPsIC4GIqlY7hA0DKgsS9hWxC7VfuZb3r8T
+Mp//aOM79+DnPBHJYKBzoDLO/F/GlH0Hr7Gih/nOkiHTvQgZ3PDAxwhGgwLAsRA0
++LmrQ3MlHrLfT9SrPZq3kUtX/JIvYfAaUE8cV941a7cvfVY1RPjznJBk2lYowNys
+GhjoS9OpRBqdMVfY4dHZoCEgc07siDXhTCw4J9tPAjqOdsqwgsuoLhTEcIYeWnR7
+otYnFITcDvRRRkP98SRPjKquemvcYgeyX7vHomN8V+GhTlCn8NF4ModE1Ny7whiu
+V/+dwFH3S3Phg2wo2THfU1igUzZUJ5LhiO486NVa7n3wLZqpAMnsvDujqoL/8tWz
+ZQ5o/RF6XJHA0UKXxt3UiGZHDGuS3I6clZJa1PXgSfEHZyQmQ24bl2fmDURdLUbt
++t//Y5PZTktwjxIELbGYvVXoJYYHW7Jr5PlxvUxqq7WRHwOd9nL4Bs8gqr64I9sB
+8yMnjffnl5ZL53pS6SjIzPgymYNOYN1KpDuNoSBuXN8= \ No newline at end of file
diff --git a/modules/libmar/tests/unit/data/mycert.der b/modules/libmar/tests/unit/data/mycert.der
new file mode 100644
index 0000000000..ea1fd47faa
--- /dev/null
+++ b/modules/libmar/tests/unit/data/mycert.der
Binary files differ
diff --git a/modules/libmar/tests/unit/data/mycert2.der b/modules/libmar/tests/unit/data/mycert2.der
new file mode 100644
index 0000000000..d8cdfea972
--- /dev/null
+++ b/modules/libmar/tests/unit/data/mycert2.der
Binary files differ
diff --git a/modules/libmar/tests/unit/data/mycert3.der b/modules/libmar/tests/unit/data/mycert3.der
new file mode 100644
index 0000000000..b942d4d795
--- /dev/null
+++ b/modules/libmar/tests/unit/data/mycert3.der
Binary files differ
diff --git a/modules/libmar/tests/unit/data/no_pib.mar b/modules/libmar/tests/unit/data/no_pib.mar
new file mode 100644
index 0000000000..8976e7d737
--- /dev/null
+++ b/modules/libmar/tests/unit/data/no_pib.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/signed_no_pib.mar b/modules/libmar/tests/unit/data/signed_no_pib.mar
new file mode 100644
index 0000000000..92d97fec51
--- /dev/null
+++ b/modules/libmar/tests/unit/data/signed_no_pib.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/signed_pib.mar b/modules/libmar/tests/unit/data/signed_pib.mar
new file mode 100644
index 0000000000..1b8baa7969
--- /dev/null
+++ b/modules/libmar/tests/unit/data/signed_pib.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/data/signed_pib_mar.signature.0 b/modules/libmar/tests/unit/data/signed_pib_mar.signature.0
new file mode 100644
index 0000000000..d597fa5491
--- /dev/null
+++ b/modules/libmar/tests/unit/data/signed_pib_mar.signature.0
@@ -0,0 +1,11 @@
+Qv7nfMB5+ri3errM8NqkCl7LwWFHu3DXBFAHaw3Rl27hGyZw4xR+oKbQMkwvdrY7
+GxWZ0vBNSI4nte+Ii6XjDQcnzQgqINEZkL5EVMs1re1zA8OzuItxtXWeCoAPGgMg
+uhvPVWxMCUMia1yCWpVKwA9CKfsX+0+5jbSLeMg43q6Zoj+AVanCZZlQiH2nuBPL
+YB9hib9GlK4kjS1EqFmYuA8oDQiWDmWK1ULAmFUy9Ezho4il21rG4FQJYywLTQSr
+8PiSTKVH+8LZAvPNEzhG3UGOVsj85w2TzmLbvSiYFJCMx8NQLHbB+cmt+1ytenaK
+Qt+b2PC5Hs8LczOxTxpzgtAZPQbx2jqCxCeFOZGzY7Gfz4oi4YdqY+d4n854wwIb
+rxX7asiYwhOHoJ5nxKoqN1gsRyshSqYDH9+TwXJPrk1S8i5sIBMQpycr+f+1MPGx
+RsoorG3sKUfC+dXi3QqZEnBc+ULqIOrmW9J3TTUsxNpOkm03NvPQZyeF1wpU4jfz
+W1Hnu7nltdqDX1bdmCChZ3rP+7JJYwfvVtmBseIFGZHVMhqvzvvdlxLn+MeTDiAA
+Zrhi/BNkQstX7Bdqe58adzRAv/O80DH8ErKBqvqh17HXwMmGx6i+EGyNt8DfFLSm
+xEzxnsmFnOaBytzpth4pltEEpioQPS7/CSdRydi/29w= \ No newline at end of file
diff --git a/modules/libmar/tests/unit/data/signed_pib_mar.signature.mycert2 b/modules/libmar/tests/unit/data/signed_pib_mar.signature.mycert2
new file mode 100644
index 0000000000..045fc80be1
--- /dev/null
+++ b/modules/libmar/tests/unit/data/signed_pib_mar.signature.mycert2
@@ -0,0 +1,11 @@
+i6oFIDMnyZ5CUaYUCg8MEL48puCQdZMH9s2ZoGKzxK4YO6a/2Yhur4jNRfoxgQm3
+2o4qO4gUCjcwZmQHoSmseELJWP+6I929SZ4KUc/bXsIOMlZLcq+YSQSCbmkM/AeV
+NMW4SR8eVtU0BjstZafaWtvCp0nzYXwyDLUUKl006CzylCjGDO2yNC3GGTc6N0cC
+I1nzDOTNYknuHLJLhjJaJEd+c/J5g3BsDXi3Bh7ZtO1OkU/x/jhxbPfK2YsyHpUm
+8/4BKDy6ocV2zrDXuE4ZBPJXsOGshr3kZLAkrhUbGK14EEFx+PtCRLigfWlGIWd1
+ZdYv+0r+JaOdskArdcHCtfBF6IOnQLB1UjD2NsyhMnKPPm7KO26A+ig8DxlTyt4N
+sop0UryhQxHhh/iTkIJlMN1JONr39EG66pI/jo2HwArNL/sfqZ1m9GR+tDKKtMYm
+gFn0nxQiIgquYA2Q3sKdgtcHvQGxxvyKOa3lelykjny/4RCwsfM1S1KwG9TpPHW4
+5VUoztOuIsSpAwdc+gzNfzvqCi0ac0bUF66ksZ2qlKpG0VRq0O9Rdtv9FClbVUWM
+PRlmUuRdXkn6ouCx58dwHoABXr910GdqV5EoNXNyDG/Mnqu0eYSGDRQEjVvh5v+u
+FSbVjBI+ie7oTFeInJ7eWgJ7/XTMtHsCAw+RHN1drFo= \ No newline at end of file
diff --git a/modules/libmar/tests/unit/data/signed_pib_with_mycert2.mar b/modules/libmar/tests/unit/data/signed_pib_with_mycert2.mar
new file mode 100644
index 0000000000..22a998e227
--- /dev/null
+++ b/modules/libmar/tests/unit/data/signed_pib_with_mycert2.mar
Binary files differ
diff --git a/modules/libmar/tests/unit/head_libmar.js b/modules/libmar/tests/unit/head_libmar.js
new file mode 100644
index 0000000000..49ce2e8ba6
--- /dev/null
+++ b/modules/libmar/tests/unit/head_libmar.js
@@ -0,0 +1,162 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const BIN_SUFFIX = mozinfo.bin_suffix;
+const tempDir = do_get_tempdir();
+
+/**
+ * Compares binary data of 2 arrays and throws if they aren't the same.
+ * Throws on mismatch, does nothing on match.
+ *
+ * @param arr1 The first array to compare
+ * @param arr2 The second array to compare
+ */
+function compareBinaryData(arr1, arr2) {
+ Assert.equal(arr1.length, arr2.length);
+ for (let i = 0; i < arr1.length; i++) {
+ if (arr1[i] != arr2[i]) {
+ throw new Error(
+ `Data differs at index ${i}, arr1: ${arr1[i]}, arr2: ${arr2[i]}`
+ );
+ }
+ }
+}
+
+/**
+ * Reads a file's data and returns it
+ *
+ * @param file The file to read the data from
+ * @return a byte array for the data in the file.
+ */
+function getBinaryFileData(file) {
+ let fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ // Open as RD_ONLY with default permissions.
+ fileStream.init(file, -1, -1, null);
+
+ // Check the returned size versus the expected size.
+ let stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ stream.setInputStream(fileStream);
+ let bytes = stream.readByteArray(stream.available());
+ fileStream.close();
+ return bytes;
+}
+
+/**
+ * Runs each method in the passed in object
+ * Every method of the passed in object that starts with test_ will be ran
+ * The cleanup_per_test method of the object will be run right away, it will be
+ * registered to be the cleanup function, and it will be run between each test.
+ *
+ * @return The number of tests ran
+ */
+function run_tests(obj) {
+ let cleanup_per_test = obj.cleanup_per_test;
+ if (cleanup_per_test === undefined) {
+ cleanup_per_test = function __cleanup_per_test() {};
+ }
+
+ registerCleanupFunction(cleanup_per_test);
+
+ // Make sure there's nothing left over from a preious failed test
+ cleanup_per_test();
+
+ let ranCount = 0;
+ // hasOwnProperty ensures we only see direct properties and not all
+ for (let f in obj) {
+ if (
+ typeof obj[f] === "function" &&
+ obj.hasOwnProperty(f) &&
+ f.toString().indexOf("test_") === 0
+ ) {
+ obj[f]();
+ cleanup_per_test();
+ ranCount++;
+ }
+ }
+ return ranCount;
+}
+
+/**
+ * Creates a MAR file with the content of files.
+ *
+ * @param outMAR The file where the MAR should be created to
+ * @param dataDir The directory where the relative file paths exist
+ * @param files The relative file paths of the files to include in the MAR
+ */
+function createMAR(outMAR, dataDir, files) {
+ // You cannot create an empy MAR.
+ Assert.ok(!!files.length);
+
+ // Get an nsIProcess to the signmar binary.
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
+ let signmarBin = do_get_file("signmar" + BIN_SUFFIX);
+
+ // Make sure the signmar binary exists and is an executable.
+ Assert.ok(signmarBin.exists());
+ Assert.ok(signmarBin.isExecutable());
+
+ // Ensure on non Windows platforms we encode the same permissions
+ // as the refernence MARs contain. On Windows this is also safe.
+ // The reference MAR files have permissions of 0o664, so in case
+ // someone is running these tests locally with another permission
+ // (perhaps 0o777), make sure that we encode them as 0o664.
+ for (let filePath of files) {
+ let f = dataDir.clone();
+ f.append(filePath);
+ f.permissions = 0o664;
+ }
+
+ // Setup the command line arguments to create the MAR.
+ let args = [
+ "-C",
+ dataDir.path,
+ "-H",
+ "@MAR_CHANNEL_ID@",
+ "-V",
+ "13.0a1",
+ "-c",
+ outMAR.path,
+ ];
+ args = args.concat(files);
+
+ info("Running: " + signmarBin.path + " " + args.join(" "));
+ process.init(signmarBin);
+ process.run(true, args, args.length);
+
+ // Verify signmar returned 0 for success.
+ Assert.equal(process.exitValue, 0);
+
+ // Verify the out MAR file actually exists.
+ Assert.ok(outMAR.exists());
+}
+
+/**
+ * Extracts a MAR file to the specified output directory.
+ *
+ * @param mar The MAR file that should be matched
+ * @param dataDir The directory to extract to
+ */
+function extractMAR(mar, dataDir) {
+ // Get an nsIProcess to the signmar binary.
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
+ let signmarBin = do_get_file("signmar" + BIN_SUFFIX);
+
+ // Make sure the signmar binary exists and is an executable.
+ Assert.ok(signmarBin.exists());
+ Assert.ok(signmarBin.isExecutable());
+
+ // Setup the command line arguments to extract the MAR.
+ let args = ["-C", dataDir.path, "-x", mar.path];
+
+ info("Running: " + signmarBin.path + " " + args.join(" "));
+ process.init(signmarBin);
+ process.run(true, args, args.length);
+
+ return process.exitValue;
+}
diff --git a/modules/libmar/tests/unit/test_create.js b/modules/libmar/tests/unit/test_create.js
new file mode 100644
index 0000000000..224364b419
--- /dev/null
+++ b/modules/libmar/tests/unit/test_create.js
@@ -0,0 +1,112 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+ /**
+ * Creates MAR from the passed files, compares it to the reference MAR.
+ *
+ * @param refMARFileName The name of the MAR file that should match
+ * @param files The files that should go in the created MAR
+ * @param checkNoMAR If true return an error if a file already exists
+ */
+ function run_one_test(refMARFileName, files, checkNoMAR) {
+ if (checkNoMAR === undefined) {
+ checkNoMAR = true;
+ }
+
+ // Ensure the MAR we will create doesn't already exist.
+ let outMAR = tempDir.clone();
+ outMAR.append("out.mar");
+ if (checkNoMAR) {
+ Assert.ok(!outMAR.exists());
+ }
+
+ // Create the actual MAR file.
+ createMAR(outMAR, do_get_file("data"), files);
+
+ // Get the reference MAR data.
+ let refMAR = do_get_file("data/" + refMARFileName);
+ let refMARData = getBinaryFileData(refMAR);
+
+ // Verify the data of the MAR is what it should be.
+ let outMARData = getBinaryFileData(outMAR);
+ if (mozinfo.os != "win") {
+ // Modify the array index that contains the file permission in this mar so
+ // the comparison succeeds. This value is only changed when the value is
+ // the expected value on non-Windows platforms since the MAR files are
+ // created on Windows. This makes it possible to use the same MAR files for
+ // all platforms.
+ switch (refMARFileName) {
+ case "0_sized.mar":
+ if (outMARData[143] == 180) {
+ outMARData[143] = 182;
+ }
+ break;
+ case "1_byte.mar":
+ if (outMARData[144] == 180) {
+ outMARData[144] = 182;
+ }
+ break;
+ case "binary_data.mar":
+ if (outMARData[655] == 180) {
+ outMARData[655] = 182;
+ }
+ break;
+ case "multiple_file.mar":
+ if (outMARData[656] == 180) {
+ outMARData[656] = 182;
+ }
+ if (outMARData[681] == 180) {
+ outMARData[681] = 182;
+ }
+ if (outMARData[705] == 180) {
+ outMARData[705] = 182;
+ }
+ }
+ }
+ compareBinaryData(outMARData, refMARData);
+ }
+
+ // Define the unit tests to run.
+ let tests = {
+ // Test creating a MAR file with a 0 byte file.
+ test_zero_sized: function _test_zero_sized() {
+ return run_one_test("0_sized.mar", ["0_sized_file"]);
+ },
+ // Test creating a MAR file with a 1 byte file.
+ test_one_byte: function _test_one_byte() {
+ return run_one_test("1_byte.mar", ["1_byte_file"]);
+ },
+ // Test creating a MAR file with binary data.
+ test_binary_data: function _test_binary_data() {
+ return run_one_test("binary_data.mar", ["binary_data_file"]);
+ },
+ // Test creating a MAR file with multiple files inside of it.
+ test_multiple_file: function _test_multiple_file() {
+ return run_one_test("multiple_file.mar", [
+ "0_sized_file",
+ "1_byte_file",
+ "binary_data_file",
+ ]);
+ },
+ // Test creating a MAR file on top of a different one that already exists
+ // at the location the new one will be created at.
+ test_overwrite_already_exists: function _test_overwrite_already_exists() {
+ let differentFile = do_get_file("data/1_byte.mar");
+ let outMARDir = tempDir.clone();
+ differentFile.copyTo(outMARDir, "out.mar");
+ return run_one_test("binary_data.mar", ["binary_data_file"], false);
+ },
+ // Between each test make sure the out MAR does not exist.
+ cleanup_per_test: function _cleanup_per_test() {
+ let outMAR = tempDir.clone();
+ outMAR.append("out.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+ },
+ };
+
+ // Run all the tests
+ Assert.equal(run_tests(tests), Object.keys(tests).length - 1);
+}
diff --git a/modules/libmar/tests/unit/test_extract.js b/modules/libmar/tests/unit/test_extract.js
new file mode 100644
index 0000000000..46cbbcbbee
--- /dev/null
+++ b/modules/libmar/tests/unit/test_extract.js
@@ -0,0 +1,147 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+ /**
+ * Extracts a MAR and makes sure each file matches the reference files.
+ *
+ * @param marFileName The name of the MAR file to extract
+ * @param files The files that the extracted MAR should contain
+ */
+ function extract_and_compare(marFileName, files) {
+ // Get the MAR file that we will be extracting
+ let mar = do_get_file("data/" + marFileName);
+
+ // Get the path that we will extract to
+ let outDir = tempDir.clone();
+ outDir.append("out");
+ Assert.ok(!outDir.exists());
+ outDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o777);
+
+ // Get the ref files and the files that will be extracted.
+ let outFiles = [];
+ let refFiles = [];
+ for (let i = 0; i < files.length; i++) {
+ let outFile = outDir.clone();
+ outFile.append(files[i]);
+ Assert.ok(!outFile.exists());
+
+ outFiles.push(outFile);
+ refFiles.push(do_get_file("data/" + files[i]));
+ }
+
+ // Extract the MAR contents to ./out dir and verify 0 for success.
+ Assert.equal(extractMAR(mar, outDir), 0);
+
+ // Compare to make sure the extracted files are the same.
+ for (let i = 0; i < files.length; i++) {
+ Assert.ok(outFiles[i].exists());
+ let refFileData = getBinaryFileData(refFiles[i]);
+ let outFileData = getBinaryFileData(outFiles[i]);
+ compareBinaryData(refFileData, outFileData);
+ }
+ }
+
+ /**
+ * Attempts to extract a MAR and expects a failure
+ *
+ * @param marFileName The name of the MAR file to extract
+ */
+ function extract_and_fail(marFileName) {
+ // Get the MAR file that we will be extracting
+ let mar = do_get_file("data/" + marFileName);
+
+ // Get the path that we will extract to
+ let outDir = tempDir.clone();
+ outDir.append("out");
+ Assert.ok(!outDir.exists());
+ outDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o777);
+
+ // Extract the MAR contents to ./out dir and verify -1 (255 from the
+ // nsIprocess) for failure
+ Assert.equal(extractMAR(mar, outDir), 1);
+ }
+
+ // Define the unit tests to run.
+ let tests = {
+ // Test extracting a MAR file with a 0 byte file.
+ test_zero_sized: function _test_zero_sized() {
+ return extract_and_compare("0_sized.mar", ["0_sized_file"]);
+ },
+ // Test extracting a MAR file with a 1 byte file.
+ test_one_byte: function _test_one_byte() {
+ return extract_and_compare("1_byte.mar", ["1_byte_file"]);
+ },
+ // Test extracting a MAR file with binary data.
+ test_binary_data: function _test_binary_data() {
+ return extract_and_compare("binary_data.mar", ["binary_data_file"]);
+ },
+ // Test extracting a MAR without a product information block (PIB) which
+ // contains binary data.
+ test_no_pib: function _test_no_pib() {
+ return extract_and_compare("no_pib.mar", ["binary_data_file"]);
+ },
+ // Test extracting a MAR without a product information block (PIB) that is
+ // signed and which contains binary data.
+ test_no_pib_signed: function _test_no_pib_signed() {
+ return extract_and_compare("signed_no_pib.mar", ["binary_data_file"]);
+ },
+ // Test extracting a MAR with a product information block (PIB) that is
+ // signed and which contains binary data.
+ test_pib_signed: function _test_pib_signed() {
+ return extract_and_compare("signed_pib.mar", ["binary_data_file"]);
+ },
+ // Test extracting a MAR file with multiple files inside of it.
+ test_multiple_file: function _test_multiple_file() {
+ return extract_and_compare("multiple_file.mar", [
+ "0_sized_file",
+ "1_byte_file",
+ "binary_data_file",
+ ]);
+ },
+ // Test collision detection where file A + B are the same offset
+ test_collision_same_offset: function test_collision_same_offset() {
+ return extract_and_fail("manipulated_same_offset.mar");
+ },
+ // Test collision detection where file A's indexes are a subset of file B's
+ test_collision_is_contained: function test_collision_is_contained() {
+ return extract_and_fail("manipulated_is_container.mar");
+ },
+ // Test collision detection where file B's indexes are a subset of file A's
+ test_collision_contained_by: function test_collision_contained_by() {
+ return extract_and_fail("manipulated_is_contained.mar");
+ },
+ // Test collision detection where file A ends in file B's indexes
+ test_collision_a_onto_b: function test_collision_a_onto_b() {
+ return extract_and_fail("manipulated_frontend_collision.mar");
+ },
+ // Test collision detection where file B ends in file A's indexes
+ test_collsion_b_onto_a: function test_collsion_b_onto_a() {
+ return extract_and_fail("manipulated_backend_collision.mar");
+ },
+ // Test collision detection where file C shares indexes with both file A & B
+ test_collision_multiple: function test_collision_multiple() {
+ return extract_and_fail("manipulated_multiple_collision.mar");
+ },
+ // Test collision detection where A is the last file in the list
+ test_collision_last: function test_collision_multiple_last() {
+ return extract_and_fail("manipulated_multiple_collision_last.mar");
+ },
+ // Test collision detection where A is the first file in the list
+ test_collision_first: function test_collision_multiple_first() {
+ return extract_and_fail("manipulated_multiple_collision_first.mar");
+ },
+ // Between each test make sure the out directory and its subfiles do
+ // not exist.
+ cleanup_per_test: function _cleanup_per_test() {
+ let outDir = tempDir.clone();
+ outDir.append("out");
+ if (outDir.exists()) {
+ outDir.remove(true);
+ }
+ },
+ };
+
+ // Run all the tests
+ Assert.equal(run_tests(tests), Object.keys(tests).length - 1);
+}
diff --git a/modules/libmar/tests/unit/test_sign_verify.js b/modules/libmar/tests/unit/test_sign_verify.js
new file mode 100644
index 0000000000..20f0d691ac
--- /dev/null
+++ b/modules/libmar/tests/unit/test_sign_verify.js
@@ -0,0 +1,591 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+ /**
+ * Signs a MAR file.
+ *
+ * @param inMAR The MAR file that should be signed
+ * @param outMAR The MAR file to create
+ */
+ function signMAR(inMAR, outMAR, certs, wantSuccess, useShortHandCmdLine) {
+ // Get a process to the signmar binary from the dist/bin directory.
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ let signmarBin = do_get_file("signmar" + BIN_SUFFIX);
+
+ // Make sure the signmar binary exists and is an executable.
+ Assert.ok(signmarBin.exists());
+ Assert.ok(signmarBin.isExecutable());
+
+ // Setup the command line arguments to sign the MAR.
+ let NSSConfigDir = do_get_file("data");
+ let args = ["-d", NSSConfigDir.path];
+ if (certs.length == 1 && useShortHandCmdLine) {
+ args.push("-n", certs[0]);
+ } else {
+ for (let i = 0; i < certs.length; i++) {
+ args.push("-n" + i, certs[i]);
+ }
+ }
+ args.push("-s", inMAR.path, outMAR.path);
+
+ let exitValue;
+ process.init(signmarBin);
+ try {
+ process.run(true, args, args.length);
+ exitValue = process.exitValue;
+ } catch (e) {
+ // On Windows negative return value throws an exception
+ exitValue = -1;
+ }
+
+ // Verify signmar returned 0 for success.
+ if (wantSuccess) {
+ Assert.equal(exitValue, 0);
+ } else {
+ Assert.notEqual(exitValue, 0);
+ }
+ }
+
+ /**
+ * Extract a MAR signature.
+ *
+ * @param inMAR The MAR file who's signature should be extracted
+ * @param sigIndex The index of the signature to extract
+ * @param extractedSig The file where the extracted signature will be stored
+ * @param wantSuccess True if a successful signmar return code is desired
+ */
+ function extractMARSignature(inMAR, sigIndex, extractedSig, wantSuccess) {
+ // Get a process to the signmar binary from the dist/bin directory.
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ let signmarBin = do_get_file("signmar" + BIN_SUFFIX);
+
+ // Make sure the signmar binary exists and is an executable.
+ Assert.ok(signmarBin.exists());
+ Assert.ok(signmarBin.isExecutable());
+
+ // Setup the command line arguments to extract the signature in the MAR.
+ let args = ["-n" + sigIndex, "-X", inMAR.path, extractedSig.path];
+
+ let exitValue;
+ process.init(signmarBin);
+ try {
+ process.run(true, args, args.length);
+ exitValue = process.exitValue;
+ } catch (e) {
+ // On Windows negative return value throws an exception
+ exitValue = -1;
+ }
+
+ // Verify signmar returned 0 for success.
+ if (wantSuccess) {
+ Assert.equal(exitValue, 0);
+ } else {
+ Assert.notEqual(exitValue, 0);
+ }
+ }
+
+ /**
+ * Import a MAR signature.
+ *
+ * @param inMAR The MAR file who's signature should be imported to
+ * @param sigIndex The index of the signature to import to
+ * @param sigFile The file where the base64 signature exists
+ * @param outMAR The same as inMAR but with the specified signature
+ * swapped at the specified index.
+ * @param wantSuccess True if a successful signmar return code is desired
+ */
+ function importMARSignature(inMAR, sigIndex, sigFile, outMAR, wantSuccess) {
+ // Get a process to the signmar binary from the dist/bin directory.
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ let signmarBin = do_get_file("signmar" + BIN_SUFFIX);
+
+ // Make sure the signmar binary exists and is an executable.
+ Assert.ok(signmarBin.exists());
+ Assert.ok(signmarBin.isExecutable());
+
+ // Setup the command line arguments to import the signature in the MAR.
+ let args = ["-n" + sigIndex, "-I", inMAR.path, sigFile.path, outMAR.path];
+
+ let exitValue;
+ process.init(signmarBin);
+ try {
+ process.run(true, args, args.length);
+ exitValue = process.exitValue;
+ } catch (e) {
+ // On Windows negative return value throws an exception
+ exitValue = -1;
+ }
+
+ // Verify signmar returned 0 for success.
+ if (wantSuccess) {
+ Assert.equal(exitValue, 0);
+ } else {
+ Assert.notEqual(exitValue, 0);
+ }
+ }
+
+ /**
+ * Verifies a MAR file.
+ *
+ * @param signedMAR Verifies a MAR file
+ */
+ function verifyMAR(signedMAR, wantSuccess, certs, useShortHandCmdLine) {
+ // Get a process to the signmar binary from the dist/bin directory.
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ let signmarBin = do_get_file("signmar" + BIN_SUFFIX);
+
+ // Make sure the signmar binary exists and is an executable.
+ Assert.ok(signmarBin.exists());
+ Assert.ok(signmarBin.isExecutable());
+
+ // Will reference the arguments to use for verification in signmar
+ let args = [];
+
+ // Setup the command line arguments to create the MAR.
+ // Windows & Mac vs. Linux/... have different command line for verification
+ // since on Windows we verify with CryptoAPI, on Mac with Security
+ // Transforms or CDSA/CSSM and on all other platforms we verify with NSS. So
+ // on Windows and Mac we use an exported DER file and on other platforms we
+ // use the NSS config db.
+ if (mozinfo.os == "win" || mozinfo.os == "mac") {
+ if (certs.length == 1 && useShortHandCmdLine) {
+ args.push("-D", "data/" + certs[0] + ".der");
+ } else {
+ for (let i = 0; i < certs.length; i++) {
+ args.push("-D" + i, "data/" + certs[i] + ".der");
+ }
+ }
+ } else {
+ let NSSConfigDir = do_get_file("data");
+ args = ["-d", NSSConfigDir.path];
+ if (certs.length == 1 && useShortHandCmdLine) {
+ args.push("-n", certs[0]);
+ } else {
+ for (let i = 0; i < certs.length; i++) {
+ args.push("-n" + i, certs[i]);
+ }
+ }
+ }
+ args.push("-v", signedMAR.path);
+
+ let exitValue;
+ process.init(signmarBin);
+ try {
+ // We put this in a try block because nsIProcess doesn't like -1 returns
+ process.run(true, args, args.length);
+ exitValue = process.exitValue;
+ } catch (e) {
+ // On Windows negative return value throws an exception
+ exitValue = -1;
+ }
+
+ // Verify signmar returned 0 for success.
+ if (wantSuccess) {
+ Assert.equal(exitValue, 0);
+ } else {
+ Assert.notEqual(exitValue, 0);
+ }
+ }
+
+ /**
+ * Strips a MAR signature.
+ *
+ * @param signedMAR The MAR file that should be signed
+ * @param outMAR The MAR file to write to with signature stripped
+ */
+ function stripMARSignature(signedMAR, outMAR, wantSuccess) {
+ // Get a process to the signmar binary from the dist/bin directory.
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ let signmarBin = do_get_file("signmar" + BIN_SUFFIX);
+
+ // Make sure the signmar binary exists and is an executable.
+ Assert.ok(signmarBin.exists());
+ Assert.ok(signmarBin.isExecutable());
+
+ // Setup the command line arguments to create the MAR.
+ let args = ["-r", signedMAR.path, outMAR.path];
+
+ let exitValue;
+ process.init(signmarBin);
+ try {
+ process.run(true, args, args.length);
+ exitValue = process.exitValue;
+ } catch (e) {
+ // On Windows negative return value throws an exception
+ exitValue = -1;
+ }
+
+ // Verify signmar returned 0 for success.
+ if (wantSuccess) {
+ Assert.equal(exitValue, 0);
+ } else {
+ Assert.notEqual(exitValue, 0);
+ }
+ }
+
+ function cleanup() {
+ let outMAR = tempDir.clone();
+ outMAR.append("signed_out.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+ outMAR = tempDir.clone();
+ outMAR.append("multiple_signed_out.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+ outMAR = tempDir.clone();
+ outMAR.append("out.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+
+ let outDir = tempDir.clone();
+ outDir.append("out");
+ if (outDir.exists()) {
+ outDir.remove(true);
+ }
+ }
+
+ const wantFailure = false;
+ const wantSuccess = true;
+ // Define the unit tests to run.
+ let tests = {
+ // Test signing a MAR file with a single signature
+ test_sign_single: function _test_sign_single() {
+ let inMAR = do_get_file("data/binary_data.mar");
+ let outMAR = tempDir.clone();
+ outMAR.append("signed_out.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+ signMAR(inMAR, outMAR, ["mycert"], wantSuccess, true);
+ Assert.ok(outMAR.exists());
+ let outMARData = getBinaryFileData(outMAR);
+ let refMAR = do_get_file("data/signed_pib.mar");
+ let refMARData = getBinaryFileData(refMAR);
+ compareBinaryData(outMARData, refMARData);
+ },
+ // Test signing a MAR file with multiple signatures
+ test_sign_multiple: function _test_sign_multiple() {
+ let inMAR = do_get_file("data/binary_data.mar");
+ let outMAR = tempDir.clone();
+ outMAR.append("multiple_signed_out.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+ Assert.ok(!outMAR.exists());
+ signMAR(
+ inMAR,
+ outMAR,
+ ["mycert", "mycert2", "mycert3"],
+ wantSuccess,
+ true
+ );
+ Assert.ok(outMAR.exists());
+ let outMARData = getBinaryFileData(outMAR);
+ let refMAR = do_get_file("data/multiple_signed_pib.mar");
+ let refMARData = getBinaryFileData(refMAR);
+ compareBinaryData(outMARData, refMARData);
+ },
+ // Test verifying a signed MAR file
+ test_verify_single: function _test_verify_single() {
+ let signedMAR = do_get_file("data/signed_pib.mar");
+ verifyMAR(signedMAR, wantSuccess, ["mycert"], true);
+ verifyMAR(signedMAR, wantSuccess, ["mycert"], false);
+ },
+ // Test verifying a signed MAR file with too many certs fails.
+ // Or if you want to look at it another way, One mycert signature
+ // is missing.
+ test_verify_single_too_many_certs:
+ function _test_verify_single_too_many_certs() {
+ let signedMAR = do_get_file("data/signed_pib.mar");
+ verifyMAR(signedMAR, wantFailure, ["mycert", "mycert"], true);
+ verifyMAR(signedMAR, wantFailure, ["mycert", "mycert"], false);
+ },
+ // Test verifying a signed MAR file fails when using a wrong cert
+ test_verify_single_wrong_cert: function _test_verify_single_wrong_cert() {
+ let signedMAR = do_get_file("data/signed_pib.mar");
+ verifyMAR(signedMAR, wantFailure, ["mycert2"], true);
+ verifyMAR(signedMAR, wantFailure, ["mycert2"], false);
+ },
+ // Test verifying a signed MAR file with multiple signatures
+ test_verify_multiple: function _test_verify_multiple() {
+ let signedMAR = do_get_file("data/multiple_signed_pib.mar");
+ verifyMAR(signedMAR, wantSuccess, ["mycert", "mycert2", "mycert3"]);
+ },
+ // Test verifying an unsigned MAR file fails
+ test_verify_unsigned_mar_file_fails:
+ function _test_verify_unsigned_mar_file_fails() {
+ let unsignedMAR = do_get_file("data/binary_data.mar");
+ verifyMAR(unsignedMAR, wantFailure, ["mycert", "mycert2", "mycert3"]);
+ },
+ // Test verifying a signed MAR file with the same signature multiple
+ // times fails. The input MAR has: mycert, mycert2, mycert3.
+ // we're checking to make sure the number of verified signatures
+ // is only 1 and not 3. Each signature should be verified once.
+ test_verify_multiple_same_cert: function _test_verify_multiple_same_cert() {
+ let signedMAR = do_get_file("data/multiple_signed_pib.mar");
+ verifyMAR(signedMAR, wantFailure, ["mycert", "mycert", "mycert"]);
+ },
+ // Test verifying a signed MAR file with the correct signatures but in
+ // a different order fails
+ test_verify_multiple_wrong_order:
+ function _test_verify_multiple_wrong_order() {
+ let signedMAR = do_get_file("data/multiple_signed_pib.mar");
+ verifyMAR(signedMAR, wantSuccess, ["mycert", "mycert2", "mycert3"]);
+ verifyMAR(signedMAR, wantFailure, ["mycert", "mycert3", "mycert2"]);
+ verifyMAR(signedMAR, wantFailure, ["mycert2", "mycert", "mycert3"]);
+ verifyMAR(signedMAR, wantFailure, ["mycert2", "mycert3", "mycert"]);
+ verifyMAR(signedMAR, wantFailure, ["mycert3", "mycert", "mycert2"]);
+ verifyMAR(signedMAR, wantFailure, ["mycert3", "mycert2", "mycert"]);
+ },
+ // Test verifying a signed MAR file without a PIB
+ test_verify_no_pib: function _test_verify_no_pib() {
+ let signedMAR = do_get_file("data/signed_no_pib.mar");
+ verifyMAR(signedMAR, wantSuccess, ["mycert"], true);
+ verifyMAR(signedMAR, wantSuccess, ["mycert"], false);
+ },
+ // Test verifying a signed MAR file with multiple signatures without a PIB
+ test_verify_no_pib_multiple: function _test_verify_no_pib_multiple() {
+ let signedMAR = do_get_file("data/multiple_signed_no_pib.mar");
+ verifyMAR(signedMAR, wantSuccess, ["mycert", "mycert2", "mycert3"]);
+ },
+ // Test verifying a crafted MAR file where the attacker tried to adjust
+ // the version number manually.
+ test_crafted_mar: function _test_crafted_mar() {
+ let signedBadMAR = do_get_file("data/manipulated_signed.mar");
+ verifyMAR(signedBadMAR, wantFailure, ["mycert"], true);
+ verifyMAR(signedBadMAR, wantFailure, ["mycert"], false);
+ },
+ // Test verifying a file that doesn't exist fails
+ test_bad_path_verify_fails: function _test_bad_path_verify_fails() {
+ let noMAR = do_get_file("data/does_not_exist.mar", true);
+ Assert.ok(!noMAR.exists());
+ verifyMAR(noMAR, wantFailure, ["mycert"], true);
+ },
+ // Test to make sure a stripped MAR is the same as the original MAR
+ test_strip_signature: function _test_strip_signature() {
+ let originalMAR = do_get_file("data/binary_data.mar");
+ let signedMAR = tempDir.clone();
+ signedMAR.append("signed_out.mar");
+ let outMAR = tempDir.clone();
+ outMAR.append("out.mar", true);
+ stripMARSignature(signedMAR, outMAR, wantSuccess);
+
+ // Verify that the stripped MAR matches the original data MAR exactly
+ let outMARData = getBinaryFileData(outMAR);
+ let originalMARData = getBinaryFileData(originalMAR);
+ compareBinaryData(outMARData, originalMARData);
+ },
+ // Test to make sure a stripped multi-signature-MAR is the same as the original MAR
+ test_strip_multiple_signatures: function _test_strip_multiple_signatures() {
+ let originalMAR = do_get_file("data/binary_data.mar");
+ let signedMAR = tempDir.clone();
+ signedMAR.append("multiple_signed_out.mar");
+ let outMAR = tempDir.clone();
+ outMAR.append("out.mar");
+ stripMARSignature(signedMAR, outMAR, wantSuccess);
+
+ // Verify that the stripped MAR matches the original data MAR exactly
+ let outMARData = getBinaryFileData(outMAR);
+ let originalMARData = getBinaryFileData(originalMAR);
+ compareBinaryData(outMARData, originalMARData);
+ },
+ // Test extracting the first signature in a MAR that has only a single signature
+ test_extract_sig_single: function _test_extract_sig_single() {
+ let inMAR = do_get_file("data/signed_pib.mar");
+ let extractedSig = do_get_file("extracted_signature", true);
+ if (extractedSig.exists()) {
+ extractedSig.remove(false);
+ }
+ extractMARSignature(inMAR, 0, extractedSig, wantSuccess);
+ Assert.ok(extractedSig.exists());
+
+ let referenceSig = do_get_file("data/signed_pib_mar.signature.0");
+ compareBinaryData(extractedSig, referenceSig);
+ },
+ // Test extracting the all signatures in a multi signature MAR
+ // The input MAR has 3 signatures.
+ test_extract_sig_multi: function _test_extract_sig_multi() {
+ for (let i = 0; i < 3; i++) {
+ let inMAR = do_get_file("data/multiple_signed_pib.mar");
+ let extractedSig = do_get_file("extracted_signature", true);
+ if (extractedSig.exists()) {
+ extractedSig.remove(false);
+ }
+ extractMARSignature(inMAR, i, extractedSig, wantSuccess);
+ Assert.ok(extractedSig.exists());
+
+ let referenceSig = do_get_file("data/multiple_signed_pib_mar.sig." + i);
+ compareBinaryData(extractedSig, referenceSig);
+ }
+ },
+ // Test extracting a signature that is out of range fails
+ test_extract_sig_out_of_range: function _test_extract_sig_out_of_range() {
+ let inMAR = do_get_file("data/signed_pib.mar");
+ let extractedSig = do_get_file("extracted_signature", true);
+ if (extractedSig.exists()) {
+ extractedSig.remove(false);
+ }
+ const outOfBoundsIndex = 5;
+ extractMARSignature(inMAR, outOfBoundsIndex, extractedSig, wantFailure);
+ Assert.ok(!extractedSig.exists());
+ },
+ // Test signing a file that doesn't exist fails
+ test_bad_path_sign_fails: function _test_bad_path_sign_fails() {
+ let inMAR = do_get_file("data/does_not_exist.mar", true);
+ let outMAR = tempDir.clone();
+ outMAR.append("signed_out.mar");
+ Assert.ok(!inMAR.exists());
+ signMAR(inMAR, outMAR, ["mycert"], wantFailure, true);
+ Assert.ok(!outMAR.exists());
+ },
+ // Test verifying only a subset of the signatures fails.
+ // The input MAR has: mycert, mycert2, mycert3.
+ // We're only verifying 2 of the 3 signatures and that should fail.
+ test_verify_multiple_subset: function _test_verify_multiple_subset() {
+ let signedMAR = do_get_file("data/multiple_signed_pib.mar");
+ verifyMAR(signedMAR, wantFailure, ["mycert", "mycert2"]);
+ },
+ // Test importing the first signature in a MAR that has only
+ // a single signature
+ test_import_sig_single: function _test_import_sig_single() {
+ // Make sure the input MAR was signed with mycert only
+ let inMAR = do_get_file("data/signed_pib.mar");
+ verifyMAR(inMAR, wantSuccess, ["mycert"], false);
+ verifyMAR(inMAR, wantFailure, ["mycert2"], false);
+ verifyMAR(inMAR, wantFailure, ["mycert3"], false);
+
+ // Get the signature file for this MAR signed with the key from mycert2
+ let sigFile = do_get_file("data/signed_pib_mar.signature.mycert2");
+ Assert.ok(sigFile.exists());
+ let outMAR = tempDir.clone();
+ outMAR.append("sigchanged_signed_pib.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+
+ // Run the import operation
+ importMARSignature(inMAR, 0, sigFile, outMAR, wantSuccess);
+
+ // Verify we have a new MAR file, that mycert no longer verifies and that,
+ // mycert2 does verify
+ Assert.ok(outMAR.exists());
+ verifyMAR(outMAR, wantFailure, ["mycert"], false);
+ verifyMAR(outMAR, wantSuccess, ["mycert2"], false);
+ verifyMAR(outMAR, wantFailure, ["mycert3"], false);
+
+ // Compare the binary data to something that was signed originally
+ // with the private key from mycert2
+ let refMAR = do_get_file("data/signed_pib_with_mycert2.mar");
+ Assert.ok(refMAR.exists());
+ let refMARData = getBinaryFileData(refMAR);
+ let outMARData = getBinaryFileData(outMAR);
+ compareBinaryData(outMARData, refMARData);
+ },
+ // Test importing a signature that doesn't belong to the file
+ // fails to verify.
+ test_import_wrong_sig: function _test_import_wrong_sig() {
+ // Make sure the input MAR was signed with mycert only
+ let inMAR = do_get_file("data/signed_pib.mar");
+ verifyMAR(inMAR, wantSuccess, ["mycert"], false);
+ verifyMAR(inMAR, wantFailure, ["mycert2"], false);
+ verifyMAR(inMAR, wantFailure, ["mycert3"], false);
+
+ // Get the signature file for multiple_signed_pib.mar signed with the
+ // key from mycert
+ let sigFile = do_get_file("data/multiple_signed_pib_mar.sig.0");
+ Assert.ok(sigFile.exists());
+ let outMAR = tempDir.clone();
+ outMAR.append("sigchanged_signed_pib.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+
+ // Run the import operation
+ importMARSignature(inMAR, 0, sigFile, outMAR, wantSuccess);
+
+ // Verify we have a new MAR file and that the mar file fails to verify
+ // when using a signature for another mar file.
+ Assert.ok(outMAR.exists());
+ verifyMAR(outMAR, wantFailure, ["mycert"], false);
+ verifyMAR(outMAR, wantFailure, ["mycert2"], false);
+ verifyMAR(outMAR, wantFailure, ["mycert3"], false);
+ },
+ // Test importing to the second signature in a MAR that has multiple
+ // signature
+ test_import_sig_multiple: function _test_import_sig_multiple() {
+ // Make sure the input MAR was signed with mycert only
+ let inMAR = do_get_file("data/multiple_signed_pib.mar");
+ verifyMAR(inMAR, wantSuccess, ["mycert", "mycert2", "mycert3"], false);
+ verifyMAR(inMAR, wantFailure, ["mycert", "mycert", "mycert3"], false);
+
+ // Get the signature file for this MAR signed with the key from mycert
+ let sigFile = do_get_file("data/multiple_signed_pib_mar.sig.0");
+ Assert.ok(sigFile.exists());
+ let outMAR = tempDir.clone();
+ outMAR.append("sigchanged_signed_pib.mar");
+ if (outMAR.exists()) {
+ outMAR.remove(false);
+ }
+
+ // Run the import operation
+ const secondSigPos = 1;
+ importMARSignature(inMAR, secondSigPos, sigFile, outMAR, wantSuccess);
+
+ // Verify we have a new MAR file and that mycert no longer verifies
+ // and that mycert2 does verify
+ Assert.ok(outMAR.exists());
+ verifyMAR(outMAR, wantSuccess, ["mycert", "mycert", "mycert3"], false);
+ verifyMAR(outMAR, wantFailure, ["mycert", "mycert2", "mycert3"], false);
+
+ // Compare the binary data to something that was signed originally
+ // with the private keys from mycert, mycert, mycert3
+ let refMAR = do_get_file("data/multiple_signed_pib_2.mar");
+ Assert.ok(refMAR.exists());
+ let refMARData = getBinaryFileData(refMAR);
+ let outMARData = getBinaryFileData(outMAR);
+ compareBinaryData(outMARData, refMARData);
+ },
+ // Test stripping a MAR that doesn't exist fails
+ test_bad_path_strip_fails: function _test_bad_path_strip_fails() {
+ let noMAR = do_get_file("data/does_not_exist.mar", true);
+ Assert.ok(!noMAR.exists());
+ let outMAR = tempDir.clone();
+ outMAR.append("out.mar");
+ stripMARSignature(noMAR, outMAR, wantFailure);
+ },
+ // Test extracting from a bad path fails
+ test_extract_bad_path: function _test_extract_bad_path() {
+ let noMAR = do_get_file("data/does_not_exist.mar", true);
+ let extractedSig = do_get_file("extracted_signature", true);
+ Assert.ok(!noMAR.exists());
+ if (extractedSig.exists()) {
+ extractedSig.remove(false);
+ }
+ extractMARSignature(noMAR, 0, extractedSig, wantFailure);
+ Assert.ok(!extractedSig.exists());
+ },
+ // Between each test make sure the out MAR does not exist.
+ cleanup_per_test: function _cleanup_per_test() {},
+ };
+
+ cleanup();
+
+ // Run all the tests
+ Assert.equal(run_tests(tests), Object.keys(tests).length - 1);
+
+ registerCleanupFunction(cleanup);
+}
diff --git a/modules/libmar/tests/unit/xpcshell.toml b/modules/libmar/tests/unit/xpcshell.toml
new file mode 100644
index 0000000000..5ffea5544f
--- /dev/null
+++ b/modules/libmar/tests/unit/xpcshell.toml
@@ -0,0 +1,10 @@
+[DEFAULT]
+head = "head_libmar.js"
+support-files = ["data/**"]
+skip-if = ["os == 'win' && msix"] # Updates are disabled for MSIX builds
+
+["test_create.js"]
+
+["test_extract.js"]
+
+["test_sign_verify.js"]