1 /* 2 * 3 * Copyright 2021 Google LLC 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 * https://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 s2a 20 21 import ( 22 "context" 23 "errors" 24 25 commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" 26 "google.golang.org/grpc/credentials" 27 "google.golang.org/grpc/peer" 28 ) 29 30 // AuthInfo exposes security information from the S2A to the application. 31 type AuthInfo interface { 32 // AuthType returns the authentication type. 33 AuthType() string 34 // ApplicationProtocol returns the application protocol, e.g. "grpc". 35 ApplicationProtocol() string 36 // TLSVersion returns the TLS version negotiated during the handshake. 37 TLSVersion() commonpb.TLSVersion 38 // Ciphersuite returns the ciphersuite negotiated during the handshake. 39 Ciphersuite() commonpb.Ciphersuite 40 // PeerIdentity returns the authenticated identity of the peer. 41 PeerIdentity() *commonpb.Identity 42 // LocalIdentity returns the local identity of the application used during 43 // session setup. 44 LocalIdentity() *commonpb.Identity 45 // PeerCertFingerprint returns the SHA256 hash of the peer certificate used in 46 // the S2A handshake. 47 PeerCertFingerprint() []byte 48 // LocalCertFingerprint returns the SHA256 hash of the local certificate used 49 // in the S2A handshake. 50 LocalCertFingerprint() []byte 51 // IsHandshakeResumed returns true if a cached session was used to resume 52 // the handshake. 53 IsHandshakeResumed() bool 54 // SecurityLevel returns the security level of the connection. 55 SecurityLevel() credentials.SecurityLevel 56 } 57 58 // AuthInfoFromPeer extracts the authinfo.S2AAuthInfo object from the given 59 // peer, if it exists. This API should be used by gRPC clients after 60 // obtaining a peer object using the grpc.Peer() CallOption. 61 func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) { 62 s2aAuthInfo, ok := p.AuthInfo.(AuthInfo) 63 if !ok { 64 return nil, errors.New("no S2AAuthInfo found in Peer") 65 } 66 return s2aAuthInfo, nil 67 } 68 69 // AuthInfoFromContext extracts the authinfo.S2AAuthInfo object from the given 70 // context, if it exists. This API should be used by gRPC server RPC handlers 71 // to get information about the peer. On the client-side, use the grpc.Peer() 72 // CallOption and the AuthInfoFromPeer function. 73 func AuthInfoFromContext(ctx context.Context) (AuthInfo, error) { 74 p, ok := peer.FromContext(ctx) 75 if !ok { 76 return nil, errors.New("no Peer found in Context") 77 } 78 return AuthInfoFromPeer(p) 79 } 80