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/alts/handshaker/transport_security_common_api.h"
22
23 #include "upb/upb.hpp"
24
grpc_gcp_rpc_protocol_versions_set_max(grpc_gcp_rpc_protocol_versions * versions,uint32_t max_major,uint32_t max_minor)25 bool grpc_gcp_rpc_protocol_versions_set_max(
26 grpc_gcp_rpc_protocol_versions* versions, uint32_t max_major,
27 uint32_t max_minor) {
28 if (versions == nullptr) {
29 gpr_log(GPR_ERROR,
30 "versions is nullptr in "
31 "grpc_gcp_rpc_protocol_versions_set_max().");
32 return false;
33 }
34 versions->max_rpc_version.major = max_major;
35 versions->max_rpc_version.minor = max_minor;
36 return true;
37 }
38
grpc_gcp_rpc_protocol_versions_set_min(grpc_gcp_rpc_protocol_versions * versions,uint32_t min_major,uint32_t min_minor)39 bool grpc_gcp_rpc_protocol_versions_set_min(
40 grpc_gcp_rpc_protocol_versions* versions, uint32_t min_major,
41 uint32_t min_minor) {
42 if (versions == nullptr) {
43 gpr_log(GPR_ERROR,
44 "versions is nullptr in "
45 "grpc_gcp_rpc_protocol_versions_set_min().");
46 return false;
47 }
48 versions->min_rpc_version.major = min_major;
49 versions->min_rpc_version.minor = min_minor;
50 return true;
51 }
52
grpc_gcp_rpc_protocol_versions_encode(const grpc_gcp_rpc_protocol_versions * versions,grpc_slice * slice)53 bool grpc_gcp_rpc_protocol_versions_encode(
54 const grpc_gcp_rpc_protocol_versions* versions, grpc_slice* slice) {
55 if (versions == nullptr || slice == nullptr) {
56 gpr_log(GPR_ERROR,
57 "Invalid nullptr arguments to "
58 "grpc_gcp_rpc_protocol_versions_encode().");
59 return false;
60 }
61 upb::Arena arena;
62 grpc_gcp_RpcProtocolVersions* versions_msg =
63 grpc_gcp_RpcProtocolVersions_new(arena.ptr());
64 grpc_gcp_RpcProtocolVersions_assign_from_struct(versions_msg, arena.ptr(),
65 versions);
66 return grpc_gcp_rpc_protocol_versions_encode(versions_msg, arena.ptr(),
67 slice);
68 }
69
grpc_gcp_rpc_protocol_versions_encode(const grpc_gcp_RpcProtocolVersions * versions,upb_arena * arena,grpc_slice * slice)70 bool grpc_gcp_rpc_protocol_versions_encode(
71 const grpc_gcp_RpcProtocolVersions* versions, upb_arena* arena,
72 grpc_slice* slice) {
73 if (versions == nullptr || arena == nullptr || slice == nullptr) {
74 gpr_log(GPR_ERROR,
75 "Invalid nullptr arguments to "
76 "grpc_gcp_rpc_protocol_versions_encode().");
77 return false;
78 }
79 size_t buf_length;
80 char* buf =
81 grpc_gcp_RpcProtocolVersions_serialize(versions, arena, &buf_length);
82 if (buf == nullptr) {
83 return false;
84 }
85 *slice = grpc_slice_from_copied_buffer(buf, buf_length);
86 return true;
87 }
88
grpc_gcp_rpc_protocol_versions_decode(const grpc_slice & slice,grpc_gcp_rpc_protocol_versions * versions)89 bool grpc_gcp_rpc_protocol_versions_decode(
90 const grpc_slice& slice, grpc_gcp_rpc_protocol_versions* versions) {
91 if (versions == nullptr) {
92 gpr_log(GPR_ERROR,
93 "version is nullptr in "
94 "grpc_gcp_rpc_protocol_versions_decode().");
95 return false;
96 }
97 upb::Arena arena;
98 grpc_gcp_RpcProtocolVersions* versions_msg =
99 grpc_gcp_RpcProtocolVersions_parse(
100 reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(slice)),
101 GRPC_SLICE_LENGTH(slice), arena.ptr());
102 if (versions_msg == nullptr) {
103 gpr_log(GPR_ERROR, "cannot deserialize RpcProtocolVersions message");
104 return false;
105 }
106 grpc_gcp_rpc_protocol_versions_assign_from_upb(versions, versions_msg);
107 return true;
108 }
109
grpc_gcp_rpc_protocol_versions_assign_from_upb(grpc_gcp_rpc_protocol_versions * versions,const grpc_gcp_RpcProtocolVersions * value)110 void grpc_gcp_rpc_protocol_versions_assign_from_upb(
111 grpc_gcp_rpc_protocol_versions* versions,
112 const grpc_gcp_RpcProtocolVersions* value) {
113 const grpc_gcp_RpcProtocolVersions_Version* max_version_msg =
114 grpc_gcp_RpcProtocolVersions_max_rpc_version(value);
115 if (max_version_msg != nullptr) {
116 versions->max_rpc_version.major =
117 grpc_gcp_RpcProtocolVersions_Version_major(max_version_msg);
118 versions->max_rpc_version.minor =
119 grpc_gcp_RpcProtocolVersions_Version_minor(max_version_msg);
120 } else {
121 versions->max_rpc_version.major = 0;
122 versions->max_rpc_version.minor = 0;
123 }
124 const grpc_gcp_RpcProtocolVersions_Version* min_version_msg =
125 grpc_gcp_RpcProtocolVersions_min_rpc_version(value);
126 if (min_version_msg != nullptr) {
127 versions->min_rpc_version.major =
128 grpc_gcp_RpcProtocolVersions_Version_major(min_version_msg);
129 versions->min_rpc_version.minor =
130 grpc_gcp_RpcProtocolVersions_Version_minor(min_version_msg);
131 } else {
132 versions->min_rpc_version.major = 0;
133 versions->min_rpc_version.minor = 0;
134 }
135 }
136
grpc_gcp_RpcProtocolVersions_assign_from_struct(grpc_gcp_RpcProtocolVersions * versions,upb_arena * arena,const grpc_gcp_rpc_protocol_versions * value)137 void grpc_gcp_RpcProtocolVersions_assign_from_struct(
138 grpc_gcp_RpcProtocolVersions* versions, upb_arena* arena,
139 const grpc_gcp_rpc_protocol_versions* value) {
140 grpc_gcp_RpcProtocolVersions_Version* max_version_msg =
141 grpc_gcp_RpcProtocolVersions_mutable_max_rpc_version(versions, arena);
142 grpc_gcp_RpcProtocolVersions_Version_set_major(max_version_msg,
143 value->max_rpc_version.major);
144 grpc_gcp_RpcProtocolVersions_Version_set_minor(max_version_msg,
145 value->max_rpc_version.minor);
146 grpc_gcp_RpcProtocolVersions_Version* min_version_msg =
147 grpc_gcp_RpcProtocolVersions_mutable_min_rpc_version(versions, arena);
148 grpc_gcp_RpcProtocolVersions_Version_set_major(min_version_msg,
149 value->min_rpc_version.major);
150 grpc_gcp_RpcProtocolVersions_Version_set_minor(min_version_msg,
151 value->min_rpc_version.minor);
152 }
153
grpc_gcp_rpc_protocol_versions_copy(const grpc_gcp_rpc_protocol_versions * src,grpc_gcp_rpc_protocol_versions * dst)154 bool grpc_gcp_rpc_protocol_versions_copy(
155 const grpc_gcp_rpc_protocol_versions* src,
156 grpc_gcp_rpc_protocol_versions* dst) {
157 if ((src == nullptr && dst != nullptr) ||
158 (src != nullptr && dst == nullptr)) {
159 gpr_log(GPR_ERROR,
160 "Invalid arguments to "
161 "grpc_gcp_rpc_protocol_versions_copy().");
162 return false;
163 }
164 if (src == nullptr) {
165 return true;
166 }
167 grpc_gcp_rpc_protocol_versions_set_max(dst, src->max_rpc_version.major,
168 src->max_rpc_version.minor);
169 grpc_gcp_rpc_protocol_versions_set_min(dst, src->min_rpc_version.major,
170 src->min_rpc_version.minor);
171 return true;
172 }
173
174 namespace grpc_core {
175 namespace internal {
176
grpc_gcp_rpc_protocol_version_compare(const grpc_gcp_rpc_protocol_versions_version * v1,const grpc_gcp_rpc_protocol_versions_version * v2)177 int grpc_gcp_rpc_protocol_version_compare(
178 const grpc_gcp_rpc_protocol_versions_version* v1,
179 const grpc_gcp_rpc_protocol_versions_version* v2) {
180 if ((v1->major > v2->major) ||
181 (v1->major == v2->major && v1->minor > v2->minor)) {
182 return 1;
183 }
184 if ((v1->major < v2->major) ||
185 (v1->major == v2->major && v1->minor < v2->minor)) {
186 return -1;
187 }
188 return 0;
189 }
190
191 } // namespace internal
192 } // namespace grpc_core
193
grpc_gcp_rpc_protocol_versions_check(const grpc_gcp_rpc_protocol_versions * local_versions,const grpc_gcp_rpc_protocol_versions * peer_versions,grpc_gcp_rpc_protocol_versions_version * highest_common_version)194 bool grpc_gcp_rpc_protocol_versions_check(
195 const grpc_gcp_rpc_protocol_versions* local_versions,
196 const grpc_gcp_rpc_protocol_versions* peer_versions,
197 grpc_gcp_rpc_protocol_versions_version* highest_common_version) {
198 if (local_versions == nullptr || peer_versions == nullptr) {
199 gpr_log(GPR_ERROR,
200 "Invalid arguments to "
201 "grpc_gcp_rpc_protocol_versions_check().");
202 return false;
203 }
204 /* max_common_version is MIN(local.max, peer.max) */
205 const grpc_gcp_rpc_protocol_versions_version* max_common_version =
206 grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
207 &local_versions->max_rpc_version, &peer_versions->max_rpc_version) > 0
208 ? &peer_versions->max_rpc_version
209 : &local_versions->max_rpc_version;
210 /* min_common_version is MAX(local.min, peer.min) */
211 const grpc_gcp_rpc_protocol_versions_version* min_common_version =
212 grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
213 &local_versions->min_rpc_version, &peer_versions->min_rpc_version) > 0
214 ? &local_versions->min_rpc_version
215 : &peer_versions->min_rpc_version;
216 bool result = grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
217 max_common_version, min_common_version) >= 0;
218 if (result && highest_common_version != nullptr) {
219 memcpy(highest_common_version, max_common_version,
220 sizeof(grpc_gcp_rpc_protocol_versions_version));
221 }
222 return result;
223 }
224