Skip to content

Commit

Permalink
Additional unit tests, minor bug fixes
Browse files Browse the repository at this point in the history
Note that tpm4720 tools require openssl v1.0 devel libraries to build
  • Loading branch information
jetwhiz committed Jul 23, 2018
1 parent 76da9f8 commit 28c7def
Show file tree
Hide file tree
Showing 24 changed files with 305 additions and 143 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -30,6 +30,8 @@ have been updated to correct this typo.

## Installation

***Note***: *The TPM 4720 tools require v1.0 of the OpenSSL development library, and will not compile with the newer v1.1 version! On more recent operating systems (such as Ubuntu 18+ and Fedora 27+), you will need to update the installer to specify v1.0 instead (e.g., `compat-openssl10-devel` for RPMs or `libssl1.0-dev` for APT).*

### Automated

keylime requires Python 2.7.10 or newer for proper TLS support.
Expand Down
1 change: 1 addition & 0 deletions auto-ipsec/libreswan/.gitignore
@@ -0,0 +1 @@
/ipsec-extra/
1 change: 1 addition & 0 deletions auto-ipsec/racoon/.gitignore
@@ -0,0 +1 @@
/ipsec-extra/
16 changes: 14 additions & 2 deletions installer.sh
Expand Up @@ -119,7 +119,15 @@ echo "==========================================================================
echo $'\t\t\tInstalling python & crypto libs'
echo "=================================================================================="
$PACKAGE_MGR install -y $PYTHON_PREIN
if [[ $? > 0 ]] ; then
echo "ERROR: Package(s) failed to install properly!"
exit 1
fi
$PACKAGE_MGR install -y $PYTHON_DEPS
if [[ $? > 0 ]] ; then
echo "ERROR: Package(s) failed to install properly!"
exit 1
fi
pip install $PYTHON_PIPS


Expand Down Expand Up @@ -312,15 +320,19 @@ echo $'\t\t\t\tBuild and install tpm4720'
echo "=================================================================================="
# Create temp dir for building tpm
TMPDIR=`mktemp -d` || exit 1
echo -n "INFO: Using temp tpm directory: "
echo $TMPDIR
echo "INFO: Using temp tpm directory: $TMPDIR"

$PACKAGE_MGR -y install $BUILD_TOOLS
if [[ $? > 0 ]] ; then
echo "ERROR: Package(s) failed to install properly!"
exit 1
fi
mkdir -p $TMPDIR/tpm4720
cd $TMPDIR/tpm4720
git clone $TPM4720_GIT tpm4720-keylime
cd $TMPDIR/tpm4720/tpm4720-keylime
git checkout $TPM4720_VER

