Skip to content

Commit

Permalink
Merge branch 'develop' into activate
Browse files Browse the repository at this point in the history
  • Loading branch information
jaytaph committed Mar 23, 2021
2 parents 9ee8318 + 868f6f2 commit 081dcc6
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 2 deletions.
1 change: 1 addition & 0 deletions internal/api/apikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ func (api *API) GetAPIKey(addrHash hash.Hash, ID string) (*key.APIKeyType, error
return nil, err
}

// @TODO: we use 200's even with error response body's
if statusCode < 200 || statusCode > 299 {
return nil, errNoSuccess
}
Expand Down
122 changes: 122 additions & 0 deletions internal/api/apikey_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright (c) 2021 BitMaelum Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package api

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/bitmaelum/bitmaelum-suite/pkg/hash"
"github.com/stretchr/testify/assert"
)

func TestAPI_GetAPIKey(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
assert.Equal(t, req.URL.String(), "/account/c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2/apikey/12345678")
_, _ = rw.Write([]byte("incorrect data"))
}))
defer server.Close()

api, err := NewAnonymous(server.URL, nil)
assert.NoError(t, err)

apiKey, err := api.GetAPIKey(hash.New("foobar"), "12345678")
assert.Error(t, err)
assert.Nil(t, apiKey)
}

func TestAPI_GetAPIKey_IncorrectStatusCode(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
assert.Equal(t, req.URL.String(), "/account/c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2/apikey/12345678")
rw.WriteHeader(500)
}))
defer server.Close()

api, err := NewAnonymous(server.URL, nil)
assert.NoError(t, err)

apiKey, err := api.GetAPIKey(hash.New("foobar"), "12345678")
assert.Error(t, err)
assert.Nil(t, apiKey)
}

func TestAPI_GetAPIKey_ErrorBody(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
assert.Equal(t, req.URL.String(), "/account/c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2/apikey/12345678")
rw.WriteHeader(200)
_, _ = rw.Write([]byte(`{"error": true, "status":"something happened"}`))
}))
defer server.Close()

api, err := NewAnonymous(server.URL, nil)
assert.NoError(t, err)

apiKey, err := api.GetAPIKey(hash.New("foobar"), "12345678")
assert.EqualError(t, err, "something happened")
assert.Nil(t, apiKey)
}

func TestAPI_GetAPIKey_Correct(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
assert.Equal(t, req.URL.String(), "/account/c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2/apikey/12345678")
rw.WriteHeader(200)
_, _ = rw.Write([]byte(`{"key": "12345678", "address_hash":"addresshash", "expires":"2006-01-02T15:04:05Z", "admin": false, "description":"description"}`))
}))
defer server.Close()

api, err := NewAnonymous(server.URL, nil)
assert.NoError(t, err)

apiKey, err := api.GetAPIKey(hash.New("foobar"), "12345678")
assert.NoError(t, err)
assert.NotNil(t, apiKey)
assert.Equal(t, apiKey.ID, "12345678")
assert.Equal(t, apiKey.AddressHash.String(), "addresshash")
assert.Equal(t, apiKey.Expires.String(), "2006-01-02 15:04:05 +0000 UTC")
assert.Equal(t, apiKey.Admin, false)
assert.Equal(t, apiKey.Desc, "description")
}

// // GetAPIKey gets a single key
// func (api *API) GetAPIKey(addrHash hash.Hash, ID string) (*key.APIKeyType, error) {
// url := fmt.Sprintf("/account/%s/apikey/%s", addrHash.String(), ID)
// body, statusCode, err := api.Get(url)
// if err != nil {
// return nil, err
// }
//
// if statusCode < 200 || statusCode > 299 {
// return nil, errNoSuccess
// }
//
// if isErrorResponse(body) {
// return nil, GetErrorFromResponse(body)
// }
//
// // Parse body for key
// k := &key.APIKeyType{}
// err = json.Unmarshal(body, &k)
// if err != nil {
// return nil, err
// }
//
// return k, nil
// }
38 changes: 38 additions & 0 deletions internal/editor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2021 BitMaelum Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package internal

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestFindEditor(t *testing.T) {
ed, err := FindEditor("edit.exe")
assert.NoError(t, err)
assert.Equal(t, "edit.exe", ed)

_ = os.Setenv("EDITOR", "foo-edit.exe")
ed, err = FindEditor("")
assert.NoError(t, err)
assert.Equal(t, "foo-edit.exe", ed)
}
10 changes: 10 additions & 0 deletions internal/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ import (
"github.com/stretchr/testify/assert"
)

func TestSetMockTime(t *testing.T) {
mockTimeNow := func() time.Time {
return time.Date(2010, 01, 01, 12, 34, 56, 0, time.UTC)
}

SetMockTime(mockTimeNow)

assert.Equal(t, "2010-01-01 12:34:56 +0000 UTC", TimeNow().String())
}

