Ejemplo n.º 1
0
def cmd_revoke(workingdir,name=None,serial=None):
    cwd = os.getcwd()
    try:
        common.ch_dir(workingdir,os.getuid()==0)
        priv = read_private()
        
        if name is not None and serial is not None:
            raise Exception("You may not specify a cert and a serial at the same time")
        if name is None and serial is None:
            raise Exception("You must specify a cert or a serial to revoke")
        if name is not None:
            # load up the cert
            cert = X509.load_cert("%s-cert.crt"%name)
            serial = cert.get_serial_number()
            
        #convert serial to string
        serial = str(serial)
            
        # get the ca key cert and keys as strings
        with open('cacert.crt','r') as f:
            cacert = f.read()
        ca_pk = str(priv[0]['ca'])
        
        if serial not in priv[0]['revoked_keys']:
            priv[0]['revoked_keys'].append(serial)
        
        crl = ca_impl.gencrl(priv[0]['revoked_keys'],cacert,ca_pk)
         
        write_private(priv)
        
        return crl
    finally:
        os.chdir(cwd)
    return crl
Ejemplo n.º 2
0
    def test_010_reg_instance_post(self):
        """Test registrar's POST /v2/instances/{UUID} Interface"""
        global keyblob, aik, vtpm, ek

        # Change CWD for TPM-related operations
        cwd = os.getcwdu()
        common.ch_dir(common.WORK_DIR, None)
        secdir = secure_mount.mount()

        # Initialize the TPM with AIK
        (ek, ekcert, aik) = tpm_initialize.init(self_activate=False,
                                                config_pw=config.get(
                                                    'cloud_node',
                                                    'tpm_ownerpassword'))
        vtpm = tpm_initialize.is_vtpm()

        # Seed RNG (root only)
        if common.REQUIRE_ROOT:
            tpm_random.init_system_rand()

        # Handle virtualized and emulated TPMs
        if ekcert is None:
            if vtpm:
                ekcert = 'virtual'
            elif tpm_initialize.is_emulator():
                ekcert = 'emulator'

        # Get back to our original CWD
        common.ch_dir(cwd, None)

        data = {
            'ek': ek,
            'ekcert': ekcert,
            'aik': aik,
        }
        v_json_message = json.dumps(data)

        response = tornado_requests.request(
            "POST",
            "http://%s:%s/v2/instances/%s" %
            (tenant_templ.registrar_ip, tenant_templ.registrar_boot_port,
             tenant_templ.node_uuid),
            data=v_json_message,
            context=None)
        self.assertEqual(response.status_code, 200,
                         "Non-successful Registrar Instance Add return code!")
        response_body = response.json()

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

        keyblob = response_body["results"]["blob"]
        self.assertIsNotNone(keyblob, "Malformed response body!")
Ejemplo n.º 3
0
def cmd_certpkg(workingdir,name,needfile=True):
    cwd = os.getcwd()
    try:
        common.ch_dir(workingdir,os.getuid()==0)
        # zip up the crt, private key, and public key
        
        with open('cacert.crt','r') as f:
            cacert = f.read()
        
        with open("%s-public.pem"%name,'rb') as f:
            pub = f.read()
            
        with open("%s-cert.crt"%name,'rb') as f:
            cert = f.read()
        
        priv = read_private()
        private = priv[0][name]
        
        with open("%s-private.pem"%name,'rb') as f:
            prot_priv = f.read()
        
        #code to create a pem formatted protected private key using the keystore password
    #     pk = EVP.load_key_string(str(priv[0][name]))
    #     f = BIO.MemoryBuffer()
    #     # globalcb will return the global password provided by the user
    #     pk.save_key_bio(f, 'aes_256_cbc', globalcb)
    #     prot_priv = f.getvalue()
    #     f.close()
        
        # no compression to avoid extraction errors in tmpfs
        sf = cStringIO.StringIO()
        with zipfile.ZipFile(sf,'w',compression=zipfile.ZIP_STORED) as f:
            f.writestr('%s-public.pem'%name,pub)
            f.writestr('%s-cert.crt'%name,cert)
            f.writestr('%s-private.pem'%name,private)
            f.writestr('cacert.crt',cacert)
        pkg = sf.getvalue()
        
        # actually output the package to disk with a protected private key
        with zipfile.ZipFile('%s-pkg.zip'%name,'w',compression=zipfile.ZIP_STORED) as f:
            f.writestr('%s-public.pem'%name,pub)
            f.writestr('%s-cert.crt'%name,cert)
            f.writestr('%s-private.pem'%name,prot_priv)
            f.writestr('cacert.crt',cacert)

        logger.info("Creating cert package for %s in %s-pkg.zip"%(name,name))
        
        return pkg
    finally:
        os.chdir(cwd)
