1//
2// Copyright 2020 gRPC authors.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#ifndef GRPCPP_SECURITY_TLS_CERTIFICATE_PROVIDER_H
18#define GRPCPP_SECURITY_TLS_CERTIFICATE_PROVIDER_H
19
20#include <memory>
21#include <vector>
22
23#include <grpc/grpc_security.h>
24#include <grpc/grpc_security_constants.h>
25#include <grpc/status.h>
26#include <grpc/support/log.h>
27#include <grpcpp/impl/codegen/grpc_library.h>
28#include <grpcpp/support/config.h>
29
30namespace grpc {
31namespace experimental {
32
33// Interface for a class that handles the process to fetch credential data.
34// Implementations should be a wrapper class of an internal provider
35// implementation.
36class CertificateProviderInterface {
37 public:
38 virtual ~CertificateProviderInterface() = default;
39 virtual grpc_tls_certificate_provider* c_provider() = 0;
40};
41
42// A struct that stores the credential data presented to the peer in handshake
43// to show local identity. The private_key and certificate_chain should always
44// match.
45struct IdentityKeyCertPair {
46 std::string private_key;
47 std::string certificate_chain;
48};
49
50// A basic CertificateProviderInterface implementation that will load credential
51// data from static string during initialization. This provider will always
52// return the same cert data for all cert names, and reloading is not supported.
53class StaticDataCertificateProvider : public CertificateProviderInterface {
54 public:
55 StaticDataCertificateProvider(
56 const std::string& root_certificate,
57 const std::vector<IdentityKeyCertPair>& identity_key_cert_pairs);
58
59 explicit StaticDataCertificateProvider(const std::string& root_certificate)
60 : StaticDataCertificateProvider(root_certificate, {}) {}
61
62 explicit StaticDataCertificateProvider(
63 const std::vector<IdentityKeyCertPair>& identity_key_cert_pairs)
64 : StaticDataCertificateProvider("", identity_key_cert_pairs) {}
65
66 ~StaticDataCertificateProvider() override;
67
68 grpc_tls_certificate_provider* c_provider() override { return c_provider_; }
69
70 private:
71 grpc_tls_certificate_provider* c_provider_ = nullptr;
72};
73
74// A CertificateProviderInterface implementation that will watch the credential
75// changes on the file system. This provider will always return the up-to-date
76// cert data for all the cert names callers set through |TlsCredentialsOptions|.
77// Several things to note:
78// 1. This API only supports one key-cert file and hence one set of identity
79// key-cert pair, so SNI(Server Name Indication) is not supported.
80// 2. The private key and identity certificate should always match. This API
81// guarantees atomic read, and it is the callers' responsibility to do atomic
82// updates. There are many ways to atomically update the key and certs in the
83// file system. To name a few:
84// 1) creating a new directory, renaming the old directory to a new name, and
85// then renaming the new directory to the original name of the old directory.
86// 2) using a symlink for the directory. When need to change, put new
87// credential data in a new directory, and change symlink.
88class FileWatcherCertificateProvider final
89 : public CertificateProviderInterface {
90 public:
91 // Constructor to get credential updates from root and identity file paths.
92 //
93 // @param private_key_path is the file path of the private key.
94 // @param identity_certificate_path is the file path of the identity
95 // certificate chain.
96 // @param root_cert_path is the file path to the root certificate bundle.
97 // @param refresh_interval_sec is the refreshing interval that we will check
98 // the files for updates.
99 FileWatcherCertificateProvider(const std::string& private_key_path,
100 const std::string& identity_certificate_path,
101 const std::string& root_cert_path,
102 unsigned int refresh_interval_sec);
103 // Constructor to get credential updates from identity file paths only.
104 FileWatcherCertificateProvider(const std::string& private_key_path,
105 const std::string& identity_certificate_path,
106 unsigned int refresh_interval_sec)
107 : FileWatcherCertificateProvider(private_key_path,
108 identity_certificate_path, "",
109 refresh_interval_sec) {}
110 // Constructor to get credential updates from root file path only.
111 FileWatcherCertificateProvider(const std::string& root_cert_path,
112 unsigned int refresh_interval_sec)
113 : FileWatcherCertificateProvider("", "", root_cert_path,
114 refresh_interval_sec) {}
115
116 ~FileWatcherCertificateProvider() override;
117
118 grpc_tls_certificate_provider* c_provider() override { return c_provider_; }
119
120 private:
121 grpc_tls_certificate_provider* c_provider_ = nullptr;
122};
123
124} // namespace experimental
125} // namespace grpc
126
127#endif // GRPCPP_SECURITY_TLS_CERTIFICATE_PROVIDER_H
128

source code of include/grpcpp/security/tls_certificate_provider.h