forked from FiloSottile/mkcert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtruststore_java.go
135 lines (117 loc) · 3.61 KB
/
truststore_java.go
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
// Copyright 2018 The mkcert Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"crypto/sha1"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"hash"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
)
var (
hasJava bool
hasKeytool bool
javaHome string
cacertsPath string
keytoolPath string
storePass string = "changeit"
)
func init() {
if runtime.GOOS == "windows" {
keytoolPath = filepath.Join("bin", "keytool.exe")
} else {
keytoolPath = filepath.Join("bin", "keytool")
}
if v := os.Getenv("JAVA_HOME"); v != "" {
hasJava = true
javaHome = v
log.Printf("JAVA_HOME: \"%s\" ✅\n", os.Getenv("JAVA_HOME"))
if pathExists(filepath.Join(v, keytoolPath)) {
hasKeytool = true
keytoolPath = filepath.Join(v, keytoolPath)
log.Printf("KEYTOOL: \"%s\" ✅\n", keytoolPath)
} else {
log.Printf("KEYTOOL: \"%s\" ❌\n", keytoolPath)
}
if pathExists(filepath.Join(v, "lib", "security", "cacerts")) {
cacertsPath = filepath.Join(v, "lib", "security", "cacerts")
}
if pathExists(filepath.Join(v, "jre", "lib", "security", "cacerts")) {
cacertsPath = filepath.Join(v, "jre", "lib", "security", "cacerts")
}
if (cacertsPath == "") {
log.Printf("CACERTS: \"%s\" ❌\n", cacertsPath)
} else {
log.Printf("CACERTS: \"%s\" ✅\n", cacertsPath)
}
} else {
log.Printf("JAVA_HOME: \"%s\" ❌\n", os.Getenv("JAVA_HOME"))
}
}
func (m *mkcert) checkJava() bool {
if !hasKeytool {
return false
}
// exists returns true if the given x509.Certificate's fingerprint
// is in the keytool -list output
exists := func(c *x509.Certificate, h hash.Hash, keytoolOutput []byte) bool {
h.Write(c.Raw)
fp := strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
return bytes.Contains(keytoolOutput, []byte(fp))
}
keytoolOutput, err := exec.Command(keytoolPath, "-list", "-keystore", cacertsPath, "-storepass", storePass).CombinedOutput()
fatalIfCmdErr(err, "keytool -list", keytoolOutput)
// keytool outputs SHA1 and SHA256 (Java 9+) certificates in uppercase hex
// with each octet pair delimitated by ":". Drop them from the keytool output
keytoolOutput = bytes.Replace(keytoolOutput, []byte(":"), nil, -1)
// pre-Java 9 uses SHA1 fingerprints
s1, s256 := sha1.New(), sha256.New()
return exists(m.caCert, s1, keytoolOutput) || exists(m.caCert, s256, keytoolOutput)
}
func (m *mkcert) installJava() {
args := []string{
"-importcert", "-noprompt",
"-keystore", cacertsPath,
"-storepass", storePass,
"-file", filepath.Join(m.CAROOT, rootName),
"-alias", m.caUniqueName(),
}
out, err := execKeytool(exec.Command(keytoolPath, args...))
fatalIfCmdErr(err, "keytool -importcert", out)
}
func (m *mkcert) uninstallJava() {
args := []string{
"-delete",
"-alias", m.caUniqueName(),
"-keystore", cacertsPath,
"-storepass", storePass,
}
out, err := execKeytool(exec.Command(keytoolPath, args...))
if bytes.Contains(out, []byte("does not exist")) {
return // cert didn't exist
}
fatalIfCmdErr(err, "keytool -delete", out)
}
// execKeytool will execute a "keytool" command and if needed re-execute
// the command with commandWithSudo to work around file permissions.
func execKeytool(cmd *exec.Cmd) ([]byte, error) {
out, err := cmd.CombinedOutput()
if err != nil && bytes.Contains(out, []byte("java.io.FileNotFoundException")) && runtime.GOOS != "windows" {
origArgs := cmd.Args[1:]
cmd = commandWithSudo(cmd.Path)
cmd.Args = append(cmd.Args, origArgs...)
cmd.Env = []string{
"JAVA_HOME=" + javaHome,
}
out, err = cmd.CombinedOutput()
}
return out, err
}