This repository has been archived by the owner on Oct 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgenerate.go
154 lines (123 loc) · 3.04 KB
/
generate.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
150
151
152
153
154
package main
// #include <stdlib.h>
// #include <generate.h>
import "C"
import (
"bytes"
"crypto/sha512"
"flag"
"io"
"io/ioutil"
"os"
"path"
"sort"
"strings"
"unsafe"
log "github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
)
const (
Seed = "2f727c7f12896af73cc89c48ca0a00d366b728eb42ae8bcdd293538fddfdc05b0d0a52d2278fa092d74f3524053e44a1fae905c8ee9af42d567e789f819e7094"
)
func Generate(seed []byte) string {
if len(seed) != 64 {
panic("invalid seed length")
}
var x *C.char
cseed := C.CBytes(seed)
defer C.free(cseed)
log.Debug("calling the underlaying C generate function")
C.generate((*C.uchar)(cseed), &x)
str := C.GoString(x)
C.free(unsafe.Pointer(x))
return str
}
func GetMachineIdentity() (public, secret string) {
log.Debug("calculating machine identity")
links, err := netlink.LinkList()
if err != nil {
panic(err)
}
log.WithFields(log.Fields{
"count": len(links),
}).Debug("nics found")
sh := sha512.New()
io.WriteString(sh, Seed)
//add motheroard ID if available
log.Debugf("reading motherboard id")
if data, err := ioutil.ReadFile("/sys/devices/virtual/dmi/id/board_serial"); err == nil {
sh.Write(bytes.TrimSpace(data))
} else {
log.WithError(err).Debug("could not read motherboard id, skipping ...")
}
devices := []string{}
//all physical devices.
for _, link := range links {
if link.Type() != "device" {
continue
}
attrs := link.Attrs()
if attrs.Name == "lo" {
continue
}
log.WithFields(log.Fields{
"nic": attrs.Name,
"mac": attrs.HardwareAddr.String(),
}).Debug("adding device to list of identity devices")
devices = append(devices, attrs.HardwareAddr.String())
}
// don't rely on the order of nics
// we sort the list to ensure it's the same
// whatever the kernel does
sort.Strings(devices)
log.WithFields(log.Fields{
"macs": devices,
"count": len(devices),
}).Debug("macs used in identity generation (sorted)")
for _, dev := range devices {
io.WriteString(sh, dev)
}
log.Info("generating identity ...")
secret = Generate(sh.Sum(nil))
parts := strings.Split(
secret,
":",
)
//parts (addr:0:public:secret)
public = strings.Join(parts[:3], ":")
return
}
func main() {
var output string
var debug bool
flag.StringVar(&output, "out", ".", "Output directory where to write the identity files")
flag.BoolVar(&debug, "debug", false, "enable debug output")
flag.Parse()
if output == "" {
flag.PrintDefaults()
os.Exit(1)
}
if debug {
log.SetLevel(log.DebugLevel)
}
public, secret := GetMachineIdentity()
if err := os.MkdirAll(output, 0755); err != nil {
log.WithError(err).Fatalf("failed to create directory: %s", output)
}
if err := ioutil.WriteFile(
path.Join(output, "identity.public"),
[]byte(public),
0644,
); err != nil {
log.WithError(err).Fatalf("failed to write public identity file: %s", err)
}
if err := ioutil.WriteFile(
path.Join(output, "identity.secret"),
[]byte(secret),
0600,
); err != nil {
log.WithError(err).Fatalf("failed to write secret identity file: %s", err)
os.Exit(1)
}
os.Exit(0)
}