def discover_openSSL_implementation(self):
     logger.debug("Beginning discovery of openssl implementation")
     logger.debug("Looking for openssl binary")
     openssl_binaries = self.which_cmd('openssl')
     if len(openssl_binaries)>0:
         logger.debug("Found OpenSSL binary at {0}".format(openssl_binaries[0]))
         import openssl_binary_implementation as openssl_impl
         if sys.platform!='linux2':
             openssl_impl.openssl_binary_path=self.relative_path_to_packaged_openssl_binary
         else:
             openssl_impl.openssl_binary_path=openssl_binaries[0]
         if 'OPENSSL_DIR' in os.environ:
             if sys.platform!='linux2':
                 openssl_impl.openssl_binary_path=os.path.join(os.environ['OPENSSL_DIR'],'openssl.exe')
             else:
                 openssl_impl.openssl_binary_path=os.path.join(os.environ['OPENSSL_DIR'],'openssl')
         openssl_impl.ccm_crypto_path=self.relative_path_to_packaged_ccm_binary
         openssl_impl.cbc_crypto_path=self.relative_path_to_packaged_cbc_binary
     else:
         try:
             logger.debug("Looking for M2Crypto")
             import M2Crypto as openssl_impl
         except ImportError:
             logger.debug("Could not find M2Crypto module")
             logger.critical("Could not find OpenSSL Implementation")
             raise RuntimeError("Could not find OpenSSL Implementation")
     return openssl_impl
def split_certificate_blob_into_certs(certificate_blob):
    """ Split a binary certificate chain blob into single binary certificates

    input:
    certificate_blob: String containing the entire certificate blob

    output:
    [cert1, cert2, ...]
    List of individual certificates found in the blob

    This function looks for a pattern ('0\x82.{2}0\x82') that marks the beginning of all certs, and splits the
    blob on these markers.

    """
    offsets=[]
    certificates_list=[]
    certificate_start_pattern = r'0\x82.{2}0\x82'
    for matches in re.finditer(certificate_start_pattern, certificate_blob):
        offsets.append(matches.start())

    logger.debug("Offsets:" + repr(offsets))
    for index, offset_val in enumerate(offsets):
        start_offset = offset_val
        if index < len(offsets)-1:
            end_offset = offsets[index+1]
        else:
            end_offset = None
        certificate = certificate_blob[start_offset:end_offset]
        certificates_list.append(certificate)

    return certificates_list
 def chipsets(self):
     """(list[str]) List of chipset names supported by the configs in the
     config dir.
     """
     chipsets = []
     for config in self.configs:
         chipsets.append(config.chipset)
     logger.debug('Chipsets found from the configs: ' + str(chipsets))
     return chipsets
def _get_subject_string_from_certificate_params(certificate_params):
    subject_list=[]
    for key in certificate_params:
        if type(certificate_params[key])==list:
            for item in certificate_params[key]:
                subject_list.append(key + '=' + item)
            continue
        subject_list.append(key + "=" + certificate_params[key])
    logger.debug("Subject List = " + repr(subject_list))
    subject_string = r'/'+r"/".join(subject_list)
    logger.debug("Subject String = " + subject_string)
    return subject_string
    def get_chipset_config_path(self, chipset):
        """
        :param str chipset: chipset to return config file for
        :returns: config path corresponding to the given chipset
        :rtype: str
        """
        logger.debug('Searching configs corresponding to chipset: ' + chipset)
        chipset_dir = c_path.join(self.config_dir, chipset)

        if c_path.validate_dir(chipset_dir):
            return self._get_config_path(chipset_dir)
        raise RuntimeError('Did not find config for chipset: "' + chipset + '"')
    def transfer_from_obj(self, obj):
        """Updates the values of the config root node using the attributes of
        the object provided.

        :param Cfg_Secimage obj: Object to be used for obtaining the values.
        """
        assert isinstance(obj, self.obj_module.Cfg_Secimage)
        logger.debug('Updating config contents using object: ' + obj)
        self.root = self.transfer_from_obj_to_node(obj,
                                                   self.root,
                                                   defines.CONFIG_STRUCTURE,
                                                   defines.ROOTNODE_NAME)
        logger.debug('Config contents updated.')
    def transfer_to_obj(self, obj):
        """Updates the attributes of the object provided using the values of the
        root config node.

        :params: same as :meth:`transfer_from_obj`
        """
        assert isinstance(obj, self.obj_module.Cfg_Secimage)
        logger.debug('Updating object using config contents: ' + obj)
        obj = self.transfer_from_node_to_obj(self.root,
                                             obj,
                                             defines.CONFIG_STRUCTURE,
                                             defines.ROOTNODE_NAME,)
        logger.debug('Object updated using the config.')
    def qcom_hmac(self, data, hmac_params):
        if data == None or hmac_params == None:
            raise RuntimeError('Input parameters to the HMAC function are incorrect')
        else:
            msm_id = hmac_params.MSM_ID
            sw_id = hmac_params.SW_ID
            ipad = 0x3636363636363636
            opad = 0x5C5C5C5C5C5C5C5C
            logger.debug("MSM_ID key : " + repr(msm_id))
            logger.debug("SW_ID key : " + repr(sw_id))
            logger.debug("ipad : " + repr(ipad))
            logger.debug("opad : " + repr(opad))
            Si = sw_id ^ ipad
            Si = binascii.unhexlify(format(Si,'x'))
            So = msm_id ^ opad
            So = binascii.unhexlify(format(So,'x'))
            msg_step1 = hashlib.sha256(data).hexdigest()
            msg_step1_bin = binascii.a2b_hex(msg_step1)
            logger.debug2("H(code image) : " + msg_step1)
            msg_step2 = hashlib.sha256(Si + msg_step1_bin).hexdigest()
            msg_step2_bin = binascii.a2b_hex(msg_step2)
            logger.debug2("H[(SWID^ipad) || H(code image)] : " + msg_step2)
            msg_step3 = hashlib.sha256(So + msg_step2_bin).hexdigest()
            msg_step3_bin = binascii.a2b_hex(msg_step3)
            logger.debug2("H[(MSMID^opad) || H[(SWID^ipad) || H(code image)]] : " + msg_step3)

            hmac = msg_step3_bin
            return hmac
def verify_certificate_chain(certificate_chain):
    """ Verify the certificate chain to be valid

    input:
    certificate_chain: [cert1,cert2,cert3]
    List of certificates (*in PEM FORMAT*) in the certificate chain. It assumes that the last certificate is the Root CA certificate.

    output:
    [True|False]
    Boolean value
    """
    CAfile_contents = _create_CAfile_contents_from_cert_chain(certificate_chain)

    CAfile_tempfile_name=utility_functions.store_data_to_temp_file(CAfile_contents)

    level1_cert_to_verify_contents = certificate_chain[0]

    level1_cert_to_verify_tempfile_name=utility_functions.store_data_to_temp_file(level1_cert_to_verify_contents)
    try:
        verify_level1_cert_command_out = utility_functions.system_command_logged([openssl_binary_path, 'verify', '-CAfile', CAfile_tempfile_name, level1_cert_to_verify_tempfile_name])
    except:
        logger.critical("verify_certificate_chain: OPENSSL could not verify cert chain")
    logger.debug("OpenSSL verify command output: " + verify_level1_cert_command_out)
    logger.debug("Deleting temporary files: " + CAfile_tempfile_name +", " + level1_cert_to_verify_tempfile_name)
    os.unlink(CAfile_tempfile_name)
    os.unlink(level1_cert_to_verify_tempfile_name)

    if verify_level1_cert_command_out.rstrip() == level1_cert_to_verify_tempfile_name + ": OK":
        logger.debug("The certificate chain is verified")
        return True
    else:
        logger.debug("The certificate chain is not verified")
        return False
    def sign(self, signingpackage_fname, outputdir):
        signaturepackage_binary = None
        cmds = self._getCmds(signingpackage_fname, outputdir)
        cass_server = self.cass_signer_attributes.server.host if self.cass_signer_attributes.server else "default CASS server"
        logger.info("Connecting to {0}".format(cass_server))
        output = self._executeCmds(cmds)
        logger.debug(output)
        signaturepackage_filepath = os.path.join(outputdir, self.SIGNATUREPACKPAGE_RELPATH)
        if os.path.isfile(signaturepackage_filepath):
            logger.info("Signature package retrieved from server.")
            signaturepackage_binary = c_misc.load_data_from_file(signaturepackage_filepath)

            #clean up
            path, filename = os.path.split(signaturepackage_filepath)
            shutil.rmtree(path)
        return signaturepackage_binary
def get_public_key_from_certificate(certificate):
    if 'BEGIN CERTIFICATE' not in certificate:
        certificate = cert_der_to_pem(certificate)



    pubkey=_extract_public_key_from_certificate(certificate)
    pubkey_file_name=utility_functions.store_data_to_temp_file(pubkey)
    command_list=[openssl_binary_path,'rsa','-pubin','-inform','PEM','-text','-noout','<',pubkey_file_name]
    logger.debug("Command_list = " + repr(command_list))

    pubkey_text = utility_functions.system_command_logged(command_list, stderr_to_temp=True)
    logger.debug2("Pubkey text: " + pubkey_text)


    os.unlink(pubkey_file_name)
    def _generate_signing_package(self, hash_to_sign, signing_attributes, cass_signer_attributes,
                                image_path, signingpackage_fname, binary_to_sign):

        signingpackage = SigningPackage(secimage.__version__)
        signingrequest = signingpackage.createSigningRequest("image_to_sign=%s" % image_path)

        hexbindigest = binascii.b2a_hex(hash_to_sign)
        logger.debug("Digest to sign (hexbinary)= [%s]" % hexbindigest)
        signingrequest.setDigest(hexbindigest)
        signingrequest.setCapability(cass_signer_attributes.capability)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_SW_SIZE, "0x%.8X" % len(binary_to_sign))

        hmac_params = signerutils.get_hmac_params_from_config(signing_attributes)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_HW_ID, "0x%s" % hmac_params.msm_id_str)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_SW_ID, signing_attributes.sw_id)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_MODEL_ID, signing_attributes.model_id)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_OEM_ID, signing_attributes.oem_id)
        if signing_attributes.debug:
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_DEBUG, signing_attributes.debug)
        if signing_attributes.app_id:
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_APP_ID, signing_attributes.app_id)
        if signing_attributes.crash_dump:
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_CRASH_DUMP, signing_attributes.crash_dump)

        if self._is_tcg_supported(signing_attributes) is True:
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_TCG_MIN, signing_attributes.tcg_min)
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_TCG_MAX, signing_attributes.tcg_max)
        else:
            #opendsp does not CASS_SIGNATTR_USE_EXP3 currently
            if signing_attributes.exponent == 3:
                signingrequest.setSigningAttribute(self.CASS_SIGNATTR_USE_EXP3, 'TRUE')
            elif signing_attributes.exponent == 65537:
                signingrequest.setSigningAttribute(self.CASS_SIGNATTR_USE_EXP3, 'FALSE')
            else:
                raise RuntimeError, "Exponent value of {0} is invalid!".format(signing_attributes.exponent)

        # Set signature algorithm to SHA256 by default
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_SHA256, 'TRUE')

        pathname, fname = os.path.split(signingpackage_fname)
        c_path.create_dir(pathname)

        signingpackage.toxml()
        signingpackage.saveToFile(signingpackage_fname)
        logger.info("Signing package created. Digest = [%s]" % signingpackage.getDigest())
        return signingpackage
