This repository was archived by the owner on Dec 20, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathKeybox-Generator.py
More file actions
88 lines (68 loc) · 4.54 KB
/
Keybox-Generator.py
File metadata and controls
88 lines (68 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# Copyright (C) 2025 VD_Priv8 (VD171)
# This code is licensed under GNU AGPLv3 (https://www.gnu.org/licenses/agpl-3.0.html).
# See the LICENSE file for details.
import argparse, os, re, secrets, shutil, subprocess
INFO = {
"version": "1.3",
"author": "VD_Priv8 (VD171)",
"github": "https://github.com/VD171",
"telegram": "https://t.me/VD_Priv8"
}
def vd_random_serial():
return secrets.token_hex(16)
def main():
vd_parser = argparse.ArgumentParser(epilog=f"KeyBox Generator v{INFO['version']}\nby {INFO['author']}\nGitHub: {INFO['github']}\nTelegram: {INFO['telegram']}\n ", formatter_class=argparse.RawDescriptionHelpFormatter)
vd_parser.add_argument("--file", default="keybox.xml", help="Keybox file path")
vd_parser.add_argument("--days", default="365", help="How many days for expiring the new certificate")
vd_parser.add_argument("--title", default="New certificate generated by @VD_Priv8", help="Title for the new certificate. Use TEE for a valid title")
vd_parser.add_argument("--serial_ca", default="171", help="Set the unique Serial for the new certificate. Must be hex format. Use random for a valid Serial")
vd_parser.add_argument("--serial_subject", default="VDPriv8", help="Set serialNumber in Subject for the new certificate. Use random for a valid serialNumber")
vd_parser.add_argument("--out", default="keybox.new.xml", help="New Keybox file path")
vd_args = vd_parser.parse_args()
if not shutil.which("openssl"):
exit("Error: openssl not found! Be sure to run: pkg install openssl-tool")
if not os.path.exists(vd_args.file):
exit(f"Error: File '{vd_args.file}' not found! Use: --file")
if vd_args.serial_ca.lower() == "random":
vd_args.serial_ca = vd_random_serial()
if vd_args.serial_subject.lower() == "random":
vd_args.serial_subject = vd_random_serial()
try:
vd_serial_ca = int(vd_args.serial_ca, 16)
except ValueError:
exit("Error: serial_ca must be a valid hex string!")
vd_temp_key = ".temp.private.key"
vd_temp_cert = ".temp.certificate.pem"
vd_temp_new_key = ".temp.new.private.key"
vd_temp_new_csr = ".temp.new.certificate.csr"
with open(vd_args.file, encoding="utf-8") as vd_file:
vd_content = vd_file.read()
vd_content = re.sub(r"\s*<Key algorithm=\"rsa\">.*?</Key>(\s*)", r"\1", vd_content, flags=re.DOTALL)
if "<Key algorithm=\"ecdsa\">" not in vd_content:
exit("Error: ECDSA Key not found!")
vd_key = re.search(r"<PrivateKey format=\"pem\">(.*?)</PrivateKey>", vd_content, re.DOTALL)
vd_cert = re.search(r"(<Certificate format=\"pem\">(.*?)</Certificate>)", vd_content, re.DOTALL)
vd_number = re.search(r"(<NumberOfCertificates>(.*?)</NumberOfCertificates>)", vd_content, re.DOTALL)
if not all([vd_key, vd_cert, vd_number]):
exit("Error: Missing required elements!")
vd_new_key = subprocess.run("openssl ecparam -name prime256v1 -genkey", shell=True, capture_output=True, text=True, check=True).stdout.strip()
vd_new_key = re.search(r"(-----BEGIN (EC )?PRIVATE KEY-----.*?-----END (EC )?PRIVATE KEY-----)", vd_new_key, re.DOTALL).group(1)
for vd_temp, vd_data in {vd_temp_key: vd_key.group(1), vd_temp_cert: vd_cert.group(2), vd_temp_new_key: vd_new_key}.items():
with open(vd_temp, "w") as vd_file:
vd_file.write(re.sub(r"\s*([\r\n]+)\s*", r"\1", vd_data).strip())
if not os.path.exists(vd_temp):
exit(f"Error: Can't create {vd_temp}!")
subprocess.run(f"openssl req -new -key {vd_temp_new_key} -out {vd_temp_new_csr} -subj '/title={vd_args.title}/serialNumber={vd_args.serial_subject}'", shell=True, check=True)
vd_new_cert = subprocess.run(f"openssl x509 -req -in {vd_temp_new_csr} -CA {vd_temp_cert} -CAkey {vd_temp_key} -CAcreateserial -set_serial {vd_serial_ca} -days {vd_args.days} -sha256", shell=True, capture_output=True, text=True, check=True).stdout.strip()
vd_number_new = vd_number.group(1).replace(vd_number.group(2), str(int(vd_number.group(2)) + 1))
vd_cert_new = vd_cert.group(1).replace(vd_cert.group(2), vd_new_cert) + "\n" + vd_cert.group(1)
with open(vd_args.out, "w") as vd_file:
vd_file.write(vd_content.replace(vd_number.group(1), vd_number_new).replace(vd_key.group(1), vd_new_key).replace(vd_cert.group(1), vd_cert_new))
print(f"New keybox: {vd_args.out}.")
for vd_temp in [vd_temp_key, vd_temp_cert, vd_temp_new_key, vd_temp_new_csr, ".temp.certificate.srl"]:
try:
os.remove(vd_temp)
except FileNotFoundError:
pass
if __name__ == "__main__":
main()