Skip to content

Commit

Permalink
SQLAlchemy port
Browse files Browse the repository at this point in the history
This PR migrates Keylime from using raw sql statements tied to
sqlite to an ORM model, allowing easier relational mapping and
a means to use more databases such as postgres / mariadb

This change is required for the early implementation of a multi
tenancy based system.

Resolves: keylime#130
  • Loading branch information
Luke Hinds committed Mar 31, 2020
1 parent c409cc4 commit 4d8d8cd
Show file tree
Hide file tree
Showing 22 changed files with 1,158 additions and 857 deletions.
1 change: 1 addition & 0 deletions docker/Dockerfile-tpm12
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ RUN dnf -y install git \
python3-dbus \
python3-m2crypto \
python3-cryptography \
python3-sqlalchemy
procps \
openssl-devel \
libtool \
Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile-tpm20
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ RUN dnf -y install git \
python3-dbus \
python3-m2crypto \
python3-cryptography \
python3-sqlalchemy
procps \
libtool \
tpm2-tss \
Expand Down
5 changes: 1 addition & 4 deletions installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ case "$ID" in
PACKAGE_MGR=$(command -v apt-get)
PYTHON_PREIN="git patch"
PYTHON_DEPS="python3 python3-pip python3-dev python3-setuptools python3-zmq python3-tornado python3-cryptography python3-simplejson python3-requests gcc g++ libssl-dev swig python3-yaml wget"
PYTHON_PIPS="m2crypto"
BUILD_TOOLS="build-essential libtool automake pkg-config m4 libgcrypt20-dev uthash-dev autoconf autoconf-archive libcurl4-gnutls-dev gnulib doxygen libdbus-1-dev"
NEED_BUILD_TOOLS=1
$PACKAGE_MGR update
Expand All @@ -96,7 +95,6 @@ case "$ID" in
NEED_EPEL=1
PYTHON_PREIN="python36 python36-devel python36-setuptools python36-pip git wget patch openssl"
PYTHON_DEPS="gcc gcc-c++ openssl-devel swig python36-PyYAML python36-tornado python36-simplejson python36-cryptography python36-requests python36-zmq yaml-cpp-devel"
PYTHON_PIPS="m2crypto"
BUILD_TOOLS="openssl-devel file libtool make automake m4 libgcrypt-devel autoconf autoconf-archive libcurl-devel libstdc++-devel uriparser-devel dbus-devel gnulib-devel doxygen"
NEED_BUILD_TOOLS=1
CENTOS7_TSS_FLAGS="--enable-esapi=no --disable-doxygen-doc"
Expand All @@ -106,8 +104,7 @@ case "$ID" in
PACKAGE_MGR=$(command -v dnf)
NEED_EPEL=1
PYTHON_PREIN="python3 python3-devel python3-setuptools python3-pip"
PYTHON_DEPS="gcc gcc-c++ openssl-devel python3-yaml python3-requests swig python3-cryptography wget git"
PYTHON_PIPS="tornado==5.0.2 pyzmq m2crypto simplejson"
PYTHON_DEPS="gcc gcc-c++ openssl-devel python3-yaml python3-requests swig python3-cryptography wget git python3-tornado python3-zmq python3-simplejson"
BUILD_TOOLS="git wget patch libyaml openssl-devel libtool make automake m4 libgcrypt-devel autoconf libcurl-devel libstdc++-devel dbus-devel"
#TPM2_TOOLS_PKGS="tpm2-tss tpm2-tools tpm2-abrmd" TODO: still on 3.1.1 tpm2_tools
NEED_BUILD_TOOLS=1
Expand Down
32 changes: 25 additions & 7 deletions keylime.conf
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ tpm_signing_alg = rsassa
[cloud_verifier]
#=============================================================================

# The cloud verifier IP address and port used to communicate with other services
# The cloud verifier IP address and port used to communicate with other services
# as well as a bind address for the verifier server.
cloudverifier_ip = 127.0.0.1
cloudverifier_port = 8881
Expand Down Expand Up @@ -163,8 +163,17 @@ registrar_private_key = default
# here as you did for private_key_pw in the [cloud_verifier] section
registrar_private_key_pw = default

# The file to use for SQLite persistence of agent data
db_filename = cv_data.sqlite
# Database URL Configuration
# See document [here] for instructions on using different database configurations
# The default is sqlite and will be situated at "/var/lib/keylime/cv_data.sqlite"
drivername = sqlite
username = ''
password = ''
host = ''
port = ''
database = cv_data.sqlite
query = ''


# Number of worker processes to use for the cloud verifier
# Set to 0 to create one worker per processor
Expand All @@ -185,8 +194,8 @@ quote_interval = 2
# currently this only works if you are using keylime-CA
revocation_notifier = True

# The revocation notifier IP address and port used to start the revocation service.
# If the revocation_notifier is true, then the verifier automatically
# The revocation notifier IP address and port used to start the revocation service.
# If the revocation_notifier is true, then the verifier automatically
# starts revocation service.
revocation_notifier_ip = 127.0.0.1
revocation_notifier_port = 8992
Expand Down Expand Up @@ -397,8 +406,17 @@ registrar_private_key = default
# here as you did for private_key_pw in the [cloud_verifier] section
registrar_private_key_pw = default

# The file to use for SQLite persistence of agent data
db_filename = reg_data.sqlite