def privkey_pem_to_der(pem_privkey):
    """ Convert PEM format PRIVATE key into DER format
    input:
    pem_privkey: String containing base64 PEM Private key

    output
    der_privkey: String containing binary Private key
    """
    pem_tempfile_name = utility_functions.store_data_to_temp_file(pem_privkey)
    try:
        der_privkey = utility_functions.system_command_logged([openssl_binary_path, 'rsa', '-in', pem_tempfile_name, '-inform', 'PEM', '-outform', 'DER'], stderr_to_temp=True)
    except:
        logger.critical("privkey_pem_to_der: OPENSSL Could not convert PEM key to DER key")
    logger.debug2("PEM Format private key: " + hexdump(der_privkey))
    logger.debug("Deleting temporary file: " + pem_tempfile_name)
    os.unlink(pem_tempfile_name)
    return der_privkey
def privkey_der_to_pem(der_privkey):
    """ Convert binary DER format PRIVATE key into base64 coded ASCII PEM format
    input:
    der_privkey: String containing binary PRIVATE KEY

    output
    pem_privkey: String containing base64 PEM PRIVATE KEY
    """
    der_tempfile_name = utility_functions.store_data_to_temp_file(der_privkey)
    try:
        pem_privkey = utility_functions.system_command_logged([openssl_binary_path, 'rsa', '-in', der_tempfile_name, '-inform', 'DER', '-outform', 'PEM'], stderr_to_temp=True)
    except:
        logger.critical("privkey_der_to_pem: OPENSSL Could not convert DER key to PEM")
    logger.debug2("PEM Format Private Key: " + pem_privkey)
    logger.debug("Deleting temporary file: " + der_tempfile_name)
    os.unlink(der_tempfile_name)
    return pem_privkey
def cert_pem_to_der(pem_certificate):
    """ Convert PEM format certificate into DER format
    input:
    pem_certificate: String containing base64 PEM certificate

    output
    der_certificate: String containing binary certificate
    """

    pem_tempfile_name = utility_functions.store_data_to_temp_file(pem_certificate)
    try:
        der_certificate = utility_functions.system_command_logged([openssl_binary_path, 'x509', '-in', pem_tempfile_name, '-inform', 'PEM', '-outform', 'DER'], stderr_to_temp=True)
    except:
        logger.critical("cert_pem_to_der: OPENSSL could not convert PEM cert to DER")
    logger.debug2("PEM Format certificate: " + hexdump(der_certificate))
    logger.debug("Deleting temporary file: " + pem_tempfile_name)
    os.unlink(pem_tempfile_name)
    return der_certificate
def cert_der_to_pem(der_certificate):
    """ Convert binary DER format certificate into base64 coded ASCII PEM format
    input:
    der_certificate: String containing binary certificate

    output
    pem_certificate: String containing base64 PEM certificate
    """

    der_tempfile_name = utility_functions.store_data_to_temp_file(der_certificate)
    try:
        pem_certificate = utility_functions.system_command_logged([openssl_binary_path, 'x509', '-in', der_tempfile_name, '-inform', 'DER', '-outform', 'PEM'], stderr_to_temp=True)
    except:
        logger.critical("cert_der_to_pem: OPENSSL could not convert DER cert to PEM")
    logger.debug2("PEM Format certificate: " + pem_certificate)
    logger.debug("Deleting temporary file: " + der_tempfile_name)
    os.unlink(der_tempfile_name)
    return pem_certificate
    def _process_signature_package(self, signaturepackage, signingpackage, signature_result_file):
        signaturePackage = SignaturePackage(signaturepackage)
        logger.debug("Signing package digest from Signature Package = [%s]" % signaturePackage.getSPDigest())
        if (signaturePackage.getSPDigest().lower() != signingpackage.getDigest().lower()):
            raise ExternalSignerError, "Signing Package Digest mismatched from Signature Package!"

        if signaturePackage.getCount() == 1:
            signatureResponse = signaturePackage.getSignatureResponse(1)
        else:
            raise ExternalSignerError, "Signature Package has unexpected count = %d!" % signaturePackage.getCount()

        statusCode = signatureResponse.getStatusCode()
        logger.debug("Status returned from Signature Response: %s" % statusCode)

        if statusCode == "1":
            signatureResponse.saveResultToFile(signature_result_file)
        else:
            raise ExternalSignerError, "Error returned from Signature Response:\n%s" % signatureResponse.getError()
    def __init__(self, data,
                 debug_dir=None,
                 debug_prefix=None,
                 debug_suffix=None,
                 ):
        # Public properties
        self.debug_dir = debug_dir
        self.debug_prefix = debug_prefix
        self.debug_suffix = debug_suffix

        # Store the original image
        self.store_debug_data(df.FILE_DATA_IN, data)

        """
        Extract the various segments/sections of the data:
        1. Elf header
        2. Prog headers
        3. Bin
        """
        # Extract the header
        self.ehdr = extract_ehdr(data)
        self.store_debug_data(df.FILE_HDR_IN, self.ehdr.pack())
        self.store_debug_data(df.FILE_HDR_IN_REPR, repr(self.ehdr), suffix=df.FILE_HDR_IN_REPR_SUFFIX)

        # Extract the program headers
        self.phdrs = extract_phdrs(data, self.ehdr)
        self.store_debug_data(df.FILE_PHDR_IN, pack_phdrs(self.phdrs))
        self.store_debug_data(df.FILE_PHDR_IN_REPR, repr_phdrs(self.phdrs), suffix=df.FILE_PHDR_IN_REPR_SUFFIX)

        # Dump the individual segments
        self.segments = extract_segments(data, self.phdrs)
        for idx, phdr in enumerate(self.phdrs):
            length = len(self.segments[phdr])
            is_load = self._segment_to_put(phdr)
            if length >= 0 and length <= 16:
                logger.debug(('' if is_load else 'Non-') + 'Loadable segment - ' + str(idx + 1) + ' is of size: '  + str(length))
                if is_load and (length > 0 and length <= 16):
                    logger.warning(('' if is_load else 'Non-') + 'Loadable segment - ' + str(idx + 1) + ' is of size: '  + str(length))
            self.store_debug_data(df.FILE_SEGMENT_IN.format(idx), self.segments[phdr])

        # Zero out the sections for now
        zero_out_sections(self.ehdr)
    def get_rootcerts(self):
        root_cert_list = []
        for i in range(0, self.general_properties.num_root_certs):
            config_cert_name = self.cert_config.multirootcert.root_cert_name
            root_cert_path_to_replace = os.path.join(self.cert_config.multirootcert.directory, config_cert_name)

            root_cert_path = self.replace_macros(
                                root_cert_path_to_replace,
                                exponent=str(self.signing_attributes.exponent),
                                key_size=str(self.general_properties.key_size),
                                index=str(i))

            if os.path.isfile(root_cert_path) is False:
                err_str = "certificate_path does not exist: {0}!".format(root_cert_path)
                raise RuntimeError(err_str)
            root_cert = c_misc.load_data_from_file(root_cert_path)
            root_cert_list.append(root_cert)
            logger.debug('Package root cert {0}: {1}'.format(i, root_cert_path))

        return root_cert_list
    def query_data_path(self, T1_namespace, T2_namespace, T3_namespace,
                        asset_tag):

        query_result = self.data_prov.query(T1_namespace, T2_namespace,
                                            T3_namespace)[0]

        # check if asset folder has been found correctly #
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        if not query_result.config:
            raise RuntimeError('DataProvisioner: ' +
                               c_path.join(query_result.path, 'config.xml') +
                               ' is not found')

        # check if config.xml is valid #
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        try:
            asset_file_name = str(
                getattr(query_result.config.METACONFIG, asset_tag))
        except Exception:
            raise RuntimeError('DataProvisioner: ' + asset_tag +
                               ' is not found in config.xml')
            return 'ERROR'

        # Inject the mrc_index into file string before the period #
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        asset_file_name = string.replace(asset_file_name, '.',
                                         str(self.cert_mrc_index) + '.')

        # check if asset file exists #
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        asset_file_path = os.path.join(query_result.path, asset_file_name)
        asset_file_path = os.path.normpath(asset_file_path)

        if not c_path.validate_file(asset_file_path):
            raise RuntimeError('DataProvisioner: ' + asset_file_path +
                               ' is not found')

        self.log_once(asset_tag + " = " + asset_file_path)
        logger.debug("DataProvisioner config: " + str(query_result.config))

        return asset_file_path
