GRPC Core 0.10.0.0

- Main Page
- Data Structures
- Files

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
transport_security_interface.h
Go to the documentation of this file.
1 /*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 #ifndef GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
35 #define GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
36
37 #include <stdint.h>
38 #include <stdlib.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /* --- tsi result --- */
45
46 typedef enum {
47 TSI_OK = 0,
48 TSI_UNKNOWN_ERROR = 1,
49 TSI_INVALID_ARGUMENT = 2,
50 TSI_PERMISSION_DENIED = 3,
51 TSI_INCOMPLETE_DATA = 4,
52 TSI_FAILED_PRECONDITION = 5,
53 TSI_UNIMPLEMENTED = 6,
54 TSI_INTERNAL_ERROR = 7,
55 TSI_DATA_CORRUPTED = 8,
56 TSI_NOT_FOUND = 9,
57 TSI_PROTOCOL_FAILURE = 10,
58 TSI_HANDSHAKE_IN_PROGRESS = 11,
59 TSI_OUT_OF_RESOURCES = 12
60 } tsi_result;
61
62 const char* tsi_result_to_string(tsi_result result);
63
64 /* --- tsi tracing --- */
65
66 /* Set this early to avoid races */
67 extern int tsi_tracing_enabled;
68
69 /* --- tsi_frame_protector object ---
70
71 This object protects and unprotects buffers once the handshake is done.
72 Implementations of this object must be thread compatible. */
73
74 typedef struct tsi_frame_protector tsi_frame_protector;
75
76 /* Outputs protected frames.
77 - unprotected_bytes is an input only parameter and points to the data
78 to be protected.
79 - unprotected_bytes_size is an input/output parameter used by the caller to
80 specify how many bytes are available in unprotected_bytes. The output
81 value is the number of bytes consumed during the call.
82 - protected_output_frames points to a buffer allocated by the caller that
83 will be written.
84 - protected_output_frames_size is an input/output parameter used by the
85 caller to specify how many bytes are available in protected_output_frames.
86 As an output, this value indicates the number of bytes written.
87 - This method returns TSI_OK in case of success or a specific error code in
88 case of failure. Note that even if all the input unprotected bytes are
89 consumed, they may not have been processed into the returned protected
90 output frames. The caller should call the protect_flush method
91 to make sure that there are no more protected bytes buffered in the
92 protector.
93
94 A typical way to call this method would be:
95
96 ------------------------------------------------------------------------
97 unsigned char protected_buffer[4096];
98 size_t protected_buffer_size = sizeof(protected_buffer);
99 tsi_result result = TSI_OK;
100 while (message_size > 0) {
101 size_t protected_buffer_size_to_send = protected_buffer_size;
102 size_t processed_message_size = message_size;
103 result = tsi_frame_protector_protect(protector,
104 message_bytes,
105 &processed_message_size,
106 protected_buffer,
107 &protected_buffer_size_to_send);
108 if (result != TSI_OK) break;
109 send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send);
110 message_bytes += processed_message_size;
111 message_size -= processed_message_size;
112
113 // Don't forget to flush.
114 if (message_size == 0) {
115 size_t still_pending_size;
116 do {
117 protected_buffer_size_to_send = protected_buffer_size;
118 result = tsi_frame_protector_protect_flush(
119 protector, protected_buffer,
120 &protected_buffer_size_to_send, &still_pending_size);
121 if (result != TSI_OK) break;
122 send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send);
123 } while (still_pending_size > 0);
124 }
125 }
126
127 if (result != TSI_OK) HandleError(result);
128 ------------------------------------------------------------------------ */
129 tsi_result tsi_frame_protector_protect(tsi_frame_protector* self,
130 const unsigned char* unprotected_bytes,
131 size_t* unprotected_bytes_size,
132 unsigned char* protected_output_frames,
133 size_t* protected_output_frames_size);
134
135 /* Indicates that we need to flush the bytes buffered in the protector and get
136 the resulting frame.
137 - protected_output_frames points to a buffer allocated by the caller that
138 will be written.
139 - protected_output_frames_size is an input/output parameter used by the
140 caller to specify how many bytes are available in protected_output_frames.
141 - still_pending_bytes is an output parameter indicating the number of bytes
142 that still need to be flushed from the protector.*/
143 tsi_result tsi_frame_protector_protect_flush(
144 tsi_frame_protector* self, unsigned char* protected_output_frames,
145 size_t* protected_output_frames_size, size_t* still_pending_size);
146
147 /* Outputs unprotected bytes.
148 - protected_frames_bytes is an input only parameter and points to the
149 protected frames to be unprotected.
150 - protected_frames_bytes_size is an input/output only parameter used by the
151 caller to specify how many bytes are available in protected_bytes. The
152 output value is the number of bytes consumed during the call.
153 Implementations will buffer up to a frame of protected data.
154 - unprotected_bytes points to a buffer allocated by the caller that will be
155 written.
156 - unprotected_bytes_size is an input/output parameter used by the caller to
157 specify how many bytes are available in unprotected_bytes. This
158 value is expected to be at most max_protected_frame_size minus overhead
159 which means that max_protected_frame_size is a safe bet. The output value
160 is the number of bytes actually written.
161
162 - This method returns TSI_OK in case of success. Success includes cases where
163 there is not enough data to output a frame in which case
164 unprotected_bytes_size will be set to 0 and cases where the internal buffer
165 needs to be read before new protected data can be processed in which case
166 protected_frames_size will be set to 0. */
167 tsi_result tsi_frame_protector_unprotect(
168 tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
169 size_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
170 size_t* unprotected_bytes_size);
171
172 /* Destroys the tsi_frame_protector object. */
173 void tsi_frame_protector_destroy(tsi_frame_protector* self);
174
175 /* --- tsi_peer objects ---
176
177 tsi_peer objects are a set of properties. The peer owns the properties. */
178
179 /* This property is of type TSI_PEER_PROPERTY_STRING. */
180 #define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type"
181
182 /* Property values may contain NULL characters just like C++ strings.
183 The length field gives the length of the string. */
184 typedef struct tsi_peer_property {
185 char* name;
186 struct {
187 char* data;
188 size_t length;
189 } value;
190 } tsi_peer_property;
191
192 typedef struct {
193 tsi_peer_property* properties;
194 size_t property_count;
195 } tsi_peer;
196
197 /* Destructs the tsi_peer object. */
198 void tsi_peer_destruct(tsi_peer* self);
199
200 /* --- tsi_handshaker objects ----
201
202 Implementations of this object must be thread compatible.
203
204 A typical usage of this object would be:
205
206 ------------------------------------------------------------------------
207 tsi_result result = TSI_OK;
208 unsigned char buf[4096];
209 size_t buf_offset;
210 size_t buf_size;
211 while (1) {
212 // See if we need to send some bytes to the peer.
213 do {
214 size_t buf_size_to_send = sizeof(buf);
215 result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf,
216 &buf_size_to_send);
217 if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send);
218 } while (result == TSI_INCOMPLETE_DATA);
219 if (result != TSI_OK) return result;
220 if (!tsi_handshaker_is_in_progress(handshaker)) break;
221
222 do {
223 // Read bytes from the peer.
224 buf_size = sizeof(buf);
225 buf_offset = 0;
226 read_bytes_from_peer(buf, &buf_size);
227 if (buf_size == 0) break;
228
229 // Process the bytes from the peer. We have to be careful as these bytes
230 // may contain non-handshake data (protected data). If this is the case,
231 // we will exit from the loop with buf_size > 0.
232 size_t consumed_by_handshaker = buf_size;
233 result = tsi_handshaker_process_bytes_from_peer(
234 handshaker, buf, &consumed_by_handshaker);
235 buf_size -= consumed_by_handshaker;
236 buf_offset += consumed_by_handshaker;
237 } while (result == TSI_INCOMPLETE_DATA);
238
239 if (result != TSI_OK) return result;
240 if (!tsi_handshaker_is_in_progress(handshaker)) break;
241 }
242
243 // Check the Peer.
244 tsi_peer peer;
245 do {
246 result = tsi_handshaker_extract_peer(handshaker, &peer);
247 if (result != TSI_OK) break;
248 result = check_peer(&peer);
249 } while (0);
250 tsi_peer_destruct(&peer);
251 if (result != TSI_OK) return result;
252
253 // Create the protector.
254 tsi_frame_protector* protector = NULL;
255 result = tsi_handshaker_create_frame_protector(handshaker, NULL,
256 &protector);
257 if (result != TSI_OK) return result;
258
259 // Do not forget to unprotect outstanding data if any.
260 if (buf_size > 0) {
261 result = tsi_frame_protector_unprotect(protector, buf + buf_offset,
262 buf_size, ..., ...);
263 ....
264 }
265 ...
266 ------------------------------------------------------------------------ */
267 typedef struct tsi_handshaker tsi_handshaker;
268
269 /* Gets bytes that need to be sent to the peer.
270 - bytes is the buffer that will be written with the data to be sent to the
271 peer.
272 - bytes_size is an input/output parameter specifying the capacity of the
273 bytes parameter as input and the number of bytes written as output.
274 Returns TSI_OK if all the data to send to the peer has been written or if
275 nothing has to be sent to the peer (in which base bytes_size outputs to 0),
276 otherwise returns TSI_INCOMPLETE_DATA which indicates that this method
277 needs to be called again to get all the bytes to send to the peer (there
278 was more data to write than the specified bytes_size). In case of a fatal
279 error in the handshake, another specific error code is returned. */
280 tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
281 unsigned char* bytes,
282 size_t* bytes_size);
283
284 /* Processes bytes received from the peer.
285 - bytes is the buffer containing the data.
286 - bytes_size is an input/output parameter specifying the size of the data as
287 input and the number of bytes consumed as output.
288 Return TSI_OK if the handshake has all the data it needs to process,
289 otherwise return TSI_INCOMPLETE_DATA which indicates that this method
290 needs to be called again to complete the data needed for processing. In
291 case of a fatal error in the handshake, another specific error code is
292 returned. */
293 tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker* self,
294 const unsigned char* bytes,
295 size_t* bytes_size);
296
297 /* Gets the result of the handshaker.
298 Returns TSI_OK if the hanshake completed successfully and there has been no
299 errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet
300 but no error has been encountered so far. Otherwise the handshaker failed
301 with the returned error. */
302 tsi_result tsi_handshaker_get_result(tsi_handshaker* self);
303
304 /* Returns 1 if the handshake is in progress, 0 otherwise. */
305 #define tsi_handshaker_is_in_progress(h) \
306 (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS)
307
308 /* This method may return TSI_FAILED_PRECONDITION if
309 tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise
310 assuming the handshaker is not in a fatal error state.
311 The caller is responsible for destructing the peer. */
312 tsi_result tsi_handshaker_extract_peer(tsi_handshaker* self, tsi_peer* peer);
313
314 /* This method creates a tsi_frame_protector object after the handshake phase
315 is done. After this method has been called successfully, the only method
316 that can be called on this object is Destroy.
317 - max_output_protected_frame_size is an input/output parameter specifying the
318 desired max output protected frame size as input and outputing the actual
319 max output frame size as the output. Passing NULL is OK and will result in
320 the implementation choosing the default maximum protected frame size. Note
321 that this size only applies to outgoing frames (generated with
322 tsi_frame_protector_protect) and not incoming frames (input of
323 tsi_frame_protector_unprotect).
324 - protector is an output parameter pointing to the newly created
325 tsi_frame_protector object.
326 This method may return TSI_FAILED_PRECONDITION if
327 tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming
328 the handshaker is not in a fatal error state.
329 The caller is responsible for destroying the protector. */
330 tsi_result tsi_handshaker_create_frame_protector(
331 tsi_handshaker* self, size_t* max_output_protected_frame_size,
332 tsi_frame_protector** protector);
333
334 /* This method releases the tsi_handshaker object. After this method is called,
335 no other method can be called on the object. */
336 void tsi_handshaker_destroy(tsi_handshaker* self);
337
338 #ifdef __cplusplus
339 }
340 #endif
341
342 #endif /* GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */
tsi_frame_protector
Definition: transport_security.h:65
tsi_handshaker_process_bytes_from_peer
tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size)
Definition: transport_security.c:153
TSI_PROTOCOL_FAILURE
Definition: transport_security_interface.h:57
TSI_INTERNAL_ERROR
Definition: transport_security_interface.h:54
TSI_OUT_OF_RESOURCES
Definition: transport_security_interface.h:59
tsi_handshaker_get_bytes_to_send_to_peer
tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size)
Definition: transport_security.c:145
tsi_peer_destruct
void tsi_peer_destruct(tsi_peer *self)
Definition: transport_security.c:226
tsi_frame_protector_protect
tsi_result tsi_frame_protector_protect(tsi_frame_protector *self, const unsigned char *unprotected_bytes, size_t *unprotected_bytes_size, unsigned char *protected_output_frames, size_t *protected_output_frames_size)
Definition: transport_security.c:95
tsi_frame_protector_unprotect
tsi_result tsi_frame_protector_unprotect(tsi_frame_protector *self, const unsigned char *protected_frames_bytes, size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, size_t *unprotected_bytes_size)
Definition: transport_security.c:122
tsi_peer_property::data
char * data
Definition: transport_security_interface.h:187
tsi_peer_property::value
struct tsi_peer_property::@12 value
TSI_DATA_CORRUPTED
Definition: transport_security_interface.h:55
tsi_peer
Definition: transport_security_interface.h:192
TSI_INCOMPLETE_DATA
Definition: transport_security_interface.h:51
TSI_PERMISSION_DENIED
Definition: transport_security_interface.h:50
TSI_FAILED_PRECONDITION
Definition: transport_security_interface.h:52
tsi_peer::properties
tsi_peer_property * properties
Definition: transport_security_interface.h:193
tsi_peer::property_count
size_t property_count
Definition: transport_security_interface.h:194
tsi_result
tsi_result
Definition: transport_security_interface.h:46
tsi_handshaker_destroy
void tsi_handshaker_destroy(tsi_handshaker *self)
Definition: transport_security.c:194
TSI_UNIMPLEMENTED
Definition: transport_security_interface.h:53
tsi_handshaker_create_frame_protector
tsi_result tsi_handshaker_create_frame_protector(tsi_handshaker *self, size_t *max_output_protected_frame_size, tsi_frame_protector **protector)
Definition: transport_security.c:177
tsi_tracing_enabled
int tsi_tracing_enabled
Definition: transport_security.c:41
TSI_NOT_FOUND
Definition: transport_security_interface.h:56
tsi_handshaker_get_result
tsi_result tsi_handshaker_get_result(tsi_handshaker *self)
Definition: transport_security.c:161
tsi_peer_property
struct tsi_peer_property tsi_peer_property
TSI_INVALID_ARGUMENT
Definition: transport_security_interface.h:49
tsi_peer_property::name
char * name
Definition: transport_security_interface.h:185
tsi_handshaker_extract_peer
tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer)
Definition: transport_security.c:167
tsi_frame_protector_destroy
void tsi_frame_protector_destroy(tsi_frame_protector *self)
Definition: transport_security.c:136
TSI_HANDSHAKE_IN_PROGRESS
Definition: transport_security_interface.h:58
tsi_handshaker
Definition: transport_security.h:86
tsi_frame_protector_protect_flush
tsi_result tsi_frame_protector_protect_flush(tsi_frame_protector *self, unsigned char *protected_output_frames, size_t *protected_output_frames_size, size_t *still_pending_size)
Definition: transport_security.c:110
tsi_result_to_string
const char * tsi_result_to_string(tsi_result result)
Definition: transport_security.c:58
tsi_peer_property::length
size_t length
Definition: transport_security_interface.h:188
TSI_UNKNOWN_ERROR
Definition: transport_security_interface.h:48
TSI_OK
Definition: transport_security_interface.h:47
tsi_peer_property
Definition: transport_security_interface.h:184