Skip to content

Commit

Permalink
Simplify identity package implementation (#188)
Browse files Browse the repository at this point in the history
There is already a dependency on fabric-gateway so reuse similar
implementation provided by that package.

Signed-off-by: Mark S. Lewis <Mark.S.Lewis@outlook.com>
  • Loading branch information
bestbeforetoday authored Mar 23, 2024
1 parent d480efd commit 53f1d21
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 146 deletions.
105 changes: 9 additions & 96 deletions pkg/identity/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,107 +7,20 @@ package identity

import (
"crypto/ecdsa"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/pem"
"errors"
"fmt"
"math/big"
"os"
)

func ecdsaPrivateKeySign(privateKey *ecdsa.PrivateKey) signFn {
n := privateKey.Params().Params().N

return func(message []byte) ([]byte, error) {
digest := sha256.Sum256(message)
r, s, err := ecdsa.Sign(rand.Reader, privateKey, digest[:])
if err != nil {
return nil, err
}

s = canonicalECDSASignatureSValue(s, n)

return asn1ECDSASignature(r, s)
}
}

func canonicalECDSASignatureSValue(s *big.Int, curveN *big.Int) *big.Int {
halfOrder := new(big.Int).Rsh(curveN, 1)
if s.Cmp(halfOrder) <= 0 {
return s
}

// Set s to N - s so it is in the lower part of signature space, less or equal to half order
return new(big.Int).Sub(curveN, s)
}

type ecdsaSignature struct {
R, S *big.Int
}

func asn1ECDSASignature(r, s *big.Int) ([]byte, error) {
return asn1.Marshal(ecdsaSignature{
R: r,
S: s,
})
}

func ReadECDSAPrivateKey(f string) (*ecdsa.PrivateKey, error) {
in, err := os.ReadFile(f)
if err != nil {
return nil, err
}
"github.com/hyperledger/fabric-gateway/pkg/hash"
"github.com/hyperledger/fabric-gateway/pkg/identity"
)

k, err := privateKeyFromPEM(in)
func ecdsaPrivateKeySign(privateKey *ecdsa.PrivateKey) (signFn, error) {
sign, err := identity.NewPrivateKeySign(privateKey)
if err != nil {
return nil, err
}

key, ok := k.(*ecdsa.PrivateKey)
if !ok {
return nil, errors.New("expecting ecdsa key")
}

return key, nil
}

// privateKeyFromPEM unmarshals a pem to private key
func privateKeyFromPEM(raw []byte) (interface{}, error) {
if len(raw) == 0 {
return nil, errors.New("invalid PEM. It must be different from nil")
}
block, _ := pem.Decode(raw)
if block == nil {
return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil. [% x]", raw)
}
cert, err := privateKeyFromDER(block.Bytes)
if err != nil {
return nil, err
}
return cert, err
}

// privateKeyFromDER unmarshals a der to private key
func privateKeyFromDER(der []byte) (key interface{}, err error) {

if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
return key, nil
}

if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
switch key.(type) {
case *ecdsa.PrivateKey:
return
default:
return nil, errors.New("found unknown private key type in PKCS#8 wrapping")
}
}

if key, err = x509.ParseECPrivateKey(der); err != nil {
return nil, errors.New("invalid key type. The DER must contain an ecdsa.PrivateKey")
result := func(message []byte) ([]byte, error) {
digest := hash.SHA256(message)
return sign(digest)
}
return
return result, nil
}
25 changes: 16 additions & 9 deletions pkg/identity/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import (
"crypto"
"crypto/ecdsa"
"crypto/x509"
"encoding/pem"
"fmt"
"os"

"github.com/hyperledger/fabric-gateway/pkg/identity"
)

// Identity used to interact with a Fabric network.
Expand All @@ -32,7 +33,7 @@ type SigningIdentity interface {
}

