commit
						c1d0693cb1
					
				
							
								
								
									
										46
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										46
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
| 	"ImportPath": "github.com/ethereum/go-ethereum", | 	"ImportPath": "github.com/ethereum/go-ethereum", | ||||||
| 	"GoVersion": "go1.4", | 	"GoVersion": "go1.4.1", | ||||||
| 	"Packages": [ | 	"Packages": [ | ||||||
| 		"./..." | 		"./..." | ||||||
| 	], | 	], | ||||||
| @ -15,26 +15,6 @@ | |||||||
| 			"Comment": "null-12", | 			"Comment": "null-12", | ||||||
| 			"Rev": "7dda39b2e7d5e265014674c5af696ba4186679e9" | 			"Rev": "7dda39b2e7d5e265014674c5af696ba4186679e9" | ||||||
| 		}, | 		}, | ||||||
| 		{ |  | ||||||
| 			"ImportPath": "code.google.com/p/go.crypto/pbkdf2", |  | ||||||
| 			"Comment": "null-236", |  | ||||||
| 			"Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			"ImportPath": "code.google.com/p/go.crypto/ripemd160", |  | ||||||
| 			"Comment": "null-236", |  | ||||||
| 			"Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			"ImportPath": "code.google.com/p/go.crypto/scrypt", |  | ||||||
| 			"Comment": "null-236", |  | ||||||
| 			"Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			"ImportPath": "code.google.com/p/go.net/websocket", |  | ||||||
| 			"Comment": "null-173", |  | ||||||
| 			"Rev": "4231557d7c726df4cf9a4e8cdd8a417c8c200bdb" |  | ||||||
| 		}, |  | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "code.google.com/p/snappy-go/snappy", | 			"ImportPath": "code.google.com/p/snappy-go/snappy", | ||||||
| 			"Comment": "null-15", | 			"Comment": "null-15", | ||||||
| @ -44,22 +24,18 @@ | |||||||
| 			"ImportPath": "github.com/ethereum/serpent-go", | 			"ImportPath": "github.com/ethereum/serpent-go", | ||||||
| 			"Rev": "5767a0dbd759d313df3f404dadb7f98d7ab51443" | 			"Rev": "5767a0dbd759d313df3f404dadb7f98d7ab51443" | ||||||
| 		}, | 		}, | ||||||
| 		{ |  | ||||||
| 			"ImportPath": "github.com/fjl/goupnp", |  | ||||||
| 			"Rev": "fa95df6feb61e136b499d01711fcd410ccaf20c1" |  | ||||||
| 		}, |  | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "github.com/howeyc/fsnotify", | 			"ImportPath": "github.com/howeyc/fsnotify", | ||||||
| 			"Comment": "v0.9.0-11-g6b1ef89", | 			"Comment": "v0.9.0-11-g6b1ef89", | ||||||
| 			"Rev": "6b1ef893dc11e0447abda6da20a5203481878dda" | 			"Rev": "6b1ef893dc11e0447abda6da20a5203481878dda" | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "github.com/jackpal/go-nat-pmp", | 			"ImportPath": "github.com/huin/goupnp", | ||||||
| 			"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" | 			"Rev": "4191d8a85005844ea202fde52799681971b12dfe" | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "github.com/obscuren/ecies", | 			"ImportPath": "github.com/jackpal/go-nat-pmp", | ||||||
| 			"Rev": "d899334bba7bf4a157cab19d8ad836dcb1de0c34" | 			"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "github.com/obscuren/otto", | 			"ImportPath": "github.com/obscuren/otto", | ||||||
| @ -109,6 +85,18 @@ | |||||||
| 			"ImportPath": "golang.org/x/crypto/pbkdf2", | 			"ImportPath": "golang.org/x/crypto/pbkdf2", | ||||||
| 			"Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" | 			"Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"ImportPath": "golang.org/x/crypto/ripemd160", | ||||||
|  | 			"Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"ImportPath": "golang.org/x/crypto/scrypt", | ||||||
|  | 			"Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"ImportPath": "golang.org/x/net/websocket", | ||||||
|  | 			"Rev": "59b0df9b1f7abda5aab0495ee54f408daf182ce7" | ||||||
|  | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "gopkg.in/check.v1", | 			"ImportPath": "gopkg.in/check.v1", | ||||||
| 			"Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673" | 			"Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673" | ||||||
|  | |||||||
							
								
								
									
										77
									
								
								Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,77 +0,0 @@ | |||||||
| // Copyright 2012 The Go Authors. All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC |  | ||||||
| 2898 / PKCS #5 v2.0. |  | ||||||
| 
 |  | ||||||
| A key derivation function is useful when encrypting data based on a password |  | ||||||
| or any other not-fully-random data. It uses a pseudorandom function to derive |  | ||||||
| a secure encryption key based on the password. |  | ||||||
| 
 |  | ||||||
| While v2.0 of the standard defines only one pseudorandom function to use, |  | ||||||
| HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved |  | ||||||
| Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To |  | ||||||
| choose, you can pass the `New` functions from the different SHA packages to |  | ||||||
| pbkdf2.Key. |  | ||||||
| */ |  | ||||||
| package pbkdf2 |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto/hmac" |  | ||||||
| 	"hash" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Key derives a key from the password, salt and iteration count, returning a
 |  | ||||||
| // []byte of length keylen that can be used as cryptographic key. The key is
 |  | ||||||
| // derived based on the method described as PBKDF2 with the HMAC variant using
 |  | ||||||
| // the supplied hash function.
 |  | ||||||
| //
 |  | ||||||
| // For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you
 |  | ||||||
| // can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
 |  | ||||||
| // doing:
 |  | ||||||
| //
 |  | ||||||
| // 	dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
 |  | ||||||
| //
 |  | ||||||
| // Remember to get a good random salt. At least 8 bytes is recommended by the
 |  | ||||||
| // RFC.
 |  | ||||||
| //
 |  | ||||||
| // Using a higher iteration count will increase the cost of an exhaustive
 |  | ||||||
| // search but will also make derivation proportionally slower.
 |  | ||||||