# Database URL Configuration
# See document [here] for instructions on using different database configurations
# The default is sqlite and will be situated at "/var/lib/keylime/reg_data.sqlite"
drivername = sqlite
username = ''
password = ''
host = ''
port = ''
database = reg_data.sqlite
query = ''

# The file to use for SQLite persistence of provider hypervisor data
prov_db_filename = provider_reg_data.sqlite
Expand Down
90 changes: 24 additions & 66 deletions keylime/cloud_verifier_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
above. Use of this work other than as specifically authorized by the U.S. Government may
violate any copyrights that exist in this work.
'''

import ast
from urllib.parse import urlparse
import configparser
import base64
Expand All @@ -39,7 +39,6 @@
from keylime import crypto
from keylime import ca_util
from keylime import revocation_notifier
from keylime import keylime_sqlite
from keylime import tpm_obj
from keylime.tpm_abstract import TPM_Utilities, Hash_Algorithms, Encrypt_Algorithms, Sign_Algorithms

Expand Down Expand Up @@ -306,35 +305,38 @@ def prepare_get_quote(agent):
"""
agent['nonce'] = TPM_Utilities.random_password(20)

tpm_policy = ast.literal_eval(agent['tpm_policy'])
vtpm_policy = ast.literal_eval(agent['vtpm_policy'])

params = {
'nonce': agent['nonce'],
'mask': agent['tpm_policy']['mask'],
'vmask': agent['vtpm_policy']['mask'],
'mask': tpm_policy['mask'],
'vmask': vtpm_policy['mask'],
}

return params


def process_get_status(agent):
if isinstance(agent['ima_whitelist'], dict) and 'whitelist' in agent['ima_whitelist']:
wl_len = len(agent['ima_whitelist']['whitelist'])
ima_whitelist = ast.literal_eval(agent.ima_whitelist)
if isinstance(ima_whitelist, dict) and 'whitelist' in ima_whitelist:
wl_len = len(ima_whitelist['whitelist'])
else:
wl_len = 0
response = {'operational_state': agent['operational_state'],
'v': agent['v'],
'ip': agent['ip'],
'port': agent['port'],
'tpm_policy': agent['tpm_policy'],
'vtpm_policy': agent['vtpm_policy'],
'metadata': agent['metadata'],
response = {'operational_state': agent.operational_state,
'v': agent.v,
'ip': agent.ip,
'port': agent.port,
'tpm_policy': agent.tpm_policy,
'vtpm_policy': agent.vtpm_policy,
'meta_data': agent.meta_data,
'ima_whitelist_len': wl_len,
'tpm_version': agent['tpm_version'],
'accept_tpm_hash_algs': agent['accept_tpm_hash_algs'],
'accept_tpm_encryption_algs': agent['accept_tpm_encryption_algs'],
'accept_tpm_signing_algs': agent['accept_tpm_signing_algs'],
'hash_alg': agent['hash_alg'],
'enc_alg': agent['enc_alg'],
'sign_alg': agent['sign_alg'],
'tpm_version': agent.tpm_version,
'accept_tpm_hash_algs': agent.accept_tpm_hash_algs,
'accept_tpm_encryption_algs': agent.accept_tpm_encryption_algs,
'accept_tpm_signing_algs': agent.accept_tpm_signing_algs,
'hash_alg': agent.hash_alg,
'enc_alg': agent.enc_alg,
'sign_alg': agent.sign_alg,
}
return response

Expand Down Expand Up @@ -371,7 +373,7 @@ def notifyError(agent, msgtype='revocation'):
'port': agent['port'],
'tpm_policy': agent['tpm_policy'],
'vtpm_policy': agent['vtpm_policy'],
'metadata': agent['metadata'],
'meta_data': agent['meta_data'],
}

revocation['event_time'] = time.asctime()
Expand All @@ -387,47 +389,3 @@ def notifyError(agent, msgtype='revocation'):
else:
tosend['siganture'] = "none"
revocation_notifier.notify(tosend)

# ===== sqlite stuff =====


def init_db(db_filename):

# in the form key, SQL type

cols_db = {
'agent_id': 'TEXT PRIMARY_KEY',
'v': 'TEXT',
'ip': 'TEXT',
'port': 'INT',
'operational_state': 'INT',
'public_key': 'TEXT',
'tpm_policy': 'TEXT',
'vtpm_policy': 'TEXT',
'metadata': 'TEXT',
'ima_whitelist': 'TEXT',
'revocation_key': 'TEXT',
'tpm_version': 'INT',
'accept_tpm_hash_algs': 'TEXT',
'accept_tpm_encryption_algs': 'TEXT',
'accept_tpm_signing_algs': 'TEXT',
'hash_alg': 'TEXT',
'enc_alg': 'TEXT',
'sign_alg': 'TEXT',
}

# these are the columns that contain json data and need marshalling
json_cols_db = ['tpm_policy', 'vtpm_policy', 'metadata', 'ima_whitelist',
'accept_tpm_hash_algs', 'accept_tpm_encryption_algs', 'accept_tpm_signing_algs']

# in the form key : default value
exclude_db = {
'registrar_keys': '',
'nonce': '',
'b64_encrypted_V': '',
'provide_V': True,
'num_retries': 0,
'pending_event': None,
'first_verified': False,
}
return keylime_sqlite.KeylimeDB(db_filename, cols_db, json_cols_db, exclude_db)
Loading

0 comments on commit 4d8d8cd

Please sign in to comment.