github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/bccsp/idemix/handlers/revocation.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  package handlers
     7  
     8  import (
     9  	"crypto/elliptic"
    10  	"encoding/pem"
    11  	"fmt"
    12  	"reflect"
    13  
    14  	"github.com/hellobchain/newcryptosm"
    15  	"github.com/hellobchain/newcryptosm/ecdsa"
    16  	"github.com/hellobchain/newcryptosm/x509"
    17  
    18  	"github.com/hellobchain/third_party/hyperledger/fabric/bccsp"
    19  	"github.com/pkg/errors"
    20  )
    21  
    22  // revocationSecretKey contains the revocation secret key
    23  // and implements the bccsp.Key interface
    24  type revocationSecretKey struct {
    25  	// sk is the idemix reference to the revocation key
    26  	privKey *ecdsa.PrivateKey
    27  	// exportable if true, sk can be exported via the Bytes function
    28  	exportable bool
    29  }
    30  
    31  func NewRevocationSecretKey(sk *ecdsa.PrivateKey, exportable bool) *revocationSecretKey {
    32  	return &revocationSecretKey{privKey: sk, exportable: exportable}
    33  }
    34  
    35  // Bytes converts this key to its byte representation,
    36  // if this operation is allowed.
    37  func (k *revocationSecretKey) Bytes() ([]byte, error) {
    38  	if k.exportable {
    39  		return k.privKey.D.Bytes(), nil
    40  	}
    41  
    42  	return nil, errors.New("not exportable")
    43  }
    44  
    45  // SKI returns the subject key identifier of this key.
    46  func (k *revocationSecretKey) SKI() []byte {
    47  	// Marshall the public key
    48  	raw := elliptic.Marshal(k.privKey.Curve, k.privKey.PublicKey.X, k.privKey.PublicKey.Y)
    49  
    50  	// Hash it
    51  	hash := newcryptosm.SHA256.New()
    52  	if ecdsa.IsSM2(k.privKey.Params()) {
    53  		hash = newcryptosm.SM3.New()
    54  	}
    55  	hash.Write(raw)
    56  	return hash.Sum(nil)
    57  }
    58  
    59  // Symmetric returns true if this key is a symmetric key,
    60  // false if this key is asymmetric
    61  func (k *revocationSecretKey) Symmetric() bool {
    62  	return false
    63  }
    64  
    65  // Private returns true if this key is a private key,
    66  // false otherwise.
    67  func (k *revocationSecretKey) Private() bool {
    68  	return true
    69  }
    70  
    71  // PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
    72  // This method returns an error in symmetric key schemes.
    73  func (k *revocationSecretKey) PublicKey() (bccsp.Key, error) {
    74  	return &revocationPublicKey{&k.privKey.PublicKey}, nil
    75  }
    76  
    77  type revocationPublicKey struct {
    78  	pubKey *ecdsa.PublicKey
    79  }
    80  
    81  func NewRevocationPublicKey(pubKey *ecdsa.PublicKey) *revocationPublicKey {
    82  	return &revocationPublicKey{pubKey: pubKey}
    83  }
    84  
    85  // Bytes converts this key to its byte representation,
    86  // if this operation is allowed.
    87  func (k *revocationPublicKey) Bytes() (raw []byte, err error) {
    88  	raw, err = x509.MarshalPKIXPublicKey(k.pubKey)
    89  	if err != nil {
    90  		return nil, fmt.Errorf("Failed marshalling key [%s]", err)
    91  	}
    92  	return
    93  }
    94  
    95  // SKI returns the subject key identifier of this key.
    96  func (k *revocationPublicKey) SKI() []byte {
    97  	// Marshall the public key
    98  	raw := elliptic.Marshal(k.pubKey.Curve, k.pubKey.X, k.pubKey.Y)
    99  
   100  	// Hash it
   101  	hash := newcryptosm.SHA256.New()
   102  	if ecdsa.IsSM2(k.pubKey.Params()) {
   103  		hash = newcryptosm.SM3.New()
   104  	}
   105  	hash.Write(raw)
   106  	return hash.Sum(nil)
   107  }
   108  
   109  // Symmetric returns true if this key is a symmetric key,
   110  // false if this key is asymmetric
   111  func (k *revocationPublicKey) Symmetric() bool {
   112  	return false
   113  }
   114  
   115  // Private returns true if this key is a private key,
   116  // false otherwise.
   117  func (k *revocationPublicKey) Private() bool {
   118  	return false
   119  }
   120  
   121  // PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
   122  // This method returns an error in symmetric key schemes.
   123  func (k *revocationPublicKey) PublicKey() (bccsp.Key, error) {
   124  	return k, nil
   125  }
   126  
   127  // RevocationKeyGen generates revocation secret keys.
   128  type RevocationKeyGen struct {
   129  	// exportable is a flag to allow an revocation secret key to be marked as exportable.
   130  	// If a secret key is marked as exportable, its Bytes method will return the key's byte representation.
   131  	Exportable bool
   132  	// Revocation implements the underlying cryptographic algorithms
   133  	Revocation Revocation
   134  }
   135  
   136  func (g *RevocationKeyGen) KeyGen(opts bccsp.KeyGenOpts) (bccsp.Key, error) {
   137  	// Create a new key pair
   138  	key, err := g.Revocation.NewKey()
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  
   143  	return &revocationSecretKey{exportable: g.Exportable, privKey: key}, nil
   144  }
   145  
   146  // RevocationPublicKeyImporter imports revocation public keys
   147  type RevocationPublicKeyImporter struct {
   148  }
   149  
   150  func (i *RevocationPublicKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
   151  	der, ok := raw.([]byte)
   152  	if !ok {
   153  		return nil, errors.New("invalid raw, expected byte array")
   154  	}
   155  
   156  	if len(der) == 0 {
   157  		return nil, errors.New("invalid raw, it must not be nil")
   158  	}
   159  
   160  	blockPub, _ := pem.Decode(raw.([]byte))
   161  	if blockPub == nil {
   162  		return nil, errors.New("Failed to decode revocation ECDSA public key")
   163  	}
   164  	revocationPk, err := x509.ParsePKIXPublicKey(blockPub.Bytes)
   165  	if err != nil {
   166  		return nil, errors.Wrap(err, "Failed to parse revocation ECDSA public key bytes")
   167  	}
   168  	ecdsaPublicKey, isECDSA := revocationPk.(*ecdsa.PublicKey)
   169  	if !isECDSA {
   170  		return nil, errors.Errorf("key is of type %v, not of type ECDSA", reflect.TypeOf(revocationPk))
   171  	}
   172  
   173  	return &revocationPublicKey{ecdsaPublicKey}, nil
   174  }
   175  
   176  type CriSigner struct {
   177  	Revocation Revocation
   178  }
   179  
   180  func (s *CriSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) ([]byte, error) {
   181  	revocationSecretKey, ok := k.(*revocationSecretKey)
   182  	if !ok {
   183  		return nil, errors.New("invalid key, expected *revocationSecretKey")
   184  	}
   185  	criOpts, ok := opts.(*bccsp.IdemixCRISignerOpts)
   186  	if !ok {
   187  		return nil, errors.New("invalid options, expected *IdemixCRISignerOpts")
   188  	}
   189  
   190  	return s.Revocation.Sign(
   191  		revocationSecretKey.privKey,
   192  		criOpts.UnrevokedHandles,
   193  		criOpts.Epoch,
   194  		criOpts.RevocationAlgorithm,
   195  	)
   196  }
   197  
   198  type CriVerifier struct {
   199  	Revocation Revocation
   200  }
   201  
   202  func (v *CriVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (bool, error) {
   203  	revocationPublicKey, ok := k.(*revocationPublicKey)
   204  	if !ok {
   205  		return false, errors.New("invalid key, expected *revocationPublicKey")
   206  	}
   207  	criOpts, ok := opts.(*bccsp.IdemixCRISignerOpts)
   208  	if !ok {
   209  		return false, errors.New("invalid options, expected *IdemixCRISignerOpts")
   210  	}
   211  	if len(signature) == 0 {
   212  		return false, errors.New("invalid signature, it must not be empty")
   213  	}
   214  
   215  	err := v.Revocation.Verify(
   216  		revocationPublicKey.pubKey,
   217  		signature,
   218  		criOpts.Epoch,
   219  		criOpts.RevocationAlgorithm,
   220  	)
   221  	if err != nil {
   222  		return false, err
   223  	}
   224  
   225  	return true, nil
   226  }