s2a_utils.go

 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
19package s2a
20
21import (
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.
31type 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.
61func 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.
73func 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}