binman: add tests for sign option
Add the test which provides sequence of actions:
1. create the image from binman dts
2. create public and private keys
3. add public key into dtb with fdt_add_pubkey
4. 1. sign FIT container with new sign option with extracting from
image
2. sign exact FIT container with replacing of it in image
5. check with fit_check_sign
Signed-off-by: Ivan Mikhaylov <fr0st61te@gmail.com>
Renumber test file from 277 to 280;
Move UpdateSignatures() to Entry base class;
Don't allow missing mkimage as it doesn't make sense;
Propagate --toolpath for CI;
Call mark_build_done() to avoid regenerating FIT:
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index f1e14c6..9862e23 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -707,6 +707,14 @@
AddNode(dtb.GetRoot(), '')
return tree
+ def _CheckSign(self, fit, key):
+ try:
+ tools.run('fit_check_sign', '-k', key, '-f', fit)
+ except:
+ self.fail('Expected signed FIT container')
+ return False
+ return True
+
def testRun(self):
"""Test a basic run with valid args"""
result = self._RunBinman('-h')
@@ -6565,6 +6573,91 @@
err = stderr.getvalue()
self.assertRegex(err, "Image 'image'.*missing bintools.*: openssl")
+ def _PrepareSignEnv(self, dts='280_fit_sign.dts'):
+ """Prepare sign environment
+
+ Create private and public keys, add pubkey into dtb.
+
+ Returns:
+ Tuple:
+ FIT container
+ Image name
+ Private key
+ DTB
+ """
+
+ data = self._DoReadFileRealDtb(dts)
+ updated_fname = tools.get_output_filename('image-updated.bin')
+ tools.write_file(updated_fname, data)
+ dtb = tools.get_output_filename('source.dtb')
+ private_key = tools.get_output_filename('test_key.key')
+ public_key = tools.get_output_filename('test_key.crt')
+ fit = tools.get_output_filename('fit.fit')
+ key_dir = tools.get_output_dir()
+
+ tools.run('openssl', 'req', '-batch' , '-newkey', 'rsa:4096',
+ '-sha256', '-new', '-nodes', '-x509', '-keyout',
+ private_key, '-out', public_key)
+ tools.run('fdt_add_pubkey', '-a', 'sha256,rsa4096', '-k', key_dir,
+ '-n', 'test_key', '-r', 'conf', dtb)
+
+ return fit, updated_fname, private_key, dtb
+
+ def testSignSimple(self):
+ """Test that a FIT container can be signed in image"""
+ is_signed = False
+ fit, fname, private_key, dtb = self._PrepareSignEnv()
+
+ # do sign with private key
+ control.SignEntries(fname, None, private_key, 'sha256,rsa4096',
+ ['fit'])
+ is_signed = self._CheckSign(fit, dtb)
+
+ self.assertEqual(is_signed, True)
+
+ def testSignExactFIT(self):
+ """Test that a FIT container can be signed and replaced in image"""
+ is_signed = False
+ fit, fname, private_key, dtb = self._PrepareSignEnv()
+
+ # Make sure we propagate the toolpath, since mkimage may not be on PATH
+ args = []
+ if self.toolpath:
+ for path in self.toolpath:
+ args += ['--toolpath', path]
+
+ # do sign with private key
+ self._DoBinman(*args, 'sign', '-i', fname, '-k', private_key, '-a',
+ 'sha256,rsa4096', '-f', fit, 'fit')
+ is_signed = self._CheckSign(fit, dtb)
+
+ self.assertEqual(is_signed, True)
+
+ def testSignNonFit(self):
+ """Test a non-FIT entry cannot be signed"""
+ is_signed = False
+ fit, fname, private_key, _ = self._PrepareSignEnv(
+ '281_sign_non_fit.dts')
+
+ # do sign with private key
+ with self.assertRaises(ValueError) as e:
+ self._DoBinman('sign', '-i', fname, '-k', private_key, '-a',
+ 'sha256,rsa4096', '-f', fit, 'u-boot')
+ self.assertIn(
+ "Node '/u-boot': Updating signatures is not supported with this entry type",
+ str(e.exception))
+
+ def testSignMissingMkimage(self):
+ """Test that FIT signing handles a missing mkimage tool"""
+ fit, fname, private_key, _ = self._PrepareSignEnv()
+
+ # try to sign with a missing mkimage tool
+ bintool.Bintool.set_missing_list(['mkimage'])
+ with self.assertRaises(ValueError) as e:
+ control.SignEntries(fname, None, private_key, 'sha256,rsa4096',
+ ['fit'])
+ self.assertIn("Node '/fit': Missing tool: 'mkimage'", str(e.exception))
+
if __name__ == "__main__":
unittest.main()