blob: 3b4ca294ee923f127f0447849e62c969904e2535 [file] [log] [blame]
Serge Bazanskif3312ef2020-08-01 17:15:52 +02001package pki
2
3import (
Serge Bazanskief2fbaf2020-08-01 22:01:33 +02004 "crypto/tls"
5 "crypto/x509"
Serge Bazanskif3312ef2020-08-01 17:15:52 +02006 "fmt"
7 "io/ioutil"
8 "os"
9
10 "github.com/golang/glog"
11)
12
13// DeveloperCredentialsLocation returns the path containing HSPKI credentials
14// on developer machines. These are provisioned by //cluster/prodaccess, and
15// are used if available.
16func DeveloperCredentialsLocation() (string, error) {
17 cfgDir, err := os.UserConfigDir()
18 if err != nil {
19 glog.Exitf("UserConfigDir: %w", err)
20 }
21
22 return fmt.Sprintf("%s/hspki", cfgDir), nil
23}
24
Serge Bazanskief2fbaf2020-08-01 22:01:33 +020025// DeveloperCredentialsPrincipal returns the principal/DN for which the local
26// developer credentials are provisioned.
27func DeveloperCredentialsPrincipal() (string, error) {
28 creds, err := loadDeveloperCredentials()
29 if err != nil {
30 return "", fmt.Errorf("when loading developer credentials: %w", err)
31 }
32 pair, err := tls.X509KeyPair(creds.cert, creds.key)
33 if err != nil {
34 return "", fmt.Errorf("when loading developer client cert: %w", err)
35 }
36 cert, err := x509.ParseCertificate(pair.Certificate[0])
37 if err != nil {
38 return "", fmt.Errorf("when parsing developer client cert: %w", err)
39 }
40 return cert.Subject.CommonName, nil
41}
42
Serge Bazanskif3312ef2020-08-01 17:15:52 +020043type creds struct {
44 ca []byte
45 cert []byte
46 key []byte
47}
48
49func loadDeveloperCredentials() (*creds, error) {
50 path, err := DeveloperCredentialsLocation()
51 if err != nil {
52 return nil, fmt.Errorf("DeveloperCredentialsLocation: %w")
53 }
54
55 c := creds{}
56 for _, el := range []struct {
57 target *[]byte
58 path string
59 }{
60 {&c.ca, path + "/" + "ca.crt"},
61 {&c.cert, path + "/" + "tls.crt"},
62 {&c.key, path + "/" + "tls.key"},
63 } {
64 data, err := ioutil.ReadFile(el.path)
65 if err != nil {
66 return nil, fmt.Errorf("ReadFile(%q): %w", el.path, err)
67 }
68 *el.target = data
69 }
70
71 return &c, nil
72}
73
74func loadFlagCredentials() (*creds, error) {
75 c := creds{}
76 for _, el := range []struct {
77 target *[]byte
78 path string
79 }{
80 {&c.ca, flagCAPath},
81 {&c.cert, flagCertificatePath},
82 {&c.key, flagKeyPath},
83 } {
84 data, err := ioutil.ReadFile(el.path)
85 if err != nil {
86 return nil, fmt.Errorf("ReadFile(%q): %w", el.path, err)
87 }
88 *el.target = data
89 }
90
91 return &c, nil
92}
93
94func loadCredentials() (*creds, error) {
95 dev, err := loadDeveloperCredentials()
96 if err == nil {
97 return dev, nil
98 }
99 glog.Warningf("Could not load developer PKI credentials: %v", err)
100
101 fl, err := loadFlagCredentials()
102 if err == nil {
103 return fl, err
104 }
105 glog.Warningf("Could not load flag-defined PKI credentials: %v", err)
106
107 return nil, fmt.Errorf("could not load any credentials")
108}