gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/lib/server/idemix/revocationkey.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package idemix 8 9 import ( 10 "encoding/pem" 11 "io/ioutil" 12 13 "gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/util" 14 "gitee.com/zhaochuninhefei/gmgo/sm2" 15 "gitee.com/zhaochuninhefei/gmgo/x509" 16 log "gitee.com/zhaochuninhefei/zcgolog/zclog" 17 "github.com/pkg/errors" 18 ) 19 20 // RevocationKey represents issuer revocation public and private key 21 type RevocationKey interface { 22 // Load loads this revocation key from the disk 23 Load() error 24 // Store stores this revocation key to the disk 25 Store() error 26 // GetKey returns *sm2.PrivateKey that represents revocation public and private key pair 27 GetKey() *sm2.PrivateKey 28 // SetKey sets revocation public and private key 29 SetKey(key *sm2.PrivateKey) 30 // SetNewKey creates new revocation public and private key pair and sets them in this object 31 SetNewKey() error 32 } 33 34 // caIdemixRevocationKey implements RevocationKey interface 35 type caIdemixRevocationKey struct { 36 pubKeyFile string 37 privateKeyFile string 38 key *sm2.PrivateKey 39 idemixLib Lib 40 } 41 42 // NewRevocationKey returns an instance of an object that implements RevocationKey interface 43 func NewRevocationKey(pubKeyFile, privateKeyFile string, lib Lib) RevocationKey { 44 return &caIdemixRevocationKey{ 45 pubKeyFile: pubKeyFile, 46 privateKeyFile: privateKeyFile, 47 idemixLib: lib, 48 } 49 } 50 51 // Load loads the Issuer revocation public and private key from the location specified 52 // by pubKeyFile and privateKeyFile attributes, respectively 53 func (rk *caIdemixRevocationKey) Load() error { 54 pubKeyBytes, err := ioutil.ReadFile(rk.pubKeyFile) 55 if err != nil { 56 return errors.Wrapf(err, "Failed to read revocation public key from %s", rk.pubKeyFile) 57 } 58 if len(pubKeyBytes) == 0 { 59 return errors.New("Revocation public key file is empty") 60 } 61 privKey, err := ioutil.ReadFile(rk.privateKeyFile) 62 if err != nil { 63 return errors.Wrapf(err, "Failed to read revocation private key from %s", rk.privateKeyFile) 64 } 65 if len(privKey) == 0 { 66 return errors.New("Revocation private key file is empty") 67 } 68 pk, pubKey, err := DecodeKeys(privKey, pubKeyBytes) 69 if err != nil { 70 return errors.WithMessage(err, "Failed to decode revocation key") 71 } 72 pk.PublicKey = *pubKey 73 rk.key = pk 74 return nil 75 } 76 77 // Store stores the CA's Idemix public and private key to the location 78 // specified by pubKeyFile and secretKeyFile attributes, respectively 79 func (rk *caIdemixRevocationKey) Store() error { 80 pk := rk.GetKey() 81 if pk == nil { 82 return errors.New("Revocation key is not set") 83 } 84 pkBytes, pubKeyBytes, err := EncodeKeys(pk, &pk.PublicKey) 85 if err != nil { 86 return errors.WithMessage(err, "Failed to encode revocation public key") 87 } 88 err = util.WriteFile(rk.privateKeyFile, []byte(pkBytes), 0644) 89 if err != nil { 90 log.Errorf("Failed to store revocation private key: %s", err.Error()) 91 return errors.Wrapf(err, "Failed to store revocation private key at %s", rk.privateKeyFile) 92 } 93 94 err = util.WriteFile(rk.pubKeyFile, []byte(pubKeyBytes), 0644) 95 if err != nil { 96 log.Errorf("Failed to store revocation public key: %s", err.Error()) 97 return errors.Wrapf(err, "Failed to store revocation public key at %s", rk.pubKeyFile) 98 } 99 100 log.Infof("The revocation key was successfully stored. The public key is at: %s, private key is at: %s", 101 rk.pubKeyFile, rk.privateKeyFile) 102 return nil 103 } 104 105 // GetKey returns revocation key 106 func (rk *caIdemixRevocationKey) GetKey() *sm2.PrivateKey { 107 return rk.key 108 } 109 110 // SetKey sets revocation key 111 func (rk *caIdemixRevocationKey) SetKey(key *sm2.PrivateKey) { 112 rk.key = key 113 } 114 115 // SetNewKey creates new revocation key and sets it in this object 116 func (rk *caIdemixRevocationKey) SetNewKey() (err error) { 117 rk.key, err = rk.idemixLib.GenerateLongTermRevocationKey() 118 return err 119 } 120 121 // EncodeKeys encodes ECDSA key pair to PEM encoding 122 func EncodeKeys(privateKey *sm2.PrivateKey, publicKey *sm2.PublicKey) ([]byte, []byte, error) { 123 encodedPK, err := x509.MarshalECPrivateKey(privateKey) 124 if err != nil { 125 return nil, nil, errors.Wrap(err, "Failed to encode ECDSA private key") 126 } 127 pemEncodedPK := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedPK}) 128 129 encodedPubKey, err := x509.MarshalPKIXPublicKey(publicKey) 130 if err != nil { 131 return nil, nil, errors.Wrap(err, "Failed to encode ECDSA public key") 132 } 133 pemEncodedPubKey := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: encodedPubKey}) 134 return pemEncodedPK, pemEncodedPubKey, nil 135 } 136 137 // DecodeKeys decodes SM2 key pair that are pem encoded 138 func DecodeKeys(pemEncodedPK, pemEncodedPubKey []byte) (*sm2.PrivateKey, *sm2.PublicKey, error) { 139 block, _ := pem.Decode(pemEncodedPK) 140 if block == nil { 141 return nil, nil, errors.New("Failed to decode ECDSA private key") 142 } 143 ecPriv, err := x509.ParseECPrivateKey(block.Bytes) 144 if err != nil { 145 return nil, nil, errors.Wrap(err, "Failed to parse ECDSA private key bytes") 146 } 147 sm2Priv, ok := ecPriv.(*sm2.PrivateKey) 148 if !ok { 149 return nil, nil, errors.Wrap(err, "pemEncodedPK is not sm2 PrivateKey") 150 } 151 blockPub, _ := pem.Decode(pemEncodedPubKey) 152 if blockPub == nil { 153 return nil, nil, errors.New("Failed to decode ECDSA public key") 154 } 155 key, err := x509.ParsePKIXPublicKey(blockPub.Bytes) 156 if err != nil { 157 return nil, nil, errors.Wrap(err, "Failed to parse ECDSA public key bytes") 158 } 159 publicKey := key.(*sm2.PublicKey) 160 // TODO 转为sm2的PublicKey 该步骤可能不需要 161 var puk sm2.PublicKey 162 puk.Curve = sm2.P256Sm2() 163 puk.X = publicKey.X 164 puk.Y = publicKey.Y 165 return sm2Priv, &puk, nil 166 }