def test_021_node_quotes_identity_get(self):
        """Test node's GET /v2/quotes/identity Interface"""
        global aik

        self.assertIsNotNone(
            aik, "Required value not set.  Previous step may have failed?")

        nonce = tpm_initialize.random_password(20)

        numretries = config.getint('tenant', 'max_retries')
        while numretries >= 0:
            response = tornado_requests.request(
                "GET", "http://%s:%s/v2/quotes/identity/nonce/%s/" %
                (tenant_templ.cloudnode_ip, tenant_templ.cloudnode_port,
                 nonce))
            if response.status_code == 200:
                break
            numretries -= 1
            time.sleep(config.getint('tenant', 'max_retries'))
        self.assertEqual(response.status_code, 200,
                         "Non-successful Node identity return code!")
        response_body = response.json()

        # Ensure response is well-formed
        self.assertIn("results", response_body, "Malformed response body!")
        self.assertIn("quote", response_body["results"],
                      "Malformed response body!")
        self.assertIn("pubkey", response_body["results"],
                      "Malformed response body!")

        # Check the quote identity
        self.assertTrue(
            tpm_quote.check_quote(nonce, response_body["results"]["pubkey"],
                                  response_body["results"]["quote"], aik),
            "Invalid quote!")
Example #2
0
 def test_040_node_quotes_integrity_get(self):
     """Test node's GET /v2/quotes/integrity Interface"""
     global public_key, aik
     
     self.assertIsNotNone(aik, "Required value not set.  Previous step may have failed?")
     
     nonce = tpm_initialize.random_password(20)
     mask = self.tpm_policy["mask"]
     vmask = self.vtpm_policy["mask"]
     partial = "1"
     if public_key is None:
         partial = "0"
     
     response = tornado_requests.request(
                                         "GET",
                                         "http://%s:%s/v2/quotes/integrity/nonce/%s/mask/%s/vmask/%s/partial/%s/"%(tenant_templ.cloudnode_ip,tenant_templ.cloudnode_port,nonce,mask,vmask,partial)
                                     )
     self.assertEqual(response.status_code, 200, "Non-successful Node Integrity Get return code!")
     response_body = response.json()
     
     # Ensure response is well-formed
     self.assertIn("results", response_body, "Malformed response body!")
     self.assertIn("quote", response_body["results"], "Malformed response body!")
     if public_key is None:
         self.assertIn("pubkey", response_body["results"], "Malformed response body!")
         public_key = response_body["results"]["pubkey"]
     
     quote = response_body["results"]["quote"]
     
     validQuote = tpm_quote.check_quote(nonce,
                                         public_key,
                                         quote,
                                         aik,
                                         self.tpm_policy)
     self.assertTrue(validQuote)
Example #3
0
 def validate_tpm_quote(self, public_key, quote):
     registrar_client.serverAuthTLSContext(config, 'tenant')
     aikFromRegistrar = registrar_client.getAIK(self.cloudverifier_ip,
                                                self.registrar_port,
                                                self.node_uuid)
     if aikFromRegistrar is not None:
         return tpm_quote.check_quote(self.nonce, public_key, quote,
                                      aikFromRegistrar)
     else:
         logger.warning("AIK not found in registrar, quote not validated")
         return False
