• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2017 gRPC authors.
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 //     http://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 #ifndef GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H
20 #define GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H
21 
22 #include <grpc/support/sync.h>
23 #include <openssl/x509v3.h>
24 
25 #include "src/core/tsi/transport_security_interface.h"
26 
27 #define TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE 32
28 #define TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE 128
29 #define TSI_TEST_SMALL_READ_BUFFER_ALLOCATED_SIZE 41
30 #define TSI_TEST_SMALL_PROTECTED_BUFFER_SIZE 37
31 #define TSI_TEST_SMALL_MESSAGE_BUFFER_ALLOCATED_SIZE 42
32 #define TSI_TEST_SMALL_CLIENT_MAX_OUTPUT_PROTECTED_FRAME_SIZE 39
33 #define TSI_TEST_SMALL_SERVER_MAX_OUTPUT_PROTECTED_FRAME_SIZE 43
34 #define TSI_TEST_DEFAULT_BUFFER_SIZE 4096
35 #define TSI_TEST_DEFAULT_PROTECTED_BUFFER_SIZE 16384
36 #define TSI_TEST_DEFAULT_CHANNEL_SIZE 32768
37 #define TSI_TEST_BIG_MESSAGE_SIZE 17000
38 #define TSI_TEST_SMALL_MESSAGE_SIZE 10
39 #define TSI_TEST_NUM_OF_ARGUMENTS 7
40 #define TSI_TEST_NUM_OF_COMBINATIONS 128
41 #define TSI_TEST_UNUSED_BYTES "HELLO GOOGLE"
42 
43 // ---  tsi_test_fixture object ---
44 // The tests for specific TSI implementations should create their own
45 // custom "subclass" of this fixture, which wraps all information
46 // that will be used to test correctness of TSI handshakes and frame
47 // protect/unprotect operations with respect to TSI implementations.
48 typedef struct tsi_test_fixture tsi_test_fixture;
49 
50 // ---  tsi_test_frame_protector_fixture object ---
51 // The object wraps all necessary information used to test correctness of TSI
52 // frame protector implementations.
53 typedef struct tsi_test_frame_protector_fixture
54     tsi_test_frame_protector_fixture;
55 
56 // ---  tsi_test_frame_protector_config object ---
57 // This object is used to configure different parameters of TSI frame protector
58 // APIs.
59 typedef struct tsi_test_frame_protector_config tsi_test_frame_protector_config;
60 
61 // ---  tsi_test_channel object ---
62 // This object represents simulated channels between the client and server
63 // from/to which they could read/write the exchanged information.
64 typedef struct tsi_test_channel tsi_test_channel;
65 
66 // V-table for tsi_test_fixture operations that are implemented differently in
67 // different TSI implementations.
68 typedef struct tsi_test_fixture_vtable {
69   void (*setup_handshakers)(tsi_test_fixture* fixture);
70   void (*check_handshaker_peers)(tsi_test_fixture* fixture);
71   void (*destruct)(tsi_test_fixture* fixture);
72 } tsi_test_fixture_vtable;
73 
74 struct tsi_test_fixture {
75   const tsi_test_fixture_vtable* vtable;
76   // client/server TSI handshaker used to perform TSI handshakes, and will get
77   // instantiated during the call to setup_handshakers.
78   tsi_handshaker* client_handshaker;
79   tsi_handshaker* server_handshaker;
80   // client/server TSI handshaker results used to store the result of TSI
81   // handshake. If the handshake fails, the result will store NULL upon
82   // finishing the handshake.
83   tsi_handshaker_result* client_result;
84   tsi_handshaker_result* server_result;
85   // size of buffer used to store data received from the peer.
86   size_t handshake_buffer_size;
87   // tsi_test_channel instance.
88   tsi_test_channel* channel;
89   // tsi_test_frame_protector_config instance
90   tsi_test_frame_protector_config* config;
91   // a flag indicating if client has finished TSI handshake first (i.e., before
92   // server).
93   // The flag should be referred if and only if TSI handshake finishes
94   // successfully.
95   bool has_client_finished_first;
96   // a flag indicating whether to test tsi_handshaker_result_get_unused_bytes()
97   // for TSI implementation. This field is true by default, and false
98   // for SSL TSI implementation due to grpc issue #12164
99   // (https://github.com/grpc/grpc/issues/12164).
100   //
101   bool test_unused_bytes;
102   // These objects will be used coordinate client/server handshakers with TSI
103   // thread to perform TSI handshakes in an asynchronous manner (for GTS TSI
104   // implementations).
105   //
106   gpr_cv cv;
107   gpr_mu mu;
108   bool notified;
109 };
110 
111 struct tsi_test_frame_protector_fixture {
112   // client/server TSI frame protectors whose ownership are transferred.
113   tsi_frame_protector* client_frame_protector;
114   tsi_frame_protector* server_frame_protector;
115   // tsi_test_channel instance.
116   tsi_test_channel* channel;
117   // tsi_test_frame_protector_config instance
118   tsi_test_frame_protector_config* config;
119 };
120 
121 struct tsi_test_channel {
122   // simulated channels between client and server. If the server (client)
123   // wants to send data to the client (server), he will write data to
124   // client_channel (server_channel), which will be read by client (server).
125   uint8_t* client_channel;
126   uint8_t* server_channel;
127   // size of data written to the client/server channel.
128   size_t bytes_written_to_client_channel;
129   size_t bytes_written_to_server_channel;
130   // size of data read from the client/server channel
131   size_t bytes_read_from_client_channel;
132   size_t bytes_read_from_server_channel;
133 };
134 
135 struct tsi_test_frame_protector_config {
136   // size of buffer used to store protected frames to be unprotected.
137   size_t read_buffer_allocated_size;
138   // size of buffer used to store bytes resulted from unprotect operations.
139   size_t message_buffer_allocated_size;
140   // size of buffer used to store frames resulted from protect operations.
141   size_t protected_buffer_size;
142   // size of client/server maximum frame size.
143   size_t client_max_output_protected_frame_size;
144   size_t server_max_output_protected_frame_size;
145   // pointer that points to client/server message to be protected.
146   uint8_t* client_message;
147   uint8_t* server_message;
148   // size of client/server message.
149   size_t client_message_size;
150   size_t server_message_size;
151 };
152 
153 // This method creates a tsi_test_frame_protector_config instance. Each
154 // parameter of this function is a boolean value indicating whether to set the
155 // corresponding parameter with a default value or not. If it's false, it will
156 // be set with a specific value which is usually much smaller than the default.
157 // Both values are defined with #define directive.
158 tsi_test_frame_protector_config* tsi_test_frame_protector_config_create(
159     bool use_default_read_buffer_allocated_size,
160     bool use_default_message_buffer_allocated_size,
161     bool use_default_protected_buffer_size, bool use_default_client_message,
162     bool use_default_server_message,
163     bool use_default_client_max_output_protected_frame_size,
164     bool use_default_server_max_output_protected_frame_size);
165 
166 // This method sets different buffer and frame sizes of a
167 // tsi_test_frame_protector_config instance with user provided values.
168 void tsi_test_frame_protector_config_set_buffer_size(
169     tsi_test_frame_protector_config* config, size_t read_buffer_allocated_size,
170     size_t message_buffer_allocated_size, size_t protected_buffer_size,
171     size_t client_max_output_protected_frame_size,
172     size_t server_max_output_protected_frame_size);
173 
174 // This method destroys a tsi_test_frame_protector_config instance.
175 void tsi_test_frame_protector_config_destroy(
176     tsi_test_frame_protector_config* config);
177 
178 // This method initializes members of tsi_test_fixture instance.
179 // Note that the struct instance should be allocated before making
180 // this call.
181 void tsi_test_fixture_init(tsi_test_fixture* fixture);
182 
183 // This method destroys a tsi_test_fixture instance. Note that the
184 // fixture instance must be dynamically allocated and will be freed by
185 // this function.
186 void tsi_test_fixture_destroy(tsi_test_fixture* fixture);
187 
188 // This method creates a tsi_test_frame_protector_fixture instance.
189 tsi_test_frame_protector_fixture* tsi_test_frame_protector_fixture_create();
190 
191 // This method initializes members of tsi_test_frame_protector_fixture instance.
192 // Note that the struct instance should be allocated before making
193 // this call.
194 void tsi_test_frame_protector_fixture_init(
195     tsi_test_frame_protector_fixture* fixture,
196     tsi_frame_protector* client_frame_protector,
197     tsi_frame_protector* server_frame_protector);
198 
199 // This method destroys a tsi_test_frame_protector_fixture instance. Note that
200 // the fixture instance must be dynamically allocated and will be freed by this
201 // function.
202 void tsi_test_frame_protector_fixture_destroy(
203     tsi_test_frame_protector_fixture* fixture);
204 
205 // This method performs a protect operation on raw data and sends the result to
206 // peer.
207 void tsi_test_frame_protector_send_message_to_peer(
208     tsi_test_frame_protector_config* config, tsi_test_channel* channel,
209     tsi_frame_protector* protector, bool is_client);
210 
211 // This method receives message from peer and unprotects it.
212 void tsi_test_frame_protector_receive_message_from_peer(
213     tsi_test_frame_protector_config* config, tsi_test_channel* channel,
214     tsi_frame_protector* protector, unsigned char* message,
215     size_t* bytes_received, bool is_client);
216 
217 // This method performs a full TSI handshake between a client and a server.
218 // Note that the test library will implement the new TSI handshaker API to
219 // perform handshakes.
220 void tsi_test_do_handshake(tsi_test_fixture* fixture);
221 
222 // This method performs a round trip test between the client and the server.
223 // That is, the client sends a protected message to a server who receives the
224 // message, and unprotects it. The same operation is triggered again with
225 // the client and server switching its role.
226 void tsi_test_do_round_trip(tsi_test_fixture* fixture);
227 
228 // This method performs the above round trip test without doing handshakes.
229 void tsi_test_frame_protector_do_round_trip_no_handshake(
230     tsi_test_frame_protector_fixture* fixture);
231 
232 struct SelfSignedCertificateOptions {
233   std::string common_name;
234   std::string organization;
235   std::string organizational_unit;
236 };
237 
238 // Returns a PEM-encoded self-signed certificate.
239 std::string GenerateSelfSignedCertificate(
240     const SelfSignedCertificateOptions& options);
241 
242 // Returns the OpenSSL representation of a PEM cert.
243 X509* ReadPemCert(absl::string_view pem_cert);
244 
245 // Returns the OpenSSL representation of a CRL.
246 X509_CRL* ReadCrl(absl::string_view crl_pem);
247 
248 #endif  // GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H
249