# Install tpm4720
cd tpm
make -f makefile-tpm
Expand Down
18 changes: 10 additions & 8 deletions keylime/ca_impl_openssl.py
Expand Up @@ -19,15 +19,13 @@
'''

import time
from M2Crypto import X509, EVP, RSA, ASN1, BIO
import common
from M2Crypto import X509, EVP, RSA, ASN1
import ConfigParser

import common
config = ConfigParser.SafeConfigParser()
config.read(common.CONFIG_FILE)

logger = common.init_logging('ca_impl_openssl')

def mk_cert_valid(cert, days=365):
"""
Make a cert valid from now and til 'days' from now.
Expand Down Expand Up @@ -68,7 +66,7 @@ def mk_request(bits, cn):
return x, pk


def mk_cacert():
def mk_cacert(name=None):
"""
Make a CA certificate.
Returns the certificate, private key and public key.
Expand All @@ -79,10 +77,13 @@ def mk_cacert():
cert.set_serial_number(1)
cert.set_version(2)
mk_cert_valid(cert,config.getint('ca','cert_ca_lifetime'))

if name==None:
name = config.get('ca','cert_ca_name')

issuer = X509.X509_Name()
issuer.C = config.get('ca','cert_country')
issuer.CN = config.get('ca','cert_ca_name')
issuer.CN = name
issuer.ST = config.get('ca','cert_state')
issuer.L = config.get('ca','cert_locality')
issuer.O = config.get('ca','cert_organization')
Expand All @@ -91,7 +92,7 @@ def mk_cacert():
cert.set_subject(cert.get_issuer())
cert.set_pubkey(pkey)
cert.add_ext(X509.new_extension('basicConstraints', 'CA:TRUE'))
cert.add_ext(X509.new_extension('subjectKeyIdentifier', cert.get_fingerprint()))
cert.add_ext(X509.new_extension('subjectKeyIdentifier', str(cert.get_fingerprint())))
cert.add_ext(X509.new_extension('crlDistributionPoints','URI:http://localhost/crl.pem'))
cert.add_ext(X509.new_extension('keyUsage', 'keyCertSign, cRLSign'))
cert.sign(pk, 'sha256')
Expand Down Expand Up @@ -119,5 +120,6 @@ def mk_signed_cert(cacert,ca_pk,name,serialnum):
return cert, pk

def gencrl(_,a,b):
logger = common.init_logging('ca_impl_openssl')
logger.warning("CRL creation with openssl is not supported")
return ""
return ""
4 changes: 2 additions & 2 deletions keylime/ca_util.py
Expand Up @@ -118,7 +118,7 @@ def cmd_mkcert(workingdir,name):
if cc.verify(cacert.get_pubkey()):
logger.info("Created certificate for name %s successfully in %s"%(name,workingdir))
else:
logger.errro("ERROR: Cert does not validate against CA")
logger.error("ERROR: Cert does not validate against CA")
finally:
os.chdir(cwd)

Expand Down Expand Up @@ -449,7 +449,7 @@ def read_private():

def main(argv=sys.argv):
parser = argparse.ArgumentParser(argv[0])
parser.add_argument('-c', '---command',action='store',dest='command',required=True,help="valid commands are init,create,pkg,revoke,listen")
parser.add_argument('-c', '--command',action='store',dest='command',required=True,help="valid commands are init,create,pkg,revoke,listen")
parser.add_argument('-n', '--name',action='store',help='the common name of the certificate to create')
parser.add_argument('-d','--dir',action='store',help='use a custom directory to store certificates and keys')
parser.add_argument('-i','--insecure',action='store_true',default=False,help='create cert packages with unprotected private keys and write them to disk. USE WITH CAUTION!')
Expand Down
72 changes: 0 additions & 72 deletions keylime/cloud_verifier_common.py
Expand Up @@ -355,75 +355,3 @@ def init_db(db_filename):
}
return keylime_sqlite.KeylimeDB(db_filename,cols_db,json_cols_db,exclude_db)

def test_sql():
# testing
db_filename = 'cv_testdata.sqlite'

if os.path.exists(db_filename):
os.remove(db_filename)

db = init_db(db_filename)

json_body = {
'v': 'vbaby',
'instance_id': '209483',
'cloudnode_ip': 'ipaddy',
'cloudnode_port': '39843',
'tpm_policy': '{"atpm":"1"}',
'vtpm_policy': '{"abv":"1"}',
'ima_whitelist': '{"abi":"1"}',
'metadata': '{"cert_serial":"1"}',
'operational_state': 0,
'ip': "128.1.1.1.",
'port': 2000,
'revocation_key': '',
'public_key': 'bleh',
}

json_body2 = {
'v': 'vbaby',
'instance_id': '2094aqrea3',
'cloudnode_ip': 'ipaddy',
'cloudnode_port': '39843',
'tpm_policy': '{"a":"1"}',
'vtpm_policy': '{"ab":"1"}',
'ima_whitelist': '{"ab":"1"}',
'metadata': '{"cert_serial":"1"}',
'operational_state': 0,
'ip': "128.1.1.1.",
'port': 2000,
'revocation_key': '',
'public_key': 'bleh',
}

#some DB testing stuff
print "testing add"
db.add_instance('209483',json_body)
print 'testing update'
db.update_instance('209483','v','NEWVVV')
print 'testing remove'
print db.remove_instance('209483')
db.print_db()
print 'testing get instance ids'
db.add_instance('209483',json_body)
db.add_instance('2094aqrea3',json_body2)
print db.get_instance_ids()

print 'testing get instance'
print db.get_instance(209483)

print 'testing overwrite'
instance = db.get_instance('2094aqrea3')
instance['instance_id']=209483
instance['v']='OVERWRITTENVVVV'
db.overwrite_instance(209483, instance)
print db.get_instance(209483)

print 'testing update_all'
db.update_all_instances('operational_state', 2)

import sys
sys.exit(0)

if __name__=="__main__":
test_sql()
46 changes: 5 additions & 41 deletions keylime/crypto.py
Expand Up @@ -29,8 +29,7 @@
from Cryptodome.Cipher import AES
from Cryptodome.Protocol import KDF
from Cryptodome.Signature import pss

import tpm_random


def rsa_import_pubkey(buf):
return RSA.importKey(buf)
Expand All @@ -44,12 +43,8 @@ def rsa_export_pubkey(privkey):
def rsa_export_privkey(privkey):
return privkey.exportKey()

def rsa_generate(size,useTPM=False):
# warning this can be pretty slow 20-40s
if useTPM:
return RSA.generate(2048,randfunc=tpm_random.get_tpm_randomness)
else:
return RSA.generate(2048)
def rsa_generate(size):
return RSA.generate(2048)

def rsa_sign(key,message):
h = SHA384.new(message)
Expand All @@ -58,7 +53,7 @@ def rsa_sign(key,message):

def rsa_verify(pubkey,received_message,signature):
h = SHA384.new(received_message)
verifier = verifier = pss.new(pubkey)
verifier = pss.new(pubkey)
try:
verifier.verify(h, base64.b64decode(signature))
return True
Expand All @@ -76,7 +71,7 @@ def rsa_decrypt(key,ciphertext):

def generate_random_key(size=32):
return get_random_bytes(size)

def strbitxor(a,b):
a = bytearray(a)
b = bytearray(b)
Expand Down Expand Up @@ -146,34 +141,3 @@ def decrypt(ciphertext, key):
cipher = AES.new(key, AES.MODE_GCM, nonce = nonce)
cipher_text = bytes(ciphertext[AES.block_size:-AES.block_size])
return _strip_pad(cipher.decrypt_and_verify(cipher_text, digest))

def main():
message = b"a secret message!"
print "testing crypto..."

key = rsa_generate(2048)
pubkeypem = rsa_export_pubkey(key)
print pubkeypem
pubkey = rsa_import_pubkey(pubkeypem)

keypem = rsa_export_privkey(key)
print keypem
key = rsa_import_privkey(keypem)

ciphertext = rsa_encrypt(pubkey, message)
plain = rsa_decrypt(key, ciphertext)
print "rsa test %s"%(plain==message)

aeskey = kdf(message,'salty-McSaltface')
ciphertext = encrypt(message,aeskey)
print "aes ciphertext %s"%ciphertext
plaintext = decrypt(ciphertext,aeskey)
print "aes test passed %s"%(plaintext==message)

digest = do_hmac(aeskey,message)
print digest
aeskey2 = kdf(message,'salty-McSaltface')
print "hmac test passed %s"%(do_hmac(aeskey2,message)==digest)

if __name__=="__main__":
main()
6 changes: 0 additions & 6 deletions keylime/keylime_sqlite.py
Expand Up @@ -65,7 +65,6 @@ def __init__(self,dbname,cols_db,json_cols_db,exclude_db):
os.chmod(self.db_filename,0o600)

def print_db(self):
return
with sqlite3.connect(self.db_filename) as conn:
cur = conn.cursor()
cur.execute('SELECT * FROM main')
Expand Down Expand Up @@ -110,7 +109,6 @@ def add_instance(self,instance_id, d):
if d[item] is not None and isinstance(d[item],basestring):
d[item] = json.loads(d[item])

self.print_db()
return d

def remove_instance(self,instance_id):
Expand All @@ -123,7 +121,6 @@ def remove_instance(self,instance_id):
cur.execute('DELETE FROM main WHERE instance_id=?',(instance_id,))
conn.commit()

self.print_db()
return True

def update_instance(self,instance_id, key, value):
Expand All @@ -138,7 +135,6 @@ def update_instance(self,instance_id, key, value):
cur.execute('UPDATE main SET %s = ? where instance_id = ?'%(key),(value,instance_id))
conn.commit()

self.print_db()
return

def update_all_instances(self,key,value):
Expand All @@ -152,7 +148,6 @@ def update_all_instances(self,key,value):
value = json.dumps(value)
cur.execute('UPDATE main SET %s = ?'%key,(value,))
conn.commit()
self.print_db()
return

def get_instance(self,instance_id):
Expand Down Expand Up @@ -199,6 +194,5 @@ def overwrite_instance(self,instance_id,instance):
else:
cur.execute('UPDATE main SET %s = ? where instance_id = ?'%(key),(instance[key],instance_id))
conn.commit()
self.print_db()
return

27 changes: 17 additions & 10 deletions keylime/make_node_bundle.sh
Expand Up @@ -25,17 +25,24 @@ rm -rf build dist

# copy in extra pycryptodome libraries
mkdir -p build/crypto
CRYPTO_DIR=`pwd`"/build/crypto"

# find out where the crypto objects are stored
if [[ -d "/usr/local/lib/python2.7/dist-packages/" ]] ; then
# Typical for Debian-based
cd /usr/local/lib/python2.7/dist-packages/
elif [[ -d "/usr/lib64/python2.7/site-packages/" ]] ; then
# Typical for CentOS-based
cd /usr/lib64/python2.7/site-packages/
fi
# Copy py dependencies to crypto folder
copy_py_deps () {
pushd $1
IFS=$'\n'
CRYPTO_PY=`find -name _BLAKE2b.so | awk -F\/ '{print $2}'`
for dir in $CRYPTO_PY ; do
find "$dir" -name "*.so" -exec cp -t $CRYPTO_DIR '{}' \;
done
popd
}

find `find -name _BLAKE2b.so | awk -F\/ '{print $2}'` -name "*.so" | xargs cp -t $OLDPWD/build/crypto
# Find python's dist-packages or site-packages dirs
IFS=$'\n'
DIST_PATH=`python -c "import sys;import re; print '\n'.join(filter(lambda x:re.search(r'(dist|site)-packages$',x), sys.path))"`
for path in $DIST_PATH ; do
copy_py_deps "$path"
done

cd $OLDPWD
pyinstaller --clean cn_installer.spec
2 changes: 1 addition & 1 deletion keylime/make_node_bundle_tarball.sh
Expand Up @@ -27,7 +27,7 @@ if [[ -n "$(command -v yum)" ]]; then
PACKAGE_MGR=$(command -v yum)
PACKAGE_INSP="rpm -ql"
PYTHON_PREIN="epel-release git gcc" #note: gcc is required for pip to build m2crypto
PYTHON_DEPS="python python-pip upx python-devel python-setuptools czmq-devel python-zmq openssl-devel"
PYTHON_DEPS="python python-pip upx python-devel python-setuptools czmq-devel zeromq-devel python-zmq openssl-devel"
PYTHON_PIPS="pyinstaller m2crypto tornado"
elif [[ -n "$(command -v apt-get)" ]]; then
PACKAGE_MGR=$(command -v apt-get)
Expand Down
2 changes: 1 addition & 1 deletion keylime/tenant.py
Expand Up @@ -637,7 +637,7 @@ def do_verify(self):

def main(argv=sys.argv):
parser = argparse.ArgumentParser(argv[0])
parser.add_argument('-c', '---command',action='store',dest='command',default='add',help="valid commands are add,delete,status,reactivate,regdelete. defaults to add")
parser.add_argument('-c', '--command',action='store',dest='command',default='add',help="valid commands are add,delete,status,reactivate,regdelete. defaults to add")
parser.add_argument('-t', '--targethost',action='store',dest='node_ip',help="the IP address of the host to provision")
parser.add_argument('--cv_targethost',action='store',default=None,dest='cv_node_ip',help='the IP address of the host to provision that the verifier will use (optional). Use only if different than argument to option -t/--targethost')
parser.add_argument('-v', '--cv',action='store',dest='verifier_ip',help="the IP address of the cloud verifier")
Expand Down
1 change: 1 addition & 0 deletions scripts/README.md
@@ -0,0 +1 @@
these are some old scripts we used for testing. it is unlikely that they work. Use tests instead.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions setup.py
Expand Up @@ -110,6 +110,9 @@
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
install_requires=['pycryptodomex>=3.4.1','tornado>=4.3','m2crypto>=0.21.1','pyzmq>=14.4'],

# test packages required
tests_require=['green','coverage'],

# List additional groups of dependencies here (e.g. development
# dependencies). You can install these using the following syntax,
Expand Down
File renamed without changes.

0 comments on commit 28c7def

Please sign in to comment.