blob: 14b38e644d128a273e399676a219e84366ca4a68 [file] [log] [blame]
//
//
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#ifndef GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_UTILS_H
#define GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_UTILS_H
#include <grpc/support/port_platform.h>
#include <openssl/x509.h>
#include "absl/strings/string_view.h"
#include <grpc/grpc_security_constants.h>
#include "src/core/tsi/ssl/key_logging/ssl_key_logging.h"
#include "src/core/tsi/transport_security_interface.h"
namespace grpc_core {
// Converts an SSL error status code to a readable string.
//
// error: the SSL error status code.
//
// return: the corresponding status string.
const char* SslErrorString(int error);
// Logs the SSL error stack.
void LogSslErrorStack(void);
// Performs an SSL_write and handle errors.
//
// ssl: the SSL object to write to.
// unprotected_bytes: the buffer containing the bytes for writing to |ssl|.
// unprotected_bytes_size: the size of the buffer |unprotected_bytes|.
//
// return: TSI_OK if the write operation succeeds or corresponding TSI errors.
tsi_result DoSslWrite(SSL* ssl, unsigned char* unprotected_bytes,
size_t unprotected_bytes_size);
// Performs an SSL_read and handle errors.
//
// ssl: the SSL object to read from.
// unprotected_bytes: the buffer to which this function will populate the read
// result from |ssl|.
// unprotected_bytes_size: the maximum size of the buffer |unprotected_bytes|.
// This will be populated with the size of the bytes
// read from |ssl| if this function returns TSI_OK.
//
// return: TSI_OK if the write operation succeeds or corresponding TSI errors.
tsi_result DoSslRead(SSL* ssl, unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size);
// Builds a maximum-size TLS frame if there is enough (|buffer_offset| +
// |unprotected_bytes_size| >= |buffers_size|) data. Otherwise it copies the
// |unprotected_bytes| into |buffer| and returns TSI_OK.
//
// unprotected_bytes: pointing to the buffer containing the plaintext to be
// protected.
// buffer_size: the size of |buffer|. If |buffer_offset| equals |buffer_size|,
// then we have enough data to create a TLS frame.
// buffer_offset: the offset of |buffer|. The data in |buffer| up to
// |buffer_offset| are valid data. This will be updated whenever
// new data are copied into |buffer|.
// buffer: the buffer holding the data that has not been sent for protecting.
// ssl: the |SSL| object that protects the data.
// network_io: the |BIO| object associated with |ssl|.
// unprotected_bytes_size: the size of the unprotected plaintext. This will be
// populated with the size of data that is consumed by
// this function. Caller can use this to see the size of
// unconsumed data in |unprotected_bytes|.
// protected_output_frames: the TLS frames built out of the plaintext.
// protected_output_frames_size: the size of the TLS frames built.
//
// return: TSI_OK if either successfully created a TSI frame or copied the
// |unprotected_data| into |buffer|. Returns corresponding TSI errors
// otherwise.
tsi_result SslProtectorProtect(const unsigned char* unprotected_bytes,
const size_t buffer_size, size_t& buffer_offset,
unsigned char* buffer, SSL* ssl, BIO* network_io,
std::size_t* unprotected_bytes_size,
unsigned char* protected_output_frames,
size_t* protected_output_frames_size);
// Builds a TLS frame out of the remaining plaintext bytes that's left in
// buffer. Populates the size of the remianing TLS frame to
// |still_pending_size|.
//
// buffer_size: the size of |buffer|. If |buffer_offset| equals |buffer_size|,
// then we have enough data to create a TLS frame.
// buffer_offset: the offset of |buffer|. The data in |buffer| up to
// |buffer_offset| are valid data. This will be updated whenever
// new data are copied into |buffer|.
// buffer: the buffer holding the data that has not been sent for protecting.
// ssl: the |SSL| object that protects the data.
// network_io: the |BIO| object associated with |ssl|.
// protected_output_frames: the TLS frames built out of the plaintext.
// protected_output_frames_size: the size of the TLS frames built.
// still_pending_size: the size of the bytes that remains in |network_io|.
//
// return: TSI_OK if successfully created a TSI frame. Returns corresponding TSI
// errors otherwise.
tsi_result SslProtectorProtectFlush(size_t& buffer_offset,
unsigned char* buffer, SSL* ssl,
BIO* network_io,
unsigned char* protected_output_frames,
size_t* protected_output_frames_size,
size_t* still_pending_size);
// Extracts the plaintext from a TLS frame.
//
// protected_frames_bytes: the TLS frame to extract plaintext from.
// ssl: the |SSL| object that protects the data.
// network_io: the |BIO| object associated with |ssl|.
// unprotected_bytes_size: the size of the unprotected plaintext. This will be
// populated with the size of data that is consumed by
// this function. Caller can use this to see the size of
// unconsumed data in |unprotected_bytes|.
// protected_output_frames: the TLS frames built out of the plaintext.
// protected_output_frames_size: the size of the TLS frames built.
//
// return: TSI_OK if either successfully created a TSI frame or copied the
// |unprotected_data| into |buffer|. Returns corresponding TSI errors
// otherwise.
tsi_result SslProtectorUnprotect(const unsigned char* protected_frames_bytes,
SSL* ssl, BIO* network_io,
size_t* protected_frames_bytes_size,
unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size);
} // namespace grpc_core
#endif // GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_UTILS_H