-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathorgsig.go
166 lines (142 loc) · 3.9 KB
/
orgsig.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
155
156
157
158
159
160
161
162
163
164
165
166
package main
import (
"bufio"
"flag"
"fmt"
"os"
"strings"
"github.com/libp2p/go-libp2p-core/crypto"
libp2pcrypto "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/pkg/errors"
"happystoic/p2pnetwork/pkg/config"
"happystoic/p2pnetwork/pkg/cryptotools"
"happystoic/p2pnetwork/pkg/org"
)
/*
*
* TODO: write docs
*
*/
const version = "v0.0.1"
func parseFlags() (*string, *string, *bool, *string, error) {
// flags regarding the organisation key
loadKeyPath := flag.String("load-key-path", "",
"Path to a file with organisation private key. If not set, new "+
"private-key is generated.")
saveKeyPath := flag.String("save-key-path", "", "If "+
"set, value will be used as a path to save organisation private-key.")
// flags regarding the signature of a peer
signPeer := flag.Bool("sign-peer", false, "Flag to "+
"sign peer ID. Flag peer-id can be used to set peer"+
"ID, otherwise, cli will ask. The signature will be printed to stdout.")
peerId := flag.String("peer-id", "",
"Public ID of a peer to sign. Flag --sign-peer must be "+
"set for this option to be valid.")
flag.Parse() // parse the args
return loadKeyPath, saveKeyPath, signPeer, peerId, nil
}
func processArgs() (*string, *string, *bool, *string, error) {
loadKeyPath, saveKeyPath, signPeer, peerId, err := parseFlags()
if err != nil {
return nil, nil, nil, nil, err
}
if *saveKeyPath == "" && !(*signPeer) {
err = errors.Errorf("Nothing to do. At least one of" +
" 'save-key-path' or 'sign-peer' flags must be set. Run '--help'" +
" for more information")
}
return loadKeyPath, saveKeyPath, signPeer, peerId, err
}
func readPeerIDFromCli() (string, error) {
fmt.Println("Peer ID to sign:")
fmt.Print("> ")
input, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
return "", err
}
// get rid of \n at the end of a line
return input[:len(input)-1], err
}
func produceOutput(key crypto.PrivKey, saveKeyPath string, signature string) error {
var out strings.Builder
out.WriteString("\n")
if signature != "" {
out.WriteString(fmt.Sprintf("Peer's signature:\n%s\n\n", signature))
}
if saveKeyPath != "" {
bytes, err := libp2pcrypto.MarshalPrivateKey(key)
if err != nil {
return err
}
err = os.WriteFile(saveKeyPath, bytes, 0644)
if err != nil {
return err
}
out.WriteString(fmt.Sprintf("Saved organisation private key to path:"+
"\n\t%s\n", saveKeyPath))
}
pubId, err := peer.IDFromPrivateKey(key)
if err != nil {
return err
}
out.WriteString(fmt.Sprintf("Organisation's ID (public-key):"+
"\n\t%s\n\n", pubId.String()))
fmt.Print(out.String())
return nil
}
func fatal(code int, err error) {
fmt.Println(err)
os.Exit(code)
}
func getPeerToSign(peerIdArg string) (peer.ID, error) {
var err error
if peerIdArg == "" {
peerIdArg, err = readPeerIDFromCli()
if err != nil {
return "", err
}
}
return peer.Decode(peerIdArg)
}
func main() {
fmt.Printf("Running %s orgsig\n\n", version)
// process command line arguments
loadKeyPath, saveKeyPath, signPeer, peerId, err := processArgs()
if err != nil {
fatal(1, err)
}
// load or generate new private key of the organization
var i config.IdentityConfig
if *loadKeyPath != "" {
i = config.IdentityConfig{LoadKeyFromFile: *loadKeyPath}
} else {
if *saveKeyPath == "" {
fatal(2, fmt.Errorf("--save-key-path must be set"+
" when generating new organisation private key"))
}
i = config.IdentityConfig{GenerateNewKey: true}
}
key, err := cryptotools.GetPrivateKey(&i)
if err != nil {
fatal(3, err)
}
// sign the peer if possible
signature := ""
if *signPeer {
p, err := getPeerToSign(*peerId)
if err != nil {
fatal(4, err)
}
signature, err = org.SignPeer(key, p)
if err != nil {
fatal(5, err)
}
}
// produce desired output
err = produceOutput(key, *saveKeyPath, signature)
if err != nil {
fatal(6, err)
}
fmt.Println("Finished...")
}