Imported Upstream version 1.33.1
[platform/upstream/grpc.git] / src / core / tsi / local_transport_security.cc
1 /*
2  *
3  * Copyright 2018 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 #include <grpc/support/port_platform.h>
20
21 #include "src/core/tsi/local_transport_security.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/string_util.h>
30
31 #include "src/core/lib/iomgr/exec_ctx.h"
32 #include "src/core/tsi/transport_security_grpc.h"
33
34 /* Main struct for local TSI zero-copy frame protector. */
35 typedef struct local_zero_copy_grpc_protector {
36   tsi_zero_copy_grpc_protector base;
37 } local_zero_copy_grpc_protector;
38
39 /* Main struct for local TSI handshaker result. */
40 typedef struct local_tsi_handshaker_result {
41   tsi_handshaker_result base;
42   bool is_client;
43 } local_tsi_handshaker_result;
44
45 /* Main struct for local TSI handshaker. */
46 typedef struct local_tsi_handshaker {
47   tsi_handshaker base;
48   bool is_client;
49 } local_tsi_handshaker;
50
51 /* --- tsi_zero_copy_grpc_protector methods implementation. --- */
52
53 static tsi_result local_zero_copy_grpc_protector_protect(
54     tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices,
55     grpc_slice_buffer* protected_slices) {
56   if (self == nullptr || unprotected_slices == nullptr ||
57       protected_slices == nullptr) {
58     gpr_log(GPR_ERROR, "Invalid nullptr arguments to zero-copy grpc protect.");
59     return TSI_INVALID_ARGUMENT;
60   }
61   grpc_slice_buffer_move_into(unprotected_slices, protected_slices);
62   return TSI_OK;
63 }
64
65 static tsi_result local_zero_copy_grpc_protector_unprotect(
66     tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices,
67     grpc_slice_buffer* unprotected_slices) {
68   if (self == nullptr || unprotected_slices == nullptr ||
69       protected_slices == nullptr) {
70     gpr_log(GPR_ERROR,
71             "Invalid nullptr arguments to zero-copy grpc unprotect.");
72     return TSI_INVALID_ARGUMENT;
73   }
74   grpc_slice_buffer_move_into(protected_slices, unprotected_slices);
75   return TSI_OK;
76 }
77
78 static void local_zero_copy_grpc_protector_destroy(
79     tsi_zero_copy_grpc_protector* self) {
80   gpr_free(self);
81 }
82
83 static const tsi_zero_copy_grpc_protector_vtable
84     local_zero_copy_grpc_protector_vtable = {
85         local_zero_copy_grpc_protector_protect,
86         local_zero_copy_grpc_protector_unprotect,
87         local_zero_copy_grpc_protector_destroy,
88         nullptr /* local_zero_copy_grpc_protector_max_frame_size */};
89
90 tsi_result local_zero_copy_grpc_protector_create(
91     tsi_zero_copy_grpc_protector** protector) {
92   if (grpc_core::ExecCtx::Get() == nullptr || protector == nullptr) {
93     gpr_log(
94         GPR_ERROR,
95         "Invalid nullptr arguments to local_zero_copy_grpc_protector create.");
96     return TSI_INVALID_ARGUMENT;
97   }
98   local_zero_copy_grpc_protector* impl =
99       static_cast<local_zero_copy_grpc_protector*>(gpr_zalloc(sizeof(*impl)));
100   impl->base.vtable = &local_zero_copy_grpc_protector_vtable;
101   *protector = &impl->base;
102   return TSI_OK;
103 }
104
105 /* --- tsi_handshaker_result methods implementation. --- */
106
107 static tsi_result handshaker_result_extract_peer(
108     const tsi_handshaker_result* /*self*/, tsi_peer* /*peer*/) {
109   return TSI_OK;
110 }
111
112 static tsi_result handshaker_result_create_zero_copy_grpc_protector(
113     const tsi_handshaker_result* self,
114     size_t* /*max_output_protected_frame_size*/,
115     tsi_zero_copy_grpc_protector** protector) {
116   if (self == nullptr || protector == nullptr) {
117     gpr_log(GPR_ERROR,
118             "Invalid arguments to create_zero_copy_grpc_protector()");
119     return TSI_INVALID_ARGUMENT;
120   }
121   tsi_result ok = local_zero_copy_grpc_protector_create(protector);
122   if (ok != TSI_OK) {
123     gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
124   }
125   return ok;
126 }
127
128 static void handshaker_result_destroy(tsi_handshaker_result* self) {
129   if (self == nullptr) {
130     return;
131   }
132   local_tsi_handshaker_result* result =
133       reinterpret_cast<local_tsi_handshaker_result*>(
134           const_cast<tsi_handshaker_result*>(self));
135   gpr_free(result);
136 }
137
138 static const tsi_handshaker_result_vtable result_vtable = {
139     handshaker_result_extract_peer,
140     handshaker_result_create_zero_copy_grpc_protector,
141     nullptr, /* handshaker_result_create_frame_protector */
142     nullptr, /* handshaker_result_get_unused_bytes */
143     handshaker_result_destroy};
144
145 static tsi_result create_handshaker_result(bool is_client,
146                                            tsi_handshaker_result** self) {
147   if (self == nullptr) {
148     gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()");
149     return TSI_INVALID_ARGUMENT;
150   }
151   local_tsi_handshaker_result* result =
152       static_cast<local_tsi_handshaker_result*>(gpr_zalloc(sizeof(*result)));
153   result->is_client = is_client;
154   result->base.vtable = &result_vtable;
155   *self = &result->base;
156   return TSI_OK;
157 }
158
159 /* --- tsi_handshaker methods implementation. --- */
160
161 static tsi_result handshaker_next(
162     tsi_handshaker* self, const unsigned char* /*received_bytes*/,
163     size_t /*received_bytes_size*/, const unsigned char** /*bytes_to_send*/,
164     size_t* bytes_to_send_size, tsi_handshaker_result** result,
165     tsi_handshaker_on_next_done_cb /*cb*/, void* /*user_data*/) {
166   if (self == nullptr) {
167     gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()");
168     return TSI_INVALID_ARGUMENT;
169   }
170   /* Note that there is no interaction between TSI peers, and all operations are
171    * local.
172    */
173   local_tsi_handshaker* handshaker =
174       reinterpret_cast<local_tsi_handshaker*>(self);
175   *bytes_to_send_size = 0;
176   create_handshaker_result(handshaker->is_client, result);
177   return TSI_OK;
178 }
179
180 static void handshaker_destroy(tsi_handshaker* self) {
181   if (self == nullptr) {
182     return;
183   }
184   local_tsi_handshaker* handshaker =
185       reinterpret_cast<local_tsi_handshaker*>(self);
186   gpr_free(handshaker);
187 }
188
189 static const tsi_handshaker_vtable handshaker_vtable = {
190     nullptr, /* get_bytes_to_send_to_peer -- deprecated */
191     nullptr, /* process_bytes_from_peer   -- deprecated */
192     nullptr, /* get_result                -- deprecated */
193     nullptr, /* extract_peer              -- deprecated */
194     nullptr, /* create_frame_protector    -- deprecated */
195     handshaker_destroy,
196     handshaker_next,
197     nullptr, /* shutdown */
198 };
199
200 tsi_result local_tsi_handshaker_create(bool is_client, tsi_handshaker** self) {
201   if (self == nullptr) {
202     gpr_log(GPR_ERROR, "Invalid arguments to local_tsi_handshaker_create()");
203     return TSI_INVALID_ARGUMENT;
204   }
205   local_tsi_handshaker* handshaker =
206       static_cast<local_tsi_handshaker*>(gpr_zalloc(sizeof(*handshaker)));
207   handshaker->is_client = is_client;
208   handshaker->base.vtable = &handshaker_vtable;
209   *self = &handshaker->base;
210   return TSI_OK;
211 }