Sign a file using osslsigncode.

    Args:
      in_filename: file to read from
      out_filename: file to output to, if none we output to the same filename as
        the input with a .signed suffix.

    Returns:
      output filename string
    Raises:
      pexpect.ExceptionPexpect: if the expect invocation of osslsigncode fails.
      SigningError: for signing failures.

def SignFile(self, in_filename, out_filename=None):
    """Sign a file using osslsigncode.

    Args:
      in_filename: file to read from
      out_filename: file to output to, if none we output to the same filename as
        the input with a .signed suffix.

    Returns:
      output filename string
    Raises:
      pexpect.ExceptionPexpect: if the expect invocation of osslsigncode fails.
      SigningError: for signing failures.
    """
    if out_filename is None:
      out_filename = "%s.signed" % in_filename

    args = [
        "-certs", self.cert, "-key", self.key, "-n", self.application, "-t",
        "http://timestamp.verisign.com/scripts/timestamp.dll", "-h", "sha1",
        "-in", in_filename, "-out", out_filename
    ]

    try:
      output_log = io.StringIO()
      ossl = pexpect.spawn("osslsigncode", args)
      # Use logfile_read so we don't get the password we're injecting.
      ossl.logfile_read = output_log
      ossl.expect("Enter PEM pass phrase")
      ossl.sendline(self.password)
      ossl.wait()
    except pexpect.ExceptionPexpect:
      output_log.seek(0)
      logging.exception(output_log.read())
      raise

    if not os.path.exists(out_filename):
      raise SigningError("Expected output %s not created" % out_filename)

    try:
      subprocess.check_call(["osslsigncode", "verify", "-in", out_filename])
    except subprocess.CalledProcessError:
      logging.exception("Bad signature verification on %s", out_filename)
      raise SigningError("Bad signature verification on %s" % out_filename)

    return out_filename