Example #4
0
def process_quote_response(instance, json_response):
    """Validates the response from the Cloud node.
    
    This method invokes an Registrar Server call to register, and then check the quote. 
    """
    received_public_key = None
    quote = None

    # in case of failure in response content do not continue
    try:
        received_public_key = json_response.get("pubkey", None)
        quote = json_response["quote"]

        ima_measurement_list = json_response.get("ima_measurement_list", None)

        logger.debug("received quote:      %s" % quote)
        logger.debug("for nonce:           %s" % instance['nonce'])
        logger.debug("received public key: %s" % received_public_key)
        logger.debug("received ima_measurement_list    %s" %
                     (ima_measurement_list != None))
    except Exception:
        return None

    # if no public key provided, then ensure we have cached it
    if received_public_key is None:
        if instance.get('public_key', "") == "" or instance.get(
                'b64_encrypted_V', "") == "":
            logger.error(
                "node did not provide public key and no key or encrypted_v was cached at CV"
            )
            return False
        instance['provide_V'] = False
        received_public_key = instance['public_key']

    if instance.get('registrar_keys', "") is "":
        registrar_client.init_client_tls(config, 'cloud_verifier')
        registrar_keys = registrar_client.getKeys(
            config.get("general", "registrar_ip"),
            config.get("general", "registrar_tls_port"),
            instance['instance_id'])
        if registrar_keys is None:
            logger.warning("AIK not found in registrar, quote not validated")
            return False
        instance['registrar_keys'] = registrar_keys

    if tpm_quote.is_deep_quote(quote):
        validQuote = tpm_quote.check_deep_quote(
            instance['nonce'], received_public_key, quote,
            instance['registrar_keys']['aik'],
            instance['registrar_keys']['provider_keys']['aik'],
            instance['vtpm_policy'], instance['tpm_policy'],
            ima_measurement_list, instance['ima_whitelist'])
    else:
        validQuote = tpm_quote.check_quote(instance['nonce'],
                                           received_public_key, quote,
                                           instance['registrar_keys']['aik'],
                                           instance['tpm_policy'],
                                           ima_measurement_list,
                                           instance['ima_whitelist'])
    if not validQuote:
        return False

    # set a flag so that we know that the node was verified once.
    # we only issue notifications for nodes that were at some point good
    instance['first_verified'] = True

    # has public key changed? if so, clear out b64_encrypted_V, it is no longer valid
    if received_public_key != instance.get('public_key', ""):
        instance['public_key'] = received_public_key
        instance['b64_encrypted_V'] = ""
        instance['provide_V'] = True

    # ok we're done
    return validQuote
