My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
ServerKeys  
Keys used by the server to encrypt recovery keys stored in Datastore.
Updated Apr 15, 2013 by o...@google.com

Introduction

Disk recovery keys grant the ability to unlock or decrypt a FileVault 2 volume. Therefore the keys are treated as extremely sensitive data and are encrypted upon receipt by the Cauliflower Vest service. Without this encryption it would be trivial for an attacker who compromises a Cauliflower Vest App Engine admin login to retrieve non-encrypted recover keys.

The keys remain encrypted in storage and are only decrypted when a client makes an authenticated request to request its recovery key.

This document describes this function and key storage in more detail so that you may make a security assessment for your enterprise.

Crypto

Cauliflower Vest is built to use AES-wrapped HMAC keys to encrypt/decrypt the recovery keys in datastore. This makes their storage in App Engine datastore secure as long as the key itself is stored securely. The keyczar package performs the crypto.

Source Code Key Storage

To start out testing Cauliflower Vest, the easiest key storage solution is to put the keys into the source code that you upload to your App Engine instance. This is the only method that is already coded for you out of the box.

Once you have populated the keys into your source, the permissions on your workstation's build directory should be appropriately restrictive to protect the keys. In addition, any other administrators that you grant access to your app will have access to the keys if they are even mildly creative, e.g. by using the App Engine interactive console to load Python modules and print the keys. App Engine admin tools also provide the ability to download the current source, though that can disabled in the Admin Console under Versions -> "permanently prohibit code downloads."

However, for testing the default code key storage technique is enough. An example of how to generate some test keys to get started is available in the Configuration document under the Server heading.

Key Storage Service

Obviously storing keys in code is not the most flexible or secure model. For maintenance reasons code key storge is annoying because any source control system you may use will either end up containing the key (insecure) or leave the key empty. This will require you to insert the key each time before you update the code on your app instance (maintenance problem). Additionally this means that your App Engine instance technically knows its own key at all times. This can make it difficult to segregate user access to this key when you have multiple users with admin access who are not all supposed to have disk unlock privileges.

One alternative would be to have the Cauliflower Vest instance call a key storage service. This service would accept requests from the App Engine instance, verify their authenticity and then return the key used for datastore crypto. In this model the App Engine instance would not know the key until the moment it needs to encrypt or decrypt the item in Datastore. Not only does this make it harder for unauthorized users to access the key and decrypt the Datastore, but it also simplifies maintenance and source control.

To implement your own key storage service, familiarize yourself with the Asserting Identity to Other Systems section of the App Identity API documentation. Using the App Identity API, you could modify the Cauliflower Vest code to call your key storage service in a secure manner, to obtain a service key for encryption at rest on App Engine.

However even this is just another obstacle to anyone you have granted admin access to on your Cauliflower Vest instance. The authorization protocol to the key storage server would need to be very specifically designed. It may still be possible for your users with admin privilege to your App Engine instance to invoke the code required to obtain the key by accessing the admin console. Coding a solution for this might be extremely difficult.

However if your App Engine admin accounts are compromised or access to your App Engine instance is poorly delegated, there are greater access problems to worry about.

Regrettably we do not have an open source solution for a key storage server or a service to provide for key storage that fully protects the key from all forms of admin users until the exact time that the key is needed.

Extending the Get Keys Methods

You may extend Cauliflower Vest's key acquiring methods relatively easily. If you already have some key service you can plug it in.

Edit the following file:

src/cauliflowervest/server/settings.py

Find the following portion:

KEY_TYPE_DATASTORE_FILEVAULT = 'key_type_datastore_filevault'
KEY_TYPE_DEFAULT = KEY_TYPE_DATASTORE_FILEVAULT

These constants are used to define a dict in the crypto module that sets up function hooks to retrieve keys.

Define a new key retrieval/storage type constant with a unique string value. Change the default to this method. e.g.

KEY_TYPE_MY_KEYSTORE_FILEVAULT = 'key_type_my_keystore_filevault'
KEY_TYPE_DEFAULT = KEY_TYPE_MY_KEYSTORE_FILEVAULT

Now, edit the following file:

src/cauliflowervest/server/crypto.py

Write your function and add a hook to it using your new constant:

ENCRYPTION_KEY_TYPES = {
    settings.KEY_TYPE_DATASTORE_FILEVAULT: lambda: settings.DEMO_KEYS,
    settings.KEY_TYPE_MY_KEYSTORE_FILEVAULT: MyFunctionToObtainKeys(),  ## New Function
    }

In this way you could define whatever key storage architecture you want to retrieve keys. The comments above this dictionary define the output interface that your new function must use. This information is copied below:

# These functions should return a list of dictionaries as documented below:
# [
#   {'versionNumber': int, version number of this key.
#    'aesKeyString': str, base64.urlsafe_b64encode encoded AES key.
#    'aesKeySize': int, optional, size in bits of the AES key. default of 128.
#    'hmacKeyString': str, base64.urlsafe_b64encode encoded HMAC key.
#    'hmacKeySize': int, optional, size in bits of the HMAC key. default of 256.
#    'status': str, Keyczar status like PRIMARY, ACTIVE, INACTIVE.
#   },
#   { ... },
# ]

Assessing the Server Security Model

Note that our App Engine instances themselves are secure and other app instances or random Systems Administrators do not have access to your data or code. However some of the issues raised in this document may make it prohibitively difficult for you to store your recovery keys on App Engine, even though you wish to use the client. However if your site has a close 1:1 match between the App Engine maintainers and security personnel with access to recovery keys, then these issues are relatively moot.

Please see the DIYServer wiki for more information about implementing your own server on your own resources. Assuming you deploy it to software and hardware you trust entirely, rolling your own DIY server would mitigate the key access issues presented in this doc.


Sign in to add a comment
Powered by Google Project Hosting