Ejemplo n.º 4
0
def cmd_init(workingdir):
    cwd = os.getcwd()
    try:
        common.ch_dir(workingdir, logger)

        rmfiles("*.pem")
        rmfiles("*.crt")
        rmfiles("*.zip")
        rmfiles("*.der")
        rmfiles("private.json")

        cacert, ca_pk, _ = ca_impl.mk_cacert()

        priv = read_private()

        # write out keys
        with open('cacert.crt', 'wb') as f:
            f.write(cacert.as_pem())

        f = BIO.MemoryBuffer()
        ca_pk.save_key_bio(f, None)
        priv[0]['ca'] = f.getvalue()
        f.close()

        # store the last serial number created.
        # the CA is always serial # 1
        priv[0]['lastserial'] = 1

        write_private(priv)

        ca_pk.get_rsa().save_pub_key('ca-public.pem')

        # generate an empty crl
        crl = ca_impl.gencrl([], cacert.as_pem(), str(priv[0]['ca']))
        with open('cacrl.der', 'wb') as f:
            f.write(crl)
        convert_crl_to_pem("cacrl.der", "cacrl.pem")

        # Sanity checks...
        cac = X509.load_cert('cacert.crt')
        if cac.verify():
            logger.info("CA certificate created successfully in %s" %
                        workingdir)
        else:
            logger.error("ERROR: Cert does not self validate")
    finally:
        os.chdir(cwd)
Ejemplo n.º 5
0
def cmd_mkcert(workingdir, name):
    cwd = os.getcwd()
    try:
        common.ch_dir(workingdir, logger)
        priv = read_private()

        cacert = X509.load_cert('cacert.crt')
        ca_pk = EVP.load_key_string(str(priv[0]['ca']))

        cert, pk = ca_impl.mk_signed_cert(cacert, ca_pk, name,
                                          priv[0]['lastserial'] + 1)
        with open('%s-cert.crt' % name, 'w') as f:
            f.write(cert.as_pem())

        f = BIO.MemoryBuffer()
        pk.save_key_bio(f, None)
        priv[0][name] = f.getvalue()
        f.close()

        #increment serial number after successful creation
        priv[0]['lastserial'] += 1

        write_private(priv)

        # write out the private key with password
        with os.fdopen(
                os.open("%s-private.pem" % name, os.O_WRONLY | os.O_CREAT,
                        0600), 'w') as f:
            biofile = BIO.File(f)
            pk.save_key_bio(biofile, 'aes_256_cbc', globalcb)
            biofile.close()

        pk.get_rsa().save_pub_key('%s-public.pem' % name)

        cc = X509.load_cert('%s-cert.crt' % name)

        if cc.verify(cacert.get_pubkey()):
            logger.info("Created certificate for name %s successfully in %s" %
                        (name, workingdir))
        else:
            logger.error("ERROR: Cert does not validate against CA")
Ejemplo n.º 6
0
def cmd_regencrl(workingdir):
    cwd = os.getcwd()
    try:
        common.ch_dir(workingdir,logger)
        priv = read_private()
            
        # get the ca key cert and keys as strings
        with open('cacert.crt','r') as f:
            cacert = f.read()
        ca_pk = str(priv[0]['ca'])
        
        crl = ca_impl.gencrl(priv[0]['revoked_keys'],cacert,ca_pk)
         
        write_private(priv)
        
        # write out the CRL to the disk
        with open('cacrl.der','wb') as f:
            f.write(crl)
        convert_crl_to_pem("cacrl.der","cacrl.pem")
        
    finally:
        os.chdir(cwd)
    return crl
