Skip to content

Commit 6113fec

Browse files
authored
sign method with norm s and signed txs (#335)
* sign method with norm s and signed txs Signed-off-by: May.Buzaglo <[email protected]> * create signed env method and test sign Signed-off-by: May.Buzaglo <[email protected]> * signer argument Signed-off-by: May.Buzaglo <[email protected]> --------- Signed-off-by: May.Buzaglo <[email protected]>
1 parent 3a395fc commit 6113fec

File tree

3 files changed

+115
-3
lines changed

3 files changed

+115
-3
lines changed

node/crypto/signer.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,39 @@ package crypto
99
import (
1010
"crypto/ecdsa"
1111
"crypto/rand"
12-
"crypto/sha256"
12+
"encoding/asn1"
13+
"math/big"
14+
15+
"github.com/hyperledger/fabric-lib-go/bccsp/utils"
16+
"github.com/hyperledger/fabric-x-common/common/util"
1317
)
1418

1519
type ECDSASigner ecdsa.PrivateKey
1620

1721
func (s ECDSASigner) Sign(message []byte) ([]byte, error) {
18-
digest := sha256.Sum256(message)
22+
digest := util.ComputeSHA256(message)
1923
sk := (ecdsa.PrivateKey)(s)
20-
return sk.Sign(rand.Reader, digest[:], nil)
24+
return signECDSA(&sk, digest)
25+
}
26+
27+
func signECDSA(k *ecdsa.PrivateKey, digest []byte) (signature []byte, err error) {
28+
r, s, err := ecdsa.Sign(rand.Reader, k, digest)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
s, err = utils.ToLowS(&k.PublicKey, s)
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
return marshalECDSASignature(r, s)
39+
}
40+
41+
func marshalECDSASignature(r, s *big.Int) ([]byte, error) {
42+
return asn1.Marshal(ECDSASignature{r, s})
43+
}
44+
45+
type ECDSASignature struct {
46+
R, S *big.Int
2147
}

node/crypto/signer_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package crypto_test
8+
9+
import (
10+
"crypto/ecdsa"
11+
"testing"
12+
13+
"github.com/hyperledger/fabric-lib-go/bccsp/utils"
14+
"github.com/hyperledger/fabric-x-common/common/util"
15+
"github.com/hyperledger/fabric-x-orderer/internal/cryptogen/csp"
16+
"github.com/hyperledger/fabric-x-orderer/node/crypto"
17+
"github.com/stretchr/testify/require"
18+
)
19+
20+
func TestECDSASigner(t *testing.T) {
21+
// Generate a private key
22+
dir := t.TempDir()
23+
cryptoPrivateKey, err := csp.GeneratePrivateKey(dir, "ecdsa")
24+
require.NoError(t, err)
25+
ecdsaPrivateKey := cryptoPrivateKey.(*ecdsa.PrivateKey)
26+
signer := crypto.ECDSASigner(*ecdsaPrivateKey)
27+
28+
// Sign a message
29+
msg := []byte("foo")
30+
sig, err := signer.Sign(msg)
31+
require.NoError(t, err)
32+
33+
// Verify the signature over the massage
34+
r, s, err := utils.UnmarshalECDSASignature(sig)
35+
require.NoError(t, err)
36+
verify := ecdsa.Verify(&((*ecdsa.PrivateKey)(&signer).PublicKey), util.ComputeSHA256(msg), r, s)
37+
require.True(t, verify)
38+
}

testutil/tx/tx_utils.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@ package tx
88

99
import (
1010
"bytes"
11+
"crypto/ecdsa"
12+
"crypto/x509"
1113
"encoding/binary"
14+
"encoding/pem"
1215
"fmt"
16+
"strings"
1317
"time"
1418

1519
"github.com/hyperledger/fabric-protos-go-apiv2/common"
1620
"github.com/hyperledger/fabric-x-common/protoutil"
21+
"github.com/hyperledger/fabric-x-orderer/node/crypto"
1722
protos "github.com/hyperledger/fabric-x-orderer/node/protos/comm"
1823
"google.golang.org/protobuf/proto"
1924
)
@@ -64,6 +69,49 @@ func CreateStructuredEnvelope(data []byte) *common.Envelope {
6469
}
6570
}
6671

72+
// CreateSignedEnvelope creates a dummy data transaction signed by a private key of a client.
73+
func CreateSignedEnvelope(payloadData []byte, signer *crypto.ECDSASigner) (*common.Envelope, error) {
74+
payload := createStructuredPayload(payloadData, common.HeaderType_MESSAGE)
75+
payloadBytes := deterministicMarshall(payload)
76+
signedEnvelope, err := signEnvelope(payloadBytes, signer)
77+
if err != nil {
78+
return nil, fmt.Errorf("failed to sign envelope")
79+
}
80+
return signedEnvelope, nil
81+
}
82+
83+
// CreateECDSASigner reads a private key from the given path and creates a signer.
84+
func CreateECDSASigner(privateKeyBytes []byte) (*crypto.ECDSASigner, error) {
85+
block, _ := pem.Decode(privateKeyBytes)
86+
if block == nil || block.Bytes == nil {
87+
return nil, fmt.Errorf("failed decoding private key PEM")
88+
}
89+
90+
if block.Type != "PRIVATE KEY" {
91+
return nil, fmt.Errorf("unexpected pem type, got a %s", strings.ToLower(block.Type))
92+
}
93+
94+
priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
95+
if err != nil {
96+
return nil, fmt.Errorf("failed parsing private key DER: %v", err)
97+
}
98+
99+
return (*crypto.ECDSASigner)(priv.(*ecdsa.PrivateKey)), nil
100+
}
101+
102+
func signEnvelope(payload []byte, signer *crypto.ECDSASigner) (*common.Envelope, error) {
103+
signature, err := signer.Sign(payload)
104+
if err != nil {
105+
return nil, err
106+
}
107+
108+
envelope := &common.Envelope{
109+
Payload: payload,
110+
Signature: signature,
111+
}
112+
return envelope, nil
113+
}
114+
67115
func CreateStructuredConfigEnvelope(data []byte) *common.Envelope {
68116
payload := createStructuredPayload(data, common.HeaderType_CONFIG_UPDATE)
69117
payloadBytes := deterministicMarshall(payload)

0 commit comments

Comments
 (0)