def gen_rsa_key_pair(key_size_in_bits, key_exponent, priv_key_output_file, pub_key_output_file):
    """ Generate RSA Key pair

        input:

        key_size_in_bits: Size of the key in bits.
        key_exponent: [3, 65537]
                      Exponent used in key calculation.
        priv_key_output_file: File name for storing private key
        pub_key_output_file: File name for storing public key

        output:

        returned value: {"public_key": [Generated public key],
                         "private_key": [Generated private key] }
                         Dictionary holding the values of public and private keys
    """

    logger.debug("the openssl_binary is:{0}".format(openssl_binary_path))
    if key_exponent==3:
        exponent_str="-3"
    elif key_exponent == 65537:
        exponent_str="-f4"
    else:
        logger.warning("Exponent value supplied is INVALID! going with default exponent of 65537.")
        exponent_str="-f4"

    key_size_str=str(key_size_in_bits)

    if priv_key_output_file is not None:
        pk_file=open(priv_key_output_file,"wb")
    else:
        pk_file=tempfile.NamedTemporaryFile(delete=False)
        logger.debug("No output file specified for private key storage, so creating temp file: " + pk_file.name)

    try:
        private_key = utility_functions.system_command_logged([openssl_binary_path, "genrsa", exponent_str, key_size_str], stderr_to_temp=True)
    except subprocess.CalledProcessError, e:
        logger.critical("gen_rsa_key_pair: OPENSSL Errored out on generation of RSA key.")
        logger.critical("call to OpenSSL binary returned an error!: retval = " + str(e.returncode) + " Command = " + str(e.cmd))
        raise RuntimeError("call to OpenSSL binary returned an error!: retval = " + str(e.returncode) + " Command = " + str(e.cmd))
def _create_sigining_request(certificate_params, key_pair, days=7300, configfile="opensslroot.cfg"):
    """ Create a CSR (Certificate Signing Request)
    input:

        certificate_params ={
                              'C'              : "US",
                              'ST'             : "California",
                              'L'              : "San Diego",
                              'O'              : "ASIC",
                              'CN'             : "Qualcomm",
                          }
        Dictionary of parameters to put in the certificate. The parameters above are an example

        key_pair = None | key_pair = {"public_key": [Generated public key],
                                      "private_key": [Generated private key] }

        Dictionary holding the values of public and private keys. If this is None, a key
        is generated.

        days = validity period of certificate in days

        configfile = configfile used by openssl

    output:
        certificate_request: String representation of PEM certificate signing request (CSR).
        key_pair : {"public_key": [Generated public key],
                    "private_key": [Generated private key] }
    """

    subject_string = _get_subject_string_from_certificate_params(certificate_params)

    if key_pair == None:
        logger.debug("No key pair provided, will generate a key RSA 2048 bits")
        key_tempfile_name="certificate.key"
        command_list=[openssl_binary_path, "req", "-new", "-nodes", "-keyout", key_tempfile_name, "-subj", subject_string, "-newkey", "rsa:2048", "-days", str(days), "-config", configfile]
    else:
        key_tempfile_name =utility_functions.store_data_to_temp_file(key_pair['private_key'])
        command_list = [openssl_binary_path, "req", "-new", "-key", key_tempfile_name, "-subj", subject_string, "-days", str(days), "-config", configfile]
    logger.debug("Command List: " + repr(command_list))

    return _execute_openssl_certificate_command(command_list, key_pair, key_tempfile_name)
def _create_self_signed_certificate(certificate_params, key_pair, days, configfile, serial_num):
    """ Create a self signed certificate
    input:
        certificate_params ={
                              'C'              : "US",
                              'ST'             : "California",
                              'L'              : "San Diego",
                              'O'              : "ASIC",
                              'CN'             : "Qualcomm",
                          }
        Dictionary of parameters to put in the certificate. The parameters above are an example

        key_pair = None | key_pair = {"public_key": [Generated public key],
                                      "private_key": [Generated private key] }

        Dictionary holding the values of public and private keys. If this is None, a key
        is generated.

        days = validity period of certificate in days

        configfile = configfile used by openssl

        serial_num = Serial number of certificate

    output:
        certificate: String representation of PEM certificate.
        key_pair : {"public_key": [Generated public key],
                    "private_key": [Generated private key] }
    """

    subject_string = _get_subject_string_from_certificate_params(certificate_params)

    if key_pair == None:
        logger.debug("No key pair provided, will generate a key RSA 2048 bits")
        key_tempfile_name="certificate.key"
        command_list = [openssl_binary_path, "req", "-new", "-x509", "-keyout", key_tempfile_name, "-subj", subject_string, "-newkey", "rsa:2048", "-days", str(days), "-config", configfile, "-set_serial", str(serial_num), "-sha256"]
    else:
        key_tempfile_name =utility_functions.store_data_to_temp_file(key_pair['private_key'])
        command_list = [openssl_binary_path, "req", "-new", "-key", key_tempfile_name, "-x509", "-subj", subject_string, "-days", str(days), "-config", configfile, "-set_serial", str(serial_num), "-sha256"]

    return _execute_openssl_certificate_command(command_list, key_pair, key_tempfile_name)
def get_env_build_policy(environment):
    # get the supported build policies from the policy file
    supported_build_policies = sectools_builder_core.BuildPolicy.get_supported_build_policies(
        DEFAULT_POLICY_FILE)
    enabled_env_build_policies = []
    # get the enabled build policy from the environment using the ids from the supported build policies
    for policy in supported_build_policies:
        if environment.get("USES_SEC_POLICY_" + policy.upper()):
            logger.debug("Found build policy environment variable {0}".format(
                "USES_SEC_POLICY_" + policy.upper()))
            enabled_env_build_policies.append(policy)
        elif environment.get("SEC_POLICY_" + policy.upper()):
            logger.debug("Found build policy environment variable {0}".format(
                "SEC_POLICY_" + policy.upper()))
            enabled_env_build_policies.append(policy)
        elif environment.get(policy.upper()):
            logger.debug("Found build policy environment variable {0}".format(
                policy.upper()))
            enabled_env_build_policies.append(policy)
        elif environment.get(policy):
            logger.debug(
                "Found build policy environment variable {0}".format(policy))
            enabled_env_build_policies.append(policy)
    if not enabled_env_build_policies:
        logger.info(
            "No environmental build policy variable was enabled nor was one provided as a command line argument. Sectools will not be executed."
        )
        logger.info(
            "If execution of Sectools is desired, a build policy must be set in the environment or passed as a command line argument. Supported build policies are: {0}"
            .format(", ".join(supported_build_policies).upper()))
        return None
    elif len(enabled_env_build_policies) > 1:
        error_message = "The following environmental build policy variables are enabled: {0}. Only one build policy can be enabled at a time.".format(
            ", ".join(enabled_env_build_policies).upper())
        logger.error(error_message)
        raise RuntimeError(error_message)
    else:
        logger.debug(
            "Successfully retrieved build policy {0} from environment".format(
                enabled_env_build_policies[0].upper()))
        return enabled_env_build_policies[0]
    def config_paths(self):
        """(list[tuple(str)]) List of the config paths found in the workspace
        conforming to the naming structure.
        """
        config_dir = self.config_dir
        config_paths = []

        logger.debug('Searching config path sets in dir: ' + config_dir)
        for entry in os.listdir(config_dir):
            path = c_path.join(config_dir, entry)
            if c_path.validate_dir(path):
                config = self._get_config_path(path)
                if config:
                    config_paths.append(config)
                else:
                    logger.debug2('Skipping dir: ' + entry + '\n'
                                  '    ' + 'Does not contain any configs')
            else:
                logger.debug2('Skipping file in first level: ' + entry)
        logger.debug('Config paths found from the config dir: ' + str(config_paths))
        return config_paths
Exemple #26
0
    def config_paths(self):
        """(list[tuple(str)]) List of the config paths found in the workspace
        conforming to the naming structure.
        """
        config_dir = self.config_dir
        config_paths = []

        logger.debug('Searching config path sets in dir: ' + config_dir)
        for entry in os.listdir(config_dir):
            path = c_path.join(config_dir, entry)
            if c_path.validate_dir(path):
                oem, qc, ui, user = self._get_config_paths(path)
                if oem or qc or ui or user:
                    config_paths.append((oem, qc, ui, user))
                else:
                    logger.debug2('Skipping dir: ' + entry + '\n'
                                  '    ' + 'Does not contain any configs')
            else:
                logger.debug2('Skipping file in first level: ' + entry)
        logger.debug('Config paths found from the config dir: ' + str(config_paths))
        return config_paths
 def _apply_attribute_overrides(self):
     if self.attributes_to_override and len(
             self.attributes_to_override) > 0:
         for key, value in self.attributes_to_override.iteritems():
             if key in self.attribute_dict.keys():
                 # add new entry to dictionary
                 self.attribute_dict.update(value)
                 # remove old dictionary entry
                 if key != value.keys()[0]:
                     del self.attribute_dict[key]
                 logger.debug(
                     "Overrode CASS signing request's \"{0}\" attribute with {1}."
                     .format(key, value))
             else:
                 raise RuntimeError(
                     "Attempted to override CASS signing request's \"{0}\" attribute with \"{1}\" but \"{0}\" is not an attribute of CASS signing request.\n"
                     "If you would like to add \"{1}\" to CASS signing request's attributes, add {2} to the dictionary created in _create_attributes_to_add"
                     .format(key,
                             value.keys()[0], value))
     else:
         logger.debug("No CASS signing request attributes were overridden.")
