(root)/
Python-3.11.7/
Tools/
scripts/
get-remote-certificate.py
       1  #!/usr/bin/env python3
       2  #
       3  # fetch the certificate that the server(s) are providing in PEM form
       4  #
       5  # args are HOST:PORT [, HOST:PORT...]
       6  #
       7  # By Bill Janssen.
       8  
       9  import re
      10  import os
      11  import sys
      12  import tempfile
      13  
      14  
      15  def fetch_server_certificate (host, port):
      16  
      17      def subproc(cmd):
      18          from subprocess import Popen, PIPE, STDOUT, DEVNULL
      19          proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, stdin=DEVNULL)
      20          status = proc.wait()
      21          output = proc.stdout.read()
      22          return status, output
      23  
      24      def strip_to_x509_cert(certfile_contents, outfile=None):
      25          m = re.search(br"^([-]+BEGIN CERTIFICATE[-]+[\r]*\n"
      26                        br".*[\r]*^[-]+END CERTIFICATE[-]+)$",
      27                        certfile_contents, re.MULTILINE | re.DOTALL)
      28          if not m:
      29              return None
      30          else:
      31              tn = tempfile.mktemp()
      32              with open(tn, "wb") as fp:
      33                  fp.write(m.group(1) + b"\n")
      34              try:
      35                  tn2 = (outfile or tempfile.mktemp())
      36                  cmd = ['openssl', 'x509', '-in', tn, '-out', tn2]
      37                  status, output = subproc(cmd)
      38                  if status != 0:
      39                      raise RuntimeError('OpenSSL x509 failed with status %s and '
      40                                         'output: %r' % (status, output))
      41                  with open(tn2, 'rb') as fp:
      42                      data = fp.read()
      43                  os.unlink(tn2)
      44                  return data
      45              finally:
      46                  os.unlink(tn)
      47  
      48      cmd = ['openssl', 's_client', '-connect', '%s:%s' % (host, port), '-showcerts']
      49      status, output = subproc(cmd)
      50  
      51      if status != 0:
      52          raise RuntimeError('OpenSSL connect failed with status %s and '
      53                             'output: %r' % (status, output))
      54      certtext = strip_to_x509_cert(output)
      55      if not certtext:
      56          raise ValueError("Invalid response received from server at %s:%s" %
      57                           (host, port))
      58      return certtext
      59  
      60  
      61  if __name__ == "__main__":
      62      if len(sys.argv) < 2:
      63          sys.stderr.write(
      64              "Usage:  %s HOSTNAME:PORTNUMBER [, HOSTNAME:PORTNUMBER...]\n" %
      65              sys.argv[0])
      66          sys.exit(1)
      67      for arg in sys.argv[1:]:
      68          host, port = arg.split(":")
      69          sys.stdout.buffer.write(fetch_server_certificate(host, int(port)))
      70      sys.exit(0)