/
connections.go
149 lines (135 loc) · 4.45 KB
/
connections.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package securestore
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/abruno06/myvault/config"
"github.com/abruno06/myvault/smartcard"
"github.com/go-piv/piv-go/piv"
"github.com/hashicorp/vault-client-go"
"github.com/hashicorp/vault-client-go/schema"
)
// connect to vault with specific tls config
func ConnectVaultWithTLSConfig(ctx context.Context, tlsConfig *tls.Config) (SecretStore, error) {
// prepare a client with the given base address
client, err := vault.New(
vault.WithAddress(config.ReadVaultURL()),
vault.WithRequestTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
//set the transport configuration
httpclient := client.Configuration().HTTPClient
transport := httpclient.Transport
transport.(*http.Transport).TLSClientConfig = tlsConfig
// Authenticate with the Vault server using ceritificate
resp, err := client.Auth.CertLogin(ctx, schema.CertLoginRequest{Name: config.ReadCertificateName()})
if err != nil {
fmt.Printf("CertLogin error: %v\n", err)
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
if err := client.SetToken(resp.Auth.ClientToken); err != nil {
log.Fatal(err)
}
fmt.Printf("Client Token: %v\n", resp.Auth.ClientToken)
return SecretStore{Client: client, Mountpath: config.ReadMountPath(), Appname: config.ReadAPPNAME()}, err
}
// connect to vault with yubikey
func ConnectVaulwithYubikey(ctx context.Context, yubikey *piv.YubiKey, pin string) (SecretStore, error) {
//set the slot to authentication
slot := piv.SlotAuthentication // You can change this to the slot you are interested in.
//read the personal certificate
cert := smartcard.ReadYubikeyCertificate(yubikey, slot)
//test the pin is correct
if err := yubikey.VerifyPIN(pin); err != nil {
return SecretStore{}, err
}
// set the auth
auth := piv.KeyAuth{PIN: pin}
//get the private key accessors
priv, err := yubikey.PrivateKey(slot, cert.PublicKey, auth)
if err != nil {
log.Fatal(err)
}
// Load the CA certificate of the server ("./cert/server.pem")
caCert, err := os.ReadFile("./cert/server.pem")
if err != nil {
log.Fatal(err)
}
// Create a certificate pool with the CA certificate
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Create a TLS configuration with the client certificate and CA certificate
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{{
Certificate: [][]byte{cert.Raw},
PrivateKey: priv,
}},
RootCAs: caCertPool,
InsecureSkipVerify: true,
}
// the Yukibykey certificate and private retrieval is complete
// print tls config
//fmt.Printf("TLS Config: %v\n", tlsConfig)
// Prepare Vault Connection
//log client token returned
//log.Printf("Client Token: %v", resp.Auth.ClientToken)
return ConnectVaultWithTLSConfig(ctx, tlsConfig)
}
// connect to vault using username and password and return the client
func ConnectVaultWithUsernamePassword(ctx context.Context, username, password string) (SecretStore, error) {
// Prepare Vault Connection
// prepare a client with the given base address
client, err := vault.New(
vault.WithAddress(config.ReadVaultURL()),
vault.WithRequestTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
// Authenticate with the Vault server using username and password
resp, err := client.Auth.UserpassLogin(ctx, username, schema.UserpassLoginRequest{Password: password})
if err != nil {
log.Fatal(err)
}
if err := client.SetToken(resp.Auth.ClientToken); err != nil {
log.Fatal(err)
}
return SecretStore{Client: client, Mountpath: config.ReadMountPath(), Appname: config.ReadAPPNAME()}, err
}
// connect to vault using token
func ConnectVaultWithToken(ctx context.Context, token string) (SecretStore, error) {
// prepare a client with the given base address
client, err := vault.New(
vault.WithAddress(config.ReadVaultURL()),
vault.WithRequestTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
if err := client.SetToken(token); err != nil {
log.Fatal(err)
}
return SecretStore{Client: client, Mountpath: config.ReadMountPath(), Appname: config.ReadAPPNAME()}, err
}
// connect to vault in annonymous mode
func ConnectVault(ctx context.Context) (SecretStore, error) {
// Prepare Vault Connection
client, err := vault.New(
vault.WithAddress(config.ReadVaultURL()),
vault.WithRequestTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
return SecretStore{Client: client, Mountpath: config.ReadMountPath(), Appname: config.ReadAPPNAME()}, err
}