@cryptotaxi247 / kubo / commits / c6823ac6e

Cleaned up code some.

Brendan Mc committed Sep 4, 2014 at 13:15 UTC c6823ac6e40ecefd59a87fc93f694f4533d498c1
3 files changed +219 -261
crypto/key.go
+149 -6
@@ -1,10 +1,18 @@
1 package crypto
2
3 import (
4 + "bytes"
5 "errors"
6
7 + "crypto/elliptic"
8 + "crypto/hmac"
9 "crypto/rand"
10 "crypto/rsa"
11 + "crypto/sha1"
12 + "crypto/sha256"
13 + "crypto/sha512"
14 + "hash"
15 + "math/big"
16
17 "code.google.com/p/goprotobuf/proto"
18 )
@@ -19,9 +27,6 @@ type PrivKey interface {
27 // Cryptographically sign the given bytes
28 Sign([]byte) ([]byte, error)
29
22 - // Decrypt a message encrypted with this keys public key
23 - Decrypt([]byte) ([]byte, error)
24 -
30 // Return a public key paired with this private key
31 GetPublic() PubKey
32
@@ -36,13 +41,13 @@ type PubKey interface {
41 // Verify that 'sig' is the signed hash of 'data'
42 Verify(data []byte, sig []byte) (bool, error)
43
39 - // Encrypt the given data with the public key
40 - Encrypt([]byte) ([]byte, error)
41 -
44 // Bytes returns a serialized, storeable representation of this key
45 Bytes() ([]byte, error)
46 }
47
48 +// Given a public key, generates the shared key.
49 +type GenSharedKey func([]byte) ([]byte, error)
50 +
51 func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
52 switch typ {
53 case RSA:
@@ -57,6 +62,144 @@ func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
62 }
63 }
64
65 +// Generates an ephemeral public key and returns a function that will compute
66 +// the shared secret key. Used in the identify module.
67 +//
68 +// Focuses only on ECDH now, but can be made more general in the future.
69 +func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
70 + var curve elliptic.Curve
71 +
72 + switch curveName {
73 + case "P-224":
74 + curve = elliptic.P224()
75 + case "P-256":
76 + curve = elliptic.P256()
77 + case "P-384":
78 + curve = elliptic.P384()
79 + case "P-521":
80 + curve = elliptic.P521()
81 + }
82 +
83 + priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
84 + if err != nil {
85 + return nil, nil, err
86 + }
87 +
88 + var pubKey bytes.Buffer
89 + pubKey.Write(x.Bytes())
90 + pubKey.Write(y.Bytes())
91 +
92 + done := func(theirPub []byte) ([]byte, error) {
93 + // Verify and unpack node's public key.
94 + curveSize := curve.Params().BitSize
95 +
96 + if len(theirPub) != (curveSize / 4) {
97 + return nil, errors.New("Malformed public key.")
98 + }
99 +
100 + bound := (curveSize / 8)
101 + x := big.NewInt(0)
102 + y := big.NewInt(0)
103 +
104 + x.SetBytes(theirPub[0:bound])
105 + y.SetBytes(theirPub[bound : bound*2])
106 +
107 + if !curve.IsOnCurve(x, y) {
108 + return nil, errors.New("Invalid public key.")
109 + }
110 +
111 + // Generate shared secret.
112 + secret, _ := curve.ScalarMult(x, y, priv)
113 +
114 + return secret.Bytes(), nil
115 + }
116 +
117 + return pubKey.Bytes(), done, nil
118 +}
119 +
120 +// Generates a set of keys for each party by stretching the shared key.
121 +// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey)
122 +func KeyStretcher(cmp int, cipherType string, hashType string, secret []byte) ([]byte, []byte, []byte, []byte, []byte, []byte) {
123 + var cipherKeySize int
124 + switch cipherType {
125 + case "AES-128":
126 + cipherKeySize = 16
127 + case "AES-256":
128 + cipherKeySize = 32
129 + }
130 +
131 + ivSize := 16
132 + hmacKeySize := 20
133 +
134 + seed := []byte("key expansion")
135 +
136 + result := make([]byte, 2*(ivSize+cipherKeySize+hmacKeySize))
137 +
138 + var h func() hash.Hash
139 +
140 + switch hashType {
141 + case "SHA1":
142 + h = sha1.New
143 + case "SHA256":
144 + h = sha256.New
145 + case "SHA512":
146 + h = sha512.New
147 + }
148 +
149 + m := hmac.New(h, secret)
150 + m.Write(seed)
151 +
152 + a := m.Sum(nil)
153 +
154 + j := 0
155 + for j < len(result) {
156 + m.Reset()
157 + m.Write(a)
158 + m.Write(seed)
159 + b := m.Sum(nil)
160 +
161 + todo := len(b)
162 +
163 + if j+todo > len(result) {
164 + todo = len(result) - j
165 + }
166 +
167 + copy(result[j:j+todo], b)
168 +
169 + j += todo
170 +
171 + m.Reset()
172 + m.Write(a)
173 + a = m.Sum(nil)
174 + }
175 +
176 + myResult := make([]byte, ivSize+cipherKeySize+hmacKeySize)
177 + theirResult := make([]byte, ivSize+cipherKeySize+hmacKeySize)
178 +
179 + half := len(result) / 2
180 +
181 + if cmp == 1 {
182 + copy(myResult, result[:half])
183 + copy(theirResult, result[half:])
184 + } else if cmp == -1 {
185 + copy(myResult, result[half:])
186 + copy(theirResult, result[:half])
187 + } else { // Shouldn't happen, but oh well.
188 + copy(myResult, result[half:])
189 + copy(theirResult, result[half:])
190 + }
191 +
192 + myIV := myResult[0:ivSize]
193 + myCKey := myResult[ivSize : ivSize+cipherKeySize]
194 + myMKey := myResult[ivSize+cipherKeySize:]
195 +
196 + theirIV := theirResult[0:ivSize]
197 + theirCKey := theirResult[ivSize : ivSize+cipherKeySize]
198 + theirMKey := theirResult[ivSize+cipherKeySize:]
199 +
200 + return myIV, theirIV, myCKey, theirCKey, myMKey, theirMKey
201 +}
202 +
203 func UnmarshalPublicKey(data []byte) (PubKey, error) {
204 pmes := new(PBPublicKey)
205 err := proto.Unmarshal(data, pmes)
crypto/rsa.go
-8
@@ -28,10 +28,6 @@ func (pk *RsaPublicKey) Verify(data, sig []byte) (bool, error) {
28 return true, nil
29 }
30
31 -func (pk *RsaPublicKey) Encrypt(message []byte) ([]byte, error) {
32 - return rsa.EncryptPKCS1v15(rand.Reader, pk.k, message)
33 -}
34 -
31 func (pk *RsaPublicKey) Bytes() ([]byte, error) {
32 b, err := x509.MarshalPKIXPublicKey(pk.k)
33 if err != nil {
@@ -56,10 +52,6 @@ func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) {
52 return rsa.SignPKCS1v15(rand.Reader, sk.k, crypto.SHA256, hashed[:])
53 }
54
59 -func (sk *RsaPrivateKey) Decrypt(ciphertext []byte) ([]byte, error) {
60 - return rsa.DecryptPKCS1v15(rand.Reader, sk.k, ciphertext)
61 -}
62 -
55 func (sk *RsaPrivateKey) GetPublic() PubKey {
56 return &RsaPublicKey{&sk.k.PublicKey}
57 }
identify/identify.go
+70 -247
@@ -4,18 +4,17 @@ package identify
4
5 import (
6 "bytes"
7 + "errors"
8 + "strings"
9 +
10 "crypto/aes"
11 "crypto/cipher"
9 - "crypto/elliptic"
12 "crypto/hmac"
13 "crypto/rand"
14 "crypto/sha1"
15 "crypto/sha256"
16 "crypto/sha512"
15 - "errors"
17 "hash"
17 - "math/big"
18 - "strings"
18
19 proto "code.google.com/p/goprotobuf/proto"
20 ci "github.com/jbenet/go-ipfs/crypto"
@@ -95,7 +94,7 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) (chan []byte, chan
94 return nil, nil, err
95 }
96
98 - epubkey, done, err := generateEPubKey(exchange) // Generate EphemeralPubKey
97 + epubkey, done, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey
98
99 var handshake bytes.Buffer // Gather corpus to sign.
100 handshake.Write(encoded)
@@ -144,87 +143,13 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) (chan []byte, chan
143 }
144
145 cmp := bytes.Compare(myPubKey, helloResp.GetPubkey())
147 - mIV, tIV, mCKey, tCKey, mMKey, tMKey := keyGenerator(cmp, cipherType, hashType, secret)
146 + mIV, tIV, mCKey, tCKey, mMKey, tMKey := ci.KeyStretcher(cmp, cipherType, hashType, secret)
147
148 secureIn := make(chan []byte)
149 secureOut := make(chan []byte)
150
152 - go func() {
153 - myBlock, _ := aes.NewCipher(mCKey)
154 - myCipher := cipher.NewCTR(myBlock, mIV)
155 -
156 - theirBlock, _ := aes.NewCipher(tCKey)
157 - theirCipher := cipher.NewCTR(theirBlock, tIV)
158 -
159 - var myMac, theirMac hash.Hash
160 - var macSize int
161 -
162 - switch hashType {
163 - case "SHA1":
164 - myMac = hmac.New(sha1.New, mMKey)
165 - theirMac = hmac.New(sha1.New, tMKey)
166 - macSize = 20
167 -
168 - case "SHA256":
169 - myMac = hmac.New(sha256.New, mMKey)
170 - theirMac = hmac.New(sha256.New, tMKey)
171 - macSize = 32
172 -
173 - case "SHA512":
174 - myMac = hmac.New(sha512.New, mMKey)
175 - theirMac = hmac.New(sha512.New, tMKey)
176 - macSize = 64
177 - }
178 -
179 - for {
180 - select {
181 - case data, ok := <-secureOut:
182 - if !ok {
183 - return
184 - }
185 -
186 - if len(data) == 0 {
187 - continue
188 - }
189 -
190 - buff := make([]byte, len(data)+macSize)
191 -
192 - myCipher.XORKeyStream(buff, data)
193 -
194 - myMac.Write(buff[0:len(data)])
195 - copy(buff[len(data):], myMac.Sum(nil))
196 - myMac.Reset()
197 -
198 - out <- buff
199 -
200 - case data, ok := <-in:
201 - if !ok {
202 - return
203 - }
204 -
205 - if len(data) <= macSize {
206 - continue
207 - }
208 -
209 - mark := len(data) - macSize
210 - buff := make([]byte, mark)
211 -
212 - theirCipher.XORKeyStream(buff, data[0:mark])
213 -
214 - theirMac.Write(data[0:mark])
215 - expected := theirMac.Sum(nil)
216 - theirMac.Reset()
217 -
218 - hmacOk := hmac.Equal(data[mark:], expected)
219 -
220 - if hmacOk {
221 - secureIn <- buff
222 - } else {
223 - secureIn <- nil
224 - }
225 - }
226 - }
227 - }()
151 + go secureInProxy(in, secureIn, hashType, tIV, tCKey, tMKey)
152 + go secureOutProxy(out, secureOut, hashType, mIV, mCKey, mMKey)
153
154 finished := []byte("Finished")
155
@@ -240,99 +165,90 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) (chan []byte, chan
165 return secureIn, secureOut, nil
166 }
167
243 -func IdFromPubKey(pk ci.PubKey) (peer.ID, error) {
244 - b, err := pk.Bytes()
245 - if err != nil {
246 - return nil, err
247 - }
248 - hash, err := u.Hash(b)
249 - if err != nil {
250 - return nil, err
168 +func makeMac(hashType string, key []byte) (hash.Hash, int) {
169 + switch hashType {
170 + case "SHA1":
171 + return hmac.New(sha1.New, key), sha1.Size
172 + case "SHA512":
173 + return hmac.New(sha512.New, key), sha512.Size
174 + default:
175 + return hmac.New(sha256.New, key), sha256.Size
176 }
252 - return peer.ID(hash), nil
177 }
178
255 -// Generates a set of keys for each party by stretching the shared key.
256 -// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey)
257 -func keyGenerator(cmp int, cipherType string, hashType string, secret []byte) ([]byte, []byte, []byte, []byte, []byte, []byte) {
258 - var cipherKeySize int
259 - switch cipherType {
260 - case "AES-128":
261 - cipherKeySize = 16
262 - case "AES-256":
263 - cipherKeySize = 32
264 - }
265 -
266 - ivSize := 16
267 - hmacKeySize := 20
268 -
269 - seed := []byte("key expansion")
179 +func secureInProxy(in, secureIn chan []byte, hashType string, tIV, tCKey, tMKey []byte) {
180 + theirBlock, _ := aes.NewCipher(tCKey)
181 + theirCipher := cipher.NewCTR(theirBlock, tIV)
182
271 - result := make([]byte, 2*(ivSize+cipherKeySize+hmacKeySize))
183 + theirMac, macSize := makeMac(hashType, tMKey)
184
273 - var h func() hash.Hash
185 + for {
186 + data, ok := <-in
187 + if !ok {
188 + return
189 + }
190
275 - switch hashType {
276 - case "SHA1":
277 - h = sha1.New
278 - case "SHA256":
279 - h = sha256.New
280 - case "SHA512":
281 - h = sha512.New
282 - }
191 + if len(data) <= macSize {
192 + continue
193 + }
194
284 - m := hmac.New(h, secret)
285 - m.Write(seed)
195 + mark := len(data) - macSize
196 + buff := make([]byte, mark)
197
287 - a := m.Sum(nil)
198 + theirCipher.XORKeyStream(buff, data[0:mark])
199
289 - j := 0
290 - for j < len(result) {
291 - m.Reset()
292 - m.Write(a)
293 - m.Write(seed)
294 - b := m.Sum(nil)
200 + theirMac.Write(data[0:mark])
201 + expected := theirMac.Sum(nil)
202 + theirMac.Reset()
203
296 - todo := len(b)
204 + hmacOk := hmac.Equal(data[mark:], expected)
205
298 - if j+todo > len(result) {
299 - todo = len(result) - j
206 + if hmacOk {
207 + secureIn <- buff
208 + } else {
209 + secureIn <- nil
210 }
211 + }
212 +}
213
302 - copy(result[j:j+todo], b)
214 +func secureOutProxy(out, secureOut chan []byte, hashType string, mIV, mCKey, mMKey []byte) {
215 + myBlock, _ := aes.NewCipher(mCKey)
216 + myCipher := cipher.NewCTR(myBlock, mIV)
217
304 - j += todo
218 + myMac, macSize := makeMac(hashType, mMKey)
219
306 - m.Reset()
307 - m.Write(a)
308 - a = m.Sum(nil)
309 - }
220 + for {
221 + data, ok := <-secureOut
222 + if !ok {
223 + return
224 + }
225
311 - myResult := make([]byte, ivSize+cipherKeySize+hmacKeySize)
312 - theirResult := make([]byte, ivSize+cipherKeySize+hmacKeySize)
226 + if len(data) == 0 {
227 + continue
228 + }
229
314 - half := len(result) / 2
230 + buff := make([]byte, len(data)+macSize)
231
316 - if cmp == 1 {
317 - copy(myResult, result[:half])
318 - copy(theirResult, result[half:])
319 - } else if cmp == -1 {
320 - copy(myResult, result[half:])
321 - copy(theirResult, result[:half])
322 - } else { // Shouldn't happen, but oh well.
323 - copy(myResult, result[half:])
324 - copy(theirResult, result[half:])
325 - }
232 + myCipher.XORKeyStream(buff, data)
233
327 - myIV := myResult[0:ivSize]
328 - myCKey := myResult[ivSize : ivSize+cipherKeySize]
329 - myMKey := myResult[ivSize+cipherKeySize:]
234 + myMac.Write(buff[0:len(data)])
235 + copy(buff[len(data):], myMac.Sum(nil))
236 + myMac.Reset()
237
331 - theirIV := theirResult[0:ivSize]
332 - theirCKey := theirResult[ivSize : ivSize+cipherKeySize]
333 - theirMKey := theirResult[ivSize+cipherKeySize:]
238 + out <- buff
239 + }
240 +}
241
335 - return myIV, theirIV, myCKey, theirCKey, myMKey, theirMKey
242 +func IdFromPubKey(pk ci.PubKey) (peer.ID, error) {
243 + b, err := pk.Bytes()
244 + if err != nil {
245 + return nil, err
246 + }
247 + hash, err := u.Hash(b)
248 + if err != nil {
249 + return nil, err
250 + }
251 + return peer.ID(hash), nil
252 }
253
254 // Determines which algorithm to use. Note: f(a, b) = f(b, a)
@@ -372,96 +288,3 @@ func selectBest(myPrefs, theirPrefs string) (string, error) {
288
289 return "", errors.New("No algorithms in common!")
290 }
375 -
376 -// Generates an ephemeral public key and returns a function that will compute
377 -// the shared secret key.
378 -//
379 -// Focuses only on ECDH now, but can be made more general in the future.
380 -func generateEPubKey(exchange string) ([]byte, func([]byte) ([]byte, error), error) {
381 - genKeyPair := func(curve elliptic.Curve) ([]byte, []byte, error) {
382 - priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
383 - if err != nil {
384 - return nil, nil, err
385 - }
386 -
387 - var pubKey bytes.Buffer
388 - pubKey.Write(x.Bytes())
389 - pubKey.Write(y.Bytes())
390 -
391 - return pubKey.Bytes(), priv, nil
392 - }
393 -
394 - genSec := func(curve elliptic.Curve, theirPub []byte, myPriv []byte) ([]byte, error) {
395 - // Verify and unpack node's public key.
396 - curveSize := curve.Params().BitSize
397 -
398 - if len(theirPub) != (curveSize / 4) {
399 - return nil, errors.New("Malformed public key.")
400 - }
401 -
402 - bound := (curveSize / 8)
403 - x := big.NewInt(0)
404 - y := big.NewInt(0)
405 -
406 - x.SetBytes(theirPub[0:bound])
407 - y.SetBytes(theirPub[bound : bound*2])
408 -
409 - if !curve.IsOnCurve(x, y) {
410 - return nil, errors.New("Invalid public key.")
411 - }
412 -
413 - // Generate shared secret.
414 - secret, _ := curve.ScalarMult(x, y, myPriv)
415 -
416 - return secret.Bytes(), nil
417 - }
418 -
419 - switch exchange {
420 - case "P-224":
421 - curve := elliptic.P224()
422 - pub, priv, err := genKeyPair(curve)
423 - if err != nil {
424 - return nil, nil, err
425 - }
426 -
427 - done := func(theirs []byte) ([]byte, error) { return genSec(curve, theirs, priv) }
428 -
429 - return pub, done, nil
430 -
431 - case "P-256":
432 - curve := elliptic.P256()
433 - pub, priv, err := genKeyPair(curve)
434 - if err != nil {
435 - return nil, nil, err
436 - }
437 -
438 - done := func(theirs []byte) ([]byte, error) { return genSec(curve, theirs, priv) }
439 -
440 - return pub, done, nil
441 -
442 - case "P-384":
443 - curve := elliptic.P384()
444 - pub, priv, err := genKeyPair(curve)
445 - if err != nil {
446 - return nil, nil, err
447 - }
448 -
449 - done := func(theirs []byte) ([]byte, error) { return genSec(curve, theirs, priv) }
450 -
451 - return pub, done, nil
452 -
453 - case "P-521":
454 - curve := elliptic.P521()
455 - pub, priv, err := genKeyPair(curve)
456 - if err != nil {
457 - return nil, nil, err
458 - }
459 -
460 - done := func(theirs []byte) ([]byte, error) { return genSec(curve, theirs, priv) }
461 -
462 - return pub, done, nil
463 -
464 - }
465 -
466 - return nil, nil, errors.New("Something silly happened.")
467 -}