/
ipn_wgkeygen.go
101 lines (85 loc) · 2.11 KB
/
ipn_wgkeygen.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
// Copyright (c) 2023 RethinkDNS and its authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// This file incorporates work covered by the following copyright and
// permission notice:
//
// SPDX-License-Identifier: MIT
//
// Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
package backend
import (
"crypto/rand"
"crypto/subtle"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"golang.org/x/crypto/curve25519"
)
// from: github.com/WireGuard/wireguard-windows/blob/dcc0eb72a/conf/parser.go#L121
const klen = 32
type (
eckey [klen]byte
)
var _ WgKey = (*eckey)(nil)
type WgKey interface {
// IsZero returns true if the key is all zeros.
IsZero() bool
// Base64 returns the key as a base64-encoded string.
Base64() string
// Hex returns the key as a hex-encoded string.
Hex() string
// Mult returns the key multiplied by the basepoint (curve25519).
Mult() WgKey
}
func (k *eckey) Hex() string {
return hex.EncodeToString(k[:])
}
func (k *eckey) Base64() string {
return base64.StdEncoding.EncodeToString(k[:])
}
func (k *eckey) IsZero() bool {
var zeros eckey
return subtle.ConstantTimeCompare(zeros[:], k[:]) == 1
}
func (k *eckey) Mult() WgKey {
var p [klen]byte
curve25519.ScalarBaseMult(&p, (*[klen]byte)(k))
return (*eckey)(&p)
}
func newPresharedKey() (*eckey, error) {
var k [klen]byte
_, err := rand.Read(k[:])
if err != nil {
return nil, err
}
return (*eckey)(&k), nil
}
func NewWgPrivateKey() (WgKey, error) {
k, err := newPresharedKey()
if err != nil {
return nil, err
}
k[0] &= 248
k[31] = (k[31] & 127) | 64
return k, nil
}
func parseKeyBase64(s string) (*eckey, error) {
k, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("Invalid key: %v", err)
}
if len(k) != klen {
return nil, errors.New("Keys must decode to exactly 32 bytes")
}
var key eckey
copy(key[:], k)
return &key, nil
}
func NewWgPrivateKeyOf(b64 string) (WgKey, error) {
return parseKeyBase64(b64)
}