1 //
2 //
3 // Copyright 2022 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 #ifndef GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_UTILS_H
20 #define GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_UTILS_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <openssl/x509.h>
25 
26 #include "absl/strings/string_view.h"
27 
28 #include <grpc/grpc_security_constants.h>
29 
30 #include "src/core/tsi/ssl/key_logging/ssl_key_logging.h"
31 #include "src/core/tsi/transport_security_interface.h"
32 
33 namespace grpc_core {
34 
35 // Converts an SSL error status code to a readable string.
36 //
37 // error: the SSL error status code.
38 //
39 // return: the corresponding status string.
40 const char* SslErrorString(int error);
41 
42 // Logs the SSL error stack.
43 void LogSslErrorStack(void);
44 
45 // Performs an SSL_write and handle errors.
46 //
47 // ssl: the SSL object to write to.
48 // unprotected_bytes: the buffer containing the bytes for writing to |ssl|.
49 // unprotected_bytes_size: the size of the buffer |unprotected_bytes|.
50 //
51 // return: TSI_OK if the write operation succeeds or corresponding TSI errors.
52 tsi_result DoSslWrite(SSL* ssl, unsigned char* unprotected_bytes,
53                       size_t unprotected_bytes_size);
54 
55 // Performs an SSL_read and handle errors.
56 //
57 // ssl: the SSL object to read from.
58 // unprotected_bytes: the buffer to which this function will populate the read
59 //                    result from |ssl|.
60 // unprotected_bytes_size: the maximum size of the buffer |unprotected_bytes|.
61 //                         This will be populated with the size of the bytes
62 //                         read from |ssl| if this function returns TSI_OK.
63 //
64 // return: TSI_OK if the write operation succeeds or corresponding TSI errors.
65 tsi_result DoSslRead(SSL* ssl, unsigned char* unprotected_bytes,
66                      size_t* unprotected_bytes_size);
67 
68 // Builds a maximum-size TLS frame if there is enough (|buffer_offset| +
69 // |unprotected_bytes_size| >= |buffers_size|) data. Otherwise it copies the
70 // |unprotected_bytes| into |buffer| and returns TSI_OK.
71 //
72 // unprotected_bytes: pointing to the buffer containing the plaintext to be
73 //                    protected.
74 // buffer_size: the size of |buffer|. If |buffer_offset| equals |buffer_size|,
75 //              then we have enough data to create a TLS frame.
76 // buffer_offset: the offset of |buffer|. The data in |buffer| up to
77 //                |buffer_offset| are valid data. This will be updated whenever
78 //                new data are copied into |buffer|.
79 // buffer: the buffer holding the data that has not been sent for protecting.
80 // ssl: the |SSL| object that protects the data.
81 // network_io: the |BIO| object associated with |ssl|.
82 // unprotected_bytes_size: the size of the unprotected plaintext. This will be
83 //                         populated with the size of data that is consumed by
84 //                         this function. Caller can use this to see the size of
85 //                         unconsumed data in |unprotected_bytes|.
86 // protected_output_frames: the TLS frames built out of the plaintext.
87 // protected_output_frames_size: the size of the TLS frames built.
88 //
89 // return: TSI_OK if either successfully created a TSI frame or copied the
90 //         |unprotected_data| into |buffer|. Returns corresponding TSI errors
91 //         otherwise.
92 tsi_result SslProtectorProtect(const unsigned char* unprotected_bytes,
93                                const size_t buffer_size, size_t& buffer_offset,
94                                unsigned char* buffer, SSL* ssl, BIO* network_io,
95                                std::size_t* unprotected_bytes_size,
96                                unsigned char* protected_output_frames,
97                                size_t* protected_output_frames_size);
98 
99 // Builds a TLS frame out of the remaining plaintext bytes that's left in
100 // buffer. Populates the size of the remianing TLS frame to
101 // |still_pending_size|.
102 //
103 // buffer_size: the size of |buffer|. If |buffer_offset| equals |buffer_size|,
104 //              then we have enough data to create a TLS frame.
105 // buffer_offset: the offset of |buffer|. The data in |buffer| up to
106 //                |buffer_offset| are valid data. This will be updated whenever
107 //                new data are copied into |buffer|.
108 // buffer: the buffer holding the data that has not been sent for protecting.
109 // ssl: the |SSL| object that protects the data.
110 // network_io: the |BIO| object associated with |ssl|.
111 // protected_output_frames: the TLS frames built out of the plaintext.
112 // protected_output_frames_size: the size of the TLS frames built.
113 // still_pending_size: the size of the bytes that remains in |network_io|.
114 //
115 // return: TSI_OK if successfully created a TSI frame. Returns corresponding TSI
116 //         errors otherwise.
117 tsi_result SslProtectorProtectFlush(size_t& buffer_offset,
118                                     unsigned char* buffer, SSL* ssl,
119                                     BIO* network_io,
120                                     unsigned char* protected_output_frames,
121                                     size_t* protected_output_frames_size,
122                                     size_t* still_pending_size);
123 
124 // Extracts the plaintext from a TLS frame.
125 //
126 // protected_frames_bytes: the TLS frame to extract plaintext from.
127 // ssl: the |SSL| object that protects the data.
128 // network_io: the |BIO| object associated with |ssl|.
129 // unprotected_bytes_size: the size of the unprotected plaintext. This will be
130 //                         populated with the size of data that is consumed by
131 //                         this function. Caller can use this to see the size of
132 //                         unconsumed data in |unprotected_bytes|.
133 // protected_output_frames: the TLS frames built out of the plaintext.
134 // protected_output_frames_size: the size of the TLS frames built.
135 //
136 // return: TSI_OK if either successfully created a TSI frame or copied the
137 //         |unprotected_data| into |buffer|. Returns corresponding TSI errors
138 //         otherwise.
139 tsi_result SslProtectorUnprotect(const unsigned char* protected_frames_bytes,
140                                  SSL* ssl, BIO* network_io,
141                                  size_t* protected_frames_bytes_size,
142                                  unsigned char* unprotected_bytes,
143                                  size_t* unprotected_bytes_size);
144 
145 }  // namespace grpc_core
146 
147 #endif  // GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_UTILS_H
148