mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-02 17:07:42 +03:00
Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal
- Add scripts/agent.py and references/api-reference.md to all remaining skills - Update all 648 LICENSE files: copyright now reads 'Mahipal' - Add implementing-security-monitoring-with-datadog (new skill with full anatomy) - All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Certificate Authority management agent using OpenSSL and cryptography library."""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from cryptography import x509
|
||||
from cryptography.x509.oid import NameOID
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
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()
|
||||
Reference in New Issue
Block a user