removed old identify
Juan Batiz-Benet committed
Sep 14, 2014 at 04:19 UTC
5684fa2362e42f2f7e6224ded0c6874b2f6c345a
1 file changed
-311
identify/identify.go
deleted
-311
@@ -1,311 +0,0 @@
1
-// Package identify handles how peers identify with eachother upon
2
-// connection to the network
3
-package identify
4
-
5
-import (
6
- "bytes"
7
- "errors"
8
- "strings"
9
-
10
- "crypto/aes"
11
- "crypto/cipher"
12
- "crypto/hmac"
13
- "crypto/rand"
14
- "crypto/sha1"
15
- "crypto/sha256"
16
- "crypto/sha512"
17
- "hash"
18
-
19
- proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
20
- ci "github.com/jbenet/go-ipfs/crypto"
21
- peer "github.com/jbenet/go-ipfs/peer"
22
- u "github.com/jbenet/go-ipfs/util"
23
-)
24
-
25
-// List of supported protocols--each section in order of preference.
26
-// Takes the form: ECDH curves : Ciphers : Hashes
27
-var SupportedExchanges = "P-256,P-224,P-384,P-521"
28
-var SupportedCiphers = "AES-256,AES-128"
29
-var SupportedHashes = "SHA256,SHA512,SHA1"
30
-
31
-// ErrUnsupportedKeyType is returned when a private key cast/type switch fails.
32
-var ErrUnsupportedKeyType = errors.New("unsupported key type")
33
-
34
-// Performs initial communication with this peer to share node ID's and
35
-// initiate communication. (secureIn, secureOut, error)
36
-func Handshake(self, remote *peer.Peer, in <-chan []byte, out chan<- []byte) (<-chan []byte, chan<- []byte, error) {
37
- // Generate and send Hello packet.
38
- // Hello = (rand, PublicKey, Supported)
39
- nonce := make([]byte, 16)
40
- _, err := rand.Read(nonce)
41
- if err != nil {
42
- return nil, nil, err
43
- }
44
-
45
- hello := new(Hello)
46
-
47
- myPubKey, err := self.PubKey.Bytes()
48
- if err != nil {
49
- return nil, nil, err
50
- }
51
-
52
- hello.Rand = nonce
53
- hello.Pubkey = myPubKey
54
- hello.Exchanges = &SupportedExchanges
55
- hello.Ciphers = &SupportedCiphers
56
- hello.Hashes = &SupportedHashes
57
-
58
- encoded, err := proto.Marshal(hello)
59
- if err != nil {
60
- return nil, nil, err
61
- }
62
-
63
- out <- encoded
64
-
65
- // Parse their Hello packet and generate an Exchange packet.
66
- // Exchange = (EphemeralPubKey, Signature)
67
- resp := <-in
68
-
69
- helloResp := new(Hello)
70
- err = proto.Unmarshal(resp, helloResp)
71
- if err != nil {
72
- return nil, nil, err
73
- }
74
-
75
- remote.PubKey, err = ci.UnmarshalPublicKey(helloResp.GetPubkey())
76
- if err != nil {
77
- return nil, nil, err
78
- }
79
-
80
- remote.ID, err = IDFromPubKey(remote.PubKey)
81
- if err != nil {
82
- return nil, nil, err
83
- }
84
-
85
- exchange, err := selectBest(SupportedExchanges, helloResp.GetExchanges())
86
- if err != nil {
87
- return nil, nil, err
88
- }
89
-
90
- cipherType, err := selectBest(SupportedCiphers, helloResp.GetCiphers())
91
- if err != nil {
92
- return nil, nil, err
93
- }
94
-
95
- hashType, err := selectBest(SupportedHashes, helloResp.GetHashes())
96
- if err != nil {
97
- return nil, nil, err
98
- }
99
-
100
- epubkey, done, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey
101
- if err != nil {
102
- return nil, nil, err
103
- }
104
-
105
- var handshake bytes.Buffer // Gather corpus to sign.
106
- handshake.Write(encoded)
107
- handshake.Write(resp)
108
- handshake.Write(epubkey)
109
-
110
- exPacket := new(Exchange)
111
-
112
- exPacket.Epubkey = epubkey
113
- exPacket.Signature, err = self.PrivKey.Sign(handshake.Bytes())
114
- if err != nil {
115
- return nil, nil, err
116
- }
117
-
118
- exEncoded, err := proto.Marshal(exPacket)
119
- if err != nil {
120
- return nil, nil, err
121
- }
122
-
123
- out <- exEncoded
124
-
125
- // Parse their Exchange packet and generate a Finish packet.
126
- // Finish = E('Finish')
127
- resp1 := <-in
128
-
129
- exchangeResp := new(Exchange)
130
- err = proto.Unmarshal(resp1, exchangeResp)
131
- if err != nil {
132
- return nil, nil, err
133
- }
134
-
135
- var theirHandshake bytes.Buffer
136
- _, err = theirHandshake.Write(resp)
137
- if err != nil {
138
- return nil, nil, err
139
- }
140
- _, err = theirHandshake.Write(encoded)
141
- if err != nil {
142
- return nil, nil, err
143
- }
144
- _, err = theirHandshake.Write(exchangeResp.GetEpubkey())
145
- if err != nil {
146
- return nil, nil, err
147
- }
148
-
149
- ok, err := remote.PubKey.Verify(theirHandshake.Bytes(), exchangeResp.GetSignature())
150
- if err != nil {
151
- return nil, nil, err
152
- }
153
-
154
- if !ok {
155
- return nil, nil, errors.New("Bad signature!")
156
- }
157
-
158
- secret, err := done(exchangeResp.GetEpubkey())
159
- if err != nil {
160
- return nil, nil, err
161
- }
162
-
163
- cmp := bytes.Compare(myPubKey, helloResp.GetPubkey())
164
- mIV, tIV, mCKey, tCKey, mMKey, tMKey := ci.KeyStretcher(cmp, cipherType, hashType, secret)
165
-
166
- secureIn := make(chan []byte)
167
- secureOut := make(chan []byte)
168
-
169
- go secureInProxy(in, secureIn, hashType, tIV, tCKey, tMKey)
170
- go secureOutProxy(out, secureOut, hashType, mIV, mCKey, mMKey)
171
-
172
- finished := []byte("Finished")
173
-
174
- secureOut <- finished
175
- resp2 := <-secureIn
176
-
177
- if bytes.Compare(resp2, finished) != 0 {
178
- return nil, nil, errors.New("Negotiation failed.")
179
- }
180
-
181
- u.DOut("[%s] identify: Got node id: %s\n", self.ID.Pretty(), remote.ID.Pretty())
182
-
183
- return secureIn, secureOut, nil
184
-}
185
-
186
-func makeMac(hashType string, key []byte) (hash.Hash, int) {
187
- switch hashType {
188
- case "SHA1":
189
- return hmac.New(sha1.New, key), sha1.Size
190
- case "SHA512":
191
- return hmac.New(sha512.New, key), sha512.Size
192
- default:
193
- return hmac.New(sha256.New, key), sha256.Size
194
- }
195
-}
196
-
197
-func secureInProxy(in <-chan []byte, secureIn chan<- []byte, hashType string, tIV, tCKey, tMKey []byte) {
198
- theirBlock, _ := aes.NewCipher(tCKey)
199
- theirCipher := cipher.NewCTR(theirBlock, tIV)
200
-
201
- theirMac, macSize := makeMac(hashType, tMKey)
202
-
203
- for {
204
- data, ok := <-in
205
- if !ok {
206
- close(secureIn)
207
- return
208
- }
209
-
210
- if len(data) <= macSize {
211
- continue
212
- }
213
-
214
- mark := len(data) - macSize
215
- buff := make([]byte, mark)
216
-
217
- theirCipher.XORKeyStream(buff, data[0:mark])
218
-
219
- theirMac.Write(data[0:mark])
220
- expected := theirMac.Sum(nil)
221
- theirMac.Reset()
222
-
223
- hmacOk := hmac.Equal(data[mark:], expected)
224
-
225
- if hmacOk {
226
- secureIn <- buff
227
- } else {
228
- secureIn <- nil
229
- }
230
- }
231
-}
232
-
233
-func secureOutProxy(out chan<- []byte, secureOut <-chan []byte, hashType string, mIV, mCKey, mMKey []byte) {
234
- myBlock, _ := aes.NewCipher(mCKey)
235
- myCipher := cipher.NewCTR(myBlock, mIV)
236
-
237
- myMac, macSize := makeMac(hashType, mMKey)
238
-
239
- for {
240
- data, ok := <-secureOut
241
- if !ok {
242
- close(out)
243
- return
244
- }
245
-
246
- if len(data) == 0 {
247
- continue
248
- }
249
-
250
- buff := make([]byte, len(data)+macSize)
251
-
252
- myCipher.XORKeyStream(buff, data)
253
-
254
- myMac.Write(buff[0:len(data)])
255
- copy(buff[len(data):], myMac.Sum(nil))
256
- myMac.Reset()
257
-
258
- out <- buff
259
- }
260
-}
261
-
262
-// IDFromPubKey returns Nodes ID given its public key
263
-func IDFromPubKey(pk ci.PubKey) (peer.ID, error) {
264
- b, err := pk.Bytes()
265
- if err != nil {
266
- return nil, err
267
- }
268
- hash, err := u.Hash(b)
269
- if err != nil {
270
- return nil, err
271
- }
272
- return peer.ID(hash), nil
273
-}
274
-
275
-// Determines which algorithm to use. Note: f(a, b) = f(b, a)
276
-func selectBest(myPrefs, theirPrefs string) (string, error) {
277
- // Person with greatest hash gets first choice.
278
- myHash, err := u.Hash([]byte(myPrefs))
279
- if err != nil {
280
- return "", err
281
- }
282
-
283
- theirHash, err := u.Hash([]byte(theirPrefs))
284
- if err != nil {
285
- return "", err
286
- }
287
-
288
- cmp := bytes.Compare(myHash, theirHash)
289
- var firstChoiceArr, secChoiceArr []string
290
-
291
- if cmp == -1 {
292
- firstChoiceArr = strings.Split(theirPrefs, ",")
293
- secChoiceArr = strings.Split(myPrefs, ",")
294
- } else if cmp == 1 {
295
- firstChoiceArr = strings.Split(myPrefs, ",")
296
- secChoiceArr = strings.Split(theirPrefs, ",")
297
- } else { // Exact same preferences.
298
- myPrefsArr := strings.Split(myPrefs, ",")
299
- return myPrefsArr[0], nil
300
- }
301
-
302
- for _, secChoice := range secChoiceArr {
303
- for _, firstChoice := range firstChoiceArr {
304
- if firstChoice == secChoice {
305
- return firstChoice, nil
306
- }
307
- }
308
- }
309
-
310
- return "", errors.New("No algorithms in common!")
311
-}