Get SSL certificate information Args: ip: Target IP address port: Target port detailed: If False, returns only basic SSL info for speed
(self, ip, port, detailed=True)
| 42 | self.use_multiprocessing = False |
| 43 | |
| 44 | def get_ssl_certificate_info(self, ip, port, detailed=True): |
| 45 | """Get SSL certificate information |
| 46 | |
| 47 | Args: |
| 48 | ip: Target IP address |
| 49 | port: Target port |
| 50 | detailed: If False, returns only basic SSL info for speed |
| 51 | """ |
| 52 | ssl_info = {} |
| 53 | |
| 54 | try: |
| 55 | # Create SSL context |
| 56 | context = ssl.create_default_context() |
| 57 | context.check_hostname = False |
| 58 | context.verify_mode = ssl.CERT_NONE |
| 59 | |
| 60 | # Connect and get certificate |
| 61 | with socket.create_connection((ip, port), timeout=self.timeout) as sock: |
| 62 | with context.wrap_socket(sock, server_hostname=ip) as ssock: |
| 63 | # Get certificate in DER format (this always works) |
| 64 | cert_der = ssock.getpeercert(binary_form=True) |
| 65 | |
| 66 | # Get cipher and protocol info |
| 67 | cipher_info = ssock.cipher() |
| 68 | protocol_version = ssock.version() |
| 69 | |
| 70 | # Parse certificate using cryptography library if available (only if detailed=True) |
| 71 | cert = None |
| 72 | if detailed and cert_der and HAS_CRYPTOGRAPHY: |
| 73 | try: |
| 74 | cert_obj = x509.load_der_x509_certificate(cert_der, default_backend()) |
| 75 | cert = self._parse_x509_certificate(cert_obj) |
| 76 | except Exception as e: |
| 77 | ssl_info['parse_error'] = str(e)[:MAX_ERROR_LENGTH] |
| 78 | |
| 79 | # Always add basic connection info |
| 80 | if cipher_info: |
| 81 | ssl_info['cipher_suite'] = cipher_info[0] if len(cipher_info) > 0 else 'Unknown' |
| 82 | ssl_info['cipher_protocol'] = cipher_info[1] if len(cipher_info) > 1 else 'Unknown' |
| 83 | ssl_info['cipher_bits'] = cipher_info[2] if len(cipher_info) > 2 else 0 |
| 84 | |
| 85 | ssl_info['protocol_version'] = protocol_version or 'Unknown' |
| 86 | |
| 87 | # Certificate fingerprints (only if detailed) |
| 88 | if detailed and cert_der: |
| 89 | ssl_info['sha1_fingerprint'] = hashlib.sha1(cert_der).hexdigest().upper() |
| 90 | ssl_info['sha256_fingerprint'] = hashlib.sha256(cert_der).hexdigest().upper() |
| 91 | ssl_info['md5_fingerprint'] = hashlib.md5(cert_der).hexdigest().upper() |
| 92 | |
| 93 | # Detailed certificate information (only if detailed=True) |
| 94 | if detailed and cert and not cert.get('error'): |
| 95 | # Basic certificate info - handle the tuple structure properly |
| 96 | try: |
| 97 | subject_list = cert.get('subject', []) |
| 98 | if subject_list: |
| 99 | ssl_info['subject'] = dict((x[0], x[1]) for x in subject_list if len(x) >= 2) |
| 100 | |
| 101 | issuer_list = cert.get('issuer', []) |