Files
mukul975 c47eed6a64 Production hardening: security fixes, code quality, 724 skills complete
- 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
2026-03-19 13:26:49 +01:00

144 lines
5.2 KiB
Python

#!/usr/bin/env python3
"""Agent for implementing end-to-end encryption (E2EE) for messaging using X25519 + AES-GCM."""
import json
import argparse
import os
try:
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey, X25519PublicKey
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes, serialization
HAS_CRYPTO = True
except ImportError:
HAS_CRYPTO = False
NONCE_SIZE = 12
KEY_SIZE = 32
HKDF_INFO = b"e2ee-messaging-v1"
def generate_keypair():
"""Generate X25519 key pair for Diffie-Hellman key exchange."""
private_key = X25519PrivateKey.generate()
public_key = private_key.public_key()
priv_bytes = private_key.private_bytes(
serialization.Encoding.Raw, serialization.PrivateFormat.Raw, serialization.NoEncryption()
)
pub_bytes = public_key.public_bytes(serialization.Encoding.Raw, serialization.PublicFormat.Raw)
return {
"private_key_hex": priv_bytes.hex(),
"public_key_hex": pub_bytes.hex(),
"algorithm": "X25519",
}
def derive_shared_secret(my_private_hex, their_public_hex):
"""Derive shared secret using X25519 ECDH + HKDF-SHA256."""
my_private = X25519PrivateKey.from_private_bytes(bytes.fromhex(my_private_hex))
their_public = X25519PublicKey.from_public_bytes(bytes.fromhex(their_public_hex))
shared_key = my_private.exchange(their_public)
derived_key = HKDF(
algorithm=hashes.SHA256(), length=KEY_SIZE, salt=None, info=HKDF_INFO
).derive(shared_key)
return derived_key
def encrypt_message(message, shared_key_hex):
"""Encrypt a message using AES-256-GCM with a shared key."""
key = bytes.fromhex(shared_key_hex)
nonce = os.urandom(NONCE_SIZE)
aesgcm = AESGCM(key)
ciphertext = aesgcm.encrypt(nonce, message.encode("utf-8"), None)
return {
"nonce_hex": nonce.hex(),
"ciphertext_hex": ciphertext.hex(),
"algorithm": "AES-256-GCM",
}
def decrypt_message(nonce_hex, ciphertext_hex, shared_key_hex):
"""Decrypt a message using AES-256-GCM."""
key = bytes.fromhex(shared_key_hex)
nonce = bytes.fromhex(nonce_hex)
ciphertext = bytes.fromhex(ciphertext_hex)
aesgcm = AESGCM(key)
plaintext = aesgcm.decrypt(nonce, ciphertext, None)
return {"plaintext": plaintext.decode("utf-8")}
def simulate_key_exchange(alice_name="Alice", bob_name="Bob"):
"""Simulate a complete key exchange between two parties."""
alice_kp = generate_keypair()
bob_kp = generate_keypair()
alice_shared = derive_shared_secret(alice_kp["private_key_hex"], bob_kp["public_key_hex"])
bob_shared = derive_shared_secret(bob_kp["private_key_hex"], alice_kp["public_key_hex"])
keys_match = alice_shared == bob_shared
return {
"alice_public_key": alice_kp["public_key_hex"],
"bob_public_key": bob_kp["public_key_hex"],
"shared_secret_match": keys_match,
"shared_key_hex": alice_shared.hex() if keys_match else None,
"key_exchange": "X25519 ECDH",
"kdf": "HKDF-SHA256",
"encryption": "AES-256-GCM",
}
def demo_full_flow():
"""Demonstrate complete E2EE message flow."""
kx = simulate_key_exchange()
if not kx["shared_secret_match"]:
return {"error": "Key exchange failed"}
shared_key = kx["shared_key_hex"]
test_message = "Hello, this is an end-to-end encrypted message."
encrypted = encrypt_message(test_message, shared_key)
decrypted = decrypt_message(encrypted["nonce_hex"], encrypted["ciphertext_hex"], shared_key)
return {
"key_exchange": kx,
"original_message": test_message,
"encrypted": encrypted,
"decrypted": decrypted,
"integrity_check": decrypted["plaintext"] == test_message,
}
def main():
if not HAS_CRYPTO:
print(json.dumps({"error": "cryptography library not installed"}))
return
parser = argparse.ArgumentParser(description="E2EE Messaging Agent (X25519 + AES-256-GCM)")
sub = parser.add_subparsers(dest="command")
sub.add_parser("keygen", help="Generate X25519 key pair")
sub.add_parser("exchange", help="Simulate key exchange")
sub.add_parser("demo", help="Full E2EE demo flow")
e = sub.add_parser("encrypt", help="Encrypt message")
e.add_argument("--message", required=True)
e.add_argument("--key", required=True, help="Shared key hex")
d = sub.add_parser("decrypt", help="Decrypt message")
d.add_argument("--nonce", required=True)
d.add_argument("--ciphertext", required=True)
d.add_argument("--key", required=True, help="Shared key hex")
args = parser.parse_args()
if args.command == "keygen":
result = generate_keypair()
elif args.command == "exchange":
result = simulate_key_exchange()
elif args.command == "demo":
result = demo_full_flow()
elif args.command == "encrypt":
result = encrypt_message(args.message, args.key)
elif args.command == "decrypt":
result = decrypt_message(args.nonce, args.ciphertext, args.key)
else:
parser.print_help()
return
print(json.dumps(result, indent=2, default=str))
if __name__ == "__main__":
main()