-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadd-local-trust
160 lines (143 loc) · 6.47 KB
/
add-local-trust
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/python3
# vim:set et sw=4:
#
# add-local-cert - a script to convert local PEM formatted cefticicates to p11-kit fomrat
# Prints extraneous debuging info and sest DESTDIR to './dest' by default
debug = False
import os
import argparse
import re
import sys
import tempfile
import subprocess
# Get DESTDIR value from environment if set
DESTDIR = os.getenv('DESTDIR')
if DESTDIR is None:
DESTDIR = ''
if debug == True:
DESTDIR = './dest'
# Contants
OPENSSL = "/usr/bin/openssl"
LOCALDIR = DESTDIR + "/etc/ssl/local"
# Parse aruments
parser = argparse.ArgumentParser(prog='add-local-trust',
description='Creates a local p11-kit trust file from a PEM formatted certficate',
epilog='Example: add-local-trust --server-auth /etc/pki/anchors/00cb2416.p11-kit')
parser.add_argument('-s', '--serverauth', action='store_true', help='Add Server Auth trust')
parser.add_argument('-e', '--email', action='store_true', help='Add E-mail trust')
parser.add_argument('-c', '--codesigning', action='store_true', help='Add Code Signing trust')
parser.add_argument('-d', '--distrust', action='store_true',
help='Completely distrust the certificate (overrides other trust arguments)')
parser.add_argument('filename', help='Path to PEM encoded certificate file')
args = parser.parse_args()
if debug == True:
print("Server Auth trust is: %s" % (args.serverauth))
print("E-Mail trust is: %s" % (args.email))
print("Code Signing trust is: %s" % (args.codesigning))
print("Distrust is: %s" % (args.distrust))
print("Filename is: %s" % (args.filename))
# Determine trust
trust = ''
if args.serverauth == True:
trust = 'satrust'
if args.email == True:
if trust == '':
trust = 'smtrust'
else:
trust == trust + ',smtrust'
if args.codesigning == True:
if trust == '':
trust = 'cstrust'
else:
trust == trust + ',cstrust'
if args.distrust == True:
trust = 'distrusted'
# Defualt to server auth if no trust args passed
if trust == '':
trust = 'satrust'
# Verify that file exists
if not os.path.exists(args.filename):
print("File not found: %s!" % (args.filename))
print("Exiting...\n\n")
exit(1)
if debug == True:
print("Trust value is: %s" % (trust))
print("Filename is %s" % (args.filename))
# Make sure localdir is present
os.makedirs(LOCALDIR, mode = 0o755, exist_ok = True)
def get_cert_hash(filepath):
gethash = [OPENSSL, "x509", "-hash", "-in", filepath, "-noout"]
certhash = subprocess.check_output(gethash).decode('utf-8').strip()
return certhash;
def get_trust_value(trustlist):
if trust == 'distrusted':
trust_ext_oid = "1.3.6.1.4.1.3319.6.10.1"
trust_ext_value = "0.%06%0a%2b%06%01%04%01%99w%06%0a%01%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
else:
trust_ext_oid = "2.5.29.37"
if trust == 'satrust':
trust_ext_value = "0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%01"
if trust == 'satrust,smtrust':
trust_ext_value = "0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01"
if trust == 'satrust,cstrust':
trust_ext_value = "0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
if trust == 'satrust,smtrust,cstrust':
trust_ext_value = "0%2a%06%03U%1d%25%01%01%ff%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
if trust == 'smtrust':
trust_ext_value = "0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%04"
if trust == 'smtrust,cstrust':
trust_ext_value = "0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%03"
if trust == 'cstrust':
trust_ext_value = "0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%03"
if trust == '':
trust_ext_value = "0%18%06%03U%1d%25%01%01%ff%04%0e0%0c%06%0a%2b%06%01%04%01%99w%06%0a%10"
return trust_ext_oid,trust_ext_value;
def get_p11_label(srcpem):
ostcmd = [OPENSSL, "x509", "-in", srcpem, "--noout", "-text"]
openssl_text = subprocess.check_output(ostcmd).decode('utf-8').strip()
for line in openssl_text.split("\n"):
if "Subject:" in line:
subject_line = line.strip().replace(" = ", "=")
if "CN" in subject_line:
labelrex = re.search(r"CN=.*", subject_line)
label = labelrex.group(0).replace("CN=", "")
elif "OU" in subject_line:
labelrex = re.search(r"OU=.*", subject_line)
label = re.sub(",.*$", "", labelrex.group(0).replace("OU=", ""))
elif "O" in subject_line:
labelrex = re.search(r"O=.*", subject_line)
label = re.sub(",.*$", "", labelrex.group(0).replace("O=", ""))
return label;
def write_p11_file(srcpem,trust_oid,trust_value,trust):
ostcmd = [OPENSSL, "x509", "-in", srcpem, "--noout", "-text"]
openssl_text = subprocess.check_output(ostcmd).decode('utf-8').strip()
oskcmd = [OPENSSL, "x509", "-in", srcpem, "-noout", "-pubkey"]
openssl_key = subprocess.check_output(oskcmd).decode('utf-8').strip()
keyhash = get_cert_hash(srcpem)
filepath = LOCALDIR + "/" + keyhash + ".p11-kit"
label = get_p11_label(srcpem)
with open(srcpem, 'r') as file:
srcpem_text = file.read()
print("\nWriting anchor: %s\n Label: %s\n Keyhash: %s\n Trust: %s\n" % (filepath, label, keyhash, trust.replace("satrust", "Server Auth").replace("smtrust", "E-mail").replace("cstrust", "Code Signing").replace(",", ", ")))
writep11 = open(filepath, 'w')
writep11.write("[p11-kit-object-v1]\n")
writep11.write("label: \"" + label + "\"\n")
writep11.write("class: x-certificate-extension\n")
writep11.write("object-id: " + trust_oid + "\n")
writep11.write("value: \"" + trust_value + "\"\n")
writep11.write("modifiable: false\n")
writep11.write(openssl_key + "\n\n")
writep11.write("[p11-kit-object-v1]\n")
writep11.write("label: \"" + label + "\"\n")
writep11.write("trusted: true\n")
# nss-mozilla-ca-policy is always false for modified certificates
writep11.write("nss-mozilla-ca-policy: false\n")
writep11.write("modifiable: false\n")
# nss-{server,email}-distrust-after are always forever for modified certs
writep11.write("nss-server-distrust-after: \"%00\"\n")
writep11.write("nss-email-distrust-after: \"%00\"\n")
writep11.write(srcpem_text + "\n")
writep11.write(re.sub(r"\n", "\n#", (re.sub(r"^", '#', openssl_text))) + "\n")
return 0;
trust_oid,trust_value = get_trust_value(trust)
write_p11_file(args.filename,trust_oid,trust_value,trust)