Skip to content

Commit 7e69350

Browse files
authored
Fix SSL connections on Firefox 54+ (#201)
* Fix SSL connections on Firefox 54+ Closes #200
1 parent 655425d commit 7e69350

12 files changed

+488
-503
lines changed

ant/apple/apple-keygen.sh.in

Lines changed: 127 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -7,241 +7,208 @@
77
# 2. Exports public certificate from Java Keystore #
88
# 3. Imports into Apple OS X Trusted Root Certs #
99
# #
10-
# Note: If [sslcert] and [sslkey] are specified, import to browser/OS is omitted. #
10+
# Note: If [trustedcert] and [trustedkey] are specified, import to browser/OS is #
11+
# omitted. #
1112
# #
1213
# Depends: #
1314
# java #
1415
# #
1516
# Optional: #
16-
# openssl - Required if providing [sslcert], [sslkey] parameters #
17+
# openssl - Required if providing [trustedcert], [trustedkey] parameters #
1718
# #
1819
# Usage: #
19-
# $ ./${apple.keygen.name} "install" [hostname] [sslcert] [sslkey] #
20+
# $ ./${apple.keygen.name} "install" [hostname] [trustedcert] [trustedkey] #
2021
# $ ./${apple.keygen.name} "uninstall" #
2122
# #
2223
##########################################################################################
2324

24-
# Random password hash
25-
password=$(cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-z0-9' | fold -w ${jks.passlength} | head -n 1)
26-
27-
# Check for java
28-
${apple.jvmver} > /dev/null 2>&1
29-
fallback=$?
25+
# Handle CN=${ssl.cn} override
26+
cnoverride="$2"
3027

31-
#
3228
# Handle trusted ssl certificate
3329
if [[ -n $3 && -n $4 ]]; then
34-
sslcertpath="$3"
35-
sslkeypath="$4"
36-
makekeystore="${ssl.convert}"
37-
else
38-
makekeystore="${jks.command}"
39-
fi
40-
41-
42-
makedercert="${der.command}"
43-
installdir="${apple.installdir}"
44-
45-
# Substitution variables (!storepass, !keypass, !install, etc)
46-
install="${jks.install}"
47-
storepass="${jks.storepass}"
48-
keypass="${jks.keypass}"
49-
keystore="${jks.keystore}"
50-
dercert="${der.cert}"
51-
props="${jks.properties}"
52-
keytool="${jks.keytool}"
53-
keytoolfallback="${apple.jvmfallback}/${jks.keytool}"
54-
55-
# Keystore generation variable substitutions
56-
keystorepath=$(echo "$keystore" | sed -e "s|$install|$installdir|g")
57-
makekeystore=$(echo "$makekeystore" | sed -e "s|$storepass|$password|g")
58-
makekeystore=$(echo "$makekeystore" | sed -e "s|$keypass|$password|g")
59-
makekeystore=$(echo "$makekeystore" | sed -e "s|$keystore|$keystorepath|g")
60-
61-
62-
if [ $fallback -eq 0 ]; then
63-
# Prefix with java_home --exec
64-
makekeystore="${apple.jvmcmd} $makekeystore"
65-
else
66-
# Fallback on Internet Plug-Ins version if needed
67-
makekeystore=$(echo "$makekeystore" | sed -e "s|$keytool|$keytoolfallback|g")
30+
trustedcertpath="$3"
31+
trustedkeypath="$4"
6832
fi
6933

70-
# Cert export variable substitutions
71-
dercertpath=$(echo "$dercert" | sed -e "s|$install|$installdir|g")
72-
makedercert=$(echo "$makedercert" | sed -e "s|$storepass|$password|g")
73-
makedercert=$(echo "$makedercert" | sed -e "s|$keypass|$password|g")
74-
makedercert=$(echo "$makedercert" | sed -e "s|$keystore|$keystorepath|g")
75-
makedercert=$(echo "$makedercert" | sed -e "s|$dercert|$dercertpath|g")
34+
# Random password hash
35+
password=$(cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-z0-9' | fold -w ${ssl.passlength} | head -n 1)
7636

77-
if [ $fallback -eq 0 ]; then
37+
if ${apple.jvmver} > /dev/null 2>&1; then
7838
# Prefix with java_home --exec
79-
makedercert="${apple.jvmcmd} $makedercert"
39+
keytoolcmd="${apple.jvmcmd} keytool"
8040
else
8141
# Fallback on Internet Plug-Ins version if needed
82-
makedercert=$(echo "$makedercert" | sed -e "s|$keytool|$keytoolfallback|g")
83-
fi
84-
85-
# // Handle "community" mode, custom signing auth cert
86-
if [ -n "${build.type}" ]; then
87-
authcert="${authcert.install}"
88-
authcertpath=$(echo "$authcert" | sed -e "s|$install|$installdir|g")
42+
keytoolcmd="${apple.jvmfallback}/keytool"
8943
fi
9044

45+
# Check for IPv4 address
46+
function ip4 {
47+
if [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
48+
return 0
49+
fi
50+
return 1
51+
}
9152

92-
# Property file containing jks signing info
93-
propspath=$(echo "$props" | sed -e "s|$install|$installdir|g")
94-
95-
# Convert trusted SSL cert to jks
96-
function create_pkcs12 {
97-
echo "Creating PKCS12 keypair..."
98-
keypair="${ssl.keypair}"
99-
sslcert="${ssl.cert}"
100-
sslkey="${ssl.key}"
101-
generated="${ssl.command}"
102-
103-
keypairpath=$(echo "$keypair" | sed -e "s|$install|$installdir|g")
104-
generated=$(echo "$generated" | sed -e "s|$keypair|$keypairpath|g")
105-
generated=$(echo "$generated" | sed -e "s|$sslcert|$sslcertpath|g")
106-
generated=$(echo "$generated" | sed -e "s|$sslkey|$sslkeypath|g")
107-
generated=$(echo "$generated" | sed -e "s|$keypass|$password|g")
108-
109-
makekeystore=$(echo "$makekeystore" | sed -e "s|$keypair|$keypairpath|g")
110-
111-
eval "$generated" > /dev/null 2>&1
112-
check_exists "$keypairpath"
113-
114-
if [ $? -ne 0 ]; then
115-
echo "Error creating PKCS12 keypair from $sslcertpath, $sslkeypath to $keypairpath"
116-
echo -e "${bash.failure}\n"
117-
exit 1
53+
# Replace all install-time variables
54+
function replace_vars {
55+
cmd=$(echo "$1" | sed -e "s|\"keytool\"|$keytoolcmd|g")
56+
57+
# Handle CN=${ssl.cn} override
58+
if [ -n "$cnoverride" ]; then
59+
cmd=$(echo "$cmd" | sed -e "s|CN=${ssl.cn},|CN=$cnoverride,|g")
60+
if ip4 "$cnoverride"; then
61+
cmd=$(echo "$cmd" | sed -e "s|san=dns:${ssl.cn},|san=ip:$cnoverride,|g")
62+
else
63+
cmd=$(echo "$cmd" | sed -e "s|san=dns:${ssl.cn},|san=dns:$cnoverride,|g")
64+
fi
65+
# Remove dangling san
66+
cmd=$(echo "$cmd" | sed -e "s|,dns:${ssl.cnalt}||g")
11867
fi
11968

120-
# Remove lingering self-signed certs
121-
rm "$dercertpath" > /dev/null 2>&1
69+
cmd=$(echo "$cmd" | sed -e "s|\!install|${apple.installdir}|g")
70+
cmd=$(echo "$cmd" | sed -e "s|\!storepass|$password|g")
71+
cmd=$(echo "$cmd" | sed -e "s|\!keypass|$password|g")
72+
cmd=$(echo "$cmd" | sed -e "s|\!sslcert|$trustedcertpath|g")
73+
cmd=$(echo "$cmd" | sed -e "s|\!sslkey|$trustedkeypath|g")
12274

75+
echo "$cmd"
12376
return 0
12477
}
12578

79+
# Handle "community" mode, custom signing auth cert
80+
if [ -n '${build.type}' ]; then
81+
authcertpath=$(echo "${authcert.install}" | sed -e "s|\!install|${apple.installdir}|g")
82+
fi
83+
12684
# Write out the secure websocket properties file
12785
function write_properties {
128-
echo "Writing properties file..."
129-
echo "wss.alias=${jks.alias}" > "$propspath"
86+
propspath=$(echo "$1" | sed -e "s|\!install|${apple.installdir}|g")
87+
keystorepath=$(echo "${ssl.jks}" | sed -e "s|\!install|${apple.installdir}|g")
88+
echo "wss.alias=${ssl.alias}" > "$propspath"
13089
echo "wss.keystore=$keystorepath" >> "$propspath"
13190
echo "wss.keypass=$password" >> "$propspath"
13291
echo "wss.storepass=$password" >> "$propspath"
133-
echo "wss.host=${jks.host}" >> "$propspath"
92+
echo "wss.host=${ssl.host}" >> "$propspath"
13493
if [ -n "$authcertpath" ]; then
13594
echo "authcert.override=$authcertpath" >> "$propspath"
13695
fi
13796
echo "" >> "$propspath"
138-
check_exists "$propspath"
97+
check_exists "$propspath"
13998
return $?
14099
}
141100

142-
# Check to see if file exists
101+
# Delete a file if exists
102+
function delete_file {
103+
testfile=$(echo "$1" | sed -e "s|\!install|${apple.installdir}|g")
104+
rm -f "$testfile" > /dev/null 2>&1
105+
return 0
106+
}
107+
108+
# Check to see if file exists with optional message
143109
function check_exists {
144-
if [ -e "$1" ]; then
145-
echo -e "${bash.success}\n"
110+
testfile=$(echo "$1" | sed -e "s|\!install|${apple.installdir}|g")
111+
if [ -e "$testfile" ]; then
112+
if [ -n "$2" ]; then
113+
echo -e "${bash.success} $2 $testfile"
114+
else
115+
echo -e "${bash.success} $testfile"
116+
fi
146117
return 0
147118
fi
148-
echo -e "${bash.failure}\n"
119+
echo -e "${bash.failure} $testfile"
149120
return 1
150121
}
151122

152123
# Remove all matching system certificates
153124
function remove_certs {
154-
hash=$(security find-certificate -e "${vendor.email}" -Z |grep ^SHA-1|rev|cut -d' ' -f1|rev)
155-
if [ -n "$hash" ]; then
156-
security delete-certificate -Z "$hash" > /dev/null 2>&1
157-
# Recurse on self
158-
remove_certs
159-
return 0
125+
if security find-certificate -e "${vendor.email}" -Z > /dev/null 2>&1; then
126+
echo -e "${bash.success} Found certificate matching ${vendor.email}"
127+
hash=$(security find-certificate -e "${vendor.email}" -Z |grep ^SHA-1|rev|cut -d' ' -f1|rev)
128+
if [ -n "$hash" ]; then
129+
# Remove and recurse
130+
security delete-certificate -Z "$hash" > /dev/null 2>&1 && remove_certs
131+
fi
132+
else
133+
echo -e "${bash.success} No more matching certificates found"
160134
fi
161-
# No certs found, exit
162-
return 1
135+
136+
return 0
163137
}
164138

165-
# Check for IPv4 address
166-
function ip4 {
167-
if [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
168-
return 0
139+
# Runs a steps, optionally checks for a file
140+
# e.g: run_step "Description" "ls -al *.txt > ./out" "./out"
141+
function run_step {
142+
if eval "$(replace_vars "$2") > /dev/null 2>&1"; then
143+
if [ -z "$3" ]; then
144+
echo -e "${bash.success} $1"
145+
return 0
146+
elif check_exists "$3" "$1"; then
147+
return 0
148+
else
149+
return 1
150+
fi
169151
fi
152+
echo -e "${bash.failure}\n"
170153
return 1
171154
}
172155

173-
# Handle CN=${jks.cn} override
174-
if [ -n "$2" ]; then
175-
cname="CN=${jks.cn},"
176-
newcname="CN=$2,"
177-
san="san=dns:${jks.cn},"
178-
newsan="san=dns:$2,"
179-
newipsan="san=ip:$2,"
180-
cnalt=",dns:${jks.cnalt}"
181-
newcnalt=""
182-
183-
makekeystore=$(echo "$makekeystore" | sed -e "s|$cname|$newcname|g")
184-
if ip4 "$2"; then
185-
makekeystore=$(echo "$makekeystore" | sed -e "s|$san|$newipsan|g")
186-
else
187-
makekeystore=$(echo "$makekeystore" | sed -e "s|$san|$newsan|g")
188-
fi
189-
makekeystore=$(echo "$makekeystore" | sed -e "s|$cnalt|$newcnalt|g")
190-
fi
191-
192156
#
193157
# Uninstall mode
194158
#
195159
if [ "$1" == "uninstall" ]; then
196-
echo "Removing installed certificates (warnings are safe to ignore)..."
160+
echo -e "\nRemoving installed certificates..."
197161
remove_certs
198-
echo -e "${bash.success}\n"
162+
echo -e "\n[Finished ${apple.keygen.name}]\n"
199163
exit 0
200164
fi
201165

202166
#
203167
# Install mode
204168
#
205169

206-
# Delete old keystore, if exists
207-
rm -f "$keystorepath" > /dev/null 2>&1
170+
# Delete old files if exist
171+
delete_file "${ssl.jks}"
172+
delete_file "${ssl.crt}"
208173

209174
# Handle trusted ssl certificate, if specified
210-
if [ -n "$sslcertpath" ]; then
211-
create_pkcs12
212-
echo "Creating keystore for secure websockets..."
213-
eval "$makekeystore" > /dev/null 2>&1
214-
check_exists "$keystorepath"
215-
write_properties
216-
status=$?
217-
echo "Finished"
218-
exit $status
175+
if [ -n "$trustedcertpath" ]; then
176+
echo -e "\nCreating keystore for secure websockets..."
177+
run_step "\nConverting to PKCS12 keypair" "${trusted.command}" "${trusted.keypair}"
178+
run_step "\nConverting to jks format" "${trusted.convert}" "${ssl.jks}"
179+
write_properties "${ssl.properties}" || exit 1
180+
echo -e "\n[Finished ${apple.keygen.name}]\n"
181+
exit 0
219182
fi
220183

221184
# Handle self-signed certificate
222-
echo "Creating keystore for secure websockets..."
223-
eval "$makekeystore" > /dev/null 2>&1
224-
check_exists "$keystorepath"
225-
226-
echo "Converting keystore to native certificate..."
227-
eval "$makedercert" > /dev/null 2>&1
228-
check_exists "$dercertpath"
229-
230-
write_properties
231-
232-
echo "Removing old certificates (warnings are safe to ignore)..."
185+
echo -e "\nCreating keystore for secure websockets..."
186+
# Delete old files if exist
187+
delete_file "${ca.jks}"
188+
delete_file "${ca.crt}"
189+
delete_file "${ssl.csr}"
190+
191+
run_step "Creating a CA keypair" "${ca.jkscmd}" "${ca.jks}" || exit 1
192+
run_step "Exporting CA certificate" "${ca.crtcmd}" "${ca.crt}" || exit 1
193+
run_step "Creating an SSL keypair" "${ssl.jkscmd}" "${ssl.jks}" || exit 1
194+
run_step "Creating an SSL CSR" "${ssl.jkscsr}" "${ssl.csr}" || exit 1
195+
run_step "Issuing SSL certificate from CA" "${ssl.crtcmd}" "${ssl.crt}" || exit 1
196+
run_step "Importing CA certificate into SSL keypair" "${ssl.importca}" "" || exit 1
197+
run_step "Importing chained SSL certificate into SSL keypair" "${ssl.importssl}" "" || exit 1
198+
199+
echo -e "\nWriting properties file..."
200+
write_properties "${ssl.properties}" || exit 1
201+
202+
echo -e "\nRemoving installed certificates..."
233203
remove_certs
234-
echo -e "${bash.success}\n"
235-
236-
echo "Installing certificate..."
237204

238205
# Install new certificate
239-
security add-trusted-cert -d -r "${apple.keygen.store}" -k "${apple.keychain}" "$dercertpath"
240-
if [ $? -eq 0 ]; then
241-
echo -e "${bash.success}\n"
242-
else
243-
echo -e "${bash.failure}\n"
244-
fi
206+
run_step "Installing certificate" "${apple.keygen.install}" "" || exit 1
207+
208+
echo -e "\nCleaning up..."
209+
delete_file "${ca.jks}"
210+
delete_file "${ssl.csr}"
211+
delete_file "${ssl.crt}"
245212

246-
echo "Finished"
213+
echo -e "\n[Finished ${apple.keygen.name}]\n"
247214
exit 0

ant/apple/apple.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ apple.keygen.store=trustRoot
1414
apple.keygen.name=apple-keygen.sh
1515
apple.keygen.in=${basedir}/ant/apple/${apple.keygen.name}.in
1616
apple.keygen.out=${dist.dir}/auth/${apple.keygen.name}
17+
apple.keygen.install=security add-trusted-cert -d -r \\"${apple.keygen.store}\\" -k \\"${apple.keychain}\\" \\"${ca.crt}\\"
1718
apple.jvmver=/usr/libexec/java_home -v ${javac.target}+
1819
apple.jvmcmd=${apple.jvmver} --exec
1920
apple.jvmfallback=/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin

0 commit comments

Comments
 (0)