github.com/kaituanwang/hyperledger@v2.0.1+incompatible/cmd/common/signer/signer.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package signer 8 9 import ( 10 "crypto/ecdsa" 11 "crypto/rand" 12 "crypto/x509" 13 "encoding/asn1" 14 "encoding/pem" 15 "io/ioutil" 16 "math/big" 17 18 "github.com/hyperledger/fabric-protos-go/msp" 19 "github.com/hyperledger/fabric/bccsp/utils" 20 "github.com/hyperledger/fabric/common/util" 21 "github.com/hyperledger/fabric/protoutil" 22 "github.com/pkg/errors" 23 ) 24 25 // Config holds the configuration for 26 // creation of a Signer 27 type Config struct { 28 MSPID string 29 IdentityPath string 30 KeyPath string 31 } 32 33 // Signer signs messages. 34 // TODO: Ideally we'd use an MSP to be agnostic, but since it's impossible to 35 // initialize an MSP without a CA cert that signs the signing identity, 36 // this will do for now. 37 type Signer struct { 38 key *ecdsa.PrivateKey 39 Creator []byte 40 } 41 42 func (si *Signer) Serialize() ([]byte, error) { 43 return si.Creator, nil 44 } 45 46 // NewSigner creates a new Signer out of the given configuration 47 func NewSigner(conf Config) (*Signer, error) { 48 sId, err := serializeIdentity(conf.IdentityPath, conf.MSPID) 49 if err != nil { 50 return nil, errors.WithStack(err) 51 } 52 key, err := loadPrivateKey(conf.KeyPath) 53 if err != nil { 54 return nil, errors.WithStack(err) 55 } 56 return &Signer{ 57 Creator: sId, 58 key: key, 59 }, nil 60 } 61 62 func serializeIdentity(clientCert string, mspID string) ([]byte, error) { 63 b, err := ioutil.ReadFile(clientCert) 64 if err != nil { 65 return nil, errors.WithStack(err) 66 } 67 sId := &msp.SerializedIdentity{ 68 Mspid: mspID, 69 IdBytes: b, 70 } 71 return protoutil.MarshalOrPanic(sId), nil 72 } 73 74 func (si *Signer) Sign(msg []byte) ([]byte, error) { 75 digest := util.ComputeSHA256(msg) 76 return signECDSA(si.key, digest) 77 } 78 79 func loadPrivateKey(file string) (*ecdsa.PrivateKey, error) { 80 b, err := ioutil.ReadFile(file) 81 if err != nil { 82 return nil, errors.WithStack(err) 83 } 84 bl, _ := pem.Decode(b) 85 if bl == nil { 86 return nil, errors.Errorf("failed to decode PEM block from %s", file) 87 } 88 key, err := x509.ParsePKCS8PrivateKey(bl.Bytes) 89 if err != nil { 90 return nil, errors.Wrapf(err, "failed to parse private key from %s", file) 91 } 92 return key.(*ecdsa.PrivateKey), nil 93 } 94 95 func signECDSA(k *ecdsa.PrivateKey, digest []byte) (signature []byte, err error) { 96 r, s, err := ecdsa.Sign(rand.Reader, k, digest) 97 if err != nil { 98 return nil, err 99 } 100 101 s, _, err = utils.ToLowS(&k.PublicKey, s) 102 if err != nil { 103 return nil, err 104 } 105 106 return marshalECDSASignature(r, s) 107 } 108 109 func marshalECDSASignature(r, s *big.Int) ([]byte, error) { 110 return asn1.Marshal(ECDSASignature{r, s}) 111 } 112 113 type ECDSASignature struct { 114 R, S *big.Int 115 }