def setUpClass(cls): """Prepare the keys and payload to give to the CV""" contents = "random garbage to test as payload" # contents = contents.encode('utf-8') ret = user_data_encrypt.encrypt(contents) cls.K = ret["k"] cls.U = ret["u"] cls.V = ret["v"] cls.payload = ret["ciphertext"] # Set up to register an agent cls.auth_tag = crypto.do_hmac(cls.K, tenant_templ.agent_uuid) # Prepare policies for agent cls.tpm_policy = config.get("tenant", "tpm_policy") cls.tpm_policy = tpm_abstract.TPM_Utilities.readPolicy(cls.tpm_policy) # Allow targeting a specific API version (default latest) cls.api_version = "2.0" # Set up allowlist bundles. Use invalid exclusion list regex for bad bundle. cls.ima_policy_bundle = ima.read_allowlist() cls.ima_policy_bundle["excllist"] = base64.b64encode( json.dumps([]).encode()).decode() cls.bad_ima_policy_bundle = ima.read_allowlist() cls.bad_ima_policy_bundle["excllist"] = base64.b64encode( json.dumps(["*"]).encode()).decode()
def test_030_cv_agent_post(self): """Test CV's POST /agents/{UUID} Interface""" self.assertIsNotNone( self.V, "Required value not set. Previous step may have failed?") b64_v = base64.b64encode(self.V) data = { "v": b64_v, "cloudagent_ip": tenant_templ.cloudagent_ip, "cloudagent_port": tenant_templ.cloudagent_port, "tpm_policy": json.dumps(self.tpm_policy), "ima_policy_bundle": json.dumps(self.ima_policy_bundle), "ima_sign_verification_keys": "", "mb_refstate": None, "metadata": json.dumps(self.metadata), "revocation_key": self.revocation_key, "accept_tpm_hash_algs": config.get("tenant", "accept_tpm_hash_algs").split(","), "accept_tpm_encryption_algs": config.get("tenant", "accept_tpm_encryption_algs").split(","), "accept_tpm_signing_algs": config.get("tenant", "accept_tpm_signing_algs").split(","), "supported_version": tenant_templ.supported_version, "ak_tpm": aik_tpm, "mtls_cert": mtls_cert, } test_030_cv_agent_post = RequestsClient(tenant_templ.verifier_base_url, tls_enabled) response = test_030_cv_agent_post.post( f"/v{self.api_version}/agents/{tenant_templ.agent_uuid}", data=json.dumps(data), cert=tenant_templ.cert, verify=False, ) self.assertEqual(response.status_code, 200, "Non-successful CV agent Post return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!") time.sleep(10)
def test_030_cv_agent_post(self): """Test CV's POST /agents/{UUID} Interface""" self.assertIsNotNone( self.V, "Required value not set. Previous step may have failed?") b64_v = base64.b64encode(self.V) data = { 'v': b64_v, 'cloudagent_ip': tenant_templ.cloudagent_ip, 'cloudagent_port': tenant_templ.cloudagent_port, 'tpm_policy': json.dumps(self.tpm_policy), 'vtpm_policy': json.dumps(self.vtpm_policy), 'allowlist': json.dumps(self.allowlist), 'ima_sign_verification_keys': '', 'mb_refstate': None, 'metadata': json.dumps(self.metadata), 'revocation_key': self.revocation_key, 'accept_tpm_hash_algs': config.get('tenant', 'accept_tpm_hash_algs').split(','), 'accept_tpm_encryption_algs': config.get('tenant', 'accept_tpm_encryption_algs').split(','), 'accept_tpm_signing_algs': config.get('tenant', 'accept_tpm_signing_algs').split(','), 'supported_version': tenant_templ.supported_version } test_030_cv_agent_post = RequestsClient(tenant_templ.verifier_base_url, tls_enabled) response = test_030_cv_agent_post.post( f'/v{self.api_version}/agents/{tenant_templ.agent_uuid}', data=json.dumps(data), cert=tenant_templ.cert, verify=False) self.assertEqual(response.status_code, 200, "Non-successful CV agent Post return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!") time.sleep(10)
def prepare_error(agent, msgtype="revocation", event=None): # prepare the revocation message: revocation = { "type": msgtype, "ip": agent["ip"], "agent_id": agent["agent_id"], "port": agent["port"], "tpm_policy": agent["tpm_policy"], "meta_data": agent["meta_data"], "event_time": time.asctime(), } if event: revocation["event_id"] = event.event_id revocation["severity_label"] = event.severity_label.name revocation["context"] = event.context tosend = {"msg": json.dumps(revocation).encode("utf-8")} # also need to load up private key for signing revocations if agent["revocation_key"] != "": signing_key = crypto.rsa_import_privkey(agent["revocation_key"]) tosend["signature"] = crypto.rsa_sign(signing_key, tosend["msg"]) else: tosend["signature"] = "none" return tosend
def test_024_agent_keys_ukey_post(self): """Test agents's POST /keys/ukey Interface""" self.assertIsNotNone(public_key, "Required value not set. Previous step may have failed?") self.assertIsNotNone(self.U, "Required value not set. Previous step may have failed?") self.assertIsNotNone(self.auth_tag, "Required value not set. Previous step may have failed?") self.assertIsNotNone(self.payload, "Required value not set. Previous step may have failed?") encrypted_U = crypto.rsa_encrypt(crypto.rsa_import_pubkey(public_key), self.U) b64_encrypted_u = base64.b64encode(encrypted_U) data = {"encrypted_key": b64_encrypted_u, "auth_tag": self.auth_tag, "payload": self.payload} test_024_agent_keys_ukey_post = RequestsClient( tenant_templ.agent_base_url, tls_enabled=True, ignore_hostname=True ) response = test_024_agent_keys_ukey_post.post( f"/v{self.api_version}/keys/ukey", data=json.dumps(data), cert=tenant_templ.agent_cert, verify=False, # TODO: use agent certificate ) self.assertEqual(response.status_code, 200, "Non-successful Agent ukey post return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!")
def test_026_cv_allowlist_get(self): """Test CV's GET /allowlists/{name} Interface""" cv_client = RequestsClient(tenant_templ.verifier_base_url, tls_enabled) response = cv_client.get( f"/v{self.api_version}/allowlists/test-allowlist", cert=tenant_templ.cert, verify=False ) self.assertEqual(response.status_code, 200, "Non-successful CV allowlist Post return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!") results = json_response["results"] self.assertEqual(results["name"], "test-allowlist") self.assertEqual(results["tpm_policy"], json.dumps(self.tpm_policy)) self.assertEqual(results["ima_policy"], json.dumps(self.allowlist))
def test_011_reg_agent_activate_put(self): """Test registrar's PUT /agents/{UUID}/activate Interface""" self.assertIsNotNone( keyblob, "Required value not set. Previous step may have failed?") key = tpm_instance.activate_identity(keyblob) data = { "auth_tag": crypto.do_hmac(key, tenant_templ.agent_uuid), } test_011_reg_agent_activate_put = RequestsClient( tenant_templ.registrar_base_url, tls_enabled=False) response = test_011_reg_agent_activate_put.put( f"/v{self.api_version}/agents/{tenant_templ.agent_uuid}/activate", data=json.dumps(data), cert="", verify=False, ) self.assertEqual( response.status_code, 200, "Non-successful Registrar agent Activate return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!")
def test_023_agent_keys_vkey_post(self): """Test agent's POST /keys/vkey Interface""" # CV should do this (during CV POST/PUT test) # Running this test might hide problems with the CV sending the V key self.assertIsNotNone( self.V, "Required value not set. Previous step may have failed?") self.assertIsNotNone( public_key, "Required value not set. Previous step may have failed?") encrypted_V = crypto.rsa_encrypt(crypto.rsa_import_pubkey(public_key), str(self.V)) b64_encrypted_V = base64.b64encode(encrypted_V) data = {"encrypted_key": b64_encrypted_V} test_023_agent_keys_vkey_post = RequestsClient( tenant_templ.agent_base_url, tls_enabled=False) response = test_023_agent_keys_vkey_post.post( f"/v{self.api_version}/keys/vkey", data=json.dumps(data), cert="", verify=False) self.assertEqual(response.status_code, 200, "Non-successful Agent vkey post return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!")
def echo_json_response(handler, code, status=None, results=None): """Takes a json package and returns it to the user w/ full HTTP headers""" if handler is None or code is None: return False if status is None: status = http.client.responses[code] if results is None: results = {} json_res = {"code": code, "status": status, "results": results} json_response = json.dumps(json_res) json_response = json_response.encode("utf-8") if isinstance(handler, BaseHTTPRequestHandler): handler.send_response(code) handler.send_header("Content-Type", "application/json") handler.end_headers() handler.wfile.write(json_response) return True if isinstance(handler, tornado.web.RequestHandler): handler.set_status(code) handler.set_header("Content-Type", "application/json") handler.write(json_response) handler.finish() return True return False
def add_vtpm_group(rsa_mod=None): """ Add new vtpm group""" fprt = "add_vtpm_group" if config.STUB_TPM and config.TPM_CANNED_VALUES is not None: # Use canned values for stubbing jsonIn = config.TPM_CANNED_VALUES if fprt in jsonIn: # The value we're looking for has been canned! thisTiming = jsonIn[fprt]['timing'] thisRetout = jsonIn[fprt]['retout'] logger.debug( "TPM call '{}' was stubbed out, with a simulated delay of {:f} sec" .format(fprt, thisTiming)) time.sleep(thisTiming) return tuple(thisRetout) # Our command hasn't been canned! raise Exception("Command %s not found in canned JSON!" % (fprt)) logger.debug('Adding group') t0 = time.time() if rsa_mod is None: rsa_mod = '\x00' * 256 assert len(rsa_mod) == 256 ca_digest = '\x00' * 20 rsp = vtpm_cmd(VTPM_ORD_GROUP_NEW, ca_digest + rsa_mod) (uuid, aik_pub, aik_priv_ca) = struct.unpack('16s256s256s', rsp) uuid = struct.unpack(uuid_fmt, uuid) uuid = '-'.join([part.encode('hex') for part in uuid]) logger.info('Created group with UUID: %s', uuid) aikpem = tpmconv(aik_pub) # return the group group_num = get_group_num(uuid) t1 = time.time() retout = (uuid, aikpem, group_num, base64.b64encode(aik_priv_ca)) if config.TPM_CANNED_VALUES_PATH is not None: with open(config.TPM_CANNED_VALUES_PATH, "ab") as can: jsonObj = { 'type': "add_vtpm_group", 'retout': list(retout), 'fileout': "", 'cmd': "add_vtpm_group", 'timing': t1 - t0, 'code': 0, 'nonce': None } can.write("\"{}\": {},\n".format( "add_vtpm_group", json.dumps(jsonObj, indent=4, sort_keys=True, Dumper=SafeDumper))) return retout
def do_GET(self): self.send_response(200) self.send_header('Content-Type', 'application/json') self.end_headers() if TESTING_MODE: myUUID = str(uuid.uuid4()) else: myUUID = provider_vtpm_add.add_vtpm("current_group.tpm") self.request.sendall(json.dumps({'uuid': myUUID}))
def test_ima_buf_verification(self): """The verification of ima-buf entries supporting keys loaded onto keyrings""" list_map = ima.process_allowlists(ALLOWLIST, "") ima_keyrings = file_signatures.ImaKeyrings() self.assertTrue( ima.process_measurement_list(AgentAttestState("1"), KEYRINGS.splitlines(), json.dumps(list_map), ima_keyrings=ima_keyrings) is not None)
def test_025_cv_allowlist_post(self): """Test CV's POST /allowlist/{name} Interface""" data = { "name": "test-allowlist", "tpm_policy": json.dumps(self.tpm_policy), "ima_policy": json.dumps(self.allowlist), } cv_client = RequestsClient(tenant_templ.verifier_base_url, tls_enabled) response = cv_client.post( f"/v{self.api_version}/allowlists/test-allowlist", data=json.dumps(data), cert=tenant_templ.cert, verify=False, ) self.assertEqual(response.status_code, 201, "Non-successful CV allowlist Post return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!")
def write_error(self, status_code, **kwargs): self.set_header("Content-Type", "text/json") if self.settings.get("serve_traceback") and "exc_info" in kwargs: # in debug mode, try to send a traceback lines = [] for line in traceback.format_exception(*kwargs["exc_info"]): lines.append(line) self.finish( json.dumps({ "code": status_code, "status": self._reason, "traceback": lines, "results": {}, })) else: self.finish( json.dumps({ "code": status_code, "status": self._reason, "results": {}, }))
def write_error(self, status_code, **kwargs): self.set_header('Content-Type', 'text/json') if self.settings.get("serve_traceback") and "exc_info" in kwargs: # in debug mode, try to send a traceback lines = [] for line in traceback.format_exception(*kwargs["exc_info"]): lines.append(line) self.finish( json.dumps({ 'code': status_code, 'status': self._reason, 'traceback': lines, 'results': {}, })) else: self.finish( json.dumps({ 'code': status_code, 'status': self._reason, 'results': {}, }))
def test_010_reg_agent_post(self): """Test registrar's POST /agents/{UUID} Interface""" global keyblob, tpm_instance, ek_tpm, aik_tpm contact_ip = "127.0.0.1" contact_port = 9002 tpm_instance = tpm_main.tpm() # Change CWD for TPM-related operations cwd = os.getcwd() fs_util.ch_dir(config.WORK_DIR) _ = secure_mount.mount() # Create a mTLS cert for testing global mtls_cert rsa_key = crypto.rsa_generate(2048) valid_util = datetime.datetime.utcnow() + datetime.timedelta(days=(360 * 5)) mtls_cert = crypto.generate_selfsigned_cert("TEST_CERT", rsa_key, valid_util).public_bytes( serialization.Encoding.PEM ) # Initialize the TPM with AIK (ekcert, ek_tpm, aik_tpm) = tpm_instance.tpm_init( self_activate=False, config_pw=config.get("cloud_agent", "tpm_ownerpassword") ) # Handle emulated TPMs if ekcert is None: if tpm_instance.is_emulator(): ekcert = "emulator" # Get back to our original CWD fs_util.ch_dir(cwd) data = {"ekcert": ekcert, "aik_tpm": aik_tpm, "ip": contact_ip, "port": contact_port, "mtls_cert": mtls_cert} if ekcert is None or ekcert == "emulator": data["ek_tpm"] = ek_tpm test_010_reg_agent_post = RequestsClient(tenant_templ.registrar_base_url, tls_enabled=False) response = test_010_reg_agent_post.post( f"/v{self.api_version}/agents/{tenant_templ.agent_uuid}", data=json.dumps(data), cert="", verify=False ) self.assertEqual(response.status_code, 200, "Non-successful Registrar agent Add return code!") json_response = response.json() # Ensure response is well-formed self.assertIn("results", json_response, "Malformed response body!") self.assertIn("blob", json_response["results"], "Malformed response body!") keyblob = json_response["results"]["blob"] self.assertIsNotNone(keyblob, "Malformed response body!")
def test_034_cv_agent_post_invalid_exclude_list(self): """Test CV's POST /agents/{UUID} Interface""" self.assertIsNotNone(self.V, "Required value not set. Previous step may have failed?") b64_v = base64.b64encode(self.V) # Set unsupported regex in exclude list allowlist = {"exclude": ["*"]} data = { "v": b64_v, "mb_refstate": None, "cloudagent_ip": tenant_templ.cloudagent_ip, "cloudagent_port": tenant_templ.cloudagent_port, "tpm_policy": json.dumps(self.tpm_policy), "allowlist": json.dumps(allowlist), "ima_sign_verification_keys": "", "metadata": json.dumps(self.metadata), "revocation_key": self.revocation_key, "accept_tpm_hash_algs": config.get("tenant", "accept_tpm_hash_algs").split(","), "accept_tpm_encryption_algs": config.get("tenant", "accept_tpm_encryption_algs").split(","), "accept_tpm_signing_algs": config.get("tenant", "accept_tpm_signing_algs").split(","), "supported_version": tenant_templ.supported_version, } client = RequestsClient(tenant_templ.verifier_base_url, tls_enabled) response = client.post( f"/v{self.api_version}/agents/{tenant_templ.agent_uuid}", cert=tenant_templ.cert, data=json.dumps(data), verify=False, ) self.assertEqual(response.status_code, 400, "Successful CV agent Post return code!") # Ensure response is well-formed json_response = response.json() self.assertIn("results", json_response, "Malformed response body!")
def test_json_response_tornado(self): """Tests JSON response output for Tornado""" mock_handler = MagicMock(spec=tornado.web.RequestHandler) test_data = {"key_1": "value", "key_2": 2} expected_output = json.dumps({ "code": 200, "status": "Success", "results": test_data, }).encode("utf-8") res = web_util.echo_json_response(mock_handler, 200, "Success", test_data) self.assertTrue(res) mock_handler.set_status.assert_called_once_with(200) mock_handler.set_header.assert_called_once_with('Content-Type', 'application/json') mock_handler.write.assert_called_once_with(expected_output) mock_handler.finish.assert_called_once()
def activate_group(uuid, keyblob): fprt = "activate_group" if config.STUB_TPM and config.TPM_CANNED_VALUES is not None: # Use canned values for stubbing jsonIn = config.TPM_CANNED_VALUES if fprt in jsonIn: # The value we're looking for has been canned! thisTiming = jsonIn[fprt]['timing'] thisRetout = jsonIn[fprt]['retout'] logger.debug( "TPM call '{}' was stubbed out, with a simulated delay of {:f} sec" .format(fprt, thisTiming)) time.sleep(thisTiming) return base64.b64decode(thisRetout) # Our command hasn't been canned! raise Exception("Command %s not found in canned JSON!" % (fprt)) t0 = time.time() group_id = get_group_num(uuid) priv_ca = base64.b64decode(keyblob) assert len(priv_ca) == 256 logger.debug('Activating group number %d', group_id) body = vtpm_cmd(VTPM_ORD_GROUP_ACTIVATE, struct.pack('>II', group_id, 256) + priv_ca) (algId, encScheme, size), body = unpack('>IHH', body) assert size == len(body) t1 = time.time() logger.info('Received Key. AlgID: 0x%x, encScheme: 0x%x, size: 0x%x', algId, encScheme, size) logger.info('Key: %r', body) if config.TPM_CANNED_VALUES_PATH is not None: with open(config.TPM_CANNED_VALUES_PATH, "ab") as can: jsonObj = { 'type': "activate_group", 'retout': base64.b64encode(body), 'fileout': "", 'cmd': "activate_group", 'timing': t1 - t0, 'code': 0, 'nonce': None } can.write("\"{}\": {},\n".format( "activate_group", json.dumps(jsonObj, indent=4, sort_keys=True))) return body
async def request(method, url, params=None, data=None, context=None, headers=None): http_client = httpclient.AsyncHTTPClient() if params is not None and len(list(params.keys())) > 0: url += "?" for key in list(params.keys()): url += f"{key}={params[key]}&" url = url[:-1] if context is not None: url = url.replace("http://", "https://", 1) # Convert dict to JSON before sending if isinstance(data, dict): data = json.dumps(data) if headers is None: headers = {} if "Content-Type" not in headers: headers["Content-Type"] = "application/json" try: req = httpclient.HTTPRequest(url=url, method=method, ssl_options=context, body=data, headers=headers) response = await http_client.fetch(req) except httpclient.HTTPError as e: if e.response is None: return TornadoResponse(500, str(e)) return TornadoResponse(e.response.code, e.response.body) except ConnectionError as e: return TornadoResponse(599, f"Connection error: {str(e)}") except ssl.SSLError as e: return TornadoResponse(599, f"SSL connection error: {str(e)}") except OSError as e: return TornadoResponse(599, f"TCP/IP Connection error: {str(e)}") if response is None: return None return TornadoResponse(response.code, response.body)
def test_measurment_verification(self): """Test IMA measurement list verification""" lines = MEASUREMENTS.splitlines() lists_map = ima.process_ima_policy(ALLOWLIST, "") lists_map_empty = ima.process_ima_policy(ALLOWLIST_EMPTY, "") _, failure = ima.process_measurement_list(AgentAttestState("1"), lines) self.assertTrue(not failure, "Validation should always work when no allowlist and no keyring is specified") _, failure = ima.process_measurement_list(AgentAttestState("1"), lines, lists_map) self.assertTrue(not failure) # test with list with JSON _, failure = ima.process_measurement_list(AgentAttestState("1"), lines, json.dumps(lists_map)) self.assertTrue(not failure) # No files are in the allowlist -> this should fail _, failure = ima.process_measurement_list(AgentAttestState("1"), lines, lists_map_empty) self.assertTrue(failure)
def test_json_response_http_server(self): """Tests JSON response output for Tornado""" mock_handler = MagicMock(spec=http.server.BaseHTTPRequestHandler) mock_handler.wfile = MagicMock() test_data = {"key_1": "value", "key_2": 2} expected_output = json.dumps({ "code": 200, "status": "Success", "results": test_data, }).encode("utf-8") res = web_util.echo_json_response(mock_handler, 200, "Success", test_data) self.assertTrue(res) mock_handler.send_response.assert_called_once_with(200) mock_handler.send_header.assert_called_once_with( "Content-Type", "application/json") mock_handler.end_headers.assert_called_once() mock_handler.wfile.write.assert_called_once_with(expected_output)
def __init__(self, component: Component, sub_components: Optional[List[str]], event_id: str, context: Union[str, Dict[str, json.JSONType]], recoverable: bool): # Build full event id with the format "component.[sub_component].event_id" self.event_id = component.value if sub_components is not None: self.event_id += "." + ".".join(sub_components) self.event_id += f".{event_id}" # Convert message if isinstance(context, str): context = {"message": context} self.context = json.dumps(context) self.severity_label = _severity_match(self.event_id) self.recoverable = recoverable
def worker(tosend): context = zmq.Context() mysock = context.socket(zmq.PUB) mysock.connect(f"ipc://{_SOCKET_PATH}") # wait 100ms for connect to happen time.sleep(0.2) # now send it out via 0mq logger.info("Sending revocation event to listening nodes...") for i in range(config.getint('cloud_verifier', 'max_retries')): try: mysock.send_string(json.dumps(tosend)) break except Exception as e: logger.debug( "Unable to publish revocation message %d times, trying again in %f seconds: %s" % (i, config.getfloat('cloud_verifier', 'retry_interval'), e)) time.sleep(config.getfloat('cloud_verifier', 'retry_interval')) mysock.close()
def doActivateAgent(registrar_ip, registrar_port, agent_id, key): data = { 'auth_tag': crypto.do_hmac(key, agent_id), } client = RequestsClient(f'{registrar_ip}:{registrar_port}', tls_enabled) response = client.put(f'/v{api_version}/agents/{agent_id}/activate', cert=tls_cert_info, data=json.dumps(data), verify=False) response_body = response.json() if response.status_code == 200: logger.info("Registration activated for agent %s.", agent_id) return True logger.error( "Error: unexpected http response code from Registrar Server: " + str(response.status_code)) keylime_logging.log_http_response(logger, logging.ERROR, response_body) return False
def add_vtpm_to_group(uuid): fprt = "add_vtpm_to_group" if config.STUB_TPM and config.TPM_CANNED_VALUES is not None: # Use canned values for stubbing jsonIn = config.TPM_CANNED_VALUES if fprt in jsonIn: # The value we're looking for has been canned! thisTiming = jsonIn[fprt]['timing'] thisRetout = jsonIn[fprt]['retout'] logger.debug( "TPM call '{}' was stubbed out, with a simulated delay of {:f} sec" .format(fprt, thisTiming)) time.sleep(thisTiming) return thisRetout # Our command hasn't been canned! raise Exception("Command %s not found in canned JSON!" % (fprt)) t0 = time.time() num = get_group_num(uuid) vtpm_uuid = add_vtpm(num) t1 = time.time() retout = str(UUID(vtpm_uuid)).upper() if config.TPM_CANNED_VALUES_PATH is not None: with open(config.TPM_CANNED_VALUES_PATH, "ab") as can: jsonObj = { 'type': "add_vtpm_to_group", 'retout': retout, 'fileout': "", 'cmd': "add_vtpm_to_group", 'timing': t1 - t0, 'code': 0, 'nonce': None } can.write("\"{}\": {},\n".format( "add_vtpm_to_group", json.dumps(jsonObj, indent=4, sort_keys=True))) return retout
def worker(tosend): context = zmq.Context() mysock = context.socket(zmq.PUB) mysock.connect(f"ipc://{_SOCKET_PATH}") # wait 100ms for connect to happen time.sleep(0.2) # now send it out via 0mq logger.info("Sending revocation event to listening nodes...") for i in range(config.getint("cloud_verifier", "max_retries")): try: mysock.send_string(json.dumps(tosend)) break except Exception as e: interval = config.getfloat("cloud_verifier", "retry_interval") exponential_backoff = config.getboolean( "cloud_verifier", "exponential_backoff") next_retry = retry.retry_time(exponential_backoff, interval, i, logger) logger.debug( "Unable to publish revocation message %d times, trying again in %f seconds: %s", i, next_retry, e) time.sleep(next_retry) mysock.close()
def notify_error(agent, msgtype='revocation', event=None): send_mq = config.getboolean('cloud_verifier', 'revocation_notifier') send_webhook = config.getboolean('cloud_verifier', 'revocation_notifier_webhook', fallback=False) if not (send_mq or send_webhook): return # prepare the revocation message: revocation = { 'type': msgtype, 'ip': agent['ip'], 'agent_id': agent['agent_id'], 'port': agent['port'], 'tpm_policy': agent['tpm_policy'], 'vtpm_policy': agent['vtpm_policy'], 'meta_data': agent['meta_data'], 'event_time': time.asctime() } if event: revocation['event_id'] = event.event_id revocation['severity_label'] = event.severity_label.name revocation['context'] = event.context tosend = {'msg': json.dumps(revocation).encode('utf-8')} # also need to load up private key for signing revocations if agent['revocation_key'] != "": signing_key = crypto.rsa_import_privkey(agent['revocation_key']) tosend['signature'] = crypto.rsa_sign(signing_key, tosend['msg']) else: tosend['signature'] = "none" if send_mq: revocation_notifier.notify(tosend) if send_webhook: revocation_notifier.notify_webhook(tosend)
def notify_error(agent, msgtype="revocation", event=None): send_mq = config.getboolean("cloud_verifier", "revocation_notifier") send_webhook = config.getboolean("cloud_verifier", "revocation_notifier_webhook", fallback=False) if not (send_mq or send_webhook): return # prepare the revocation message: revocation = { "type": msgtype, "ip": agent["ip"], "agent_id": agent["agent_id"], "port": agent["port"], "tpm_policy": agent["tpm_policy"], "meta_data": agent["meta_data"], "event_time": time.asctime(), } if event: revocation["event_id"] = event.event_id revocation["severity_label"] = event.severity_label.name revocation["context"] = event.context tosend = {"msg": json.dumps(revocation).encode("utf-8")} # also need to load up private key for signing revocations if agent["revocation_key"] != "": signing_key = crypto.rsa_import_privkey(agent["revocation_key"]) tosend["signature"] = crypto.rsa_sign(signing_key, tosend["msg"]) else: tosend["signature"] = "none" if send_mq: revocation_notifier.notify(tosend) if send_webhook: revocation_notifier.notify_webhook(tosend)
def test_dumps(self): fixtures = [ {"input": {}, "expected": "{}"}, {"input": {"foo": "bar"}, "expected": '{"foo": "bar"}'}, {"input": {"foo": b"bar"}, "expected": '{"foo": "bar"}'}, { "input": {"foo": {"foo": {"foo": b"bar"}}}, "expected": '{"foo": {"foo": {"foo": "bar"}}}', }, {"input": [], "expected": "[]"}, {"input": (), "expected": "[]"}, {"input": [b"a", b"b", 1, 2.0], "expected": '["a", "b", 1, 2.0]'}, {"input": {"foo": [b"bar"]}, "expected": '{"foo": ["bar"]}'}, { "input": ( 1, 2, b"a", ), "expected": '[1, 2, "a"]', }, ] for f in fixtures: self.assertEqual(keylime_json.dumps(f["input"]), f["expected"])