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