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 }