Ejemplo n.º 7
0
def main(argv=sys.argv):
    if os.getuid()!=0 and common.REQUIRE_ROOT:
        logger.critical("This process must be run as root.")
        return

    # get params for initialization
    registrar_ip = config.get('general', 'registrar_ip')
    registrar_port = config.get('general', 'registrar_port')
    
    # initialize the tmpfs partition to store keys if it isn't already available
    secdir = secure_mount.mount()

    # change dir to working dir
    common.ch_dir(common.WORK_DIR,logger)
    
    #initialize tpm 
    (ek,ekcert,aik,ek_tpm,aik_name) = tpm.tpm_init(self_activate=False,config_pw=config.get('cloud_agent','tpm_ownerpassword')) # this tells initialize not to self activate the AIK
    virtual_agent = tpm.is_vtpm()
    
    # try to get some TPM randomness into the system entropy pool
    tpm.init_system_rand()
        
    if ekcert is None:
        if virtual_agent:
            ekcert = 'virtual'
        elif tpm.is_emulator():
            ekcert = 'emulator'
        
    # now we need the UUID
    try:
        agent_uuid = config.get('cloud_agent','agent_uuid')
    except ConfigParser.NoOptionError:
        agent_uuid = None
    if agent_uuid == 'openstack':
        agent_uuid = openstack.get_openstack_uuid()
    elif agent_uuid == 'hash_ek':
        agent_uuid = hashlib.sha256(ek).hexdigest()
    elif agent_uuid == 'generate' or agent_uuid is None:
        agent_uuid = str(uuid.uuid4())
    if common.DEVELOP_IN_ECLIPSE:
        agent_uuid = "C432FBB3-D2F1-4A97-9EF7-75BD81C866E9"
    if common.STUB_VTPM and common.TPM_CANNED_VALUES is not None:
        # Use canned values for stubbing 
        jsonIn = common.TPM_CANNED_VALUES
        if "add_vtpm_to_group" in jsonIn:
            # The value we're looking for has been canned! 
            agent_uuid = jsonIn['add_vtpm_to_group']['retout']
        else:
            # Our command hasn't been canned!
            raise Exception("Command %s not found in canned JSON!"%("add_vtpm_to_group"))
    
    logger.info("Agent UUID: %s"%agent_uuid)
    
    # register it and get back a blob
    keyblob = registrar_client.doRegisterAgent(registrar_ip,registrar_port,agent_uuid,tpm_version,ek,ekcert,aik,ek_tpm,aik_name)
    
    if keyblob is None:
        raise Exception("Registration failed")
    
    # get the ephemeral registrar key
    key = tpm.activate_identity(keyblob)
    
    # tell the registrar server we know the key
    retval=False
    if virtual_agent:
        deepquote = tpm.create_deep_quote(hashlib.sha1(key).hexdigest(),agent_uuid+aik+ek)
        retval = registrar_client.doActivateVirtualAgent(registrar_ip, registrar_port, agent_uuid, deepquote)
    else:
        retval = registrar_client.doActivateAgent(registrar_ip,registrar_port,agent_uuid,key)

    if not retval:
        raise Exception("Registration failed on activate")
    
    serveraddr = ('', config.getint('general', 'cloudagent_port'))
    server = CloudAgentHTTPServer(serveraddr,Handler,agent_uuid)
    serverthread = threading.Thread(target=server.serve_forever)

    logger.info( 'Starting Cloud Agent on port %s use <Ctrl-C> to stop'%serveraddr[1])
    serverthread.start()
    
    # want to listen for revocations?
    if config.getboolean('cloud_agent','listen_notfications'):
        cert_path = config.get('cloud_agent','revocation_cert')
        if cert_path == "default":
            cert_path = '%s/unzipped/RevocationNotifier-cert.crt'%(secdir)
        elif cert_path[0]!='/':
            # if it is a relative, convert to absolute in work_dir
            cert_path = os.path.abspath('%s/%s'%(common.WORK_DIR,cert_path))
            
        def perform_actions(revocation):
            actionlist = []
            
            # load the actions from inside the keylime module
            actionlisttxt = config.get('cloud_agent','revocation_actions')
            if actionlisttxt.strip() != "":
                actionlist = actionlisttxt.split(',')
                actionlist = ["revocation_actions.%s"%i for i in actionlist]
                
            # load actions from unzipped
            if os.path.exists("%s/unzipped/action_list"%secdir):
                with open("%s/unzipped/action_list"%secdir,'r') as f:
                    actionlisttxt = f.read()
                if actionlisttxt.strip()!="":
                    localactions = actionlisttxt.strip().split(',')
                    for action in localactions:
                        if not action.startswith('local_action_'):
                            logger.warning("invalid local action: %s.  must start with local_action_"%action)
                        else:
                            actionlist.append(action)
                    
                    uzpath = "%s/unzipped"%secdir
                    if uzpath not in sys.path:
                        sys.path.append(uzpath)

            for action in actionlist:
                logger.debug("executing revocation action %s"%action)
                try:
                    module = importlib.import_module(action)
                    execute = getattr(module,'execute')
                    execute(revocation)
                except Exception as e:
                    logger.warn("Exception during execution of revocation action %s: %s"%(action,e))
        try:
            while True:
                try:
                    revocation_notifier.await_notifications(perform_actions,revocation_cert_path=cert_path)
                except Exception as e:
                    logger.exception(e)
                    logger.warn("No connection to revocation server, retrying in 10s...")
                    time.sleep(10)
        except KeyboardInterrupt:
            logger.info("TERM Signal received, shutting down...")
            tpm.flush_keys()
            server.shutdown()
    else:  
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            logger.info("TERM Signal received, shutting down...")
            tpm.flush_keys()
            server.shutdown()
