get_cert.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #!/usr/bin/env python3
  2. import hashlib
  3. import logging
  4. import ssl
  5. import socket
  6. import click
  7. logging.basicConfig(level=logging.INFO,
  8. format='[%(levelname)-4s] %(message)s',
  9. datefmt='%Y-%m-%d %H:%M')
  10. logger = logging.getLogger('certo')
  11. def establish_conn(addr, port, starttls):
  12. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  13. sock.settimeout(1)
  14. try:
  15. if starttls:
  16. logger.debug("Using STARTTLS")
  17. logger.debug("Connecting to %s:%s" % (addr, port))
  18. sock.connect((addr, port))
  19. sock.send(b"STARTTLS\n")
  20. sock.recv(1000)
  21. wrapped_socket = ssl.wrap_socket(sock)
  22. else:
  23. wrapped_socket = ssl.wrap_socket(sock)
  24. wrapped_socket.connect((addr, port))
  25. return wrapped_socket.getpeercert(True)
  26. finally:
  27. wrapped_socket.close()
  28. def get_cert(addr, port, starttls):
  29. cert = establish_conn(addr, port, starttls)
  30. pem_cert = ssl.DER_cert_to_PEM_cert(cert)
  31. logger.debug("The certificate is:\n%s" % pem_cert)
  32. return cert
  33. def capitalize_and_colons(in_hash):
  34. in_hash = in_hash.upper()
  35. new_hash = in_hash[0:2]
  36. for i in range(2, len(in_hash), 2):
  37. new_hash += ":" + in_hash[i:i+2]
  38. return new_hash
  39. def compute_fingerprints(cert, with_colons):
  40. thumb_md5 = hashlib.md5(cert).hexdigest()
  41. thumb_sha1 = hashlib.sha1(cert).hexdigest()
  42. thumb_sha256 = hashlib.sha256(cert).hexdigest()
  43. logger.info("MD5: " + thumb_md5)
  44. if with_colons:
  45. logger.info(" " + capitalize_and_colons(thumb_md5))
  46. logger.info("SHA1: " + thumb_sha1)
  47. if with_colons:
  48. logger.info(" " + capitalize_and_colons(thumb_sha1))
  49. logger.info("SHA256: " + thumb_sha256)
  50. if with_colons:
  51. logger.info(" " + capitalize_and_colons(thumb_sha256))
  52. @click.command()
  53. @click.argument('address')#, help="address to be used to retrieve the certificate")
  54. @click.option('-p', '--port', default=443, type=click.IntRange(1,65535), help="The port to connect to.")
  55. @click.option('--starttls', is_flag=True, flag_value=True, help="Whether to use starttls on connection.")
  56. @click.option('--debug/--nodebug', is_flag=True, flag_value=False, help="Debug output.")
  57. @click.option('-o', '--output', help="Path to save the certificate to.")
  58. @click.option('--colons/--nocolons', is_flag=True, flag_value=False, help="Whether to output also hashed with colons")
  59. def doit(address, port, starttls, debug, output, colons):
  60. if debug:
  61. logger.setLevel(logging.DEBUG)
  62. cert = get_cert(address, port, starttls)
  63. if output:
  64. with open(output, 'w') as f:
  65. logger.debug("Opening file %s" % output)
  66. f.write(ssl.DER_cert_to_PEM_cert(cert))
  67. logger.info("The certificate has been saved to %s" % output)
  68. compute_fingerprints(cert, colons)
  69. if __name__ == '__main__':
  70. doit()