Skip to content

Commit 518c0e4

Browse files
committed
refactor: migrate key handling to wgtypes.Key, removing custom crypto wrappers
Replace PrivateKey []byte helpers (PubKey, KeyToBase64, Base64ToKey) and manual curve25519/rand usage with wgtypes.Key and wgtypes.GeneratePrivateKey. EnsurePrivateKey now returns wgtypes.Key directly, propagated through runtimeconfig.
1 parent c30c4a8 commit 518c0e4

4 files changed

Lines changed: 33 additions & 67 deletions

File tree

internal/deviceagent/runtimeconfig/runtimeconfig.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package runtimeconfig
33
import (
44
"bytes"
55
"context"
6-
"encoding/base64"
76
"encoding/json"
87
"fmt"
98
"io"
@@ -27,6 +26,7 @@ import (
2726
"github.com/nais/device/pkg/pb"
2827
"github.com/sirupsen/logrus"
2928
"golang.org/x/oauth2"
29+
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
3030
"google.golang.org/api/iterator"
3131
"google.golang.org/api/option"
3232
"google.golang.org/grpc"
@@ -76,7 +76,7 @@ var _ RuntimeConfig = &runtimeConfig{}
7676
type runtimeConfig struct {
7777
enrollConfig *bootstrap.Config // TODO: convert to enroll.Config
7878
config *config.Config
79-
privateKey []byte
79+
privateKey wgtypes.Key
8080
tokens *auth.Tokens
8181
tenants []*pb.Tenant
8282
log *logrus.Entry
@@ -153,7 +153,7 @@ func (rc *runtimeConfig) ConnectToAPIServer(ctx context.Context) (pb.APIServerCl
153153

154154
func (rc *runtimeConfig) BuildHelperConfiguration(peers []*pb.Gateway) *pb.Configuration {
155155
return &pb.Configuration{
156-
PrivateKey: base64.StdEncoding.EncodeToString(rc.privateKey),
156+
PrivateKey: rc.privateKey.String(),
157157
DeviceIPv4: rc.enrollConfig.DeviceIPv4,
158158
DeviceIPv6: rc.enrollConfig.DeviceIPv6,
159159
Gateways: peers,
@@ -206,7 +206,7 @@ func New(log *logrus.Entry, cfg *config.Config) (RuntimeConfig, error) {
206206
return nil, fmt.Errorf("ensuring private key: %w", err)
207207
}
208208

209-
rc.log.WithField("public_key", wireguard.PublicKey(rc.privateKey)).Info("runtime config initialized")
209+
rc.log.WithField("public_key", rc.privateKey.PublicKey().String()).Info("runtime config initialized")
210210

211211
return rc, nil
212212
}
@@ -230,7 +230,7 @@ func (r *runtimeConfig) enroll(ctx context.Context, serial, token string) error
230230
req := &enroll.DeviceRequest{
231231
Platform: r.config.Platform,
232232
Serial: serial,
233-
WireGuardPublicKey: wireguard.PublicKey(r.privateKey),
233+
WireGuardPublicKey: []byte(r.privateKey.PublicKey().String()),
234234
}
235235

236236
buf := &bytes.Buffer{}
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
11
package wireguard
22

33
import (
4+
"encoding/base64"
45
"fmt"
56
"os"
67

78
"github.com/nais/device/internal/deviceagent/filesystem"
8-
"github.com/nais/device/internal/wireguard"
9+
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
910
)
1011

11-
func EnsurePrivateKey(keyPath string) ([]byte, error) {
12+
func EnsurePrivateKey(keyPath string) (wgtypes.Key, error) {
1213
if err := filesystem.FileMustExist(keyPath); os.IsNotExist(err) {
13-
key, err := wireguard.GenKey()
14+
key, err := wgtypes.GeneratePrivateKey()
1415
if err != nil {
15-
return nil, fmt.Errorf("generating private key: %w", err)
16+
return wgtypes.Key{}, fmt.Errorf("generating private key: %w", err)
1617
}
17-
if err := os.WriteFile(keyPath, wireguard.KeyToBase64(key), 0o600); err != nil {
18-
return nil, fmt.Errorf("writing private key to disk: %w", err)
18+
if err := os.WriteFile(keyPath, []byte(key.String()), 0o600); err != nil {
19+
return wgtypes.Key{}, fmt.Errorf("writing private key to disk: %w", err)
1920
}
21+
return key, nil
2022
} else if err != nil {
21-
return nil, fmt.Errorf("ensuring private key exists: %w", err)
23+
return wgtypes.Key{}, fmt.Errorf("ensuring private key exists: %w", err)
2224
}
2325

2426
privateKeyEncoded, err := os.ReadFile(keyPath)
2527
if err != nil {
26-
return nil, fmt.Errorf("reading private key: %v", err)
28+
return wgtypes.Key{}, fmt.Errorf("reading private key: %v", err)
2729
}
2830

29-
privateKey, err := wireguard.Base64ToKey(privateKeyEncoded)
31+
var key wgtypes.Key
32+
b, err := base64.StdEncoding.DecodeString(string(privateKeyEncoded))
3033
if err != nil {
31-
return nil, fmt.Errorf("decoding private key: %v", err)
34+
return wgtypes.Key{}, fmt.Errorf("decoding private key: %v", err)
3235
}
36+
copy(key[:], b)
3337

34-
return privateKey, nil
35-
}
36-
37-
func PublicKey(privateKey []byte) []byte {
38-
return wireguard.KeyToBase64(wireguard.PubKey(privateKey))
38+
return key, nil
3939
}

internal/deviceagent/wireguard/wireguard_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ package wireguard_test
33
import (
44
"testing"
55

6-
"github.com/nais/device/internal/wireguard"
76
"github.com/stretchr/testify/assert"
7+
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
88
)
99

1010
func TestGenKey(t *testing.T) {
11-
privateKey, err := wireguard.GenKey()
11+
key, err := wgtypes.GeneratePrivateKey()
1212
assert.NoError(t, err)
13-
assert.Len(t, privateKey, 32)
14-
privateKeyB64 := wireguard.KeyToBase64(privateKey)
15-
assert.Len(t, privateKeyB64, 44)
13+
assert.Len(t, key, 32)
14+
assert.Len(t, key.String(), 44)
1615
}

internal/wireguard/keys.go

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,35 @@
11
package wireguard
22

33
import (
4-
"crypto/rand"
5-
"encoding/base64"
64
"errors"
75
"fmt"
86
"io/fs"
97
"os"
108
"path/filepath"
119

1210
"github.com/sirupsen/logrus"
13-
"golang.org/x/crypto/curve25519"
11+
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
1412
)
1513

1614
type PrivateKey []byte
1715

18-
// Public returns the public key base64 encoded
1916
func (p PrivateKey) Public() []byte {
20-
return KeyToBase64(PubKey(p))
17+
key, _ := wgtypes.NewKey(p)
18+
pub := key.PublicKey()
19+
return []byte(pub.String())
2120
}
2221

23-
// Private returns the private key base64 encoded
2422
func (p PrivateKey) Private() []byte {
25-
return KeyToBase64(p)
23+
key, _ := wgtypes.NewKey(p)
24+
return []byte(key.String())
2625
}
2726

2827
func GenKey() (PrivateKey, error) {
29-
var privateKey [32]byte
30-
31-
n, err := rand.Read(privateKey[:])
32-
33-
if err != nil || n != len(privateKey) {
34-
return nil, fmt.Errorf("unable to generate random bytes")
35-
}
36-
37-
privateKey[0] &= 248
38-
privateKey[31] = (privateKey[31] & 127) | 64
39-
return PrivateKey(privateKey[:]), nil
40-
}
41-
42-
// PubKey derives the Curve25519 public key from a raw 32-byte private key.
43-
func PubKey(privateKeySlice []byte) []byte {
44-
var privateKey [32]byte
45-
var publicKey [32]byte
46-
copy(privateKey[:], privateKeySlice[:])
47-
48-
curve25519.ScalarBaseMult(&publicKey, &privateKey)
49-
50-
return publicKey[:]
51-
}
52-
53-
func KeyToBase64(key []byte) []byte {
54-
dst := make([]byte, base64.StdEncoding.EncodedLen(len(key)))
55-
base64.StdEncoding.Encode(dst, key)
56-
return dst
57-
}
58-
59-
func Base64ToKey(encoded []byte) ([]byte, error) {
60-
decoded := make([]byte, 32)
61-
_, err := base64.StdEncoding.Decode(decoded, encoded)
28+
key, err := wgtypes.GeneratePrivateKey()
6229
if err != nil {
63-
return nil, fmt.Errorf("decoding base64 key: %w", err)
30+
return nil, fmt.Errorf("generate private key: %w", err)
6431
}
65-
return decoded, nil
32+
return PrivateKey(key[:]), nil
6633
}
6734

6835
func ReadOrCreatePrivateKey(path string, log *logrus.Entry) (PrivateKey, error) {

0 commit comments

Comments
 (0)