func TestTimeNow(t *testing.T) {
timeNow = func() time.Time {
return time.Date(2010, 01, 01, 12, 34, 56, 0, time.UTC)
Expand Down
13 changes: 12 additions & 1 deletion pkg/bmcrypto/aes_256_gcm.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ import (
"crypto/cipher"
"crypto/rand"
"encoding/json"
"errors"
"io"
)

// keyGenerator can be used for mocking purposes
var keyGenerator = randomKeyGenerator
var (
keyGenerator = randomKeyGenerator
)

const (
keySize = 32
Expand Down Expand Up @@ -158,6 +161,10 @@ func GetAesEncryptorReader(iv []byte, key []byte, r io.Reader) (io.Reader, error
return nil, err
}

if len(iv) != block.BlockSize() {
return nil, errors.New("IV is not of blocksize")
}

stream := cipher.NewCFBEncrypter(block, iv)
return &cipher.StreamReader{S: stream, R: r}, err
}
Expand All @@ -169,6 +176,10 @@ func GetAesDecryptorReader(iv []byte, key []byte, r io.Reader) (io.Reader, error
return nil, err
}

if len(iv) != block.BlockSize() {
return nil, errors.New("IV is not of blocksize")
}

stream := cipher.NewCFBDecrypter(block, iv)
return &cipher.StreamReader{S: stream, R: r}, err
}
51 changes: 50 additions & 1 deletion pkg/bmcrypto/aes_256_gcm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestEncryptDecryptJson(t *testing.T) {
Bar: 42,
}

// MOck nonce generator for encrypt
// Mock nonce generator for encrypt
keyGenerator = mockGenerator

// Key we are using to encrypt
Expand Down Expand Up @@ -167,3 +167,52 @@ func TestEncryptor(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "foo bar baz", string(b))
}

func TestGenerateIvAndKey(t *testing.T) {
iv, key, err := GenerateIvAndKey()
assert.NoError(t, err)
assert.Len(t, iv, 16)
assert.Len(t, key, 32)
}

func TestKeySizes(t *testing.T) {
iv := []byte{0xa4, 0xc0, 0x44, 0xc6, 0x3c, 0xdd, 0x9c, 0xe6, 0xae, 0x62, 0xd7, 0xf3, 0x84, 0x6a, 0x21, 0x2e}
key := []byte{0xf2, 0x3f, 0x97, 0x75, 0xc6, 0x40, 0xfa, 0x3e, 0xf7, 0x49, 0xc2, 0x7, 0x87, 0xcf, 0xfb, 0xac, 0x10, 0xb0, 0xc4, 0xcc, 0xf0, 0xee, 0xb3, 0xe9, 0xb8, 0x9e, 0x7c, 0xfb, 0xce, 0x58, 0xc2, 0x2f}

r1 := bytes.NewBufferString("foo bar baz")
_, err := GetAesEncryptorReader(iv, []byte{0xf2, 0x3f, 0x97, 0x75, 0xc6, 0x40, 0xfa, 0x3e, 0xf7}, r1)
assert.Error(t, err)

r1 = bytes.NewBufferString("foo bar baz")
_, err = GetAesEncryptorReader([]byte{0xf2, 0x3f, 0x97, 0x75, 0xc6, 0x40, 0xfa, 0x3e, 0xf7}, key, r1)
assert.Error(t, err)

r1 = bytes.NewBufferString("foo bar baz")
_, err = GetAesDecryptorReader(iv, []byte{0xf2, 0x3f, 0x97, 0x75, 0xc6, 0x40, 0xfa, 0x3e, 0xf7}, r1)
assert.Error(t, err)

r1 = bytes.NewBufferString("foo bar baz")
_, err = GetAesDecryptorReader([]byte{0xf2, 0x3f, 0x97, 0x75, 0xc6, 0x40, 0xfa, 0x3e, 0xf7}, key, r1)
assert.Error(t, err)
}

func TestCreateCatalogKey(t *testing.T) {
// MOck nonce generator for encrypt
keyGenerator = mockGenerator

b, err := CreateCatalogKey()
assert.NoError(t, err)
assert.Equal(t, []byte{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}, b)
}

func TestJSONEncryptDecrypt(t *testing.T) {
key := []byte{0xf2, 0x3f, 0x97, 0x75, 0xc6, 0x40, 0xfa, 0x3e, 0xf7, 0x49, 0xc2, 0x7, 0x87, 0xcf, 0xfb, 0xac, 0x10, 0xb0, 0xc4, 0xcc, 0xf0, 0xee, 0xb3, 0xe9, 0xb8, 0x9e, 0x7c, 0xfb, 0xce, 0x58, 0xc2, 0x2f}

b, err := JSONEncrypt(key, make(chan int))
assert.Error(t, err)
assert.Nil(t, b)

var v string
err = JSONDecrypt(key, []byte("foobar"), &v)
assert.Error(t, err)
}
66 changes: 66 additions & 0 deletions pkg/bmcrypto/key_ecdsa_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2021 BitMaelum Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package bmcrypto

import (
"crypto/elliptic"
"testing"

"github.com/stretchr/testify/assert"
)

func TestKeyEcdsa_NewEcdsaKey(t *testing.T) {
kt := NewEcdsaKey(elliptic.P224())

assert.False(t, kt.CanEncrypt())
assert.True(t, kt.CanKeyExchange())
assert.False(t, kt.CanDualKeyExchange())
assert.Equal(t, "ecdsa", kt.String())

assert.Equal(t, "ES384", kt.JWTSignMethod().Alg())

privKey, pubKey, err := GenerateKeyPair(NewEd25519Key())
assert.NoError(t, err)

msg := []byte("secretmessage")

b, txid, c, err := kt.Encrypt(*pubKey, msg)
assert.NoError(t, err)
assert.NotNil(t, txid)
assert.NotEqual(t, msg, b)
assert.Equal(t, "ecdsa+aes", c)

b, err = kt.Decrypt(*privKey, txid, b)
assert.NoError(t, err)
assert.Equal(t, b, msg)
}

func TestKeyEcdsa_DualKeyExchange(t *testing.T) {
kt := NewEcdsaKey(elliptic.P224())

_, pubKey, err := kt.GenerateKeyPair(randReader)
assert.NotNil(t, pubKey)
assert.NoError(t, err)

b, txid, err := kt.DualKeyExchange(*pubKey)
assert.Error(t, err, errCannotuseForDualKeyExchange)
assert.Nil(t, b)
assert.Nil(t, txid)
}

0 comments on commit 081dcc6

Please sign in to comment.