Exemple #28
0
 def get_signing_request_class(self, cass_capability):
     logger.debug("CASS capability set to \"{0}\"".format(cass_capability))
     signing_requests = self.get_map()
     supported_capabilities = list()
     # search for a signing request that supports the specified cass capability
     for signing_request_id, signing_request_class in signing_requests.iteritems(
     ):
         supported_capabilities.extend(
             signing_request_class.get_supported_capabilities())
         if cass_capability in signing_request_class.get_supported_capabilities(
         ):
             return signing_request_class
     # no signing request was found that supports the specified cass capability so default to secure boot 2 signing request
     logger.debug("\"{0}\" is not a pre-configured CASS capability.\n".
                  format(cass_capability) +
                  "The pre-configured CASS capabilities are: " +
                  ", ".join(supported_capabilities))
     logger.info(
         "Using CASS Secure Boot 2 signing request for CASS capability \"{0}\""
         .format(cass_capability))
     return signing_request_secure_boot_2.SecureBoot2SigningRequest
 def build(self):
     logger.debug("Executing SectoolsBuilderCore.build()")
     # construct build policy object based on selected build_policy_id
     if self.input.build_policy is None and self.input.build_policy_id is None:
         logger.error("A build policy was not provided. Sectools execution, installation, and pilsplitting will be skipped.")
     elif self.input.build_policy is None:
         logger.debug("Constructing BuildPolicy based on selected build_policy_id...")
         self.input.build_policy = BuildPolicy(self.input.policy_file, self.input.build_policy_id, self.input.sign_id, self.input.sectools_install_base_dir, self.input.additional_secimage_policy_ids)
         logger.debug("\n\nConstructed BuildPolicy:\n" + str(self.input.build_policy) + "\n")
     # either call sectools and proceed with installation and pilsplitting or return SCons callback to build method
     if self.input.execute_sectools:
         # update config file with relocatable value
         self._generate_config_file()
         # validate files and paths
         errors = []
         validate_file(self.input.source, "source", errors)
         validate_dir(self.input.target_base_dir, "target_base_dir", errors)
         validate_dir(self.input.sectools_install_base_dir, "sectools_install_base_dir", errors)
         validate_dir(self.input.pilsplitter_target_base_dir, "pilsplitter_target_base_dir", errors)
         if errors:
             err_string = "\n".join(errors)
             logger.error(err_string)
             raise RuntimeError(err_string)
         # drive sign, install, and pilsplit sequence
         self._execute_sign()
     else:
         # return SCons callback to build method
         return self._scons_callback()
Exemple #30
0
    def data_to_sign(self):
        # Backup the parsegen
        backup = _BackupMbnParsegen(self._mbn_parsegen)

        # Set the current attributes
        if self.authority == defines.AUTHORITY_QC:
            self._mbn_parsegen.sign = self._data_signature
            self._mbn_parsegen.cert_chain = self._cert_chain

        self._mbn_parsegen.sign_qc = self._data_signature_qc
        self._mbn_parsegen.cert_chain_qc = self._cert_chain_qc

        # Set padding info
        self._mbn_parsegen.set_pad_info(self.sig_size, self.cert_chain_size)

        # Update version number before applying signature #
        if SECBOOT_MBN_HDR[
                self.secboot_version] == self._mbn_parsegen.header.get_version(
                ):
            logger.debug("Updating version to " +
                         str(self._mbn_parsegen.header.get_version()))
            self._mbn_parsegen.header.set_version_in_bin(
                self._mbn_parsegen.header.get_version())
        else:
            raise RuntimeError(
                'Version check failed. MBN header version (%s) does not match expected version (%s).'
                % (str(self._mbn_parsegen.header.get_version()),
                   str(SECBOOT_MBN_HDR[self.secboot_version])))

        # Get the data to sign (header + code)
        retval = self._mbn_parsegen.get_header(
            self.authority).pack() + self._mbn_parsegen.code

        # Clear padding info
        self._mbn_parsegen.set_pad_info(0, 0)

        # Restore the parsegen
        backup.restore(self._mbn_parsegen)

        return retval
    def get_image_info_from_meta(cls, meta_info):
        # Get a list of all files tagged with sign_id
        meta_images_list = meta_info.get_files_detailed('sign_id')

        for image in meta_images_list:
            try:
                logger.debug('Found image from meta_build for signing: ' + image.sign_id)

                source_path = None
                dest_path = None
                for each_path in image.file_path:
                    if source_path is None:
                        if getattr(each_path, 'sign_source', False):
                            source_path = each_path.value
                    if dest_path is None:
                        if getattr(each_path, 'sign_dest', False):
                            dest_path = each_path.value
                    if source_path and dest_path:
                        break

                if source_path is None or dest_path is None:
                    raise RuntimeError('SourcePath, DestPath should not be missing.')

                sign_id = image.sign_id
                chipset = image.chipset
                image_src_path = ImagePath()
                image_dest_path = DestImagePath()

                image_src_path.image_dir_base = image.image_dir_base
                image_src_path.image_dir_ext = source_path
                image_src_path.image_name = image.file_name[0].value
                image_dest_path.image_dir_base = image.image_dir_base
                image_dest_path.image_dir_ext = dest_path
                image_dest_path.image_name = image.file_name[0].value

            except Exception as e:
                logger.error(str(e))
                continue

            yield (sign_id, chipset, image_src_path, image_dest_path)
def _sign_csr_with_CA_certificate(certificate_signing_request, CA_certificate, CA_key_pair, days, serial_num, extfile_name):
    """ Sign a Certificate signing request with a higher level CA certificate
    input:
    certificate_signing_request: String form of CSR
    CA_certificate: String representation of a higher level CA certificate

    CA_key_pair : {"public_key": [Generated public key],
                "private_key": [Generated private key] }
    The key pair of the CA_certificate

    days = validity period of certificate in days

    serial_num = Serial number of certificate

    extfile_name = Name of the extensions file to be used by openssl

    output:
    CA_signed_certificate: String representation of CA Signed certificate (PEM)
    CA_key_pair: {"public_key": CA public key,
                  "private_key": CA private key }
    """

    CA_certificate_tempfile_name =utility_functions.store_data_to_temp_file(CA_certificate)
    CA_privkey_tempfile_name = utility_functions.store_data_to_temp_file(CA_key_pair['private_key'])
    certificate_signing_request_tempfile_name = utility_functions.store_data_to_temp_file(certificate_signing_request)

    command_list=[openssl_binary_path, "x509", "-req", "-in", certificate_signing_request_tempfile_name, "-CAkey",
                  CA_privkey_tempfile_name, "-CA", CA_certificate_tempfile_name, "-days", str(days),
                  "-set_serial", str(serial_num), "-extfile", extfile_name, "-sha256"]
    logger.debug("Command_list = " + repr(command_list))

    CA_signed_certificate = utility_functions.system_command_logged(command_list, stderr_to_temp=True)
    logger.debug("Generated Output of openssl certificate command: " + CA_signed_certificate)


    os.unlink(CA_certificate_tempfile_name)
    os.unlink(CA_privkey_tempfile_name)
    os.unlink(certificate_signing_request_tempfile_name)

    return (CA_signed_certificate, CA_key_pair)
Exemple #33
0
    def _generate_signing_package(self, hash_to_sign, signing_attributes, cass_signer_attributes,
                                image_path, signingpackage_fname, binary_to_sign):

        signingpackage = SigningPackage(secimage.__version__)
        signingrequest = signingpackage.createSigningRequest("image_to_sign=%s" % image_path)

        hexbindigest = binascii.b2a_hex(hash_to_sign)
        logger.debug("Digest to sign (hexbinary)= [%s]" % hexbindigest)
        signingrequest.setDigest(hexbindigest)
        signingrequest.setCapability(cass_signer_attributes.capability)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_SW_SIZE, "0x%.8X" % len(binary_to_sign))

        hmac_params = signerutils.get_hmac_params_from_config(signing_attributes)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_HW_ID, "0x%s" % hmac_params.msm_id_str)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_SW_ID, signing_attributes.sw_id)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_MODEL_ID, signing_attributes.model_id)
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_OEM_ID, signing_attributes.oem_id)
        if signing_attributes.debug:
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_DEBUG, signing_attributes.debug)
        if signing_attributes.app_id:
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_APP_ID, signing_attributes.app_id)
        if signing_attributes.crash_dump:
            signingrequest.setSigningAttribute(Certificate.SIGNATTR_CRASH_DUMP, signing_attributes.crash_dump)
        if signing_attributes.exponent == 3:
            signingrequest.setSigningAttribute(self.CASS_SIGNATTR_USE_EXP3, 'TRUE')
        elif signing_attributes.exponent == 65537:
            signingrequest.setSigningAttribute(self.CASS_SIGNATTR_USE_EXP3, 'FALSE')
        else:
            raise RuntimeError, "Exponent value of {0} is invalid!".format(signing_attributes.exponent)

        # Set signature algorithm to SHA256 by default
        signingrequest.setSigningAttribute(Certificate.SIGNATTR_SHA256, 'TRUE')

        pathname, fname = os.path.split(signingpackage_fname)
        c_path.create_dir(pathname)

        signingpackage.toxml()
        signingpackage.saveToFile(signingpackage_fname)
        logger.info("Signing package created. Digest = [%s]" % signingpackage.getDigest())
        return signingpackage
    def get_image_info_from_meta(cls, meta_info):
        # Get a list of all files tagged with sign_id
        meta_images_list = meta_info.get_files_detailed('sign_id')

        for image in meta_images_list:
            try:
                logger.debug('Found image from meta_build for signing: ' + image.sign_id)

                source_path = None
                dest_path = None
                for each_path in image.file_path:
                    if source_path is None:
                        if getattr(each_path, 'sign_source', False):
                            source_path = each_path.value
                    if dest_path is None:
                        if getattr(each_path, 'sign_dest', False):
                            dest_path = each_path.value
                    if source_path and dest_path:
                        break

                if source_path is None or dest_path is None:
                    raise RuntimeError('SourcePath, DestPath should not be missing.')

                sign_id = image.sign_id
                chipset = image.chipset
                image_src_path = ImagePath()
                image_dest_path = DestImagePath()

                image_src_path.image_dir_base = image.image_dir_base
                image_src_path.image_dir_ext = source_path
                image_src_path.image_name = image.file_name[0].value
                image_dest_path.image_dir_base = image.image_dir_base
                image_dest_path.image_dir_ext = dest_path
                image_dest_path.image_name = image.file_name[0].value

            except Exception as e:
                logger.error(str(e))
                continue

            yield (sign_id, chipset, image_src_path, image_dest_path, MetaError.SUCCESS)
