3 * Copyright 2018 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <grpc/support/port_platform.h>
21 #include "src/core/tsi/alts/frame_protector/frame_handler.h"
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
30 #include "src/core/lib/gpr/useful.h"
32 /* Use little endian to interpret a string of bytes as uint32_t. */
33 static uint32_t load_32_le(const unsigned char* buffer) {
34 return (((uint32_t)buffer[3]) << 24) | (((uint32_t)buffer[2]) << 16) |
35 (((uint32_t)buffer[1]) << 8) | ((uint32_t)buffer[0]);
38 /* Store uint32_t as a string of little endian bytes. */
39 static void store_32_le(uint32_t value, unsigned char* buffer) {
40 buffer[3] = (unsigned char)(value >> 24) & 0xFF;
41 buffer[2] = (unsigned char)(value >> 16) & 0xFF;
42 buffer[1] = (unsigned char)(value >> 8) & 0xFF;
43 buffer[0] = (unsigned char)(value)&0xFF;
46 /* Frame writer implementation. */
47 alts_frame_writer* alts_create_frame_writer() {
48 alts_frame_writer* writer =
49 static_cast<alts_frame_writer*>(gpr_zalloc(sizeof(*writer)));
53 bool alts_reset_frame_writer(alts_frame_writer* writer,
54 const unsigned char* buffer, size_t length) {
55 if (buffer == nullptr) return false;
56 size_t max_input_size = SIZE_MAX - kFrameLengthFieldSize;
57 if (length > max_input_size) {
58 gpr_log(GPR_ERROR, "length must be at most %zu", max_input_size);
61 writer->input_buffer = buffer;
62 writer->input_size = length;
63 writer->input_bytes_written = 0;
64 writer->header_bytes_written = 0;
66 static_cast<uint32_t>(writer->input_size + kFrameMessageTypeFieldSize),
67 writer->header_buffer);
68 store_32_le(kFrameMessageType, writer->header_buffer + kFrameLengthFieldSize);
72 bool alts_write_frame_bytes(alts_frame_writer* writer, unsigned char* output,
74 if (bytes_size == nullptr || output == nullptr) return false;
75 if (alts_is_frame_writer_done(writer)) {
79 size_t bytes_written = 0;
80 /* Write some header bytes, if needed. */
81 if (writer->header_bytes_written != sizeof(writer->header_buffer)) {
82 size_t bytes_to_write =
84 sizeof(writer->header_buffer) - writer->header_bytes_written);
85 memcpy(output, writer->header_buffer + writer->header_bytes_written,
87 bytes_written += bytes_to_write;
88 *bytes_size -= bytes_to_write;
89 writer->header_bytes_written += bytes_to_write;
90 output += bytes_to_write;
91 if (writer->header_bytes_written != sizeof(writer->header_buffer)) {
92 *bytes_size = bytes_written;
96 /* Write some non-header bytes. */
97 size_t bytes_to_write =
98 GPR_MIN(writer->input_size - writer->input_bytes_written, *bytes_size);
99 memcpy(output, writer->input_buffer, bytes_to_write);
100 writer->input_buffer += bytes_to_write;
101 bytes_written += bytes_to_write;
102 writer->input_bytes_written += bytes_to_write;
103 *bytes_size = bytes_written;
107 bool alts_is_frame_writer_done(alts_frame_writer* writer) {
108 return writer->input_buffer == nullptr ||
109 writer->input_size == writer->input_bytes_written;
112 size_t alts_get_num_writer_bytes_remaining(alts_frame_writer* writer) {
113 return (sizeof(writer->header_buffer) - writer->header_bytes_written) +
114 (writer->input_size - writer->input_bytes_written);
117 void alts_destroy_frame_writer(alts_frame_writer* writer) { gpr_free(writer); }
119 /* Frame reader implementation. */
120 alts_frame_reader* alts_create_frame_reader() {
121 alts_frame_reader* reader =
122 static_cast<alts_frame_reader*>(gpr_zalloc(sizeof(*reader)));
126 bool alts_is_frame_reader_done(alts_frame_reader* reader) {
127 return reader->output_buffer == nullptr ||
128 (reader->header_bytes_read == sizeof(reader->header_buffer) &&
129 reader->bytes_remaining == 0);
132 bool alts_has_read_frame_length(alts_frame_reader* reader) {
133 return sizeof(reader->header_buffer) == reader->header_bytes_read;
136 size_t alts_get_reader_bytes_remaining(alts_frame_reader* reader) {
137 return alts_has_read_frame_length(reader) ? reader->bytes_remaining : 0;
140 void alts_reset_reader_output_buffer(alts_frame_reader* reader,
141 unsigned char* buffer) {
142 reader->output_buffer = buffer;
145 bool alts_reset_frame_reader(alts_frame_reader* reader, unsigned char* buffer) {
146 if (buffer == nullptr) return false;
147 reader->output_buffer = buffer;
148 reader->bytes_remaining = 0;
149 reader->header_bytes_read = 0;
150 reader->output_bytes_read = 0;
154 bool alts_read_frame_bytes(alts_frame_reader* reader,
155 const unsigned char* bytes, size_t* bytes_size) {
156 if (bytes_size == nullptr) return false;
157 if (bytes == nullptr) {
161 if (alts_is_frame_reader_done(reader)) {
165 size_t bytes_processed = 0;
166 /* Process the header, if needed. */
167 if (reader->header_bytes_read != sizeof(reader->header_buffer)) {
168 size_t bytes_to_write = GPR_MIN(
169 *bytes_size, sizeof(reader->header_buffer) - reader->header_bytes_read);
170 memcpy(reader->header_buffer + reader->header_bytes_read, bytes,
172 reader->header_bytes_read += bytes_to_write;
173 bytes_processed += bytes_to_write;
174 bytes += bytes_to_write;
175 *bytes_size -= bytes_to_write;
176 if (reader->header_bytes_read != sizeof(reader->header_buffer)) {
177 *bytes_size = bytes_processed;
180 size_t frame_length = load_32_le(reader->header_buffer);
181 if (frame_length < kFrameMessageTypeFieldSize ||
182 frame_length > kFrameMaxSize) {
184 "Bad frame length (should be at least %zu, and at most %zu)",
185 kFrameMessageTypeFieldSize, kFrameMaxSize);
189 size_t message_type =
190 load_32_le(reader->header_buffer + kFrameLengthFieldSize);
191 if (message_type != kFrameMessageType) {
192 gpr_log(GPR_ERROR, "Unsupported message type %zu (should be %zu)",
193 message_type, kFrameMessageType);
197 reader->bytes_remaining = frame_length - kFrameMessageTypeFieldSize;
199 /* Process the non-header bytes. */
200 size_t bytes_to_write = GPR_MIN(*bytes_size, reader->bytes_remaining);
201 memcpy(reader->output_buffer, bytes, bytes_to_write);
202 reader->output_buffer += bytes_to_write;
203 bytes_processed += bytes_to_write;
204 reader->bytes_remaining -= bytes_to_write;
205 reader->output_bytes_read += bytes_to_write;
206 *bytes_size = bytes_processed;
210 size_t alts_get_output_bytes_read(alts_frame_reader* reader) {
211 return reader->output_bytes_read;
214 unsigned char* alts_get_output_buffer(alts_frame_reader* reader) {
215 return reader->output_buffer;
218 void alts_destroy_frame_reader(alts_frame_reader* reader) { gpr_free(reader); }