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