コード例 #1
0
ファイル: test_restful.py プロジェクト: ozoder/keylime
    def test_023_agent_keys_vkey_post(self):
        """Test agent's POST /v2/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
        global public_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
                }
        v_json_message = json.dumps(data)

        response = tornado_requests.request(
                                            "POST", "http://%s:%s/v%s/keys/vkey"%(tenant_templ.cloudagent_ip,tenant_templ.cloudagent_port,self.api_version),
                                            data=v_json_message
                                        )
        self.assertEqual(response.status_code, 200, "Non-successful Agent vkey post return code!")
        response_body = response.json()

        # Ensure response is well-formed
        self.assertIn("results", response_body, "Malformed response body!")
コード例 #2
0
ファイル: test_restful.py プロジェクト: ozoder/keylime
    def test_024_agent_keys_ukey_post(self):
        """Test agents's POST /v2/keys/ukey Interface"""
        global public_key

        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),str(self.U))
        b64_encrypted_u = base64.b64encode(encrypted_U)
        data = {
                  'encrypted_key': b64_encrypted_u,
                  'auth_tag': self.auth_tag,
                  'payload': self.payload
                }
        u_json_message = json.dumps(data)

        response = tornado_requests.request(
                                            "POST", "http://%s:%s/v%s/keys/ukey"%(tenant_templ.cloudagent_ip,tenant_templ.cloudagent_port,self.api_version),
                                            data=u_json_message
                                        )
        self.assertEqual(response.status_code, 200, "Non-successful Agent ukey post return code!")
        response_body = response.json()

        # Ensure response is well-formed
        self.assertIn("results", response_body, "Malformed response body!")
コード例 #3
0
def await_notifications(callback,revocation_cert_path):
    global cert_key
    
    if revocation_cert_path is None:
        raise Exception("must specify revocation_cert_path")
    
    context = zmq.Context()
    mysock = context.socket(zmq.SUB)
    mysock.setsockopt(zmq.SUBSCRIBE, '')
    mysock.connect("tcp://%s:%s"%(config.get('general','revocation_notifier_ip'),config.getint('general','revocation_notifier_port')))
    
    logger.info('Waiting for revocation messages on 0mq %s:%s'%
                (config.get('general','revocation_notifier_ip'),config.getint('general','revocation_notifier_port')))
    
    while True:
        rawbody = mysock.recv()
        body = json.loads(rawbody)
        if cert_key is None:
            # load up the CV signing public key
            if revocation_cert_path is not None and os.path.exists(revocation_cert_path):
                logger.info("Lazy loading the revocation certificate from %s"%revocation_cert_path)
                with open(revocation_cert_path,'r') as f:
                    certpem = f.read()
                cert_key = crypto.rsa_import_pubkey(certpem)
        
        if cert_key is None:
            logger.warning("Unable to check signature of revocation message: %s not available"%revocation_cert_path)
        elif str(body['signature'])=='none':
            logger.warning("No signature on revocation message from server")
        elif not crypto.rsa_verify(cert_key,str(body['msg']),str(body['signature'])):
            logger.error("Invalid revocation message siganture %s"%body)
        else:
            message = json.loads(body['msg'])
            logger.debug("Revocation signature validated for revocation: %s"%message)
            callback(message)
コード例 #4
0
def prepare_v(agent):
    # be very careful printing K, U, or V as they leak in logs stored on unprotected disks
    if common.INSECURE_DEBUG:
        logger.debug("b64_V (non encrypted): " + agent['v'])
        
    if agent.get('b64_encrypted_V',"") !="":
        b64_encrypted_V = agent['b64_encrypted_V']
        logger.debug("Re-using cached encrypted V")
    else:
        # encrypt V with the public key
        b64_encrypted_V = base64.b64encode(crypto.rsa_encrypt(crypto.rsa_import_pubkey(agent['public_key']),str(base64.b64decode(agent['v']))))
        agent['b64_encrypted_V'] = b64_encrypted_V
        
    logger.debug("b64_encrypted_V:" + b64_encrypted_V)
    post_data = {
              'encrypted_key': b64_encrypted_V
            }
    v_json_message = json.dumps(post_data)
    return v_json_message
