Add makefile with lint support (#4)

This commit is contained in:
Pedro Pombeiro 2018-08-21 11:18:46 +02:00 committed by GitHub
parent 47d1cda18c
commit c243ae5a66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 185 additions and 29 deletions

74
.golangci.yml Normal file
View File

@ -0,0 +1,74 @@
run:
concurrency: 4
deadline: 1m
issues-exit-code: 1
tests: true
# build-tags:
# - mytag
skip-dirs:
- static
skip-files:
- .*_mock.go
- jail/doc.go
output:
format: colored-line-number
print-issued-lines: true
print-linter-name: true
linters-settings:
errcheck:
check-type-assertions: false
check-blank: false
govet:
check-shadowing: false
golint:
min-confidence: 0.8
gofmt:
simplify: true
gocyclo:
min-complexity: 16
maligned:
suggest-new: true
dupl:
threshold: 50
goconst:
min-len: 3
min-occurrences: 2
# depguard:
# list-type: blacklist
# include-go-root: false
# packages:
# - github.com/davecgh/go-spew/spew
linters:
disable-all: true
enable:
- deadcode
#- depguard
- errcheck
- gas
- goconst
- gocyclo
- gofmt
- golint
- govet
- ineffassign
- interfacer
- megacheck
- misspell
- structcheck
- typecheck
- unconvert
- varcheck
fast: false
issues:
exclude:
- "composite literal uses unkeyed fields" # govet
# exclude-use-default: true
# max-per-linter: 0
# max-same: 0
# new: false
# new-from-rev: ""
# new-from-patch: ""

59
Makefile Normal file
View File

@ -0,0 +1,59 @@
.PHONY: help
help: ##@other Show this help
@perl -e '$(HELP_FUN)' $(MAKEFILE_LIST)
ifndef GOPATH
$(error GOPATH not set. Please set GOPATH and make sure status-go is located at $$GOPATH/src/github.com/status-im/status-go. \
For more information about the GOPATH environment variable, see https://golang.org/doc/code.html#GOPATH)
endif
EXPECTED_PATH=$(shell go env GOPATH)/src/github.com/status-im/doubleratchet
ifneq ($(CURDIR),$(EXPECTED_PATH))
define NOT_IN_GOPATH_ERROR
Current dir is $(CURDIR), which seems to be different from your GOPATH.
Please, build status-go from GOPATH for proper build.
GOPATH = $(shell go env GOPATH)
Current dir = $(CURDIR)
Expected dir = $(EXPECTED_PATH))
See https://golang.org/doc/code.html#GOPATH for more info
endef
$(error $(NOT_IN_GOPATH_ERROR))
endif
GOBIN=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))build/bin
GIT_COMMIT := $(shell git rev-parse --short HEAD)
# This is a code for automatic help generator.
# It supports ANSI colors and categories.
# To add new item into help output, simply add comments
# starting with '##'. To add category, use @category.
GREEN := $(shell echo "\e[32m")
WHITE := $(shell echo "\e[37m")
YELLOW := $(shell echo "\e[33m")
RESET := $(shell echo "\e[0m")
HELP_FUN = \
%help; \
while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z0-9\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \
print "Usage: make [target]\n\n"; \
for (sort keys %help) { \
print "${WHITE}$$_:${RESET}\n"; \
for (@{$$help{$$_}}) { \
$$sep = " " x (32 - length $$_->[0]); \
print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \
}; \
print "\n"; \
}
setup: lint-install ##@other Prepare project for first build
lint-install:
@# The following installs a specific version of golangci-lint, which is appropriate for a CI server to avoid different results from build to build
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $(GOPATH)/bin v1.9.1
lint: ##@other Run linter
@echo "lint"
@golangci-lint run ./...

View File

