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 #include <grpc/support/port_platform.h>
20
21 #include "src/core/tsi/ssl_transport_security_utils.h"
22
23 #include <openssl/crypto.h>
24 #include <openssl/err.h>
25 #include <openssl/ssl.h>
26 #include <openssl/x509v3.h>
27
28 #include "absl/status/status.h"
29 #include "absl/status/statusor.h"
30
31 #include "src/core/tsi/transport_security_interface.h"
32
33 namespace grpc_core {
34
SslErrorString(int error)35 const char* SslErrorString(int error) {
36 switch (error) {
37 case SSL_ERROR_NONE:
38 return "SSL_ERROR_NONE";
39 case SSL_ERROR_ZERO_RETURN:
40 return "SSL_ERROR_ZERO_RETURN";
41 case SSL_ERROR_WANT_READ:
42 return "SSL_ERROR_WANT_READ";
43 case SSL_ERROR_WANT_WRITE:
44 return "SSL_ERROR_WANT_WRITE";
45 case SSL_ERROR_WANT_CONNECT:
46 return "SSL_ERROR_WANT_CONNECT";
47 case SSL_ERROR_WANT_ACCEPT:
48 return "SSL_ERROR_WANT_ACCEPT";
49 case SSL_ERROR_WANT_X509_LOOKUP:
50 return "SSL_ERROR_WANT_X509_LOOKUP";
51 case SSL_ERROR_SYSCALL:
52 return "SSL_ERROR_SYSCALL";
53 case SSL_ERROR_SSL:
54 return "SSL_ERROR_SSL";
55 default:
56 return "Unknown error";
57 }
58 }
59
LogSslErrorStack(void)60 void LogSslErrorStack(void) {
61 unsigned long err;
62 while ((err = ERR_get_error()) != 0) {
63 char details[256];
64 ERR_error_string_n(static_cast<uint32_t>(err), details, sizeof(details));
65 gpr_log(GPR_ERROR, "%s", details);
66 }
67 }
68
DoSslWrite(SSL * ssl,unsigned char * unprotected_bytes,size_t unprotected_bytes_size)69 tsi_result DoSslWrite(SSL* ssl, unsigned char* unprotected_bytes,
70 size_t unprotected_bytes_size) {
71 GPR_ASSERT(unprotected_bytes_size <= INT_MAX);
72 ERR_clear_error();
73 int ssl_write_result = SSL_write(ssl, unprotected_bytes,
74 static_cast<int>(unprotected_bytes_size));
75 if (ssl_write_result < 0) {
76 ssl_write_result = SSL_get_error(ssl, ssl_write_result);
77 if (ssl_write_result == SSL_ERROR_WANT_READ) {
78 gpr_log(GPR_ERROR,
79 "Peer tried to renegotiate SSL connection. This is unsupported.");
80 return TSI_UNIMPLEMENTED;
81 } else {
82 gpr_log(GPR_ERROR, "SSL_write failed with error %s.",
83 SslErrorString(ssl_write_result));
84 return TSI_INTERNAL_ERROR;
85 }
86 }
87 return TSI_OK;
88 }
89
DoSslRead(SSL * ssl,unsigned char * unprotected_bytes,size_t * unprotected_bytes_size)90 tsi_result DoSslRead(SSL* ssl, unsigned char* unprotected_bytes,
91 size_t* unprotected_bytes_size) {
92 GPR_ASSERT(*unprotected_bytes_size <= INT_MAX);
93 ERR_clear_error();
94 int read_from_ssl = SSL_read(ssl, unprotected_bytes,
95 static_cast<int>(*unprotected_bytes_size));
96 if (read_from_ssl <= 0) {
97 read_from_ssl = SSL_get_error(ssl, read_from_ssl);
98 switch (read_from_ssl) {
99 case SSL_ERROR_ZERO_RETURN: // Received a close_notify alert.
100 case SSL_ERROR_WANT_READ: // We need more data to finish the frame.
101 *unprotected_bytes_size = 0;
102 return TSI_OK;
103 case SSL_ERROR_WANT_WRITE:
104 gpr_log(
105 GPR_ERROR,
106 "Peer tried to renegotiate SSL connection. This is unsupported.");
107 return TSI_UNIMPLEMENTED;
108 case SSL_ERROR_SSL:
109 gpr_log(GPR_ERROR, "Corruption detected.");
110 LogSslErrorStack();
111 return TSI_DATA_CORRUPTED;
112 default:
113 gpr_log(GPR_ERROR, "SSL_read failed with error %s.",
114 SslErrorString(read_from_ssl));
115 return TSI_PROTOCOL_FAILURE;
116 }
117 }
118 *unprotected_bytes_size = static_cast<size_t>(read_from_ssl);
119 return TSI_OK;
120 }
121
122 // --- tsi_frame_protector util methods implementation. ---
SslProtectorProtect(const unsigned char * unprotected_bytes,const size_t buffer_size,size_t & buffer_offset,unsigned char * buffer,SSL * ssl,BIO * network_io,size_t * unprotected_bytes_size,unsigned char * protected_output_frames,size_t * protected_output_frames_size)123 tsi_result SslProtectorProtect(const unsigned char* unprotected_bytes,
124 const size_t buffer_size, size_t& buffer_offset,
125 unsigned char* buffer, SSL* ssl, BIO* network_io,
126 size_t* unprotected_bytes_size,
127 unsigned char* protected_output_frames,
128 size_t* protected_output_frames_size) {
129 int read_from_ssl;
130 size_t available;
131 tsi_result result = TSI_OK;
132
133 // First see if we have some pending data in the SSL BIO.
134 int pending_in_ssl = static_cast<int>(BIO_pending(network_io));
135 if (pending_in_ssl > 0) {
136 *unprotected_bytes_size = 0;
137 GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
138 read_from_ssl = BIO_read(network_io, protected_output_frames,
139 static_cast<int>(*protected_output_frames_size));
140 if (read_from_ssl < 0) {
141 gpr_log(GPR_ERROR,
142 "Could not read from BIO even though some data is pending");
143 return TSI_INTERNAL_ERROR;
144 }
145 *protected_output_frames_size = static_cast<size_t>(read_from_ssl);
146 return TSI_OK;
147 }
148
149 // Now see if we can send a complete frame.
150 available = buffer_size - buffer_offset;
151 if (available > *unprotected_bytes_size) {
152 // If we cannot, just copy the data in our internal buffer.
153 memcpy(buffer + buffer_offset, unprotected_bytes, *unprotected_bytes_size);
154 buffer_offset += *unprotected_bytes_size;
155 *protected_output_frames_size = 0;
156 return TSI_OK;
157 }
158
159 // If we can, prepare the buffer, send it to SSL_write and read.
160 memcpy(buffer + buffer_offset, unprotected_bytes, available);
161 result = DoSslWrite(ssl, buffer, buffer_size);
162 if (result != TSI_OK) return result;
163
164 GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
165 read_from_ssl = BIO_read(network_io, protected_output_frames,
166 static_cast<int>(*protected_output_frames_size));
167 if (read_from_ssl < 0) {
168 gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
169 return TSI_INTERNAL_ERROR;
170 }
171 *protected_output_frames_size = static_cast<size_t>(read_from_ssl);
172 *unprotected_bytes_size = available;
173 buffer_offset = 0;
174 return TSI_OK;
175 }
176
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)177 tsi_result SslProtectorProtectFlush(size_t& buffer_offset,
178 unsigned char* buffer, SSL* ssl,
179 BIO* network_io,
180 unsigned char* protected_output_frames,
181 size_t* protected_output_frames_size,
182 size_t* still_pending_size) {
183 tsi_result result = TSI_OK;
184 int read_from_ssl = 0;
185 int pending;
186
187 if (buffer_offset != 0) {
188 result = DoSslWrite(ssl, buffer, buffer_offset);
189 if (result != TSI_OK) return result;
190 buffer_offset = 0;
191 }
192
193 pending = static_cast<int>(BIO_pending(network_io));
194 GPR_ASSERT(pending >= 0);
195 *still_pending_size = static_cast<size_t>(pending);
196 if (*still_pending_size == 0) return TSI_OK;
197
198 GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
199 read_from_ssl = BIO_read(network_io, protected_output_frames,
200 static_cast<int>(*protected_output_frames_size));
201 if (read_from_ssl <= 0) {
202 gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
203 return TSI_INTERNAL_ERROR;
204 }
205 *protected_output_frames_size = static_cast<size_t>(read_from_ssl);
206 pending = static_cast<int>(BIO_pending(network_io));
207 GPR_ASSERT(pending >= 0);
208 *still_pending_size = static_cast<size_t>(pending);
209 return TSI_OK;
210 }
211
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)212 tsi_result SslProtectorUnprotect(const unsigned char* protected_frames_bytes,
213 SSL* ssl, BIO* network_io,
214 size_t* protected_frames_bytes_size,
215 unsigned char* unprotected_bytes,
216 size_t* unprotected_bytes_size) {
217 tsi_result result = TSI_OK;
218 int written_into_ssl = 0;
219 size_t output_bytes_size = *unprotected_bytes_size;
220 size_t output_bytes_offset = 0;
221
222 // First, try to read remaining data from ssl.
223 result = DoSslRead(ssl, unprotected_bytes, unprotected_bytes_size);
224 if (result != TSI_OK) return result;
225 if (*unprotected_bytes_size == output_bytes_size) {
226 // We have read everything we could and cannot process any more input.
227 *protected_frames_bytes_size = 0;
228 return TSI_OK;
229 }
230 output_bytes_offset = *unprotected_bytes_size;
231 unprotected_bytes += output_bytes_offset;
232 *unprotected_bytes_size = output_bytes_size - output_bytes_offset;
233
234 // Then, try to write some data to ssl.
235 GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX);
236 written_into_ssl = BIO_write(network_io, protected_frames_bytes,
237 static_cast<int>(*protected_frames_bytes_size));
238 if (written_into_ssl < 0) {
239 gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d",
240 written_into_ssl);
241 return TSI_INTERNAL_ERROR;
242 }
243 *protected_frames_bytes_size = static_cast<size_t>(written_into_ssl);
244
245 // Now try to read some data again.
246 result = DoSslRead(ssl, unprotected_bytes, unprotected_bytes_size);
247 if (result == TSI_OK) {
248 // Don't forget to output the total number of bytes read.
249 *unprotected_bytes_size += output_bytes_offset;
250 }
251 return result;
252 }
253
VerifyCrlSignature(X509_CRL * crl,X509 * issuer)254 bool VerifyCrlSignature(X509_CRL* crl, X509* issuer) {
255 if (issuer == nullptr || crl == nullptr) {
256 return false;
257 }
258 EVP_PKEY* ikey = X509_get_pubkey(issuer);
259 if (ikey == nullptr) {
260 // Can't verify signature because we couldn't get the pubkey, fail the
261 // check.
262 gpr_log(GPR_DEBUG, "Could not public key from certificate.");
263 EVP_PKEY_free(ikey);
264 return false;
265 }
266 int ret = X509_CRL_verify(crl, ikey);
267 if (ret < 0) {
268 gpr_log(GPR_DEBUG,
269 "There was an unexpected problem checking the CRL signature.");
270 } else if (ret == 0) {
271 gpr_log(GPR_DEBUG, "CRL failed verification.");
272 }
273 EVP_PKEY_free(ikey);
274 return ret == 1;
275 }
276
VerifyCrlCertIssuerNamesMatch(X509_CRL * crl,X509 * cert)277 bool VerifyCrlCertIssuerNamesMatch(X509_CRL* crl, X509* cert) {
278 if (cert == nullptr || crl == nullptr) {
279 return false;
280 }
281 X509_NAME* cert_issuer_name = X509_get_issuer_name(cert);
282 if (cert == nullptr) {
283 return false;
284 }
285 X509_NAME* crl_issuer_name = X509_CRL_get_issuer(crl);
286 if (crl_issuer_name == nullptr) {
287 return false;
288 }
289 return X509_NAME_cmp(cert_issuer_name, crl_issuer_name) == 0;
290 }
291
HasCrlSignBit(X509 * cert)292 bool HasCrlSignBit(X509* cert) {
293 if (cert == nullptr) {
294 return false;
295 }
296 // X509_get_key_usage was introduced in 1.1.1
297 // A missing key usage extension means all key usages are valid.
298 #if OPENSSL_VERSION_NUMBER < 0x10100000
299 // X509_check_ca sets cert->ex_flags. We dont use the return value, but those
300 // flags being set is important.
301 // https://github.com/openssl/openssl/blob/e818b74be2170fbe957a07b0da4401c2b694b3b8/crypto/x509v3/v3_purp.c#L585
302 X509_check_ca(cert);
303 if (!(cert->ex_flags & EXFLAG_KUSAGE)) {
304 return true;
305 }
306 return (cert->ex_kusage & KU_CRL_SIGN) != 0;
307 #else
308 return (X509_get_key_usage(cert) & KU_CRL_SIGN) != 0;
309 #endif // OPENSSL_VERSION_NUMBER < 0x10100000
310 }
311
IssuerFromCert(X509 * cert)312 absl::StatusOr<std::string> IssuerFromCert(X509* cert) {
313 if (cert == nullptr) {
314 return absl::InvalidArgumentError("cert cannot be null");
315 }
316 X509_NAME* issuer = X509_get_issuer_name(cert);
317 unsigned char* buf = nullptr;
318 int len = i2d_X509_NAME(issuer, &buf);
319 if (len < 0 || buf == nullptr) {
320 return absl::InvalidArgumentError("could not read issuer name from cert");
321 }
322 std::string ret(reinterpret_cast<char const*>(buf), len);
323 OPENSSL_free(buf);
324 return ret;
325 }
326
AkidFromCertificate(X509 * cert)327 absl::StatusOr<std::string> AkidFromCertificate(X509* cert) {
328 if (cert == nullptr) {
329 return absl::InvalidArgumentError("cert cannot be null.");
330 }
331 ASN1_OCTET_STRING* akid = nullptr;
332 int j = X509_get_ext_by_NID(cert, NID_authority_key_identifier, -1);
333 // Can't have multiple occurrences
334 if (j >= 0) {
335 if (X509_get_ext_by_NID(cert, NID_authority_key_identifier, j) != -1) {
336 return absl::InvalidArgumentError("Could not get AKID from certificate.");
337 }
338 akid = X509_EXTENSION_get_data(X509_get_ext(cert, j));
339 } else {
340 return absl::InvalidArgumentError("Could not get AKID from certificate.");
341 }
342 unsigned char* buf = nullptr;
343 int len = i2d_ASN1_OCTET_STRING(akid, &buf);
344 if (len <= 0) {
345 return absl::InvalidArgumentError("Could not get AKID from certificate.");
346 }
347 std::string ret(reinterpret_cast<char const*>(buf), len);
348 OPENSSL_free(buf);
349 return ret;
350 }
351
AkidFromCrl(X509_CRL * crl)352 absl::StatusOr<std::string> AkidFromCrl(X509_CRL* crl) {
353 if (crl == nullptr) {
354 return absl::InvalidArgumentError("Could not get AKID from crl.");
355 }
356 ASN1_OCTET_STRING* akid = nullptr;
357 int j = X509_CRL_get_ext_by_NID(crl, NID_authority_key_identifier, -1);
358 // Can't have multiple occurrences
359 if (j >= 0) {
360 if (X509_CRL_get_ext_by_NID(crl, NID_authority_key_identifier, j) != -1) {
361 return absl::InvalidArgumentError("Could not get AKID from crl.");
362 }
363 akid = X509_EXTENSION_get_data(X509_CRL_get_ext(crl, j));
364 } else {
365 return absl::InvalidArgumentError("Could not get AKID from crl.");
366 }
367 unsigned char* buf = nullptr;
368 int len = i2d_ASN1_OCTET_STRING(akid, &buf);
369 if (len <= 0) {
370 return absl::InvalidArgumentError("Could not get AKID from crl.");
371 }
372 std::string ret(reinterpret_cast<char const*>(buf), len);
373 OPENSSL_free(buf);
374 return ret;
375 }
376
377 } // namespace grpc_core
378