コード例 #5
0
def prepare_v(instance):
    # be very careful printing K, U, or V as they leak in logs stored on unprotected disks
    if common.DEVELOP_IN_ECLIPSE:
        logger.debug("b64_V (non encrypted): " + instance['v'])

    if instance.get('b64_encrypted_V', "") != "":
        b64_encrypted_V = instance['b64_encrypted_V']
        logger.debug("Re-using cached encrypted V")
    else:
        # encrypt V with the public key
        b64_encrypted_V = base64.b64encode(
            crypto.rsa_encrypt(
                crypto.rsa_import_pubkey(instance['public_key']),
                str(base64.b64decode(instance['v']))))
        instance['b64_encrypted_V'] = b64_encrypted_V

    logger.debug("b64_encrypted_V:" + b64_encrypted_V)
    post_data = {'encrypted_key': b64_encrypted_V}
    v_json_message = json.dumps(post_data)
    return v_json_message
コード例 #6
0
    def do_quote(self):
        """initiaite v, instance_id and ip
        initiate the cloudinit sequence"""
        self.nonce = tpm_initialize.random_password(20)

        params = {
            'nonce': self.nonce,
        }

        numtries = 0
        while True:
            try:
                response = tornado_requests.request(
                    "GET",
                    "http://%s:%s/v1/quotes/tenant" %
                    (self.cloudnode_ip, self.cloudnode_port),
                    params=params)
            except Exception as e:
                # this is one exception that should return a 'keep going' response
                if tornado_requests.is_refused(e):
                    numtries += 1
                    maxr = config.getint('tenant', 'max_retries')
                    if numtries >= maxr:
                        logger.error(
                            "Quiting after max number of retries to connect to %s"
                            % (self.cloudnode_ip))
                        raise e
                    retry = config.getfloat('tenant', 'retry_interval')
                    logger.info(
                        "Connection to %s refused %d/%d times, trying again in %f seconds..."
                        % (self.cloudnode_ip, numtries, maxr, retry))
                    time.sleep(retry)
                    continue
                else:
                    raise e

            if response.status_code == 200:
                response_body = response.json()

                public_key = response_body["pubkey"]
                logger.debug("cnquote received public key:" + public_key)
                quote = response_body["quote"]
                logger.debug("cnquote received quote:" + quote)

                if self.validate_tpm_quote(public_key, quote):
                    logger.info("Quote from %s validated" % self.cloudnode_ip)
                    # encrypt U with the public key
                    encrypted_U = crypto.rsa_encrypt(
                        crypto.rsa_import_pubkey(public_key), str(self.U))

                    b64_encrypted_u = base64.b64encode(encrypted_U)
                    logger.debug("b64_encrypted_u: " + b64_encrypted_u)
                    data = {
                        'encrypted_key': b64_encrypted_u,
                        'auth_tag': self.auth_tag
                    }

                    if self.payload is not None:
                        data['payload'] = self.payload

                    u_json_message = json.dumps(data)

                    #post encrypted U back to CloudNode
                    response = tornado_requests.request(
                        "POST",
                        "http://%s:%s/v1/quotes/tenant" %
                        (self.cloudnode_ip, self.cloudnode_port),
                        data=u_json_message)

                    if response.status_code != 200:
                        logger.error(
                            "Posting of Encrypted U to the Cloud Node failed with response code %d"
                            % response.status_code)
                        break

                else:
                    logger.error(
                        "TPM Quote from cloud node is invalid for nonce: %s" %
                        self.nonce)
                    break
            else:
                logger.error(
                    "Status command response: %d Unexpected response from Cloud Node."
                    % response.status_code)
                break
            break
