github.com/m3db/m3@v1.5.0/src/m3em/x/grpc/server.go (about)

     1  // Copyright (c) 2017 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package xgrpc
    22  
    23  import (
    24  	"crypto/tls"
    25  	"crypto/x509"
    26  	"fmt"
    27  
    28  	"google.golang.org/grpc"
    29  	"google.golang.org/grpc/credentials"
    30  )
    31  
    32  const (
    33  	defaultGrpcMaxConcurrentStreams = 16384
    34  )
    35  
    36  func options(tCred credentials.TransportCredentials) []grpc.ServerOption {
    37  	opts := []grpc.ServerOption{
    38  		grpc.MaxConcurrentStreams(defaultGrpcMaxConcurrentStreams),
    39  	}
    40  
    41  	if tCred != nil {
    42  		opts = append(opts, grpc.Creds(tCred))
    43  	}
    44  
    45  	return opts
    46  }
    47  
    48  // NewServer returns a new grpc Server with provided options
    49  func NewServer(tc credentials.TransportCredentials) *grpc.Server {
    50  	return grpc.NewServer(options(tc)...)
    51  }
    52  
    53  // NewServerCredentials returns Server Credentials
    54  func NewServerCredentials(
    55  	caCertPEMBlock []byte,
    56  	serverCertPEMBlock []byte,
    57  	serverKeyPEMBlock []byte,
    58  ) (credentials.TransportCredentials, error) {
    59  	certPool, certificate, err := newCert(caCertPEMBlock, serverCertPEMBlock, serverKeyPEMBlock)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	tlsConfig := &tls.Config{
    65  		ClientAuth:   tls.RequireAndVerifyClientCert,
    66  		Certificates: []tls.Certificate{certificate},
    67  		ClientCAs:    certPool,
    68  	}
    69  	return credentials.NewTLS(tlsConfig), nil
    70  }
    71  
    72  // NewClientCredentials returns Client Credentials
    73  func NewClientCredentials(
    74  	serverName string,
    75  	caCertPEMBlock []byte,
    76  	clientCertPEMBlock []byte,
    77  	clientKeyPEMBlock []byte,
    78  ) (credentials.TransportCredentials, error) {
    79  	certPool, certificate, err := newCert(caCertPEMBlock, clientCertPEMBlock, clientKeyPEMBlock)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	tlsConfig := &tls.Config{
    85  		ServerName:   serverName,
    86  		Certificates: []tls.Certificate{certificate},
    87  		RootCAs:      certPool,
    88  	}
    89  	return credentials.NewTLS(tlsConfig), nil
    90  }
    91  
    92  func newCert(
    93  	caCertPEMBlock []byte,
    94  	certPEMBlock []byte,
    95  	keyPEMBlock []byte,
    96  ) (*x509.CertPool, tls.Certificate, error) {
    97  	certPool := x509.NewCertPool()
    98  	ok := certPool.AppendCertsFromPEM(caCertPEMBlock)
    99  	if !ok {
   100  		return nil, tls.Certificate{}, fmt.Errorf("unable to append CA Cert")
   101  	}
   102  
   103  	certificate, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
   104  	if err != nil {
   105  		return nil, tls.Certificate{}, err
   106  	}
   107  
   108  	return certPool, certificate, nil
   109  }