storage: download integrity check

- [x] integrity tests
- [x] merge #299

Picking up from #299, where we're implementing integrity checks for uploads.
When validation is "all" (default), that means we have to check md + crc, prioritizing md. But, if md isn't returned from the api, crc is used as a fallback. The logic there is different from when a user has control. When they want md, it shouldn't fallback to crc. That's the reason for the distinction.

I'm always trying to improve wrapping my head around ideas from writing, but I'm still a bit of an amateur in that I understand ideas better if they're in code. Hope I'm not butchering your idea, but if I am, a condensed code example might clear it up for me.