コード例 #7
0
ファイル: tenant.py プロジェクト: ozoder/keylime
    def do_quote(self):
        """initiaite v, agent_id and ip
        initiate the cloudinit sequence"""
        self.nonce = TPM_Utilities.random_password(20)

        numtries = 0
        response = None
        while True:
            # Get quote
            try:
                response = tornado_requests.request(
                    "GET", "http://%s:%s/quotes/identity?nonce=%s" %
                    (self.cloudagent_ip, self.cloudagent_port, self.nonce))
            except Exception as e:
                # this is one exception that should return a 'keep going' response
                if tornado_requests.is_refused(e):
                    numtries += 1
                    maxr = config.getint('tenant', 'max_retries')
                    if numtries >= maxr:
                        raise UserError(
                            "Quitting after max number of retries to connect to %s"
                            % (self.cloudagent_ip))
                    retry = config.getfloat('tenant', 'retry_interval')
                    logger.info(
                        "Connection to %s refused %d/%d times, trying again in %f seconds..."
                        % (self.cloudagent_ip, numtries, maxr, retry))
                    time.sleep(retry)
                    continue
                else:
                    raise e
            break

        try:
            if response is not None and response.status_code != 200:
                raise UserError(
                    "Status command response: %d Unexpected response from Cloud Agent."
                    % response.status_code)

            response_body = response.json()

            if "results" not in response_body:
                raise UserError(
                    "Error: unexpected http response body from Cloud Agent: %s"
                    % str(response.status_code))

            quote = response_body["results"]["quote"]
            logger.debug("agent_quote received quote:" + quote)

            public_key = response_body["results"]["pubkey"]
            logger.debug("agent_quote received public key:" + public_key)

            # Get tpm_version, hash_alg
            tpm_version = response_body["results"]["tpm_version"]
            logger.debug("agent_quote received tpm version:" +
                         str(tpm_version))

            # Ensure hash_alg is in accept_tpm_hash_algs list
            hash_alg = response_body["results"]["hash_alg"]
            logger.debug("agent_quote received hash algorithm:" + hash_alg)
            if not Hash_Algorithms.is_accepted(
                    hash_alg,
                    config.get('tenant', 'accept_tpm_hash_algs').split(',')):
                raise UserError(
                    "TPM Quote is using an unaccepted hash algorithm: %s" %
                    hash_alg)

            # Ensure enc_alg is in accept_tpm_encryption_algs list
            enc_alg = response_body["results"]["enc_alg"]
            logger.debug("agent_quote received encryption algorithm:" +
                         enc_alg)
            if not Encrypt_Algorithms.is_accepted(
                    enc_alg,
                    config.get('tenant',
                               'accept_tpm_encryption_algs').split(',')):
                raise UserError(
                    "TPM Quote is using an unaccepted encryption algorithm: %s"
                    % enc_alg)

            # Ensure sign_alg is in accept_tpm_encryption_algs list
            sign_alg = response_body["results"]["sign_alg"]
            logger.debug("agent_quote received signing algorithm:" + sign_alg)
            if not Sign_Algorithms.is_accepted(
                    sign_alg,
                    config.get('tenant',
                               'accept_tpm_signing_algs').split(',')):
                raise UserError(
                    "TPM Quote is using an unaccepted signing algorithm: %s" %
                    sign_alg)

            if not self.validate_tpm_quote(public_key, quote, tpm_version,
                                           hash_alg):
                raise UserError(
                    "TPM Quote from cloud agent is invalid for nonce: %s" %
                    self.nonce)

            logger.info("Quote from %s validated" % self.cloudagent_ip)

            # encrypt U with the public key
            encrypted_U = crypto.rsa_encrypt(
                crypto.rsa_import_pubkey(public_key), str(self.U))

            b64_encrypted_u = base64.b64encode(encrypted_U)
            logger.debug("b64_encrypted_u: " + b64_encrypted_u)
            data = {
                'encrypted_key': b64_encrypted_u,
                'auth_tag': self.auth_tag
            }

            if self.payload is not None:
                data['payload'] = self.payload

            u_json_message = json.dumps(data)

            #post encrypted U back to CloudAgent
            response = tornado_requests.request(
                "POST",
                "http://%s:%s/keys/ukey" %
                (self.cloudagent_ip, self.cloudagent_port),
                data=u_json_message)

            if response.status_code != 200:
                common.log_http_response(logger, logging.ERROR, response_body)
                raise UserError(
                    "Posting of Encrypted U to the Cloud Agent failed with response code %d"
                    % response.status_code)

        except Exception as e:
            self.do_cvstop()
            raise e
コード例 #8
0
def get_mod_from_pem(pem):
    pubkey = crypto.rsa_import_pubkey(pem)
    return base64.b64encode(bytearray.fromhex('{:0192x}'.format(pubkey.n)))
コード例 #9
0
def get_mod_from_pem(pemfile):
    with open(pemfile, "r") as f:
        pem = f.read()
    pubkey = crypto.rsa_import_pubkey(pem)
    return base64.b64encode(bytearray.fromhex('{:0192x}'.format(pubkey.n)))