Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixes and improvements to the web components #837

Merged
merged 10 commits into from
Jan 19, 2022
24 changes: 13 additions & 11 deletions demo/agent_monitor/tenant_agent_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import keylime_logging
import common
import sys

import keylime.web_util
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: seems that the used idiom in Keylime is from keylime import web_util, and use web_util.echo_json_response() in the code.

I do not mind if stay as it is now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I don't know if this demo code actually works this only changed by the automatic refactoring.

from keylime import json
sys.path.insert(0, '../../keylime/')

Expand Down Expand Up @@ -57,14 +59,14 @@ def write_error(self, status_code, **kwargs):

class MainHandler(tornado.web.RequestHandler):
def get(self):
common.echo_json_response(
keylime.web_util.echo_json_response(
self, 405, "Not Implemented: Use /agents/ interface instead")


class AgentsHandler(BaseHandler):
def head(self):
"""HEAD not supported"""
common.echo_json_response(self, 405, "HEAD not supported")
keylime.web_util.echo_json_response(self, 405, "HEAD not supported")

def get(self):
"""This method handles the GET requests to retrieve status on agents from the Agent Monitor.
Expand All @@ -75,15 +77,15 @@ def get(self):
was not found, it either completed successfully, or failed. If found, the agent_id is still polling
to contact the Cloud Agent.
"""
common.echo_json_response(self, 405, "GET not supported")
keylime.web_util.echo_json_response(self, 405, "GET not supported")

def delete(self):
"""This method handles the DELETE requests to remove agents from the Agent Monitor.

Currently, only agents resources are available for DELETEing, i.e. /agents. All other DELETE uri's will return errors.
agents requests require a single agent_id parameter which identifies the agent to be deleted.
"""
common.echo_json_response(self, 405, "DELETE not supported")
keylime.web_util.echo_json_response(self, 405, "DELETE not supported")

def post(self):
"""This method handles the POST requests to add agents to the Agent Monitor.
Expand All @@ -93,10 +95,10 @@ def post(self):
"""
logger.info('Agent Monitor POST')
try:
rest_params = common.get_restful_params(self.request.path)
rest_params = keylime.web_util.get_restful_params(self.request.path)

if "agents" not in rest_params:
common.echo_json_response(self, 400, "uri not supported")
keylime.web_util.echo_json_response(self, 400, "uri not supported")
logger.warning(
'POST returning 400 response. uri not supported: ' + self.request.path)
return
Expand All @@ -106,7 +108,7 @@ def post(self):
if agent_id is not None: # we have to know who phoned home
content_length = len(self.request.body)
if content_length == 0:
common.echo_json_response(
keylime.web_util.echo_json_response(
self, 400, "Expected non zero content length")
logger.warning(
'POST returning 400 response. Expected non zero content length.')
Expand Down Expand Up @@ -137,15 +139,15 @@ def initthread():
t = threading.Thread(target=initthread)
t.start()

common.echo_json_response(self, 200, "Success", json_body)
keylime.web_util.echo_json_response(self, 200, "Success", json_body)
logger.info(
'POST returning 200 response for Agent Monitor connection as ' + agent_id)
else:
common.echo_json_response(self, 400, "uri not supported")
keylime.web_util.echo_json_response(self, 400, "uri not supported")
logger.warning(
"POST returning 400 response. uri not supported")
except Exception as e:
common.echo_json_response(self, 400, "Exception error: %s" % e)
keylime.web_util.echo_json_response(self, 400, "Exception error: %s" % e)
logger.warning(
"POST returning 400 response. Exception error: %s" % e)
logger.exception(e)
Expand All @@ -156,7 +158,7 @@ def put(self):
Currently, only agents resources are available for PUTing, i.e. /agents. All other PUT uri's will return errors.
agents requests require a json block sent in the body
"""
common.echo_json_response(self, 405, "PUT not supported")
keylime.web_util.echo_json_response(self, 405, "PUT not supported")


def init_mtls(config):
Expand Down
99 changes: 0 additions & 99 deletions keylime/cloud_verifier_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@

import ast
import base64
import os
import ssl
import socket
import time
import sys

from keylime import config
from keylime import keylime_logging
from keylime import registrar_client
from keylime import crypto
from keylime import ca_util
from keylime import json
from keylime import revocation_notifier
from keylime.agentstates import AgentAttestStates
Expand Down Expand Up @@ -43,100 +38,6 @@ def get_AgentAttestStates():
return AgentAttestStates.get_instance()


def init_mtls(section='cloud_verifier', generatedir='cv_ca'):
if not config.getboolean('general', "enable_tls"):
logger.warning(
"Warning: TLS is currently disabled, keys will be sent in the clear! This should only be used for testing.")
return None

logger.info("Setting up TLS...")
my_cert = config.get(section, 'my_cert')
ca_cert = config.get(section, 'ca_cert')
my_priv_key = config.get(section, 'private_key')
my_key_pw = config.get(section, 'private_key_pw')
tls_dir = config.get(section, 'tls_dir')

if tls_dir == 'generate':
if my_cert != 'default' or my_priv_key != 'default' or ca_cert != 'default':
raise Exception(
"To use tls_dir=generate, options ca_cert, my_cert, and private_key must all be set to 'default'")

if generatedir[0] != '/':
generatedir = os.path.abspath(os.path.join(config.WORK_DIR,
generatedir))
tls_dir = generatedir
ca_path = "%s/cacert.crt" % (tls_dir)
if os.path.exists(ca_path):
logger.info("Existing CA certificate found in %s, not generating a new one", tls_dir)
else:
logger.info("Generating a new CA in %s and a client certificate for connecting", tls_dir)
logger.info("use keylime_ca -d %s to manage this CA", tls_dir)
if not os.path.exists(tls_dir):
os.makedirs(tls_dir, 0o700)
if my_key_pw == 'default':
logger.warning("CAUTION: using default password for CA, please set private_key_pw to a strong password")
ca_util.setpassword(my_key_pw)
ca_util.cmd_init(tls_dir)
ca_util.cmd_mkcert(tls_dir, socket.gethostname())
ca_util.cmd_mkcert(tls_dir, 'client')

if tls_dir == 'CV':
if section != 'registrar':
raise Exception(
"You only use the CV option to tls_dir for the registrar not %s" % section)
tls_dir = os.path.abspath(os.path.join(config.WORK_DIR, 'cv_ca'))
if not os.path.exists("%s/cacert.crt" % (tls_dir)):
raise Exception(
"It appears that the verifier has not yet created a CA and certificates, please run the verifier first")

# if it is relative path, convert to absolute in WORK_DIR
if tls_dir[0] != '/':
tls_dir = os.path.abspath(os.path.join(config.WORK_DIR, tls_dir))

if ca_cert == 'default':
ca_path = os.path.join(tls_dir, "cacert.crt")
elif not os.path.isabs(ca_cert):
ca_path = os.path.join(tls_dir, ca_cert)
else:
ca_path = ca_cert

if my_cert == 'default':
my_cert = os.path.join(tls_dir, f"{socket.gethostname()}-cert.crt")
elif not os.path.isabs(my_cert):
my_cert = os.path.join(tls_dir, my_cert)
else:
pass

if my_priv_key == 'default':
my_priv_key = os.path.join(tls_dir,
f"{socket.gethostname()}-private.pem")
elif not os.path.isabs(my_priv_key):
my_priv_key = os.path.join(tls_dir, my_priv_key)

try:
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
if sys.version_info >= (3,7):
context.minimum_version = ssl.TLSVersion.TLSv1_2
else:
context.options &= ~ssl.OP_NO_TLSv1_2
context.load_verify_locations(cafile=ca_path)
context.load_cert_chain(
certfile=my_cert, keyfile=my_priv_key, password=my_key_pw)
if (config.has_option(section, 'check_client_cert')
and config.getboolean(section, 'check_client_cert')):
context.verify_mode = ssl.CERT_REQUIRED
except ssl.SSLError as exc:
if exc.reason == 'EE_KEY_TOO_SMALL':
logger.error('Higher key strength is required for keylime '
'running on this system. If keylime is responsible '
'to generate the certificate, please raise the value '
'of configuration option [ca]cert_bits, remove '
'generated certificate and re-run keylime service')
raise exc

return context


def process_quote_response(agent, json_response, agentAttestState) -> Failure:
"""Validates the response from the Cloud agent.

Expand Down