def get_cert_status(hostname, port, servername): conn = ssl.create_connection((hostname, port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=hostname) cert = sock.getpeercert(True) cert = ssl.DER_cert_to_PEM_cert(cert) cert = cert.encode('utf-8') cert = x509.load_pem_x509_certificate(cert, default_backend()) not_bef = cert.not_valid_before not_aft = cert.not_valid_after # subject = cert.subject # cn = subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value # print(cn) now = datetime.datetime.utcnow() if now < not_bef: return "ERROR", "cert in the future" still_valid = (not_aft - now).days # print(still_valid) if still_valid <= 0: return "ERROR", "cert expired: %d days" % -still_valid # TODO: check that hostname matches CN or alt names if still_valid <= 20: return "WARNING", "cert expires soon (%d<20 days)" % still_valid return "OK", "cert valid for %d days" % still_valid
def ssl_handler(conn, recv): try: host = re.search(r'Host:\s*([a-z.1-9-]*)', recv.decode()).group(1) host, recv = filter(host, recv, conn) ssl_sock = ssl.create_connection((host, 443)) sock = ssl_sock conn.send('HTTP/1.1 200 OK\r\n\r\n'.encode()) recv = get_recv(conn) sock.send(recv) except: conn.close() return while True: try: recv_host = get_recv(sock) if not recv_host: break conn.send(recv_host) recv_client = get_recv(conn) if not recv_client: break sock.send(recv_client) except Exception as e: print(e) break sock.close() conn.close()
def get_cert(self): conn = ssl.create_connection((self.urlparse.netloc, 443)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=self.urlparse.netloc) cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) # cert = ssl.get_server_certificate((self.urlparse.netloc, 443)) cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) return cert
def getExpiry(site, port): conn = ssl.create_connection((site, port)) context = ssl.SSLContext(ssl.PROTOCOL_TLS) sock = context.wrap_socket(conn, server_hostname=site) cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) return datetime.strptime(x509.get_notAfter().decode(), dateformat).isoformat()
def retrieve_ssl_certificate(hostname: str, port: int = 443) -> str: """Retreive the SSL certificate from a given hostname.""" import ssl with ssl.create_connection((hostname, port)) as conn: # type: ignore context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) with context.wrap_socket(conn, server_hostname=hostname) as sock: cert_data: bytes = sock.getpeercert(binary_form=True) # type: ignore return ssl.DER_cert_to_PEM_cert(cert_data)
def get_certificate_from_server(self, remote_server): print("Getting Server Certificate from {}:{}".format(remote_server["server"], remote_server["port"])) try: with ssl.create_connection((remote_server["server"], remote_server["port"])) as conn: context = ssl.SSLContext(ssl.PROTOCOL_TLS) sock = context.wrap_socket(conn, server_hostname=remote_server["server"]) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) return certificate except Exception as e: print("Network error: {}".format(e))
def get_certificate(url: str) -> str: """Download certificate from remote server.""" parsed_url = urlparse(url) hostname = parsed_url.hostname port = int(parsed_url.port or 443) conn = ssl.create_connection((hostname, port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=hostname) return ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))
def run(self): certs = [] self.plugin.logger.debug( "SSLCheck - SSLPortCheckerThread - checking {b}".format( b=self.binding)) try: connection = ssl.create_connection(self.binding) connection.settimeout(3) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(connection) remote_cert = asn1crypto.x509.Certificate.load( sock.getpeercert(True)) certs.append( SSLCheckResult(sni="", certificate=remote_cert['tbs_certificate'])) serial = remote_cert['tbs_certificate']['serial_number'].native # try additional SNI for sni in self.plugin.additional_sni: self.plugin.logger.debug( "SSLCheck - SSLPortCheckerThread - checking {b} SNI {s}". format(b=self.binding, s=sni)) connection = ssl.create_connection(self.binding) connection.settimeout(3) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(connection, server_hostname=sni) remote_cert = asn1crypto.x509.Certificate.load( sock.getpeercert(True)) # Only add certificate if differs from main certificate if (remote_cert['tbs_certificate']['serial_number'].native != serial): certs.append( SSLCheckResult( sni=sni, certificate=remote_cert['tbs_certificate'])) except: self.plugin.logger.debug( "SSLCheck - SSLPortCheckerThread - checking {b} - error/timed out" .format(b=self.binding)) self.plugin.logger.debug( "SSLCheck - SSLPortCheckerThread - finished checking {b}".format( b=self.binding)) self.plugin.sslinfo[self.binding] = certs
def getcerthttps(addr, port): try: conn = ssl.create_connection((addr, port)) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) sock = ctx.wrap_socket(conn, server_hostname=addr) # SNI pem_cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) response = M2Crypto.X509.load_cert_string(pem_cert) return response except Exception as ex: print(f"Exception: Connection error: {ex}") return None
def get_host_certificates_thumbprint(self, hostname, port): try: conn = ssl.create_connection((hostname, port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=hostname) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) return self.fingerprint(certificate) except ConnectionRefusedError: return '' except socket.gaierror: return ''
def retrieve_ssl_certificate(hostname: str, port: int = 443) -> str: """Retrieve the SSL certificate from a given hostname.""" import ssl with ssl.create_connection((hostname, port)) as conn: # type: ignore context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) with context.wrap_socket(conn, server_hostname=hostname) as sock: cert_data: bytes = sock.getpeercert( binary_form=True) # type: ignore return ssl.DER_cert_to_PEM_cert(cert_data)
def __init__(self, host, port): """Init.""" conn = ssl.create_connection((host, port)) context = ssl.SSLContext() sock = context.wrap_socket(conn, server_hostname=host) cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) self._x509 = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, cert ) self._fmt_not_after = time.strptime( self._x509.get_notAfter().decode("utf-8"), "%Y%m%d%H%M%SZ" )
def __load_cert(self): """Recovery the website certificate and its public key""" conn = ssl.create_connection((self.hostname, self.port_number)) context = ssl.SSLContext(ssl.PROTOCOL_TLS) sock = context.wrap_socket(conn, server_hostname=self.hostname) self.pem_data = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) self.certOpenSSL = crypto.load_certificate(crypto.FILETYPE_PEM, self.pem_data) self.certificate = self.certOpenSSL.to_cryptography() self.pubKey = self.certificate.public_key()
def get_cert_from_domain(domain): try: context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE with ssl.create_connection((domain, 443)) as sock: with context.wrap_socket(sock, server_hostname=domain) as sslsock: dercert = sslsock.getpeercert(True) data = ssl.DER_cert_to_PEM_cert(dercert) data = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, data) except Exception as e: data = str(e) return (domain, data)
def checkCertificate(_): domain = re.match(r"https:\/\/(.*)\/", _.TARGET).group(1) query = (domain, 443) try: # SNI traceable here connection = ssl.create_connection(query) context = ssl.SSLContext(ssl.PROTOCOL_TLS) sock = context.wrap_socket(connection, server_hostname=domain) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) except: e = sys.exc_info()[0] certificate = ssl.get_server_certificate(query) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, certificate) _.NOT_AFTER = datetime.strptime(x509.get_notAfter().decode(), "%Y%m%d%H%M%SZ")
def main(): args = parse_args() # Workaround needed to keep compatibility with positional and # named arguments if args.pemfile_n: args.pemfile = args.pemfile_n if args.pemfile: cert = crypto.load_certificate(crypto.FILETYPE_PEM, args.pemfile.read()) elif args.remote: hostname = args.remote if args.names: hostname = args.names[0] conn = ssl.create_connection((args.remote, args.port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=hostname) cert = crypto.load_certificate( crypto.FILETYPE_PEM, ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))) not_after = parse(cert.get_notAfter().decode('utf-8')) remaining = not_after - datetime.now(tzutc()) exit_code = 0 output = '' if args.names: missing_domain = verify_domains(cert, args.names) if missing_domain: output += '{} not found; '.format(missing_domain) exit_code = 2 output += 'Certificate expires at: {}'.format(not_after) if remaining < args.critical: exit_code = 2 elif remaining < args.warning: exit_code = 1 if exit_code == 0: print('OK: ' + output) elif exit_code == 1: print('WARNING: ' + output) elif exit_code == 2: print('CRITICAL: ' + output) exit(exit_code)
def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None): """Retrieve the certificate from the server at the specified address, and return it as a PEM-encoded string. If 'ca_certs' is specified, validate the server cert against it. If 'ssl_version' is specified, use it in the connection attempt.""" _, _ = addr if ca_certs is not None: cert_reqs = CERT_REQUIRED else: cert_reqs = CERT_NONE with create_connection(addr) as sock: with wrap_socket(sock, ssl_version=ssl_version, cert_reqs=cert_reqs, ca_certs=ca_certs) as sslsock: dercert = sslsock.getpeercert(True) sslsock = sock = None return DER_cert_to_PEM_cert(dercert)
def ssl_checker(host, port): ''' Extract some SSL Certificate properties ''' # To support the SNI Case conn = ssl.create_connection((host, port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=host) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) #certificate = ssl.get_server_certificate((host,port)) x509_certificate = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, certificate) notAfter = x509_certificate.get_notAfter() notBefore = x509_certificate.get_notBefore() issuer = x509_certificate.get_issuer() before_day = notBefore[6:8].decode('utf-8') before_month = notBefore[4:6].decode('utf-8') before_year = notBefore[:4].decode('utf-8') after_day = notAfter[6:8].decode('utf-8') after_month = notAfter[4:6].decode('utf-8') after_year = notAfter[:4].decode('utf-8') bef_date = date(int(before_year), int(before_month), int(before_day)) exp_date = date(int(after_year), int(after_month), int(after_day)) today = date.today() days_to_expire = today - exp_date days_to_expire = (abs(days_to_expire.days)) res = {} res[host] = {} res[host]['host'] = host res[host]['CN'] = issuer.CN res[host]['O'] = issuer.CN res[host]['days_to_expire'] = days_to_expire res[host]['expire_date'] = str(exp_date) res[host]['before_date'] = str(bef_date) return res
def __procotol_is_enable(self, context, protocol): """Return whether the connection with the server via the protocol provided in parameter is available. Keyword arguments: context -- ssl.SSLContex of the connection protocol -- protocol tested """ try: context.check_hostname = False context.verify_mode = ssl.CERT_NONE conn = ssl.create_connection((self.hostname, self.port_number)) sock = context.wrap_socket(conn, server_hostname=self.hostname) sock.do_handshake() if str(sock.version()).replace(".", "_") != protocol: return False return True except: return False
def fetch_cert_info(domain, ip, port): domain = domain.replace('*', 'www', 1) conn = ssl.create_connection((ip, port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) with context.wrap_socket(conn, server_hostname=domain) as sock: cert = crypto.load_certificate( crypto.FILETYPE_PEM, ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))) common_name = cert.get_subject().commonName not_after = parse_date(cert.get_notAfter().decode('utf-8')) remaining = not_after - datetime.now(tzutc()) data = { 'remaining': remaining, 'common_name': common_name, 'domain': domain, 'not_after': not_after } return data
def __init__(self, site, config): # self.port is set to the port in fqdn string first, then # config["port"], then defaults to 443. self.fqdn, *port = site.split(":") self.port = port[0] if port else config.get("port", None) self.port = self.port if self.port else 443 self.notifiers = [] self.notify_when_expiring_in = config.get("notify_when_expiring_in", 35) # The set is used to keep a reference to the plugin, otherwise # it is removed and imports in the plugin modules fail. self.plugin_source = set() notifiers = config.get("notifiers", {}) for name, params in notifiers.items(): self._load_notifier(name, params) # Do this to support sites that use SNI feature becasue # ssl.get_server_certificate(...) doesn't support SNI. try: sock = ssl.SSLContext().wrap_socket( ssl.create_connection((self.fqdn, self.port), 10), server_hostname=self.fqdn) except socket.timeout as e: self.cert = None logging.warn(e) return self.cert except socket.gaierror as e: self.cert = None logging.warn(e) return self.cert pem_data = ssl.DER_cert_to_PEM_cert(sock.getpeercert(binary_form=True)) sock.close() self.cert = x509.load_pem_x509_certificate( pem_data.encode("utf-8"), default_backend())
def __enum_cipher(self, context, protocol): """Returns the list of encryption suites available on the server for the protocol provided in parameter. Keyword arguments: context -- ssl.SSLContex of the connection protocol -- protocol tested """ print("{}{}\t {}: {}".format(Bcolors.RESET, Bcolors.BOLD, protocol, Bcolors.RESET)) cipher_enable = [] if protocol == "TLSv1_3": with open(os.path.dirname(__file__) + '/cipher_suite_tls_v13.json') as json_file: data = json.load(json_file) elif protocol == "TLSv1_2": with open(os.path.dirname(__file__) + '/cipher_suite_tls_v12.json') as json_file: data = json.load(json_file) elif protocol == "TLSv1_1": with open(os.path.dirname(__file__) + '/cipher_suite_tls_v11.json') as json_file: data = json.load(json_file) elif protocol == "TLSv1": with open(os.path.dirname(__file__) + '/cipher_suite_tls_v10.json') as json_file: data = json.load(json_file) for i in data['ciphersuites']: for key, value in i.items(): try: conn = ssl.create_connection((self.hostname, self.port_number)) context.set_ciphers(value["openssl_name"]) sock = context.wrap_socket(conn, server_hostname=self.hostname) sock.do_handshake() cipher_suite = CipherSuite.CipherSuite(key, value["security"]) cipher_enable.append(cipher_suite) print("{}\t\t{}{}".format(Bcolors.RESET, key, Bcolors.RESET)) except Exception as e: pass return cipher_enable
def isOrganization(hostname): """ Function looks up the SSL certificate for the domain, and checks if it is an OV or EV certificate by reading the following CertificatePolicies 2.23.140.1.2.2: Organization Validation 2.23.140.1.1: Extended Validation """ # Create a real connection in order to support SNI (server name indication) conn = ssl.create_connection((hostname, 443)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=hostname) cert_pem = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) cert = x509.load_pem_x509_certificate(cert_pem.encode(), default_backend()) # Find the certificate type for policy in cert.extensions.get_extension_for_class(x509.CertificatePolicies).value: oid = policy.policy_identifier.dotted_string if oid == '2.23.140.1.2.2' or oid == '2.23.140.1.1': return True return False
def check_host_certificate(host="www.google.com"): """ Given a Hostname will establish a RAW SSL Socket and get the peer certificate. The certificate is then parsed and then certain fields are brought back If cryptography.io is not present then dummy data is bought back """ port = 443 conn = ssl.create_connection((host, port)) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) sock = context.wrap_socket(conn, server_hostname=host) raw_pem_cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) try: parsed_cert = x509.load_pem_x509_certificate( raw_pem_cert.encode("UTF-8"), default_backend()) end_date = parsed_cert.not_valid_after time_to_expiry = (end_date - datetime.now()).days subject = str(parsed_cert.subject) serial = parsed_cert.serial_number logger.info("Parsed Certificate Sucessfully Using Cryptography.io") logger.info(subject) except: end_date = datetime.now() time_to_expiry = 0 subject = "" serial = 0 logger.warn( "Failed to Parse Certificate Using Cryptography.io -- using Placeholder Variables" ) return { "end_date": end_date, "time_to_expiry": time_to_expiry, "subject": subject, "serial": serial }
def get_ssl_certificate_expiry_days( domain_name, args=None, ): """get the domain expired date""" ssl_port = 443 #docker-registry.default.svc.cluster.local:5000 if ":" in domain_name: ssl_port = domain_name.split(":")[1] domain_name = domain_name.split(":")[0] conn = ssl.create_connection((domain_name, ssl_port)) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) context.verify_mode = ssl.CERT_REQUIRED context.check_hostname = not args.skip_check_hostname context.load_default_certs() for ca_file in args.add_ca_file: context.load_verify_locations(cafile=ca_file) logger.info("add_ca_file: " + ca_file) for ca_path in args.add_ca_path: context.load_verify_locations(capath=ca_path) logger.info("add_ca_path: " + ca_path) sock = context.wrap_socket(conn, server_hostname=domain_name) cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) notafter = x509.get_notAfter() notafter = notafter[0:8] now = datetime.datetime.now() notafter_t = datetime.datetime.strptime(notafter, '%Y%m%d') delta = notafter_t - now logger.info("[" + domain_name + "] certificate subject: " + str(x509.get_subject())) logger.info("[" + domain_name + "] will expire in: " + str(delta.days) + " days") return (delta.days if delta.days >= 0 else 0)
def get_ssl_certificate_expiry_days(domain_name): """get the domain expired date""" ssl_port = 443 #docker-registry.default.svc.cluster.local:5000 if ":" in domain_name: ssl_port = domain_name.split(":")[1] domain_name = domain_name.split(":")[0] conn = ssl.create_connection((domain_name, ssl_port)) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) sock = context.wrap_socket(conn, server_hostname=domain_name) cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) notafter = x509.get_notAfter() notafter = notafter[0:8] now = datetime.datetime.now() notafter_t = datetime.datetime.strptime(notafter, '%Y%m%d') delta = notafter_t - now logger.info("public url [" + domain_name + "] certificate subject: " + str(x509.get_subject())) logger.info("public url [" + domain_name + "] will expire in: " + str(delta.days) + " days") return (delta.days if delta.days >= 0 else 0)
def sslExpirationDate(address, port): if DUREE_ENTRE_CHAQUE_REQUETE != 0: sleep(DUREE_ENTRE_CHAQUE_REQUETE) try: conn = ssl.create_connection((address, int(port))) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) sock = context.wrap_socket(conn, server_hostname=address) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) certLoad = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, certificate) certinfo = {} certinfo["notBefore"] = datetime.datetime.strptime( certLoad.get_notBefore().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["notAfter"] = datetime.datetime.strptime( certLoad.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["serialNumber"] = certLoad.get_serial_number() if certLoad.get_issuer().CN != None: certinfo["deliver"] = certLoad.get_issuer().CN elif certLoad.get_issuer().O != None: certinfo["deliver"] = certLoad.get_issuer().O else: certinfo["deliver"] = "Introuvable" if certLoad.get_subject().CN != None: certinfo["deliverfor"] = certLoad.get_subject().CN if certLoad.get_subject().CN.lower() != address.lower(): if certLoad.get_subject().CN.lower() == "*." + '.'.join( address.lower().split('.')[-2:]): certinfo["status"] = "wildcard" else: for index in range(0, certLoad.get_extension_count()): if "subjectAltName" in certLoad.get_extension( index).get_short_name(): tmp = ''.join([ current if ord(current) < 128 else ' ' for current in certLoad.get_extension( index).get_data().lower() ]) #Remove non ASCII char tmp = ''.join([ current for current in tmp if current in string.printable ]) #Remove non printable char if "*." + '.'.join(address.lower().split('.') [-2:]) in ' '.join( tmp.split()).split(' '): certinfo["status"] = "wildcard" elif address.lower() not in ' '.join( tmp.split()).split(' '): return "notmatch" break else: certinfo["deliverfor"] = "Introuvable" return certinfo except socket.error as err: if ("WRONG_SSL_VERSION" in str(err) or "UNSUPPORTED_PROTOCOL" in str(err)): try: conn = ssl.create_connection((address, int(port))) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) sock = context.wrap_socket(conn, server_hostname=address) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) certLoad = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, certificate) certinfo = {} certinfo["notBefore"] = datetime.datetime.strptime( certLoad.get_notBefore().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["notAfter"] = datetime.datetime.strptime( certLoad.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["serialNumber"] = certLoad.get_serial_number() if certLoad.get_issuer().CN != None: certinfo["deliver"] = certLoad.get_issuer().CN elif certLoad.get_issuer().O != None: certinfo["deliver"] = certLoad.get_issuer().O else: certinfo["deliver"] = "Introuvable" if certLoad.get_subject().CN != None: certinfo["deliverfor"] = certLoad.get_subject().CN if certLoad.get_subject().CN.lower() != address.lower(): for index in range(0, certLoad.get_extension_count()): if certLoad.get_subject().CN.lower( ) == "*." + '.'.join( address.lower().split('.')[-2:]): certinfo["status"] = "wildcard" else: for index in range( 0, certLoad.get_extension_count()): if "subjectAltName" in certLoad.get_extension( index).get_short_name(): tmp = ''.join([ current if ord(current) < 128 else ' ' for current in certLoad.get_extension( index).get_data().lower() ]) #Remove non ASCII char tmp = ''.join([ current for current in tmp if current in string.printable ]) #Remove non printable char if "*." + '.'.join(address.lower( ).split('.')[-2:]) in ' '.join( tmp.split()).split(' '): certinfo["status"] = "wildcard" elif address.lower() not in ' '.join( tmp.split()).split(' '): return "notmatch" break else: certinfo["deliverfor"] = "Introuvable" return certinfo except ssl.SSLError as err: return "error" except socket.error as err: return "error" except: print "error" return "error" elif ("[Errno 0]" in str(err)): try: conn = ssl.create_connection((address, int(port))) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1) sock = context.wrap_socket(conn, server_hostname=address) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) certLoad = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, certificate) certinfo = {} certinfo["notBefore"] = datetime.datetime.strptime( certLoad.get_notBefore().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["notAfter"] = datetime.datetime.strptime( certLoad.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["serialNumber"] = certLoad.get_serial_number() if certLoad.get_issuer().CN != None: certinfo["deliver"] = certLoad.get_issuer().CN elif certLoad.get_issuer().O != None: certinfo["deliver"] = certLoad.get_issuer().O else: certinfo["deliver"] = "Introuvable" if certLoad.get_subject().CN != None: certinfo["deliverfor"] = certLoad.get_subject().CN if certLoad.get_subject().CN.lower() != address.lower(): if certLoad.get_subject().CN.lower( ) == "*." + '.'.join(address.lower().split('.')[-2:]): certinfo["status"] = "wildcard" else: for index in range(0, certLoad.get_extension_count()): if "subjectAltName" in certLoad.get_extension( index).get_short_name(): tmp = ''.join([ current if ord(current) < 128 else ' ' for current in certLoad.get_extension( index).get_data().lower() ]) #Remove non ASCII char tmp = ''.join([ current for current in tmp if current in string.printable ]) #Remove non printable char if "*." + '.'.join(address.lower().split( '.')[-2:]) in ' '.join( tmp.split()).split(' '): certinfo["status"] = "wildcard" elif address.lower() not in ' '.join( tmp.split()).split(' '): return "notmatch" break else: certinfo["deliverfor"] = "Introuvable" return certinfo except ssl.CertificateError as err: if DEBUG: print str(err) if ("doesn't match either of" in str(err)): return "notmatch" return "error" except socket.error as err: if ("[Errno 0]" in str(err)): try: conn = ssl.create_connection((address, int(port))) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) sock = context.wrap_socket(conn, server_hostname=address) certificate = ssl.DER_cert_to_PEM_cert( sock.getpeercert(True)) certLoad = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, certificate) certinfo = {} certinfo["notBefore"] = datetime.datetime.strptime( certLoad.get_notBefore().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["notAfter"] = datetime.datetime.strptime( certLoad.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ') certinfo["serialNumber"] = certLoad.get_serial_number() if certLoad.get_issuer().CN != None: certinfo["deliver"] = certLoad.get_issuer().CN elif certLoad.get_issuer().O != None: certinfo["deliver"] = certLoad.get_issuer().O else: certinfo["deliver"] = "Introuvable" if certLoad.get_subject().CN.lower() != address.lower( ): if certLoad.get_subject().CN.lower( ) == "*." + '.'.join( address.lower().split('.')[-2:]): certinfo["status"] = "wildcard" else: for index in range( 0, certLoad.get_extension_count()): if "subjectAltName" in certLoad.get_extension( index).get_short_name(): tmp = ''.join([ current if ord(current) < 128 else ' ' for current in certLoad.get_extension( index).get_data().lower() ]) #Remove non ASCII char tmp = ''.join([ current for current in tmp if current in string.printable ]) #Remove non printable char if "*." + '.'.join(address.lower( ).split('.')[-2:]) in ' '.join( tmp.split()).split(' '): certinfo["status"] = "wildcard" elif address.lower() not in ' '.join( tmp.split()).split(' '): return "notmatch" break return certinfo except socket.error as err: if DEBUG: print str(err) if ("[Errno 0]" in str(err)): return "INVALID CERT" except: print "error" return "error" print str(err) + "second socket" return "error" except: print "error" return "error" elif "Name or service not known" in str(err): return "errresolution" elif "Connection refused" in str(err): return "CONN REFUSED" if DEBUG: print str(err) return "error" except ssl.CertificateError as err: if ("doesn't match either of" in str(err)): return "notmatch" if DEBUG: print str(err) return "error" except ssl.gaierror as err: if "Name or service not known" in str(err): return "errresolution" except: print "error" return "error"
#!/usr/bin/env python import ssl import OpenSSL import argparse parser = argparse.ArgumentParser(description="Input server details") parser.add_argument('--host', dest='hostname', action='store', help='Server hostname') parser.add_argument('--sni', dest='server_name', action='store', default=None, help='Server SNI name') args = parser.parse_args() hostname = args.hostname server_name = args.server_name if args.server_name else hostname port = 443 conn = ssl.create_connection((hostname, port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=server_name) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, certificate) after = x509.get_notAfter() print(after)
def check(domain): print(domain) real_domain = '' subject_alt_name = '' created_at = '' expire_at = '' subject_cn = '' issuer_o = '' issuer_ou = '' issuer_cn = '' issuer_email_address = '' subject_organization_name = '' signature_algorithm = '' version = '' pubkey_bits = '' pubkey_type = '' serial_number = '' https_enabled = 0 https_valid = 0 https_redirection = 0 https_true_host = 0 https_valid_date = 0 https_error = '' try: http_url = requests.head('http://' + domain, timeout=15, allow_redirects=True).url https_url = requests.head('https://' + domain, timeout=15, allow_redirects=True).url http_uri = urlparse(http_url) https_uri = urlparse(https_url) real_domain = https_uri.netloc https_enabled = 'https' == https_uri.scheme conn = ssl.create_connection((real_domain, 443)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=real_domain) cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) https_valid = 1 https_redirection = https_enabled and http_uri.scheme == https_uri.scheme and http_uri.netloc == https_uri.netloc created_at = datetime.strptime(x509.get_notBefore().decode('ascii'), '%Y%m%d%H%M%SZ').strftime('%Y-%m-%d %H:%M:%S') expire_at = datetime.strptime(x509.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ').strftime('%Y-%m-%d %H:%M:%S') subject_cn = x509.get_subject().CN subject_organization_name = x509.get_subject().organizationName issuer_o = x509.get_issuer().O issuer_ou = x509.get_issuer().OU issuer_cn = x509.get_issuer().CN issuer_email_address = x509.get_issuer().emailAddress signature_algorithm = x509.get_signature_algorithm() version = x509.get_version() pubkey_bits = x509.get_pubkey().bits() pubkey_type = x509.get_pubkey().type() for i in xrange(x509.get_extension_count()): if 'subjectAltName' == x509.get_extension(i).get_short_name(): subject_alt_name = str(x509.get_extension(i)) true_host = re.sub(r"^(?:[a-zA-Z0-9\-\.]+\.)?([a-zA-Z0-9\-]+\.[a-zA-Z0-9]+)$", r"\1", real_domain) regex = re.compile(r"DNS:(\\*\.)?" + re.sub(r"\.", "\\.", true_host) + "(,.+|$)") https_true_host = true_host == subject_cn or None is not regex.search(subject_alt_name) https_valid_date = not x509.has_expired() serial_number = x509.get_serial_number() except requests.exceptions.RequestException as error: https_error = error.message except ssl.SSLError as error: https_error = error.message except OpenSSL.crypto.Error as error: https_error = error.message except socket.error as error: https_error = error.message except requests.packages.urllib3.exceptions.LocationValueError as error: https_error = error.message return [ str(domain), str(real_domain), str(subject_cn), str(subject_alt_name), str(created_at), str(expire_at), str(issuer_o), str(issuer_ou), str(issuer_cn), str(issuer_email_address), str(subject_organization_name), str(signature_algorithm), str(version), str(pubkey_bits), str(pubkey_type), str(serial_number), int(https_enabled), int(https_valid), int(https_true_host), int(https_valid_date), int(https_redirection), str(https_error) ]
def get_cert(target, port=443): conn = ssl.create_connection((target, port)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=target) return ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))
# assign our arguments to variables host = args.host port = args.port warning = args.warning critical = args.critical timeout = args.timeout if not critical <= warning: print( "The warning threshold must be greater than or equal to the critical threshold" ) exit(3) # set up ssl connection to host/port try: conn = ssl.create_connection((host, port)) except: print(status[2] + "error connecting to host/port") exit(2) # give ssl connection the protocol version try: context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) except: print(status[2] + "error connecting with SSLv23") exit(2) # use SNI to get the correct cert for the hostname try: sock = context.wrap_socket(conn, server_hostname=host) except:
def _utilities_extract_ssl_cert_from_url_function(self, event, *args, **kwargs): """Function: This function takes in a HTTPS URL and attempts to acquire its Certificate, saving it as an artifact. Inputs: A HTTPS_URL. Outputs: Certificate file encoded in JSON. Schema of the results : results = { "certificate": Certificate string encoded as JSON or NoneType, "successful": True if certificate is not NoneType; False otherwise } """ try: # Get the function parameters: https_url = kwargs.get("https_url") # text log = logging.getLogger(__name__) log.info("https_url: %s", https_url) if https_url is None: raise ValueError("Error: https_url must be specified.") url_dict = urlparse.urlparse(https_url) certificate = None # Init x509 as None and try to gather the cert conn = None # Init conn as None to prevent reference before assign try: ''' Not all input URLs will be formed properly Some may be all good and have the Scheme, netloc,path Others will not e.g www.google.com when passed to urlparse will not have a netloc param In these cases urlparse will stick the URL in the path attribute if at all https://docs.python.org/2/library/ssl.html#ssl.get_server_certificate ''' # If netloc is an empty string; we had issues parsing it from urlparse if not url_dict.netloc: # Empty strings are 'falsy'; # Add '//' to the URL this will sort out any 'www' url url_dict = urlparse.urlparse( '//' + https_url ) # Note; this wont fix urls with bad schemes i.e htp:/ if url_dict.port is not None: conn = ssl.create_connection( (url_dict.hostname, url_dict.port)) else: conn = ssl.create_connection((url_dict.hostname, 443)) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=url_dict.hostname) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) except Exception as parsing_ex: raise KeyError( "Problem encountered while parsing the cert. {}".format( parsing_ex)) finally: # Close the connection once we have what we want if conn is not None: conn.close() # Prepares a JSON object from the get_server_certificate function result serialized_cert = json.dumps(certificate, default=lambda o: o.__dict__, sort_keys=True, indent=4) # Results are used in PostProcessing script to create artifact on the platform results = { # If the certificate wasn't parsed; 'null' will be the result "certificate": (serialized_cert if serialized_cert is not 'null' else None), # x509 starts out as a None type; if unsuccessful it will still be a none type "successful": (certificate is not None) } # Produce a FunctionResult with the results yield FunctionResult(results) except Exception: yield FunctionError()
def getCertificates(domains: list,configName:str=None): currentConfig={} if args['audit'] != "list" and args['audit'] != "file": currentConfig['propertyName'] = configName certs=[] er=[] for host in domains: if args['verbose']: logger.debug("Looking up the certificate for '{}' ".format(host)) if "{{" in host: if args['verbose']: logger.warning("'{}' is a variable and will not be looked up!".format(host)) er.append("'{}' is a variable and will not be looked up!".format(host)) else: if validators.domain(host) != True: if args['verbose']: if configName is not None: logger.warning("'{}' is not a valid domain, on the configuration'{}'!".format(host,configName)) else: logger.warning("'{}' is not a valid domain!".format(host)) er.append("'{}' is not a valid domain!".format(host)) continue try: hostname = host port = 443 conn = ssl.create_connection((hostname,port), timeout=10) context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sock = context.wrap_socket(conn, server_hostname=hostname) certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True)) x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,certificate) except BaseException as e: if args['verbose']: logger.error("Can't connect to '{}' error: {}".format(host,str(e))) er.append("Can't connect to '{}' error: {}".format(host,str(e))) else: serial= '{0:x}'.format(x509.get_serial_number()) exp_date = str(x509.get_notAfter().decode('utf-8')) dt = parse(exp_date) daystoexp=dt.replace(tzinfo=None)-datetime.utcnow() item = {} item['Domain'] = str(host) item['Serial'] = str(serial) item['ExpDate'] = str(dt.date()) item['DaysLeft'] = daystoexp.days certs.append(item) if domains == []: if configName is not None: er.append("No customer origins found on the configuration '{}'.".format(configName)) if args['verbose']: logger.warning("No customer origins found on the configuration '{}.".format(configName)) else: er.append("No customer origins found.") if args['verbose']: logger.warning("No customer origins found.") if certs != []: currentConfig['certificates'] = certs if er != []: if args['audit'] != "list": currentConfig['errors'] = er else: errors.append(er) item_list.append(currentConfig) return