cubefs

Форк
0
233 строки · 8.3 Кб
1
/*
2
 *
3
 * Copyright 2014 gRPC authors.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18

19
package credentials
20

21
import (
22
	"context"
23
	"crypto/tls"
24
	"crypto/x509"
25
	"fmt"
26
	"io/ioutil"
27
	"net"
28
	"net/url"
29

30
	credinternal "google.golang.org/grpc/internal/credentials"
31
)
32

33
// TLSInfo contains the auth information for a TLS authenticated connection.
34
// It implements the AuthInfo interface.
35
type TLSInfo struct {
36
	State tls.ConnectionState
37
	CommonAuthInfo
38
	// This API is experimental.
39
	SPIFFEID *url.URL
40
}
41

42
// AuthType returns the type of TLSInfo as a string.
43
func (t TLSInfo) AuthType() string {
44
	return "tls"
45
}
46

47
// GetSecurityValue returns security info requested by channelz.
48
func (t TLSInfo) GetSecurityValue() ChannelzSecurityValue {
49
	v := &TLSChannelzSecurityValue{
50
		StandardName: cipherSuiteLookup[t.State.CipherSuite],
51
	}
52
	// Currently there's no way to get LocalCertificate info from tls package.
53
	if len(t.State.PeerCertificates) > 0 {
54
		v.RemoteCertificate = t.State.PeerCertificates[0].Raw
55
	}
56
	return v
57
}
58

59
// tlsCreds is the credentials required for authenticating a connection using TLS.
60
type tlsCreds struct {
61
	// TLS configuration
62
	config *tls.Config
63
}
64

65
func (c tlsCreds) Info() ProtocolInfo {
66
	return ProtocolInfo{
67
		SecurityProtocol: "tls",
68
		SecurityVersion:  "1.2",
69
		ServerName:       c.config.ServerName,
70
	}
71
}
72

73
func (c *tlsCreds) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) {
74
	// use local cfg to avoid clobbering ServerName if using multiple endpoints
75
	cfg := credinternal.CloneTLSConfig(c.config)
76
	if cfg.ServerName == "" {
77
		serverName, _, err := net.SplitHostPort(authority)
78
		if err != nil {
79
			// If the authority had no host port or if the authority cannot be parsed, use it as-is.
80
			serverName = authority
81
		}
82
		cfg.ServerName = serverName
83
	}
84
	conn := tls.Client(rawConn, cfg)
85
	errChannel := make(chan error, 1)
86
	go func() {
87
		errChannel <- conn.Handshake()
88
		close(errChannel)
89
	}()
90
	select {
91
	case err := <-errChannel:
92
		if err != nil {
93
			conn.Close()
94
			return nil, nil, err
95
		}
96
	case <-ctx.Done():
97
		conn.Close()
98
		return nil, nil, ctx.Err()
99
	}
100
	tlsInfo := TLSInfo{
101
		State: conn.ConnectionState(),
102
		CommonAuthInfo: CommonAuthInfo{
103
			SecurityLevel: PrivacyAndIntegrity,
104
		},
105
	}
106
	id := credinternal.SPIFFEIDFromState(conn.ConnectionState())
107
	if id != nil {
108
		tlsInfo.SPIFFEID = id
109
	}
110
	return credinternal.WrapSyscallConn(rawConn, conn), tlsInfo, nil
111
}
112

113
func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) {
114
	conn := tls.Server(rawConn, c.config)
115
	if err := conn.Handshake(); err != nil {
116
		conn.Close()
117
		return nil, nil, err
118
	}
119
	tlsInfo := TLSInfo{
120
		State: conn.ConnectionState(),
121
		CommonAuthInfo: CommonAuthInfo{
122
			SecurityLevel: PrivacyAndIntegrity,
123
		},
124
	}
125
	id := credinternal.SPIFFEIDFromState(conn.ConnectionState())
126
	if id != nil {
127
		tlsInfo.SPIFFEID = id
128
	}
129
	return credinternal.WrapSyscallConn(rawConn, conn), tlsInfo, nil
130
}
131

132
func (c *tlsCreds) Clone() TransportCredentials {
133
	return NewTLS(c.config)
134
}
135

136
func (c *tlsCreds) OverrideServerName(serverNameOverride string) error {
137
	c.config.ServerName = serverNameOverride
138
	return nil
139
}
140

141
// NewTLS uses c to construct a TransportCredentials based on TLS.
142
func NewTLS(c *tls.Config) TransportCredentials {
143
	tc := &tlsCreds{credinternal.CloneTLSConfig(c)}
144
	tc.config.NextProtos = credinternal.AppendH2ToNextProtos(tc.config.NextProtos)
145
	return tc
146
}
147

148
// NewClientTLSFromCert constructs TLS credentials from the provided root
149
// certificate authority certificate(s) to validate server connections. If
150
// certificates to establish the identity of the client need to be included in
151
// the credentials (eg: for mTLS), use NewTLS instead, where a complete
152
// tls.Config can be specified.
153
// serverNameOverride is for testing only. If set to a non empty string,
154
// it will override the virtual host name of authority (e.g. :authority header
155
// field) in requests.
156
func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials {
157
	return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})
158
}
159

160
// NewClientTLSFromFile constructs TLS credentials from the provided root
161
// certificate authority certificate file(s) to validate server connections. If
162
// certificates to establish the identity of the client need to be included in
163
// the credentials (eg: for mTLS), use NewTLS instead, where a complete
164
// tls.Config can be specified.
165
// serverNameOverride is for testing only. If set to a non empty string,
166
// it will override the virtual host name of authority (e.g. :authority header
167
// field) in requests.
168
func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
169
	b, err := ioutil.ReadFile(certFile)
170
	if err != nil {
171
		return nil, err
172
	}
173
	cp := x509.NewCertPool()
174
	if !cp.AppendCertsFromPEM(b) {
175
		return nil, fmt.Errorf("credentials: failed to append certificates")
176
	}
177
	return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil
178
}
179

180
// NewServerTLSFromCert constructs TLS credentials from the input certificate for server.
181
func NewServerTLSFromCert(cert *tls.Certificate) TransportCredentials {
182
	return NewTLS(&tls.Config{Certificates: []tls.Certificate{*cert}})
183
}
184

185
// NewServerTLSFromFile constructs TLS credentials from the input certificate file and key
186
// file for server.
187
func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error) {
188
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
189
	if err != nil {
190
		return nil, err
191
	}
192
	return NewTLS(&tls.Config{Certificates: []tls.Certificate{cert}}), nil
193
}
194

195
// TLSChannelzSecurityValue defines the struct that TLS protocol should return
196
// from GetSecurityValue(), containing security info like cipher and certificate used.
197
//
198
// Experimental
199
//
200
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
201
// later release.
202
type TLSChannelzSecurityValue struct {
203
	ChannelzSecurityValue
204
	StandardName      string
205
	LocalCertificate  []byte
206
	RemoteCertificate []byte
207
}
208

209
var cipherSuiteLookup = map[uint16]string{
210
	tls.TLS_RSA_WITH_RC4_128_SHA:                "TLS_RSA_WITH_RC4_128_SHA",
211
	tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA:           "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
212
	tls.TLS_RSA_WITH_AES_128_CBC_SHA:            "TLS_RSA_WITH_AES_128_CBC_SHA",
213
	tls.TLS_RSA_WITH_AES_256_CBC_SHA:            "TLS_RSA_WITH_AES_256_CBC_SHA",
214
	tls.TLS_RSA_WITH_AES_128_GCM_SHA256:         "TLS_RSA_WITH_AES_128_GCM_SHA256",
215
	tls.TLS_RSA_WITH_AES_256_GCM_SHA384:         "TLS_RSA_WITH_AES_256_GCM_SHA384",
216
	tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
217
	tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
218
	tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
219
	tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA:          "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
220
	tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:     "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
221
	tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
222
	tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
223
	tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:   "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
224
	tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
225
	tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:   "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
226
	tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
227
	tls.TLS_FALLBACK_SCSV:                       "TLS_FALLBACK_SCSV",
228
	tls.TLS_RSA_WITH_AES_128_CBC_SHA256:         "TLS_RSA_WITH_AES_128_CBC_SHA256",
229
	tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
230
	tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
231
	tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
232
	tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
233
}
234

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.