Merge pull request #421 from justincormack/arm

Update jose2go to latest to fix #239
This commit is contained in:
Ying Li 2016-01-06 08:39:37 -08:00
commit f211b1826d
20 changed files with 245 additions and 3367 deletions

3
Godeps/Godeps.json generated
View File

@ -101,7 +101,8 @@
},
{
"ImportPath": "github.com/dvsekhvalnov/jose2go",
"Rev": "5307afb3bb6169b0f68cdf519a5964c843344441"
"Comment": "v1.2",
"Rev": "6387d3c1f5abd8443b223577d5a7e0f4e0e5731f"
},
{
"ImportPath": "github.com/go-sql-driver/mysql",

View File

@ -10,11 +10,14 @@ Extensively unit tested and cross tested (100+ tests) for compatibility with [jo
## Status
Used in production. GA ready. Current version is 1.1
Used in production. GA ready. Current version is 1.2
## Important
v1.2 breaks `jose.Decode` interface by returning 3 values instead of 2.
v1.2 deprecates `jose.Compress` method in favor of using configuration options to `jose.Encrypt`,
the method will be removed in next release.
###Migration to v1.2
Pre v1.2 decoding:
@ -28,6 +31,17 @@ Should be updated to v1.2:
payload, headers, err := jose.Decode(token,sharedKey)
```
Pre v1.2 compression:
```Go
token,err := jose.Compress(payload,jose.DIR,jose.A128GCM,jose.DEF, key)
```
Should be update to v1.2:
```Go
token, err := jose.Encrypt(payload, jose.DIR, jose.A128GCM, key, jose.Zip(jose.DEF))
```
## Supported JWA algorithms
@ -368,15 +382,15 @@ import (
func main() {
payload := `{"hello": "world"}`
payload := `{"hello": "world"}`
sharedKey :=[]byte{194,164,235,6,138,248,171,239,24,216,11,22,137,199,215,133}
sharedKey := []byte{194, 164, 235, 6, 138, 248, 171, 239, 24, 216, 11, 22, 137, 199, 215, 133}
token,err := jose.Compress(payload,jose.DIR,jose.A128GCM,jose.DEF, sharedKey)
token, err := jose.Encrypt(payload, jose.DIR, jose.A128GCM, sharedKey, jose.Zip(jose.DEF))
if(err==nil) {
if err == nil {
//go use token
fmt.Printf("\nDIR A128GCM DEFLATED= %v\n",token)
fmt.Printf("\nDIR A128GCM DEFLATED= %v\n", token)
}
}
```
@ -583,6 +597,64 @@ func main() {
}
```
### Adding extra headers
It's possible to pass additional headers while encoding token. **jose2go** provides convenience configuration helpers: `Header(name string, value interface{})` and `Headers(headers map[string]interface{})` that can be passed to `Sign(..)` and `Encrypt(..)` calls.
Note: **jose2go** do not allow to override `alg`, `enc` and `zip` headers.
Example of signing with extra headers:
```Go
token, err := jose.Sign(payload, jose.ES256, key,
jose.Header("keyid", "111-222-333"),
jose.Header("trans-id", "aaa-bbb"))
```
Encryption with extra headers:
```Go
token, err := jose.Encrypt(payload, jose.DIR, jose.A128GCM, sharedKey,
jose.Headers(map[string]interface{}{"keyid": "111-22-33", "cty": "text/plain"}))
```
### Two phase validation
In some cases validation (decoding) key can be unknown prior to examining token content. For instance one can use different keys per token issuer or rely on headers information to determine which key to use, do logging or other things.
**jose2go** allows to pass `func(headers map[string]interface{}, payload string) key interface{}` callback instead of key to `jose.Decode(..)`. Callback will be executed prior to decoding and integrity validation and will recieve parsed headers and payload as is (for encrypted tokens it will be cipher text). Callback should return key to be used for actual decoding process.
Example of decoding token with callback:
```Go
package main
import (
"crypto/rsa"
"fmt"
"github.com/dvsekhvalnov/jose2go"
"github.com/dvsekhvalnov/jose2go/keys/rsa"
"io/ioutil"
)
func main() {
token := "eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.NL_dfVpZkhNn4bZpCyMq5TmnXbT4yiyecuB6Kax_lV8Yq2dG8wLfea-T4UKnrjLOwxlbwLwuKzffWcnWv3LVAWfeBxhGTa0c4_0TX_wzLnsgLuU6s9M2GBkAIuSMHY6UTFumJlEeRBeiqZNrlqvmAzQ9ppJHfWWkW4stcgLCLMAZbTqvRSppC1SMxnvPXnZSWn_Fk_q3oGKWw6Nf0-j-aOhK0S0Lcr0PV69ZE4xBYM9PUS1MpMe2zF5J3Tqlc1VBcJ94fjDj1F7y8twmMT3H1PI9RozO-21R0SiXZ_a93fxhE_l_dj5drgOek7jUN9uBDjkXUwJPAyp9YPehrjyLdw"
payload, _, err := jose.Decode(token,
func(headers map[string]interface{}, payload string) interface{} {
//log something
fmt.Printf("\nHeaders before decoding: %v\n", headers)
fmt.Printf("\nPayload before decoding: %v\n", payload)
//lookup key based on keyid header as en example
//or lookup based on something from payload, e.g. 'iss' claim for instance
return FindKey(headers['keyid'])
})
if err == nil {
//go use token
fmt.Printf("\ndecoded payload = %v\n", payload)
}
}
```
### Dealing with keys
**jose2go** provides several helper methods to simplify loading & importing of elliptic and rsa keys. Import `jose2go/keys/rsa` or `jose2go/keys/ecc` respectively:
@ -733,6 +805,8 @@ Checkout `jose_test.go` for more examples.
##Changelog
### 1.2
- interface to access token headers after decoding
- interface to provide extra headers for token encoding
- two-phase validation support
### 1.1
- security and bug fixes

View File

@ -14,53 +14,53 @@ type ecbDecrypter ecb
// NewECBEncrypter creates BlockMode for AES encryption in ECB mode
func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
return &ecbEncrypter {b:b}
return &ecbEncrypter{b: b}
}
// NewECBDecrypter creates BlockMode for AES decryption in ECB mode
func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
return &ecbDecrypter {b:b}
return &ecbDecrypter{b: b}
}
func (x *ecbEncrypter) BlockSize() int { return x.b.BlockSize() }
func (x *ecbDecrypter) BlockSize() int { return x.b.BlockSize() }
func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
bs := x.BlockSize()
if len(src) % bs != 0 {
if len(src)%bs != 0 {
panic("ecbDecrypter.CryptBlocks(): input not full blocks")
}
if len(dst) < len(src) {
panic("ecbDecrypter.CryptBlocks(): output smaller than input")
panic("ecbDecrypter.CryptBlocks(): output smaller than input")
}
if len(src) == 0 {
return
}
for len(src) > 0 {
x.b.Decrypt(dst, src)
src = src[bs:]
}
}
}
func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
bs := x.BlockSize()
if len(src) % bs != 0 {
if len(src)%bs != 0 {
panic("ecbEncrypter.CryptBlocks(): input not full blocks")
}
if len(dst) < len(src) {
panic("ecbEncrypter.CryptBlocks(): output smaller than input")
panic("ecbEncrypter.CryptBlocks(): output smaller than input")
}
if len(src) == 0 {
return
}
for len(src) > 0 {
x.b.Encrypt(dst, src)
src = src[bs:]

View File

@ -1,38 +0,0 @@
package aes
import (
// "fmt"
"crypto/aes"
// "crypto/cipher"
. "gopkg.in/check.v1"
)
func (s *TestSuite) TestNewECBEncryptor(c *C) {
//given
plaintext := []byte{0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}
kek := []byte{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
block, _ := aes.NewCipher(kek)
test := make([]byte,len(plaintext))
//when
NewECBEncrypter(block).CryptBlocks(test,plaintext)
//then
c.Assert(test, DeepEquals, []byte{105,196,224,216,106,123,4,48,216,205,183,128,112,180,197,90})
}
func (s *TestSuite) TestNewECBDecryptor(c *C) {
//given
ciphertext := []byte{105,196,224,216,106,123,4,48,216,205,183,128,112,180,197,90}
kek := []byte{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
block, _ := aes.NewCipher(kek)
test := make([]byte,len(ciphertext))
//when
NewECBDecrypter(block).CryptBlocks(test,ciphertext)
//then
c.Assert(test, DeepEquals, []byte{0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255})
}

View File

@ -1,240 +0,0 @@
package aes
import (
"testing"
// "fmt"
. "gopkg.in/check.v1"
// "github.com/dvsekhvalnov/jose2go/arrays"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
func (s *TestSuite) TestWrap_128Key_128Kek(c *C) {
//given (Section 4.1)
//000102030405060708090A0B0C0D0E0F
kek := []byte{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
//00112233445566778899AABBCCDDEEFF
key := []byte{0,17,34,51,68,85,102,119,136,153,170,187,204,221,238,255}
//1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5
expected := []byte{ 31, 166, 139, 10, 129, 18, 180, 71, 174, 243, 75, 216, 251, 90, 123, 130, 157, 62, 134,35, 113, 210, 207, 229}
//when
test,_ := KeyWrap(key, kek);
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Unwrap128Key_128Kek(c *C) {
//given (Section 4.1)
//000102030405060708090A0B0C0D0E0F
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
//00112233445566778899AABBCCDDEEFF
expected := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 }
//1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5
key := []byte{ 31, 166, 139, 10, 129, 18, 180, 71, 174, 243, 75, 216, 251, 90, 123, 130, 157, 62, 134, 35, 113, 210, 207, 229 }
//when
test,_ := KeyUnwrap(key, kek)
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Wrap_128Key_192Kek(c *C) {
//given (Section 4.2)
//000102030405060708090A0B0C0D0E0F1011121314151617
kek := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
//00112233445566778899AABBCCDDEEFF
key := []byte{0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}
//96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D
expected := []byte{150, 119, 139, 37, 174, 108, 164, 53, 249, 43, 91, 151, 192, 80, 174, 210, 70, 138, 184, 161, 122, 216, 78, 93}
//when
test,_ := KeyWrap(key, kek);
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Unwrap128Key_192Kek(c *C) {
//given (Section 4.2)
//000102030405060708090A0B0C0D0E0F1011121314151617
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }
//00112233445566778899AABBCCDDEEFF
expected := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 }
//96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D
key := []byte{ 150, 119, 139, 37, 174, 108, 164, 53, 249, 43, 91, 151, 192, 80, 174, 210, 70, 138, 184, 161, 122, 216, 78, 93 }
//when
test,_ := KeyUnwrap(key, kek)
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Wrap_128Key_256Kek(c *C) {
//given (Section 4.3)
//000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
kek := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
//00112233445566778899AABBCCDDEEFF
key := []byte{0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}
//64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7
expected := []byte{100, 232, 195, 249, 206, 15, 91, 162, 99, 233, 119, 121, 5, 129, 138, 42, 147, 200, 25, 30, 125, 110, 138, 231}
//when
test,_ := KeyWrap(key, kek);
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Unwrap128Key_256Kek(c *C) {
//given (Section 4.3)
//000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }
//00112233445566778899AABBCCDDEEFF
expected := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 }
//64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7
key := []byte{ 100, 232, 195, 249, 206, 15, 91, 162, 99, 233, 119, 121, 5, 129, 138, 42, 147, 200, 25, 30, 125, 110, 138, 231 }
//when
test,_ := KeyUnwrap(key, kek)
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Wrap_192Key_192Kek(c *C) {
//given (Section 4.4)
//000102030405060708090A0B0C0D0E0F1011121314151617
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }
//00112233445566778899AABBCCDDEEFF0001020304050607
key := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 0, 1, 2, 3, 4, 5, 6, 7 }
//031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2
expected := []byte{ 3, 29, 51, 38, 78, 21, 211, 50, 104, 242, 78, 194, 96, 116, 62, 220, 225, 198, 199, 221, 238, 114, 90, 147, 107, 168, 20, 145, 92, 103, 98, 210 }
//when
test,_ := KeyWrap(key, kek);
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Unwrap192Key_192Kek(c *C) {
//given (Section 4.4)
//000102030405060708090A0B0C0D0E0F1011121314151617
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }
//00112233445566778899AABBCCDDEEFF0001020304050607
expected := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 0, 1, 2, 3, 4, 5, 6, 7 }
//031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2
key := []byte{ 3, 29, 51, 38, 78, 21, 211, 50, 104, 242, 78, 194, 96, 116, 62, 220, 225, 198, 199, 221, 238, 114, 90, 147, 107, 168, 20, 145, 92, 103, 98, 210 }
//when
test,_ := KeyUnwrap(key, kek)
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Wrap_192Key_256Kek(c *C) {
//given (Section 4.5)
//000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }
//00112233445566778899AABBCCDDEEFF0001020304050607
key := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 0, 1, 2, 3, 4, 5, 6, 7 }
//A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1
expected := []byte{ 168, 249, 188, 22, 18, 198, 139, 63, 246, 230, 244, 251, 227, 14, 113, 228, 118, 156, 139, 128, 163, 44, 184, 149, 140, 213, 209, 125, 107, 37, 77, 161 }
//when
test,_ := KeyWrap(key, kek);
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Unwrap192Key_256Kek(c *C) {
//given (Section 4.5)
//000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }
//00112233445566778899AABBCCDDEEFF0001020304050607
expected := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 0, 1, 2, 3, 4, 5, 6, 7 }
//A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1
key := []byte{ 168, 249, 188, 22, 18, 198, 139, 63, 246, 230, 244, 251, 227, 14, 113, 228, 118, 156, 139, 128, 163, 44, 184, 149, 140, 213, 209, 125, 107, 37, 77, 161 }
//when
test,_ := KeyUnwrap(key, kek)
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Wrap_256Key_256Kek(c *C) {
//given (Section 4.6)
//000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }
//00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F
key := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
//28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21
expected := []byte{ 40, 201, 244, 4, 196, 184, 16, 244, 203, 204, 179, 92, 251, 135, 248, 38, 63, 87, 134, 226, 216, 14, 211, 38, 203, 199, 240, 231, 26, 153, 244, 59, 251, 152, 139, 155, 122, 2, 221, 33 }
//when
test,_ := KeyWrap(key, kek);
//then
c.Assert(test, DeepEquals, expected)
}
func (s *TestSuite) Test_Unwrap256Key_256Kek(c *C) {
//given (Section 4.6)
//000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
kek := []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }
//00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F
expected := []byte{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
//28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21
key := []byte{ 40, 201, 244, 4, 196, 184, 16, 244, 203, 204, 179, 92, 251, 135, 248, 38, 63, 87, 134, 226, 216, 14, 211, 38, 203, 199, 240, 231, 26, 153, 244, 59, 251, 152, 139, 155, 122, 2, 221, 33 }
//when
test,_ := KeyUnwrap(key, kek)
//then
c.Assert(test, DeepEquals, expected)
}

View File

@ -2,70 +2,70 @@
package arrays
import (
"encoding/binary"
"bytes"
"github.com/dvsekhvalnov/jose2go/base64url"
"crypto/rand"
"fmt"
"encoding/binary"
"fmt"
"github.com/dvsekhvalnov/jose2go/base64url"
)
// Xor is doing byte by byte exclusive or of 2 byte arrays
func Xor(left,right []byte) []byte {
result:=make([]byte,len(left))
for i:=0;i<len(left);i++ {
result[i]=left[i] ^ right[i]
func Xor(left, right []byte) []byte {
result := make([]byte, len(left))
for i := 0; i < len(left); i++ {
result[i] = left[i] ^ right[i]
}
return result
}
// Slice is splitting input byte array into slice of subarrays. Each of count length.
func Slice(arr []byte, count int) [][]byte {
sliceCount := len(arr) / count;
result:=make([][]byte, sliceCount)
for i:=0; i<sliceCount; i++ {
start:=i*count
end:=i*count+count
result[i]=arr[start:end]
sliceCount := len(arr) / count
result := make([][]byte, sliceCount)
for i := 0; i < sliceCount; i++ {
start := i * count
end := i*count + count
result[i] = arr[start:end]
}
return result
}
// Random generates byte array with random data of byteCount length
func Random(byteCount int) ([]byte,error) {
data := make([]byte,byteCount)
if _, err := rand.Read(data);err!=nil {
return nil,err
func Random(byteCount int) ([]byte, error) {
data := make([]byte, byteCount)
if _, err := rand.Read(data); err != nil {
return nil, err
}
return data,nil
return data, nil
}
// Concat combine several arrays into single one, resulting slice = A1 | A2 | A3 | ... | An
func Concat(arrays ...[]byte) []byte {
var result []byte=arrays[0]
for _,arr := range(arrays[1:]) {
result=append(result,arr...)
var result []byte = arrays[0]
for _, arr := range arrays[1:] {
result = append(result, arr...)
}
return result
}
// Unwrap same thing as Contact, just different interface, combines several array into single one
func Unwrap(arrays [][]byte) []byte {
var result []byte=arrays[0]
for _,arr := range(arrays[1:]) {
result=append(result,arr...)
var result []byte = arrays[0]
for _, arr := range arrays[1:] {
result = append(result, arr...)
}
return result
}
@ -73,7 +73,7 @@ func Unwrap(arrays [][]byte) []byte {
func UInt64ToBytes(value uint64) []byte {
result := make([]byte, 8)
binary.BigEndian.PutUint64(result, value)
return result
}
@ -81,36 +81,36 @@ func UInt64ToBytes(value uint64) []byte {
func UInt32ToBytes(value uint32) []byte {
result := make([]byte, 4)
binary.BigEndian.PutUint32(result, value)
return result
}
// Dump produces printable debug representation of byte array as string
func Dump(arr []byte) string {
var buf bytes.Buffer
var buf bytes.Buffer
buf.WriteString("(")
buf.WriteString(fmt.Sprintf("%v",len(arr)))
buf.WriteString(fmt.Sprintf("%v", len(arr)))
buf.WriteString(" bytes)[")
for idx,b := range(arr) {
buf.WriteString(fmt.Sprintf("%v",b))
if idx!=len(arr)-1 {
for idx, b := range arr {
buf.WriteString(fmt.Sprintf("%v", b))
if idx != len(arr)-1 {
buf.WriteString(", ")
}
}
buf.WriteString("], Hex: [")
buf.WriteString("], Hex: [")
for idx,b := range(arr) {
buf.WriteString(fmt.Sprintf("%X",b))
if idx!=len(arr)-1 {
for idx, b := range arr {
buf.WriteString(fmt.Sprintf("%X", b))
if idx != len(arr)-1 {
buf.WriteString(" ")
}
}
buf.WriteString("], Base64Url:")
buf.WriteString("], Base64Url:")
buf.WriteString(base64url.Encode(arr))
return buf.String()
return buf.String()
}

View File

@ -1,80 +0,0 @@
package arrays
import (
"testing"
// "fmt"
. "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
func (s *TestSuite) TestXor(c *C) {
//given
data:=[]byte { 0xFF, 0x00, 0xF0, 0x0F, 0x55, 0xAA, 0xBB, 0xCC}
//when
test_1:=Xor(data,[]byte{0x00, 0xFF, 0x0F, 0xF0, 0xAA, 0x55, 0x44, 0x33})
test_2:=Xor(data,[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
//then
c.Assert(test_1, DeepEquals, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
c.Assert(test_2, DeepEquals, []byte{0x00, 0xFF, 0x0F, 0xF0, 0xAA, 0x55, 0x44, 0x33})
}
func (s *TestSuite) TestSlice(c *C) {
//given
data:=[]byte{ 0, 1, 2, 3, 4, 5, 6, 7, 8 }
//when
test:=Slice(data,3)
//then
c.Assert(len(test), Equals, 3)
c.Assert(test[0], DeepEquals, []byte{0,1,2})
c.Assert(test[1], DeepEquals, []byte{3,4,5})
c.Assert(test[2], DeepEquals, []byte{6,7,8})
}
func (s *TestSuite) TestConcat(c *C) {
//given
a:=[]byte{1,2,3}
b:=[]byte{4,5}
d:=[]byte{6}
e:=[]byte{}
f:=[]byte{7,8,9,10}
//when
test:=Concat(a,b,d,e,f)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,6,7,8,9,10})
}
func (s *TestSuite) TestUnwrap(c *C) {
//given
a:=[]byte{1,2,3}
b:=[]byte{4,5}
d:=[]byte{6}
e:=[]byte{}
f:=[]byte{7,8,9,10}
//when
test:=Unwrap([][]byte{a,b,d,e,f})
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,6,7,8,9,10})
}
func (s *TestSuite) TestUInt32ToBytes(c *C) {
//then
c.Assert(UInt32ToBytes(0xFF), DeepEquals, []byte{ 0x00, 0x00, 0x00, 0xFF })
c.Assert(UInt32ToBytes(0xFFFFFFFE), DeepEquals, []byte{ 0xff, 0xff, 0xff, 0xfe })
}
func (s *TestSuite) TestUInt64ToBytes(c *C) {
//then
c.Assert(UInt64ToBytes(0xFF), DeepEquals, []byte{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF })
c.Assert(UInt64ToBytes(0xFFFFFFFFFFFFFFFE), DeepEquals, []byte{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe })
}

View File

@ -1,40 +0,0 @@
package base64url
import (
"testing"
"fmt"
. "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
func (s *TestSuite) TestEncode(c *C) {
//given
in:=[]byte{72,101,108,108,111,32,66,97,115,101,54,52,85,114,108,32,101,110,99,111,100,105,110,103,33}
//when
test:=Encode(in)
//then
c.Assert(test, Equals, "SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ")
}
func (s *TestSuite) TestDecode(c *C) {
//when
test,err := Decode("SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ")
//then
c.Assert(err, IsNil)
c.Assert(test, DeepEquals, []byte{72,101,108,108,111,32,66,97,115,101,54,52,85,114,108,32,101,110,99,111,100,105,110,103,33})
}
func (s *TestSuite) TestDecodeIllegalBase64String(c *C) {
//when
_,err := Decode("SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nQ")
//then
c.Assert(err,NotNil)
fmt.Printf("err = %v\n",err)
}

View File

@ -2,33 +2,32 @@
package compact
import (
"strings"
"github.com/dvsekhvalnov/jose2go/base64url"
"strings"
)
// Parse splitting & decoding compact serialized json web token, returns slice of byte arrays, each representing part of token
func Parse(token string) [][]byte {
parts:=strings.Split(token,".")
result:=make([][]byte,len(parts))
var e error
for i,part:=range parts {
if result[i],e=base64url.Decode(part);e!=nil {
panic(e)
}
func Parse(token string) (result [][]byte, e error) {
parts := strings.Split(token, ".")
result = make([][]byte, len(parts))
for i, part := range parts {
if result[i], e = base64url.Decode(part); e != nil {
return nil, e
}
}
return result
return result, nil
}
// Serialize converts given parts into compact serialization format
func Serialize(parts ...[]byte) string {
result:=make([]string,len(parts))
for i,part:=range parts {
result[i]=base64url.Encode(part)
result := make([]string, len(parts))
for i, part := range parts {
result[i] = base64url.Encode(part)
}
return strings.Join(result,".")
return strings.Join(result, ".")
}

View File

@ -1,90 +0,0 @@
package compact
import (
"testing"
. "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
func (s *TestSuite) TestParseThreeParts(c *C) {
//when
test:=Parse("eyJhbGciOiJIUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.chIoYWrQMA8XL5nFz6oLDJyvgHk2KA4BrFGrKymjC8E")
//then
c.Assert(test, HasLen, 3)
c.Assert(test[0], DeepEquals, []byte{123,34,97,108,103,34,58,34,72,83,50,53,54,34,44,34,99,116,121,34,58,34,116,101,120,116,92,47,112,108,97,105,110,34,125})
c.Assert(test[1], DeepEquals, []byte{123,34,104,101,108,108,111,34,58,32,34,119,111,114,108,100,34,125})
c.Assert(test[2], DeepEquals, []byte{114,18,40,97,106,208,48,15,23,47,153,197,207,170,11,12,156,175,128,121,54,40,14,1,172,81,171,43,41,163,11,193})
}
func (s *TestSuite) TestParseEmptyTrailingPart(c *C) {
//when
test:=Parse("eyJhbGciOiJub25lIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.")
//then
c.Assert(test, HasLen, 3)
c.Assert(test[0], DeepEquals, []byte{123,34,97,108,103,34,58,34,110,111,110,101,34,125})
c.Assert(test[1], DeepEquals, []byte{123,34,104,101,108,108,111,34,58,32,34,119,111,114,108,100,34,125})
c.Assert(test[2], DeepEquals, []byte{})
}
func (s *TestSuite) TestParseFiveParts(c *C) {
//when
test:=Parse("eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4R0NNIn0.FojyyzygtFOyNBjzqTRfr9HVHPrvtqbVUt9sXSuU59ZhLlzk7FrirryFnFGtj8YC9lx-IX156Ro9rBaJTCU_dfERd05DhPMffT40rdcDiLxfCLOY0E2PfsMyGQPhI6YtNBtf_sQjXWEBC59zH_VoswFAUstkvXY9eVVecoM-W9HFlIxwUXMVpEPtS96xZX5LMksDgJ9sYDTNa6EQOA0hfzw07fD_FFJShcueqJuoJjILYbad-AHbpnLTV4oTbFTYjskRxpEYQr9plFZsT4_xKiCU89slT9EFhmuaiUI_-NGdX-kNDyQZj2Vtid4LSOVv5kGxyygThuQb6wjr1AGe1g.O92pf8iqwlBIQmXA.YdGjkN7lzeKYIv743XlPRYTd3x4VA0xwa5WVoGf1hiHlhQuXGEg4Jv3elk4JoFJzgVuMMQMex8fpFFL3t5I4H9bH18pbrEo7wLXvGOsP971cuOOaXPxhX6qClkwx5qkWhcTbO_2AuJxzIaU9qBwtwWaxJm9axofAPYgYbdaMZkU4F5sFdaFY8IOe94wUA1Ocn_gxC_DYp9IEAyZut0j5RImmthPgiRO_0pK9OvusE_Xg3iGfdxu70x0KpoItuNwlEf0LUA.uP5jOGMxtDUiT6E3ubucBw")
//then
c.Assert(test, HasLen, 5)
c.Assert(test[0], DeepEquals, []byte{123,34,97,108,103,34,58,34,82,83,65,49,95,53,34,44,34,101,110,99,34,58,34,65,49,50,56,71,67,77,34,125})
c.Assert(test[1], DeepEquals, []byte{22,136,242,203,60,160,180,83,178,52,24,243,169,52,95,175,209,213,28,250,239,182,166,213,82,223,108,93,43,148,231,214,97,46,92,228,236,90,226,174,188,133,156,81,173,143,198,2,246,92,126,33,125,121,233,26,61,172,22,137,76,37,63,117,241,17,119,78,67,132,243,31,125,62,52,173,215,3,136,188,95,8,179,152,208,77,143,126,195,50,25,3,225,35,166,45,52,27,95,254,196,35,93,97,1,11,159,115,31,245,104,179,1,64,82,203,100,189,118,61,121,85,94,114,131,62,91,209,197,148,140,112,81,115,21,164,67,237,75,222,177,101,126,75,50,75,3,128,159,108,96,52,205,107,161,16,56,13,33,127,60,52,237,240,255,20,82,82,133,203,158,168,155,168,38,50,11,97,182,157,248,1,219,166,114,211,87,138,19,108,84,216,142,201,17,198,145,24,66,191,105,148,86,108,79,143,241,42,32,148,243,219,37,79,209,5,134,107,154,137,66,63,248,209,157,95,233,13,15,36,25,143,101,109,137,222,11,72,229,111,230,65,177,203,40,19,134,228,27,235,8,235,212,1,158,214})
c.Assert(test[2], DeepEquals, []byte{59,221,169,127,200,170,194,80,72,66,101,192})
c.Assert(test[3], DeepEquals, []byte{97,209,163,144,222,229,205,226,152,34,254,248,221,121,79,69,132,221,223,30,21,3,76,112,107,149,149,160,103,245,134,33,229,133,11,151,24,72,56,38,253,222,150,78,9,160,82,115,129,91,140,49,3,30,199,199,233,20,82,247,183,146,56,31,214,199,215,202,91,172,74,59,192,181,239,24,235,15,247,189,92,184,227,154,92,252,97,95,170,130,150,76,49,230,169,22,133,196,219,59,253,128,184,156,115,33,165,61,168,28,45,193,102,177,38,111,90,198,135,192,61,136,24,109,214,140,102,69,56,23,155,5,117,161,88,240,131,158,247,140,20,3,83,156,159,248,49,11,240,216,167,210,4,3,38,110,183,72,249,68,137,166,182,19,224,137,19,191,210,146,189,58,251,172,19,245,224,222,33,159,119,27,187,211,29,10,166,130,45,184,220,37,17,253,11,80})
c.Assert(test[4], DeepEquals, []byte{184,254,99,56,99,49,180,53,34,79,161,55,185,187,156,7})
}
func (s *TestSuite) TestParseEmptyMiddlePart(c *C) {
//when
test:=Parse("eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIn0..yVi-LdQQngN0C5WS.1McwSmhZzAtmmLp9y-OdnJwaJFo1nj_4ashmzl2LhubGf0Jl1OTEVJzsHZb7bkup7cGTkuxh6Vfv10ljHsjWf_URXoxP3stQqQeViVcuPV0y2Q_WHYzTNGZpmHGe-hM6gjDhyZyvu3yeXGFSvfPQmp9pWVOgDjI4RC0MQ83rzzn-rRdnZkznWjbmOPxwPrR72Qng0BISsEwbkPn4oO8-vlHkVmPpuDTaYzCT2ZR5K9JnIU8d8QdxEAGb7-s8GEJ1yqtd_w._umbK59DAKA3O89h15VoKQ")
//then
c.Assert(test, HasLen, 5)
c.Assert(test[0], DeepEquals, []byte{123,34,97,108,103,34,58,34,100,105,114,34,44,34,101,110,99,34,58,34,65,49,50,56,71,67,77,34,125})
c.Assert(test[1], DeepEquals, []byte{})
c.Assert(test[2], DeepEquals, []byte{201,88,190,45,212,16,158,3,116,11,149,146})
c.Assert(test[3], DeepEquals, []byte{212,199,48,74,104,89,204,11,102,152,186,125,203,227,157,156,156,26,36,90,53,158,63,248,106,200,102,206,93,139,134,230,198,127,66,101,212,228,196,84,156,236,29,150,251,110,75,169,237,193,147,146,236,97,233,87,239,215,73,99,30,200,214,127,245,17,94,140,79,222,203,80,169,7,149,137,87,46,61,93,50,217,15,214,29,140,211,52,102,105,152,113,158,250,19,58,130,48,225,201,156,175,187,124,158,92,97,82,189,243,208,154,159,105,89,83,160,14,50,56,68,45,12,67,205,235,207,57,254,173,23,103,102,76,231,90,54,230,56,252,112,62,180,123,217,9,224,208,18,18,176,76,27,144,249,248,160,239,62,190,81,228,86,99,233,184,52,218,99,48,147,217,148,121,43,210,103,33,79,29,241,7,113,16,1,155,239,235,60,24,66,117,202,171,93,255})
c.Assert(test[4], DeepEquals, []byte{254,233,155,43,159,67,0,160,55,59,207,97,215,149,104,41})
}
func (s *TestSuite) TestSerialize(c *C) {
//when
test:=Serialize([]byte{123,34,97,108,103,34,58,34,72,83,50,53,54,34,44,34,99,116,121,34,58,34,116,101,120,116,92,47,112,108,97,105,110,34,125},
[]byte{123,34,104,101,108,108,111,34,58,32,34,119,111,114,108,100,34,125},
[]byte{114,18,40,97,106,208,48,15,23,47,153,197,207,170,11,12,156,175,128,121,54,40,14,1,172,81,171,43,41,163,11,193})
//then
c.Assert(test, Equals, "eyJhbGciOiJIUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.chIoYWrQMA8XL5nFz6oLDJyvgHk2KA4BrFGrKymjC8E")
}
func (s *TestSuite) TestSerializeEmptyTrailingPart(c *C) {
//when
test:=Serialize([]byte{123,34,97,108,103,34,58,34,72,83,50,53,54,34,44,34,99,116,121,34,58,34,116,101,120,116,92,47,112,108,97,105,110,34,125},
[]byte{123,34,104,101,108,108,111,34,58,32,34,119,111,114,108,100,34,125},
[]byte{})
//then
c.Assert(test, Equals, "eyJhbGciOiJIUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.")
}
func (s *TestSuite) TestSerializeEmptyMiddlePart(c *C) {
//when
test:=Serialize([]byte{123,34,97,108,103,34,58,34,72,83,50,53,54,34,44,34,99,116,121,34,58,34,116,101,120,116,92,47,112,108,97,105,110,34,125},
[]byte{},
[]byte{114,18,40,97,106,208,48,15,23,47,153,197,207,170,11,12,156,175,128,121,54,40,14,1,172,81,171,43,41,163,11,193})
//then
c.Assert(test, Equals, "eyJhbGciOiJIUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0..chIoYWrQMA8XL5nFz6oLDJyvgHk2KA4BrFGrKymjC8E")
}

View File

@ -107,24 +107,58 @@ type JwcAlgorithm interface {
Name() string
}
// Sign produces signed JWT token given arbitrary payload, signature algorithm to use (see constants for list of supported algs) and signing key.
func Zip(alg string) func(cfg *joseConfig) {
return func(cfg *joseConfig) {
cfg.compressionAlg = alg
}
}
func Header(name string, value interface{}) func(cfg *joseConfig) {
return func(cfg *joseConfig) {
cfg.headers[name] = value
}
}
func Headers(headers map[string]interface{}) func(cfg *joseConfig) {
return func(cfg *joseConfig) {
for k, v := range headers {
cfg.headers[k] = v
}
}
}
type joseConfig struct {
compressionAlg string
headers map[string]interface{}
}
// Sign produces signed JWT token given arbitrary payload, signature algorithm to use (see constants for list of supported algs), signing key and extra options (see option functions)
// Signing key is of different type for different signing alg, see specific
// signing alg implementation documentation.
//
// It returns 3 parts signed JWT token as string and not nil error if something went wrong.
func Sign(payload string, signingAlg string, key interface{}) (token string, err error) {
func Sign(payload string, signingAlg string, key interface{}, options ...func(*joseConfig)) (token string, err error) {
if signer, ok := jwsHashers[signingAlg]; ok {
jwtHeader := map[string]interface{}{
"typ": "JWT",
"alg": signingAlg,
cfg := &joseConfig{compressionAlg: "", headers: make(map[string]interface{})}
//apply extra options
for _, option := range options {
option(cfg)
}
//make sure defaults and requires are managed by us
cfg.headers["alg"] = signingAlg
if _, typ := cfg.headers["typ"]; !typ {
cfg.headers["typ"] = "JWT"
}
paloadBytes := []byte(payload)
var header []byte
var signature []byte
if header, err = json.Marshal(jwtHeader); err == nil {
if header, err = json.Marshal(cfg.headers); err == nil {
securedInput := []byte(compact.Serialize(header, paloadBytes))
if signature, err = signer.Sign(securedInput, key); err == nil {
@ -143,16 +177,39 @@ func Sign(payload string, signingAlg string, key interface{}) (token string, err
// key management alg implementation documentation.
//
// It returns 5 parts encrypted JWT token as string and not nil error if something went wrong.
func Encrypt(payload string, alg string, enc string, key interface{}) (token string, err error) {
func Encrypt(payload string, alg string, enc string, key interface{}, options ...func(*joseConfig)) (token string, err error) {
jwtHeader := map[string]interface{}{
"enc": enc,
"alg": alg,
cfg := &joseConfig{compressionAlg: "", headers: make(map[string]interface{})}
//apply extra options
for _, option := range options {
option(cfg)
}
return encrypt([]byte(payload), jwtHeader, key)
//make sure required headers are managed by us
cfg.headers["alg"] = alg
cfg.headers["enc"] = enc
byteContent := []byte(payload)
if cfg.compressionAlg != "" {
if zipAlg, ok := jwcCompressors[cfg.compressionAlg]; ok {
byteContent = zipAlg.Compress([]byte(payload))
cfg.headers["zip"] = cfg.compressionAlg
} else {
return "", errors.New(fmt.Sprintf("jwt.Compress(): Unknown compression method '%v'", cfg.compressionAlg))
}
} else {
delete(cfg.headers, "zip") //we not allow to manage 'zip' header manually for encryption
}
return encrypt(byteContent, cfg.headers, key)
}
// This method is DEPRICATED and subject to be removed in next version.
// Use Encrypt(..) with Zip option instead.
//
// Compress produces encrypted & comressed JWT token given arbitrary payload, key management , encryption and compression algorithms to use (see constants for list of supported algs) and management key.
// Management key is of different type for different key management alg, see specific
// key management alg implementation documentation.
@ -181,7 +238,11 @@ func Compress(payload string, alg string, enc string, zip string, key interface{
// Returns decoded payload as a string and not nil error if something went wrong.
func Decode(token string, key interface{}) (string, map[string]interface{}, error) {
parts := compact.Parse(token)
parts, err := compact.Parse(token)
if err != nil {
return "", nil, err
}
if len(parts) == 3 {
return verify(parts, key)

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,10 @@ import (
"github.com/dvsekhvalnov/jose2go/arrays"
)
const (
MaxInt = int(^uint(0)>>1);
)
// DeriveConcatKDF implements NIST SP 800-56A Concatenation Key Derivation Function. Derives
// key material of keydatalen bits size given Z (sharedSecret), OtherInfo (AlgorithmID |
// PartyUInfo | PartyVInfo | SuppPubInfo | SuppPrivInfo) and hash function
@ -17,7 +21,7 @@ func DeriveConcatKDF(keydatalen int, sharedSecret, algId, partyUInfo, partyVInfo
reps := int(math.Ceil(float64(keyLenBytes) / float64(h.Size())))
if reps > 4294967295 {
if reps > MaxInt {
panic("kdf.DeriveConcatKDF: too much iterations (more than 2^32-1).")
}

View File

@ -1,57 +0,0 @@
package kdf
import (
. "gopkg.in/check.v1"
"crypto/sha256"
"github.com/dvsekhvalnov/jose2go/arrays"
"github.com/dvsekhvalnov/jose2go/base64url"
)
var z=[]byte{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}
var z2=[]byte{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47}
var algId=prependDatalen([]byte("alg"))
var partyUInfo=datalenFormat("pui")
var partyVInfo=datalenFormat("pvi")
func (s *TestSuite) Test256Secret_256Key(c *C) {
//when
test:=DeriveConcatKDF(256,z,algId,partyUInfo,partyVInfo,arrays.UInt32ToBytes(256),nil,sha256.New())
//then
c.Assert(test, DeepEquals, []byte{190, 69, 15, 62, 38, 64, 30, 141, 208, 163, 55, 202, 18, 71, 176, 174, 114, 221, 249, 255, 207, 131, 190, 77, 12, 115, 220, 144, 102, 149, 78, 28})
}
func (s *TestSuite) Test256Secret_384Key(c *C) {
//when
test:=DeriveConcatKDF(384,z,algId,partyUInfo,partyVInfo,arrays.UInt32ToBytes(384),nil,sha256.New())
//then
c.Assert(test, DeepEquals, []byte{187, 16, 110, 253, 151, 199, 57, 235, 219, 8, 73, 191, 208, 108, 63, 241, 235, 137, 178, 149, 3, 199, 216, 99, 105, 217, 45, 114, 109, 213, 83, 198, 52, 101, 99, 146, 193, 31, 172, 157, 19, 140, 25, 202, 153, 92, 252, 192})
}
func (s *TestSuite) Test256Secret_521Key(c *C) {
//when
test:=DeriveConcatKDF(521,z,algId,partyUInfo,partyVInfo,arrays.UInt32ToBytes(521),nil,sha256.New())
//then
c.Assert(test, DeepEquals, []byte{245, 40, 159, 13, 25, 70, 170, 74, 210, 240, 242, 224, 37, 215, 23, 201, 126, 90, 108, 103, 205, 180, 48, 193, 131, 40, 86, 183, 97, 144, 1, 150, 154, 186, 196, 127, 6, 19, 17, 230, 75, 144, 229, 195, 61, 240, 20, 173, 167, 159, 50, 103, 133, 177, 241, 145, 134, 84, 50, 246, 157, 252, 51, 24, 35})
}
func (s *TestSuite) Test384Secret_256Key(c *C) {
//when
test:=DeriveConcatKDF(256,z2,algId,partyUInfo,partyVInfo,arrays.UInt32ToBytes(256),nil,sha256.New())
//then
c.Assert(test, DeepEquals, []byte{27, 55, 33, 99, 20, 191, 202, 69, 84, 176, 250, 108, 99, 7, 91, 49, 200, 47, 219, 142, 190, 216, 197, 154, 235, 17, 76, 12, 165, 75, 201, 108})
}
//test utils
func datalenFormat(str string) []byte {
bytes,_:=base64url.Decode(str)
return prependDatalen(bytes)
}
func prependDatalen(bytes []byte) []byte {
return arrays.Concat(arrays.UInt32ToBytes(uint32(len(bytes))),bytes)
}

View File

@ -20,7 +20,7 @@ func DerivePBKDF2(password, salt []byte, iterationCount, keyBitLength int, h has
r := dkLen - (l-1)*hLen
// 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop.
if dkLen > 4294967295 {
if dkLen > MaxInt {
panic(fmt.Sprintf("kdf.DerivePBKDF2: expects derived key size to be not more that (2^32-1) bits, but was requested %v bits.", keyBitLength))
}

View File

@ -1,112 +0,0 @@
package kdf
import (
"testing"
. "gopkg.in/check.v1"
"crypto/sha256"
"crypto/sha512"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
var password=[]byte("password")
var salt=[]byte("salt")
func (s *TestSuite) TestDerivePbkdf2Sha256Count1(c *C) {
//when
test:=DerivePBKDF2(password, salt, 1, 256, sha256.New())
//then
c.Assert(test, DeepEquals, []byte{ 18, 15, 182, 207, 252, 248, 179, 44, 67, 231, 34, 82, 86, 196, 248, 55, 168, 101, 72, 201, 44, 204, 53, 72, 8, 5, 152, 124, 183, 11, 225, 123 })
}
func (s *TestSuite) TestDerivePbkdf2Sha256Count2(c *C) {
//when
test:=DerivePBKDF2(password, salt, 2, 256, sha256.New())
//then
c.Assert(test, DeepEquals, []byte{ 174, 77, 12, 149, 175, 107, 70, 211, 45, 10, 223, 249, 40, 240, 109, 208, 42, 48, 63, 142, 243, 194, 81, 223, 214, 226, 216, 90, 149, 71, 76, 67 })
}
func (s *TestSuite) TestDerivePbkdf2Sha256Count4096(c *C) {
//when
test:=DerivePBKDF2(password, salt, 4096, 256, sha256.New())
//then
c.Assert(test, DeepEquals, []byte{ 197, 228, 120, 213, 146, 136, 200, 65, 170, 83, 13, 182, 132, 92, 76, 141, 150, 40, 147, 160, 1, 206, 78, 17, 164, 150, 56, 115, 170, 152, 19, 74 })
}
func (s *TestSuite) TestDerivePbkdf2Sha256Count4096Len320(c *C) {
//when
test:=DerivePBKDF2([]byte("passwordPASSWORDpassword"), []byte("saltSALTsaltSALTsaltSALTsaltSALTsalt"), 4096, 320, sha256.New())
//then
c.Assert(test, DeepEquals, []byte{ 52, 140, 137, 219, 203, 211, 43, 47, 50, 216, 20, 184, 17, 110, 132, 207, 43, 23, 52, 126, 188, 24, 0, 24, 28, 78, 42, 31, 184, 221, 83, 225, 198, 53, 81, 140, 125, 172, 71, 233 })
}
func (s *TestSuite) TestDerivePbkdf2Sha384Count1Len384(c *C) {
//when
test:=DerivePBKDF2(password,salt, 1, 384, sha512.New384())
//then
c.Assert(test, DeepEquals, []byte{ 192, 225, 79, 6, 228, 158, 50, 215, 63, 159, 82, 221, 241, 208, 197, 199, 25, 22, 9, 35, 54, 49, 218, 221, 118, 165, 103, 219, 66, 183, 134, 118, 179, 143, 200, 0, 204, 83, 221, 182, 66, 245, 199, 68, 66, 230, 43, 228 })
}
func (s *TestSuite) TestDerivePbkdf2Sha384Count2Len384(c *C) {
//when
test:=DerivePBKDF2(password,salt, 2, 384, sha512.New384())
//then
c.Assert(test, DeepEquals, []byte{ 84, 247, 117, 198, 215, 144, 242, 25, 48, 69, 145, 98, 252, 83, 93, 191, 4, 169, 57, 24, 81, 39, 1, 106, 4, 23, 106, 7, 48, 198, 241, 244, 251, 72, 131, 42, 209, 38, 27, 170, 221, 44, 237, 213, 8, 20, 177, 200 })
}
func (s *TestSuite) TestDerivePbkdf2Sha384Count4096Len384(c *C) {
//when
test:=DerivePBKDF2(password,salt, 4096, 384, sha512.New384())
//then
c.Assert(test, DeepEquals, []byte{ 85, 151, 38, 190, 56, 219, 18, 91, 200, 94, 215, 137, 95, 110, 60, 245, 116, 199, 160, 28, 8, 12, 52, 71, 219, 30, 138, 118, 118, 77, 235, 60, 48, 123, 148, 133, 63, 190, 66, 79, 100, 136, 197, 244, 241, 40, 150, 38 })
}
func (s *TestSuite) TestDerivePbkdf2Sha384Count4096Len768(c *C) {
//when
test:=DerivePBKDF2([]byte("passwordPASSWORDpassword"), []byte("saltSALTsaltSALTsaltSALTsaltSALTsalt"), 4096, 768, sha512.New384())
//then
c.Assert(test, DeepEquals, []byte{ 129, 145, 67, 173, 102, 223, 154, 85, 37, 89, 185, 225, 49, 197, 42, 230, 197, 193, 176, 238, 209, 143, 77, 40, 59, 140, 92, 158, 174, 185, 43, 57, 44, 20, 124, 194, 210, 134, 157, 88, 255, 226, 247, 218, 19, 209, 95, 141, 146, 87, 33, 240, 237, 26, 250, 250, 36, 72, 13, 85, 207, 96, 96, 177, 127, 17, 42, 61, 231, 76, 174, 37, 253, 243, 86, 158, 36, 127, 41, 228, 219, 184, 68, 33, 132, 120, 34, 234, 153, 189, 32, 40, 60, 58, 37, 166 })
}
func (s *TestSuite) TestDerivePbkdf2Sha512Count1Len512(c *C) {
//when
test:=DerivePBKDF2(password, salt, 1, 512, sha512.New())
//then
c.Assert(test, DeepEquals, []byte{ 134, 127, 112, 207, 26, 222, 2, 207, 243, 117, 37, 153, 163, 165, 61, 196, 175, 52, 199, 166, 105, 129, 90, 229, 213, 19, 85, 78, 28, 140, 242, 82, 192, 45, 71, 10, 40, 90, 5, 1, 186, 217, 153, 191, 233, 67, 192, 143, 5, 2, 53, 215, 214, 139, 29, 165, 94, 99, 247, 59, 96, 165, 127, 206 })
}
func (s *TestSuite) TestDerivePbkdf2Sha512Count2Len512(c *C) {
//when
test:=DerivePBKDF2(password, salt, 2, 512, sha512.New())
//then
c.Assert(test, DeepEquals, []byte{ 225, 217, 193, 106, 166, 129, 112, 138, 69, 245, 199, 196, 226, 21, 206, 182, 110, 1, 26, 46, 159, 0, 64, 113, 63, 24, 174, 253, 184, 102, 213, 60, 247, 108, 171, 40, 104, 163, 155, 159, 120, 64, 237, 206, 79, 239, 90, 130, 190, 103, 51, 92, 119, 166, 6, 142, 4, 17, 39, 84, 242, 124, 207, 78 })
}
func (s *TestSuite) TestDerivePbkdf2Sha512Count4096Len512(c *C) {
//when
test:=DerivePBKDF2(password, salt, 4096, 512, sha512.New())
//then
c.Assert(test, DeepEquals, []byte{ 209, 151, 177, 179, 61, 176, 20, 62, 1, 139, 18, 243, 209, 209, 71, 158, 108, 222, 189, 204, 151, 197, 192, 248, 127, 105, 2, 224, 114, 244, 87, 181, 20, 63, 48, 96, 38, 65, 179, 213, 92, 211, 53, 152, 140, 179, 107, 132, 55, 96, 96, 236, 213, 50, 224, 57, 183, 66, 162, 57, 67, 74, 242, 213 })
}
func (s *TestSuite) TestDerivePbkdf2Sha256Count4096Len1024(c *C) {
//when
test:=DerivePBKDF2([]byte("passwordPASSWORDpassword"), []byte("saltSALTsaltSALTsaltSALTsaltSALTsalt"), 4096, 1024, sha512.New())
//then
c.Assert(test, DeepEquals, []byte{ 140, 5, 17, 244, 198, 229, 151, 198, 172, 99, 21, 216, 240, 54, 46, 34, 95, 60, 80, 20, 149, 186, 35, 184, 104, 192, 5, 23, 77, 196, 238, 113, 17, 91, 89, 249, 230, 12, 217, 83, 47, 163, 62, 15, 117, 174, 254, 48, 34, 92, 88, 58, 24, 108, 216, 43, 212, 218, 234, 151, 36, 163, 211, 184, 4, 247, 91, 221, 65, 73, 79, 163, 36, 202, 178, 75, 204, 104, 15, 179, 185, 106, 48, 207, 93, 33, 250, 195, 194, 135, 89, 19, 145, 159, 51, 153, 177, 217, 206, 126, 181, 76, 149, 186, 73, 17, 133, 150, 207, 116, 101, 113, 155, 190, 2, 196, 236, 171, 27, 21, 65, 41, 140, 50, 29, 19, 198, 246 })
}

View File

@ -1,113 +0,0 @@
package ecc
import (
"testing"
. "gopkg.in/check.v1"
"io/ioutil"
"math/big"
"crypto/elliptic"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
func (s *TestSuite) TestNewPublic(c *C) {
//given
x:=[]byte {4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}
y:=[]byte {131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}
//when
test:=NewPublic(x,y)
//then
c.Assert(test.X, DeepEquals, bigInt("2010878128539620107131539503221291822343443356718189500659356750794038206985"))
c.Assert(test.Y, DeepEquals, bigInt("59457993017710823357637488495120101390437944162821778556218889662829000218677"))
c.Assert(test.Curve, Equals, elliptic.P256())
}
func (s *TestSuite) TestNewPrivate(c *C) {
//given
x:=[]byte {4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}
y:=[]byte {131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}
d:=[]byte{ 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 }
//when
test:=NewPrivate(x,y,d)
//then
c.Assert(test.X, DeepEquals, bigInt("2010878128539620107131539503221291822343443356718189500659356750794038206985"))
c.Assert(test.Y, DeepEquals, bigInt("59457993017710823357637488495120101390437944162821778556218889662829000218677"))
c.Assert(test.D, DeepEquals, bigInt("19260228627344101198652694952536756709538941185117188878548538012226554651342"))
c.Assert(test.Curve, Equals, elliptic.P256())
}
func (s *TestSuite) TestReadPublicPKIX(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("./ec_public.key")
//when
test,e := ReadPublic(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.X, DeepEquals, bigInt("76939435694210362824363841832595476784225842365248086547769733757874741672069"))
c.Assert(test.Y, DeepEquals, bigInt("80047042001812490693675653292813886154388201612539715595028491948003157744818"))
c.Assert(test.Curve, Equals, elliptic.P256())
}
func (s *TestSuite) TestReadPublicPKCS1(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("./ec_cert.pem")
//when
test,e := ReadPublic(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.X, DeepEquals, bigInt("76939435694210362824363841832595476784225842365248086547769733757874741672069"))
c.Assert(test.Y, DeepEquals, bigInt("80047042001812490693675653292813886154388201612539715595028491948003157744818"))
c.Assert(test.Curve, Equals, elliptic.P256())
}
func (s *TestSuite) TestReadPrivatePKCS1(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("./ec_private.key")
//when
test,e := ReadPrivate(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.X, DeepEquals, bigInt("76939435694210362824363841832595476784225842365248086547769733757874741672069"))
c.Assert(test.Y, DeepEquals, bigInt("80047042001812490693675653292813886154388201612539715595028491948003157744818"))
c.Assert(test.D, DeepEquals, bigInt("7222604869653061109880849859470152714201198955914263913554931724612175399644"))
c.Assert(test.Curve, Equals, elliptic.P256())
}
func (s *TestSuite) TestReadPrivatePKCS8(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("./ec_private.pem")
//when
test,e := ReadPrivate(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.X, DeepEquals, bigInt("76939435694210362824363841832595476784225842365248086547769733757874741672069"))
c.Assert(test.Y, DeepEquals, bigInt("80047042001812490693675653292813886154388201612539715595028491948003157744818"))
c.Assert(test.D, DeepEquals, bigInt("7222604869653061109880849859470152714201198955914263913554931724612175399644"))
c.Assert(test.Curve, Equals, elliptic.P256())
}
//utils
func bigInt(value string) *big.Int {
i:=new (big.Int)
i.SetString(value,10)
return i
}

View File

@ -1,85 +0,0 @@
package Rsa
import (
"io/ioutil"
"math/big"
"testing"
. "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
func (s *TestSuite) TestNewPrivateRsaKeyPKCS1(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("priv.pem")
//when
test,e := ReadPrivate(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.D, DeepEquals, bigInt("124664500442337916425629948081980373708538939606058968438393904444884872144817323585651521088406960965803456218656807473171367526874204593887158860695954252405916280866383288176587587469870736553178754458686625418367566925639753001190058223163696966510495553421774149906056482201169970508069587759758018186673"))
c.Assert(test.Primes, HasLen, 2)
c.Assert(test.Primes[0], DeepEquals, bigInt("12153319500662601635346432957857245055929638609873673015885135318360261418965835817520733410832489021447922460160007366037402643276624674886502627435389593"))
c.Assert(test.Primes[1], DeepEquals, bigInt("10891140096045830766355607974974880425030121636560867106153739255802668290122259699296919947637286459736524694263050343032461619592457541146877906031793883"))
c.Assert(test.E, Equals, 65537)
c.Assert(test.N, DeepEquals, bigInt("132363505313722155184876628715249052276006747427497555521215412160460427148722445294983292629743653314149228192824806664548107146354876411009845771623017501212568714555984634301944063168503260813720165931647377932654326833738173931173570212088015547040743996672392373035728084429156775233489529905624779259619"))
}
func (s *TestSuite) TestNewPrivateRsaKeyPKCS8(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("priv.pem")
//when
test,e := ReadPrivate(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.D, DeepEquals, bigInt("124664500442337916425629948081980373708538939606058968438393904444884872144817323585651521088406960965803456218656807473171367526874204593887158860695954252405916280866383288176587587469870736553178754458686625418367566925639753001190058223163696966510495553421774149906056482201169970508069587759758018186673"))
c.Assert(test.Primes, HasLen, 2)
c.Assert(test.Primes[0], DeepEquals, bigInt("12153319500662601635346432957857245055929638609873673015885135318360261418965835817520733410832489021447922460160007366037402643276624674886502627435389593"))
c.Assert(test.Primes[1], DeepEquals, bigInt("10891140096045830766355607974974880425030121636560867106153739255802668290122259699296919947637286459736524694263050343032461619592457541146877906031793883"))
c.Assert(test.E, Equals, 65537)
c.Assert(test.N, DeepEquals, bigInt("132363505313722155184876628715249052276006747427497555521215412160460427148722445294983292629743653314149228192824806664548107146354876411009845771623017501212568714555984634301944063168503260813720165931647377932654326833738173931173570212088015547040743996672392373035728084429156775233489529905624779259619"))
}
func (s *TestSuite) TestNewPublicRsaKeyPKCS1(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("pub.pem")
//when
test,e := ReadPublic(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.E, Equals, 65537)
c.Assert(test.N, DeepEquals, bigInt("132363505313722155184876628715249052276006747427497555521215412160460427148722445294983292629743653314149228192824806664548107146354876411009845771623017501212568714555984634301944063168503260813720165931647377932654326833738173931173570212088015547040743996672392373035728084429156775233489529905624779259619"))
}
func (s *TestSuite) TestNewPublicRsaKeyPKIX(c *C) {
//given
keyBytes, _ := ioutil.ReadFile("pub.key")
//when
test,e := ReadPublic(keyBytes)
//then
c.Assert(e, IsNil)
c.Assert(test.E, Equals, 65537)
c.Assert(test.N, DeepEquals, bigInt("132363505313722155184876628715249052276006747427497555521215412160460427148722445294983292629743653314149228192824806664548107146354876411009845771623017501212568714555984634301944063168503260813720165931647377932654326833738173931173570212088015547040743996672392373035728084429156775233489529905624779259619"))
}
//utils
func bigInt(value string) *big.Int {
i:=new (big.Int)
i.SetString(value,10)
return i
}

View File

@ -1,52 +0,0 @@
package padding
import (
. "gopkg.in/check.v1"
)
func (s *TestSuite) TestAlignOneByte(c *C) {
//given
data:=[]byte{1,2,3}
//when
test:=Align(data,27)
//then
c.Assert(test, DeepEquals, []byte{0,1,2,3})
}
func (s *TestSuite) TestAlignMultiByte(c *C) {
//given
data:=[]byte{1,2,3}
//when
test:=Align(data,40)
//then
c.Assert(test, DeepEquals, []byte{0,0,1,2,3})
}
func (s *TestSuite) TestAlignMultiBytePartial(c *C) {
//given
data:=[]byte{1,2,3}
//when
test:=Align(data,43)
//then
c.Assert(test, DeepEquals, []byte{0,0,0,1,2,3})
}
func (s *TestSuite) TestAlignedArray(c *C) {
//given
data:=[]byte{1,2,3}
//when
test:=Align(data,24)
//then
c.Assert(test, DeepEquals, []byte{1,2,3})
}

View File

@ -1,109 +0,0 @@
package padding
import (
"testing"
. "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
type TestSuite struct{}
var _ = Suite(&TestSuite{})
func (s *TestSuite) TestRemovePkcs7NoPadding(c *C) {
//given
padded:=[]byte{1,2,3,4,5,6,7,8}
//when
test:=RemovePkcs7(padded,8)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,6,7,8})
}
func (s *TestSuite) TestRemovePkcs7(c *C) {
//given
padded:=[]byte{1,2,3,4,5,3,3,3}
//when
test:=RemovePkcs7(padded,8)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5})
}
func (s *TestSuite) TestRemovePkcs7OneBytePadding(c *C) {
//given
padded:=[]byte{1,2,3,4,5,1}
//when
test:=RemovePkcs7(padded,6)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5})
}
func (s *TestSuite) TestRemovePkcs7TrailingZeroByte(c *C) {
//given
padded:=[]byte{1,2,3,4,5,0}
//when
test:=RemovePkcs7(padded,6)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,0})
}
func (s *TestSuite) TestRemovePkcs7ExtraBlockPadding(c *C) {
//given
padded:=[]byte{1,2,3,4,5,5,5,5,5,5}
//when
test:=RemovePkcs7(padded,5)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5})
}
func (s *TestSuite) TestRemovePkcs7TrailingByteGreaterBlockSize(c *C) {
//given
padded:=[]byte{1,2,3,4,5,10}
//when
test:=RemovePkcs7(padded,6)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,10})
}
func (s *TestSuite) TestAddPkcs7(c *C) {
//given
in:=[]byte{1,2,3,4,5}
//when
test := AddPkcs7(in,8)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,3,3,3})
}
func (s *TestSuite) TestAddPkcs7OneBytePadding(c *C) {
//given
in:=[]byte{1,2,3,4,5}
//when
test := AddPkcs7(in,6)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,1})
}
func (s *TestSuite) TestAddPkcs7ExtraBlockPadding(c *C) {
//given
in:=[]byte{1,2,3,4,5,6,7,8}
//when
test := AddPkcs7(in,8)
//then
c.Assert(test, DeepEquals, []byte{1,2,3,4,5,6,7,8,8,8,8,8,8,8,8,8})
}