github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/bccsp/sw/impl.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  package sw
    17  
    18  import (
    19  	"github.com/hellobchain/wswlog/wlogging"
    20  	"hash"
    21  	"reflect"
    22  
    23  	"github.com/pkg/errors"
    24  	"github.com/hellobchain/third_party/hyperledger/fabric/bccsp"
    25  )
    26  
    27  var _ bccsp.BCCSP = (*CSP)(nil)
    28  
    29  var logger = wlogging.MustGetLoggerWithoutName()
    30  
    31  // CSP provides a generic implementation of the BCCSP interface based
    32  // on wrappers. It can be customized by providing implementations for the
    33  // following algorithm-based wrappers: KeyGenerator, KeyDeriver, KeyImporter,
    34  // Encryptor, Decryptor, Signer, Verifier, Hasher. Each wrapper is bound to a
    35  // goland type representing either an option or a key.
    36  type CSP struct {
    37  	ks bccsp.KeyStore
    38  
    39  	KeyGenerators map[reflect.Type]KeyGenerator
    40  	KeyDerivers   map[reflect.Type]KeyDeriver
    41  	KeyImporters  map[reflect.Type]KeyImporter
    42  	Encryptors    map[reflect.Type]Encryptor
    43  	Decryptors    map[reflect.Type]Decryptor
    44  	Signers       map[reflect.Type]Signer
    45  	Verifiers     map[reflect.Type]Verifier
    46  	Hashers       map[reflect.Type]Hasher
    47  }
    48  
    49  func New(keyStore bccsp.KeyStore) (*CSP, error) {
    50  	if keyStore == nil {
    51  		return nil, errors.Errorf("Invalid bccsp.KeyStore instance. It must be different from nil.")
    52  	}
    53  
    54  	encryptors := make(map[reflect.Type]Encryptor)
    55  	decryptors := make(map[reflect.Type]Decryptor)
    56  	signers := make(map[reflect.Type]Signer)
    57  	verifiers := make(map[reflect.Type]Verifier)
    58  	hashers := make(map[reflect.Type]Hasher)
    59  	keyGenerators := make(map[reflect.Type]KeyGenerator)
    60  	keyDerivers := make(map[reflect.Type]KeyDeriver)
    61  	keyImporters := make(map[reflect.Type]KeyImporter)
    62  
    63  	csp := &CSP{
    64  		keyStore,
    65  		keyGenerators, keyDerivers, keyImporters, encryptors,
    66  		decryptors, signers, verifiers, hashers,
    67  	}
    68  
    69  	return csp, nil
    70  }
    71  func (csp *CSP) GetName() string {
    72  	return "SW"
    73  }
    74  
    75  // KeyGen generates a key using opts.
    76  func (csp *CSP) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
    77  	// Validate arguments
    78  	if opts == nil {
    79  		return nil, errors.New("Invalid Opts parameter. It must not be nil.")
    80  	}
    81  
    82  	keyGenerator, found := csp.KeyGenerators[reflect.TypeOf(opts)]
    83  	if !found {
    84  		return nil, errors.Errorf("Unsupported 'KeyGenOpts' provided [%v]", opts)
    85  	}
    86  
    87  	k, err = keyGenerator.KeyGen(opts)
    88  	if err != nil {
    89  		return nil, errors.Wrapf(err, "Failed generating key with opts [%v]", opts)
    90  	}
    91  
    92  	// If the key is not Ephemeral, store it.
    93  	if !opts.Ephemeral() {
    94  		// Store the key
    95  		err = csp.ks.StoreKey(k)
    96  		if err != nil {
    97  			return nil, errors.Wrapf(err, "Failed storing key [%s]", opts.Algorithm())
    98  		}
    99  	}
   100  
   101  	return k, nil
   102  }
   103  
   104  // KeyDeriv derives a key from k using opts.
   105  // The opts argument should be appropriate for the primitive used.
   106  func (csp *CSP) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) {
   107  	// Validate arguments
   108  	if k == nil {
   109  		return nil, errors.New("Invalid Key. It must not be nil.")
   110  	}
   111  	if opts == nil {
   112  		return nil, errors.New("Invalid opts. It must not be nil.")
   113  	}
   114  
   115  	keyDeriver, found := csp.KeyDerivers[reflect.TypeOf(k)]
   116  	if !found {
   117  		return nil, errors.Errorf("Unsupported 'Key' provided [%v]", k)
   118  	}
   119  
   120  	k, err = keyDeriver.KeyDeriv(k, opts)
   121  	if err != nil {
   122  		return nil, errors.Wrapf(err, "Failed deriving key with opts [%v]", opts)
   123  	}
   124  
   125  	// If the key is not Ephemeral, store it.
   126  	if !opts.Ephemeral() {
   127  		// Store the key
   128  		err = csp.ks.StoreKey(k)
   129  		if err != nil {
   130  			return nil, errors.Wrapf(err, "Failed storing key [%s]", opts.Algorithm())
   131  		}
   132  	}
   133  
   134  	return k, nil
   135  }
   136  
   137  // KeyImport imports a key from its raw representation using opts.
   138  // The opts argument should be appropriate for the primitive used.
   139  func (csp *CSP) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
   140  	// Validate arguments
   141  	if raw == nil {
   142  		return nil, errors.New("Invalid raw. It must not be nil.")
   143  	}
   144  	if opts == nil {
   145  		return nil, errors.New("Invalid opts. It must not be nil.")
   146  	}
   147  
   148  	keyImporter, found := csp.KeyImporters[reflect.TypeOf(opts)]
   149  	if !found {
   150  		return nil, errors.Errorf("Unsupported 'KeyImportOpts' provided [%v]", opts)
   151  	}
   152  
   153  	k, err = keyImporter.KeyImport(raw, opts)
   154  	if err != nil {
   155  		return nil, errors.Wrapf(err, "Failed importing key with opts [%v]", opts)
   156  	}
   157  
   158  	// If the key is not Ephemeral, store it.
   159  	if !opts.Ephemeral() {
   160  		// Store the key
   161  		err = csp.ks.StoreKey(k)
   162  		if err != nil {
   163  			return nil, errors.Wrapf(err, "Failed storing imported key with opts [%v]", opts)
   164  		}
   165  	}
   166  
   167  	return
   168  }
   169  
   170  // GetKey returns the key this CSP associates to
   171  // the Subject Key Identifier ski.
   172  func (csp *CSP) GetKey(ski []byte) (k bccsp.Key, err error) {
   173  	k, err = csp.ks.GetKey(ski)
   174  	if err != nil {
   175  		return nil, errors.Wrapf(err, "Failed getting key for SKI [%v]", ski)
   176  	}
   177  
   178  	return
   179  }
   180  
   181  // Hash hashes messages msg using options opts.
   182  func (csp *CSP) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) {
   183  	// Validate arguments
   184  	if opts == nil {
   185  		return nil, errors.New("Invalid opts. It must not be nil.")
   186  	}
   187  
   188  	hasher, found := csp.Hashers[reflect.TypeOf(opts)]
   189  	if !found {
   190  		return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts)
   191  	}
   192  
   193  	digest, err = hasher.Hash(msg, opts)
   194  	if err != nil {
   195  		return nil, errors.Wrapf(err, "Failed hashing with opts [%v]", opts)
   196  	}
   197  
   198  	return
   199  }
   200  
   201  // GetHash returns and instance of hash.Hash using options opts.
   202  // If opts is nil then the default hash function is returned.
   203  func (csp *CSP) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) {
   204  	// Validate arguments
   205  	if opts == nil {
   206  		return nil, errors.New("Invalid opts. It must not be nil.")
   207  	}
   208  
   209  	hasher, found := csp.Hashers[reflect.TypeOf(opts)]
   210  	if !found {
   211  		return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts)
   212  	}
   213  
   214  	h, err = hasher.GetHash(opts)
   215  	if err != nil {
   216  		return nil, errors.Wrapf(err, "Failed getting hash function with opts [%v]", opts)
   217  	}
   218  
   219  	return
   220  }
   221  
   222  // Sign signs digest using key k.
   223  // The opts argument should be appropriate for the primitive used.
   224  //
   225  // Note that when a signature of a hash of a larger message is needed,
   226  // the caller is responsible for hashing the larger message and passing
   227  // the hash (as digest).
   228  func (csp *CSP) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
   229  	// Validate arguments
   230  	if k == nil {
   231  		return nil, errors.New("Invalid Key. It must not be nil.")
   232  	}
   233  	if len(digest) == 0 {
   234  		return nil, errors.New("Invalid digest. Cannot be empty.")
   235  	}
   236  
   237  	keyType := reflect.TypeOf(k)
   238  	signer, found := csp.Signers[keyType]
   239  	if !found {
   240  		return nil, errors.Errorf("Unsupported 'SignKey' provided [%s]", keyType)
   241  	}
   242  
   243  	signature, err = signer.Sign(k, digest, opts)
   244  	if err != nil {
   245  		return nil, errors.Wrapf(err, "Failed signing with opts [%v]", opts)
   246  	}
   247  
   248  	return
   249  }
   250  
   251  // Verify verifies signature against key k and digest
   252  func (csp *CSP) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
   253  	// Validate arguments
   254  	if k == nil {
   255  		return false, errors.New("Invalid Key. It must not be nil.")
   256  	}
   257  	if len(signature) == 0 {
   258  		return false, errors.New("Invalid signature. Cannot be empty.")
   259  	}
   260  	if len(digest) == 0 {
   261  		return false, errors.New("Invalid digest. Cannot be empty.")
   262  	}
   263  
   264  	verifier, found := csp.Verifiers[reflect.TypeOf(k)]
   265  	if !found {
   266  		return false, errors.Errorf("Unsupported 'VerifyKey' provided [%v]", k)
   267  	}
   268  
   269  	valid, err = verifier.Verify(k, signature, digest, opts)
   270  	if err != nil {
   271  		return false, errors.Wrapf(err, "Failed verifing with opts [%v]", opts)
   272  	}
   273  
   274  	return
   275  }
   276  
   277  // Encrypt encrypts plaintext using key k.
   278  // The opts argument should be appropriate for the primitive used.
   279  func (csp *CSP) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) ([]byte, error) {
   280  	// Validate arguments
   281  	if k == nil {
   282  		return nil, errors.New("Invalid Key. It must not be nil.")
   283  	}
   284  
   285  	encryptor, found := csp.Encryptors[reflect.TypeOf(k)]
   286  	if !found {
   287  		return nil, errors.Errorf("Unsupported 'EncryptKey' provided [%v]", k)
   288  	}
   289  
   290  	return encryptor.Encrypt(k, plaintext, opts)
   291  }
   292  
   293  // Decrypt decrypts ciphertext using key k.
   294  // The opts argument should be appropriate for the primitive used.
   295  func (csp *CSP) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) {
   296  	// Validate arguments
   297  	if k == nil {
   298  		return nil, errors.New("Invalid Key. It must not be nil.")
   299  	}
   300  
   301  	decryptor, found := csp.Decryptors[reflect.TypeOf(k)]
   302  	if !found {
   303  		return nil, errors.Errorf("Unsupported 'DecryptKey' provided [%v]", k)
   304  	}
   305  
   306  	plaintext, err = decryptor.Decrypt(k, ciphertext, opts)
   307  	if err != nil {
   308  		return nil, errors.Wrapf(err, "Failed decrypting with opts [%v]", opts)
   309  	}
   310  
   311  	return
   312  }
   313  
   314  // AddWrapper binds the passed type to the passed wrapper.
   315  // Notice that that wrapper must be an instance of one of the following interfaces:
   316  // KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher.
   317  func (csp *CSP) AddWrapper(t reflect.Type, w interface{}) error {
   318  	if t == nil {
   319  		return errors.Errorf("type cannot be nil")
   320  	}
   321  	if w == nil {
   322  		return errors.Errorf("wrapper cannot be nil")
   323  	}
   324  	switch dt := w.(type) {
   325  	case KeyGenerator:
   326  		csp.KeyGenerators[t] = dt
   327  	case KeyImporter:
   328  		csp.KeyImporters[t] = dt
   329  	case KeyDeriver:
   330  		csp.KeyDerivers[t] = dt
   331  	case Encryptor:
   332  		csp.Encryptors[t] = dt
   333  	case Decryptor:
   334  		csp.Decryptors[t] = dt
   335  	case Signer:
   336  		csp.Signers[t] = dt
   337  	case Verifier:
   338  		csp.Verifiers[t] = dt
   339  	case Hasher:
   340  		csp.Hashers[t] = dt
   341  	default:
   342  		return errors.Errorf("wrapper type not valid, must be on of: KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher")
   343  	}
   344  	return nil
   345  }