def _get_hmacparams_from_certificate_subject_dictionary(certificate_subject_dictionary):
    """ Return a dictionary of the HMAC params from the certificate subject dictionary
    input:
        certificate_subject_dictionary = dictionary of subject params from certificate

    output:
        hmac_params = Dictionary of HMAC parameters from certificate subject
    """

    sw_id_re=re.compile(r'01 ([0-9A-F]{16}) SW_ID')
    hw_id_re=re.compile(r'02 ([0-9A-F]{16}) HW_ID')
    if 'OU' in certificate_subject_dictionary.keys() and type(certificate_subject_dictionary['OU'])==list:
        certificate_subject_dictionary['OU'].sort()
    sw_id_element = sw_id_re.match(certificate_subject_dictionary['OU'][0])
    hw_id_element = hw_id_re.match(certificate_subject_dictionary['OU'][1])
    if sw_id_element == None:
        logger.critical("Error in certificate subject. SW_ID field not found. Not a valid certificate. Exiting")
        raise RuntimeError("Error in certificate subject. SW_ID field not found. Not a valid certificate. Exiting")
    elif hw_id_element == None:
        logger.critical("Error in certificate subject. HW_ID field not found. Not a valid certificate. Exiting")
        raise RuntimeError("Error in certificate subject. HW_ID field not found. Not a valid certificate. Exiting")
    else:
        logger.debug("Valid certificate: Found SW_ID and HW_ID")
        sw_id_text = sw_id_element.group(1)
        hw_id_text = hw_id_element.group(1)
        logger.debug('SW_ID = ' + sw_id_text)
        logger.debug('HW_ID = ' + hw_id_text)
        hw_id_int = int(hw_id_text, 16)
        sw_id_int = int(sw_id_text, 16)
        hmac_params = HmacParams(hw_id_int, sw_id_int)
        return hmac_params
Exemple #36
0
    def verify(self):
        '''verifies self.database is correct. Checks for type/bin file mismatch. bin files not
           in level 3. Lack of binfiles. Too many binfiles. Etc.Some things are implicitly verified
           by the file handler, like existence of files/folders and correct paths, since it
           can't create the database with bad paths

           :raises: RuntimeError
           '''

        if len(self.database.files) > 0:
            raise RuntimeError(
                "DataProvisioner:  binary files {0} exist within security_policy level of Data Provisioning file structure"
            ).format(self.database.files)
        for lvl1_name, lvl1_obj in self.database.children.items():

            if len(lvl1_obj.files) > 0:
                raise RuntimeError(
                    "DataProvisioner:  binary files {0} exists within security_policy_type level of Data Provisioning file structure"
                ).format(lvl1_obj.files)

            for lvl2_name, lvl2_obj in lvl1_obj.children.items():

                if len(lvl2_obj.files) > 0:
                    raise RuntimeError(
                        "DataProvisioner:  binary files {0} exists within data_prov_id level of Data Provisioning file structure"
                    ).format(lvl2_obj.files)

                for lvl3_name, lvl3_obj in lvl2_obj.children.items():

                    #                     if len(lvl3_obj.files) == 0:
                    #                         raise RuntimeError("DataProvisioner:  there are no binary files in data_prov_id of Data Provisioning file structure. {0}".format(lvl3_obj.path))

                    for file_name in lvl3_obj.files:
                        if c_path.validate_dir(file_name):
                            raise RuntimeError(
                                "DataProvisioner:  Directories are not allowed within the data_prov_id directory of the Data Provisioning file structure"
                            )

        logger.debug("DataProvisioner database verification passed")
        return True
Exemple #37
0
    def _get_rootcerts_from_config(self, cert_config, num_root_certs):
        root_cert_list = []

        if cert_config.multirootcert:
            for i in range(0, num_root_certs):
                config_cert_name = cert_config.multirootcert.root_cert_name
                cert_name = signerutils.macro_replace(config_cert_name,
                                                      "index",
                                                      str(i),
                                                      isMandatory=True)
                root_cert_path = os.path.join(
                    cert_config.multirootcert.directory, cert_name)
                if os.path.isfile(root_cert_path) is False:
                    err_str = "certificate_path does not exist: {0}!".format(
                        root_cert_path)
                    raise RuntimeError(err_str)
                root_cert = c_misc.load_data_from_file(root_cert_path)
                root_cert_list.append(root_cert)
                logger.debug('Package root cert {0}: {1}'.format(
                    i, root_cert_path))

        return root_cert_list
Exemple #38
0
    def invokeSecImage(self, args, input_filename, dest_config):
        sign_id = self._get_sign_id()
        cmds = [
            "secimage", "-g", sign_id, "-i", input_filename, "-c", dest_config,
            "-o",
            os.path.join(args.output_dir, SECIMAGE_OUTPUTDIR)
        ]

        if args.verbose:
            cmds.append("-v")

        if args.debug:
            cmds.append("-d")

        if args.validate:
            cmds.append("-a")
        else:
            cmds.append("-sa")

        logger.debug("""\nExecute command:
     python sectools.py {0}\n""".format(' '.join(cmds)))
        return self._executeCmds(cmds, args.verbose or args.debug)
Exemple #39
0
    def _generate_new_encryption_params_blob(self):
        self.l1_key = self._get_l1_key()
        self.l2_key = self._get_l2_key()
        self.l3_key = self._get_l3_key()

        encryption_params_hdr = EncryptionParamsHeader()
        encryption_params_hdr.add_encryption_param_section()
        eps_hdr1 = EncryptionParamsSectionHdr(None, None, 1, 0)
        eps_body1 = EncryptionParamsSectionBody(l1_key_blob=self.l1_key,
                                                image_id_bitmap=self.image_id)

        self.encryption_params_blob = encryption_params_hdr.get_header_blob() + \
                                        eps_hdr1.get_header_blob() + \
                                        eps_body1.get_binary_blob()

        self.l3_image_iv = eps_body1.get_image_iv()
        self.l3_key = eps_body1.get_l3_key()

        logger.debug("Encryption Params: \n" +
                     hexdump(self.encryption_params_blob))
        logger.debug("L1 Key: \n" + hexdump(self.l1_key))
        return self.encryption_params_blob, self.l1_key
Exemple #40
0
 def discover_openSSL_implementation(self):
     logger.debug("Beginning discovery of openssl implementation")
     logger.debug("Looking for openssl binary")
     openssl_binaries = self.which_cmd('openssl')
     if len(openssl_binaries)>0:
         logger.debug("Found OpenSSL binary at {0}".format(openssl_binaries[0]))
         import openssl_binary_implementation as openssl_impl
         if sys.platform!='linux2':
             openssl_impl.openssl_binary_path=self.relative_path_to_packaged_openssl_binary
         else:
             openssl_impl.openssl_binary_path=openssl_binaries[0]
         openssl_impl.ccm_crypto_path=self.relative_path_to_packaged_ccm_binary
         openssl_impl.cbc_crypto_path=self.relative_path_to_packaged_cbc_binary
     else:
         try:
             logger.debug("Looking for M2Crypto")
             import M2Crypto as openssl_impl                  
         except ImportError: 
             logger.debug("Could not find M2Crypto module")
             logger.critical("Could not find OpenSSL Implementation")
             raise RuntimeError("Could not find OpenSSL Implementation")
     return openssl_impl
Exemple #41
0
    def get_signing_request_class(self, cass_capability, secboot_version,
                                  sw_id):
        logger.debug("CASS capability set to \"{0}\"".format(cass_capability))
        signing_requests = self.get_map()
        supported_capabilities = list()
        secboot_version_signing_request_id_map = {}
        # search for a signing request that supports the specified cass capability
        for signing_request_id, signing_request_class in signing_requests.items(
        ):
            supported_capabilities.extend(
                signing_request_class.get_supported_capabilities())
            secboot_version_signing_request_id_map[
                signing_request_class.get_secboot_version(
                )] = signing_request_id
            if cass_capability in signing_request_class.get_supported_capabilities(
            ):
                return signing_request_class

        # no signing request was found that supports the specified cass capability so print supported capabilities
        logger.debug("\"{0}\" is not a pre-configured CASS capability\n".
                     format(cass_capability) +
                     "The pre-configured CASS capabilities are: " +
                     ", ".join(supported_capabilities))
        # For MBNv3 SPSS images use SBL2 Engine
        img_id = extract_image_id_from_sw_id(sw_id)
        if (img_id == SP_MCP_SW_ID or img_id
                == SP_APPS_SW_ID) and secboot_version == SECBOOT_VERSION_1_0:
            secboot_version = SECBOOT_VERSION_2_0
        logger.info(
            "Using CASS Secure Boot {0} signing request for CASS capability \"{1}\""
            .format(secboot_version, cass_capability))
        try:
            return signing_requests[
                secboot_version_signing_request_id_map[secboot_version]]
        except KeyError:
            raise RuntimeError(
                "CASS Signer does not support Secboot version {0}".format(
                    secboot_version))
    def _execute_pilsplit(self, file_to_pilsplit, pilsplit_prefix,
                          subdirectory):
        logger.debug("\nPilsplitting Sectools's output file...")
        if self.input.pilsplitter_target_base_dir:
            # Attempt pilsplit 3 times before failing
            pilsplit_successful = False
            for i in range(3):
                try:
                    if subdirectory:
                        subdir = c_path.join(
                            self.input.pilsplitter_target_base_dir,
                            subdirectory)
                        c_path.create_dir(subdir)
                        prefix = c_path.join(subdir, pilsplit_prefix)
                    else:
                        subdir = self.input.pilsplitter_target_base_dir
                        prefix = c_path.join(
                            self.input.pilsplitter_target_base_dir,
                            pilsplit_prefix)

                    SecImageCore.pil_split(file_to_pilsplit, prefix)
                except:
                    # Pilsplitting failed so retry pilsplit
                    continue
                pilsplit_successful = True
                logger.info(
                    "Pilsplitted \"{0}\" into directory \"{1}\"".format(
                        file_to_pilsplit, subdir))
                break
            if not pilsplit_successful:
                error_message = "Failed to pilsplit \"{0}\"".format(
                    file_to_pilsplit)
                logger.error(error_message)
                raise RuntimeError(error_message)
        else:
            logger.info(
                "Pilsplit was skipped because a value for pilsplitter_target_base_dir was not provided"
            )
    def _execute_install(self, policy):
        logger.debug("\nInstalling Sectools's output file...")
        if self.input.sectools_install_base_dir:
            path, filename = os.path.split(self.input.source)
            chipset = SecImageConfigParser(self.input.config).root.metadata.get_chipset()
            src = c_path.normalize(c_path.join(self.input.target_base_dir, policy.id, chipset, self.input.sign_id, filename))
            for install_location in policy.install_locations:
                if self.input.install_file_name:
                    dest = c_path.join(install_location, self.input.install_file_name)
                else:
                    dest = c_path.join(install_location, filename)

                try:
                    c_path.create_dir(install_location)
                    install_successful, error = c_path.copy_file(src, dest, None, True)
                    if not install_successful:
                        logger.error(error)
                except RuntimeError as e:
                    logger.error(str(e))
                    install_successful = False

                if not install_successful:
                    error_message = "Failed to install \"{0}\" to \"{1}\"".format(src, dest)
                    logger.error(error_message)
                    raise RuntimeError(error_message)

                logger.info("Installed \"{0}\" to \"{1}\"".format(src, dest))

                # pilsplit sectools's output file
                pilsplit_subdirectory = ""
                if install_location != self.input.sectools_install_base_dir:
                    pilsplit_subdirectory = install_location.replace(os.path.join(self.input.sectools_install_base_dir, "", ""), "")
                pilsplit_prefix = self.input.install_file_name.split(".")[0] if self.input.install_file_name else filename.split(".")[0]
                self._execute_pilsplit(dest, pilsplit_prefix, pilsplit_subdirectory)
        else:
            logger.info("Installation was skipped because a value for sectools_install_base_dir was not provided")
            if self.input.pilsplitter_target_base_dir:
                logger.info("Pilsplitting was skipped because a value for sectools_install_base_dir was not provided")
