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