func NewPrivateKeySigningIdentity(mspID string, certificate *x509.Certificate, privateKey crypto.PrivateKey) (SigningIdentity, error) {
credentials, err := certificateToPEM(certificate)
credentials, err := identity.CertificateToPEM(certificate)
if err != nil {
return nil, err
}
Expand All @@ -50,12 +51,12 @@ func NewPrivateKeySigningIdentity(mspID string, certificate *x509.Certificate, p
return id, nil
}

type signFn func([]byte) ([]byte, error)
type signFn func(message []byte) ([]byte, error)

func newPrivateKeySign(privateKey crypto.PrivateKey) (signFn, error) {
switch key := privateKey.(type) {
case *ecdsa.PrivateKey:
return ecdsaPrivateKeySign(key), nil
return ecdsaPrivateKeySign(key)
default:
return nil, fmt.Errorf("unsupported key type: %T", privateKey)
}
Expand All @@ -79,14 +80,20 @@ func (id *signingIdentity) Sign(message []byte) ([]byte, error) {
return id.sign(message)
}

func ReadCertificate(f string) (*x509.Certificate, []byte, error) {
func ReadCertificate(f string) (*x509.Certificate, error) {
in, err := os.ReadFile(f)
if err != nil {
return nil, nil, err
return nil, err
}

block, _ := pem.Decode(in)
return identity.CertificateFromPEM(in)
}

func ReadPrivateKey(f string) (crypto.PrivateKey, error) {
in, err := os.ReadFile(f)
if err != nil {
return nil, err
}

c, err := x509.ParseCertificate(block.Bytes)
return c, in, err
return identity.PrivateKeyFromPEM(in)
}
29 changes: 0 additions & 29 deletions pkg/identity/pem.go

This file was deleted.

16 changes: 8 additions & 8 deletions test/channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ var _ = Describe("channel", func() {
peerConnection, err := network.DialConnection(peer1)
Expect(err).NotTo(HaveOccurred())

cert, _, err := identity.ReadCertificate(SignCert)
cert, err := identity.ReadCertificate(SignCert)
Expect(err).NotTo(HaveOccurred())

priv, err := identity.ReadECDSAPrivateKey(PrivKeyPath)
priv, err := identity.ReadPrivateKey(PrivKeyPath)
Expect(err).NotTo(HaveOccurred())

id, err := identity.NewPrivateKeySigningIdentity(MSPID, cert, priv)
Expand Down Expand Up @@ -105,10 +105,10 @@ var _ = Describe("channel", func() {
peerConnection, err := network.DialConnection(peer1)
Expect(err).NotTo(HaveOccurred())

cert, _, err := identity.ReadCertificate(SignCert)
cert, err := identity.ReadCertificate(SignCert)
Expect(err).NotTo(HaveOccurred())

priv, err := identity.ReadECDSAPrivateKey(PrivKeyPath)
priv, err := identity.ReadPrivateKey(PrivKeyPath)
Expect(err).NotTo(HaveOccurred())

id, err := identity.NewPrivateKeySigningIdentity(MSPID, cert, priv)
Expand Down Expand Up @@ -142,19 +142,19 @@ var _ = Describe("channel", func() {
var PrivKeyPath2 = "../fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore/priv_sk"
var SignCertPath2 = "../fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts/Admin@org2.example.com-cert.pem"

cert, _, err := identity.ReadCertificate(SignCertPath)
cert, err := identity.ReadCertificate(SignCertPath)
Expect(err).NotTo(HaveOccurred())

priv, err := identity.ReadECDSAPrivateKey(PrivKeyPath)
priv, err := identity.ReadPrivateKey(PrivKeyPath)
Expect(err).NotTo(HaveOccurred())

signer, err := identity.NewPrivateKeySigningIdentity(MSPID, cert, priv)
Expect(err).NotTo(HaveOccurred())

cert2, _, err := identity.ReadCertificate(SignCertPath2)
cert2, err := identity.ReadCertificate(SignCertPath2)
Expect(err).NotTo(HaveOccurred())

priv2, err := identity.ReadECDSAPrivateKey(PrivKeyPath2)
priv2, err := identity.ReadPrivateKey(PrivKeyPath2)
Expect(err).NotTo(HaveOccurred())

signer2, err := identity.NewPrivateKeySigningIdentity(MSPID2, cert2, priv2)
Expand Down
8 changes: 4 additions & 4 deletions test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ var _ = Describe("e2e", func() {
peer1Connection, err := network.DialConnection(peer1)
Expect(err).NotTo(HaveOccurred())

cert, _, err := identity.ReadCertificate(SignCert)
cert, err := identity.ReadCertificate(SignCert)
Expect(err).NotTo(HaveOccurred())

priv, err := identity.ReadECDSAPrivateKey(PrivKeyPath)
priv, err := identity.ReadPrivateKey(PrivKeyPath)
Expect(err).NotTo(HaveOccurred())

org1MSP, err := identity.NewPrivateKeySigningIdentity(org1MspID, cert, priv)
Expand All @@ -140,10 +140,10 @@ var _ = Describe("e2e", func() {
peer2Connection, err := network.DialConnection(peer2)
Expect(err).NotTo(HaveOccurred())

cert2, _, err := identity.ReadCertificate(SignCert)
cert2, err := identity.ReadCertificate(SignCert)
Expect(err).NotTo(HaveOccurred())

priv2, err := identity.ReadECDSAPrivateKey(PrivKeyPath)
priv2, err := identity.ReadPrivateKey(PrivKeyPath)
Expect(err).NotTo(HaveOccurred())

org2MSP, err := identity.NewPrivateKeySigningIdentity(org2MspID, cert2, priv2)
Expand Down

0 comments on commit 53f1d21

Please sign in to comment.