github.com/blixtra/rkt@v0.8.1-0.20160204105720-ab0d1add1a43/Godeps/_workspace/src/google.golang.org/grpc/credentials/credentials.go (about) 1 /* 2 * 3 * Copyright 2014, Google Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following disclaimer 14 * in the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of Google Inc. nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 // Package credentials implements various credentials supported by gRPC library, 35 // which encapsulate all the state needed by a client to authenticate with a 36 // server and make various assertions, e.g., about the client's identity, role, 37 // or whether it is authorized to make a particular call. 38 package credentials 39 40 import ( 41 "crypto/tls" 42 "crypto/x509" 43 "fmt" 44 "io/ioutil" 45 "net" 46 "strings" 47 "time" 48 49 "golang.org/x/net/context" 50 ) 51 52 var ( 53 // alpnProtoStr are the specified application level protocols for gRPC. 54 alpnProtoStr = []string{"h2"} 55 ) 56 57 // Credentials defines the common interface all supported credentials must 58 // implement. 59 type Credentials interface { 60 // GetRequestMetadata gets the current request metadata, refreshing 61 // tokens if required. This should be called by the transport layer on 62 // each request, and the data should be populated in headers or other 63 // context. uri is the URI of the entry point for the request. When 64 // supported by the underlying implementation, ctx can be used for 65 // timeout and cancellation. 66 // TODO(zhaoq): Define the set of the qualified keys instead of leaving 67 // it as an arbitrary string. 68 GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) 69 // RequireTransportSecurity indicates whether the credentails requires 70 // transport security. 71 RequireTransportSecurity() bool 72 } 73 74 // ProtocolInfo provides information regarding the gRPC wire protocol version, 75 // security protocol, security protocol version in use, etc. 76 type ProtocolInfo struct { 77 // ProtocolVersion is the gRPC wire protocol version. 78 ProtocolVersion string 79 // SecurityProtocol is the security protocol in use. 80 SecurityProtocol string 81 // SecurityVersion is the security protocol version. 82 SecurityVersion string 83 } 84 85 // AuthInfo defines the common interface for the auth information the users are interested in. 86 type AuthInfo interface { 87 AuthType() string 88 } 89 90 // TransportAuthenticator defines the common interface for all the live gRPC wire 91 // protocols and supported transport security protocols (e.g., TLS, SSL). 92 type TransportAuthenticator interface { 93 // ClientHandshake does the authentication handshake specified by the corresponding 94 // authentication protocol on rawConn for clients. It returns the authenticated 95 // connection and the corresponding auth information about the connection. 96 ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (net.Conn, AuthInfo, error) 97 // ServerHandshake does the authentication handshake for servers. It returns 98 // the authenticated connection and the corresponding auth information about 99 // the connection. 100 ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) 101 // Info provides the ProtocolInfo of this TransportAuthenticator. 102 Info() ProtocolInfo 103 Credentials 104 } 105 106 // TLSInfo contains the auth information for a TLS authenticated connection. 107 // It implements the AuthInfo interface. 108 type TLSInfo struct { 109 State tls.ConnectionState 110 } 111 112 func (t TLSInfo) AuthType() string { 113 return "tls" 114 } 115 116 // tlsCreds is the credentials required for authenticating a connection using TLS. 117 type tlsCreds struct { 118 // TLS configuration 119 config tls.Config 120 } 121 122 func (c tlsCreds) Info() ProtocolInfo { 123 return ProtocolInfo{ 124 SecurityProtocol: "tls", 125 SecurityVersion: "1.2", 126 } 127 } 128 129 // GetRequestMetadata returns nil, nil since TLS credentials does not have 130 // metadata. 131 func (c *tlsCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { 132 return nil, nil 133 } 134 135 func (c *tlsCreds) RequireTransportSecurity() bool { 136 return true 137 } 138 139 type timeoutError struct{} 140 141 func (timeoutError) Error() string { return "credentials: Dial timed out" } 142 func (timeoutError) Timeout() bool { return true } 143 func (timeoutError) Temporary() bool { return true } 144 145 func (c *tlsCreds) ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (_ net.Conn, _ AuthInfo, err error) { 146 // borrow some code from tls.DialWithDialer 147 var errChannel chan error 148 if timeout != 0 { 149 errChannel = make(chan error, 2) 150 time.AfterFunc(timeout, func() { 151 errChannel <- timeoutError{} 152 }) 153 } 154 if c.config.ServerName == "" { 155 colonPos := strings.LastIndex(addr, ":") 156 if colonPos == -1 { 157 colonPos = len(addr) 158 } 159 c.config.ServerName = addr[:colonPos] 160 } 161 conn := tls.Client(rawConn, &c.config) 162 if timeout == 0 { 163 err = conn.Handshake() 164 } else { 165 go func() { 166 errChannel <- conn.Handshake() 167 }() 168 err = <-errChannel 169 } 170 if err != nil { 171 rawConn.Close() 172 return nil, nil, err 173 } 174 // TODO(zhaoq): Omit the auth info for client now. It is more for 175 // information than anything else. 176 return conn, nil, nil 177 } 178 179 func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) { 180 conn := tls.Server(rawConn, &c.config) 181 if err := conn.Handshake(); err != nil { 182 rawConn.Close() 183 return nil, nil, err 184 } 185 return conn, TLSInfo{conn.ConnectionState()}, nil 186 } 187 188 // NewTLS uses c to construct a TransportAuthenticator based on TLS. 189 func NewTLS(c *tls.Config) TransportAuthenticator { 190 tc := &tlsCreds{*c} 191 tc.config.NextProtos = alpnProtoStr 192 return tc 193 } 194 195 // NewClientTLSFromCert constructs a TLS from the input certificate for client. 196 func NewClientTLSFromCert(cp *x509.CertPool, serverName string) TransportAuthenticator { 197 return NewTLS(&tls.Config{ServerName: serverName, RootCAs: cp}) 198 } 199 200 // NewClientTLSFromFile constructs a TLS from the input certificate file for client. 201 func NewClientTLSFromFile(certFile, serverName string) (TransportAuthenticator, error) { 202 b, err := ioutil.ReadFile(certFile) 203 if err != nil { 204 return nil, err 205 } 206 cp := x509.NewCertPool() 207 if !cp.AppendCertsFromPEM(b) { 208 return nil, fmt.Errorf("credentials: failed to append certificates") 209 } 210 return NewTLS(&tls.Config{ServerName: serverName, RootCAs: cp}), nil 211 } 212 213 // NewServerTLSFromCert constructs a TLS from the input certificate for server. 214 func NewServerTLSFromCert(cert *tls.Certificate) TransportAuthenticator { 215 return NewTLS(&tls.Config{Certificates: []tls.Certificate{*cert}}) 216 } 217 218 // NewServerTLSFromFile constructs a TLS from the input certificate file and key 219 // file for server. 220 func NewServerTLSFromFile(certFile, keyFile string) (TransportAuthenticator, error) { 221 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 222 if err != nil { 223 return nil, err 224 } 225 return NewTLS(&tls.Config{Certificates: []tls.Certificate{cert}}), nil 226 }