Trust no one

Where things went wrong? Let’s solve the “puzzle” from last post, shall we? The issue was with the trust level. The code basically assumed that the storage layer, being a memory, filesystem or a remote web server, is trustworthy. When the data was read back from datastore, the code didn’t check whether it’s correct or not. And from the design point of view we know that the data must perfectly match the name of blob we asked for.

Encrypt 'em all

Another step in the implementation journey This time we’ll take a look at the implementation of blob encryption layer. Just before we start I give you one puzzle to solve - there’s one serious security flow in current implementation. I wonder if you’ll be able to spot it. I plan to show and fix it in the next post. General idea Blob encryption will be another layer of code, separate from the fist one - datastore.

Refactoring mistakes

Mistake? What mistake? So far we’ve implemented CAS layer. It already looks pretty nice and has high test coverage. But I made one small mistake there. Although CAS is currently doing what it’s supposed to do, it will have to be extended later to gain a bit of dynamic features. Using CAS name for such extended module would be misleading. That’s why it has to be renamed. I’ve chosen datastore for the new name.

CAS in action

Tough decisions Before I jump to description of the code itself, let’s first clarify what technology I’ll be using to write Cinode prototype. I decided to use golang. I find it rather nice to work with but it also has some thorns here and there. Why would I like to use it then? It turns out to be very practical, especially in the field of network services. Goroutines are just great - no need to think in terms of callbacks anymore, just straight, sequential code.

Password please

Good Keys, bad keys When using encryption, good encryption keys are essential. They must be generated randomly and must contain enough entropy. Otherwise we’ll open wide range of attacks on encrypted data. In addition to the key, we also need Initialization Vector (IV) which doesn’t necessarily have to be secret, but still it should be either pseudorandom or (in case of some encryption primitives) just unique when used together with the same key (IV is then also called a nonce).