def verify_certificate_chain(certificate_chain):
    """ Verify the certificate chain to be valid

    input:
    certificate_chain: [cert1,cert2,cert3]
    List of certificates (*in PEM FORMAT*) in the certificate chain. It assumes that the last certificate is the Root CA certificate.

    output:
    [True|False]
    Boolean value
    """
    CAfile_contents = _create_CAfile_contents_from_cert_chain(
        certificate_chain)

    CAfile_tempfile_name = utility_functions.store_data_to_temp_file(
        CAfile_contents)

    level1_cert_to_verify_contents = certificate_chain[0]

    level1_cert_to_verify_tempfile_name = utility_functions.store_data_to_temp_file(
        level1_cert_to_verify_contents)
    try:
        verify_level1_cert_command_out = utility_functions.system_command_logged(
            [
                openssl_binary_path, 'verify', '-CAfile', CAfile_tempfile_name,
                level1_cert_to_verify_tempfile_name
            ])
    except:
        logger.critical(
            "verify_certificate_chain: OPENSSL could not verify cert chain")
        os.unlink(CAfile_tempfile_name)
        os.unlink(level1_cert_to_verify_tempfile_name)
        raise RuntimeError(
            "verify_certificate_chain: OPENSSL could not verify cert chain")
    logger.debug("OpenSSL verify command output: " +
                 verify_level1_cert_command_out)
    logger.debug("Deleting temporary files: " + CAfile_tempfile_name + ", " +
                 level1_cert_to_verify_tempfile_name)
    os.unlink(CAfile_tempfile_name)
    os.unlink(level1_cert_to_verify_tempfile_name)

    if verify_level1_cert_command_out.rstrip(
    ) == level1_cert_to_verify_tempfile_name + ": OK":
        logger.debug("The certificate chain is verified")
        return True
    else:
        logger.debug("The certificate chain is not verified")
        return False
def privkey_der_to_pem(der_privkey):
    """ Convert binary DER format PRIVATE key into base64 coded ASCII PEM format
    input:
    der_privkey: String containing binary PRIVATE KEY

    output
    pem_privkey: String containing base64 PEM PRIVATE KEY
    """
    der_tempfile_name = utility_functions.store_data_to_temp_file(der_privkey)
    try:
        pem_privkey = utility_functions.system_command_logged(
            [
                openssl_binary_path, 'rsa', '-in', der_tempfile_name,
                '-inform', 'DER', '-outform', 'PEM'
            ],
            stderr_to_temp=True)
    except:
        logger.critical(
            "privkey_der_to_pem: OPENSSL Could not convert DER key to PEM")
    logger.debug2("PEM Format Private Key: " + pem_privkey)
    logger.debug("Deleting temporary file: " + der_tempfile_name)
    os.unlink(der_tempfile_name)
    return pem_privkey
Exemple #46
0
    def query_data_prov(self, level1_namespace, level2_namespace, level3_namespace, asset_tag, return_file_path=False):
        query_result = self.data_prov.query(level1_namespace, level2_namespace, level3_namespace)[0]
        '''check if config.xml exists'''
        if not query_result.config:
            raise RuntimeError('DataProvisioner: ' + c_path.join(query_result.path, 'config.xml') + ' is not found')
        '''check if config.xml is valid'''
        try:
            asset_file_name = str(getattr(query_result.config.METACONFIG, asset_tag))
        except Exception:
            raise RuntimeError('DataProvisioner: ' + asset_tag + ' is not found in config.xml')

        '''check if asset file exists'''
        asset_file_path = os.path.join(query_result.path, asset_file_name)
        if not c_path.validate_file(asset_file_path):
            raise RuntimeError('DataProvisioner: ' + asset_file_path + ' is not found')

        self.log_once(asset_tag + " = " + asset_file_path)
        logger.debug("DataProvisioner config: " + str(query_result.config))

        if return_file_path:
            return asset_file_path
        else:
            return query_result.files[asset_file_name]
    def read(self, xml_path, config_xml_path=None):

        import auto_gen_fm_config
        import auto_gen_fmconf_config

        try:
            self.path = c_path.normalize(xml_path)
            self.config_path =  c_path.normalize(config_xml_path)

            # load the FM config data
            if(self.config_path is not None):
                c_config.CoreConfig.__init__(self.core_fmconfig, auto_gen_fmconf_config, self.config_path)
                self.filtermethod = self.core_fmconfig.root.filterType.method
            else:
                # TODO: change default to None or error out, check with Maria
                self.filtermethod = 'all'

            # populate the FM data model
            self._populate(self.path, auto_gen_fm_config, self.core_config)

        except Exception:
            logger.debug('fuseMasterData: Exception raised')
            raise
    def _scons_callback(self):
        logger.debug("Creating SCons callback...")
        scons_targets = get_scons_targets(self.input)

        if self.input.target_image_type_filter is not None:
            logger.debug(
                "Filtering SCons target list to only include {0} images...".
                format(target_name_map[self.input.target_image_type_filter]))
            logger.debug("SCons target list before filtering: {0}".format(
                scons_targets))
            scons_targets = scons_targets[self.input.target_image_type_filter]
            logger.debug(
                "SCons target list after filtering: {0}".format(scons_targets))

        return self.input.environment.builder_function_handler(
            scons_targets, self.input.source, INPUT=self.input)
    def get_rootcerts(self):
        root_cert_list = []
        for i in range(0, self.general_properties.num_root_certs):
            config_cert_name = self.cert_config.multirootcert.root_cert_name
            root_cert_path_to_replace = os.path.join(
                self.cert_config.multirootcert.directory, config_cert_name)

            root_cert_path = self.replace_macros(
                root_cert_path_to_replace,
                exponent=str(self.signing_attributes.exponent),
                key_size=str(self.general_properties.key_size),
                index=str(i))

            if os.path.isfile(root_cert_path) is False:
                err_str = "certificate_path does not exist: {0}!".format(
                    root_cert_path)
                raise RuntimeError(err_str)
            root_cert = c_misc.load_data_from_file(root_cert_path)
            root_cert_list.append(root_cert)
            logger.debug('Package root cert {0}: {1}'.format(
                i, root_cert_path))

        return root_cert_list
def privkey_pem_to_der(pem_privkey):
    """ Convert PEM format PRIVATE key into DER format
    input:
    pem_privkey: String containing base64 PEM Private key

    output
    der_privkey: String containing binary Private key
    """
    pem_tempfile_name = utility_functions.store_data_to_temp_file(pem_privkey)
    try:
        der_privkey = utility_functions.system_command_logged(
            [
                openssl_binary_path, 'rsa', '-in', pem_tempfile_name,
                '-inform', 'PEM', '-outform', 'DER'
            ],
            stderr_to_temp=True)
    except:
        logger.critical(
            "privkey_pem_to_der: OPENSSL Could not convert PEM key to DER key")
    logger.debug2("PEM Format private key: " + hexdump(der_privkey))
    logger.debug("Deleting temporary file: " + pem_tempfile_name)
    os.unlink(pem_tempfile_name)
    return der_privkey
def main(args):
    """Parses the command line arguments, performs any basic operations based on
    the parsed arguments and starts processing using the dpc module.
    """
    # Log to file
    log_to_file(args.output_dir)

    # Print the tool's launch command
    logger.debug('\n\n    DebugPolicy launched as: "' + ' '.join(sys.argv) + '"\n')

    # Initialize DebugPolicyCore
    dpc = DebugPolicyCore(debug=args.debug)

    # Configure DebugPolicyCore
    if args.dbgp_config_path:
        dpc.dbgp_config = args.dbgp_config_path

    if args.secimage_config_path:
        dpc.secimage_config = args.secimage_config_path

    if args.platform:
        dpc.dbgp_config, dpc.secimage_config = get_chipset_mode_config(args.platform)

    if args.input_file:
        dpc.set_input_file(args.input_file)

    if args.output_dir:
        dpc.output_dir = args.output_dir

    # Process
    dpc.process(verify_setup=args.verify_inputs,
                 generate=args.generate,
                 sign=args.sign,
                 validate=args.validate)

    # Print summary of operations
    print_summary()