| func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { |  | ||||||
| 	prf := hmac.New(h, password) |  | ||||||
| 	hashLen := prf.Size() |  | ||||||
| 	numBlocks := (keyLen + hashLen - 1) / hashLen |  | ||||||
| 
 |  | ||||||
| 	var buf [4]byte |  | ||||||
| 	dk := make([]byte, 0, numBlocks*hashLen) |  | ||||||
| 	U := make([]byte, hashLen) |  | ||||||
| 	for block := 1; block <= numBlocks; block++ { |  | ||||||
| 		// N.B.: || means concatenation, ^ means XOR
 |  | ||||||
| 		// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
 |  | ||||||
| 		// U_1 = PRF(password, salt || uint(i))
 |  | ||||||
| 		prf.Reset() |  | ||||||
| 		prf.Write(salt) |  | ||||||
| 		buf[0] = byte(block >> 24) |  | ||||||
| 		buf[1] = byte(block >> 16) |  | ||||||
| 		buf[2] = byte(block >> 8) |  | ||||||
| 		buf[3] = byte(block) |  | ||||||
| 		prf.Write(buf[:4]) |  | ||||||
| 		dk = prf.Sum(dk) |  | ||||||
| 		T := dk[len(dk)-hashLen:] |  | ||||||
| 		copy(U, T) |  | ||||||
| 
 |  | ||||||
| 		// U_n = PRF(password, U_(n-1))
 |  | ||||||
| 		for n := 2; n <= iter; n++ { |  | ||||||
| 			prf.Reset() |  | ||||||
| 			prf.Write(U) |  | ||||||
| 			U = U[:0] |  | ||||||
| 			U = prf.Sum(U) |  | ||||||
| 			for x := range U { |  | ||||||
| 				T[x] ^= U[x] |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return dk[:keyLen] |  | ||||||
| } |  | ||||||
							
								
								
									
										157
									
								
								Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										157
									
								
								Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,157 +0,0 @@ | |||||||
| // Copyright 2012 The Go Authors. All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package pbkdf2 |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"crypto/sha1" |  | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"hash" |  | ||||||
| 	"testing" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type testVector struct { |  | ||||||
| 	password string |  | ||||||
| 	salt     string |  | ||||||
| 	iter     int |  | ||||||
| 	output   []byte |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Test vectors from RFC 6070, http://tools.ietf.org/html/rfc6070
 |  | ||||||
| var sha1TestVectors = []testVector{ |  | ||||||
| 	{ |  | ||||||
| 		"password", |  | ||||||
| 		"salt", |  | ||||||
| 		1, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, |  | ||||||
| 			0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, |  | ||||||
| 			0x2f, 0xe0, 0x37, 0xa6, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		"password", |  | ||||||
| 		"salt", |  | ||||||
| 		2, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, |  | ||||||
| 			0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, |  | ||||||
| 			0xd8, 0xde, 0x89, 0x57, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		"password", |  | ||||||
| 		"salt", |  | ||||||
| 		4096, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, |  | ||||||
| 			0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, |  | ||||||
| 			0x65, 0xa4, 0x29, 0xc1, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	// // This one takes too long
 |  | ||||||
| 	// {
 |  | ||||||
| 	// 	"password",
 |  | ||||||
| 	// 	"salt",
 |  | ||||||
| 	// 	16777216,
 |  | ||||||
| 	// 	[]byte{
 |  | ||||||
| 	// 		0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
 |  | ||||||
| 	// 		0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
 |  | ||||||
| 	// 		0x26, 0x34, 0xe9, 0x84,
 |  | ||||||
| 	// 	},
 |  | ||||||
| 	// },
 |  | ||||||
| 	{ |  | ||||||
| 		"passwordPASSWORDpassword", |  | ||||||
| 		"saltSALTsaltSALTsaltSALTsaltSALTsalt", |  | ||||||
| 		4096, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, |  | ||||||
| 			0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, |  | ||||||
| 			0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, |  | ||||||
| 			0x38, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		"pass\000word", |  | ||||||
| 		"sa\000lt", |  | ||||||
| 		4096, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, |  | ||||||
| 			0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Test vectors from
 |  | ||||||
| // http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors
 |  | ||||||
| var sha256TestVectors = []testVector{ |  | ||||||
| 	{ |  | ||||||
| 		"password", |  | ||||||
| 		"salt", |  | ||||||
| 		1, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, |  | ||||||
| 			0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, |  | ||||||
| 			0xa8, 0x65, 0x48, 0xc9, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		"password", |  | ||||||
| 		"salt", |  | ||||||
| 		2, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, |  | ||||||
| 			0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, |  | ||||||
| 			0x2a, 0x30, 0x3f, 0x8e, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		"password", |  | ||||||
| 		"salt", |  | ||||||
| 		4096, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, |  | ||||||
| 			0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, |  | ||||||
| 			0x96, 0x28, 0x93, 0xa0, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		"passwordPASSWORDpassword", |  | ||||||
| 		"saltSALTsaltSALTsaltSALTsaltSALTsalt", |  | ||||||
| 		4096, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, |  | ||||||
| 			0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, |  | ||||||
| 			0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, |  | ||||||
| 			0x1c, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		"pass\000word", |  | ||||||
| 		"sa\000lt", |  | ||||||
| 		4096, |  | ||||||
| 		[]byte{ |  | ||||||
| 			0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, |  | ||||||
| 			0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testVector) { |  | ||||||
| 	for i, v := range vectors { |  | ||||||
| 		o := Key([]byte(v.password), []byte(v.salt), v.iter, len(v.output), h) |  | ||||||
| 		if !bytes.Equal(o, v.output) { |  | ||||||
| 			t.Errorf("%s %d: expected %x, got %x", hashName, i, v.output, o) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestWithHMACSHA1(t *testing.T) { |  | ||||||
| 	testHash(t, sha1.New, "SHA1", sha1TestVectors) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestWithHMACSHA256(t *testing.T) { |  | ||||||
| 	testHash(t, sha256.New, "SHA256", sha256TestVectors) |  | ||||||
| } |  | ||||||
| @ -3,7 +3,7 @@ goupnp is a UPnP client library for Go | |||||||
| Installation | Installation | ||||||
| ------------ | ------------ | ||||||
| 
 | 
 | ||||||
| Run `go get -u github.com/fjl/goupnp`. | Run `go get -u github.com/huin/goupnp`. | ||||||
| 
 | 
 | ||||||
| Regenerating dcps generated source code: | Regenerating dcps generated source code: | ||||||
| ---------------------------------------- | ---------------------------------------- | ||||||
| @ -4,7 +4,7 @@ import ( | |||||||
| 	"log" | 	"log" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp/httpu" | 	"github.com/huin/goupnp/httpu" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| @ -4,7 +4,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp/dcps/internetgateway1" | 	"github.com/huin/goupnp/dcps/internetgateway1" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| @ -11,8 +11,8 @@ package internetgateway1 | |||||||
| import ( | import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp" | 	"github.com/huin/goupnp" | ||||||
| 	"github.com/fjl/goupnp/soap" | 	"github.com/huin/goupnp/soap" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Hack to avoid Go complaining if time isn't used.
 | // Hack to avoid Go complaining if time isn't used.
 | ||||||
| @ -11,8 +11,8 @@ package internetgateway2 | |||||||
| import ( | import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp" | 	"github.com/huin/goupnp" | ||||||
| 	"github.com/fjl/goupnp/soap" | 	"github.com/huin/goupnp/soap" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Hack to avoid Go complaining if time isn't used.
 | // Hack to avoid Go complaining if time isn't used.
 | ||||||
| @ -8,8 +8,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp/scpd" | 	"github.com/huin/goupnp/scpd" | ||||||
| 	"github.com/fjl/goupnp/soap" | 	"github.com/huin/goupnp/soap" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| @ -2,5 +2,5 @@ | |||||||
| //
 | //
 | ||||||
| // To run examples and see the output for your local network, run the following
 | // To run examples and see the output for your local network, run the following
 | ||||||
| // command (specifically including the -v flag):
 | // command (specifically including the -v flag):
 | ||||||
| //     go test -v github.com/fjl/goupnp/example
 | //     go test -v github.com/huin/goupnp/example
 | ||||||
| package example | package example | ||||||
| @ -4,8 +4,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp" | 	"github.com/huin/goupnp" | ||||||
| 	"github.com/fjl/goupnp/dcps/internetgateway1" | 	"github.com/huin/goupnp/dcps/internetgateway1" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Use discovered WANPPPConnection1 services to find external IP addresses.
 | // Use discovered WANPPPConnection1 services to find external IP addresses.
 | ||||||
| @ -17,8 +17,8 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"text/template" | 	"text/template" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp" | 	"github.com/huin/goupnp" | ||||||
| 	"github.com/fjl/goupnp/scpd" | 	"github.com/huin/goupnp/scpd" | ||||||
| 	"github.com/huin/goutil/codegen" | 	"github.com/huin/goutil/codegen" | ||||||
| 	"github.com/jingweno/gotask/tasking" | 	"github.com/jingweno/gotask/tasking" | ||||||
| ) | ) | ||||||
| @ -38,7 +38,7 @@ var ( | |||||||
| //   -s, --spec_filename=<upnpresources.zip>
 | //   -s, --spec_filename=<upnpresources.zip>
 | ||||||
| //     Path to the specification file, available from http://upnp.org/resources/upnpresources.zip
 | //     Path to the specification file, available from http://upnp.org/resources/upnpresources.zip
 | ||||||
| //   -o, --out_dir=<output directory>
 | //   -o, --out_dir=<output directory>
 | ||||||
| //     Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/fjl/goupnp/dcps
 | //     Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/huin/goupnp/dcps
 | ||||||
| //   --nogofmt
 | //   --nogofmt
 | ||||||
| //     Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt.
 | //     Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt.
 | ||||||
| func TaskSpecgen(t *tasking.T) { | func TaskSpecgen(t *tasking.T) { | ||||||
| @ -445,8 +445,8 @@ package {{$name}} | |||||||
| import ( | import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp" | 	"github.com/huin/goupnp" | ||||||
| 	"github.com/fjl/goupnp/soap" | 	"github.com/huin/goupnp/soap" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Hack to avoid Go complaining if time isn't used.
 | // Hack to avoid Go complaining if time isn't used.
 | ||||||
| @ -1,11 +1,11 @@ | |||||||
| // goupnp is an implementation of a client for various UPnP services.
 | // goupnp is an implementation of a client for various UPnP services.
 | ||||||
| //
 | //
 | ||||||
| // For most uses, it is recommended to use the code-generated packages under
 | // For most uses, it is recommended to use the code-generated packages under
 | ||||||
| // github.com/fjl/goupnp/dcps. Example use is shown at
 | // github.com/huin/goupnp/dcps. Example use is shown at
 | ||||||
| // http://godoc.org/github.com/fjl/goupnp/example
 | // http://godoc.org/github.com/huin/goupnp/example
 | ||||||
| //
 | //
 | ||||||
| // A commonly used client is internetgateway1.WANPPPConnection1:
 | // A commonly used client is internetgateway1.WANPPPConnection1:
 | ||||||
| // http://godoc.org/github.com/fjl/goupnp/dcps/internetgateway1#WANPPPConnection1
 | // http://godoc.org/github.com/huin/goupnp/dcps/internetgateway1#WANPPPConnection1
 | ||||||
| //
 | //
 | ||||||
| // Currently only a couple of schemas have code generated for them from the
 | // Currently only a couple of schemas have code generated for them from the
 | ||||||
| // UPnP example XML specifications. Not all methods will work on these clients,
 | // UPnP example XML specifications. Not all methods will work on these clients,
 | ||||||
| @ -20,8 +20,8 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp/httpu" | 	"github.com/huin/goupnp/httpu" | ||||||
| 	"github.com/fjl/goupnp/ssdp" | 	"github.com/huin/goupnp/ssdp" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ContextError is an error that wraps an error with some context information.
 | // ContextError is an error that wraps an error with some context information.
 | ||||||
| @ -2,8 +2,7 @@ package goupnp | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 	"github.com/huin/goupnp/soap" | ||||||
| 	"github.com/fjl/goupnp/soap" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ServiceClient is a SOAP client, root device and the service for the SOAP
 | // ServiceClient is a SOAP client, root device and the service for the SOAP
 | ||||||
| @ -10,7 +10,7 @@ import ( | |||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp/httpu" | 	"github.com/huin/goupnp/httpu" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| @ -8,7 +8,7 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp/httpu" | 	"github.com/huin/goupnp/httpu" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
							
								
								
									
										24
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,24 +0,0 @@ | |||||||
| # Compiled Object files, Static and Dynamic libs (Shared Objects) |  | ||||||
| *.o |  | ||||||
| *.a |  | ||||||
| *.so |  | ||||||
| 
 |  | ||||||
| # Folders |  | ||||||
| _obj |  | ||||||
| _test |  | ||||||
| 
 |  | ||||||
| # Architecture specific extensions/prefixes |  | ||||||
| *.[568vq] |  | ||||||
| [568vq].out |  | ||||||
| 
 |  | ||||||
| *.cgo1.go |  | ||||||
| *.cgo2.c |  | ||||||
| _cgo_defun.c |  | ||||||
| _cgo_gotypes.go |  | ||||||
| _cgo_export.* |  | ||||||
| 
 |  | ||||||
| _testmain.go |  | ||||||
| 
 |  | ||||||
| *.exe |  | ||||||
| 
 |  | ||||||
| *~ |  | ||||||
							
								
								
									
										28
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,28 +0,0 @@ | |||||||
| Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is> |  | ||||||
| Copyright (c) 2012 The Go Authors. All rights reserved. |  | ||||||
| 
 |  | ||||||
| Redistribution and use in source and binary forms, with or without |  | ||||||
| modification, are permitted provided that the following conditions are |  | ||||||
| met: |  | ||||||
| 
 |  | ||||||
|    * Redistributions of source code must retain the above copyright |  | ||||||
| notice, this list of conditions and the following disclaimer. |  | ||||||
|    * Redistributions in binary form must reproduce the above |  | ||||||
| copyright notice, this list of conditions and the following disclaimer |  | ||||||
| in the documentation and/or other materials provided with the |  | ||||||
| distribution. |  | ||||||
|    * Neither the name of Google Inc. nor the names of its |  | ||||||
| contributors may be used to endorse or promote products derived from |  | ||||||
| this software without specific prior written permission. |  | ||||||
| 
 |  | ||||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  | ||||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  | ||||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  | ||||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  | ||||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  | ||||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  | ||||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  | ||||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  | ||||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  | ||||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  | ||||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | ||||||
							
								
								
									
										94
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/README
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										94
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/README
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,94 +0,0 @@ | |||||||
| # NOTE |  | ||||||
| 
 |  | ||||||
| This implementation is direct fork of Kylom's implementation. I claim no authorship over this code apart from some minor modifications. |  | ||||||
| Please be aware this code **has not yet been reviewed**. |  | ||||||
| 
 |  | ||||||
| ecies implements the Elliptic Curve Integrated Encryption Scheme. |  | ||||||
| 
 |  | ||||||
| The package is designed to be compliant with the appropriate NIST |  | ||||||
| standards, and therefore doesn't support the full SEC 1 algorithm set. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| STATUS: |  | ||||||
| 
 |  | ||||||
| ecies should be ready for use. The ASN.1 support is only complete so |  | ||||||
| far as to supported the listed algorithms before. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| CAVEATS |  | ||||||
| 
 |  | ||||||
| 1. CMAC support is currently not present. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| SUPPORTED ALGORITHMS |  | ||||||
| 
 |  | ||||||
|         SYMMETRIC CIPHERS               HASH FUNCTIONS |  | ||||||
|              AES128                         SHA-1 |  | ||||||
|              AES192                        SHA-224 |  | ||||||
|              AES256                        SHA-256 |  | ||||||
|                                            SHA-384 |  | ||||||
|         ELLIPTIC CURVE                     SHA-512 |  | ||||||
|              P256 |  | ||||||
|              P384		    KEY DERIVATION FUNCTION |  | ||||||
|              P521	       NIST SP 800-65a Concatenation KDF |  | ||||||
| 
 |  | ||||||
| Curve P224 isn't supported because it does not provide a minimum security |  | ||||||
| level of AES128 with HMAC-SHA1. According to NIST SP 800-57, the security |  | ||||||
| level of P224 is 112 bits of security. Symmetric ciphers use CTR-mode; |  | ||||||
| message tags are computed using HMAC-<HASH> function. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| CURVE SELECTION |  | ||||||
| 
 |  | ||||||
| According to NIST SP 800-57, the following curves should be selected: |  | ||||||
| 
 |  | ||||||
|     +----------------+-------+ |  | ||||||
|     | SYMMETRIC SIZE | CURVE | |  | ||||||
|     +----------------+-------+ |  | ||||||
|     |     128-bit    |  P256 | |  | ||||||
|     +----------------+-------+ |  | ||||||
|     |     192-bit    |  P384 | |  | ||||||
|     +----------------+-------+ |  | ||||||
|     |     256-bit    |  P521 | |  | ||||||
|     +----------------+-------+ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| TODO |  | ||||||
| 
 |  | ||||||
| 1. Look at serialising the parameters with the SEC 1 ASN.1 module. |  | ||||||
| 2. Validate ASN.1 formats with SEC 1. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| TEST VECTORS |  | ||||||
| 
 |  | ||||||
| The only test vectors I've found so far date from 1993, predating AES |  | ||||||
| and including only 163-bit curves. Therefore, there are no published |  | ||||||
| test vectors to compare to. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| LICENSE |  | ||||||
| 
 |  | ||||||
| ecies is released under the same license as the Go source code. See the |  | ||||||
| LICENSE file for details. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| REFERENCES |  | ||||||
| 
 |  | ||||||
| * SEC (Standard for Efficient Cryptography) 1, version 2.0: Elliptic |  | ||||||
|   Curve Cryptography; Certicom, May 2009. |  | ||||||
|   http://www.secg.org/sec1-v2.pdf |  | ||||||
| * GEC (Guidelines for Efficient Cryptography) 2, version 0.3: Test |  | ||||||
|   Vectors for SEC 1; Certicom, September 1999. |  | ||||||
|   http://read.pudn.com/downloads168/doc/772358/TestVectorsforSEC%201-gec2.pdf |  | ||||||
| * NIST SP 800-56a: Recommendation for Pair-Wise Key Establishment Schemes |  | ||||||
|   Using Discrete Logarithm Cryptography. National Institute of Standards |  | ||||||
|   and Technology, May 2007. |  | ||||||
|   http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf |  | ||||||
| * Suite B Implementer’s Guide to NIST SP 800-56A. National Security |  | ||||||
|   Agency, July 28, 2009. |  | ||||||
|   http://www.nsa.gov/ia/_files/SuiteB_Implementer_G-113808.pdf |  | ||||||
| * NIST SP 800-57: Recommendation for Key Management – Part 1: General |  | ||||||
|   (Revision 3). National Institute of Standards and Technology, July |  | ||||||
|   2012. |  | ||||||
|   http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_part1_rev3_general.pdf |  | ||||||
| 
 |  | ||||||
							
								
								
									
										556
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/asn1.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										556
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/asn1.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,556 +0,0 @@ | |||||||
| package ecies |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"crypto" |  | ||||||
| 	"crypto/elliptic" |  | ||||||
| 	"crypto/sha1" |  | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"crypto/sha512" |  | ||||||
| 	"encoding/asn1" |  | ||||||
| 	"encoding/pem" |  | ||||||
| 	"fmt" |  | ||||||
| 	"hash" |  | ||||||
| 	"math/big" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	secgScheme     = []int{1, 3, 132, 1} |  | ||||||
| 	shaScheme      = []int{2, 16, 840, 1, 101, 3, 4, 2} |  | ||||||
| 	ansiX962Scheme = []int{1, 2, 840, 10045} |  | ||||||
| 	x963Scheme     = []int{1, 2, 840, 63, 0} |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ErrInvalidPrivateKey = fmt.Errorf("ecies: invalid private key") |  | ||||||
| 
 |  | ||||||
| func doScheme(base, v []int) asn1.ObjectIdentifier { |  | ||||||
| 	var oidInts asn1.ObjectIdentifier |  | ||||||
| 	oidInts = append(oidInts, base...) |  | ||||||
| 	return append(oidInts, v...) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // curve OID code taken from crypto/x509, including
 |  | ||||||
| //	- oidNameCurve*
 |  | ||||||
| //	- namedCurveFromOID
 |  | ||||||
| //	- oidFromNamedCurve
 |  | ||||||
| // RFC 5480, 2.1.1.1. Named Curve
 |  | ||||||
| //
 |  | ||||||
| // secp224r1 OBJECT IDENTIFIER ::= {
 |  | ||||||
| //   iso(1) identified-organization(3) certicom(132) curve(0) 33 }
 |  | ||||||
| //
 |  | ||||||
| // secp256r1 OBJECT IDENTIFIER ::= {
 |  | ||||||
| //   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
 |  | ||||||
| //   prime(1) 7 }
 |  | ||||||
| //
 |  | ||||||
| // secp384r1 OBJECT IDENTIFIER ::= {
 |  | ||||||
| //   iso(1) identified-organization(3) certicom(132) curve(0) 34 }
 |  | ||||||
| //
 |  | ||||||
| // secp521r1 OBJECT IDENTIFIER ::= {
 |  | ||||||
| //   iso(1) identified-organization(3) certicom(132) curve(0) 35 }
 |  | ||||||
| //
 |  | ||||||
| // NB: secp256r1 is equivalent to prime256v1
 |  | ||||||
| type secgNamedCurve asn1.ObjectIdentifier |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	secgNamedCurveP224 = secgNamedCurve{1, 3, 132, 0, 33} |  | ||||||
| 	secgNamedCurveP256 = secgNamedCurve{1, 2, 840, 10045, 3, 1, 7} |  | ||||||
| 	secgNamedCurveP384 = secgNamedCurve{1, 3, 132, 0, 34} |  | ||||||
| 	secgNamedCurveP521 = secgNamedCurve{1, 3, 132, 0, 35} |  | ||||||
| 	rawCurveP224       = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 3} |  | ||||||
| 	rawCurveP256       = []byte{6, 8, 4, 2, 1, 3, 4, 7, 2, 2, 0, 6, 6, 1, 3, 1, 7} |  | ||||||
| 	rawCurveP384       = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 4} |  | ||||||
| 	rawCurveP521       = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 5} |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func rawCurve(curve elliptic.Curve) []byte { |  | ||||||
| 	switch curve { |  | ||||||
| 	case elliptic.P224(): |  | ||||||
| 		return rawCurveP224 |  | ||||||
| 	case elliptic.P256(): |  | ||||||
| 		return rawCurveP256 |  | ||||||
| 	case elliptic.P384(): |  | ||||||
| 		return rawCurveP384 |  | ||||||
| 	case elliptic.P521(): |  | ||||||
| 		return rawCurveP521 |  | ||||||
| 	default: |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (curve secgNamedCurve) Equal(curve2 secgNamedCurve) bool { |  | ||||||
| 	if len(curve) != len(curve2) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, _ := range curve { |  | ||||||
| 		if curve[i] != curve2[i] { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func namedCurveFromOID(curve secgNamedCurve) elliptic.Curve { |  | ||||||
| 	switch { |  | ||||||
| 	case curve.Equal(secgNamedCurveP224): |  | ||||||
| 		return elliptic.P224() |  | ||||||
| 	case curve.Equal(secgNamedCurveP256): |  | ||||||
| 		return elliptic.P256() |  | ||||||
| 	case curve.Equal(secgNamedCurveP384): |  | ||||||
| 		return elliptic.P384() |  | ||||||
| 	case curve.Equal(secgNamedCurveP521): |  | ||||||
| 		return elliptic.P521() |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func oidFromNamedCurve(curve elliptic.Curve) (secgNamedCurve, bool) { |  | ||||||
| 	switch curve { |  | ||||||
| 	case elliptic.P224(): |  | ||||||
| 		return secgNamedCurveP224, true |  | ||||||
| 	case elliptic.P256(): |  | ||||||
| 		return secgNamedCurveP256, true |  | ||||||
| 	case elliptic.P384(): |  | ||||||
| 		return secgNamedCurveP384, true |  | ||||||
| 	case elliptic.P521(): |  | ||||||
| 		return secgNamedCurveP521, true |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil, false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // asnAlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
 |  | ||||||
| // 5280, section 4.1.1.2.
 |  | ||||||
| type asnAlgorithmIdentifier struct { |  | ||||||
| 	Algorithm  asn1.ObjectIdentifier |  | ||||||
| 	Parameters asn1.RawValue `asn1:"optional"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (a asnAlgorithmIdentifier) Cmp(b asnAlgorithmIdentifier) bool { |  | ||||||
| 	if len(a.Algorithm) != len(b.Algorithm) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, _ := range a.Algorithm { |  | ||||||
| 		if a.Algorithm[i] != b.Algorithm[i] { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type asnHashFunction asnAlgorithmIdentifier |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	oidSHA1   = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26} |  | ||||||
| 	oidSHA224 = doScheme(shaScheme, []int{4}) |  | ||||||
| 	oidSHA256 = doScheme(shaScheme, []int{1}) |  | ||||||
| 	oidSHA384 = doScheme(shaScheme, []int{2}) |  | ||||||
| 	oidSHA512 = doScheme(shaScheme, []int{3}) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func hashFromOID(oid asn1.ObjectIdentifier) func() hash.Hash { |  | ||||||
| 	switch { |  | ||||||
| 	case oid.Equal(oidSHA1): |  | ||||||
| 		return sha1.New |  | ||||||
| 	case oid.Equal(oidSHA224): |  | ||||||
| 		return sha256.New224 |  | ||||||
| 	case oid.Equal(oidSHA256): |  | ||||||
| 		return sha256.New |  | ||||||
| 	case oid.Equal(oidSHA384): |  | ||||||
| 		return sha512.New384 |  | ||||||
| 	case oid.Equal(oidSHA512): |  | ||||||
| 		return sha512.New |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func oidFromHash(hash crypto.Hash) (asn1.ObjectIdentifier, bool) { |  | ||||||
| 	switch hash { |  | ||||||
| 	case crypto.SHA1: |  | ||||||
| 		return oidSHA1, true |  | ||||||
| 	case crypto.SHA224: |  | ||||||
| 		return oidSHA224, true |  | ||||||
| 	case crypto.SHA256: |  | ||||||
| 		return oidSHA256, true |  | ||||||
| 	case crypto.SHA384: |  | ||||||
| 		return oidSHA384, true |  | ||||||
| 	case crypto.SHA512: |  | ||||||
| 		return oidSHA512, true |  | ||||||
| 	default: |  | ||||||
| 		return nil, false |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	asnAlgoSHA1 = asnHashFunction{ |  | ||||||
| 		Algorithm: oidSHA1, |  | ||||||
| 	} |  | ||||||
| 	asnAlgoSHA224 = asnHashFunction{ |  | ||||||
| 		Algorithm: oidSHA224, |  | ||||||
| 	} |  | ||||||
| 	asnAlgoSHA256 = asnHashFunction{ |  | ||||||
| 		Algorithm: oidSHA256, |  | ||||||
| 	} |  | ||||||
| 	asnAlgoSHA384 = asnHashFunction{ |  | ||||||
| 		Algorithm: oidSHA384, |  | ||||||
| 	} |  | ||||||
| 	asnAlgoSHA512 = asnHashFunction{ |  | ||||||
| 		Algorithm: oidSHA512, |  | ||||||
| 	} |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // type ASNasnSubjectPublicKeyInfo struct {
 |  | ||||||
| //
 |  | ||||||
| // }
 |  | ||||||
| //
 |  | ||||||
| 
 |  | ||||||
| type asnSubjectPublicKeyInfo struct { |  | ||||||
| 	Algorithm   asn1.ObjectIdentifier |  | ||||||
| 	PublicKey   asn1.BitString |  | ||||||
| 	Supplements ecpksSupplements `asn1:"optional"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type asnECPKAlgorithms struct { |  | ||||||
| 	Type asn1.ObjectIdentifier |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var idPublicKeyType = doScheme(ansiX962Scheme, []int{2}) |  | ||||||
| var idEcPublicKey = doScheme(idPublicKeyType, []int{1}) |  | ||||||
| var idEcPublicKeySupplemented = doScheme(idPublicKeyType, []int{0}) |  | ||||||
| 
 |  | ||||||
| func curveToRaw(curve elliptic.Curve) (rv asn1.RawValue, ok bool) { |  | ||||||
| 	switch curve { |  | ||||||
| 	case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521(): |  | ||||||
| 		raw := rawCurve(curve) |  | ||||||
| 		return asn1.RawValue{ |  | ||||||
| 			Tag:       30, |  | ||||||
| 			Bytes:     raw[2:], |  | ||||||
| 			FullBytes: raw, |  | ||||||
| 		}, true |  | ||||||
| 	default: |  | ||||||
| 		return rv, false |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func asnECPublicKeyType(curve elliptic.Curve) (algo asnAlgorithmIdentifier, ok bool) { |  | ||||||
| 	raw, ok := curveToRaw(curve) |  | ||||||
| 	if !ok { |  | ||||||
| 		return |  | ||||||
| 	} else { |  | ||||||
| 		return asnAlgorithmIdentifier{Algorithm: idEcPublicKey, |  | ||||||
| 			Parameters: raw}, true |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type asnECPrivKeyVer int |  | ||||||
| 
 |  | ||||||
| var asnECPrivKeyVer1 asnECPrivKeyVer = 1 |  | ||||||
| 
 |  | ||||||
| type asnPrivateKey struct { |  | ||||||
| 	Version asnECPrivKeyVer |  | ||||||
| 	Private []byte |  | ||||||
| 	Curve   secgNamedCurve `asn1:"optional"` |  | ||||||
| 	Public  asn1.BitString |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var asnECDH = doScheme(secgScheme, []int{12}) |  | ||||||
| 
 |  | ||||||
| type asnECDHAlgorithm asnAlgorithmIdentifier |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	dhSinglePass_stdDH_sha1kdf = asnECDHAlgorithm{ |  | ||||||
| 		Algorithm: doScheme(x963Scheme, []int{2}), |  | ||||||
| 	} |  | ||||||
| 	dhSinglePass_stdDH_sha256kdf = asnECDHAlgorithm{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{11, 1}), |  | ||||||
| 	} |  | ||||||
| 	dhSinglePass_stdDH_sha384kdf = asnECDHAlgorithm{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{11, 2}), |  | ||||||
| 	} |  | ||||||
| 	dhSinglePass_stdDH_sha224kdf = asnECDHAlgorithm{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{11, 0}), |  | ||||||
| 	} |  | ||||||
| 	dhSinglePass_stdDH_sha512kdf = asnECDHAlgorithm{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{11, 3}), |  | ||||||
| 	} |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func (a asnECDHAlgorithm) Cmp(b asnECDHAlgorithm) bool { |  | ||||||
| 	if len(a.Algorithm) != len(b.Algorithm) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, _ := range a.Algorithm { |  | ||||||
| 		if a.Algorithm[i] != b.Algorithm[i] { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // asnNISTConcatenation is the only supported KDF at this time.
 |  | ||||||
| type asnKeyDerivationFunction asnAlgorithmIdentifier |  | ||||||
| 
 |  | ||||||
| var asnNISTConcatenationKDF = asnKeyDerivationFunction{ |  | ||||||
| 	Algorithm: doScheme(secgScheme, []int{17, 1}), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (a asnKeyDerivationFunction) Cmp(b asnKeyDerivationFunction) bool { |  | ||||||
| 	if len(a.Algorithm) != len(b.Algorithm) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, _ := range a.Algorithm { |  | ||||||
| 		if a.Algorithm[i] != b.Algorithm[i] { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var eciesRecommendedParameters = doScheme(secgScheme, []int{7}) |  | ||||||
| var eciesSpecifiedParameters = doScheme(secgScheme, []int{8}) |  | ||||||
| 
 |  | ||||||
| type asnECIESParameters struct { |  | ||||||
| 	KDF asnKeyDerivationFunction     `asn1:"optional"` |  | ||||||
| 	Sym asnSymmetricEncryption       `asn1:"optional"` |  | ||||||
| 	MAC asnMessageAuthenticationCode `asn1:"optional"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type asnSymmetricEncryption asnAlgorithmIdentifier |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	aes128CTRinECIES = asnSymmetricEncryption{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{21, 0}), |  | ||||||
| 	} |  | ||||||
| 	aes192CTRinECIES = asnSymmetricEncryption{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{21, 1}), |  | ||||||
| 	} |  | ||||||
| 	aes256CTRinECIES = asnSymmetricEncryption{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{21, 2}), |  | ||||||
| 	} |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func (a asnSymmetricEncryption) Cmp(b asnSymmetricEncryption) bool { |  | ||||||
| 	if len(a.Algorithm) != len(b.Algorithm) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, _ := range a.Algorithm { |  | ||||||
| 		if a.Algorithm[i] != b.Algorithm[i] { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type asnMessageAuthenticationCode asnAlgorithmIdentifier |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	hmacFull = asnMessageAuthenticationCode{ |  | ||||||
| 		Algorithm: doScheme(secgScheme, []int{22}), |  | ||||||
| 	} |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func (a asnMessageAuthenticationCode) Cmp(b asnMessageAuthenticationCode) bool { |  | ||||||
| 	if len(a.Algorithm) != len(b.Algorithm) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, _ := range a.Algorithm { |  | ||||||
| 		if a.Algorithm[i] != b.Algorithm[i] { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type ecpksSupplements struct { |  | ||||||
| 	ECDomain      secgNamedCurve |  | ||||||
| 	ECCAlgorithms eccAlgorithmSet |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type eccAlgorithmSet struct { |  | ||||||
| 	ECDH  asnECDHAlgorithm   `asn1:"optional"` |  | ||||||
| 	ECIES asnECIESParameters `asn1:"optional"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func marshalSubjectPublicKeyInfo(pub *PublicKey) (subj asnSubjectPublicKeyInfo, err error) { |  | ||||||
| 	subj.Algorithm = idEcPublicKeySupplemented |  | ||||||
| 	curve, ok := oidFromNamedCurve(pub.Curve) |  | ||||||
| 	if !ok { |  | ||||||
| 		err = ErrInvalidPublicKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	subj.Supplements.ECDomain = curve |  | ||||||
| 	if pub.Params != nil { |  | ||||||
| 		subj.Supplements.ECCAlgorithms.ECDH = paramsToASNECDH(pub.Params) |  | ||||||
| 		subj.Supplements.ECCAlgorithms.ECIES = paramsToASNECIES(pub.Params) |  | ||||||
| 	} |  | ||||||
| 	pubkey := elliptic.Marshal(pub.Curve, pub.X, pub.Y) |  | ||||||
| 	subj.PublicKey = asn1.BitString{ |  | ||||||
| 		BitLength: len(pubkey) * 8, |  | ||||||
| 		Bytes:     pubkey, |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Encode a public key to DER format.
 |  | ||||||
| func MarshalPublic(pub *PublicKey) ([]byte, error) { |  | ||||||
| 	subj, err := marshalSubjectPublicKeyInfo(pub) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return asn1.Marshal(subj) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Decode a DER-encoded public key.
 |  | ||||||
| func UnmarshalPublic(in []byte) (pub *PublicKey, err error) { |  | ||||||
| 	var subj asnSubjectPublicKeyInfo |  | ||||||
| 
 |  | ||||||
| 	if _, err = asn1.Unmarshal(in, &subj); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if !subj.Algorithm.Equal(idEcPublicKeySupplemented) { |  | ||||||
| 		err = ErrInvalidPublicKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	pub = new(PublicKey) |  | ||||||
| 	pub.Curve = namedCurveFromOID(subj.Supplements.ECDomain) |  | ||||||
| 	x, y := elliptic.Unmarshal(pub.Curve, subj.PublicKey.Bytes) |  | ||||||
| 	if x == nil { |  | ||||||
| 		err = ErrInvalidPublicKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	pub.X = x |  | ||||||
| 	pub.Y = y |  | ||||||
| 	pub.Params = new(ECIESParams) |  | ||||||
| 	asnECIEStoParams(subj.Supplements.ECCAlgorithms.ECIES, pub.Params) |  | ||||||
| 	asnECDHtoParams(subj.Supplements.ECCAlgorithms.ECDH, pub.Params) |  | ||||||
| 	if pub.Params == nil { |  | ||||||
| 		if pub.Params = ParamsFromCurve(pub.Curve); pub.Params == nil { |  | ||||||
| 			err = ErrInvalidPublicKey |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func marshalPrivateKey(prv *PrivateKey) (ecprv asnPrivateKey, err error) { |  | ||||||
| 	ecprv.Version = asnECPrivKeyVer1 |  | ||||||
| 	ecprv.Private = prv.D.Bytes() |  | ||||||
| 
 |  | ||||||
| 	var ok bool |  | ||||||
| 	ecprv.Curve, ok = oidFromNamedCurve(prv.PublicKey.Curve) |  | ||||||
| 	if !ok { |  | ||||||
| 		err = ErrInvalidPrivateKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var pub []byte |  | ||||||
| 	if pub, err = MarshalPublic(&prv.PublicKey); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} else { |  | ||||||
| 		ecprv.Public = asn1.BitString{ |  | ||||||
| 			BitLength: len(pub) * 8, |  | ||||||
| 			Bytes:     pub, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Encode a private key to DER format.
 |  | ||||||
| func MarshalPrivate(prv *PrivateKey) ([]byte, error) { |  | ||||||
| 	ecprv, err := marshalPrivateKey(prv) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return asn1.Marshal(ecprv) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Decode a private key from a DER-encoded format.
 |  | ||||||
| func UnmarshalPrivate(in []byte) (prv *PrivateKey, err error) { |  | ||||||
| 	var ecprv asnPrivateKey |  | ||||||
| 
 |  | ||||||
| 	if _, err = asn1.Unmarshal(in, &ecprv); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} else if ecprv.Version != asnECPrivKeyVer1 { |  | ||||||
| 		err = ErrInvalidPrivateKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	privateCurve := namedCurveFromOID(ecprv.Curve) |  | ||||||
| 	if privateCurve == nil { |  | ||||||
| 		err = ErrInvalidPrivateKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv = new(PrivateKey) |  | ||||||
| 	prv.D = new(big.Int).SetBytes(ecprv.Private) |  | ||||||
| 
 |  | ||||||
| 	if pub, err := UnmarshalPublic(ecprv.Public.Bytes); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} else { |  | ||||||
| 		prv.PublicKey = *pub |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Export a public key to PEM format.
 |  | ||||||
| func ExportPublicPEM(pub *PublicKey) (out []byte, err error) { |  | ||||||
| 	der, err := MarshalPublic(pub) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var block pem.Block |  | ||||||
| 	block.Type = "ELLIPTIC CURVE PUBLIC KEY" |  | ||||||
| 	block.Bytes = der |  | ||||||
| 
 |  | ||||||
| 	buf := new(bytes.Buffer) |  | ||||||
| 	err = pem.Encode(buf, &block) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} else { |  | ||||||
| 		out = buf.Bytes() |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Export a private key to PEM format.
 |  | ||||||
| func ExportPrivatePEM(prv *PrivateKey) (out []byte, err error) { |  | ||||||
| 	der, err := MarshalPrivate(prv) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var block pem.Block |  | ||||||
| 	block.Type = "ELLIPTIC CURVE PRIVATE KEY" |  | ||||||
| 	block.Bytes = der |  | ||||||
| 
 |  | ||||||
| 	buf := new(bytes.Buffer) |  | ||||||
| 	err = pem.Encode(buf, &block) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} else { |  | ||||||
| 		out = buf.Bytes() |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Import a PEM-encoded public key.
 |  | ||||||
| func ImportPublicPEM(in []byte) (pub *PublicKey, err error) { |  | ||||||
| 	p, _ := pem.Decode(in) |  | ||||||
| 	if p == nil || p.Type != "ELLIPTIC CURVE PUBLIC KEY" { |  | ||||||
| 		return nil, ErrInvalidPublicKey |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pub, err = UnmarshalPublic(p.Bytes) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Import a PEM-encoded private key.
 |  | ||||||
| func ImportPrivatePEM(in []byte) (prv *PrivateKey, err error) { |  | ||||||
| 	p, _ := pem.Decode(in) |  | ||||||
| 	if p == nil || p.Type != "ELLIPTIC CURVE PRIVATE KEY" { |  | ||||||
| 		return nil, ErrInvalidPrivateKey |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv, err = UnmarshalPrivate(p.Bytes) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
							
								
								
									
										326
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/ecies.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										326
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/ecies.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,326 +0,0 @@ | |||||||
| package ecies |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto/cipher" |  | ||||||
| 	"crypto/ecdsa" |  | ||||||
| 	"crypto/elliptic" |  | ||||||
| 	"crypto/hmac" |  | ||||||
| 	"crypto/subtle" |  | ||||||
| 	"fmt" |  | ||||||
| 	"hash" |  | ||||||
| 	"io" |  | ||||||
| 	"math/big" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	ErrImport           = fmt.Errorf("ecies: failed to import key") |  | ||||||
| 	ErrInvalidCurve     = fmt.Errorf("ecies: invalid elliptic curve") |  | ||||||
| 	ErrInvalidParams    = fmt.Errorf("ecies: invalid ECIES parameters") |  | ||||||
| 	ErrInvalidPublicKey = fmt.Errorf("ecies: invalid public key") |  | ||||||
| 	ErrSharedKeyTooBig  = fmt.Errorf("ecies: shared key is too big") |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // PublicKey is a representation of an elliptic curve public key.
 |  | ||||||
| type PublicKey struct { |  | ||||||
| 	X *big.Int |  | ||||||
| 	Y *big.Int |  | ||||||
| 	elliptic.Curve |  | ||||||
| 	Params *ECIESParams |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Export an ECIES public key as an ECDSA public key.
 |  | ||||||
| func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey { |  | ||||||
| 	return &ecdsa.PublicKey{pub.Curve, pub.X, pub.Y} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Import an ECDSA public key as an ECIES public key.
 |  | ||||||
| func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey { |  | ||||||
| 	return &PublicKey{ |  | ||||||
| 		X:      pub.X, |  | ||||||
| 		Y:      pub.Y, |  | ||||||
| 		Curve:  pub.Curve, |  | ||||||
| 		Params: ParamsFromCurve(pub.Curve), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // PrivateKey is a representation of an elliptic curve private key.
 |  | ||||||
| type PrivateKey struct { |  | ||||||
| 	PublicKey |  | ||||||
| 	D *big.Int |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Export an ECIES private key as an ECDSA private key.
 |  | ||||||
| func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey { |  | ||||||
| 	pub := &prv.PublicKey |  | ||||||
| 	pubECDSA := pub.ExportECDSA() |  | ||||||
| 	return &ecdsa.PrivateKey{*pubECDSA, prv.D} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Import an ECDSA private key as an ECIES private key.
 |  | ||||||
| func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey { |  | ||||||
| 	pub := ImportECDSAPublic(&prv.PublicKey) |  | ||||||
| 	return &PrivateKey{*pub, prv.D} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Generate an elliptic curve public / private keypair. If params is nil,
 |  | ||||||
| // the recommended default paramters for the key will be chosen.
 |  | ||||||
| func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) { |  | ||||||
| 	pb, x, y, err := elliptic.GenerateKey(curve, rand) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	prv = new(PrivateKey) |  | ||||||
| 	prv.PublicKey.X = x |  | ||||||
| 	prv.PublicKey.Y = y |  | ||||||
| 	prv.PublicKey.Curve = curve |  | ||||||
| 	prv.D = new(big.Int).SetBytes(pb) |  | ||||||
| 	if params == nil { |  | ||||||
| 		params = ParamsFromCurve(curve) |  | ||||||
| 	} |  | ||||||
| 	prv.PublicKey.Params = params |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // MaxSharedKeyLength returns the maximum length of the shared key the
 |  | ||||||
| // public key can produce.
 |  | ||||||
| func MaxSharedKeyLength(pub *PublicKey) int { |  | ||||||
| 	return (pub.Curve.Params().BitSize + 7) / 8 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ECDH key agreement method used to establish secret keys for encryption.
 |  | ||||||
| func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) { |  | ||||||
| 	if prv.PublicKey.Curve != pub.Curve { |  | ||||||
| 		err = ErrInvalidCurve |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, prv.D.Bytes()) |  | ||||||
| 	if x == nil || (x.BitLen()+7)/8 < (skLen+macLen) { |  | ||||||
| 		err = ErrSharedKeyTooBig |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	sk = x.Bytes()[:skLen+macLen] |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data") |  | ||||||
| 	ErrSharedTooLong  = fmt.Errorf("ecies: shared secret is too long") |  | ||||||
| 	ErrInvalidMessage = fmt.Errorf("ecies: invalid message") |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	big2To32   = new(big.Int).Exp(big.NewInt(2), big.NewInt(32), nil) |  | ||||||
| 	big2To32M1 = new(big.Int).Sub(big2To32, big.NewInt(1)) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func incCounter(ctr []byte) { |  | ||||||
| 	if ctr[3]++; ctr[3] != 0 { |  | ||||||
| 		return |  | ||||||
| 	} else if ctr[2]++; ctr[2] != 0 { |  | ||||||
| 		return |  | ||||||
| 	} else if ctr[1]++; ctr[1] != 0 { |  | ||||||
| 		return |  | ||||||
| 	} else if ctr[0]++; ctr[0] != 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
 |  | ||||||
| func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) { |  | ||||||
| 	if s1 == nil { |  | ||||||
| 		s1 = make([]byte, 0) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	reps := ((kdLen + 7) * 8) / (hash.BlockSize() * 8) |  | ||||||
| 	if big.NewInt(int64(reps)).Cmp(big2To32M1) > 0 { |  | ||||||
| 		fmt.Println(big2To32M1) |  | ||||||
| 		return nil, ErrKeyDataTooLong |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	counter := []byte{0, 0, 0, 1} |  | ||||||
| 	k = make([]byte, 0) |  | ||||||
| 
 |  | ||||||
| 	for i := 0; i <= reps; i++ { |  | ||||||
| 		hash.Write(counter) |  | ||||||
| 		hash.Write(z) |  | ||||||
| 		hash.Write(s1) |  | ||||||
| 		k = append(k, hash.Sum(nil)...) |  | ||||||
| 		hash.Reset() |  | ||||||
| 		incCounter(counter) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	k = k[:kdLen] |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // messageTag computes the MAC of a message (called the tag) as per
 |  | ||||||
| // SEC 1, 3.5.
 |  | ||||||
| func messageTag(hash func() hash.Hash, km, msg, shared []byte) []byte { |  | ||||||
| 	if shared == nil { |  | ||||||
| 		shared = make([]byte, 0) |  | ||||||
| 	} |  | ||||||
| 	mac := hmac.New(hash, km) |  | ||||||
| 	mac.Write(msg) |  | ||||||
| 	tag := mac.Sum(nil) |  | ||||||
| 	return tag |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Generate an initialisation vector for CTR mode.
 |  | ||||||
| func generateIV(params *ECIESParams, rand io.Reader) (iv []byte, err error) { |  | ||||||
| 	iv = make([]byte, params.BlockSize) |  | ||||||
| 	_, err = io.ReadFull(rand, iv) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // symEncrypt carries out CTR encryption using the block cipher specified in the
 |  | ||||||
| // parameters.
 |  | ||||||
| func symEncrypt(rand io.Reader, params *ECIESParams, key, m []byte) (ct []byte, err error) { |  | ||||||
| 	c, err := params.Cipher(key) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	iv, err := generateIV(params, rand) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	ctr := cipher.NewCTR(c, iv) |  | ||||||
| 
 |  | ||||||
| 	ct = make([]byte, len(m)+params.BlockSize) |  | ||||||
| 	copy(ct, iv) |  | ||||||
| 	ctr.XORKeyStream(ct[params.BlockSize:], m) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // symDecrypt carries out CTR decryption using the block cipher specified in
 |  | ||||||
| // the parameters
 |  | ||||||
| func symDecrypt(rand io.Reader, params *ECIESParams, key, ct []byte) (m []byte, err error) { |  | ||||||
| 	c, err := params.Cipher(key) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ctr := cipher.NewCTR(c, ct[:params.BlockSize]) |  | ||||||
| 
 |  | ||||||
| 	m = make([]byte, len(ct)-params.BlockSize) |  | ||||||
| 	ctr.XORKeyStream(m, ct[params.BlockSize:]) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Encrypt encrypts a message using ECIES as specified in SEC 1, 5.1. If
 |  | ||||||
| // the shared information parameters aren't being used, they should be
 |  | ||||||
| // nil.
 |  | ||||||
| func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err error) { |  | ||||||
| 	params := pub.Params |  | ||||||
| 	if params == nil { |  | ||||||
| 		if params = ParamsFromCurve(pub.Curve); params == nil { |  | ||||||
| 			err = ErrUnsupportedECIESParameters |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	R, err := GenerateKey(rand, pub.Curve, params) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	hash := params.Hash() |  | ||||||
| 	z, err := R.GenerateShared(pub, params.KeyLen, params.KeyLen) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	Ke := K[:params.KeyLen] |  | ||||||
| 	Km := K[params.KeyLen:] |  | ||||||
| 	hash.Write(Km) |  | ||||||
| 	Km = hash.Sum(nil) |  | ||||||
| 	hash.Reset() |  | ||||||
| 
 |  | ||||||
| 	em, err := symEncrypt(rand, params, Ke, m) |  | ||||||
| 	if err != nil || len(em) <= params.BlockSize { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	d := messageTag(params.Hash, Km, em, s2) |  | ||||||
| 
 |  | ||||||
| 	Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y) |  | ||||||
| 	ct = make([]byte, len(Rb)+len(em)+len(d)) |  | ||||||
| 	copy(ct, Rb) |  | ||||||
| 	copy(ct[len(Rb):], em) |  | ||||||
| 	copy(ct[len(Rb)+len(em):], d) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Decrypt decrypts an ECIES ciphertext.
 |  | ||||||
| func (prv *PrivateKey) Decrypt(rand io.Reader, c, s1, s2 []byte) (m []byte, err error) { |  | ||||||
| 	if c == nil || len(c) == 0 { |  | ||||||
| 		err = ErrInvalidMessage |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	params := prv.PublicKey.Params |  | ||||||
| 	if params == nil { |  | ||||||
| 		if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil { |  | ||||||
| 			err = ErrUnsupportedECIESParameters |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	hash := params.Hash() |  | ||||||
| 
 |  | ||||||
| 	var ( |  | ||||||
| 		rLen   int |  | ||||||
| 		hLen   int = hash.Size() |  | ||||||
| 		mStart int |  | ||||||
| 		mEnd   int |  | ||||||
| 	) |  | ||||||
| 
 |  | ||||||
| 	switch c[0] { |  | ||||||
| 	case 2, 3, 4: |  | ||||||
| 		rLen = ((prv.PublicKey.Curve.Params().BitSize + 7) / 4) |  | ||||||
| 		if len(c) < (rLen + hLen + 1) { |  | ||||||
| 			err = ErrInvalidMessage |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	default: |  | ||||||
| 		err = ErrInvalidPublicKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	mStart = rLen |  | ||||||
| 	mEnd = len(c) - hLen |  | ||||||
| 
 |  | ||||||
| 	R := new(PublicKey) |  | ||||||
| 	R.Curve = prv.PublicKey.Curve |  | ||||||
| 	R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen]) |  | ||||||
| 	if R.X == nil { |  | ||||||
| 		err = ErrInvalidPublicKey |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Ke := K[:params.KeyLen] |  | ||||||
| 	Km := K[params.KeyLen:] |  | ||||||
| 	hash.Write(Km) |  | ||||||
| 	Km = hash.Sum(nil) |  | ||||||
| 	hash.Reset() |  | ||||||
| 
 |  | ||||||
| 	d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) |  | ||||||
| 	if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { |  | ||||||
| 		err = ErrInvalidMessage |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	m, err = symDecrypt(rand, params, Ke, c[mStart:mEnd]) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
							
								
								
									
										489
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/ecies_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										489
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/ecies_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,489 +0,0 @@ | |||||||
| package ecies |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"crypto/elliptic" |  | ||||||
| 	"crypto/rand" |  | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"flag" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"testing" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var dumpEnc bool |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| 	flDump := flag.Bool("dump", false, "write encrypted test message to file") |  | ||||||
| 	flag.Parse() |  | ||||||
| 	dumpEnc = *flDump |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Ensure the KDF generates appropriately sized keys.
 |  | ||||||
| func TestKDF(t *testing.T) { |  | ||||||
| 	msg := []byte("Hello, world") |  | ||||||
| 	h := sha256.New() |  | ||||||
| 
 |  | ||||||
| 	k, err := concatKDF(h, msg, nil, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 	if len(k) != 64 { |  | ||||||
| 		fmt.Printf("KDF: generated key is the wrong size (%d instead of 64\n", |  | ||||||
| 			len(k)) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var skLen int |  | ||||||
| var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match") |  | ||||||
| 
 |  | ||||||
| // cmpParams compares a set of ECIES parameters. We assume, as per the
 |  | ||||||
| // docs, that AES is the only supported symmetric encryption algorithm.
 |  | ||||||
| func cmpParams(p1, p2 *ECIESParams) bool { |  | ||||||
| 	if p1.hashAlgo != p2.hashAlgo { |  | ||||||
| 		return false |  | ||||||
| 	} else if p1.KeyLen != p2.KeyLen { |  | ||||||
| 		return false |  | ||||||
| 	} else if p1.BlockSize != p2.BlockSize { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // cmpPublic returns true if the two public keys represent the same pojnt.
 |  | ||||||
| func cmpPublic(pub1, pub2 PublicKey) bool { |  | ||||||
| 	if pub1.X == nil || pub1.Y == nil { |  | ||||||
| 		fmt.Println(ErrInvalidPublicKey.Error()) |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if pub2.X == nil || pub2.Y == nil { |  | ||||||
| 		fmt.Println(ErrInvalidPublicKey.Error()) |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	pub1Out := elliptic.Marshal(pub1.Curve, pub1.X, pub1.Y) |  | ||||||
| 	pub2Out := elliptic.Marshal(pub2.Curve, pub2.X, pub2.Y) |  | ||||||
| 
 |  | ||||||
| 	return bytes.Equal(pub1Out, pub2Out) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // cmpPrivate returns true if the two private keys are the same.
 |  | ||||||
| func cmpPrivate(prv1, prv2 *PrivateKey) bool { |  | ||||||
| 	if prv1 == nil || prv1.D == nil { |  | ||||||
| 		return false |  | ||||||
| 	} else if prv2 == nil || prv2.D == nil { |  | ||||||
| 		return false |  | ||||||
| 	} else if prv1.D.Cmp(prv2.D) != 0 { |  | ||||||
| 		return false |  | ||||||
| 	} else { |  | ||||||
| 		return cmpPublic(prv1.PublicKey, prv2.PublicKey) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Validate the ECDH component.
 |  | ||||||
| func TestSharedKey(t *testing.T) { |  | ||||||
| 	prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 	skLen = MaxSharedKeyLength(&prv1.PublicKey) / 2 |  | ||||||
| 
 |  | ||||||
| 	prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !bytes.Equal(sk1, sk2) { |  | ||||||
| 		fmt.Println(ErrBadSharedKeys.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Verify that the key generation code fails when too much key data is
 |  | ||||||
| // requested.
 |  | ||||||
| func TestTooBigSharedKey(t *testing.T) { |  | ||||||
| 	prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, err = prv1.GenerateShared(&prv2.PublicKey, skLen*2, skLen*2) |  | ||||||
| 	if err != ErrSharedKeyTooBig { |  | ||||||
| 		fmt.Println("ecdh: shared key should be too large for curve") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, err = prv2.GenerateShared(&prv1.PublicKey, skLen*2, skLen*2) |  | ||||||
| 	if err != ErrSharedKeyTooBig { |  | ||||||
| 		fmt.Println("ecdh: shared key should be too large for curve") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Ensure a public key can be successfully marshalled and unmarshalled, and
 |  | ||||||
| // that the decoded key is the same as the original.
 |  | ||||||
| func TestMarshalPublic(t *testing.T) { |  | ||||||
| 	prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	out, err := MarshalPublic(&prv.PublicKey) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pub, err := UnmarshalPublic(out) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !cmpPublic(prv.PublicKey, *pub) { |  | ||||||
| 		fmt.Println("ecies: failed to unmarshal public key") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Ensure that a private key can be encoded into DER format, and that
 |  | ||||||
| // the resulting key is properly parsed back into a public key.
 |  | ||||||
| func TestMarshalPrivate(t *testing.T) { |  | ||||||
| 	prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	out, err := MarshalPrivate(prv) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if dumpEnc { |  | ||||||
| 		ioutil.WriteFile("test.out", out, 0644) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv2, err := UnmarshalPrivate(out) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !cmpPrivate(prv, prv2) { |  | ||||||
| 		fmt.Println("ecdh: private key import failed") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Ensure that a private key can be successfully encoded to PEM format, and
 |  | ||||||
| // the resulting key is properly parsed back in.
 |  | ||||||
| func TestPrivatePEM(t *testing.T) { |  | ||||||
| 	prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	out, err := ExportPrivatePEM(prv) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if dumpEnc { |  | ||||||
| 		ioutil.WriteFile("test.key", out, 0644) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv2, err := ImportPrivatePEM(out) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} else if !cmpPrivate(prv, prv2) { |  | ||||||
| 		fmt.Println("ecdh: import from PEM failed") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Ensure that a public key can be successfully encoded to PEM format, and
 |  | ||||||
| // the resulting key is properly parsed back in.
 |  | ||||||
| func TestPublicPEM(t *testing.T) { |  | ||||||
| 	prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	out, err := ExportPublicPEM(&prv.PublicKey) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if dumpEnc { |  | ||||||
| 		ioutil.WriteFile("test.pem", out, 0644) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pub2, err := ImportPublicPEM(out) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} else if !cmpPublic(prv.PublicKey, *pub2) { |  | ||||||
| 		fmt.Println("ecdh: import from PEM failed") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Benchmark the generation of P256 keys.
 |  | ||||||
| func BenchmarkGenerateKeyP256(b *testing.B) { |  | ||||||
| 	for i := 0; i < b.N; i++ { |  | ||||||
| 		if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil { |  | ||||||
| 			fmt.Println(err.Error()) |  | ||||||
| 			b.FailNow() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Benchmark the generation of P256 shared keys.
 |  | ||||||
| func BenchmarkGenSharedKeyP256(b *testing.B) { |  | ||||||
| 	prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		b.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for i := 0; i < b.N; i++ { |  | ||||||
| 		_, err := prv.GenerateShared(&prv.PublicKey, skLen, skLen) |  | ||||||
| 		if err != nil { |  | ||||||
| 			fmt.Println(err.Error()) |  | ||||||
| 			b.FailNow() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Verify that an encrypted message can be successfully decrypted.
 |  | ||||||
| func TestEncryptDecrypt(t *testing.T) { |  | ||||||
| 	prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	message := []byte("Hello, world.") |  | ||||||
| 	ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !bytes.Equal(pt, message) { |  | ||||||
| 		fmt.Println("ecies: plaintext doesn't match message") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, err = prv1.Decrypt(rand.Reader, ct, nil, nil) |  | ||||||
| 	if err == nil { |  | ||||||
| 		fmt.Println("ecies: encryption should not have succeeded") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TestMarshalEncryption validates the encode/decode produces a valid
 |  | ||||||
| // ECIES encryption key.
 |  | ||||||
| func TestMarshalEncryption(t *testing.T) { |  | ||||||
| 	prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	out, err := MarshalPrivate(prv1) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv2, err := UnmarshalPrivate(out) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	message := []byte("Hello, world.") |  | ||||||
| 	ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !bytes.Equal(pt, message) { |  | ||||||
| 		fmt.Println("ecies: plaintext doesn't match message") |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, err = prv1.Decrypt(rand.Reader, ct, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type testCase struct { |  | ||||||
| 	Curve    elliptic.Curve |  | ||||||
| 	Name     string |  | ||||||
| 	Expected bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var testCases = []testCase{ |  | ||||||
| 	testCase{ |  | ||||||
| 		Curve:    elliptic.P224(), |  | ||||||
| 		Name:     "P224", |  | ||||||
| 		Expected: false, |  | ||||||
| 	}, |  | ||||||
| 	testCase{ |  | ||||||
| 		Curve:    elliptic.P256(), |  | ||||||
| 		Name:     "P256", |  | ||||||
| 		Expected: true, |  | ||||||
| 	}, |  | ||||||
| 	testCase{ |  | ||||||
| 		Curve:    elliptic.P384(), |  | ||||||
| 		Name:     "P384", |  | ||||||
| 		Expected: true, |  | ||||||
| 	}, |  | ||||||
| 	testCase{ |  | ||||||
| 		Curve:    elliptic.P521(), |  | ||||||
| 		Name:     "P521", |  | ||||||
| 		Expected: true, |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Test parameter selection for each curve, and that P224 fails automatic
 |  | ||||||
| // parameter selection (see README for a discussion of P224). Ensures that
 |  | ||||||
| // selecting a set of parameters automatically for the given curve works.
 |  | ||||||
| func TestParamSelection(t *testing.T) { |  | ||||||
| 	for _, c := range testCases { |  | ||||||
| 		testParamSelection(t, c) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func testParamSelection(t *testing.T, c testCase) { |  | ||||||
| 	params := ParamsFromCurve(c.Curve) |  | ||||||
| 	if params == nil && c.Expected { |  | ||||||
| 		fmt.Printf("%s (%s)\n", ErrInvalidParams.Error(), c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} else if params != nil && !c.Expected { |  | ||||||
| 		fmt.Printf("ecies: parameters should be invalid (%s)\n", |  | ||||||
| 			c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("%s (%s)\n", err.Error(), c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("%s (%s)\n", err.Error(), c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	message := []byte("Hello, world.") |  | ||||||
| 	ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("%s (%s)\n", err.Error(), c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("%s (%s)\n", err.Error(), c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !bytes.Equal(pt, message) { |  | ||||||
| 		fmt.Printf("ecies: plaintext doesn't match message (%s)\n", |  | ||||||
| 			c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, err = prv1.Decrypt(rand.Reader, ct, nil, nil) |  | ||||||
| 	if err == nil { |  | ||||||
| 		fmt.Printf("ecies: encryption should not have succeeded (%s)\n", |  | ||||||
| 			c.Name) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Ensure that the basic public key validation in the decryption operation
 |  | ||||||
| // works.
 |  | ||||||
| func TestBasicKeyValidation(t *testing.T) { |  | ||||||
| 	badBytes := []byte{0, 1, 5, 6, 7, 8, 9} |  | ||||||
| 
 |  | ||||||
| 	prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	message := []byte("Hello, world.") |  | ||||||
| 	ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		t.FailNow() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for _, b := range badBytes { |  | ||||||
| 		ct[0] = b |  | ||||||
| 		_, err := prv.Decrypt(rand.Reader, ct, nil, nil) |  | ||||||
| 		if err != ErrInvalidPublicKey { |  | ||||||
| 			fmt.Println("ecies: validated an invalid key") |  | ||||||
| 			t.FailNow() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										187
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/params.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										187
									
								
								Godeps/_workspace/src/github.com/obscuren/ecies/params.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,187 +0,0 @@ | |||||||
| package ecies |  | ||||||
| 
 |  | ||||||
| // This file contains parameters for ECIES encryption, specifying the
 |  | ||||||
| // symmetric encryption and HMAC parameters.
 |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto" |  | ||||||
| 	"crypto/aes" |  | ||||||
| 	"crypto/cipher" |  | ||||||
| 	"crypto/elliptic" |  | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"crypto/sha512" |  | ||||||
| 	"fmt" |  | ||||||
| 	"hash" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // The default curve for this package is the NIST P256 curve, which
 |  | ||||||
| // provides security equivalent to AES-128.
 |  | ||||||
| var DefaultCurve = elliptic.P256() |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	ErrUnsupportedECDHAlgorithm   = fmt.Errorf("ecies: unsupported ECDH algorithm") |  | ||||||
| 	ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters") |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type ECIESParams struct { |  | ||||||
| 	Hash      func() hash.Hash // hash function
 |  | ||||||
| 	hashAlgo  crypto.Hash |  | ||||||
| 	Cipher    func([]byte) (cipher.Block, error) // symmetric cipher
 |  | ||||||
| 	BlockSize int                                // block size of symmetric cipher
 |  | ||||||
| 	KeyLen    int                                // length of symmetric key
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Standard ECIES parameters:
 |  | ||||||
| // * ECIES using AES128 and HMAC-SHA-256-16
 |  | ||||||
| // * ECIES using AES256 and HMAC-SHA-256-32
 |  | ||||||
| // * ECIES using AES256 and HMAC-SHA-384-48
 |  | ||||||
| // * ECIES using AES256 and HMAC-SHA-512-64
 |  | ||||||
| var ( |  | ||||||
| 	ECIES_AES128_SHA256 *ECIESParams |  | ||||||
| 	ECIES_AES256_SHA256 *ECIESParams |  | ||||||
| 	ECIES_AES256_SHA384 *ECIESParams |  | ||||||
| 	ECIES_AES256_SHA512 *ECIESParams |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| 	ECIES_AES128_SHA256 = &ECIESParams{ |  | ||||||
| 		Hash:      sha256.New, |  | ||||||
| 		hashAlgo:  crypto.SHA256, |  | ||||||
| 		Cipher:    aes.NewCipher, |  | ||||||
| 		BlockSize: aes.BlockSize, |  | ||||||
| 		KeyLen:    16, |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ECIES_AES256_SHA256 = &ECIESParams{ |  | ||||||
| 		Hash:      sha256.New, |  | ||||||
| 		hashAlgo:  crypto.SHA256, |  | ||||||
| 		Cipher:    aes.NewCipher, |  | ||||||
| 		BlockSize: aes.BlockSize, |  | ||||||
| 		KeyLen:    32, |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ECIES_AES256_SHA384 = &ECIESParams{ |  | ||||||
| 		Hash:      sha512.New384, |  | ||||||
| 		hashAlgo:  crypto.SHA384, |  | ||||||
| 		Cipher:    aes.NewCipher, |  | ||||||
| 		BlockSize: aes.BlockSize, |  | ||||||
| 		KeyLen:    32, |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ECIES_AES256_SHA512 = &ECIESParams{ |  | ||||||
| 		Hash:      sha512.New, |  | ||||||
| 		hashAlgo:  crypto.SHA512, |  | ||||||
| 		Cipher:    aes.NewCipher, |  | ||||||
| 		BlockSize: aes.BlockSize, |  | ||||||
| 		KeyLen:    32, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var paramsFromCurve = map[elliptic.Curve]*ECIESParams{ |  | ||||||
| 	elliptic.P256(): ECIES_AES128_SHA256, |  | ||||||
| 	elliptic.P384(): ECIES_AES256_SHA384, |  | ||||||
| 	elliptic.P521(): ECIES_AES256_SHA512, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func AddParamsForCurve(curve elliptic.Curve, params *ECIESParams) { |  | ||||||
| 	paramsFromCurve[curve] = params |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ParamsFromCurve selects parameters optimal for the selected elliptic curve.
 |  | ||||||
| // Only the curves P256, P384, and P512 are supported.
 |  | ||||||
| func ParamsFromCurve(curve elliptic.Curve) (params *ECIESParams) { |  | ||||||
| 	return paramsFromCurve[curve] |  | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 		switch curve { |  | ||||||
| 		case elliptic.P256(): |  | ||||||
| 			return ECIES_AES128_SHA256 |  | ||||||
| 		case elliptic.P384(): |  | ||||||
| 			return ECIES_AES256_SHA384 |  | ||||||
| 		case elliptic.P521(): |  | ||||||
| 			return ECIES_AES256_SHA512 |  | ||||||
| 		default: |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 	*/ |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ASN.1 encode the ECIES parameters relevant to the encryption operations.
 |  | ||||||
| func paramsToASNECIES(params *ECIESParams) (asnParams asnECIESParameters) { |  | ||||||
| 	if nil == params { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	asnParams.KDF = asnNISTConcatenationKDF |  | ||||||
| 	asnParams.MAC = hmacFull |  | ||||||
| 	switch params.KeyLen { |  | ||||||
| 	case 16: |  | ||||||
| 		asnParams.Sym = aes128CTRinECIES |  | ||||||
| 	case 24: |  | ||||||
| 		asnParams.Sym = aes192CTRinECIES |  | ||||||
| 	case 32: |  | ||||||
| 		asnParams.Sym = aes256CTRinECIES |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ASN.1 encode the ECIES parameters relevant to ECDH.
 |  | ||||||
| func paramsToASNECDH(params *ECIESParams) (algo asnECDHAlgorithm) { |  | ||||||
| 	switch params.hashAlgo { |  | ||||||
| 	case crypto.SHA224: |  | ||||||
| 		algo = dhSinglePass_stdDH_sha224kdf |  | ||||||
| 	case crypto.SHA256: |  | ||||||
| 		algo = dhSinglePass_stdDH_sha256kdf |  | ||||||
| 	case crypto.SHA384: |  | ||||||
| 		algo = dhSinglePass_stdDH_sha384kdf |  | ||||||
| 	case crypto.SHA512: |  | ||||||
| 		algo = dhSinglePass_stdDH_sha512kdf |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ASN.1 decode the ECIES parameters relevant to the encryption stage.
 |  | ||||||
| func asnECIEStoParams(asnParams asnECIESParameters, params *ECIESParams) { |  | ||||||
| 	if !asnParams.KDF.Cmp(asnNISTConcatenationKDF) { |  | ||||||
| 		params = nil |  | ||||||
| 		return |  | ||||||
| 	} else if !asnParams.MAC.Cmp(hmacFull) { |  | ||||||
| 		params = nil |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	switch { |  | ||||||
| 	case asnParams.Sym.Cmp(aes128CTRinECIES): |  | ||||||
| 		params.KeyLen = 16 |  | ||||||
| 		params.BlockSize = 16 |  | ||||||
| 		params.Cipher = aes.NewCipher |  | ||||||
| 	case asnParams.Sym.Cmp(aes192CTRinECIES): |  | ||||||
| 		params.KeyLen = 24 |  | ||||||
| 		params.BlockSize = 16 |  | ||||||
| 		params.Cipher = aes.NewCipher |  | ||||||
| 	case asnParams.Sym.Cmp(aes256CTRinECIES): |  | ||||||
| 		params.KeyLen = 32 |  | ||||||
| 		params.BlockSize = 16 |  | ||||||
| 		params.Cipher = aes.NewCipher |  | ||||||
| 	default: |  | ||||||
| 		params = nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ASN.1 decode the ECIES parameters relevant to ECDH.
 |  | ||||||
| func asnECDHtoParams(asnParams asnECDHAlgorithm, params *ECIESParams) { |  | ||||||
| 	if asnParams.Cmp(dhSinglePass_stdDH_sha224kdf) { |  | ||||||
| 		params.hashAlgo = crypto.SHA224 |  | ||||||
| 		params.Hash = sha256.New224 |  | ||||||
| 	} else if asnParams.Cmp(dhSinglePass_stdDH_sha256kdf) { |  | ||||||
| 		params.hashAlgo = crypto.SHA256 |  | ||||||
| 		params.Hash = sha256.New |  | ||||||
| 	} else if asnParams.Cmp(dhSinglePass_stdDH_sha384kdf) { |  | ||||||
| 		params.hashAlgo = crypto.SHA384 |  | ||||||
| 		params.Hash = sha512.New384 |  | ||||||
| 	} else if asnParams.Cmp(dhSinglePass_stdDH_sha512kdf) { |  | ||||||
| 		params.hashAlgo = crypto.SHA512 |  | ||||||
| 		params.Hash = sha512.New |  | ||||||
| 	} else { |  | ||||||
| 		params = nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @ -64,6 +64,20 @@ func Dial(url_, protocol, origin string) (ws *Conn, err error) { | |||||||
| 	return DialConfig(config) | 	return DialConfig(config) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var portMap = map[string]string{ | ||||||
|  | 	"ws":  "80", | ||||||
|  | 	"wss": "443", | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func parseAuthority(location *url.URL) string { | ||||||
|  | 	if _, ok := portMap[location.Scheme]; ok { | ||||||
|  | 		if _, _, err := net.SplitHostPort(location.Host); err != nil { | ||||||
|  | 			return net.JoinHostPort(location.Host, portMap[location.Scheme]) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return location.Host | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // DialConfig opens a new client connection to a WebSocket with a config.
 | // DialConfig opens a new client connection to a WebSocket with a config.
 | ||||||
| func DialConfig(config *Config) (ws *Conn, err error) { | func DialConfig(config *Config) (ws *Conn, err error) { | ||||||
| 	var client net.Conn | 	var client net.Conn | ||||||
| @ -75,10 +89,10 @@ func DialConfig(config *Config) (ws *Conn, err error) { | |||||||
| 	} | 	} | ||||||
| 	switch config.Location.Scheme { | 	switch config.Location.Scheme { | ||||||
| 	case "ws": | 	case "ws": | ||||||
| 		client, err = net.Dial("tcp", config.Location.Host) | 		client, err = net.Dial("tcp", parseAuthority(config.Location)) | ||||||
| 
 | 
 | ||||||
| 	case "wss": | 	case "wss": | ||||||
| 		client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig) | 		client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig) | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		err = ErrBadScheme | 		err = ErrBadScheme | ||||||
| @ -8,7 +8,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go.net/websocket" | 	"golang.org/x/net/websocket" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // This example demonstrates a trivial client.
 | // This example demonstrates a trivial client.
 | ||||||
| @ -8,7 +8,7 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go.net/websocket" | 	"golang.org/x/net/websocket" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Echo the data received on the WebSocket.
 | // Echo the data received on the WebSocket.
 | ||||||
| @ -339,3 +339,76 @@ func TestSmallBuffer(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	conn.Close() | 	conn.Close() | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | var parseAuthorityTests = []struct { | ||||||
|  | 	in  *url.URL | ||||||
|  | 	out string | ||||||
|  | }{ | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "ws", | ||||||
|  | 			Host:   "www.google.com", | ||||||
|  | 		}, | ||||||
|  | 		"www.google.com:80", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "wss", | ||||||
|  | 			Host:   "www.google.com", | ||||||
|  | 		}, | ||||||
|  | 		"www.google.com:443", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "ws", | ||||||
|  | 			Host:   "www.google.com:80", | ||||||
|  | 		}, | ||||||
|  | 		"www.google.com:80", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "wss", | ||||||
|  | 			Host:   "www.google.com:443", | ||||||
|  | 		}, | ||||||
|  | 		"www.google.com:443", | ||||||
|  | 	}, | ||||||
|  | 	// some invalid ones for parseAuthority. parseAuthority doesn't
 | ||||||
|  | 	// concern itself with the scheme unless it actually knows about it
 | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "http", | ||||||
|  | 			Host:   "www.google.com", | ||||||
|  | 		}, | ||||||
|  | 		"www.google.com", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "http", | ||||||
|  | 			Host:   "www.google.com:80", | ||||||
|  | 		}, | ||||||
|  | 		"www.google.com:80", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "asdf", | ||||||
|  | 			Host:   "127.0.0.1", | ||||||
|  | 		}, | ||||||
|  | 		"127.0.0.1", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		&url.URL{ | ||||||
|  | 			Scheme: "asdf", | ||||||
|  | 			Host:   "www.google.com", | ||||||
|  | 		}, | ||||||
|  | 		"www.google.com", | ||||||
|  | 	}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestParseAuthority(t *testing.T) { | ||||||
|  | 	for _, tt := range parseAuthorityTests { | ||||||
|  | 		out := parseAuthority(tt.in) | ||||||
|  | 		if out != tt.out { | ||||||
|  | 			t.Errorf("got %v; want %v", out, tt.out) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -16,12 +16,12 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" | 	"code.google.com/p/go-uuid/uuid" | ||||||
| 	"code.google.com/p/go.crypto/pbkdf2" |  | ||||||
| 	"code.google.com/p/go.crypto/ripemd160" |  | ||||||
| 	"github.com/ethereum/go-ethereum/crypto/ecies" | 	"github.com/ethereum/go-ethereum/crypto/ecies" | ||||||
| 	"github.com/ethereum/go-ethereum/crypto/secp256k1" | 	"github.com/ethereum/go-ethereum/crypto/secp256k1" | ||||||
| 	"github.com/ethereum/go-ethereum/crypto/sha3" | 	"github.com/ethereum/go-ethereum/crypto/sha3" | ||||||
| 	"github.com/ethereum/go-ethereum/ethutil" | 	"github.com/ethereum/go-ethereum/ethutil" | ||||||
|  | 	"golang.org/x/crypto/pbkdf2" | ||||||
|  | 	"golang.org/x/crypto/ripemd160" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
|  | |||||||
| @ -20,6 +20,7 @@ | |||||||
|  * @date 2015 |  * @date 2015 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
| /* | /* | ||||||
| 
 | 
 | ||||||
| This key store behaves as KeyStorePlain with the difference that | This key store behaves as KeyStorePlain with the difference that | ||||||
| @ -64,17 +65,18 @@ package crypto | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"code.google.com/p/go-uuid/uuid" |  | ||||||
| 	"code.google.com/p/go.crypto/scrypt" |  | ||||||
| 	"crypto/aes" | 	"crypto/aes" | ||||||
| 	"crypto/cipher" | 	"crypto/cipher" | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"github.com/ethereum/go-ethereum/crypto/randentropy" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path" | 	"path" | ||||||
|  | 
 | ||||||
|  | 	"code.google.com/p/go-uuid/uuid" | ||||||
|  | 	"github.com/ethereum/go-ethereum/crypto/randentropy" | ||||||
|  | 	"golang.org/x/crypto/scrypt" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"github.com/ethereum/go-ethereum/crypto" | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
| 	"github.com/obscuren/ecies" | 	"github.com/ethereum/go-ethereum/crypto/ecies" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestPublicKeyEncoding(t *testing.T) { | func TestPublicKeyEncoding(t *testing.T) { | ||||||
|  | |||||||
| @ -7,9 +7,9 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fjl/goupnp" | 	"github.com/huin/goupnp" | ||||||
| 	"github.com/fjl/goupnp/dcps/internetgateway1" | 	"github.com/huin/goupnp/dcps/internetgateway1" | ||||||
| 	"github.com/fjl/goupnp/dcps/internetgateway2" | 	"github.com/huin/goupnp/dcps/internetgateway2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type upnp struct { | type upnp struct { | ||||||
|  | |||||||
| @ -21,10 +21,10 @@ import ( | |||||||
| 	"net" | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go.net/websocket" |  | ||||||
| 	"github.com/ethereum/go-ethereum/logger" | 	"github.com/ethereum/go-ethereum/logger" | ||||||
| 	"github.com/ethereum/go-ethereum/rpc" | 	"github.com/ethereum/go-ethereum/rpc" | ||||||
| 	"github.com/ethereum/go-ethereum/xeth" | 	"github.com/ethereum/go-ethereum/xeth" | ||||||
|  | 	"golang.org/x/net/websocket" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var wslogger = logger.NewLogger("RPC-WS") | var wslogger = logger.NewLogger("RPC-WS") | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user