github.com/yous1230/fabric@v2.0.0-beta.0.20191224111736-74345bee6ac2+incompatible/core/comm/creds.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package comm 8 9 import ( 10 "context" 11 "crypto/tls" 12 "errors" 13 "net" 14 15 "github.com/hyperledger/fabric/common/flogging" 16 "google.golang.org/grpc/credentials" 17 ) 18 19 var ( 20 ErrClientHandshakeNotImplemented = errors.New("core/comm: client handshakes are not implemented with serverCreds") 21 ErrServerHandshakeNotImplemented = errors.New("core/comm: server handshakes are not implemented with clientCreds") 22 ErrOverrideHostnameNotSupported = errors.New("core/comm: OverrideServerName is not supported") 23 24 // alpnProtoStr are the specified application level protocols for gRPC. 25 alpnProtoStr = []string{"h2"} 26 ) 27 28 // NewServerTransportCredentials returns a new initialized 29 // grpc/credentials.TransportCredentials 30 func NewServerTransportCredentials( 31 serverConfig *tls.Config, 32 logger *flogging.FabricLogger) credentials.TransportCredentials { 33 34 // NOTE: unlike the default grpc/credentials implementation, we do not 35 // clone the tls.Config which allows us to update it dynamically 36 serverConfig.NextProtos = alpnProtoStr 37 // override TLS version and ensure it is 1.2 38 serverConfig.MinVersion = tls.VersionTLS12 39 serverConfig.MaxVersion = tls.VersionTLS12 40 return &serverCreds{ 41 serverConfig: serverConfig, 42 logger: logger} 43 } 44 45 // serverCreds is an implementation of grpc/credentials.TransportCredentials. 46 type serverCreds struct { 47 serverConfig *tls.Config 48 logger *flogging.FabricLogger 49 } 50 51 // ClientHandShake is not implemented for `serverCreds`. 52 func (sc *serverCreds) ClientHandshake(context.Context, 53 string, net.Conn) (net.Conn, credentials.AuthInfo, error) { 54 return nil, nil, ErrClientHandshakeNotImplemented 55 } 56 57 // ServerHandshake does the authentication handshake for servers. 58 func (sc *serverCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { 59 conn := tls.Server(rawConn, sc.serverConfig) 60 if err := conn.Handshake(); err != nil { 61 if sc.logger != nil { 62 sc.logger.With("remote address", 63 conn.RemoteAddr().String()).Errorf("TLS handshake failed with error %s", err) 64 } 65 return nil, nil, err 66 } 67 return conn, credentials.TLSInfo{State: conn.ConnectionState()}, nil 68 } 69 70 // Info provides the ProtocolInfo of this TransportCredentials. 71 func (sc *serverCreds) Info() credentials.ProtocolInfo { 72 return credentials.ProtocolInfo{ 73 SecurityProtocol: "tls", 74 SecurityVersion: "1.2", 75 } 76 } 77 78 // Clone makes a copy of this TransportCredentials. 79 func (sc *serverCreds) Clone() credentials.TransportCredentials { 80 creds := NewServerTransportCredentials(sc.serverConfig, sc.logger) 81 return creds 82 } 83 84 // OverrideServerName overrides the server name used to verify the hostname 85 // on the returned certificates from the server. 86 func (sc *serverCreds) OverrideServerName(string) error { 87 return ErrOverrideHostnameNotSupported 88 } 89 90 type DynamicClientCredentials struct { 91 TLSConfig *tls.Config 92 TLSOptions []TLSOption 93 } 94 95 func (dtc *DynamicClientCredentials) latestConfig() *tls.Config { 96 tlsConfigCopy := dtc.TLSConfig.Clone() 97 for _, tlsOption := range dtc.TLSOptions { 98 tlsOption(tlsConfigCopy) 99 } 100 return tlsConfigCopy 101 } 102 103 func (dtc *DynamicClientCredentials) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { 104 return credentials.NewTLS(dtc.latestConfig()).ClientHandshake(ctx, authority, rawConn) 105 } 106 107 func (dtc *DynamicClientCredentials) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { 108 return nil, nil, ErrServerHandshakeNotImplemented 109 } 110 111 func (dtc *DynamicClientCredentials) Info() credentials.ProtocolInfo { 112 return credentials.NewTLS(dtc.latestConfig()).Info() 113 } 114 115 func (dtc *DynamicClientCredentials) Clone() credentials.TransportCredentials { 116 return credentials.NewTLS(dtc.latestConfig()) 117 } 118 119 func (dtc *DynamicClientCredentials) OverrideServerName(name string) error { 120 dtc.TLSConfig.ServerName = name 121 return nil 122 }