Exemplo n.º 1
0
def _sign_fw(fw):

    # load the .cab file
    download_dir = app.config['DOWNLOAD_DIR']
    fn = os.path.join(download_dir, fw.filename)
    try:
        with open(fn, 'rb') as f:
            cabarchive = CabArchive(f.read())
    except IOError as e:
        raise NotImplementedError('cannot read %s: %s' % (fn, str(e)))

    # sign each component in the archive
    print('Signing: %s' % fn)
    for md in fw.mds:
        try:
            ploader.archive_sign(cabarchive, cabarchive[md.filename_contents])
        except KeyError as _:
            raise NotImplementedError('no {} firmware found'.format(md.filename_contents))

    # overwrite old file
    cab_data = cabarchive.save()
    with open(fn, 'wb') as f:
        f.write(cab_data)

    # inform the plugin loader
    ploader.file_modified(fn)

    # update the database
    fw.checksum_signed = hashlib.sha1(cab_data).hexdigest()
    fw.signed_timestamp = datetime.datetime.utcnow()
    db.session.commit()
Exemplo n.º 2
0
 def test_invalid_version_format(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = _get_valid_metainfo(version_format='foo')
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 3
0
 def test_autogenerated(self):
     cabarchive = CabArchive()
     cabarchive['0x0962_nonsecure.bin'] = _get_valid_firmware()
     cabarchive['NVM0.metainfo.xml'] = _get_generated_metainfo()
     ufile = UploadedFile()
     _add_version_formats(ufile)
     ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 4
0
 def test_missing_firmware(self):
     cabarchive = CabArchive()
     cabarchive['firmware123.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = _get_valid_metainfo()
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 5
0
 def test_invalid_type(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     with self.assertRaises(FileNotSupported):
         ufile = UploadedFile()
         _add_version_formats(ufile)
         ufile.parse('foo.doc', cabarchive.save())
Exemplo n.º 6
0
 def test_uncompressed(self):
     cabarchive = CabArchive()
     cabarchive['README.txt'] = CabFile(b'foofoofoofoofoofoofoofoo')
     cabarchive['firmware.bin'] = CabFile(b'barbarbarbarbarbarbarbar')
     buf = cabarchive.save()
     self.assertEqual(len(buf), 156)
     self.assertEqual(hashlib.sha1(buf).hexdigest(), '676654685d6b5918d68081a786ae1d4dbfeb5e01')
Exemplo n.º 7
0
 def test_compressed(self):
     cabarchive = CabArchive()
     cabarchive['README.txt'] = CabFile(b'foofoofoofoofoofoofoofoo')
     cabarchive['firmware.bin'] = CabFile(b'barbarbarbarbarbarbarbar')
     buf = cabarchive.save(compress=True)
     self.assertEqual(len(buf), 122)
     self.assertEqual(hashlib.sha1(buf).hexdigest(), '74e94703c403aa93b16d01b088eb52e3a9c73288')
Exemplo n.º 8
0
 def test_metainfo_invalid(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = CabFile(b'<compoXXXXnent/>')
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 9
0
 def test_metainfo_missing(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         _add_version_formats(ufile)
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 10
0
 def test_release_date(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = _get_alternate_metainfo()
     ufile = UploadedFile()
     _add_version_formats(ufile)
     ufile.parse('foo.cab', cabarchive.save())
     self.assertEqual(ufile.fw.mds[0].release_timestamp, 1562025600)
Exemplo n.º 11
0
 def test_metadata(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = _get_valid_metainfo()
     ufile = UploadedFile()
     ufile.parse('foo.cab', cabarchive.save())
     self.assertTrue(ufile.fw.mds[0].inhibit_download)
     self.assertTrue(ufile.fw.mds[0].version_format == 'quad')
Exemplo n.º 12
0
 def test_valid_path_back(self):
     cabarchive = CabArchive()
     cabarchive['DriverPackage\\firmware.bin'] = _get_valid_firmware()
     cabarchive['DriverPackage\\firmware.metainfo.xml'] = _get_valid_metainfo()
     ufile = UploadedFile()
     ufile.parse('foo.cab', cabarchive.save())
     cabarchive2 = ufile.cabarchive_repacked
     self.assertIsNotNone(cabarchive2['firmware.bin'])
     self.assertIsNotNone(cabarchive2['firmware.metainfo.xml'])
Exemplo n.º 13
0
 def test_inf_invalid(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = CabFile(b'<component/>')
     cabarchive['firmware.inf'] = CabFile(b'fubar')
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         _add_version_formats(ufile)
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 14
0
    def test_compressed(self):

        with open("data/compressed.cab", "rb") as f:
            old = f.read()
        arc = CabArchive()
        arc.parse(old)
        cff = arc.find_file("*.txt")
        self.assertEqual(cff.buf, b"test123")
        _check_range(arc.save(compress=True), old)
Exemplo n.º 15
0
 def test_release_mentions_file(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['README.txt'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = \
         _get_valid_metainfo(release_description='See README.txt for details.')
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 16
0
 def test_invalid_bom(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = CabFile(b'\xEF\xBB\xBF<?xml version="1.0" encoding="UTF-8"?>\n'
                                                   b'<component type="firmware"/>\n')
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         _add_version_formats(ufile)
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 17
0
 def test_valid(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = _get_valid_metainfo()
     ufile = UploadedFile()
     _add_version_formats(ufile)
     ufile.parse('foo.cab', cabarchive.save())
     cabarchive2 = ufile.cabarchive_repacked
     self.assertIsNotNone(cabarchive2['firmware.bin'])
     self.assertIsNotNone(cabarchive2['firmware.metainfo.xml'])
Exemplo n.º 18
0
 def test_invalid_xml_header(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = CabFile(b'<!-- Copyright 2015 Richard Hughes <*****@*****.**> -->\n'
                                                   b'<?xml version="1.0" encoding="UTF-8"?>\n'
                                                   b'<component type="firmware"/>\n')
     with self.assertRaises(MetadataInvalid):
         ufile = UploadedFile()
         _add_version_formats(ufile)
         ufile.parse('foo.cab', cabarchive.save())
Exemplo n.º 19
0
    def test_simple(self):

        with open("data/simple.cab", "rb") as f:
            old = f.read()
        arc = CabArchive()
        arc.parse(old)
        cff = arc["test.txt"]
        self.assertEqual(cff.filename, "test.txt")
        self.assertEqual(cff.buf, b"test123")
        self.assertEqual(len(cff.buf), 7)
        self.assertEqual(cff.date.year, 2015)
        _check_range(arc.save(), old)
Exemplo n.º 20
0
    def test_utf8(self):

        with open("data/utf8.cab", "rb") as f:
            old = f.read()
        arc = CabArchive()
        arc.parse(old)
        cff = arc.find_file("tést.dat")
        self.assertEqual(cff.filename, "tést.dat")
        self.assertEqual(cff.buf, "tést123".encode())
        self.assertEqual(len(cff.buf), 8)
        self.assertEqual(cff.date.year, 2015)
        _check_range(arc.save(), old)
Exemplo n.º 21
0
    def test_multiple_metainfo_same_firmware(self):
        cabarchive = CabArchive()
        cabarchive['firmware.bin'] = _get_valid_firmware()
        cabarchive['firmware1.metainfo.xml'] = _get_valid_metainfo()
        cabarchive['firmware2.metainfo.xml'] = _get_valid_metainfo()

        ufile = UploadedFile()
        ufile.parse('foo.cab', cabarchive.save())
        cabarchive2 = ufile.cabarchive_repacked
        self.assertIsNotNone(cabarchive2['firmware.bin'])
        self.assertIsNotNone(cabarchive2['firmware1.metainfo.xml'])
        self.assertIsNotNone(cabarchive2['firmware2.metainfo.xml'])
Exemplo n.º 22
0
 def test_extra_files(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = _get_valid_metainfo()
     cabarchive['README.txt'] = CabFile(b'fubar')
     ufile = UploadedFile()
     ufile.parse('foo.cab', cabarchive.save())
     cabarchive2 = ufile.cabarchive_repacked
     self.assertIsNotNone(cabarchive2['firmware.bin'])
     self.assertIsNotNone(cabarchive2['firmware.metainfo.xml'])
     with self.assertRaises(KeyError):
         self.assertIsNotNone(cabarchive2['README.txt'])
Exemplo n.º 23
0
 def test_valid_with_ignored_inf(self):
     cabarchive = CabArchive()
     cabarchive['firmware.bin'] = _get_valid_firmware()
     cabarchive['firmware.metainfo.xml'] = _get_valid_metainfo(enable_inf_parsing=False)
     cabarchive['firmware.inf'] = CabFile(b'fubar')
     ufile = UploadedFile()
     _add_version_formats(ufile)
     ufile.parse('foo.cab', cabarchive.save())
     cabarchive2 = ufile.cabarchive_repacked
     self.assertIsNotNone(cabarchive2['firmware.bin'])
     self.assertIsNotNone(cabarchive2['firmware.metainfo.xml'])
     self.assertIsNotNone(cabarchive2['firmware.inf'])
Exemplo n.º 24
0
    def test_large_compressed(self):

        with open("data/large-compressed.cab", "rb") as f:
            old = f.read()
        arc = CabArchive()
        arc.parse(old)
        cff = arc.find_files("random.bin")[0]
        self.assertEqual(len(cff.buf), 0xFFFFF)
        self.assertEqual(
            hashlib.sha1(cff.buf).hexdigest(),
            "8497fe89c41871e3cbd7955e13321e056dfbd170",
        )
        _check_range(arc.save(compress=True), old)
Exemplo n.º 25
0
    def test_create_compressed(self):
        cabarchive = CabArchive()

        # make predictable
        dt_epoch = datetime.datetime.fromtimestamp(0, datetime.timezone.utc)
        cabarchive["README.txt"] = CabFile(b"foofoofoofoofoofoofoofoo",
                                           mtime=dt_epoch)
        cabarchive["firmware.bin"] = CabFile(b"barbarbarbarbarbarbarbar",
                                             mtime=dt_epoch)
        buf = cabarchive.save(compress=True)
        self.assertEqual(len(buf), 122)
        self.assertEqual(
            hashlib.sha1(buf).hexdigest(),
            "74e94703c403aa93b16d01b088eb52e3a9c73288")
Exemplo n.º 26
0
def _sign_fw(fw):

    # load the .cab file
    download_dir = app.config['DOWNLOAD_DIR']
    fn = os.path.join(download_dir, fw.filename)
    try:
        with open(fn, 'rb') as f:
            cabarchive = CabArchive(f.read())
    except IOError as e:
        raise NotImplementedError('cannot read %s: %s' % (fn, str(e)))

    # create Jcat file
    jcatfile = JcatFile()

    # sign each component in the archive
    print('Signing: %s' % fn)
    for md in fw.mds:
        try:

            # create Jcat item with SHA1 and SHA256 checksum blob
            cabfile = cabarchive[md.filename_contents]
            jcatitem = jcatfile.get_item(md.filename_contents)
            jcatitem.add_blob(JcatBlobSha1(cabfile.buf))
            jcatitem.add_blob(JcatBlobSha256(cabfile.buf))

            # sign using plugins
            for blob in ploader.archive_sign(cabfile.buf):

                # add GPG only to archive for backwards compat with older fwupd
                if blob.kind == JcatBlobKind.GPG:
                    fn_blob = md.filename_contents + '.' + blob.filename_ext
                    cabarchive[fn_blob] = CabFile(blob.data)

                # add to Jcat file too
                jcatitem.add_blob(blob)

        except KeyError as _:
            raise NotImplementedError('no {} firmware found'.format(
                md.filename_contents))

    # rewrite the metainfo.xml file to reflect latest changes and sign it
    for md in fw.mds:

        # write new metainfo.xml file
        component = _generate_metadata_mds([md], metainfo=True)
        blob_xml = b'<?xml version="1.0" encoding="UTF-8"?>\n' + \
                   ET.tostring(component,
                               encoding='UTF-8',
                               xml_declaration=False,
                               pretty_print=True)
        _show_diff(cabarchive[md.filename_xml].buf, blob_xml)
        cabarchive[md.filename_xml].buf = blob_xml

        # sign it
        jcatitem = jcatfile.get_item(md.filename_xml)
        jcatitem.add_blob(JcatBlobSha1(blob_xml))
        jcatitem.add_blob(JcatBlobSha256(blob_xml))
        for blob in ploader.archive_sign(blob_xml):
            jcatitem.add_blob(blob)

    # write jcat file
    if jcatfile.items:
        cabarchive['firmware.jcat'] = CabFile(jcatfile.save())

    # overwrite old file
    cab_data = cabarchive.save()
    with open(fn, 'wb') as f:
        f.write(cab_data)

    # inform the plugin loader
    ploader.file_modified(fn)

    # update the download size
    for md in fw.mds:
        md.release_download_size = len(cab_data)

    # update the database
    fw.checksum_signed_sha1 = hashlib.sha1(cab_data).hexdigest()
    fw.checksum_signed_sha256 = hashlib.sha256(cab_data).hexdigest()
    fw.signed_timestamp = datetime.datetime.utcnow()
    db.session.commit()
Exemplo n.º 27
0
    def test_create(self):

        # create new archive
        arc = CabArchive()
        arc.set_id = 0x0622

        # first example
        cff = CabFile()
        cff.buf = (b"#include <stdio.h>\r\n\r\nvoid main(void)\r\n"
                   b'{\r\n    printf("Hello, world!\\n");\r\n}\r\n')
        cff.date = datetime.date(1997, 3, 12)
        cff.time = datetime.time(11, 13, 52)
        cff.is_arch = True
        arc["hello.c"] = cff

        # second example
        cff = CabFile()
        cff.buf = (b"#include <stdio.h>\r\n\r\nvoid main(void)\r\n"
                   b'{\r\n    printf("Welcome!\\n");\r\n}\r\n\r\n')
        cff.date = datetime.date(1997, 3, 12)
        cff.time = datetime.time(11, 15, 14)
        cff.is_arch = True
        arc["welcome.c"] = cff

        # verify
        data = arc.save(False)
        with open("/tmp/test.cab", "wb") as f:
            f.write(data)
        expected = (
            b"\x4D\x53\x43\x46\x00\x00\x00\x00\xFD\x00\x00\x00\x00\x00\x00\x00"
            b"\x2C\x00\x00\x00\x00\x00\x00\x00\x03\x01\x01\x00\x02\x00\x00\x00"
            b"\x22\x06\x00\x00\x5E\x00\x00\x00\x01\x00\x00\x00\x4D\x00\x00\x00"
            b"\x00\x00\x00\x00\x00\x00\x6C\x22\xBA\x59\x20\x00\x68\x65\x6C\x6C"
            b"\x6F\x2E\x63\x00\x4A\x00\x00\x00\x4D\x00\x00\x00\x00\x00\x6C\x22"
            b"\xE7\x59\x20\x00\x77\x65\x6C\x63\x6F\x6D\x65\x2E\x63\x00\xBD\x5A"
            b"\xA6\x30\x97\x00\x97\x00\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C"
            b"\x73\x74\x64\x69\x6F\x2E\x68\x3E\x0D\x0A\x0D\x0A\x76\x6F\x69\x64"
            b"\x20\x6D\x61\x69\x6E\x28\x76\x6F\x69\x64\x29\x0D\x0A\x7B\x0D\x0A"
            b"\x20\x20\x20\x20\x70\x72\x69\x6E\x74\x66\x28\x22\x48\x65\x6C\x6C"
            b"\x6F\x2C\x20\x77\x6F\x72\x6C\x64\x21\x5C\x6E\x22\x29\x3B\x0D\x0A"
            b"\x7D\x0D\x0A\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C\x73\x74\x64"
            b"\x69\x6F\x2E\x68\x3E\x0D\x0A\x0D\x0A\x76\x6F\x69\x64\x20\x6D\x61"
            b"\x69\x6E\x28\x76\x6F\x69\x64\x29\x0D\x0A\x7B\x0D\x0A\x20\x20\x20"
            b"\x20\x70\x72\x69\x6E\x74\x66\x28\x22\x57\x65\x6C\x63\x6F\x6D\x65"
            b"\x21\x5C\x6E\x22\x29\x3B\x0D\x0A\x7D\x0D\x0A\x0D\x0A")
        _check_range(bytearray(data), bytearray(expected))

        # use cabextract to test validity
        try:
            self.assertEqual(
                subprocess.call(["cabextract", "--test", "/tmp/test.cab"]), 0)
        except FileNotFoundError as _:
            pass

        # check we can parse what we just created
        arc = CabArchive()
        with open("/tmp/test.cab", "rb") as f:
            arc.parse(f.read())

        # add an extra file
        arc["test.inf"] = CabFile(b"$CHICAGO$")

        # save with compression
        with open("/tmp/test.cab", "wb") as f:
            f.write(arc.save(True))

        # use cabextract to test validity
        try:
            self.assertEqual(
                subprocess.call(["cabextract", "--test", "/tmp/test.cab"]), 0)
        except FileNotFoundError as _:
            pass