forked from hswaw/hscloud
108 lines
2.4 KiB
Go
108 lines
2.4 KiB
Go
package pki
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
|
|
"github.com/golang/glog"
|
|
)
|
|
|
|
// DeveloperCredentialsLocation returns the path containing HSPKI credentials
|
|
// on developer machines. These are provisioned by //cluster/prodaccess, and
|
|
// are used if available.
|
|
func DeveloperCredentialsLocation() (string, error) {
|
|
cfgDir, err := os.UserConfigDir()
|
|
if err != nil {
|
|
glog.Exitf("UserConfigDir: %w", err)
|
|
}
|
|
|
|
return fmt.Sprintf("%s/hspki", cfgDir), nil
|
|
}
|
|
|
|
// DeveloperCredentialsPrincipal returns the principal/DN for which the local
|
|
// developer credentials are provisioned.
|
|
func DeveloperCredentialsPrincipal() (string, error) {
|
|
creds, err := loadDeveloperCredentials()
|
|
if err != nil {
|
|
return "", fmt.Errorf("when loading developer credentials: %w", err)
|
|
}
|
|
pair, err := tls.X509KeyPair(creds.cert, creds.key)
|
|
if err != nil {
|
|
return "", fmt.Errorf("when loading developer client cert: %w", err)
|
|
}
|
|
cert, err := x509.ParseCertificate(pair.Certificate[0])
|
|
if err != nil {
|
|
return "", fmt.Errorf("when parsing developer client cert: %w", err)
|
|
}
|
|
return cert.Subject.CommonName, nil
|
|
}
|
|
|
|
type creds struct {
|
|
ca []byte
|
|
cert []byte
|
|
key []byte
|
|
}
|
|
|
|
func loadDeveloperCredentials() (*creds, error) {
|
|
path, err := DeveloperCredentialsLocation()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("DeveloperCredentialsLocation: %w")
|
|
}
|
|
|
|
c := creds{}
|
|
for _, el := range []struct {
|
|
target *[]byte
|
|
path string
|
|
}{
|
|
{&c.ca, path + "/" + "ca.crt"},
|
|
{&c.cert, path + "/" + "tls.crt"},
|
|
{&c.key, path + "/" + "tls.key"},
|
|
} {
|
|
data, err := ioutil.ReadFile(el.path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("ReadFile(%q): %w", el.path, err)
|
|
}
|
|
*el.target = data
|
|
}
|
|
|
|
return &c, nil
|
|
}
|
|
|
|
func loadFlagCredentials() (*creds, error) {
|
|
c := creds{}
|
|
for _, el := range []struct {
|
|
target *[]byte
|
|
path string
|
|
}{
|
|
{&c.ca, flagCAPath},
|
|
{&c.cert, flagCertificatePath},
|
|
{&c.key, flagKeyPath},
|
|
} {
|
|
data, err := ioutil.ReadFile(el.path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("ReadFile(%q): %w", el.path, err)
|
|
}
|
|
*el.target = data
|
|
}
|
|
|
|
return &c, nil
|
|
}
|
|
|
|
func loadCredentials() (*creds, error) {
|
|
dev, err := loadDeveloperCredentials()
|
|
if err == nil {
|
|
return dev, nil
|
|
}
|
|
glog.Warningf("Could not load developer PKI credentials: %v", err)
|
|
|
|
fl, err := loadFlagCredentials()
|
|
if err == nil {
|
|
return fl, err
|
|
}
|
|
glog.Warningf("Could not load flag-defined PKI credentials: %v", err)
|
|
|
|
return nil, fmt.Errorf("could not load any credentials")
|
|
}
|