Analyze SSL certificate and connection security
(self, ssl_info, cert)
| 198 | return ssl_info |
| 199 | |
| 200 | def _analyze_ssl_security(self, ssl_info, cert): |
| 201 | """Analyze SSL certificate and connection security""" |
| 202 | analysis = { |
| 203 | 'security_level': 'Unknown', |
| 204 | 'warnings': [], |
| 205 | 'recommendations': [] |
| 206 | } |
| 207 | |
| 208 | try: |
| 209 | # Check cipher strength |
| 210 | cipher_bits = ssl_info.get('cipher_bits', 0) |
| 211 | if cipher_bits < 128: |
| 212 | analysis['warnings'].append(f"Weak cipher strength: {cipher_bits} bits") |
| 213 | analysis['security_level'] = 'Weak' |
| 214 | elif cipher_bits < 256: |
| 215 | analysis['security_level'] = 'Moderate' |
| 216 | else: |
| 217 | analysis['security_level'] = 'Strong' |
| 218 | |
| 219 | # Check protocol version |
| 220 | protocol = ssl_info.get('protocol_version', '') |
| 221 | if protocol in ['SSLv2', 'SSLv3', 'TLSv1', 'TLSv1.1']: |
| 222 | analysis['warnings'].append(f"Outdated protocol: {protocol}") |
| 223 | analysis['recommendations'].append("Upgrade to TLS 1.2 or higher") |
| 224 | |
| 225 | # Check certificate validity period |
| 226 | validity_days = ssl_info.get('validity_period_days', 0) |
| 227 | if validity_days > 825: # More than ~2.3 years |
| 228 | analysis['warnings'].append(f"Long validity period: {validity_days} days") |
| 229 | analysis['recommendations'].append("Consider shorter certificate validity periods") |
| 230 | |
| 231 | # Check expiration |
| 232 | days_until_expiry = ssl_info.get('days_until_expiry', 0) |
| 233 | if days_until_expiry < 30: |
| 234 | analysis['warnings'].append(f"Certificate expires soon: {days_until_expiry} days") |
| 235 | analysis['recommendations'].append("Renew certificate soon") |
| 236 | |
| 237 | # Check for self-signed |
| 238 | if ssl_info.get('is_self_signed', False): |
| 239 | analysis['warnings'].append("Self-signed certificate") |
| 240 | analysis['recommendations'].append("Use CA-issued certificate for production") |
| 241 | |
| 242 | # Check common name vs SAN |
| 243 | subject_cn = ssl_info.get('subject', {}).get('commonName', '') |
| 244 | san_dns = ssl_info.get('san_dns_names', []) |
| 245 | if subject_cn and subject_cn not in san_dns: |
| 246 | analysis['warnings'].append("Common Name not in Subject Alternative Names") |
| 247 | |
| 248 | except Exception as e: |
| 249 | analysis['error'] = str(e)[:MAX_ERROR_LENGTH] |
| 250 | |
| 251 | return analysis |
| 252 | |
| 253 | def _extract_public_key_info(self, cert): |
| 254 | """Extract public key information from certificate""" |
no outgoing calls
no test coverage detected