4.2. Datastore

As stated in the Threat Model, Datastore is an untrusted server that provides persistent storage. Since Datastore can be malicious, you must protect the confidentiality and integrity of any sensitive data you store on it.

Datastore is structured as a key-value store. In this context, key refers to an unique identifier that is used to index the value in the database, and does not refer to a crypographic key.

All key-value entries in Datastore exist in a single, global namespace and Datastore does not perform any access control. Therefore, any value entry can be overwritten or deleted by any user who knows the corresponding storage key.

An implementation of Datastore is provided for you (see source code in userlib) and is already imported into proj2.go.

The client application can interact with Datastore using the API documented below.

userlib.DatastoreSet(key UUID, value []byte)

Stores the given value at the given storage key.

Unlike the Keystore, key-value entries in the Datastore are mutable; if key already maps to a value, then value can be overwritten with a call to DatastoreSet() using the same key.

Parameters
  • key (UUID) – Unique identifier used to index value in the database.

  • value ([]byte) – Value

Example:

UUID := uuid.New()
data := []byte("This is some data")
userlib.DatastoreSet(UUID, data)
userlib.DatastoreGet(key UUID) (value []byte, ok bool)

If the given key does exist in Datastore, return the value stored at key and ok is set to true.

If the given key does not exist in Datastore, then ok is set to false.

Parameters

key (UUID) – Key

Return type

[]byte

Example:

UUID := uuid.New()
data := []byte("This is some data")
userlib.DatastoreSet(UUID, data)
download_data, _ := userlib.DatastoreGet(UUID)
if data != download_data {
    panic("The data should match.")
}
userlib.DatastoreDelete(key UUID)

Delete the given key-value entry from the Datastore, if it exists.

Parameters

key (UUID) – Key

Example:

UUID := uuid.New()
data := []byte("This is some data")
userlib.DatastoreSet(UUID, data)
userlib.DatastoreDelete(UUID)
_, ok := userlib.DatastoreGet(UUID)
if ok {
    panic("The data is still there.")
}