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/grpc_security_constants.h> 23 #include <grpc/support/port_platform.h> 24 #include <openssl/evp.h> 25 #include <openssl/x509.h> 26 27 #include "absl/status/status.h" 28 #include "absl/status/statusor.h" 29 #include "absl/strings/string_view.h" 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 remaining 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 // Verifies that `crl` was signed by `issuer. 146 // return: true if valid, false otherwise. 147 bool VerifyCrlSignature(X509_CRL* crl, X509* issuer); 148 149 // Verifies the CRL issuer and certificate issuer name match. 150 // return: true if equal, false if not. 151 bool VerifyCrlCertIssuerNamesMatch(X509_CRL* crl, X509* cert); 152 153 // Verifies the certificate in question has the cRLSign bit present. 154 // return: true if cRLSign bit is present, false otherwise. 155 bool HasCrlSignBit(X509* cert); 156 157 // Gets a stable representation of the issuer name from an X509 certificate. 158 // return: a std::string of the DER encoding of the X509_NAME issuer name. 159 absl::StatusOr<std::string> IssuerFromCert(X509* cert); 160 161 // Gets a stable representation of the authority key identifier from an X509 162 // certificate. 163 // return: a std::string of the DER encoding of the AKID or a status on failure. 164 absl::StatusOr<std::string> AkidFromCertificate(X509* cert); 165 166 // Gets a stable representation of the authority key identifier from an X509 167 // crl. 168 // return: a std::string of the DER encoding of the AKID or a status on failure. 169 absl::StatusOr<std::string> AkidFromCrl(X509_CRL* crl); 170 171 // Returns a vector of X509 instances parsed from the given PEM-encoded 172 // certificate chain. Caller takes ownership of the X509 pointers in the output 173 // vector. 174 absl::StatusOr<std::vector<X509*>> ParsePemCertificateChain( 175 absl::string_view cert_chain_pem); 176 177 // Returns an EVP_PKEY instance parsed from the non-empty PEM private key block 178 // in private_key_pem. Caller takes ownership of the EVP_PKEY pointer. 179 absl::StatusOr<EVP_PKEY*> ParsePemPrivateKey(absl::string_view private_key_pem); 180 } // namespace grpc_core 181 182 #endif // GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_UTILS_H 183