From 5c601cedd2b85dbd2563e1916b91358f3ab91435 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 17:04:10 +0100 Subject: [PATCH 01/14] nacl functions --- crypto/cipher/nacl/nacl.go | 38 +++++++++++ crypto/cipher/nacl/nacl_test.go | 113 ++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 crypto/cipher/nacl/nacl.go create mode 100644 crypto/cipher/nacl/nacl_test.go diff --git a/crypto/cipher/nacl/nacl.go b/crypto/cipher/nacl/nacl.go new file mode 100644 index 000000000..fe7666886 --- /dev/null +++ b/crypto/cipher/nacl/nacl.go @@ -0,0 +1,38 @@ +package nacl + +import ( + "errors" + "io" + + "golang.org/x/crypto/nacl/secretbox" +) + +const nonceSize = 24 + +func easyOpen(box, key []byte) ([]byte, error) { + if len(box) < nonceSize { + return nil, errors.New("secretbox: message too short") + } + decryptNonce := new([nonceSize]byte) + copy(decryptNonce[:], box[:nonceSize]) + + var secretKey [32]byte + copy(secretKey[:], key) + + decrypted, ok := secretbox.Open([]byte{}, box[nonceSize:], decryptNonce, &secretKey) + if !ok { + return nil, errors.New("secretbox: could not decrypt data with private key") + } + return decrypted, nil +} + +func easySeal(message, key []byte, rand io.Reader) ([]byte, error) { + nonce := new([nonceSize]byte) + if _, err := rand.Read(nonce[:]); err != nil { + return nil, err + } + + var secretKey [32]byte + copy(secretKey[:], key) + return secretbox.Seal(nonce[:], message, nonce, &secretKey), nil +} diff --git a/crypto/cipher/nacl/nacl_test.go b/crypto/cipher/nacl/nacl_test.go new file mode 100644 index 000000000..89c97de8d --- /dev/null +++ b/crypto/cipher/nacl/nacl_test.go @@ -0,0 +1,113 @@ +package nacl + +import ( + "bytes" + "io" + "testing" + "testing/iotest" + + "github.com/mailchain/mailchain/crypto/ed25519/ed25519test" + "github.com/stretchr/testify/assert" +) + +func Test_easySeal(t *testing.T) { + assert := assert.New(t) + type args struct { + message []byte + key []byte + rand io.Reader + } + tests := []struct { + name string + args args + want []byte + wantErr bool + }{ + { + "success-charlotte", + args{ + []byte("message"), + ed25519test.CharlottePublicKey.Bytes(), + bytes.NewReader([]byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")), + }, + []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, + false, + }, + { + "err-rand", + args{ + []byte("message"), + ed25519test.CharlottePublicKey.Bytes(), + iotest.DataErrReader(bytes.NewReader(nil)), + }, + nil, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := easySeal(tt.args.message, tt.args.key, tt.args.rand) + if (err != nil) != tt.wantErr { + t.Errorf("easySeal() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !assert.Equal(tt.want, got) { + t.Errorf("easySeal() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_easyOpen(t *testing.T) { + assert := assert.New(t) + type args struct { + box []byte + key []byte + } + tests := []struct { + name string + args args + want []byte + wantErr bool + }{ + { + "success", + args{ + []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, + ed25519test.CharlottePrivateKey.Bytes()[32:], + }, + []byte("message"), + false, + }, + { + "err-nonce-size", + args{ + []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, + ed25519test.CharlottePrivateKey.Bytes()[32:], + }, + nil, + true, + }, + { + "err-input", + args{ + []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, + ed25519test.SofiaPrivateKey.Bytes()[32:], + }, + nil, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := easyOpen(tt.args.box, tt.args.key) + if (err != nil) != tt.wantErr { + t.Errorf("easyOpen() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !assert.Equal(tt.want, got) { + t.Errorf("easyOpen() = %v, want %v", got, tt.want) + } + }) + } +} From 810c4535ce12446590e3d0e824b5b507da66eaf5 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 19:56:53 +0100 Subject: [PATCH 02/14] return just the pk bytes --- crypto/ed25519/ed25519test/keys.go | 4 +-- crypto/ed25519/keys.go | 7 ++-- crypto/ed25519/private.go | 16 +++------ crypto/ed25519/private_test.go | 54 ++---------------------------- 4 files changed, 10 insertions(+), 71 deletions(-) diff --git a/crypto/ed25519/ed25519test/keys.go b/crypto/ed25519/ed25519test/keys.go index 8225317ff..161e42174 100644 --- a/crypto/ed25519/ed25519test/keys.go +++ b/crypto/ed25519/ed25519test/keys.go @@ -16,14 +16,14 @@ var CharlottePublicKey crypto.PublicKey // nolint: gochecknoglobals // nolint: gochecknoinits func init() { var err error - SofiaPrivateKey, err = ed25519.PrivateKeyFromSeed(testutil.MustHexDecodeString("0d9b4a3c10721991c6b806f0f343535dc2b46c74bece50a0a0d6b9f0070d3157")) + SofiaPrivateKey, err = ed25519.PrivateKeyFromBytes(testutil.MustHexDecodeString("0d9b4a3c10721991c6b806f0f343535dc2b46c74bece50a0a0d6b9f0070d3157")) if err != nil { log.Fatal(err) } SofiaPublicKey = SofiaPrivateKey.PublicKey() - CharlottePrivateKey, err = ed25519.PrivateKeyFromSeed(testutil.MustHexDecodeString("39d4c97d6a7f9e3306a2b5aae604ee67ec8b1387fffb39128fc055656cff05bb")) + CharlottePrivateKey, err = ed25519.PrivateKeyFromBytes(testutil.MustHexDecodeString("39d4c97d6a7f9e3306a2b5aae604ee67ec8b1387fffb39128fc055656cff05bb")) if err != nil { log.Fatal(err) } diff --git a/crypto/ed25519/keys.go b/crypto/ed25519/keys.go index e71c75df8..0c06f1311 100644 --- a/crypto/ed25519/keys.go +++ b/crypto/ed25519/keys.go @@ -9,11 +9,9 @@ import ( func sofiaSeed() []byte { return testutil.MustHexDecodeString("0d9b4a3c10721991c6b806f0f343535dc2b46c74bece50a0a0d6b9f0070d3157") } - func sofiaPrivateKeyBytes() []byte { // nolint: deadcode - return []byte{0xd, 0x9b, 0x4a, 0x3c, 0x10, 0x72, 0x19, 0x91, 0xc6, 0xb8, 0x6, 0xf0, 0xf3, 0x43, 0x53, 0x5d, 0xc2, 0xb4, 0x6c, 0x74, 0xbe, 0xce, 0x50, 0xa0, 0xa0, 0xd6, 0xb9, 0xf0, 0x7, 0xd, 0x31, 0x57, 0x72, 0x3c, 0xaa, 0x23, 0xa5, 0xb5, 0x11, 0xaf, 0x5a, 0xd7, 0xb7, 0xef, 0x60, 0x76, 0xe4, 0x14, 0xab, 0x7e, 0x75, 0xa9, 0xdc, 0x91, 0xe, 0xa6, 0xe, 0x41, 0x7a, 0x2b, 0x77, 0xa, 0x56, 0x71} // nolint: lll + return []byte{0x72, 0x3c, 0xaa, 0x23, 0xa5, 0xb5, 0x11, 0xaf, 0x5a, 0xd7, 0xb7, 0xef, 0x60, 0x76, 0xe4, 0x14, 0xab, 0x7e, 0x75, 0xa9, 0xdc, 0x91, 0xe, 0xa6, 0xe, 0x41, 0x7a, 0x2b, 0x77, 0xa, 0x56, 0x71} // nolint: lll } - func sofiaPublicKey() PublicKey { // nolint: deadcode return PublicKey{key: []byte{0x72, 0x3c, 0xaa, 0x23, 0xa5, 0xb5, 0x11, 0xaf, 0x5a, 0xd7, 0xb7, 0xef, 0x60, 0x76, 0xe4, 0x14, 0xab, 0x7e, 0x75, 0xa9, 0xdc, 0x91, 0xe, 0xa6, 0xe, 0x41, 0x7a, 0x2b, 0x77, 0xa, 0x56, 0x71}} // nolint: lll } @@ -31,9 +29,8 @@ func charlotteSeed() []byte { // nolint: deadcode } func charlottePrivateKeyBytes() []byte { // nolint: deadcode - return []byte{0x39, 0xd4, 0xc9, 0x7d, 0x6a, 0x7f, 0x9e, 0x33, 0x6, 0xa2, 0xb5, 0xaa, 0xe6, 0x4, 0xee, 0x67, 0xec, 0x8b, 0x13, 0x87, 0xff, 0xfb, 0x39, 0x12, 0x8f, 0xc0, 0x55, 0x65, 0x6c, 0xff, 0x5, 0xbb, 0x2e, 0x32, 0x2f, 0x87, 0x40, 0xc6, 0x1, 0x72, 0x11, 0x1a, 0xc8, 0xea, 0xdc, 0xdd, 0xa2, 0x51, 0x2f, 0x90, 0xd0, 0x6d, 0xe, 0x50, 0x3e, 0xf1, 0x89, 0x97, 0x9a, 0x15, 0x9b, 0xec, 0xe1, 0xe8} // nolint: lll + return []byte{0x2e, 0x32, 0x2f, 0x87, 0x40, 0xc6, 0x1, 0x72, 0x11, 0x1a, 0xc8, 0xea, 0xdc, 0xdd, 0xa2, 0x51, 0x2f, 0x90, 0xd0, 0x6d, 0xe, 0x50, 0x3e, 0xf1, 0x89, 0x97, 0x9a, 0x15, 0x9b, 0xec, 0xe1, 0xe8} // nolint: lll } - func charlottePublicKey() PublicKey { // nolint: deadcode return PublicKey{key: []byte{0x2e, 0x32, 0x2f, 0x87, 0x40, 0xc6, 0x1, 0x72, 0x11, 0x1a, 0xc8, 0xea, 0xdc, 0xdd, 0xa2, 0x51, 0x2f, 0x90, 0xd0, 0x6d, 0xe, 0x50, 0x3e, 0xf1, 0x89, 0x97, 0x9a, 0x15, 0x9b, 0xec, 0xe1, 0xe8}} // nolint: lll } diff --git a/crypto/ed25519/private.go b/crypto/ed25519/private.go index 7916b5d6c..ad77bb9f2 100644 --- a/crypto/ed25519/private.go +++ b/crypto/ed25519/private.go @@ -13,7 +13,7 @@ type PrivateKey struct { // Bytes returns the byte representation of the private key func (pk PrivateKey) Bytes() []byte { - return pk.key + return pk.key[32:] } // PublicKey return the public key that is derived from the private key @@ -23,18 +23,10 @@ func (pk PrivateKey) PublicKey() crypto.PublicKey { return PublicKey{key: publicKey} } -// PrivateKeyFromBytes get a private key from []byte +// PrivateKeyFromBytes get a private key from seed []byte func PrivateKeyFromBytes(pk []byte) (*PrivateKey, error) { - if len(pk) != ed25519.PrivateKeySize { - return nil, errors.Errorf("ed25519: bad private key length: %v", len(pk)) - } - return &PrivateKey{key: pk}, nil -} - -// PrivateKeyFromBytes get a private key from []byte -func PrivateKeyFromSeed(seed []byte) (*PrivateKey, error) { - if l := len(seed); l != ed25519.SeedSize { + if l := len(pk); l != ed25519.SeedSize { return nil, errors.Errorf("ed25519: bad seed length: %v", l) } - return &PrivateKey{key: ed25519.NewKeyFromSeed(seed)}, nil + return &PrivateKey{key: ed25519.NewKeyFromSeed(pk)}, nil } diff --git a/crypto/ed25519/private_test.go b/crypto/ed25519/private_test.go index beaa61a97..d6f6cd70d 100644 --- a/crypto/ed25519/private_test.go +++ b/crypto/ed25519/private_test.go @@ -9,56 +9,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestPrivateKeyFromSeed(t *testing.T) { - assert := assert.New(t) - type args struct { - seed []byte - } - tests := []struct { - name string - args args - want *PrivateKey - wantErr bool - }{ - { - "success-sofia", - args{ - sofiaSeed(), - }, - sofiaPrivateKey(), - false, - }, - { - "success-charlotte", - args{ - charlotteSeed(), - }, - charlottePrivateKey(), - false, - }, - { - "err-len", - args{ - testutil.MustHexDecodeString("39d4c9"), - }, - nil, - true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := PrivateKeyFromSeed(tt.args.seed) - if (err != nil) != tt.wantErr { - t.Errorf("PrivateKeyFromSeed() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !assert.Equal(tt.want, got) { - t.Errorf("PrivateKeyFromSeed() = %v, want %v", got, tt.want) - } - }) - } -} - func TestPrivateKey_Bytes(t *testing.T) { assert := assert.New(t) tests := []struct { @@ -105,7 +55,7 @@ func TestPrivateKeyFromBytes(t *testing.T) { { "success-sofia", args{ - sofiaPrivateKeyBytes(), + sofiaSeed(), }, sofiaPrivateKey(), false, @@ -113,7 +63,7 @@ func TestPrivateKeyFromBytes(t *testing.T) { { "success-charlotte", args{ - charlottePrivateKeyBytes(), + charlotteSeed(), }, charlottePrivateKey(), false, From 8d023602b49d6028b671bd4cc0285336ccc8f448 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 19:57:11 +0100 Subject: [PATCH 03/14] implement nacl cipher --- crypto/cipher/nacl/decrypter.go | 21 ++++++ crypto/cipher/nacl/decrypter_test.go | 83 +++++++++++++++++++++ crypto/cipher/nacl/encrypter.go | 38 ++++++++++ crypto/cipher/nacl/encrypter_test.go | 105 +++++++++++++++++++++++++++ crypto/cipher/nacl/end_end_test.go | 62 ++++++++++++++++ crypto/cipher/nacl/nacl.go | 11 ++- crypto/cipher/nacl/nacl_test.go | 16 +++- 7 files changed, 330 insertions(+), 6 deletions(-) create mode 100644 crypto/cipher/nacl/decrypter.go create mode 100644 crypto/cipher/nacl/decrypter_test.go create mode 100644 crypto/cipher/nacl/encrypter.go create mode 100644 crypto/cipher/nacl/encrypter_test.go create mode 100644 crypto/cipher/nacl/end_end_test.go diff --git a/crypto/cipher/nacl/decrypter.go b/crypto/cipher/nacl/decrypter.go new file mode 100644 index 000000000..de5fc557e --- /dev/null +++ b/crypto/cipher/nacl/decrypter.go @@ -0,0 +1,21 @@ +package nacl + +import ( + "github.com/mailchain/mailchain/crypto" + "github.com/mailchain/mailchain/crypto/cipher" +) + +// NewDecrypter create a new decrypter attaching the private key to it +func NewDecrypter(privateKey crypto.PrivateKey) Decrypter { + return Decrypter{privateKey: privateKey} +} + +// Decrypter will decrypt data using AES256CBC method +type Decrypter struct { + privateKey crypto.PrivateKey +} + +// Decrypt data using recipient private key with AES in CBC mode. +func (d Decrypter) Decrypt(data cipher.EncryptedContent) (cipher.PlainContent, error) { + return easyOpen(data, d.privateKey.Bytes()) +} diff --git a/crypto/cipher/nacl/decrypter_test.go b/crypto/cipher/nacl/decrypter_test.go new file mode 100644 index 000000000..9a91005c5 --- /dev/null +++ b/crypto/cipher/nacl/decrypter_test.go @@ -0,0 +1,83 @@ +package nacl + +import ( + "reflect" + "testing" + + "github.com/mailchain/mailchain/crypto" + "github.com/mailchain/mailchain/crypto/cipher" + "github.com/mailchain/mailchain/crypto/ed25519/ed25519test" + "github.com/stretchr/testify/assert" +) + +func TestNewDecrypter(t *testing.T) { + type args struct { + privateKey crypto.PrivateKey + } + tests := []struct { + name string + args args + want Decrypter + }{ + { + "success", + args{ + ed25519test.CharlottePrivateKey, + }, + Decrypter{ + privateKey: ed25519test.CharlottePrivateKey, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NewDecrypter(tt.args.privateKey); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewDecrypter() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDecrypter_Decrypt(t *testing.T) { + assert := assert.New(t) + type fields struct { + privateKey crypto.PrivateKey + } + type args struct { + data cipher.EncryptedContent + } + tests := []struct { + name string + fields fields + args args + want cipher.PlainContent + wantErr bool + }{ + { + "success-charlotte", + fields{ + ed25519test.CharlottePrivateKey, + }, + args{ + cipher.EncryptedContent{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, + }, + cipher.PlainContent{0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65}, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d := Decrypter{ + privateKey: tt.fields.privateKey, + } + got, err := d.Decrypt(tt.args.data) + if (err != nil) != tt.wantErr { + t.Errorf("Decrypter.Decrypt() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !assert.Equal(tt.want, got) { + t.Errorf("Decrypter.Decrypt() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/crypto/cipher/nacl/encrypter.go b/crypto/cipher/nacl/encrypter.go new file mode 100644 index 000000000..171843f4c --- /dev/null +++ b/crypto/cipher/nacl/encrypter.go @@ -0,0 +1,38 @@ +package nacl + +import ( + "crypto/rand" + "io" + + "github.com/mailchain/mailchain/crypto" + "github.com/mailchain/mailchain/crypto/cipher" + "github.com/mailchain/mailchain/crypto/ed25519" + "github.com/pkg/errors" +) + +// NewEncrypter create a new encrypter with crypto rand for reader +func NewEncrypter() Encrypter { + return Encrypter{rand: rand.Reader} +} + +// Encrypter will encrypt data using AES256CBC method +type Encrypter struct { + rand io.Reader +} + +func (e Encrypter) Encrypt(recipientPublicKey crypto.PublicKey, message cipher.PlainContent) (cipher.EncryptedContent, error) { + if err := validatePublicKeyType(recipientPublicKey); err != nil { + return nil, err + } + + return easySeal(message, recipientPublicKey.Bytes(), e.rand) +} + +func validatePublicKeyType(recipientPublicKey crypto.PublicKey) error { + switch recipientPublicKey.(type) { + case ed25519.PublicKey: + return nil + default: + return errors.Errorf("invalid public key type for nacl encryption") + } +} diff --git a/crypto/cipher/nacl/encrypter_test.go b/crypto/cipher/nacl/encrypter_test.go new file mode 100644 index 000000000..3741d7dbb --- /dev/null +++ b/crypto/cipher/nacl/encrypter_test.go @@ -0,0 +1,105 @@ +package nacl + +import ( + "bytes" + "io" + "testing" + + "github.com/mailchain/mailchain/crypto" + "github.com/mailchain/mailchain/crypto/cipher" + "github.com/mailchain/mailchain/crypto/ed25519" + "github.com/mailchain/mailchain/crypto/ed25519/ed25519test" + "github.com/mailchain/mailchain/crypto/secp256k1" + "github.com/stretchr/testify/assert" +) + +func Test_validatePublicKeyType(t *testing.T) { + type args struct { + recipientPublicKey crypto.PublicKey + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + "ed25519", + args{ + ed25519.PublicKey{}, + }, + false, + }, + { + "not-supported", + args{ + secp256k1.PublicKey{}, + }, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := validatePublicKeyType(tt.args.recipientPublicKey); (err != nil) != tt.wantErr { + t.Errorf("validatePublicKeyType() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestEncrypter_Encrypt(t *testing.T) { + assert := assert.New(t) + type fields struct { + rand io.Reader + } + type args struct { + recipientPublicKey crypto.PublicKey + message cipher.PlainContent + } + tests := []struct { + name string + fields fields + args args + want cipher.EncryptedContent + wantErr bool + }{ + { + "success-charlotte", + fields{ + bytes.NewReader([]byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")), + }, + args{ + ed25519test.CharlottePublicKey, + []byte("message"), + }, + cipher.EncryptedContent{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, + false, + }, + { + "err-key-type", + fields{ + nil, + }, + args{ + secp256k1.PublicKey{}, + []byte("message"), + }, + nil, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := Encrypter{ + rand: tt.fields.rand, + } + got, err := e.Encrypt(tt.args.recipientPublicKey, tt.args.message) + if (err != nil) != tt.wantErr { + t.Errorf("Encrypter.Encrypt() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !assert.Equal(tt.want, got) { + t.Errorf("Encrypter.Encrypt() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/crypto/cipher/nacl/end_end_test.go b/crypto/cipher/nacl/end_end_test.go new file mode 100644 index 000000000..f189f3a9b --- /dev/null +++ b/crypto/cipher/nacl/end_end_test.go @@ -0,0 +1,62 @@ +package nacl + +import ( + "testing" + + "github.com/mailchain/mailchain/crypto" + "github.com/mailchain/mailchain/crypto/ed25519/ed25519test" + "github.com/stretchr/testify/assert" +) + +func TestEncryptDecrypt(t *testing.T) { + assert := assert.New(t) + cases := []struct { + name string + recipientPublicKey crypto.PublicKey + recipientPrivateKey crypto.PrivateKey + data []byte + err error + }{ + { + "to-sofia-short-text", + ed25519test.SofiaPublicKey, + ed25519test.SofiaPrivateKey, + []byte("Hi Sofia"), + nil, + }, + { + "to-sofia-medium-text", + ed25519test.SofiaPublicKey, + ed25519test.SofiaPrivateKey, + []byte("Hi Sofia, this is a little bit of a longer message to make sure there are no problems"), + nil, + }, + { + "to-charlotte-short-text", + ed25519test.CharlottePublicKey, + ed25519test.CharlottePrivateKey, + []byte("Hi Charlotte"), + nil, + }, + { + "to-charlotte-medium-text", + ed25519test.CharlottePublicKey, + ed25519test.CharlottePrivateKey, + []byte("Hi Charlotte, this is a little bit of a longer message to make sure there are no problems"), + nil, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + encrypted, err := NewEncrypter().Encrypt(tc.recipientPublicKey, tc.data) + assert.Equal(tc.err, err) + assert.NotNil(encrypted) + decrypter := Decrypter{tc.recipientPrivateKey} + + decrypted, err := decrypter.Decrypt(encrypted) + assert.Equal(tc.err, err) + assert.Equal(tc.data, []byte(decrypted)) + }) + } +} diff --git a/crypto/cipher/nacl/nacl.go b/crypto/cipher/nacl/nacl.go index fe7666886..6c23d4fdb 100644 --- a/crypto/cipher/nacl/nacl.go +++ b/crypto/cipher/nacl/nacl.go @@ -1,23 +1,30 @@ package nacl import ( + "encoding/hex" "errors" + "fmt" "io" "golang.org/x/crypto/nacl/secretbox" ) const nonceSize = 24 +const secretKeySize = 32 func easyOpen(box, key []byte) ([]byte, error) { + if len(key) != secretKeySize { + return nil, errors.New("secretbox: key length must be 32") + } if len(box) < nonceSize { return nil, errors.New("secretbox: message too short") } decryptNonce := new([nonceSize]byte) copy(decryptNonce[:], box[:nonceSize]) - var secretKey [32]byte + var secretKey [secretKeySize]byte copy(secretKey[:], key) + fmt.Println(hex.EncodeToString(key) + hex.EncodeToString(secretKey[:])) decrypted, ok := secretbox.Open([]byte{}, box[nonceSize:], decryptNonce, &secretKey) if !ok { @@ -32,7 +39,7 @@ func easySeal(message, key []byte, rand io.Reader) ([]byte, error) { return nil, err } - var secretKey [32]byte + var secretKey [secretKeySize]byte copy(secretKey[:], key) return secretbox.Seal(nonce[:], message, nonce, &secretKey), nil } diff --git a/crypto/cipher/nacl/nacl_test.go b/crypto/cipher/nacl/nacl_test.go index 89c97de8d..c15c8276b 100644 --- a/crypto/cipher/nacl/nacl_test.go +++ b/crypto/cipher/nacl/nacl_test.go @@ -74,16 +74,25 @@ func Test_easyOpen(t *testing.T) { "success", args{ []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, - ed25519test.CharlottePrivateKey.Bytes()[32:], + ed25519test.CharlottePrivateKey.Bytes(), }, []byte("message"), false, }, + { + "err-key-size", + args{ + []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, + ed25519test.CharlottePrivateKey.Bytes()[16:], + }, + nil, + true, + }, { "err-nonce-size", args{ []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, - ed25519test.CharlottePrivateKey.Bytes()[32:], + ed25519test.CharlottePrivateKey.Bytes(), }, nil, true, @@ -92,7 +101,7 @@ func Test_easyOpen(t *testing.T) { "err-input", args{ []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x19, 0x83, 0xe5, 0x6e, 0x7f, 0xed, 0xfe, 0xbb, 0xd0, 0x70, 0x34, 0xce, 0x25, 0x49, 0x76, 0xa3, 0x50, 0x78, 0x91, 0x18, 0xe6, 0xe3}, - ed25519test.SofiaPrivateKey.Bytes()[32:], + ed25519test.SofiaPrivateKey.Bytes(), }, nil, true, @@ -103,7 +112,6 @@ func Test_easyOpen(t *testing.T) { got, err := easyOpen(tt.args.box, tt.args.key) if (err != nil) != tt.wantErr { t.Errorf("easyOpen() error = %v, wantErr %v", err, tt.wantErr) - return } if !assert.Equal(tt.want, got) { t.Errorf("easyOpen() = %v, want %v", got, tt.want) From d42598602ee0d2c4a444e513b8fb8068116bf13f Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 22:07:18 +0100 Subject: [PATCH 04/14] deal with backticks --- Makefile | 5 +++-- docs/openapi/spec.json | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 20109bd4d..2159f1452 100644 --- a/Makefile +++ b/Makefile @@ -36,13 +36,14 @@ openapi: mailchain/goswagger-tool swagger generate spec -b ./cmd/mailchain/internal/http/handlers -o ./docs/openapi/spec.json echo "" >> ./docs/openapi/spec.json - + echo "// nolint: gofmt" > ./docs/openapi/spec.json echo "package handlers" > ./cmd/mailchain/internal/http/handlers/openapi.go echo "" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo "// nolint: lll" >> ./cmd/mailchain/internal/http/handlers/openapi.go + echo "// nolint: funlen" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo 'func spec() string {' >> ./cmd/mailchain/internal/http/handlers/openapi.go echo ' return `' >> ./cmd/mailchain/internal/http/handlers/openapi.go - cat ./docs/openapi/spec.json >> ./cmd/mailchain/internal/http/handlers/openapi.go + cat ./docs/openapi/spec.json | sed 's/`/``/g' >> ./cmd/mailchain/internal/http/handlers/openapi.go echo '`' >> ./cmd/mailchain/internal/http/handlers/openapi.go echo '}' >> ./cmd/mailchain/internal/http/handlers/openapi.go addlicense -l apache -c Finobo ./cmd/mailchain/internal/http/handlers/openapi.go diff --git a/docs/openapi/spec.json b/docs/openapi/spec.json index b87c86cb5..d4877196d 100644 --- a/docs/openapi/spec.json +++ b/docs/openapi/spec.json @@ -155,10 +155,11 @@ }, "/messages/{message_id}/read": { "get": { + "description": "Messages can be either read or unread.", "tags": [ "Messages" ], - "summary": "Get message read status.", + "summary": "Message read status.", "operationId": "GetRead", "responses": { "200": { @@ -375,11 +376,11 @@ }, "/public-key": { "get": { - "description": "Get the public key.", + "description": "This method will get the public key to use when encrypting messages and envelopes.\nProtocols and networks have different methods for retrieving or calculating a public key from an address.", "tags": [ "PublicKey" ], - "summary": "Get public key from an address.", + "summary": "Public key from address.", "operationId": "GetPublicKey", "parameters": [ { @@ -457,6 +458,13 @@ "GetMessagesResponseHeaders": { "type": "object", "properties": { + "content-type": { + "description": "The content type and the encoding of the message body", + "type": "string", + "x-go-name": "ContentType", + "readOnly": true, + "example": "text/plain; charset=\\\"UTF-8\\\"," + }, "date": { "description": "When the message was created, this can be different to the transaction data of the message.", "type": "string", @@ -559,14 +567,21 @@ "description": "GetBody body response", "type": "object", "required": [ - "public_key" + "public_key", + "public_key_encoding" ], "properties": { "public_key": { - "description": "The public key", + "description": "The public key encoded as per `public_key_encoding`", "type": "string", "x-go-name": "PublicKey", "example": "0x79964e63752465973b6b3c610d8ac773fc7ce04f5d1ba599ba8768fb44cef525176f81d3c7603d5a2e466bc96da7b2443bef01b78059a98f45d5c440ca379463" + }, + "public_key_encoding": { + "description": "Encoding method used for encoding the `public_key`", + "type": "string", + "x-go-name": "PublicKeyEncoding", + "example": "hex/0x-prefix" } }, "x-go-package": "github.com/mailchain/mailchain/cmd/mailchain/internal/http/handlers" @@ -599,6 +614,13 @@ "type": "string", "x-go-name": "Name", "example": "mailchain.eth" + }, + "status": { + "description": "The rfc1035 error status, if present\nSince 0 status belongs to 'No Error', it's safe to use 'omitempty'", + "type": "integer", + "format": "int64", + "x-go-name": "Status", + "example": 3 } }, "x-go-package": "github.com/mailchain/mailchain/cmd/mailchain/internal/http/handlers" @@ -615,6 +637,13 @@ "type": "string", "x-go-name": "Address", "example": "0x4ad2b251246aafc2f3bdf3b690de3bf906622c51" + }, + "status": { + "description": "The rfc1035 error status, if present\nSince 0 status belongs to 'No Error', it's safe to use 'omitempty'", + "type": "integer", + "format": "int64", + "x-go-name": "Status", + "example": 3 } }, "x-go-package": "github.com/mailchain/mailchain/cmd/mailchain/internal/http/handlers" From c0af325719e26218fe93a4e2452c180368404e3b Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 22:07:28 +0100 Subject: [PATCH 05/14] move keys file --- crypto/ed25519/{keys.go => keys_test.go} | 4 ---- 1 file changed, 4 deletions(-) rename crypto/ed25519/{keys.go => keys_test.go} (84%) diff --git a/crypto/ed25519/keys.go b/crypto/ed25519/keys_test.go similarity index 84% rename from crypto/ed25519/keys.go rename to crypto/ed25519/keys_test.go index 0c06f1311..6a707e746 100644 --- a/crypto/ed25519/keys.go +++ b/crypto/ed25519/keys_test.go @@ -20,10 +20,6 @@ func sofiaPublicKeyBytes() []byte { // nolint: deadcode return []byte{0x72, 0x3c, 0xaa, 0x23, 0xa5, 0xb5, 0x11, 0xaf, 0x5a, 0xd7, 0xb7, 0xef, 0x60, 0x76, 0xe4, 0x14, 0xab, 0x7e, 0x75, 0xa9, 0xdc, 0x91, 0xe, 0xa6, 0xe, 0x41, 0x7a, 0x2b, 0x77, 0xa, 0x56, 0x71} // nolint: lll } -func sofiaPrivateKey() *PrivateKey { // nolint: deadcode - return &PrivateKey{key: ed25519.PrivateKey{0xd, 0x9b, 0x4a, 0x3c, 0x10, 0x72, 0x19, 0x91, 0xc6, 0xb8, 0x6, 0xf0, 0xf3, 0x43, 0x53, 0x5d, 0xc2, 0xb4, 0x6c, 0x74, 0xbe, 0xce, 0x50, 0xa0, 0xa0, 0xd6, 0xb9, 0xf0, 0x7, 0xd, 0x31, 0x57, 0x72, 0x3c, 0xaa, 0x23, 0xa5, 0xb5, 0x11, 0xaf, 0x5a, 0xd7, 0xb7, 0xef, 0x60, 0x76, 0xe4, 0x14, 0xab, 0x7e, 0x75, 0xa9, 0xdc, 0x91, 0xe, 0xa6, 0xe, 0x41, 0x7a, 0x2b, 0x77, 0xa, 0x56, 0x71}} // nolint: lll -} - func charlotteSeed() []byte { // nolint: deadcode return testutil.MustHexDecodeString("39d4c97d6a7f9e3306a2b5aae604ee67ec8b1387fffb39128fc055656cff05bb") // nolint: lll } From 4be272b8618152e53d1f62065435783a6f8a0fe3 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 22:13:51 +0100 Subject: [PATCH 06/14] lint --- cmd/mailchain/commands/commandstest/test_util.go | 3 ++- cmd/mailchain/internal/http/config.go | 1 + cmd/mailchain/internal/prompts/secret.go | 2 +- cmd/mailchain/internal/settings/base.go | 1 + crypto/cipher/nacl/nacl.go | 6 +++--- crypto/ed25519/public.go | 1 - .../{ecdsa_keys.go => ecdsa_keys_test.go} | 0 crypto/secp256k1/public.go | 1 + internal/envelope/marshaller.go | 2 ++ internal/mail/rfc2822/headers.go | 16 +--------------- internal/protocols/ethereum/signer.go | 1 + nameservice/lookup.go | 1 + 12 files changed, 14 insertions(+), 21 deletions(-) rename crypto/secp256k1/{ecdsa_keys.go => ecdsa_keys_test.go} (100%) diff --git a/cmd/mailchain/commands/commandstest/test_util.go b/cmd/mailchain/commands/commandstest/test_util.go index d3a17e363..5a9522656 100644 --- a/cmd/mailchain/commands/commandstest/test_util.go +++ b/cmd/mailchain/commands/commandstest/test_util.go @@ -9,10 +9,11 @@ import ( ) func ExecuteCommandC(root *cobra.Command, args []string, flags map[string]string) (c *cobra.Command, output string, err error) { - buf := new(bytes.Buffer) if err := root.ValidateArgs(args); err != nil { return nil, "", err } + buf := new(bytes.Buffer) + root.SetOutput(buf) root.SetArgs(args) for x := range flags { diff --git a/cmd/mailchain/internal/http/config.go b/cmd/mailchain/internal/http/config.go index 8356c5a11..6dc6dda64 100644 --- a/cmd/mailchain/internal/http/config.go +++ b/cmd/mailchain/internal/http/config.go @@ -22,6 +22,7 @@ type config struct { } // nolint: gocyclo +// nolint: funlen func produceConfig(s *settings.Base) (*config, error) { mailboxStore, err := s.MailboxState.Produce() if err != nil { diff --git a/cmd/mailchain/internal/prompts/secret.go b/cmd/mailchain/internal/prompts/secret.go index 862eea707..db15966fa 100644 --- a/cmd/mailchain/internal/prompts/secret.go +++ b/cmd/mailchain/internal/prompts/secret.go @@ -21,7 +21,7 @@ func Secret(suppliedSecret, prePromptNote, promptLabel string, allowEmpty, confi func secretFromPrompt(promptLabel string, confirmPrompt bool) (string, error) { prompt := promptui.Prompt{ - Label: fmt.Sprintf("%s", promptLabel), + Label: promptLabel, Mask: '*', } secret, err := prompt.Run() diff --git a/cmd/mailchain/internal/settings/base.go b/cmd/mailchain/internal/settings/base.go index b54abd38c..b6a6d4596 100644 --- a/cmd/mailchain/internal/settings/base.go +++ b/cmd/mailchain/internal/settings/base.go @@ -7,6 +7,7 @@ import ( "github.com/mailchain/mailchain/cmd/mailchain/internal/settings/output" "github.com/mailchain/mailchain/cmd/mailchain/internal/settings/values" "github.com/mailchain/mailchain/internal/protocols" + "github.com/mailchain/mailchain/internal/protocols/ethereum" "github.com/mailchain/mailchain/internal/protocols/substrate" ) diff --git a/crypto/cipher/nacl/nacl.go b/crypto/cipher/nacl/nacl.go index 6c23d4fdb..0ec12f6e7 100644 --- a/crypto/cipher/nacl/nacl.go +++ b/crypto/cipher/nacl/nacl.go @@ -1,9 +1,7 @@ package nacl import ( - "encoding/hex" "errors" - "fmt" "io" "golang.org/x/crypto/nacl/secretbox" @@ -23,8 +21,8 @@ func easyOpen(box, key []byte) ([]byte, error) { copy(decryptNonce[:], box[:nonceSize]) var secretKey [secretKeySize]byte + copy(secretKey[:], key) - fmt.Println(hex.EncodeToString(key) + hex.EncodeToString(secretKey[:])) decrypted, ok := secretbox.Open([]byte{}, box[nonceSize:], decryptNonce, &secretKey) if !ok { @@ -40,6 +38,8 @@ func easySeal(message, key []byte, rand io.Reader) ([]byte, error) { } var secretKey [secretKeySize]byte + copy(secretKey[:], key) + return secretbox.Seal(nonce[:], message, nonce, &secretKey), nil } diff --git a/crypto/ed25519/public.go b/crypto/ed25519/public.go index a902a11e4..43f1acb4c 100644 --- a/crypto/ed25519/public.go +++ b/crypto/ed25519/public.go @@ -17,5 +17,4 @@ func (pk PublicKey) Bytes() []byte { // Address returns the byte representation of the address func (pk PublicKey) Address() []byte { return nil - // return pk.key.ethcrypto.PubkeyToAddress(pk.ecdsa).Bytes() } diff --git a/crypto/secp256k1/ecdsa_keys.go b/crypto/secp256k1/ecdsa_keys_test.go similarity index 100% rename from crypto/secp256k1/ecdsa_keys.go rename to crypto/secp256k1/ecdsa_keys_test.go diff --git a/crypto/secp256k1/public.go b/crypto/secp256k1/public.go index 2b5511934..ded91cab0 100644 --- a/crypto/secp256k1/public.go +++ b/crypto/secp256k1/public.go @@ -55,6 +55,7 @@ func PublicKeyFromHex(input string) (*PublicKey, error) { if err != nil { return nil, err } + switch len(keyBytes) { case 64: pub := make([]byte, 65) diff --git a/internal/envelope/marshaller.go b/internal/envelope/marshaller.go index e42ffe5f8..2c146baef 100644 --- a/internal/envelope/marshaller.go +++ b/internal/envelope/marshaller.go @@ -26,7 +26,9 @@ func Unmarshal(buf []byte) (Data, error) { return nil, errors.Errorf("buffer is empty") } var err error + var envData Data + switch buf[0] { case Kind0x01: data := &ZeroX01{} diff --git a/internal/mail/rfc2822/headers.go b/internal/mail/rfc2822/headers.go index b06571183..94bbd36c3 100644 --- a/internal/mail/rfc2822/headers.go +++ b/internal/mail/rfc2822/headers.go @@ -1,17 +1,3 @@ -// Copyright 2019 Finobo -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package rfc2822 import ( @@ -100,7 +86,7 @@ func parseSubject(h nm.Header) (string, error) { func parseContentType(h nm.Header) string { sources, ok := h["Content-Type"] - if !ok || len(sources) == 0 || len(sources[0]) == 0 { + if !ok || len(sources) == 0 || sources[0] == "" { return mail.DefaultContentType } diff --git a/internal/protocols/ethereum/signer.go b/internal/protocols/ethereum/signer.go index 1138bf6c7..bfc3aec87 100644 --- a/internal/protocols/ethereum/signer.go +++ b/internal/protocols/ethereum/signer.go @@ -49,6 +49,7 @@ func (e Signer) Sign(opts signer.Options) (signedTransaction interface{}, err er if err != nil { return nil, err } + switch opts := opts.(type) { case SignerOptions: // Depending on the presence of the chain ID, sign with EIP155 or homestead diff --git a/nameservice/lookup.go b/nameservice/lookup.go index ba691061e..0e411c6bd 100644 --- a/nameservice/lookup.go +++ b/nameservice/lookup.go @@ -63,6 +63,7 @@ func (s LookupService) ResolveName(ctx context.Context, protocol, network, domai Address string `json:"address"` } var okRes response + if err := json.NewDecoder(res.Body).Decode(&okRes); err != nil { return nil, err } From 7b523c33ab9b87444227cdc53511cb53493d0539 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 22:22:41 +0100 Subject: [PATCH 07/14] fix lint --- cmd/mailchain/commands/commandstest/test_util.go | 5 ++--- cmd/mailchain/internal/http/config.go | 3 +-- cmd/mailchain/internal/http/handlers/messages.go | 1 + cmd/mailchain/internal/http/handlers/send_message.go | 3 +-- cmd/mailchain/internal/http/server.go | 1 + cmd/mailchain/internal/prompts/select.go | 1 + cmd/mailchain/internal/settings/defaults/networks.go | 8 ++++---- cmd/mailchain/internal/settings/network.go | 2 +- cmd/mailchain/internal/settings/network_test.go | 2 +- cmd/relay/relayer/relay.go | 1 + crypto/secp256k1/public.go | 2 +- internal/clients/etherscan/pubkey-finder.go | 2 +- internal/envelope/factory.go | 1 + internal/envelope/marshaller.go | 6 +++--- internal/keystore/nacl/address.go | 2 ++ internal/keystore/nacl/filestore.go | 1 + internal/keystore/nacl/nacl.go | 5 +++-- internal/protocols/substrate/address.go | 2 ++ nameservice/errors.go | 4 ++-- nameservice/lookup.go | 1 + sender/relay/relay.go | 1 + stores/s3store/sent.go | 1 + stores/sent_store.go | 1 + 23 files changed, 34 insertions(+), 22 deletions(-) diff --git a/cmd/mailchain/commands/commandstest/test_util.go b/cmd/mailchain/commands/commandstest/test_util.go index 5a9522656..144112c9e 100644 --- a/cmd/mailchain/commands/commandstest/test_util.go +++ b/cmd/mailchain/commands/commandstest/test_util.go @@ -25,15 +25,14 @@ func ExecuteCommandC(root *cobra.Command, args []string, flags map[string]string } func AssertCommandOutput(t *testing.T, cmd *cobra.Command, err error, out, wantOutput string) bool { - assert := assert.New(t) if err == nil { - if !assert.Equal(wantOutput, out) { + if !assert.Equal(t, wantOutput, out) { t.Errorf("cmd().Execute().out = %v, want %v", out, wantOutput) return false } } if err != nil { - if !assert.Equal(wantOutput+"\n"+cmd.UsageString()+"\n", out) { + if !assert.Equal(t, wantOutput+"\n"+cmd.UsageString()+"\n", out) { t.Errorf("cmd().Execute().out = %v, want %v", out, wantOutput) return false } diff --git a/cmd/mailchain/internal/http/config.go b/cmd/mailchain/internal/http/config.go index 6dc6dda64..d696abb34 100644 --- a/cmd/mailchain/internal/http/config.go +++ b/cmd/mailchain/internal/http/config.go @@ -22,8 +22,7 @@ type config struct { } // nolint: gocyclo -// nolint: funlen -func produceConfig(s *settings.Base) (*config, error) { +func produceConfig(s *settings.Base) (*config, error) { // nolint: funlen mailboxStore, err := s.MailboxState.Produce() if err != nil { return nil, errors.WithMessage(err, "Could not config mailbox store") diff --git a/cmd/mailchain/internal/http/handlers/messages.go b/cmd/mailchain/internal/http/handlers/messages.go index b07358587..670a76a24 100644 --- a/cmd/mailchain/internal/http/handlers/messages.go +++ b/cmd/mailchain/internal/http/handlers/messages.go @@ -32,6 +32,7 @@ import ( ) // nolint: gocyclo +// nolint: funlen // GetMessages returns a handler get spec func GetMessages(inbox stores.State, receivers map[string]mailbox.Receiver, ks keystore.Store, deriveKeyOptions multi.OptionsBuilders) func(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/mailchain/internal/http/handlers/send_message.go b/cmd/mailchain/internal/http/handlers/send_message.go index 7772758a4..baaf08d8e 100644 --- a/cmd/mailchain/internal/http/handlers/send_message.go +++ b/cmd/mailchain/internal/http/handlers/send_message.go @@ -39,7 +39,7 @@ import ( // SendMessage handler http func SendMessage(sent stores.Sent, senders map[string]sender.Message, ks keystore.Store, - deriveKeyOptions multi.OptionsBuilders) func(w http.ResponseWriter, r *http.Request) { + deriveKeyOptions multi.OptionsBuilders) func(w http.ResponseWriter, r *http.Request) { // nolint: funlen encrypter := aes256cbc.NewEncrypter() // Post swagger:route POST /messages Send SendMessage // @@ -104,7 +104,6 @@ func SendMessage(sent stores.Sent, senders map[string]sender.Message, ks keystor } w.WriteHeader(http.StatusOK) - return } } diff --git a/cmd/mailchain/internal/http/server.go b/cmd/mailchain/internal/http/server.go index a605dee4d..00dbe2a62 100644 --- a/cmd/mailchain/internal/http/server.go +++ b/cmd/mailchain/internal/http/server.go @@ -102,6 +102,7 @@ func SetupFlags(cmd *cobra.Command) error { func CreateNegroni(config *settings.Server, router http.Handler) *negroni.Negroni { n := negroni.New() + if !config.CORS.Disabled.Get() { n.Use(cors.New(cors.Options{ AllowedOrigins: config.CORS.AllowedOrigins.Get(), diff --git a/cmd/mailchain/internal/prompts/select.go b/cmd/mailchain/internal/prompts/select.go index 3b4293963..6a4b988a7 100644 --- a/cmd/mailchain/internal/prompts/select.go +++ b/cmd/mailchain/internal/prompts/select.go @@ -29,6 +29,7 @@ func SelectItemSkipable(label string, items []string, skipable bool) (selected s if skipable { items = append([]string{"skip"}, items...) } + prompt := promptui.Select{ Label: label, Items: items, diff --git a/cmd/mailchain/internal/settings/defaults/networks.go b/cmd/mailchain/internal/settings/defaults/networks.go index 2c6e240b0..534b54acb 100644 --- a/cmd/mailchain/internal/settings/defaults/networks.go +++ b/cmd/mailchain/internal/settings/defaults/networks.go @@ -13,8 +13,8 @@ type NetworkDefaults struct { Disabled bool } -func EthereumNetworkAny() NetworkDefaults { - return NetworkDefaults{ +func EthereumNetworkAny() *NetworkDefaults { + return &NetworkDefaults{ NameServiceAddress: NameServiceAddressKind, NameServiceDomainName: NameServiceDomainNameKind, PublicKeyFinder: mailchain.ClientEtherscanNoAuth, @@ -24,8 +24,8 @@ func EthereumNetworkAny() NetworkDefaults { } } -func SubstrateNetworkAny() NetworkDefaults { - return NetworkDefaults{ +func SubstrateNetworkAny() *NetworkDefaults { + return &NetworkDefaults{ // NameServiceAddress: NameServiceAddressKind, // NameServiceDomainName: NameServiceDomainNameKind, PublicKeyFinder: SubstratePublicKeyFinder, diff --git a/cmd/mailchain/internal/settings/network.go b/cmd/mailchain/internal/settings/network.go index b9139c146..dda7530cc 100644 --- a/cmd/mailchain/internal/settings/network.go +++ b/cmd/mailchain/internal/settings/network.go @@ -11,7 +11,7 @@ import ( "github.com/mailchain/mailchain/sender" ) -func network(s values.Store, protocol, network string, nd defaults.NetworkDefaults) *Network { +func network(s values.Store, protocol, network string, nd *defaults.NetworkDefaults) *Network { k := &Network{ kind: network, protocol: protocol, diff --git a/cmd/mailchain/internal/settings/network_test.go b/cmd/mailchain/internal/settings/network_test.go index d7ec55ec4..22a3984c9 100644 --- a/cmd/mailchain/internal/settings/network_test.go +++ b/cmd/mailchain/internal/settings/network_test.go @@ -18,7 +18,7 @@ func Test_network(t *testing.T) { s values.Store protocol string network string - nd defaults.NetworkDefaults + nd *defaults.NetworkDefaults } tests := []struct { name string diff --git a/cmd/relay/relayer/relay.go b/cmd/relay/relayer/relay.go index 29f4be68b..606cce0c5 100644 --- a/cmd/relay/relayer/relay.go +++ b/cmd/relay/relayer/relay.go @@ -22,6 +22,7 @@ func (f RelayFunc) HandleRequest(w http.ResponseWriter, req *http.Request) { errs.JSONWriter(w, http.StatusBadGateway, err) return } + defer resp.Body.Close() copyHeader(resp.Header, w.Header()) w.WriteHeader(resp.StatusCode) diff --git a/crypto/secp256k1/public.go b/crypto/secp256k1/public.go index ded91cab0..793627f71 100644 --- a/crypto/secp256k1/public.go +++ b/crypto/secp256k1/public.go @@ -55,7 +55,7 @@ func PublicKeyFromHex(input string) (*PublicKey, error) { if err != nil { return nil, err } - + switch len(keyBytes) { case 64: pub := make([]byte, 65) diff --git a/internal/clients/etherscan/pubkey-finder.go b/internal/clients/etherscan/pubkey-finder.go index 1632380d7..97b0460db 100644 --- a/internal/clients/etherscan/pubkey-finder.go +++ b/internal/clients/etherscan/pubkey-finder.go @@ -62,6 +62,7 @@ func getFromResultHash(address string, txResult *txList) (common.Hash, error) { if len(txResult.Result) == 0 { return common.Hash{}, errors.Errorf("No transactions found for address: %v", address) } + for i := range txResult.Result { x := txResult.Result[i] if strings.EqualFold(x.From, address) { @@ -69,5 +70,4 @@ func getFromResultHash(address string, txResult *txList) (common.Hash, error) { } } return common.Hash{}, errors.Errorf("No transactions from address found") - } diff --git a/internal/envelope/factory.go b/internal/envelope/factory.go index 1de6c070d..843ece9af 100644 --- a/internal/envelope/factory.go +++ b/internal/envelope/factory.go @@ -23,6 +23,7 @@ import ( func NewEnvelope(encrypter cipher.Encrypter, pubkey crypto.PublicKey, o []CreateOptionsBuilder) (Data, error) { opts := &CreateOpts{} apply(opts, o) + switch opts.Kind { case Kind0x01: return NewZeroX01(encrypter, pubkey, opts) diff --git a/internal/envelope/marshaller.go b/internal/envelope/marshaller.go index 2c146baef..1db0d708b 100644 --- a/internal/envelope/marshaller.go +++ b/internal/envelope/marshaller.go @@ -22,12 +22,12 @@ import ( // Unmarshal parses the envelope buffer representation in buf and places the // decoded result in data. func Unmarshal(buf []byte) (Data, error) { + var err error + var envData Data + if len(buf) == 0 { return nil, errors.Errorf("buffer is empty") } - var err error - - var envData Data switch buf[0] { case Kind0x01: diff --git a/internal/keystore/nacl/address.go b/internal/keystore/nacl/address.go index b3349f09e..232a8ccdd 100644 --- a/internal/keystore/nacl/address.go +++ b/internal/keystore/nacl/address.go @@ -29,6 +29,7 @@ func (fs FileStore) HasAddress(address []byte) bool { if err != nil { return false } + defer fd.Close() return true @@ -41,6 +42,7 @@ func (fs FileStore) GetAddresses() ([][]byte, error) { return nil, err } addresses := [][]byte{} + for _, f := range files { fileName := f.Name() if !strings.HasSuffix(fileName, ".json") { diff --git a/internal/keystore/nacl/filestore.go b/internal/keystore/nacl/filestore.go index 03b944382..cbe478b6c 100644 --- a/internal/keystore/nacl/filestore.go +++ b/internal/keystore/nacl/filestore.go @@ -40,6 +40,7 @@ func (fs FileStore) getEncryptedKey(address []byte) (*keystore.EncryptedKey, err if err != nil { return nil, errors.WithMessage(err, "could not find key file") } + defer fd.Close() encryptedKey := new(keystore.EncryptedKey) diff --git a/internal/keystore/nacl/nacl.go b/internal/keystore/nacl/nacl.go index 2dedbda49..4f1e2a419 100644 --- a/internal/keystore/nacl/nacl.go +++ b/internal/keystore/nacl/nacl.go @@ -30,13 +30,13 @@ import ( const nonceSize = 24 func easyOpen(box, key []byte) ([]byte, error) { + var secretKey [32]byte + if len(box) < nonceSize { return nil, errors.New("secretbox: message too short") } decryptNonce := new([nonceSize]byte) copy(decryptNonce[:], box[:nonceSize]) - - var secretKey [32]byte copy(secretKey[:], key) decrypted, ok := secretbox.Open([]byte{}, box[nonceSize:], decryptNonce, &secretKey) @@ -53,6 +53,7 @@ func easySeal(message, key []byte) ([]byte, error) { } var secretKey [32]byte + copy(secretKey[:], key) return secretbox.Seal(nonce[:], message, nonce, &secretKey), nil } diff --git a/internal/protocols/substrate/address.go b/internal/protocols/substrate/address.go index e618e5c0b..499e5c0fe 100644 --- a/internal/protocols/substrate/address.go +++ b/internal/protocols/substrate/address.go @@ -9,10 +9,12 @@ func SS58AddressFormat(network string, publicKey []byte) ([]byte, error) { if len(publicKey) != 32 { return nil, errors.Errorf("public key must be 32 bytes") } + prefixedKey, err := prefixWithNetwork(network, publicKey) if err != nil { return nil, errors.WithStack(err) } + hash := blake2b.Sum512(addSS58Prefix(prefixedKey)) // take first 2 bytes of hash since public key diff --git a/nameservice/errors.go b/nameservice/errors.go index 2b165f784..22c2de92a 100644 --- a/nameservice/errors.go +++ b/nameservice/errors.go @@ -63,8 +63,8 @@ func WrapError(err error) error { return err } -func isErrorOfAnyType(err error, errors []string) bool { - for _, errorMsg := range errors { +func isErrorOfAnyType(err error, errorStrings []string) bool { + for _, errorMsg := range errorStrings { if strings.Contains(err.Error(), errorMsg) { return true } diff --git a/nameservice/lookup.go b/nameservice/lookup.go index 0e411c6bd..79135121d 100644 --- a/nameservice/lookup.go +++ b/nameservice/lookup.go @@ -76,6 +76,7 @@ func (s LookupService) ResolveName(ctx context.Context, protocol, network, domai Code int `json:"code"` } var errRes response + if err := json.NewDecoder(res.Body).Decode(&errRes); err != nil { return nil, err } diff --git a/sender/relay/relay.go b/sender/relay/relay.go index f2e772832..9e8a06109 100644 --- a/sender/relay/relay.go +++ b/sender/relay/relay.go @@ -24,6 +24,7 @@ func (c Client) Send(ctx context.Context, network string, to, from, data []byte, // NewClient create new API client func NewClient(baseURL string) (*Client, error) { senders := map[string]sender.Message{} + for _, network := range []string{ethereum.Mainnet, ethereum.Ropsten, ethereum.Kovan, ethereum.Rinkeby, ethereum.Goerli} { client, err := ethrpc2.New(createAddress(baseURL, protocols.Ethereum, network)) if err != nil { diff --git a/stores/s3store/sent.go b/stores/s3store/sent.go index bd1aa4254..403409139 100644 --- a/stores/s3store/sent.go +++ b/stores/s3store/sent.go @@ -70,6 +70,7 @@ func (h Sent) PutMessage(messageID mail.ID, contentsHash, msg []byte, headers ma metadata := map[string]*string{ "Version": aws.String(mailchain.Version), } + for k, v := range headers { metadata[k] = aws.String(v) } diff --git a/stores/sent_store.go b/stores/sent_store.go index bfc47a6f6..b5c0607f3 100644 --- a/stores/sent_store.go +++ b/stores/sent_store.go @@ -93,6 +93,7 @@ func (s SentStore) PutMessage(messageID mail.ID, contentsHash, msg []byte, heade func responseAsError(r *http.Response) error { var httpError errs.HTTPError + if r.StatusCode != http.StatusCreated { if err := json.NewDecoder(r.Body).Decode(&httpError); err != nil { return errors.WithMessage(err, "failed to read response") From c870860a3369f661347bf674058e6ee93219bb2a Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 22:23:23 +0100 Subject: [PATCH 08/14] improve lint --- internal/mail/headers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/mail/headers.go b/internal/mail/headers.go index 5b0327678..fbcfba89a 100644 --- a/internal/mail/headers.go +++ b/internal/mail/headers.go @@ -21,7 +21,7 @@ import ( const DefaultContentType = "text/plain; charset=\"UTF-8\"" // NewHeaders create the headers for sending a new message -func NewHeaders(date time.Time, from, to Address, replyTo *Address, subject string, contentType string) *Headers { +func NewHeaders(date time.Time, from, to Address, replyTo *Address, subject, contentType string) *Headers { return &Headers{ From: from, To: to, From 6c0f55e4d4c34153712a698f760344001535e0e7 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 22:48:05 +0100 Subject: [PATCH 09/14] resolve lint --- Makefile | 7 +++- .../internal/http/handlers/openapi.go | 41 ++++++++++++++++--- cmd/mailchain/internal/http/handlers/spec.go | 10 ++++- cmd/mailchain/internal/prompts/secret.go | 1 + .../internal/settings/output/structure.go | 3 ++ .../internal/settings/output/yaml.go | 5 +++ crypto/cipher/nacl/nacl.go | 7 ++-- crypto/ed25519/private.go | 1 + internal/protocols/substrate/pubkey.go | 1 + nameservice/lookup.go | 6 +-- 10 files changed, 66 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 2159f1452..f9c94fb98 100644 --- a/Makefile +++ b/Makefile @@ -36,14 +36,17 @@ openapi: mailchain/goswagger-tool swagger generate spec -b ./cmd/mailchain/internal/http/handlers -o ./docs/openapi/spec.json echo "" >> ./docs/openapi/spec.json - echo "// nolint: gofmt" > ./docs/openapi/spec.json + + echo "// nolint: gofmt" > ./cmd/mailchain/internal/http/handlers/openapi.go echo "package handlers" > ./cmd/mailchain/internal/http/handlers/openapi.go + echo "" >> ./cmd/mailchain/internal/http/handlers/openapi.go + echo "" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo "// nolint: lll" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo "// nolint: funlen" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo 'func spec() string {' >> ./cmd/mailchain/internal/http/handlers/openapi.go echo ' return `' >> ./cmd/mailchain/internal/http/handlers/openapi.go - cat ./docs/openapi/spec.json | sed 's/`/``/g' >> ./cmd/mailchain/internal/http/handlers/openapi.go + cat ./docs/openapi/spec.json | sed 's/`/¬/g' >> ./cmd/mailchain/internal/http/handlers/openapi.go echo '`' >> ./cmd/mailchain/internal/http/handlers/openapi.go echo '}' >> ./cmd/mailchain/internal/http/handlers/openapi.go addlicense -l apache -c Finobo ./cmd/mailchain/internal/http/handlers/openapi.go diff --git a/cmd/mailchain/internal/http/handlers/openapi.go b/cmd/mailchain/internal/http/handlers/openapi.go index 3f2b2dfe6..21471464d 100644 --- a/cmd/mailchain/internal/http/handlers/openapi.go +++ b/cmd/mailchain/internal/http/handlers/openapi.go @@ -14,7 +14,9 @@ package handlers + // nolint: lll +// nolint: funlen func spec() string { return ` { @@ -174,10 +176,11 @@ func spec() string { }, "/messages/{message_id}/read": { "get": { + "description": "Messages can be either read or unread.", "tags": [ "Messages" ], - "summary": "Get message read status.", + "summary": "Message read status.", "operationId": "GetRead", "responses": { "200": { @@ -394,11 +397,11 @@ func spec() string { }, "/public-key": { "get": { - "description": "Get the public key.", + "description": "This method will get the public key to use when encrypting messages and envelopes.\nProtocols and networks have different methods for retrieving or calculating a public key from an address.", "tags": [ "PublicKey" ], - "summary": "Get public key from an address.", + "summary": "Public key from address.", "operationId": "GetPublicKey", "parameters": [ { @@ -476,6 +479,13 @@ func spec() string { "GetMessagesResponseHeaders": { "type": "object", "properties": { + "content-type": { + "description": "The content type and the encoding of the message body", + "type": "string", + "x-go-name": "ContentType", + "readOnly": true, + "example": "text/plain; charset=\\\"UTF-8\\\"," + }, "date": { "description": "When the message was created, this can be different to the transaction data of the message.", "type": "string", @@ -578,14 +588,21 @@ func spec() string { "description": "GetBody body response", "type": "object", "required": [ - "public_key" + "public_key", + "public_key_encoding" ], "properties": { "public_key": { - "description": "The public key", + "description": "The public key encoded as per ¬public_key_encoding¬", "type": "string", "x-go-name": "PublicKey", "example": "0x79964e63752465973b6b3c610d8ac773fc7ce04f5d1ba599ba8768fb44cef525176f81d3c7603d5a2e466bc96da7b2443bef01b78059a98f45d5c440ca379463" + }, + "public_key_encoding": { + "description": "Encoding method used for encoding the ¬public_key¬", + "type": "string", + "x-go-name": "PublicKeyEncoding", + "example": "hex/0x-prefix" } }, "x-go-package": "github.com/mailchain/mailchain/cmd/mailchain/internal/http/handlers" @@ -618,6 +635,13 @@ func spec() string { "type": "string", "x-go-name": "Name", "example": "mailchain.eth" + }, + "status": { + "description": "The rfc1035 error status, if present\nSince 0 status belongs to 'No Error', it's safe to use 'omitempty'", + "type": "integer", + "format": "int64", + "x-go-name": "Status", + "example": 3 } }, "x-go-package": "github.com/mailchain/mailchain/cmd/mailchain/internal/http/handlers" @@ -634,6 +658,13 @@ func spec() string { "type": "string", "x-go-name": "Address", "example": "0x4ad2b251246aafc2f3bdf3b690de3bf906622c51" + }, + "status": { + "description": "The rfc1035 error status, if present\nSince 0 status belongs to 'No Error', it's safe to use 'omitempty'", + "type": "integer", + "format": "int64", + "x-go-name": "Status", + "example": 3 } }, "x-go-package": "github.com/mailchain/mailchain/cmd/mailchain/internal/http/handlers" diff --git a/cmd/mailchain/internal/http/handlers/spec.go b/cmd/mailchain/internal/http/handlers/spec.go index fe766bcd2..c4e2085ab 100644 --- a/cmd/mailchain/internal/http/handlers/spec.go +++ b/cmd/mailchain/internal/http/handlers/spec.go @@ -14,12 +14,18 @@ package handlers -import "net/http" +import ( + "net/http" + "strings" +) // GetSpec returns a handler get spec func GetSpec() func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - _, _ = w.Write([]byte(spec())) + var mdreplacer = strings.NewReplacer("¬", "`") + + doc := mdreplacer.Replace(spec()) + _, _ = w.Write([]byte(doc)) } } diff --git a/cmd/mailchain/internal/prompts/secret.go b/cmd/mailchain/internal/prompts/secret.go index db15966fa..ab6c6a1bf 100644 --- a/cmd/mailchain/internal/prompts/secret.go +++ b/cmd/mailchain/internal/prompts/secret.go @@ -33,6 +33,7 @@ func secretFromPrompt(promptLabel string, confirmPrompt bool) (string, error) { Label: fmt.Sprintf("Repeat %s", promptLabel), Mask: '*', } + confirm, err := confirmPromptValue.Run() if err != nil { fmt.Printf("Prompt failed %v\n", err) diff --git a/cmd/mailchain/internal/settings/output/structure.go b/cmd/mailchain/internal/settings/output/structure.go index 536e63ce6..538dbabaf 100644 --- a/cmd/mailchain/internal/settings/output/structure.go +++ b/cmd/mailchain/internal/settings/output/structure.go @@ -19,6 +19,7 @@ func (e Element) SortedElements() []Element { sort.Slice(e.Elements, func(i, j int) bool { return e.Elements[i].FullName < e.Elements[j].FullName }) + return e.Elements } @@ -26,11 +27,13 @@ func (e Element) SortedAttributes() []Attribute { sort.Slice(e.Attributes, func(i, j int) bool { return e.Attributes[i].FullName < e.Attributes[j].FullName }) + return e.Attributes } func (e Element) ShortName() string { dots := strings.Split(e.FullName, ".") + return dots[len(dots)-1] } diff --git a/cmd/mailchain/internal/settings/output/yaml.go b/cmd/mailchain/internal/settings/output/yaml.go index 4494381c8..67908887d 100644 --- a/cmd/mailchain/internal/settings/output/yaml.go +++ b/cmd/mailchain/internal/settings/output/yaml.go @@ -55,15 +55,18 @@ func yamlAttributeStringSlice(fullName string, val []string, isDefault bool, out if len(val) == 0 { createNamePortion(shortKey, isDefault, false, commentDefaults, excludeDefaults, out, tabsize, indent) fmt.Fprint(out, " []\n") + return } createNamePortion(shortKey, isDefault, true, commentDefaults, excludeDefaults, out, tabsize, indent) + for _, item := range val { itemFormat := "%s- %q\n" if commentDefaults && isDefault { itemFormat = "# " + itemFormat } + fmt.Fprintf(out, itemFormat, strings.Repeat(" ", tabsize*(indent+1)), item) } } @@ -72,10 +75,12 @@ func createNamePortion(name string, isDefault, trailingNewLine, commentDefaults, if isDefault && excludeDefaults { return } + if isDefault && commentDefaults { fmt.Fprintf(out, "# ") } fmt.Fprintf(out, "%s%s:", strings.Repeat(" ", tabsize*indent), name) + if trailingNewLine { fmt.Fprintf(out, "\n") } diff --git a/crypto/cipher/nacl/nacl.go b/crypto/cipher/nacl/nacl.go index 0ec12f6e7..b3783afe6 100644 --- a/crypto/cipher/nacl/nacl.go +++ b/crypto/cipher/nacl/nacl.go @@ -11,17 +11,18 @@ const nonceSize = 24 const secretKeySize = 32 func easyOpen(box, key []byte) ([]byte, error) { + var secretKey [secretKeySize]byte + if len(key) != secretKeySize { return nil, errors.New("secretbox: key length must be 32") } + if len(box) < nonceSize { return nil, errors.New("secretbox: message too short") } + decryptNonce := new([nonceSize]byte) copy(decryptNonce[:], box[:nonceSize]) - - var secretKey [secretKeySize]byte - copy(secretKey[:], key) decrypted, ok := secretbox.Open([]byte{}, box[nonceSize:], decryptNonce, &secretKey) diff --git a/crypto/ed25519/private.go b/crypto/ed25519/private.go index ad77bb9f2..7682b2e69 100644 --- a/crypto/ed25519/private.go +++ b/crypto/ed25519/private.go @@ -28,5 +28,6 @@ func PrivateKeyFromBytes(pk []byte) (*PrivateKey, error) { if l := len(pk); l != ed25519.SeedSize { return nil, errors.Errorf("ed25519: bad seed length: %v", l) } + return &PrivateKey{key: ed25519.NewKeyFromSeed(pk)}, nil } diff --git a/internal/protocols/substrate/pubkey.go b/internal/protocols/substrate/pubkey.go index 1b12f3d6d..4ea5b91fc 100644 --- a/internal/protocols/substrate/pubkey.go +++ b/internal/protocols/substrate/pubkey.go @@ -32,6 +32,7 @@ func (pkf *PublicKeyFinder) PublicKeyFromAddress(ctx context.Context, protocol, if protocol != "substrate" { return nil, errors.New("protocol must be 'substrate'") } + if len(address) != 35 { return nil, errors.New("address must be 35 bytes in length") } diff --git a/nameservice/lookup.go b/nameservice/lookup.go index 79135121d..b4afa3f52 100644 --- a/nameservice/lookup.go +++ b/nameservice/lookup.go @@ -59,10 +59,9 @@ func (s LookupService) ResolveName(ctx context.Context, protocol, network, domai return nil, err } if res.StatusCode == http.StatusOK { - type response struct { + var okRes struct { Address string `json:"address"` } - var okRes response if err := json.NewDecoder(res.Body).Decode(&okRes); err != nil { return nil, err @@ -71,11 +70,10 @@ func (s LookupService) ResolveName(ctx context.Context, protocol, network, domai return common.FromHex(okRes.Address), nil } - type response struct { + var errRes struct { Message string `json:"message"` Code int `json:"code"` } - var errRes response if err := json.NewDecoder(res.Body).Decode(&errRes); err != nil { return nil, err From 9f8f0522cc4a1bea9924c897aeb1bdc6cd6b823a Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 22:57:34 +0100 Subject: [PATCH 10/14] fix build --- cmd/mailchain/commands/commandstest/test_util.go | 3 ++- cmd/mailchain/internal/http/server.go | 3 --- crypto/cipher/nacl/nacl.go | 1 + crypto/ed25519/keys_test.go | 4 ++++ internal/envelope/marshaller.go | 1 + 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/mailchain/commands/commandstest/test_util.go b/cmd/mailchain/commands/commandstest/test_util.go index 144112c9e..d08c4b5a8 100644 --- a/cmd/mailchain/commands/commandstest/test_util.go +++ b/cmd/mailchain/commands/commandstest/test_util.go @@ -12,12 +12,13 @@ func ExecuteCommandC(root *cobra.Command, args []string, flags map[string]string if err := root.ValidateArgs(args); err != nil { return nil, "", err } + buf := new(bytes.Buffer) root.SetOutput(buf) root.SetArgs(args) for x := range flags { - root.Flags().Set(x, flags[x]) + _ = root.Flags().Set(x, flags[x]) } c, err = root.ExecuteC() diff --git a/cmd/mailchain/internal/http/server.go b/cmd/mailchain/internal/http/server.go index 00dbe2a62..994b59a8f 100644 --- a/cmd/mailchain/internal/http/server.go +++ b/cmd/mailchain/internal/http/server.go @@ -92,9 +92,6 @@ func SetupFlags(cmd *cobra.Command) error { if err := viper.BindPFlag("server.cors.disabled", cmd.Flags().Lookup("cors-disabled")); err != nil { return err } - // if err := viper.BindPFlag("server.cors.allowed-origins", cmd.Flags().Lookup("cors-allowed-origins")); err != nil { - // return err - // } cmd.PersistentFlags().String("passphrase", "", "Passphrase to encrypt/decrypt key with") return nil diff --git a/crypto/cipher/nacl/nacl.go b/crypto/cipher/nacl/nacl.go index b3783afe6..e09a0f27a 100644 --- a/crypto/cipher/nacl/nacl.go +++ b/crypto/cipher/nacl/nacl.go @@ -29,6 +29,7 @@ func easyOpen(box, key []byte) ([]byte, error) { if !ok { return nil, errors.New("secretbox: could not decrypt data with private key") } + return decrypted, nil } diff --git a/crypto/ed25519/keys_test.go b/crypto/ed25519/keys_test.go index 6a707e746..e989f2ed8 100644 --- a/crypto/ed25519/keys_test.go +++ b/crypto/ed25519/keys_test.go @@ -9,6 +9,10 @@ import ( func sofiaSeed() []byte { return testutil.MustHexDecodeString("0d9b4a3c10721991c6b806f0f343535dc2b46c74bece50a0a0d6b9f0070d3157") } + +func sofiaPrivateKey() *PrivateKey { // nolint: deadcode + return &PrivateKey{key: ed25519.PrivateKey{0xd, 0x9b, 0x4a, 0x3c, 0x10, 0x72, 0x19, 0x91, 0xc6, 0xb8, 0x6, 0xf0, 0xf3, 0x43, 0x53, 0x5d, 0xc2, 0xb4, 0x6c, 0x74, 0xbe, 0xce, 0x50, 0xa0, 0xa0, 0xd6, 0xb9, 0xf0, 0x7, 0xd, 0x31, 0x57, 0x72, 0x3c, 0xaa, 0x23, 0xa5, 0xb5, 0x11, 0xaf, 0x5a, 0xd7, 0xb7, 0xef, 0x60, 0x76, 0xe4, 0x14, 0xab, 0x7e, 0x75, 0xa9, 0xdc, 0x91, 0xe, 0xa6, 0xe, 0x41, 0x7a, 0x2b, 0x77, 0xa, 0x56, 0x71}} // nolint: lll +} func sofiaPrivateKeyBytes() []byte { // nolint: deadcode return []byte{0x72, 0x3c, 0xaa, 0x23, 0xa5, 0xb5, 0x11, 0xaf, 0x5a, 0xd7, 0xb7, 0xef, 0x60, 0x76, 0xe4, 0x14, 0xab, 0x7e, 0x75, 0xa9, 0xdc, 0x91, 0xe, 0xa6, 0xe, 0x41, 0x7a, 0x2b, 0x77, 0xa, 0x56, 0x71} // nolint: lll } diff --git a/internal/envelope/marshaller.go b/internal/envelope/marshaller.go index 1db0d708b..8f01c9d73 100644 --- a/internal/envelope/marshaller.go +++ b/internal/envelope/marshaller.go @@ -23,6 +23,7 @@ import ( // decoded result in data. func Unmarshal(buf []byte) (Data, error) { var err error + var envData Data if len(buf) == 0 { From a10802b3d7203c26e237e35a362fcf896fb5dd58 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 23:03:06 +0100 Subject: [PATCH 11/14] fix build --- Makefile | 3 +- .../commands/commandstest/test_util.go | 1 + .../internal/http/handlers/messages.go | 1 - .../internal/http/handlers/openapi.go | 2 +- .../internal/http/handlers/protocols.go | 1 + .../internal/http/handlers/version.go | 1 - cmd/mailchain/internal/prompts/secret.go | 3 + .../internal/settings/output/yaml.go | 2 + cmd/mailchain/internal/settings/protocol.go | 90 ++----------------- .../internal/settings/values/bool.go | 1 + .../internal/settings/values/string.go | 1 + internal/clients/etherscan/receiver.go | 1 + internal/encoding/hex.go | 1 + internal/envelope/0x01.go | 1 + stores/s3store/sent.go | 2 + 15 files changed, 23 insertions(+), 88 deletions(-) diff --git a/Makefile b/Makefile index f9c94fb98..9545a6ec9 100644 --- a/Makefile +++ b/Makefile @@ -37,11 +37,10 @@ openapi: echo "" >> ./docs/openapi/spec.json - echo "// nolint: gofmt" > ./cmd/mailchain/internal/http/handlers/openapi.go echo "package handlers" > ./cmd/mailchain/internal/http/handlers/openapi.go echo "" >> ./cmd/mailchain/internal/http/handlers/openapi.go - echo "" >> ./cmd/mailchain/internal/http/handlers/openapi.go + echo "// nolint: gofmt" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo "// nolint: lll" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo "// nolint: funlen" >> ./cmd/mailchain/internal/http/handlers/openapi.go echo 'func spec() string {' >> ./cmd/mailchain/internal/http/handlers/openapi.go diff --git a/cmd/mailchain/commands/commandstest/test_util.go b/cmd/mailchain/commands/commandstest/test_util.go index d08c4b5a8..b7a9d4422 100644 --- a/cmd/mailchain/commands/commandstest/test_util.go +++ b/cmd/mailchain/commands/commandstest/test_util.go @@ -17,6 +17,7 @@ func ExecuteCommandC(root *cobra.Command, args []string, flags map[string]string root.SetOutput(buf) root.SetArgs(args) + for x := range flags { _ = root.Flags().Set(x, flags[x]) } diff --git a/cmd/mailchain/internal/http/handlers/messages.go b/cmd/mailchain/internal/http/handlers/messages.go index 670a76a24..2c574156f 100644 --- a/cmd/mailchain/internal/http/handlers/messages.go +++ b/cmd/mailchain/internal/http/handlers/messages.go @@ -44,7 +44,6 @@ func GetMessages(inbox stores.State, receivers map[string]mailbox.Receiver, ks k // Responses: // 200: GetMessagesResponse // 422: ValidationError - return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() req, err := parseGetMessagesRequest(r) diff --git a/cmd/mailchain/internal/http/handlers/openapi.go b/cmd/mailchain/internal/http/handlers/openapi.go index 21471464d..eb8c7b9fa 100644 --- a/cmd/mailchain/internal/http/handlers/openapi.go +++ b/cmd/mailchain/internal/http/handlers/openapi.go @@ -14,7 +14,7 @@ package handlers - +// nolint: gofmt // nolint: lll // nolint: funlen func spec() string { diff --git a/cmd/mailchain/internal/http/handlers/protocols.go b/cmd/mailchain/internal/http/handlers/protocols.go index 407ffac8a..12fc384ad 100644 --- a/cmd/mailchain/internal/http/handlers/protocols.go +++ b/cmd/mailchain/internal/http/handlers/protocols.go @@ -32,6 +32,7 @@ func GetProtocols(base *settings.Base) func(w http.ResponseWriter, r *http.Reque if protocol.Disabled.Get() { continue } + networks := []string{} for _, network := range protocol.Networks { if !network.Disabled() { diff --git a/cmd/mailchain/internal/http/handlers/version.go b/cmd/mailchain/internal/http/handlers/version.go index b1f8cb668..d8377cdb5 100644 --- a/cmd/mailchain/internal/http/handlers/version.go +++ b/cmd/mailchain/internal/http/handlers/version.go @@ -17,7 +17,6 @@ func GetVersion() func(w http.ResponseWriter, r *http.Request) { // // Responses: // 200: GetVersionResponseBody - return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(GetVersionResponseBody{ diff --git a/cmd/mailchain/internal/prompts/secret.go b/cmd/mailchain/internal/prompts/secret.go index ab6c6a1bf..90167d1d6 100644 --- a/cmd/mailchain/internal/prompts/secret.go +++ b/cmd/mailchain/internal/prompts/secret.go @@ -15,6 +15,7 @@ func Secret(suppliedSecret, prePromptNote, promptLabel string, allowEmpty, confi if allowEmpty { return "", nil } + fmt.Println(prePromptNote) return secretFromPrompt(promptLabel, confirmPrompt) } @@ -24,10 +25,12 @@ func secretFromPrompt(promptLabel string, confirmPrompt bool) (string, error) { Label: promptLabel, Mask: '*', } + secret, err := prompt.Run() if err != nil { return "", errors.Errorf("failed read %q", promptLabel) } + if confirmPrompt { confirmPromptValue := promptui.Prompt{ Label: fmt.Sprintf("Repeat %s", promptLabel), diff --git a/cmd/mailchain/internal/settings/output/yaml.go b/cmd/mailchain/internal/settings/output/yaml.go index 67908887d..393dcd23c 100644 --- a/cmd/mailchain/internal/settings/output/yaml.go +++ b/cmd/mailchain/internal/settings/output/yaml.go @@ -39,6 +39,7 @@ func yamlAttributeDefault(a Attribute, out io.Writer, tabsize, indent int, comme if excludeDefaults && a.IsDefault { return } + createNamePortion(a.ShortName(), a.IsDefault, false, commentDefaults, excludeDefaults, out, tabsize, indent) fmt.Fprintf(out, yamlValueFormat(a.Value), a.Value) fmt.Fprint(out, "\n") @@ -79,6 +80,7 @@ func createNamePortion(name string, isDefault, trailingNewLine, commentDefaults, if isDefault && commentDefaults { fmt.Fprintf(out, "# ") } + fmt.Fprintf(out, "%s%s:", strings.Repeat(" ", tabsize*indent), name) if trailingNewLine { diff --git a/cmd/mailchain/internal/settings/protocol.go b/cmd/mailchain/internal/settings/protocol.go index 0d2b4d2b2..c72d0a072 100644 --- a/cmd/mailchain/internal/settings/protocol.go +++ b/cmd/mailchain/internal/settings/protocol.go @@ -1,8 +1,6 @@ package settings import ( - "fmt" - "github.com/mailchain/mailchain/cmd/mailchain/internal/settings/output" "github.com/mailchain/mailchain/cmd/mailchain/internal/settings/values" "github.com/mailchain/mailchain/internal/mailbox" @@ -10,14 +8,7 @@ import ( "github.com/mailchain/mailchain/sender" ) -func protocol(s values.Store, protocol string, networkClients map[string]NetworkClient) *Protocol { - return &Protocol{ - Disabled: values.NewDefaultBool(false, s, - fmt.Sprintf("protocols.%s.disabled", protocol)), - Kind: protocol, - Networks: networkClients, - } -} +func protocol(s values.Store, protocol string, networkClients map[string]NetworkClient) *Protocol type Protocol struct { Networks map[string]NetworkClient @@ -25,81 +16,14 @@ type Protocol struct { Disabled values.Bool } -func (p Protocol) GetSenders(senders *Senders) (map[string]sender.Message, error) { - msg := map[string]sender.Message{} - for network, v := range p.Networks { - s, err := v.ProduceSender(senders) - if err != nil { - return nil, err - } - msg[p.Kind+"/"+network] = s - } - return msg, nil -} +func (p Protocol) GetSenders(senders *Senders) (map[string]sender.Message, error) -func (p Protocol) GetReceivers(receivers *Receivers) (map[string]mailbox.Receiver, error) { - msg := map[string]mailbox.Receiver{} - for network, v := range p.Networks { - s, err := v.ProduceReceiver(receivers) - if err != nil { - return nil, err - } - msg[p.Kind+"/"+network] = s - } - return msg, nil -} +func (p Protocol) GetReceivers(receivers *Receivers) (map[string]mailbox.Receiver, error) -func (p Protocol) GetPublicKeyFinders(publicKeyFinders *PublicKeyFinders) (map[string]mailbox.PubKeyFinder, error) { - msg := map[string]mailbox.PubKeyFinder{} - for network, v := range p.Networks { - s, err := v.ProducePublicKeyFinders(publicKeyFinders) - if err != nil { - return nil, err - } - msg[p.Kind+"/"+network] = s - } - return msg, nil -} +func (p Protocol) GetPublicKeyFinders(publicKeyFinders *PublicKeyFinders) (map[string]mailbox.PubKeyFinder, error) -func (p Protocol) GetAddressNameServices(ans *AddressNameServices) (map[string]nameservice.ReverseLookup, error) { - msg := map[string]nameservice.ReverseLookup{} - for network, v := range p.Networks { - s, err := v.ProduceNameServiceAddress(ans) - if err != nil { - return nil, err - } - msg[p.Kind+"/"+network] = s - } - return msg, nil -} +func (p Protocol) GetAddressNameServices(ans *AddressNameServices) (map[string]nameservice.ReverseLookup, error) -func (p Protocol) GetDomainNameServices(ans *DomainNameServices) (map[string]nameservice.ForwardLookup, error) { - msg := map[string]nameservice.ForwardLookup{} - for network, v := range p.Networks { - s, err := v.ProduceNameServiceDomain(ans) - if err != nil { - return nil, err - } - msg[p.Kind+"/"+network] = s - } - return msg, nil -} +func (p Protocol) GetDomainNameServices(ans *DomainNameServices) (map[string]nameservice.ForwardLookup, error) -func (p Protocol) Output() output.Element { - networkElements := []output.Element{} - for _, c := range p.Networks { - networkElements = append(networkElements, c.Output()) - } - return output.Element{ - FullName: "protocols." + p.Kind, - Attributes: []output.Attribute{ - p.Disabled.Attribute(), - }, - Elements: []output.Element{ - output.Element{ - FullName: "protocols." + p.Kind + ".networks", - Elements: networkElements, - }, - }, - } -} +func (p Protocol) Output() output.Element diff --git a/cmd/mailchain/internal/settings/values/bool.go b/cmd/mailchain/internal/settings/values/bool.go index e2e7018f1..ce71af8e0 100644 --- a/cmd/mailchain/internal/settings/values/bool.go +++ b/cmd/mailchain/internal/settings/values/bool.go @@ -24,6 +24,7 @@ func (d DefaultBool) Get() bool { if d.store.IsSet(d.setting) { return d.store.GetBool(d.setting) } + return d.def } diff --git a/cmd/mailchain/internal/settings/values/string.go b/cmd/mailchain/internal/settings/values/string.go index 1f6dad1bc..2c1dd38b5 100644 --- a/cmd/mailchain/internal/settings/values/string.go +++ b/cmd/mailchain/internal/settings/values/string.go @@ -24,6 +24,7 @@ func (d DefaultString) Get() string { if d.store.IsSet(d.setting) { return d.store.GetString(d.setting) } + return d.def } diff --git a/internal/clients/etherscan/receiver.go b/internal/clients/etherscan/receiver.go index f813ff004..89f16f138 100644 --- a/internal/clients/etherscan/receiver.go +++ b/internal/clients/etherscan/receiver.go @@ -36,6 +36,7 @@ func (c APIClient) Receive(ctx context.Context, network string, address []byte) } res := []cipher.EncryptedContent{} txHashes := map[string]bool{} + for i := range txResult.Result { // TODO: paging x := txResult.Result[i] if !strings.HasPrefix(x.Input, "0x6d61696c636861696e") { diff --git a/internal/encoding/hex.go b/internal/encoding/hex.go index a3c96b4bd..e615568e0 100644 --- a/internal/encoding/hex.go +++ b/internal/encoding/hex.go @@ -32,6 +32,7 @@ func DecodeZeroX(in string) ([]byte, error) { if in == "" { return nil, errors.Errorf("empty hex string") } + if !strings.HasPrefix(in, "0x") { return nil, errors.Errorf("missing \"0x\" prefix from hex string") } diff --git a/internal/envelope/0x01.go b/internal/envelope/0x01.go index 3cc1fcc45..bf80faa92 100644 --- a/internal/envelope/0x01.go +++ b/internal/envelope/0x01.go @@ -63,6 +63,7 @@ func (d *ZeroX01) URL(decrypter cipher.Decrypter) (*url.URL, error) { if err != nil { return nil, errors.WithStack(err) } + locationHash := UInt64Bytes(decrypted) code, hash, err := locationHash.Values() diff --git a/stores/s3store/sent.go b/stores/s3store/sent.go index 403409139..d1deb475f 100644 --- a/stores/s3store/sent.go +++ b/stores/s3store/sent.go @@ -36,7 +36,9 @@ func NewSent(region, bucket, id, secret string) (*Sent, error) { if bucket == "" { return nil, errors.Errorf("`bucket` must be specified") } + var creds *credentials.Credentials + if id != "" && secret != "" { creds = credentials.NewStaticCredentials(id, secret, "") } From 8159ba83c49b17370bf0a6e142ad3b3a9135503c Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 23:12:04 +0100 Subject: [PATCH 12/14] fix build --- cmd/mailchain/internal/settings/protocol.go | 90 +++++++++++++++++++-- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/cmd/mailchain/internal/settings/protocol.go b/cmd/mailchain/internal/settings/protocol.go index c72d0a072..a2bf6ddde 100644 --- a/cmd/mailchain/internal/settings/protocol.go +++ b/cmd/mailchain/internal/settings/protocol.go @@ -1,6 +1,8 @@ package settings import ( + "fmt" + "github.com/mailchain/mailchain/cmd/mailchain/internal/settings/output" "github.com/mailchain/mailchain/cmd/mailchain/internal/settings/values" "github.com/mailchain/mailchain/internal/mailbox" @@ -8,7 +10,14 @@ import ( "github.com/mailchain/mailchain/sender" ) -func protocol(s values.Store, protocol string, networkClients map[string]NetworkClient) *Protocol +func protocol(s values.Store, protocol string, networkClients map[string]NetworkClient) *Protocol { + return &Protocol{ + Disabled: values.NewDefaultBool(false, s, + fmt.Sprintf("protocols.%s.disabled", protocol)), + Kind: protocol, + Networks: networkClients, + } +} type Protocol struct { Networks map[string]NetworkClient @@ -16,14 +25,81 @@ type Protocol struct { Disabled values.Bool } -func (p Protocol) GetSenders(senders *Senders) (map[string]sender.Message, error) +func (p Protocol) GetSenders(senders *Senders) (map[string]sender.Message, error) { + msg := map[string]sender.Message{} + for network, v := range p.Networks { + s, err := v.ProduceSender(senders) + if err != nil { + return nil, err + } + msg[p.Kind+"/"+network] = s + } + return msg, nil +} -func (p Protocol) GetReceivers(receivers *Receivers) (map[string]mailbox.Receiver, error) +func (p Protocol) GetReceivers(receivers *Receivers) (map[string]mailbox.Receiver, error) { + msg := map[string]mailbox.Receiver{} + for network, v := range p.Networks { + s, err := v.ProduceReceiver(receivers) + if err != nil { + return nil, err + } + msg[p.Kind+"/"+network] = s + } + return msg, nil +} -func (p Protocol) GetPublicKeyFinders(publicKeyFinders *PublicKeyFinders) (map[string]mailbox.PubKeyFinder, error) +func (p Protocol) GetPublicKeyFinders(publicKeyFinders *PublicKeyFinders) (map[string]mailbox.PubKeyFinder, error) { + msg := map[string]mailbox.PubKeyFinder{} + for network, v := range p.Networks { + s, err := v.ProducePublicKeyFinders(publicKeyFinders) + if err != nil { + return nil, err + } + msg[p.Kind+"/"+network] = s + } + return msg, nil +} -func (p Protocol) GetAddressNameServices(ans *AddressNameServices) (map[string]nameservice.ReverseLookup, error) +func (p Protocol) GetAddressNameServices(ans *AddressNameServices) (map[string]nameservice.ReverseLookup, error) { + msg := map[string]nameservice.ReverseLookup{} + for network, v := range p.Networks { + s, err := v.ProduceNameServiceAddress(ans) + if err != nil { + return nil, err + } + msg[p.Kind+"/"+network] = s + } + return msg, nil +} -func (p Protocol) GetDomainNameServices(ans *DomainNameServices) (map[string]nameservice.ForwardLookup, error) +func (p Protocol) GetDomainNameServices(ans *DomainNameServices) (map[string]nameservice.ForwardLookup, error) { + msg := map[string]nameservice.ForwardLookup{} + for network, v := range p.Networks { + s, err := v.ProduceNameServiceDomain(ans) + if err != nil { + return nil, err + } + msg[p.Kind+"/"+network] = s + } + return msg, nil +} -func (p Protocol) Output() output.Element +func (p Protocol) Output() output.Element { + networkElements := []output.Element{} + for _, c := range p.Networks { + networkElements = append(networkElements, c.Output()) + } + return output.Element{ + FullName: "protocols." + p.Kind, + Attributes: []output.Attribute{ + p.Disabled.Attribute(), + }, + Elements: []output.Element{ + output.Element{ + FullName: "protocols." + p.Kind + ".networks", + Elements: networkElements, + }, + }, + } +} \ No newline at end of file From 87b16e630b5e4d28232635d6bc6bac41fe8ac15a Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 23:13:31 +0100 Subject: [PATCH 13/14] go formatted --- internal/envelope/0x01.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/envelope/0x01.go b/internal/envelope/0x01.go index bf80faa92..553c37fc8 100644 --- a/internal/envelope/0x01.go +++ b/internal/envelope/0x01.go @@ -63,7 +63,7 @@ func (d *ZeroX01) URL(decrypter cipher.Decrypter) (*url.URL, error) { if err != nil { return nil, errors.WithStack(err) } - + locationHash := UInt64Bytes(decrypted) code, hash, err := locationHash.Values() From fb0dc58cd83c9b87a28edc74ab63deb27cbcc9b1 Mon Sep 17 00:00:00 2001 From: Rob De Feo Date: Thu, 24 Oct 2019 23:16:16 +0100 Subject: [PATCH 14/14] fix lint --- cmd/mailchain/internal/settings/protocol.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/mailchain/internal/settings/protocol.go b/cmd/mailchain/internal/settings/protocol.go index a2bf6ddde..0d2b4d2b2 100644 --- a/cmd/mailchain/internal/settings/protocol.go +++ b/cmd/mailchain/internal/settings/protocol.go @@ -102,4 +102,4 @@ func (p Protocol) Output() output.Element { }, }, } -} \ No newline at end of file +}