Exemple #52
0
    def generate_new_cert(self,
                          cert_type,
                          cert_info,
                          prev_cert_info,
                          extfile=None,
                          self_sign=False,
                          padding=PAD_PKCS):

        # Update the subject parameters
        subject_params = self.create_subject_params(cert_type,
                                                    cert_info.params.params)

        # Generate the certificate request
        cert_req, priv_key, pub_key = self.generate_cert_request(
            cert_type,
            cert_info,
            subject_params,
            self_sign=self_sign,
            key_exp=self.signing_attributes.exponent,
            key_size=self.signing_attributes.key_size,
            padding=padding)

        # Settle on the extfile
        if extfile is None:
            extfile = cert_info.extfile

        # Sign the certificate request
        if not self_sign:
            logger.debug('Signing certificate request for ' + cert_type)
            cert = self.sign_cert_request(cert_req,
                                          prev_cert_info,
                                          extfile,
                                          padding=padding)
        else:
            cert = cert_req

        return cert, priv_key, pub_key
Exemple #53
0
    def _validate_tcg_raw(self, tcg_min_attest, tcg_max_attest, tcg_min_ca,
                          tcg_max_ca):
        tcg_ok = False

        if (self.config.general_properties.num_certs_in_certchain == 2) and \
            (self.config.signing.signature_format == "opendsp"):
            logger.info(
                "2-level certificate chain is not supported for opendsp signature"
            )
            return False

        if tcg_min_attest is not None:
            assert (isinstance(tcg_min_attest, BaseAttribute))
        if tcg_max_attest is not None:
            assert (isinstance(tcg_max_attest, BaseAttribute))
        if tcg_min_ca is not None:
            assert (isinstance(tcg_min_ca, BaseAttribute))
        if tcg_max_ca is not None:
            assert (isinstance(tcg_max_ca, BaseAttribute))

        if ((tcg_min_attest is None) and (tcg_max_attest is None)
                and (tcg_min_ca is None) and (tcg_max_ca is None)):
            # This is ok. No TCGs in attest cert.
            tcg_ok = True
            logger.debug(
                "\nNo TCGs found in Attestation cert or CA cert. This is OK.")
        elif ((tcg_min_attest is not None) and (tcg_max_attest is not None)
              and (tcg_min_ca is None) and (tcg_max_ca is None)):
            logger.info(
                "\nTCGs found in Attestation cert, but not in CA cert. This is invalid."
            )
        elif ((tcg_min_attest is None) and (tcg_max_attest is None)
              and (tcg_min_ca is not None) and (tcg_max_ca is not None)):
            logger.info(
                "\nNo TCGs found in Attestation cert, but there are TCGs in CA cert. This is invalid."
            )
        elif ((tcg_min_attest is not None) and (tcg_max_attest is not None)
              and (tcg_min_ca is not None) and (tcg_max_ca is not None)):
            if (tcg_min_ca.value <= tcg_min_attest.value <=
                    tcg_max_attest.value <= tcg_max_ca.value):
                tcg_ok = True
                logger.debug("\nTCG values fall within CA constraints.")
            else:
                logger.info("\nTCG values are outside the CA constraints.")
        else:
            logger.info("\nInvalid TCG values")

        tcg_log_mesg =  "\nAttestation cert : tcg_min={0} tcg_max={1}". \
                                format(tcg_min_attest, tcg_max_attest) + \
                        "\nCA cert (allowed): tcg_min={0} tcg_max={1}\n". \
                                format(tcg_min_ca, tcg_max_ca)
        if (tcg_ok is False):
            logger.info(tcg_log_mesg)
        else:
            logger.debug(tcg_log_mesg)

        return tcg_ok
Exemple #54
0
    def gen_keys(self, exponent, keysize, priv_key_path=None, pub_key_path=None):
        # Generate the key pair using openssl
        priv_key = self._gen_rsa_key_pair(exponent, keysize)

        # Save the private key to file
        priv_path = priv_key_path if priv_key_path is not None else c_path.create_tmp_file()

        # Generate the public key file
        try:
            logger.debug('Writing generated private key to PEM file: ' + priv_path)
            c_path.store_data_to_file(priv_path, priv_key)

            # Extract the public key from the private key
            pub_key = self.get_public_key_from_private(priv_key)
        finally:
            # Cleanup temp file
            c_path.remove_tmp_file(priv_path)

        # Save the public key to file
        if pub_key_path is not None:
            logger.debug('Writing generated public key to PEM file: ' + pub_key_path)
            c_path.store_data_to_file(pub_key_path, pub_key)

        return priv_key, pub_key
    def _validate_tcg_raw(self, tcg_min_attest, tcg_max_attest,
                                tcg_min_ca, tcg_max_ca):
        tcg_ok = False

        if (self.config.general_properties.num_certs_in_certchain == 2) and \
            (self.config.signing.signature_format == "opendsp"):
            logger.info("2-level certificate chain is not supported for opendsp signature")
            return False

        if tcg_min_attest is not None:
            assert(isinstance(tcg_min_attest, BaseAttribute))
        if tcg_max_attest is not None:
            assert(isinstance(tcg_max_attest, BaseAttribute))
        if tcg_min_ca is not None:
            assert(isinstance(tcg_min_ca, BaseAttribute))
        if tcg_max_ca is not None:
            assert(isinstance(tcg_max_ca, BaseAttribute))

        if ((tcg_min_attest is None) and (tcg_max_attest is None) and
            (tcg_min_ca is None) and (tcg_max_ca is None)):
            # This is ok. No TCGs in attest cert.
            tcg_ok = True
            logger.debug("\nNo TCGs found in Attestation cert or CA cert. This is OK.")
        elif ((tcg_min_attest is not None) and (tcg_max_attest is not None) and
            (tcg_min_ca is None) and (tcg_max_ca is None)):
            logger.info("\nTCGs found in Attestation cert, but not in CA cert. This is invalid.")
        elif ((tcg_min_attest is None) and (tcg_max_attest is None) and
              (tcg_min_ca is not None) and (tcg_max_ca is not None)):
            logger.info("\nNo TCGs found in Attestation cert, but there are TCGs in CA cert. This is invalid.")
        elif ((tcg_min_attest is not None) and (tcg_max_attest is not None) and
              (tcg_min_ca is not None) and (tcg_max_ca is not None)):
            if (tcg_min_ca.value <= tcg_min_attest.value <=
                  tcg_max_attest.value <= tcg_max_ca.value):
                tcg_ok = True
                logger.debug("\nTCG values fall within CA constraints.")
            else:
                logger.info("\nTCG values are outside the CA constraints.")
        else:
            logger.info("\nInvalid TCG values")

        tcg_log_mesg =  "\nAttestation cert : tcg_min={0} tcg_max={1}". \
                                format(tcg_min_attest, tcg_max_attest) + \
                        "\nCA cert (allowed): tcg_min={0} tcg_max={1}\n". \
                                format(tcg_min_ca, tcg_max_ca)
        if (tcg_ok is False):
            logger.info(tcg_log_mesg)
        else:
            logger.debug(tcg_log_mesg)

        return tcg_ok
    def _validate_attributes_with_tcg_rule(self, attest_cert_obj):
        isValid = True
        #Enforce TCG rules
        attributes_zero_list = [
                      Certificate.SIGNATTR_SW_ID,
                      Certificate.SIGNATTR_HW_ID,
                      Certificate.SIGNATTR_OEM_ID,
                      Certificate.SIGNATTR_MODEL_ID,
                      ]

        attributes_none_list = [
                      Certificate.SIGNATTR_APP_ID,
                      Certificate.SIGNATTR_CRASH_DUMP,
                      Certificate.SIGNATTR_ROT_EN,
                      ]

        if attest_cert_obj.tcg_min and attest_cert_obj.tcg_max:
            #Only enforce TCG rules currently
            for attr_name in attributes_zero_list:
                attr = attest_cert_obj.get_attr(attr_name)
                if attr.value != 0:
                    logger.debug("{0} should be 0 under TCG validation rules. Current value is {1}".\
                                 format(attr_name, attr.str))
                    isValid = False

            for attr_name in attributes_none_list:
                attr = attest_cert_obj.get_attr(attr_name)
                if attr != None:
                    logger.debug("{0} should be None under TCG validation rules. Current value is {1}".\
                                 format(attr_name, attr.str))
                    isValid = False

            attr = attest_cert_obj.get_attr(Certificate.SIGNATTR_DEBUG)
            if attr is not None and attr.value != DEBUG_DISABLED:
                logger.debug("{0} should be 2 under TCG validation rules. Current value is {1}".\
                             format(Certificate.SIGNATTR_DEBUG, attr.str))
                isValid = False

        return isValid
    if len(args) > 1:
        feature = args[1]
        for supported_feature in FEATURES_LIST:
            if feature == supported_feature.CMD_ARG_TOOL_NAME:
                supported_feature.main(supported_feature.parse_args(sys.argv[1:]))
                break
        else:
            raise RuntimeError('Feature provided from command line: "' + feature + '" is invalid.' + '\n'
                               '       ' + 'Please choose from : ' + str([f.CMD_ARG_TOOL_NAME for f in FEATURES_LIST]))