Ejemplo n.º 8
0
def cmd_certpkg(workingdir,name,insecure=False):
    cwd = os.getcwd()
    try:
        common.ch_dir(workingdir,logger)
        # zip up the crt, private key, and public key
        
        with open('cacert.crt','r') as f:
            cacert = f.read()
        
        with open("%s-public.pem"%name,'rb') as f:
            pub = f.read()
            
        with open("%s-cert.crt"%name,'rb') as f:
            cert = f.read()
            
        with open('cacrl.der','r') as f:
            crl = f.read()
        
        with open('cacrl.pem','r') as f:
            crlpem = f.read()
        
        cert_obj = X509.load_cert_string(cert)
        serial = cert_obj.get_serial_number()
        subject = str(cert_obj.get_subject())
        
        priv = read_private()
        private = priv[0][name]
        
        with open("%s-private.pem"%name,'rb') as f:
            prot_priv = f.read()
        
        #code to create a pem formatted protected private key using the keystore password
    #     pk = EVP.load_key_string(str(priv[0][name]))
    #     f = BIO.MemoryBuffer()
    #     # globalcb will return the global password provided by the user
    #     pk.save_key_bio(f, 'aes_256_cbc', globalcb)
    #     prot_priv = f.getvalue()
    #     f.close()
        
        # no compression to avoid extraction errors in tmpfs
        sf = cStringIO.StringIO()
        with zipfile.ZipFile(sf,'w',compression=zipfile.ZIP_STORED) as f:
            f.writestr('%s-public.pem'%name,pub)
            f.writestr('%s-cert.crt'%name,cert)
            f.writestr('%s-private.pem'%name,private)
            f.writestr('cacert.crt',cacert)
            f.writestr('cacrl.der',crl)
            f.writestr('cacrl.pem',crlpem)
        pkg = sf.getvalue()
        
        if insecure:
            logger.warn("Unprotected private keys in cert package being written to disk")
            with open('%s-pkg.zip'%name,'w') as f:
                f.write(pkg)
        else:
            # actually output the package to disk with a protected private key
            with zipfile.ZipFile('%s-pkg.zip'%name,'w',compression=zipfile.ZIP_STORED) as f:
                f.writestr('%s-public.pem'%name,pub)
                f.writestr('%s-cert.crt'%name,cert)
                f.writestr('%s-private.pem'%name,prot_priv)
                f.writestr('cacert.crt',cacert)
                f.writestr('cacrl.der',crl)
                f.writestr('cacrl.pem',crlpem)

        logger.info("Creating cert package for %s in %s-pkg.zip"%(name,name))
        
        return pkg,serial,subject
    finally:
        os.chdir(cwd)
