mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 14:14:56 +03:00
c47eed6a64
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
139 lines
5.9 KiB
Python
139 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Certificate Authority management agent using OpenSSL and cryptography library."""
|
|
|
|
import json
|
|
import sys
|
|
import argparse
|
|
from datetime import datetime
|
|
|
|
try:
|
|
from cryptography import x509
|
|
from cryptography.x509.oid import NameOID
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
from datetime import timedelta
|
|
except ImportError:
|
|
print("Install: pip install cryptography")
|
|
sys.exit(1)
|
|
|
|
|
|
def generate_ca_certificate(cn="Internal Root CA", org="Organization", days=3650):
|
|
"""Generate a self-signed root CA certificate."""
|
|
key = rsa.generate_private_key(public_exponent=65537, key_size=4096)
|
|
subject = issuer = x509.Name([
|
|
x509.NameAttribute(NameOID.COMMON_NAME, cn),
|
|
x509.NameAttribute(NameOID.ORGANIZATION_NAME, org),
|
|
])
|
|
cert = (x509.CertificateBuilder()
|
|
.subject_name(subject)
|
|
.issuer_name(issuer)
|
|
.public_key(key.public_key())
|
|
.serial_number(x509.random_serial_number())
|
|
.not_valid_before(datetime.utcnow())
|
|
.not_valid_after(datetime.utcnow() + timedelta(days=days))
|
|
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
|
|
.add_extension(x509.KeyUsage(digital_signature=True, key_cert_sign=True,
|
|
crl_sign=True, content_commitment=False,
|
|
key_encipherment=False, data_encipherment=False,
|
|
key_agreement=False, encipher_only=False,
|
|
decipher_only=False), critical=True)
|
|
.sign(key, hashes.SHA256()))
|
|
return cert, key
|
|
|
|
|
|
def generate_server_cert(ca_cert, ca_key, cn, san_names, days=365):
|
|
"""Generate a server certificate signed by the CA."""
|
|
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
|
subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)])
|
|
san = x509.SubjectAlternativeName([x509.DNSName(n) for n in san_names])
|
|
cert = (x509.CertificateBuilder()
|
|
.subject_name(subject)
|
|
.issuer_name(ca_cert.subject)
|
|
.public_key(key.public_key())
|
|
.serial_number(x509.random_serial_number())
|
|
.not_valid_before(datetime.utcnow())
|
|
.not_valid_after(datetime.utcnow() + timedelta(days=days))
|
|
.add_extension(san, critical=False)
|
|
.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)
|
|
.sign(ca_key, hashes.SHA256()))
|
|
return cert, key
|
|
|
|
|
|
def audit_certificate(cert_path):
|
|
"""Audit an existing certificate for security issues."""
|
|
with open(cert_path, "rb") as f:
|
|
cert_data = f.read()
|
|
cert = x509.load_pem_x509_certificate(cert_data)
|
|
issues = []
|
|
if cert.public_key().key_size < 2048:
|
|
issues.append({"issue": "Weak key size", "severity": "HIGH",
|
|
"detail": f"Key size {cert.public_key().key_size} < 2048"})
|
|
if cert.not_valid_after_utc.replace(tzinfo=None) < datetime.utcnow():
|
|
issues.append({"issue": "Certificate expired", "severity": "CRITICAL",
|
|
"detail": f"Expired on {cert.not_valid_after_utc}"})
|
|
days_remaining = (cert.not_valid_after_utc.replace(tzinfo=None) - datetime.utcnow()).days
|
|
if 0 < days_remaining < 30:
|
|
issues.append({"issue": "Certificate expiring soon", "severity": "HIGH",
|
|
"detail": f"{days_remaining} days remaining"})
|
|
sig_algo = cert.signature_hash_algorithm
|
|
if sig_algo and sig_algo.name in ("sha1", "md5"):
|
|
issues.append({"issue": f"Weak signature algorithm: {sig_algo.name}", "severity": "HIGH"})
|
|
return {
|
|
"subject": cert.subject.rfc4514_string(),
|
|
"issuer": cert.issuer.rfc4514_string(),
|
|
"not_before": str(cert.not_valid_before_utc),
|
|
"not_after": str(cert.not_valid_after_utc),
|
|
"key_size": cert.public_key().key_size,
|
|
"serial": cert.serial_number,
|
|
"issues": issues,
|
|
}
|
|
|
|
|
|
def run_audit(cert_path=None, generate=False, cn=None, org=None):
|
|
"""Execute CA operations."""
|
|
print(f"\n{'='*60}")
|
|
print(f" CERTIFICATE AUTHORITY AGENT")
|
|
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
|
|
print(f"{'='*60}\n")
|
|
|
|
if cert_path:
|
|
info = audit_certificate(cert_path)
|
|
print(f"--- CERTIFICATE AUDIT ---")
|
|
print(f" Subject: {info['subject']}")
|
|
print(f" Issuer: {info['issuer']}")
|
|
print(f" Valid: {info['not_before']} to {info['not_after']}")
|
|
print(f" Key Size: {info['key_size']}")
|
|
print(f" Issues: {len(info['issues'])}")
|
|
for i in info["issues"]:
|
|
print(f" [{i['severity']}] {i['issue']}: {i.get('detail', '')}")
|
|
return info
|
|
|
|
if generate:
|
|
cert, key = generate_ca_certificate(cn=cn or "Internal Root CA", org=org or "Org")
|
|
print(f"--- CA CERTIFICATE GENERATED ---")
|
|
print(f" Subject: {cert.subject.rfc4514_string()}")
|
|
print(f" Serial: {cert.serial_number}")
|
|
return {"status": "generated", "subject": cert.subject.rfc4514_string()}
|
|
|
|
return {}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Certificate Authority Agent")
|
|
parser.add_argument("--audit", help="Path to PEM certificate to audit")
|
|
parser.add_argument("--generate", action="store_true", help="Generate new CA")
|
|
parser.add_argument("--cn", help="Common name for CA cert")
|
|
parser.add_argument("--org", help="Organization name")
|
|
parser.add_argument("--output", help="Save report to JSON file")
|
|
args = parser.parse_args()
|
|
|
|
report = run_audit(args.audit, args.generate, args.cn, args.org)
|
|
if args.output:
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2, default=str)
|
|
print(f"\n[+] Report saved to {args.output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|