github.com/hyperledger-labs/bdls@v2.1.1+incompatible/core/chaincode/accesscontrol/mapper.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package accesscontrol
     8  
     9  import (
    10  	"context"
    11  	"sync"
    12  	"time"
    13  
    14  	"github.com/hyperledger/fabric/common/crypto/tlsgen"
    15  	"github.com/hyperledger/fabric/common/util"
    16  	"google.golang.org/grpc/credentials"
    17  	"google.golang.org/grpc/peer"
    18  )
    19  
    20  var ttl = time.Minute * 10
    21  
    22  type certHash string
    23  
    24  type KeyGenFunc func() (*tlsgen.CertKeyPair, error)
    25  
    26  type certMapper struct {
    27  	keyGen KeyGenFunc
    28  	sync.RWMutex
    29  	m map[certHash]string
    30  }
    31  
    32  func newCertMapper(keyGen KeyGenFunc) *certMapper {
    33  	return &certMapper{
    34  		keyGen: keyGen,
    35  		m:      make(map[certHash]string),
    36  	}
    37  }
    38  
    39  func (r *certMapper) lookup(h certHash) string {
    40  	r.RLock()
    41  	defer r.RUnlock()
    42  	return r.m[h]
    43  }
    44  
    45  func (r *certMapper) register(hash certHash, name string) {
    46  	r.Lock()
    47  	defer r.Unlock()
    48  	r.m[hash] = name
    49  	time.AfterFunc(ttl, func() {
    50  		r.purge(hash)
    51  	})
    52  }
    53  
    54  func (r *certMapper) purge(hash certHash) {
    55  	r.Lock()
    56  	defer r.Unlock()
    57  	delete(r.m, hash)
    58  }
    59  
    60  func (r *certMapper) genCert(name string) (*tlsgen.CertKeyPair, error) {
    61  	keyPair, err := r.keyGen()
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	hash := util.ComputeSHA256(keyPair.TLSCert.Raw)
    66  	r.register(certHash(hash), name)
    67  	return keyPair, nil
    68  }
    69  
    70  // ExtractCertificateHash extracts the hash of the certificate from the stream
    71  func extractCertificateHashFromContext(ctx context.Context) []byte {
    72  	pr, extracted := peer.FromContext(ctx)
    73  	if !extracted {
    74  		return nil
    75  	}
    76  
    77  	authInfo := pr.AuthInfo
    78  	if authInfo == nil {
    79  		return nil
    80  	}
    81  
    82  	tlsInfo, isTLSConn := authInfo.(credentials.TLSInfo)
    83  	if !isTLSConn {
    84  		return nil
    85  	}
    86  	certs := tlsInfo.State.PeerCertificates
    87  	if len(certs) == 0 {
    88  		return nil
    89  	}
    90  	raw := certs[0].Raw
    91  	if len(raw) == 0 {
    92  		return nil
    93  	}
    94  	return util.ComputeSHA256(raw)
    95  }