@ -1,8 +1,9 @@
package doubleratchet
import (
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
var chainKey = Key{0xeb, 0x8, 0x10, 0x7c, 0x33, 0x54, 0x0, 0x20, 0xe9, 0x4f, 0x6c, 0x84, 0xe4, 0x39, 0x50, 0x5a, 0x2f, 0x60, 0xbe, 0x81, 0xa, 0x78, 0x8b, 0xeb, 0x1e, 0x2c, 0x9, 0x8d, 0x4b, 0x4d, 0xc1, 0x40}

View File

@ -27,7 +27,7 @@ type DHPair interface {
PublicKey() Key
}
// Keys is any 32-byte key. It's created for the possibility of pretty hex output.
// Key is any 32-byte key. It's created for the possibility of pretty hex output.
type Key [32]byte
// Stringer interface compliance.

View File

@ -1,8 +1,9 @@
package doubleratchet
import (
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
func TestKey_String(t *testing.T) {

View File

@ -19,7 +19,7 @@ import (
// see function comments for details.
type DefaultCrypto struct{}
// See the Crypto interface.
// GenerateDH creates a new Diffie-Hellman key pair.
func (c DefaultCrypto) GenerateDH() (DHPair, error) {
var privKey [32]byte
if _, err := io.ReadFull(rand.Reader, privKey[:]); err != nil {
@ -37,7 +37,8 @@ func (c DefaultCrypto) GenerateDH() (DHPair, error) {
}, nil
}
// See the Crypto interface.
// DH returns the output from the Diffie-Hellman calculation between
// the private key from the DH key pair dhPair and the DH public key dbPub.
func (c DefaultCrypto) DH(dhPair DHPair, dhPub Key) Key {
var (
dhOut [32]byte
@ -48,7 +49,8 @@ func (c DefaultCrypto) DH(dhPair DHPair, dhPub Key) Key {
return dhOut
}
// See the Crypto interface.
// KdfRK returns a pair (32-byte root key, 32-byte chain key) as the output of applying
// a KDF keyed by a 32-byte root key rk to a Diffie-Hellman output dhOut.
func (c DefaultCrypto) KdfRK(rk, dhOut Key) (rootKey, chainKey, headerKey Key) {
var (
r = hkdf.New(sha256.New, dhOut[:], rk[:], []byte("rsZUpEuXUqqwXBvSy3EcievAh4cMj6QL"))
@ -64,7 +66,8 @@ func (c DefaultCrypto) KdfRK(rk, dhOut Key) (rootKey, chainKey, headerKey Key) {
return
}
// See the Crypto interface.
// KdfCK returns a pair (32-byte chain key, 32-byte message key) as the output of applying
// a KDF keyed by a 32-byte chain key ck to some constant.
func (c DefaultCrypto) KdfCK(ck Key) (chainKey Key, msgKey Key) {
const (
ckInput = 15
@ -73,11 +76,11 @@ func (c DefaultCrypto) KdfCK(ck Key) (chainKey Key, msgKey Key) {
h := hmac.New(sha256.New, ck[:])
h.Write([]byte{ckInput})
_, _ = h.Write([]byte{ckInput})
copy(chainKey[:], h.Sum(nil))
h.Reset()
h.Write([]byte{mkInput})
_, _ = h.Write([]byte{mkInput})
copy(msgKey[:], h.Sum(nil))
return chainKey, msgKey
@ -101,7 +104,7 @@ func (c DefaultCrypto) Encrypt(mk Key, plaintext, ad []byte) []byte {
return append(ciphertext, c.computeSignature(authKey[:], ciphertext, ad)...)
}
// See the Crypto interface.
// Decrypt returns the AEAD decryption of ciphertext with message key mk.
func (c DefaultCrypto) Decrypt(mk Key, authCiphertext, ad []byte) ([]byte, error) {
var (
l = len(authCiphertext)
@ -147,8 +150,8 @@ func (c DefaultCrypto) deriveEncKeys(mk Key) (encKey Key, authKey Key, iv [16]by
func (c DefaultCrypto) computeSignature(authKey, ciphertext, associatedData []byte) []byte {
h := hmac.New(sha256.New, authKey)
h.Write(associatedData)
h.Write(ciphertext)
_, _ = h.Write(associatedData)
_, _ = h.Write(ciphertext)
return h.Sum(nil)
}

View File

@ -2,8 +2,9 @@ package doubleratchet
import (
"fmt"
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
func TestDhPair(t *testing.T) {

View File

@ -1,8 +1,9 @@
package doubleratchet
import (
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
var (
@ -28,7 +29,8 @@ func TestKeysStorageInMemory_Put(t *testing.T) {
ks := &KeysStorageInMemory{}
// Act and assert.
ks.Put(pubKey1, 0, mk)
err := ks.Put(pubKey1, 0, mk)
require.NoError(t, err)
}
func TestKeysStorageInMemory_Count(t *testing.T) {
@ -58,12 +60,15 @@ func TestKeysStorageInMemory_Flow(t *testing.T) {
t.Run("delete non-existent pubkey", func(t *testing.T) {
// Act and assert.
ks.DeletePk(pubKey1)
err := ks.DeletePk(pubKey1)
require.NoError(t, err)
})
t.Run("put and get existing", func(t *testing.T) {
// Act.
ks.Put(pubKey1, 0, mk)
err := ks.Put(pubKey1, 0, mk)
require.NoError(t, err)
k, ok, err := ks.Get(pubKey1, 0)
// Assert.
@ -124,7 +129,9 @@ func TestKeysStorageInMemory_Flow(t *testing.T) {
t.Run("delete existing message key", func(t *testing.T) {
// Act.
ks.DeleteMk(pubKey1, 0)
err := ks.DeleteMk(pubKey1, 0)
require.NoError(t, err)
cnt, err := ks.Count(pubKey1)
// Assert.

View File

@ -1,8 +1,9 @@
package doubleratchet
import (
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
func TestMessageHeader_EncodeAndDecode(t *testing.T) {

View File

@ -6,6 +6,7 @@ import "fmt"
type option func(*State) error
// WithMaxSkip specifies the maximum number of skipped message in a single chain.
// nolint: golint
func WithMaxSkip(n int) option {
return func(s *State) error {
if n < 0 {
@ -17,6 +18,7 @@ func WithMaxSkip(n int) option {
}
// WithMaxKeep specifies the maximum number of ratchet steps before a message is deleted.
// nolint: golint
func WithMaxKeep(n int) option {
return func(s *State) error {
if n < 0 {
@ -28,6 +30,7 @@ func WithMaxKeep(n int) option {
}
// WithKeysStorage replaces the default keys storage with the specified.
// nolint: golint
func WithKeysStorage(ks KeysStorage) option {
return func(s *State) error {
if ks == nil {
@ -39,6 +42,7 @@ func WithKeysStorage(ks KeysStorage) option {
}
// WithCrypto replaces the default cryptographic supplement with the specified.
// nolint: golint
func WithCrypto(c Crypto) option {
return func(s *State) error {
if c == nil {

View File

@ -1,8 +1,9 @@
package doubleratchet
import (
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
func TestWithMaxSkip_OK(t *testing.T) {

View File

@ -114,7 +114,7 @@ func (s *sessionState) RatchetDecrypt(m Message, ad []byte) ([]byte, error) {
if err != nil {
return nil, fmt.Errorf("can't decrypt skipped message: %s", err)
}
s.MkSkipped.DeleteMk(m.Header.DH, uint(m.Header.N))
_ = s.MkSkipped.DeleteMk(m.Header.DH, uint(m.Header.N))
return plaintext, nil
}

View File

@ -79,7 +79,7 @@ func (s *sessionHE) RatchetDecrypt(m MessageHE, ad []byte) ([]byte, error) {
var (
// All changes must be applied on a different session object, so that this session won't be modified nor left in a dirty session.
sc State = s.State
sc = s.State
skippedKeys1 []skippedKey
skippedKeys2 []skippedKey
@ -103,9 +103,11 @@ func (s *sessionHE) RatchetDecrypt(m MessageHE, ad []byte) ([]byte, error) {
return nil, fmt.Errorf("can't decrypt: %s", err)
}
s.applyChanges(sc, append(skippedKeys1, skippedKeys2...))
if err = s.applyChanges(sc, append(skippedKeys1, skippedKeys2...)); err != nil {
return nil, fmt.Errorf("failed to apply changes: %s", err)
}
if step {
s.deleteSkippedKeys(s.HKr)
_ = s.deleteSkippedKeys(s.HKr)
}
return plaintext, nil
@ -146,7 +148,7 @@ func (s *sessionHE) trySkippedMessages(m MessageHE, ad []byte) ([]byte, error) {
if err != nil {
return nil, fmt.Errorf("can't decrypt skipped message: %s", err)
}
s.MkSkipped.DeleteMk(hk, n)
_ = s.MkSkipped.DeleteMk(hk, n)
return plaintext, nil
}
}

View File

@ -2,14 +2,14 @@ package doubleratchet
import (
"fmt"
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
var (
sharedHka = Key{0xbd, 0x29, 0x18, 0xcb, 0x18, 0x6c, 0x26, 0x32, 0xd5, 0x82, 0x41, 0x2d, 0x11, 0xa4, 0x55, 0x87, 0x1e, 0x5b, 0xa3, 0xb5, 0x5a, 0x6d, 0xe1, 0x97, 0xde, 0xf7, 0x5e, 0xc3, 0xf2, 0xec, 0x1d, 0xd}
sharedNhkb = Key{0x32, 0x89, 0x3a, 0xed, 0x4b, 0xf0, 0xbf, 0xc1, 0xa5, 0xa9, 0x53, 0x73, 0x5b, 0xf9, 0x76, 0xce, 0x70, 0x8e, 0xe1, 0xa, 0xed, 0x98, 0x1d, 0xe3, 0xb4, 0xe9, 0xa9, 0x88, 0x54, 0x94, 0xaf, 0x23}
k = Key{0x4b, 0x22, 0x7f, 0x60, 0x7b, 0x1e, 0x76, 0xb6, 0xf5, 0xf2, 0x72, 0x22, 0xf3, 0x14, 0xaf, 0x69, 0x60, 0xca, 0xd4, 0x26, 0x51, 0x88, 0xc9, 0xd, 0xbf, 0x23, 0x42, 0xfd, 0x1a, 0x30, 0xad, 0x4b}
)
func TestNewHE(t *testing.T) {

View File

@ -2,8 +2,9 @@ package doubleratchet
import (
"fmt"
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
func TestNew(t *testing.T) {

View File

@ -1,8 +1,9 @@
package doubleratchet
import (
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
var (