示例#1
0
 def sign(self, binary_to_sign, imageinfo):
     '''
     This function returns a SignerOutput object which has all the security assets generated
     by the signer.
     '''
     hasher = Hasher()
     hmacParams = signerutils.get_hmac_params_from_config(
         imageinfo.signing_attributes)
     hash_to_sign = hasher.qcom_hmac(binary_to_sign, hmacParams)
     return self._signer_impl.sign(hash_to_sign, imageinfo, binary_to_sign)
示例#2
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(signing_attributes.cass_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_oid_supported(signing_attributes) is True:
            attr_min, attr_max = Certificate.GetOIDAttrName(signing_attributes.object_id.name)
            #Min/max can be supplied by CASS server and is optional
            if signing_attributes.object_id.min:
                signingrequest.setSigningAttribute(attr_min, signing_attributes.object_id.min)
            if signing_attributes.object_id.max:
                signingrequest.setSigningAttribute(attr_max, signing_attributes.object_id.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 sign(self, binary_to_sign, imageinfo, debug_dir=None):
        '''
        This function returns a SignerOutput object which has all the security assets generated
        by the signer.
        '''
        self._signer_impl.validate_inputs(imageinfo.signing_attributes, imageinfo.general_properties)

        hasher = Hasher()
        hmacParams = signerutils.get_hmac_params_from_config(imageinfo.signing_attributes)
        hash_to_sign=hasher.qcom_hmac(binary_to_sign, hmacParams)
        signer_output = self._signer_impl.sign(hash_to_sign, imageinfo, binary_to_sign, debug_dir)

        #print certificate properties
        attestation_cert_obj = Certificate(signer_output.attestation_cert)
        logger.info('\nAttestation Certificate Properties:\n' + str(attestation_cert_obj))

        return signer_output
    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
示例#5
0
    def sign(self, binary_to_sign, imageinfo, debug_dir=None):
        '''
        This function returns a SignerOutput object which has all the security assets generated
        by the signer.
        '''
        self._signer_impl.validate_config(imageinfo)

        hasher = Hasher()
        hmacParams = signerutils.get_hmac_params_from_config(
            imageinfo.signing_attributes)
        hash_to_sign = hasher.qcom_hmac(binary_to_sign, hmacParams)
        signer_output = self._signer_impl.sign(hash_to_sign, imageinfo,
                                               binary_to_sign, debug_dir)

        #print certificate properties
        attestation_cert_obj = Certificate(signer_output.attestation_cert)
        logger.info('\nAttestation Certificate Properties:\n' +
                    str(attestation_cert_obj))

        return signer_output
示例#6
0
    def _sign(self, hash_to_sign,
                    imageinfo,
                    binary_to_sign,
                    sha_algo):

        # abstract some of the image information
        signing_attributes = imageinfo.signing_attributes
        general_properties = imageinfo.general_properties

        # GET OPENSSL DATA
        openssl_configfile = self.openssl_info.openssl_config
        openssl_attest_ca_xts = self.openssl_info.attest_ca_xts
        openssl_ca_cert_xts = self.openssl_info.ca_cert_xts

        # GET SIGNING ATTRIBUTE DATA
        debug_val = int(signing_attributes.debug, 16) if signing_attributes.debug is not None else None
        oem_id = int(signing_attributes.oem_id, 16) & 0xFFFF
        model_id = int(signing_attributes.model_id, 16) & 0xFFFF
        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
        soc_hw_version = int(signing_attributes.soc_hw_version, 16) if signing_attributes.soc_hw_version is not None else None
        mask_soc_hw_version = int(signing_attributes.mask_soc_hw_version, 16) if signing_attributes.mask_soc_hw_version is not None else None
        in_use_soc_hw_version = signing_attributes.in_use_soc_hw_version if signing_attributes.in_use_soc_hw_version is not None else None
        use_serial_number_in_signing = signing_attributes.use_serial_number_in_signing if signing_attributes.use_serial_number_in_signing is not None else None

        # GET CERTIFICATE INFORMATION
        cert_dict = {}
        cert_dict['id'] = imageinfo.cert_config
        cert_dict['chip'] = self.config.metadata.chipset
        cert_dict['keysize'] = general_properties.key_size
        cert_dict['exponent'] = general_properties.exponent
        cert_dict['mrc_index'] = general_properties.mrc_index

        # Can't use imageinfo.data_prov_basepath because MockImage can't use it
        cert_dict['dp_path'] = self.config.data_provisioning.base_path

        self.cert_data_object = CertData(cert_dict)
        crypto_params_dict = self.cert_data_object.get_crypto_params()

        # 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_configfile, 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_configfile,
                                                            serial_num=1,
                                                            extfile_name=openssl_ca_cert_xts)
                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_oid_supported(signing_attributes) is True:
                    if self.validate_oid_from_config(attestation_ca_certificate_params['certificate_path'], signing_attributes) is False:
                        raise ConfigError("{0} min and max are not set correctly in configuration."\
                                          "Signing will not continue.".format(signing_attributes.object_id.name)
                                          )
                    attestation_certificate_extensions_path = self._generate_attestation_certificate_extensions(
                                                                    openssl_attest_ca_xts,
                                                                    signing_attributes.object_id.name,
                                                                    signing_attributes.object_id.min,
                                                                    signing_attributes.object_id.max)
                else:
                    attestation_certificate_extensions_path = openssl_attest_ca_xts

                logger.info('Generating new Attestation certificate and a random key')
                hmac_params = signerutils.get_hmac_params_from_config(signing_attributes)
                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 = SHA1_OU_STRING if sha_algo == 'sha1' else SHA256_OU_STRING

                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 soc_hw_version is not None:
                    certificate_soc_hw_version = "11 " + "%0.8X" % soc_hw_version + " SOC_HW_VERSION"
                    certificate_ou.append(certificate_soc_hw_version)
                if mask_soc_hw_version is not None:
                    certificate_mask_soc_hw_version = "12 " + "%0.4X" % mask_soc_hw_version + " MASK_SOC_HW_VERSION"
                    certificate_ou.append(certificate_mask_soc_hw_version)
                if in_use_soc_hw_version is not None:
                    certificate_in_use_soc_hw_version = "13 " + "%0.4X" % in_use_soc_hw_version + " IN_USE_SOC_HW_VERSION"
                    certificate_ou.append(certificate_in_use_soc_hw_version)
                if use_serial_number_in_signing is not None:
                    certificate_use_serial_number_in_signing = "14 " + "%0.4X" % use_serial_number_in_signing + " USE_SERIAL_NUMBER_IN_SIGNING"
                    certificate_ou.append(certificate_use_serial_number_in_signing)

                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_configfile,
                                                            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_configfile,
                                                            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_oid_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, sha_algo)

            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.cert_data_object.get_rootcerts(general_properties.num_root_certs)

        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.root_key = root_key_pair['private_key']
        # Make sure the variable is defined
        try:
            attestation_ca_certificate_key_pair
        except Exception: pass
        else:
            signer_output.attestation_ca_key = attestation_ca_certificate_key_pair['private_key']
        signer_output.attestation_key = attestation_certificate_key_pair['private_key']

        return signer_output
    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
    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

        # 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_oid_supported(signing_attributes) is True:
                    if self.validate_oid_from_config(
                            attestation_ca_certificate_params[
                                'certificate_path'],
                            signing_attributes) is False:
                        raise ConfigError("{0} min and max are not set correctly in configuration."\
                                          "Signing will not continue.".format(signing_attributes.object_id.name)
                                          )
                    attestation_certificate_extensions_path = self._generate_attestation_certificate_extensions(
                        openssl_config_file_paths.
                        attestation_certificate_extensions_path,
                        signing_attributes.object_id.name,
                        signing_attributes.object_id.min,
                        signing_attributes.object_id.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_oid_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