Example #5
0
    def validate_tpm_quote(self, public_key, quote):
        registrar_client.init_client_tls(config, 'tenant')
        reg_keys = registrar_client.getKeys(self.cloudverifier_ip,
                                            self.registrar_port,
                                            self.node_uuid)
        if reg_keys is None:
            logger.warning("AIK not found in registrar, quote not validated")
            return False

        if not tpm_quote.check_quote(self.nonce, public_key, quote,
                                     reg_keys['aik']):
            if reg_keys['regcount'] > 1:
                logger.error(
                    "WARNING: This UUID had more than one ek-ekcert registered to it!  This might indicate that your system is misconfigured or a malicious node is present.  Run 'regdelete' for this node and restart it to make this message go away!"
                )
            return False

        if reg_keys['regcount'] > 1:
            logger.warn(
                "WARNING: This UUID had more than one ek-ekcert registered to it!  This might indicate that your system is misconfigured.  Run 'regdelete' for this node and restart it to make this message go away!"
            )

        if not common.STUB_TPM and (
                not config.getboolean('tenant', 'require_ek_cert')
                and config.get('tenant', 'ek_check_script') == ""):
            logger.warn(
                "DANGER: EK cert checking is disabled and no additional checks on EKs have been specified with ek_check_script option. Keylime is not secure!!"
            )

        # check EK cert and make sure it matches EK
        if not self.check_ek(reg_keys['ek'], reg_keys['ekcert']):
            return False
        # if node is virtual, check phyisical EK cert and make sure it matches phyiscal EK
        if 'provider_keys' in reg_keys:
            if not self.check_ek(reg_keys['provider_keys']['ek'],
                                 reg_keys['provider_keys']['ekcert']):
                return False

        # check all EKs with optional script:
        script = config.get('tenant', 'ek_check_script')
        if script is not "":
            if script[0] != '/':
                script = "%s/%s" % (common.WORK_DIR, script)

            logger.info("Checking EK with script %s" % script)
            #now we need to exec the script with the ek and ek cert in vars
            env = os.environ.copy()
            env['NODE_UUID'] = self.node_uuid
            env['EK'] = reg_keys['ek']
            if reg_keys['ekcert'] is not None:
                env['EK_CERT'] = reg_keys['ekcert']
            else:
                env['EK_CERT'] = ""

            env['PROVKEYS'] = json.dumps(reg_keys.get('provider_keys', {}))
            proc = subprocess.Popen(script,
                                    env=env,
                                    shell=True,
                                    cwd=common.WORK_DIR,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
            retval = proc.wait()

            if retval != 0:
                logger.error("External check script failed to validate EK")
                while True:
                    line = proc.stdout.readline()
                    if line == "":
                        break
                    logger.debug("ek_check output: %s" % line.strip())
                return False
            else:
                logger.debug(
                    "External check script successfully to validated EK")
                while True:
                    line = proc.stdout.readline()
                    if line == "":
                        break
                    logger.debug("ek_check output: %s" % line.strip())
        return True
Example #6
0
def process_quote_response(instance, json_response, config):
    """Validates the response from the Cloud node.
    
    This method invokes an Registrar Server call to register, and then check the quote. 
    """
    received_public_key = None
    quote = None

    # in case of failure in response content do not continue
    try:
        received_public_key = json_response.get("pubkey", None)
        quote = json_response["quote"]
        ima_measurement_list = json_response.get("ima_measurement_list", None)

        logger.debug("received quote:      %s" % quote)
        logger.debug("for nonce:           %s" % instance['nonce'])
        logger.debug("received public key: %s" % received_public_key)
        logger.debug("received ima_measurement_list    %s" %
                     (ima_measurement_list != None))
    except Exception:
        return None

    # if no public key provided, then ensure we have cached it
    if received_public_key is None:
        if instance.get('public_key', "") == "" or instance.get(
                'b64_encrypted_V', "") == "":
            logger.error(
                "node did not provide public key and no key or encrypted_v was cached at CV"
            )
            return False
        instance['provide_V'] = False
        received_public_key = instance['public_key']

    if instance.get('aikFromRegistrar', "") is "" or instance.get(
            'aikFromRegistrarCacheHits', common.MAX_STALE_REGISTRAR_CACHE
    ) >= common.MAX_STALE_REGISTRAR_CACHE:
        # talk to yourself fool
        registrar_client.serverAuthTLSContext(config, 'cloud_verifier')
        aikFromRegistrar = registrar_client.getAIK(
            config.get("general", "registrar_ip"),
            config.get("general", "registrar_port"), instance['instance_id'])
        if aikFromRegistrar is None:
            logger.warning("AIK not found in registrar, quote not validated")
            return False
        instance['aikFromRegistrar'] = aikFromRegistrar
        instance['aikFromRegistrarCacheHits'] = 0
    else:
        aikFromRegistrar = instance['aikFromRegistrar']
        instance['aikFromRegistrarCacheHits'] += 1

    if not instance['vtpm_policy']:
        validQuote = tpm_quote.check_quote(instance['nonce'],
                                           received_public_key, quote,
                                           aikFromRegistrar,
                                           instance['tpm_policy'],
                                           ima_measurement_list,
                                           instance['ima_whitelist'])
    else:
        registrar_client.serverAuthTLSContext(config, 'cloud_verifier')
        dq_aik = registrar_client.getAIK(
            config.get("general", "provider_registrar_ip"),
            config.get("general", "provider_registrar_port"),
            instance['instance_id'])
        if dq_aik is None:
            logger.warning(
                "provider AIK not found in registrar, deep quote not validated"
            )
            return False
        validQuote = tpm_quote.check_deep_quote(
            instance['nonce'], received_public_key, quote, aikFromRegistrar,
            dq_aik, instance['vtpm_policy'], instance['tpm_policy'],
            ima_measurement_list, instance['ima_whitelist'])
    if not validQuote:
        return False

    # has public key changed? if so, clear out b64_encrypted_V, it is no longer valid
    if received_public_key != instance.get('public_key', ""):
        instance['public_key'] = received_public_key
        instance['b64_encrypted_V'] = ""
        instance['provide_V'] = True

    # ok we're done
    return validQuote