<commit_before>'''
DISTRIBUTION STATEMENT A. Approved for public release: distribution unlimited.

This material is based upon work supported by the Assistant Secretary of Defense for
Research and Engineering under Air Force Contract No. FA8721-05-C-0002 and/or
FA8702-15-D-0001. Any opinions, findings, conclusions or recommendations expressed in this
material are those of the author(s) and do not necessarily reflect the views of the
Assistant Secretary of Defense for Research and Engineering.

Copyright 2016 Massachusetts Institute of Technology.

The software/firmware is provided to you on an As-Is basis

Delivered to the US Government with Unlimited Rights, as defined in DFARS Part
252.227-7013 or 7014 (Feb 2014). Notwithstanding any copyright notice, U.S. Government
rights in this work are defined by DFARS 252.227-7013 or DFARS 252.227-7014 as detailed
above. Use of this work other than as specifically authorized by the U.S. Government may
violate any copyrights that exist in this work.
'''

import base64
import configparser
import os
import subprocess
import socket
import time
import requests

try:
    import simplejson as json
except ImportError:
    raise("Simplejson is mandatory, please install")

from keylime import common
from keylime import  keylime_logging
from keylime import secure_mount
from M2Crypto import EVP, X509

logger = keylime_logging.init_logging('ca_impl_cfssl')

config = configparser.ConfigParser()
config.read(common.CONFIG_FILE)

cfssl_ip = config.get('general', 'cfssl_ip')
cfssl_port = config.get('general', 'cfssl_port')

cfsslproc = None

def post_cfssl(params,data):
    numtries = 0
    maxr = 10
    retry=0.05
    while True:
        try:
            response = requests.post("http://%s:%s/%s"%(cfssl_ip, cfssl_port,params), json=data, timeout=1)
            break
        except requests.exceptions.ConnectionError as e:
            numtries+=1
            if numtries >= maxr:
                logger.error("Quiting after max number of retries to connect to cfssl server")
                raise e
            logger.info("Connection to cfssl refused %d/%d times, trying again in %f seconds..."%(numtries,maxr,retry))
            time.sleep(retry)
            continue

    if response.status_code!=200:
        raise Exception("Unable to issue CFSSL API command %s: %s"%(params,response.text))
    return response.json()

def start_cfssl(cmdline=""):
    global cfsslproc
    cmd = "cfssl serve -loglevel=1 %s "%cmdline
    env = os.environ.copy()
    env['PATH']=env['PATH']+":/usr/local/bin"

    # make sure cfssl isn't running
    os.system('pkill -f cfssl')

    cfsslproc = subprocess.Popen(cmd,env=env,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,universal_newlines=True)
    if cfsslproc.returncode is not None:
        raise Exception("Unable to launch %: failed with code "%(cmd,cfsslproc.returncode))

    logger.debug("Waiting for cfssl to start...")
    while True:
        line = cfsslproc.stdout.readline()
        if "Now listening on" in line:
            break
    time.sleep(0.2)# give cfssl a little more time to get started
    logger.debug("cfssl started successfully")

def stop_cfssl():
    global cfsslproc
    if cfsslproc is not None:
        cfsslproc.kill()
        os.system("pkill -f cfssl")
        cfsslproc = None

def mk_cacert():
    csr = {"CN": config.get('ca','cert_ca_name'),
           "key": {<commit_msg>warn if cfssl binary is not found<commit_after>'''
DISTRIBUTION STATEMENT A. Approved for public release: distribution unlimited.

This material is based upon work supported by the Assistant Secretary of Defense for
Research and Engineering under Air Force Contract No. FA8721-05-C-0002 and/or
FA8702-15-D-0001. Any opinions, findings, conclusions or recommendations expressed in this
material are those of the author(s) and do not necessarily reflect the views of the
Assistant Secretary of Defense for Research and Engineering.

Copyright 2016 Massachusetts Institute of Technology.

The software/firmware is provided to you on an As-Is basis

Delivered to the US Government with Unlimited Rights, as defined in DFARS Part
252.227-7013 or 7014 (Feb 2014). Notwithstanding any copyright notice, U.S. Government
rights in this work are defined by DFARS 252.227-7013 or DFARS 252.227-7014 as detailed
above. Use of this work other than as specifically authorized by the U.S. Government may
violate any copyrights that exist in this work.
'''

import base64
import configparser
import os
import subprocess
import socket
import time
import requests
import shutil
import sys

try:
    import simplejson as json
except ImportError:
    raise("Simplejson is mandatory, please install")

from keylime import common
from keylime import  keylime_logging
from keylime import secure_mount
from M2Crypto import EVP, X509

logger = keylime_logging.init_logging('ca_impl_cfssl')

config = configparser.ConfigParser()
config.read(common.CONFIG_FILE)

cfssl_ip = config.get('general', 'cfssl_ip')
cfssl_port = config.get('general', 'cfssl_port')

cfsslproc = None

def post_cfssl(params,data):
    numtries = 0
    maxr = 10
    retry=0.05
    while True:
        try:
            response = requests.post("http://%s:%s/%s"%(cfssl_ip, cfssl_port,params), json=data, timeout=1)
            break
        except requests.exceptions.ConnectionError as e:
            numtries+=1
            if numtries >= maxr:
                logger.error("Quiting after max number of retries to connect to cfssl server")
                raise e
            logger.info("Connection to cfssl refused %d/%d times, trying again in %f seconds..."%(numtries,maxr,retry))
            time.sleep(retry)
            continue

    if response.status_code!=200:
        raise Exception("Unable to issue CFSSL API command %s: %s"%(params,response.text))
    return response.json()

def start_cfssl(cmdline=""):
    if shutil.which("cfssl") is None:
        logger.error("cfssl binary not found in the path.  Please install cfssl or change the setting \"ca_implementation\" in keylime.conf")
        sys.exit(1)
    global cfsslproc
    cmd = "cfssl serve -loglevel=1 %s "%cmdline
    env = os.environ.copy()
    env['PATH']=env['PATH']+":/usr/local/bin"

    # make sure cfssl isn't running
    os.system('pkill -f cfssl')

    cfsslproc = subprocess.Popen(cmd,env=env,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,universal_newlines=True)
    if cfsslproc.returncode is not None:
        raise Exception("Unable to launch %: failed with code "%(cmd,cfsslproc.returncode))

    logger.debug("Waiting for cfssl to start...")
    while True:
        line = cfsslproc.stdout.readline()
        if "Now listening on" in line:
            break
    time.sleep(0.2)# give cfssl a little more time to get started
    logger.debug("cfssl started successfully")

def stop_cfssl():
    global cfsslproc
    if cfsslproc is not None:
        cfsslproc.kill()
        os.system("pkill -f cfssl")
        cfsslproc = None

def mk_cacert():
    csr = {"CN": config.get('ca','cert_ca_name'),
           "key": {
{'fraction_non_alphanumeric': 0.0892277283636877, 'fraction_numerical': 0.023295213892418468, 'mean_word_length': 3.4413793103448276, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4789434', 'n_tokens_mistral': 2208, 'n_tokens_neox': 2062, 'n_words': 730}