if __name__ == '__main__':
    try:
        # Check that the command line are valid and are normalized.
        args = SectoolsParser().pos_args

        main(args)

    except Exception:
        logger.debug(traceback.format_exc())
        logger.error(sys.exc_info()[1])
        sys.exit(1)

    except KeyboardInterrupt:
        print
        logger.error('Keyboard Interrupt Received. Exiting!')
        sys.exit(1)

    sys.exit(0)

    def _sign(self, hash_to_sign,
                    cert_config,
                    signing_attributes,
                    general_properties,
                    binary_to_sign):

        openssl_config_file_paths = self.config.signing.signer_attributes.local_signer_attributes.openssl_config_inputs

        self._validate_config(cert_config, general_properties, openssl_config_file_paths)

        # Obtain all the information from the signing_attributes

        debug_val = int(signing_attributes.debug, 16) if signing_attributes.debug is not None else None
        msm_part = int(signing_attributes.msm_part, 16)
        oem_id = int(signing_attributes.oem_id, 16)
        model_id = int(signing_attributes.model_id, 16)
        num_certs_in_certchain = general_properties.num_certs_in_certchain
        app_id = int(signing_attributes.app_id, 16) if signing_attributes.app_id is not None else None
        crash_dump = int(signing_attributes.crash_dump, 16) if signing_attributes.crash_dump is not None else None
        rot_en = int(signing_attributes.rot_en, 16) if signing_attributes.rot_en is not None else None

        # Create the crypto_params_dict
        self.certconfig_parser = CertConfigParser(cert_config, signing_attributes, general_properties)
        crypto_params_dict = self.certconfig_parser.get_crypto_params()

        hmac_params = signerutils.get_hmac_params_from_config(signing_attributes)

        # Create the attestation_certificate_key_pair
        attestation_certificate_key_pair = None

        root_certificate_params = crypto_params_dict['root_certificate_properties']
        root_certificate_params_is_valid, generate_new_root_certificate = self._validate_certificate_params_dict(root_certificate_params)
        if root_certificate_params_is_valid:
            if generate_new_root_certificate:
                logger.info('Generating new Root certificate and a random key')
                generated_root_key_pair = crypto_functions.gen_rsa_key_pair(general_properties.key_size, key_exponent=signing_attributes.exponent)
                root_cert, root_key_pair = crypto_functions.create_root_certficate(root_certificate_params, generated_root_key_pair, 7300, openssl_config_file_paths.openssl_configfile_path, 1)
            else:
                logger.info('Using a predefined Root certificate and a predefined key')
                logger.info('Key Used: '+ root_certificate_params['private_key_path'])
                logger.info('Certificate Used: '+ root_certificate_params['certificate_path'])
                root_cert, root_key_pair = self._get_certificate_and_key_pair_from_files(root_certificate_params)
        else:
            logger.error("Root certificate params are invalid! Please check config file.")
            raise RuntimeError("Root certificate params are invalid! Please check config file.")

        if num_certs_in_certchain > 2:
            logger.debug("Generating Attestation CA certificate, since certchain size is greater than 2")
            attestation_ca_certificate_params = crypto_params_dict['attest_ca_certificate_properties']
            attestation_ca_params_is_valid, generate_new_attestation_ca = self._validate_certificate_params_dict(attestation_ca_certificate_params)
            if attestation_ca_params_is_valid:
                if generate_new_attestation_ca:
                    logger.info('Generating new Attestation CA certificate and a random key')
                    generated_attestation_ca__key_pair = crypto_functions.gen_rsa_key_pair(general_properties.key_size, key_exponent=signing_attributes.exponent)
                    attestation_ca_certificate, attestation_ca_certificate_key_pair = \
                        crypto_functions.create_certificate(attestation_ca_certificate_params,
                                                            generated_attestation_ca__key_pair,
                                                            root_cert,
                                                            root_key_pair,
                                                            days=7300,
                                                            configfile=openssl_config_file_paths.openssl_configfile_path,
                                                            serial_num=1,
                                                            extfile_name=openssl_config_file_paths.ca_certificate_extensions_path)
                else:
                    logger.info('Using a predefined Attestation CA certificate and a predefined key')
                    logger.info('Key Used: '+ attestation_ca_certificate_params['private_key_path'])
                    logger.info('Certificate Used: '+ attestation_ca_certificate_params['certificate_path'])
                    attestation_ca_certificate, attestation_ca_certificate_key_pair = self._get_certificate_and_key_pair_from_files(attestation_ca_certificate_params)
            else:
                logger.error("Attestation CA certificate params are invalid! Please check config file.")
                raise RuntimeError("Attestation CA certificate params are invalid! Please check config file.")

        attestation_certificate_params = crypto_params_dict['attest_certificate_properties']
        attestation_certificate_params_is_valid, generate_new_attestation_certificate = self._validate_certificate_params_dict(attestation_certificate_params)

        if attestation_certificate_params_is_valid:
            if generate_new_attestation_certificate:
                #TCG support
                if self._is_tcg_supported(signing_attributes) is True:
                    if self.validate_tcg_from_config(attestation_ca_certificate_params['certificate_path'], signing_attributes) is False:
                        raise ConfigError("tcg_min and tcg_max are not set correctly in configuration."\
                                          "Signing will not continue."
                                          )
                    attestation_certificate_extensions_path = self._generate_attestation_certificate_extensions(
                                                                    openssl_config_file_paths.attestation_certificate_extensions_path,
                                                                    signing_attributes.tcg_min,
                                                                    signing_attributes.tcg_max)
                else:
                    attestation_certificate_extensions_path = openssl_config_file_paths.attestation_certificate_extensions_path


                logger.info('Generating new Attestation certificate and a random key')
                certificate_ou_sw_id ="01 " + hmac_params.sw_id_str + " SW_ID"
                certificate_ou_hw_id ="02 " + hmac_params.msm_id_str + " HW_ID"
                certificate_ou_oem_id ="04 " + "%0.4X" % oem_id + " OEM_ID"
                certificate_ou_sw_size ="05 " + "%0.8X" % len(binary_to_sign) + " SW_SIZE"
                certificate_ou_model_id ="06 " + "%0.4X" % model_id + " MODEL_ID"
                certificate_hash_alg = "07 0001 SHA256"

                certificate_ou = [
                                  certificate_ou_sw_id,
                                  certificate_ou_hw_id,
                                  certificate_ou_oem_id,
                                  certificate_ou_sw_size,
                                  certificate_ou_model_id,
                                  certificate_hash_alg
                                 ]
                #Optional attributes
                if debug_val is not None:
                    certificate_ou_debug_id ="03 " + "%0.16X" % debug_val + " DEBUG"
                    certificate_ou.append(certificate_ou_debug_id)
                if app_id is not None:
                    certificate_app_id = "08 " + "%0.16X" % app_id + " APP_ID"
                    certificate_ou.append(certificate_app_id)
                if crash_dump is not None:
                    certificate_crash_dump = "09 " + "%0.16X" % crash_dump + " CRASH_DUMP"
                    certificate_ou.append(certificate_crash_dump)
                if rot_en is not None:
                    certificate_rot_en = "10 " + "%0.16X" % rot_en + " ROT_EN"
                    certificate_ou.append(certificate_rot_en)

                if 'OU' in attestation_certificate_params.keys():
                    if type(attestation_certificate_params['OU'])==list:
                        for item in attestation_certificate_params['OU']:
                            certificate_ou.append(item)
                    else:
                        certificate_ou.append(attestation_certificate_params['OU'])

                attestation_certificate_params['OU']=certificate_ou

                if attestation_certificate_key_pair is None:
                    attestation_certificate_key_pair = crypto_functions.gen_rsa_key_pair(key_exponent=signing_attributes.exponent,
                                                                                         key_size_in_bits = general_properties.key_size)
                if num_certs_in_certchain > 2: #sign the attestation cert with the attestation_ca_cert
                    attestation_certificate, attestation_certificate_key_pair = \
                        crypto_functions.create_certificate(attestation_certificate_params,
                                                            attestation_certificate_key_pair,
                                                            attestation_ca_certificate,
                                                            attestation_ca_certificate_key_pair,
                                                            days=7300,
                                                            configfile=openssl_config_file_paths.openssl_configfile_path,
                                                            serial_num=1,
                                                            extfile_name=attestation_certificate_extensions_path)
                else: #sign the attestation cert with the root cert
                    attestation_certificate, attestation_certificate_key_pair = \
                        crypto_functions.create_certificate(attestation_certificate_params,
                                                            attestation_certificate_key_pair,
                                                            root_cert,
                                                            root_key_pair,
                                                            days=7300,
                                                            configfile=openssl_config_file_paths.openssl_configfile_path,
                                                            serial_num=1,
                                                            extfile_name=attestation_certificate_extensions_path)
                attestation_certificate = crypto_functions.cert_pem_to_der(attestation_certificate)

                #Clean temp file
                if self._is_tcg_supported(signing_attributes) is True:
                    c_path.clean_file(attestation_certificate_extensions_path)


            else:           #generate_new_attestation_certificate == False
                logger.info('Using a predefined Attestation certificate and a predefined key')
                logger.info('Key Used: '+ attestation_certificate_params['private_key_path'])
                logger.info('Certificate Used: '+ attestation_certificate_params['certificate_path'])
                attestation_certificate, attestation_certificate_key_pair = self._get_certificate_and_key_pair_from_files(attestation_certificate_params)
                attestation_certificate = crypto_functions.cert_pem_to_der(attestation_certificate)

                # Since the get_hmac_params_from_certificate_chain always works with the first cert in the cert chain,
                # this function will work for a single der certificate as well.
                hmac_params = crypto_functions.get_hmacparams_from_certificate_chain(attestation_certificate)
                hasher = Hasher()
                hash_to_sign=hasher.qcom_hmac(binary_to_sign, hmac_params)

            signature = crypto_functions.encrypt_with_private_key(hash_to_sign, attestation_certificate_key_pair['private_key'])
        else:
            logger.error("Attestation certificate params are invalid! Please check config file.")
            raise RuntimeError("Attestation certificate params are invalid! Please check config file.")

        if num_certs_in_certchain > 2:
            attestation_ca_certificate = crypto_functions.cert_pem_to_der(attestation_ca_certificate)
        else:
            attestation_ca_certificate = None

        root_cert = crypto_functions.cert_pem_to_der(root_cert)

        root_cert_list = self.certconfig_parser.get_rootcerts()
        certificate_list = self._get_certificate_list(general_properties.num_root_certs,
                                                      num_certs_in_certchain,
                                                      attestation_certificate,
                                                      attestation_ca_certificate,
                                                      root_cert,
                                                      root_cert_list)

        cert_chain=crypto_functions.create_certificate_chain(certificate_list)

        signer_output = SignerOutput()
        signer_output.root_cert = root_cert
        signer_output.attestation_ca_cert = attestation_ca_certificate
        signer_output.attestation_cert = attestation_certificate
        signer_output.signature = signature
        signer_output.cert_chain = cert_chain
        signer_output.root_cert_list = root_cert_list
        signer_output.attestation_key = attestation_certificate_key_pair['private_key']

        return signer_output