Ejemplo n.º 9
0
def main(argv=sys.argv):
    if os.getuid() != 0 and not common.DEVELOP_IN_ECLIPSE:
        logger.critical("This process must be run as root.")
        return

    # get params for initialization
    registrar_ip = config.get('general', 'registrar_ip')
    registrar_port = config.get('general', 'registrar_port')

    # initialize the tmpfs partition to store keys if it isn't already available
    secure_mount.mount()

    # change dir to working dir
    common.ch_dir()

    #initialize tpm
    (ek, ekcert, aik) = tpm_initialize.init(
        self_activate=False,
        config_pw=config.get('cloud_node', 'tpm_ownerpassword')
    )  # this tells initialize not to self activate the AIK
    virtual_node = tpm_initialize.is_vtpm()

    if common.STUB_TPM:
        ekcert = common.TEST_EK_CERT

    if virtual_node and (ekcert is None or common.STUB_TPM):
        ekcert = 'virtual'

    # now we need the UUID
    try:
        node_uuid = config.get('cloud_node', 'node_uuid')
    except ConfigParser.NoOptionError:
        node_uuid = None
    if node_uuid == 'openstack':
        node_uuid = openstack.get_openstack_uuid()
    elif node_uuid == 'hash_ek':
        node_uuid = hashlib.sha256(ek).hexdigest()
    elif node_uuid == 'generate' or node_uuid is None:
        node_uuid = str(uuid.uuid4())
    if common.DEVELOP_IN_ECLIPSE:
        node_uuid = "C432FBB3-D2F1-4A97-9EF7-75BD81C866E9"

    # use an TLS context with no certificate checking
    registrar_client.noAuthTLSContext(config)

    # register it and get back a blob
    keyblob = registrar_client.doRegisterNode(registrar_ip, registrar_port,
                                              node_uuid, ek, ekcert, aik)

    if keyblob is None:
        raise Exception("Registration failed")

    # get the ephemeral registrar key
    key = tpm_initialize.activate_identity(keyblob)

    # tell the registrar server we know the key
    if virtual_node:
        deepquote = tpm_quote.create_deep_quote(
            hashlib.sha1(key).hexdigest(), node_uuid + aik + ek)
        registrar_client.doActivateVirtualNode(registrar_ip, registrar_port,
                                               node_uuid, deepquote)
    else:
        registrar_client.doActivateNode(registrar_ip, registrar_port,
                                        node_uuid, key)

    serveraddr = ('', config.getint('general', 'cloudnode_port'))
    server = CloudNodeHTTPServer(serveraddr, Handler, node_uuid)

    thread = threading.Thread(target=server.serve_forever)

    threads = []
    servers = []

    threads.append(thread)
    servers.append(server)

    # start the server
    logger.info('Starting Cloud Node on port %s use <Ctrl-C> to stop' %
                serveraddr[1])
    for thread in threads:
        thread.start()

    def signal_handler(signal, frame):
        do_shutdown(servers)
        sys.exit(0)

    # Catch these signals.  Note that a SIGKILL cannot be caught, so
    # killing this process with "kill -9" may result in improper shutdown
    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGQUIT, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)

    # keep the main thread active, so it can process the signals and gracefully shutdown
    while True:
        if not any([thread.isAlive() for thread in threads]):
            # All threads have stopped
            break
        else:
            # Some threads are still going
            time.sleep(1)

    for thread in threads:
        thread.join()