Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions utils/serialization/envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@ func UnwrapEnvelope(message []byte) ([]byte, *common.ChannelHeader, error) {

// ParseEnvelope parse the envelope content.
func ParseEnvelope(envelope *common.Envelope) (*common.Payload, *common.ChannelHeader, error) {
if envelope == nil {
return nil, nil, errors.New("nil envelope")
}

payload, err := protoutil.UnmarshalPayload(envelope.Payload)
if err != nil {
return nil, nil, errors.Wrap(err, "error unmarshaling payload")
}

if payload.Header == nil { // Will panic if payload.Header is nil
return nil, nil, errors.New("nil payload header")
}

channelHdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)
if err != nil {
return nil, nil, errors.Wrap(err, "error unmarshaling channel header")
Expand Down
95 changes: 95 additions & 0 deletions utils/serialization/envelope_wrapper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package serialization_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/hyperledger/fabric-protos-go-apiv2/common"
"github.com/hyperledger/fabric-x-common/protoutil"

"github.com/hyperledger/fabric-x-committer/utils/serialization"
"github.com/hyperledger/fabric-x-committer/utils/test"
)

// TestUnwrapEnvelopeBadInput tests UnwrapEnvelope function with invalid inputs.
func TestUnwrapEnvelopeBadInput(t *testing.T) {
t.Parallel()
t.Run("Not an envelope", func(t *testing.T) {
t.Parallel()
_, _, err := serialization.UnwrapEnvelope([]byte("invalid input"))
require.Error(t, err)
})

t.Run("OK Header with an invalid payload", func(t *testing.T) {
t.Parallel()
envelopeBytes := protoutil.MarshalOrPanic(&common.Envelope{
Payload: []byte("not-a-payload"),
})
_, _, err := serialization.UnwrapEnvelope(envelopeBytes)
require.Error(t, err)
})

t.Run("OK Payload with a nil Header", func(t *testing.T) {
t.Parallel()
envelopeBytes := protoutil.MarshalOrPanic(&common.Envelope{
Payload: protoutil.MarshalOrPanic(&common.Payload{
Header: nil,
Data: []byte("some data"),
}),
})

_, _, err := serialization.UnwrapEnvelope(envelopeBytes)
require.Error(t, err)
})

t.Run("OK payload but invalid ChannelHeader", func(t *testing.T) {
t.Parallel()
envelopeBytes := protoutil.MarshalOrPanic(&common.Envelope{
Payload: protoutil.MarshalOrPanic(&common.Payload{
Header: &common.Header{
ChannelHeader: []byte("not-a-channel-header"),
},
Data: []byte("some data"),
}),
})

_, _, err := serialization.UnwrapEnvelope(envelopeBytes)
require.Error(t, err)
})
}

// TestUnwrapEnvelopeGoodInput Tests properly wrapped envelope is unwrapped correctly.
func TestUnwrapEnvelopeGoodInput(t *testing.T) {
t.Parallel()
expectedPayload := []byte("test payload")

expectedChannelHeader := &common.ChannelHeader{
ChannelId: "test-channel",
}

// Wrap
wrappedEnvelope := protoutil.MarshalOrPanic(&common.Envelope{
Payload: protoutil.MarshalOrPanic(&common.Payload{
Header: &common.Header{
ChannelHeader: protoutil.MarshalOrPanic(expectedChannelHeader),
},
Data: expectedPayload,
}),
})

// Unwrap
actualPayload, actualChannelHeader, err := serialization.UnwrapEnvelope(wrappedEnvelope)

// -Check 1- Check unwrap envelope has no error
require.NoError(t, err)

// -Check 2- Check we get the correct Payload & Header
require.Equal(t, expectedPayload, actualPayload)
test.RequireProtoEqual(t, expectedChannelHeader, actualChannelHeader)
}
7 changes: 7 additions & 0 deletions utils/signature/sigtest/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (

// SerializeVerificationKey encodes a ECDSA public key into a PEM file.
func SerializeVerificationKey(key *ecdsa.PublicKey) ([]byte, error) {
if key == nil {
return nil, errors.New("key is nil")
}
x509encodedPub, err := x509.MarshalPKIXPublicKey(key)
if err != nil {
return nil, errors.Wrap(err, "cannot serialize public key")
Expand All @@ -32,6 +35,10 @@ func SerializeVerificationKey(key *ecdsa.PublicKey) ([]byte, error) {

// SerializeSigningKey encodes a ECDSA private key into a PEM file.
func SerializeSigningKey(key *ecdsa.PrivateKey) ([]byte, error) {
if key == nil {
return nil, errors.New("key is nil")
}

x509encodedPri, err := x509.MarshalECPrivateKey(key)
if err != nil {
return nil, errors.Wrap(err, "cannot serialize private key")
Expand Down
92 changes: 92 additions & 0 deletions utils/signature/sigtest/crypto_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package sigtest

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"fmt"
"testing"

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

func TestVerificationAndSigningKeys(t *testing.T) {
t.Parallel()
tests := []struct {
name string
curve elliptic.Curve
}{
{
name: "P256",
curve: elliptic.P256(),
},
{
name: "P384",
curve: elliptic.P384(),
},
{
name: "P224",
curve: elliptic.P224(),
},
{
name: "P521",
curve: elliptic.P521(),
},
}

for _, tt := range tests {
t.Run(fmt.Sprintf("Serialize %s VerificationKey", tt.name),
func(t *testing.T) {
t.Parallel()

privKey, err := ecdsa.GenerateKey(tt.curve, rand.Reader)
require.NoError(t, err)
require.NotNil(t, privKey)

_, err = SerializeVerificationKey(&privKey.PublicKey)
require.NoError(t, err)
})

t.Run(fmt.Sprintf("Serialize and Parse %s SigningKey", tt.name),
func(t *testing.T) {
t.Parallel()
privateKey, err := ecdsa.GenerateKey(tt.curve, rand.Reader)
require.NoError(t, err)
key, err := SerializeSigningKey(privateKey)
require.NotNil(t, key)
require.NoError(t, err)

_, err = ParseSigningKey(key)
require.NoError(t, err)
})
}

t.Run("Signing Key Empty", func(t *testing.T) {
t.Parallel()
_, err := SerializeSigningKey(&ecdsa.PrivateKey{})
require.Error(t, err)
})

t.Run("Signing Key is nil", func(t *testing.T) {
t.Parallel()
_, err := SerializeSigningKey(nil)
require.Error(t, err)
})

t.Run("Verification Key Empty", func(t *testing.T) {
t.Parallel()
_, err := SerializeVerificationKey(&ecdsa.PublicKey{})
require.Error(t, err)
})

t.Run("Verification Key is nil", func(t *testing.T) {
t.Parallel()
_, err := SerializeVerificationKey(nil)
require.Error(t, err)
})
}