github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/gossip/identity/identity.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  
    17  package identity
    18  
    19  import (
    20  	"bytes"
    21  	"sync"
    22  
    23  	"errors"
    24  
    25  	"github.com/hyperledger/fabric/gossip/api"
    26  	"github.com/hyperledger/fabric/gossip/common"
    27  )
    28  
    29  // Mapper holds mappings between pkiID
    30  // to certificates(identities) of peers
    31  type Mapper interface {
    32  	// Put associates an identity to its given pkiID, and returns an error
    33  	// in case the given pkiID doesn't match the identity
    34  	Put(pkiID common.PKIidType, identity api.PeerIdentityType) error
    35  
    36  	// Get returns the identity of a given pkiID, or error if such an identity
    37  	// isn't found
    38  	Get(pkiID common.PKIidType) (api.PeerIdentityType, error)
    39  
    40  	// Sign signs a message, returns a signed message on success
    41  	// or an error on failure
    42  	Sign(msg []byte) ([]byte, error)
    43  
    44  	// Verify verifies a signed message
    45  	Verify(vkID, signature, message []byte) error
    46  
    47  	// GetPKIidOfCert returns the PKI-ID of a certificate
    48  	GetPKIidOfCert(api.PeerIdentityType) common.PKIidType
    49  }
    50  
    51  // identityMapperImpl is a struct that implements Mapper
    52  type identityMapperImpl struct {
    53  	mcs        api.MessageCryptoService
    54  	pkiID2Cert map[string]api.PeerIdentityType
    55  	sync.RWMutex
    56  }
    57  
    58  // NewIdentityMapper method, all we need is a reference to a MessageCryptoService
    59  func NewIdentityMapper(mcs api.MessageCryptoService) Mapper {
    60  	return &identityMapperImpl{
    61  		mcs:        mcs,
    62  		pkiID2Cert: make(map[string]api.PeerIdentityType),
    63  	}
    64  }
    65  
    66  // put associates an identity to its given pkiID, and returns an error
    67  // in case the given pkiID doesn't match the identity
    68  func (is *identityMapperImpl) Put(pkiID common.PKIidType, identity api.PeerIdentityType) error {
    69  	if pkiID == nil {
    70  		return errors.New("PkiID is nil")
    71  	}
    72  	if identity == nil {
    73  		return errors.New("Identity is nil")
    74  	}
    75  
    76  	if err := is.mcs.ValidateIdentity(identity); err != nil {
    77  		return err
    78  	}
    79  
    80  	id := is.mcs.GetPKIidOfCert(identity)
    81  	if !bytes.Equal(pkiID, id) {
    82  		return errors.New("Identity doesn't match the computed pkiID")
    83  	}
    84  
    85  	is.Lock()
    86  	defer is.Unlock()
    87  	is.pkiID2Cert[string(id)] = identity
    88  	return nil
    89  }
    90  
    91  // get returns the identity of a given pkiID, or error if such an identity
    92  // isn't found
    93  func (is *identityMapperImpl) Get(pkiID common.PKIidType) (api.PeerIdentityType, error) {
    94  	is.RLock()
    95  	defer is.RUnlock()
    96  	identity, exists := is.pkiID2Cert[string(pkiID)]
    97  	if !exists {
    98  		return nil, errors.New("PkiID wasn't found")
    99  	}
   100  	return identity, nil
   101  }
   102  
   103  // Sign signs a message, returns a signed message on success
   104  // or an error on failure
   105  func (is *identityMapperImpl) Sign(msg []byte) ([]byte, error) {
   106  	return is.mcs.Sign(msg)
   107  }
   108  
   109  // Verify verifies a signed message
   110  func (is *identityMapperImpl) Verify(vkID, signature, message []byte) error {
   111  	cert, err := is.Get(vkID)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	return is.mcs.Verify(cert, signature, message)
   116  }
   117  
   118  // GetPKIidOfCert returns the PKI-ID of a certificate
   119  func (is *identityMapperImpl) GetPKIidOfCert(identity api.PeerIdentityType) common.PKIidType {
   120  	return is.mcs.GetPKIidOfCert(identity)
   121  }