• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
grpc_gcp_rpc_protocol_versions_set_max(grpc_gcp_rpc_protocol_versions * versions,uint32_t max_major,uint32_t max_minor)23 bool grpc_gcp_rpc_protocol_versions_set_max(
24     grpc_gcp_rpc_protocol_versions* versions, uint32_t max_major,
25     uint32_t max_minor) {
26   if (versions == nullptr) {
27     gpr_log(GPR_ERROR,
28             "versions is nullptr in "
29             "grpc_gcp_rpc_protocol_versions_set_max().");
30     return false;
31   }
32   versions->has_max_rpc_version = true;
33   versions->max_rpc_version.has_major = true;
34   versions->max_rpc_version.has_minor = true;
35   versions->max_rpc_version.major = max_major;
36   versions->max_rpc_version.minor = max_minor;
37   return true;
38 }
39 
grpc_gcp_rpc_protocol_versions_set_min(grpc_gcp_rpc_protocol_versions * versions,uint32_t min_major,uint32_t min_minor)40 bool grpc_gcp_rpc_protocol_versions_set_min(
41     grpc_gcp_rpc_protocol_versions* versions, uint32_t min_major,
42     uint32_t min_minor) {
43   if (versions == nullptr) {
44     gpr_log(GPR_ERROR,
45             "versions is nullptr in "
46             "grpc_gcp_rpc_protocol_versions_set_min().");
47     return false;
48   }
49   versions->has_min_rpc_version = true;
50   versions->min_rpc_version.has_major = true;
51   versions->min_rpc_version.has_minor = true;
52   versions->min_rpc_version.major = min_major;
53   versions->min_rpc_version.minor = min_minor;
54   return true;
55 }
56 
grpc_gcp_rpc_protocol_versions_encode_length(const grpc_gcp_rpc_protocol_versions * versions)57 size_t grpc_gcp_rpc_protocol_versions_encode_length(
58     const grpc_gcp_rpc_protocol_versions* versions) {
59   if (versions == nullptr) {
60     gpr_log(GPR_ERROR,
61             "Invalid nullptr arguments to "
62             "grpc_gcp_rpc_protocol_versions_encode_length().");
63     return 0;
64   }
65   pb_ostream_t size_stream;
66   memset(&size_stream, 0, sizeof(pb_ostream_t));
67   if (!pb_encode(&size_stream, grpc_gcp_RpcProtocolVersions_fields, versions)) {
68     gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&size_stream));
69     return 0;
70   }
71   return size_stream.bytes_written;
72 }
73 
grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes(const grpc_gcp_rpc_protocol_versions * versions,uint8_t * bytes,size_t bytes_length)74 bool grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes(
75     const grpc_gcp_rpc_protocol_versions* versions, uint8_t* bytes,
76     size_t bytes_length) {
77   if (versions == nullptr || bytes == nullptr || bytes_length == 0) {
78     gpr_log(GPR_ERROR,
79             "Invalid nullptr arguments to "
80             "grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes().");
81     return false;
82   }
83   pb_ostream_t output_stream = pb_ostream_from_buffer(bytes, bytes_length);
84   if (!pb_encode(&output_stream, grpc_gcp_RpcProtocolVersions_fields,
85                  versions)) {
86     gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&output_stream));
87     return false;
88   }
89   return true;
90 }
91 
grpc_gcp_rpc_protocol_versions_encode(const grpc_gcp_rpc_protocol_versions * versions,grpc_slice * slice)92 bool grpc_gcp_rpc_protocol_versions_encode(
93     const grpc_gcp_rpc_protocol_versions* versions, grpc_slice* slice) {
94   if (versions == nullptr || slice == nullptr) {
95     gpr_log(GPR_ERROR,
96             "Invalid nullptr arguments to "
97             "grpc_gcp_rpc_protocol_versions_encode().");
98     return false;
99   }
100   size_t encoded_length =
101       grpc_gcp_rpc_protocol_versions_encode_length(versions);
102   if (encoded_length == 0) return false;
103   *slice = grpc_slice_malloc(encoded_length);
104   return grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes(
105       versions, GRPC_SLICE_START_PTR(*slice), encoded_length);
106 }
107 
grpc_gcp_rpc_protocol_versions_decode(grpc_slice slice,grpc_gcp_rpc_protocol_versions * versions)108 bool grpc_gcp_rpc_protocol_versions_decode(
109     grpc_slice slice, grpc_gcp_rpc_protocol_versions* versions) {
110   if (versions == nullptr) {
111     gpr_log(GPR_ERROR,
112             "version is nullptr in "
113             "grpc_gcp_rpc_protocol_versions_decode().");
114     return false;
115   }
116   pb_istream_t stream = pb_istream_from_buffer(GRPC_SLICE_START_PTR(slice),
117                                                GRPC_SLICE_LENGTH(slice));
118   if (!pb_decode(&stream, grpc_gcp_RpcProtocolVersions_fields, versions)) {
119     gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
120     return false;
121   }
122   return true;
123 }
124 
grpc_gcp_rpc_protocol_versions_copy(const grpc_gcp_rpc_protocol_versions * src,grpc_gcp_rpc_protocol_versions * dst)125 bool grpc_gcp_rpc_protocol_versions_copy(
126     const grpc_gcp_rpc_protocol_versions* src,
127     grpc_gcp_rpc_protocol_versions* dst) {
128   if ((src == nullptr && dst != nullptr) ||
129       (src != nullptr && dst == nullptr)) {
130     gpr_log(GPR_ERROR,
131             "Invalid arguments to "
132             "grpc_gcp_rpc_protocol_versions_copy().");
133     return false;
134   }
135   if (src == nullptr) {
136     return true;
137   }
138   grpc_gcp_rpc_protocol_versions_set_max(dst, src->max_rpc_version.major,
139                                          src->max_rpc_version.minor);
140   grpc_gcp_rpc_protocol_versions_set_min(dst, src->min_rpc_version.major,
141                                          src->min_rpc_version.minor);
142   return true;
143 }
144 
145 namespace grpc_core {
146 namespace internal {
147 
grpc_gcp_rpc_protocol_version_compare(const grpc_gcp_rpc_protocol_versions_version * v1,const grpc_gcp_rpc_protocol_versions_version * v2)148 int grpc_gcp_rpc_protocol_version_compare(
149     const grpc_gcp_rpc_protocol_versions_version* v1,
150     const grpc_gcp_rpc_protocol_versions_version* v2) {
151   if ((v1->major > v2->major) ||
152       (v1->major == v2->major && v1->minor > v2->minor)) {
153     return 1;
154   }
155   if ((v1->major < v2->major) ||
156       (v1->major == v2->major && v1->minor < v2->minor)) {
157     return -1;
158   }
159   return 0;
160 }
161 
162 }  // namespace internal
163 }  // namespace grpc_core
164 
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)165 bool grpc_gcp_rpc_protocol_versions_check(
166     const grpc_gcp_rpc_protocol_versions* local_versions,
167     const grpc_gcp_rpc_protocol_versions* peer_versions,
168     grpc_gcp_rpc_protocol_versions_version* highest_common_version) {
169   if (local_versions == nullptr || peer_versions == nullptr) {
170     gpr_log(GPR_ERROR,
171             "Invalid arguments to "
172             "grpc_gcp_rpc_protocol_versions_check().");
173     return false;
174   }
175   /* max_common_version is MIN(local.max, peer.max) */
176   const grpc_gcp_rpc_protocol_versions_version* max_common_version =
177       grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
178           &local_versions->max_rpc_version, &peer_versions->max_rpc_version) > 0
179           ? &peer_versions->max_rpc_version
180           : &local_versions->max_rpc_version;
181   /* min_common_version is MAX(local.min, peer.min) */
182   const grpc_gcp_rpc_protocol_versions_version* min_common_version =
183       grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
184           &local_versions->min_rpc_version, &peer_versions->min_rpc_version) > 0
185           ? &local_versions->min_rpc_version
186           : &peer_versions->min_rpc_version;
187   bool result = grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
188                     max_common_version, min_common_version) >= 0
189                     ? true
190                     : false;
191   if (result && highest_common_version != nullptr) {
192     memcpy(highest_common_version, max_common_version,
193            sizeof(grpc_gcp_rpc_protocol_versions_version));
194   }
195   return result;
196 }
197