Skip to content

Commit a9067e9

Browse files
committed
Added Utils unit tests - envelope and crypto
Signed-off-by: Effi-S <effi.szt@gmail.com>
1 parent 57b2bf7 commit a9067e9

File tree

4 files changed

+209
-3
lines changed

4 files changed

+209
-3
lines changed

utils/serialization/envelope_wrapper.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0
77
package serialization
88

99
import (
10+
"errors"
1011
"fmt"
1112

1213
"github.com/hyperledger/fabric-protos-go-apiv2/common"
@@ -19,14 +20,23 @@ import (
1920
// NoOpSigner supports unsigned envelopes.
2021
type NoOpSigner struct{}
2122

22-
// WrapEnvelope serialize envelope.
23-
func WrapEnvelope(data []byte, header *common.Header) []byte {
23+
// WrapEnvelopePayload serialize envelope.
24+
func WrapEnvelopePayload(data []byte, header *common.Header) []byte {
2425
return protoutil.MarshalOrPanic(&common.Payload{
2526
Header: header,
2627
Data: data,
2728
})
2829
}
2930

31+
func WrapEnvelope(data []byte, header *common.Header) []byte {
32+
payloadBytes := WrapEnvelopePayload(data, header)
33+
34+
envelope := &common.Envelope{
35+
Payload: payloadBytes,
36+
}
37+
return protoutil.MarshalOrPanic(envelope)
38+
}
39+
3040
// UnwrapEnvelope deserialize an envelope.
3141
func UnwrapEnvelope(message []byte) ([]byte, *common.ChannelHeader, error) {
3242
envelope, err := protoutil.GetEnvelopeFromBlock(message)
@@ -48,6 +58,11 @@ func ParseEnvelope(envelope *common.Envelope) (*common.Payload, *common.ChannelH
4858
if err != nil {
4959
return nil, nil, err
5060
}
61+
62+
if payload.Header == nil {
63+
return nil, nil, errors.New("payload header is nil")
64+
}
65+
5166
channelHdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)
5267
if err != nil {
5368
return nil, nil, err
@@ -81,7 +96,7 @@ func CreateEnvelope(
8196
channelHeader.TxId = protoutil.ComputeTxID(signatureHeader.Nonce, signatureHeader.Creator)
8297
}
8398
payloadHeader := protoutil.MakePayloadHeader(channelHeader, signatureHeader)
84-
payload := WrapEnvelope(data, payloadHeader)
99+
payload := WrapEnvelopePayload(data, payloadHeader)
85100

86101
signature, err := signer.Sign(payload)
87102
if err != nil {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package serialization_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hyperledger/fabric-protos-go-apiv2/common"
7+
"github.com/hyperledger/fabric-x-committer/utils/serialization"
8+
"github.com/hyperledger/fabric-x-committer/utils/test"
9+
"github.com/hyperledger/fabric/protoutil"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
// UnwrapEnvelope function with invalid inputs
14+
func TestUnwrapEnvelopeBadInput(t *testing.T) {
15+
t.Run("Not an envelope", func(t *testing.T) {
16+
_, _, err := serialization.UnwrapEnvelope([]byte("invalid input"))
17+
require.Error(t, err)
18+
})
19+
20+
t.Run("OK Header with an invalid payload", func(t *testing.T) {
21+
envelope := &common.Envelope{
22+
Payload: []byte("not-a-payload"),
23+
}
24+
25+
envelopeBytes := protoutil.MarshalOrPanic(envelope)
26+
27+
_, _, err := serialization.UnwrapEnvelope(envelopeBytes)
28+
require.Error(t, err)
29+
})
30+
31+
t.Run(" OK Payload with a nil Header", func(t *testing.T) {
32+
payload := &common.Payload{
33+
Header: nil,
34+
Data: []byte("some data"),
35+
}
36+
payloadBytes := protoutil.MarshalOrPanic(payload)
37+
38+
envelope := &common.Envelope{
39+
Payload: payloadBytes,
40+
}
41+
envelopeBytes := protoutil.MarshalOrPanic(envelope)
42+
43+
_, _, err := serialization.UnwrapEnvelope(envelopeBytes)
44+
require.Error(t, err)
45+
})
46+
47+
t.Run("OK payload but invalid ChannelHeader", func(t *testing.T) {
48+
header := &common.Header{
49+
ChannelHeader: []byte("not-a-channel-header"),
50+
}
51+
payload := &common.Payload{
52+
Header: header,
53+
Data: []byte("some data"),
54+
}
55+
payloadBytes := protoutil.MarshalOrPanic(payload)
56+
57+
envelope := &common.Envelope{
58+
Payload: payloadBytes,
59+
}
60+
envelopeBytes := protoutil.MarshalOrPanic(envelope)
61+
62+
_, _, err := serialization.UnwrapEnvelope(envelopeBytes)
63+
require.Error(t, err)
64+
})
65+
}
66+
67+
// Test properly wrapped envelope is unwrapped correctly
68+
func TestUnwrapEnvelopeGoodInput(t *testing.T) {
69+
70+
// -1- Check unwrap envelope has no error
71+
originalPayload := []byte("test payload")
72+
originalChannelHeader := &common.ChannelHeader{
73+
ChannelId: "test-channel",
74+
}
75+
originalHeader := &common.Header{
76+
ChannelHeader: protoutil.MarshalOrPanic(originalChannelHeader),
77+
}
78+
79+
wrappedEnvelope := serialization.WrapEnvelope(originalPayload, originalHeader)
80+
payload, channelHeader, err := serialization.UnwrapEnvelope(wrappedEnvelope)
81+
82+
// -2- Check we get the correct Payload & Header
83+
require.NoError(t, err)
84+
require.Equal(t, originalPayload, payload)
85+
test.RequireProtoEqual(t, originalChannelHeader, channelHeader)
86+
}

utils/signature/sigtest/crypto.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@ func SerializeVerificationKey(key *ecdsa.PublicKey) ([]byte, error) {
3232

3333
// SerializeSigningKey encodes a ECDSA private key into a PEM file.
3434
func SerializeSigningKey(key *ecdsa.PrivateKey) ([]byte, error) {
35+
36+
if key == nil {
37+
return nil, errors.New("key is nil")
38+
}
39+
3540
x509encodedPri, err := x509.MarshalECPrivateKey(key)
3641
if err != nil {
3742
return nil, errors.Wrap(err, "cannot serialize private key")
3843
}
44+
3945
return pem.EncodeToMemory(&pem.Block{
4046
Type: "EC PRIVATE KEY",
4147
Bytes: x509encodedPri,
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package sigtest
2+
3+
import (
4+
"crypto/ecdsa"
5+
"crypto/elliptic"
6+
"crypto/rand"
7+
"fmt"
8+
"testing"
9+
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestSerializeVerificationKey(t *testing.T) {
14+
tests := []struct {
15+
name string
16+
curve elliptic.Curve
17+
wantErr bool
18+
}{
19+
{
20+
name: "P256",
21+
curve: elliptic.P256(),
22+
},
23+
{
24+
name: "P384",
25+
curve: elliptic.P384(),
26+
},
27+
{
28+
name: "P224",
29+
curve: elliptic.P224(),
30+
},
31+
{
32+
name: "P521",
33+
curve: elliptic.P521(),
34+
},
35+
36+
// {
37+
// // ? TODO find an invalid example?
38+
// name: "Invalid input",
39+
// curve: elliptic.(),
40+
// wantErr: true,
41+
// },
42+
}
43+
44+
for _, tt := range tests {
45+
t.Run(tt.name, func(t *testing.T) {
46+
privKey, err := ecdsa.GenerateKey(tt.curve, rand.Reader)
47+
require.NoError(t, err)
48+
49+
_, err = SerializeVerificationKey(&privKey.PublicKey)
50+
if tt.wantErr {
51+
require.Error(t, err)
52+
} else {
53+
require.NoError(t, err)
54+
}
55+
})
56+
}
57+
}
58+
59+
func TestSerializeSigningKey(t *testing.T) {
60+
61+
// Panic can happen from unwanted side effects when nil and empty Keys are passed
62+
defer func() {
63+
if r := recover(); r != nil {
64+
t.Errorf("SerializeSigningKey() panics: %v", r)
65+
}
66+
}()
67+
68+
t.Run("Key Empty", func(t *testing.T) {
69+
emptyKey := &ecdsa.PrivateKey{}
70+
_, err := SerializeSigningKey(emptyKey)
71+
require.Error(t, err)
72+
})
73+
t.Run("Key is nil", func(t *testing.T) {
74+
_, err := SerializeSigningKey(nil)
75+
require.Error(t, err)
76+
})
77+
78+
t.Run("Key OK", func(t *testing.T) {
79+
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
80+
key, err := SerializeSigningKey(privateKey)
81+
fmt.Println(key)
82+
require.NoError(t, err)
83+
})
84+
85+
}
86+
87+
func TestParseSigningKey(t *testing.T) {
88+
t.Run("Key is nil", func(t *testing.T) {
89+
_, err := ParseSigningKey(nil)
90+
require.Error(t, err)
91+
})
92+
t.Run("Key OK", func(t *testing.T) {
93+
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
94+
key, err := SerializeSigningKey(privateKey)
95+
require.NoError(t, err)
96+
_, err = ParseSigningKey(key)
97+
require.NoError(t, err)
98+
})
99+
}

0 commit comments

Comments
 (0)