'Common code to invoke xmlsec and parse the output.
:param com_list: Key-value parameter list for xmlsec
:param extra_args: Positional parameters to be appended after all
key-value parameters
:param validate_output: Parse and validate the output
:param exception: The exception class to raise on errors
:result: Whatever xmlsec wrote to an --output temporary file'

def _run_xmlsec(self, com_list, extra_args, validate_output=True, exception=XmlsecError, key_file=None, passphrase=None):

    ntf = NamedTemporaryFile(suffix='.xml', delete=self._xmlsec_delete_tmpfiles)
    com_list.extend(['--output', ntf.name])
    named_pipe = None
    if (key_file is not None):
        if (passphrase is not None):
            named_pipe = NamedPipe()
            with open(key_file) as f:
                key = importKey(f.read(), passphrase=passphrase)
            key_file = named_pipe.name
        com_list.extend(['--privkey-pem', key_file])
    com_list += extra_args
    logger.debug(('xmlsec    command:    %s' % '    '.join(com_list)))
    pof = Popen(com_list, stderr=PIPE, stdout=PIPE)
    if (named_pipe is not None):
        try:
            with open(named_pipe.name, 'wb') as f:
                f.write(key.exportKey())
        finally:
            named_pipe.close()
    p_out = pof.stdout.read()
    p_err = pof.stderr.read()
    if ((pof.returncode is not None) and (pof.returncode < 0)):
        logger.error((LOG_LINE % (p_out, p_err)))
        raise XmlsecError(('%d:%s' % (pof.returncode, p_err)))
    try:
        if validate_output:
            parse_xmlsec_output(p_err)
    except XmlsecError as exc:
        logger.error((LOG_LINE_2 % (p_out, p_err, exc)))
        raise
    ntf.seek(0)
    return (p_out, p_err, ntf.read())
