Checksuming axios downloaded files in jest

I recently had the need to make a test where I confirm the file in a backend server is the same as the one available in the front end client. Due to the fact that frontend frameworks like vue can have a lot logic this test is important for me as it allows me to validate the backend-frontend integration.

function mytest(image_data_list) {
   return Promise.all(image_data_list.map(image_data => axios.get(image_data.url, {
                adapter: require('axios/lib/adapters/http'),
                responseType: 'arraybuffer'
            })
            .then((response) => {
                expect(
                    crypto.createHash("sha256")
                        .update(response.data)
                        .digest("base64"))
                    .toBe(image_data.sha256);
            })
            .catch( (error) => {
                    reject(`check failed`);
                }
            )
     ))
}

Now i am going to try to describe in pseudo code what happens.

function mytest(image_data_list) {

Here our test function takes a list of objects with each object containing the url and sha256. It is not obvious from the function signature because…javascript is not explicitly statically typed but that is besides the point.

return Promise.all(image_data_list.map(image_data => axios.get(image_data.url, {
                adapter: require('axios/lib/adapters/http'),
                responseType: 'arraybuffer'
            })

The test framework I normally use is called jest, and it likes tests to return promises. If you do not return the promise to the caller(the framework) the test code may actually never run, giving you false test positives(One more pitfall, I hate it).

So given we have a list of url data to test and that axios.get returns a promise it seems fit to use the Promise.all. As javascript is so functional we end up with using map to map all the url data to checksum tests promises.

There are 2 properties set for the configuration of axios.get: adapter and responseType.

The adapter property is a trick to skip jest’s jsdom XMLHttpRequests which set the HOST as localhost leading to CORS issues. More about it here.

The responseType is set as arraybuffer because we need to have raw unprocessed access to the response data. If this would not be the case we could potentially end up with different hashes. Fortunately for us the the crypto library’s update method can take an array buffer as input.

If the hash check fails expect will reject the promise and will make your test fail.

u-boot signature check: Signature check Bad (error 1)

For some reason mkimage allows you to sign with public keys that are not paired with the private key  leading to fit images that will never be bootable due to signature verification failure like in the title of the post.

For example imagine you generate 2 sets of keys by doing :

#From https://github.com/siemens/u-boot/blob/master/doc/uImage.FIT/beaglebone_vboot.txt
#priv key
openssl genrsa -F4 -out keys/k1.key 2048
openssl genrsa -F4 -out keys/k2.key 2048

#pub key
openssl req -batch -new -x509 -key keys/k1.key -out keys/dev.crt

#Somehow mess things up:
mv keys/k2.key keys/k1.key

If you follow the above instructions and run mkimage on the keys directory, you will get no error, which is kind of amazing. What will happen is that next time you try to boot the fit image the validation will always fail.

A good way to make sure that you do not have such a situation going all the way to a board, and in the worst case bricking it, is to check with a tool included in u-boot:

uboot-fit_check_sign -f $fit_image -k $uboot_with_dtb

Extra: mkimage has an extra way of making things look fine when they are not.

When running mkimage and asking it to sign an image and the keys directory does not exist or there is some issue with the keys passed, mkimage will happily return success, even if it does not fulfill the request:

$ mkimage -f sign.its -K $dtb_with_pubkeysz -k $non_existing_dir -r image.fit
$ echo $?
0

For a good primer on how fit images and signatures work with u-boot, have a look at this doc It is a really good text. Do not get fooled by the beaglebone name, as it is generic for other boards.

Migrating my blog out of blogspot

I am moving my blog from https://cheesesamongus.blogspot.com/ to wordpress because the blogspot platform seems abandoned by google, with many quality of life improvements simply not existing. Given i mostly write about code, not having a simple way to introduce code really bothered me. It also looks like their editor stopped working properly and copying and pasting code from github breaks the editor.

It is already hard for me to have the discipline to write something, and any friction to achieve that will lead to me just losing interest in favor of other useless endeavors. The editor from wordpress is positively gorgeous in comparison, and that is quite motivating.