github.com/true-sqn/fabric@v2.1.1+incompatible/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  	"hash"
    20  	"reflect"
    21  
    22  	"github.com/hyperledger/fabric/bccsp"
    23  	"github.com/hyperledger/fabric/common/flogging"
    24  	"github.com/pkg/errors"
    25  )
    26  
    27  var (
    28  	logger = flogging.MustGetLogger("bccsp_sw")
    29  )
    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{keyStore,
    64  		keyGenerators, keyDerivers, keyImporters, encryptors,
    65  		decryptors, signers, verifiers, hashers}
    66  
    67  	return csp, nil
    68  }
    69  
    70  // KeyGen generates a key using opts.
    71  func (csp *CSP) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
    72  	// Validate arguments
    73  	if opts == nil {
    74  		return nil, errors.New("Invalid Opts parameter. It must not be nil.")
    75  	}
    76  
    77  	keyGenerator, found := csp.KeyGenerators[reflect.TypeOf(opts)]
    78  	if !found {
    79  		return nil, errors.Errorf("Unsupported 'KeyGenOpts' provided [%v]", opts)
    80  	}
    81  
    82  	k, err = keyGenerator.KeyGen(opts)
    83  	if err != nil {
    84  		return nil, errors.Wrapf(err, "Failed generating key with opts [%v]", opts)
    85  	}
    86  
    87  	// If the key is not Ephemeral, store it.
    88  	if !opts.Ephemeral() {
    89  		// Store the key
    90  		err = csp.ks.StoreKey(k)
    91  		if err != nil {
    92  			return nil, errors.Wrapf(err, "Failed storing key [%s]", opts.Algorithm())
    93  		}
    94  	}
    95  
    96  	return k, nil
    97  }
    98  
    99  // KeyDeriv derives a key from k using opts.
   100  // The opts argument should be appropriate for the primitive used.
   101  func (csp *CSP) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) {
   102  	// Validate arguments
   103  	if k == nil {
   104  		return nil, errors.New("Invalid Key. It must not be nil.")
   105  	}
   106  	if opts == nil {
   107  		return nil, errors.New("Invalid opts. It must not be nil.")
   108  	}
   109  
   110  	keyDeriver, found := csp.KeyDerivers[reflect.TypeOf(k)]
   111  	if !found {
   112  		return nil, errors.Errorf("Unsupported 'Key' provided [%v]", k)
   113  	}
   114  
   115  	k, err = keyDeriver.KeyDeriv(k, opts)
   116  	if err != nil {
   117  		return nil, errors.Wrapf(err, "Failed deriving key with opts [%v]", opts)
   118  	}
   119  
   120  	// If the key is not Ephemeral, store it.
   121  	if !opts.Ephemeral() {
   122  		// Store the key
   123  		err = csp.ks.StoreKey(k)
   124  		if err != nil {
   125  			return nil, errors.Wrapf(err, "Failed storing key [%s]", opts.Algorithm())
   126  		}
   127  	}
   128  
   129  	return k, nil
   130  }
   131  
   132  // KeyImport imports a key from its raw representation using opts.
   133  // The opts argument should be appropriate for the primitive used.
   134  func (csp *CSP) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
   135  	// Validate arguments
   136  	if raw == nil {
   137  		return nil, errors.New("Invalid raw. It must not be nil.")
   138  	}
   139  	if opts == nil {
   140  		return nil, errors.New("Invalid opts. It must not be nil.")
   141  	}
   142  
   143  	keyImporter, found := csp.KeyImporters[reflect.TypeOf(opts)]
   144  	if !found {
   145  		return nil, errors.Errorf("Unsupported 'KeyImportOpts' provided [%v]", opts)
   146  	}
   147  
   148  	k, err = keyImporter.KeyImport(raw, opts)
   149  	if err != nil {
   150  		return nil, errors.Wrapf(err, "Failed importing key with opts [%v]", opts)
   151  	}
   152  
   153  	// If the key is not Ephemeral, store it.
   154  	if !opts.Ephemeral() {
   155  		// Store the key
   156  		err = csp.ks.StoreKey(k)
   157  		if err != nil {
   158  			return nil, errors.Wrapf(err, "Failed storing imported key with opts [%v]", opts)
   159  		}
   160  	}
   161  
   162  	return
   163  }
   164  
   165  // GetKey returns the key this CSP associates to
   166  // the Subject Key Identifier ski.
   167  func (csp *CSP) GetKey(ski []byte) (k bccsp.Key, err error) {
   168  	k, err = csp.ks.GetKey(ski)
   169  	if err != nil {
   170  		return nil, errors.Wrapf(err, "Failed getting key for SKI [%v]", ski)
   171  	}
   172  
   173  	return
   174  }
   175  
   176  // Hash hashes messages msg using options opts.
   177  func (csp *CSP) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) {
   178  	// Validate arguments
   179  	if opts == nil {
   180  		return nil, errors.New("Invalid opts. It must not be nil.")
   181  	}
   182  
   183  	hasher, found := csp.Hashers[reflect.TypeOf(opts)]
   184  	if !found {
   185  		return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts)
   186  	}
   187  
   188  	digest, err = hasher.Hash(msg, opts)
   189  	if err != nil {
   190  		return nil, errors.Wrapf(err, "Failed hashing with opts [%v]", opts)
   191  	}
   192  
   193  	return
   194  }
   195  
   196  // GetHash returns and instance of hash.Hash using options opts.
   197  // If opts is nil then the default hash function is returned.
   198  func (csp *CSP) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) {
   199  	// Validate arguments
   200  	if opts == nil {
   201  		return nil, errors.New("Invalid opts. It must not be nil.")
   202  	}
   203  
   204  	hasher, found := csp.Hashers[reflect.TypeOf(opts)]
   205  	if !found {
   206  		return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts)
   207  	}
   208  
   209  	h, err = hasher.GetHash(opts)
   210  	if err != nil {
   211  		return nil, errors.Wrapf(err, "Failed getting hash function with opts [%v]", opts)
   212  	}
   213  
   214  	return
   215  }
   216  
   217  // Sign signs digest using key k.
   218  // The opts argument should be appropriate for the primitive used.
   219  //
   220  // Note that when a signature of a hash of a larger message is needed,
   221  // the caller is responsible for hashing the larger message and passing
   222  // the hash (as digest).
   223  func (csp *CSP) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
   224  	// Validate arguments
   225  	if k == nil {
   226  		return nil, errors.New("Invalid Key. It must not be nil.")
   227  	}
   228  	if len(digest) == 0 {
   229  		return nil, errors.New("Invalid digest. Cannot be empty.")
   230  	}
   231  
   232  	keyType := reflect.TypeOf(k)
   233  	signer, found := csp.Signers[keyType]
   234  	if !found {
   235  		return nil, errors.Errorf("Unsupported 'SignKey' provided [%s]", keyType)
   236  	}
   237  
   238  	signature, err = signer.Sign(k, digest, opts)
   239  	if err != nil {
   240  		return nil, errors.Wrapf(err, "Failed signing with opts [%v]", opts)
   241  	}
   242  
   243  	return
   244  }
   245  
   246  // Verify verifies signature against key k and digest
   247  func (csp *CSP) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
   248  	// Validate arguments
   249  	if k == nil {
   250  		return false, errors.New("Invalid Key. It must not be nil.")
   251  	}
   252  	if len(signature) == 0 {
   253  		return false, errors.New("Invalid signature. Cannot be empty.")
   254  	}
   255  	if len(digest) == 0 {
   256  		return false, errors.New("Invalid digest. Cannot be empty.")
   257  	}
   258  
   259  	verifier, found := csp.Verifiers[reflect.TypeOf(k)]
   260  	if !found {
   261  		return false, errors.Errorf("Unsupported 'VerifyKey' provided [%v]", k)
   262  	}
   263  
   264  	valid, err = verifier.Verify(k, signature, digest, opts)
   265  	if err != nil {
   266  		return false, errors.Wrapf(err, "Failed verifing with opts [%v]", opts)
   267  	}
   268  
   269  	return
   270  }
   271  
   272  // Encrypt encrypts plaintext using key k.
   273  // The opts argument should be appropriate for the primitive used.
   274  func (csp *CSP) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) ([]byte, error) {
   275  	// Validate arguments
   276  	if k == nil {
   277  		return nil, errors.New("Invalid Key. It must not be nil.")
   278  	}
   279  
   280  	encryptor, found := csp.Encryptors[reflect.TypeOf(k)]
   281  	if !found {
   282  		return nil, errors.Errorf("Unsupported 'EncryptKey' provided [%v]", k)
   283  	}
   284  
   285  	return encryptor.Encrypt(k, plaintext, opts)
   286  }
   287  
   288  // Decrypt decrypts ciphertext using key k.
   289  // The opts argument should be appropriate for the primitive used.
   290  func (csp *CSP) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) {
   291  	// Validate arguments
   292  	if k == nil {
   293  		return nil, errors.New("Invalid Key. It must not be nil.")
   294  	}
   295  
   296  	decryptor, found := csp.Decryptors[reflect.TypeOf(k)]
   297  	if !found {
   298  		return nil, errors.Errorf("Unsupported 'DecryptKey' provided [%v]", k)
   299  	}
   300  
   301  	plaintext, err = decryptor.Decrypt(k, ciphertext, opts)
   302  	if err != nil {
   303  		return nil, errors.Wrapf(err, "Failed decrypting with opts [%v]", opts)
   304  	}
   305  
   306  	return
   307  }
   308  
   309  // AddWrapper binds the passed type to the passed wrapper.
   310  // Notice that that wrapper must be an instance of one of the following interfaces:
   311  // KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher.
   312  func (csp *CSP) AddWrapper(t reflect.Type, w interface{}) error {
   313  	if t == nil {
   314  		return errors.Errorf("type cannot be nil")
   315  	}
   316  	if w == nil {
   317  		return errors.Errorf("wrapper cannot be nil")
   318  	}
   319  	switch dt := w.(type) {
   320  	case KeyGenerator:
   321  		csp.KeyGenerators[t] = dt
   322  	case KeyImporter:
   323  		csp.KeyImporters[t] = dt
   324  	case KeyDeriver:
   325  		csp.KeyDerivers[t] = dt
   326  	case Encryptor:
   327  		csp.Encryptors[t] = dt
   328  	case Decryptor:
   329  		csp.Decryptors[t] = dt
   330  	case Signer:
   331  		csp.Signers[t] = dt
   332  	case Verifier:
   333  		csp.Verifiers[t] = dt
   334  	case Hasher:
   335  		csp.Hashers[t] = dt
   336  	default:
   337  		return errors.Errorf("wrapper type not valid, must be on of: KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher")
   338  	}
   339  	return nil
   340  }