LCOV - code coverage report
Current view: top level - source/extensions/transport_sockets/tls - connection_info_impl_base.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 270 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 23 0.0 %

          Line data    Source code
       1             : #include "source/extensions/transport_sockets/tls/connection_info_impl_base.h"
       2             : 
       3             : #include "source/common/common/hex.h"
       4             : 
       5             : #include "absl/strings/str_replace.h"
       6             : #include "openssl/err.h"
       7             : #include "openssl/x509v3.h"
       8             : 
       9             : namespace Envoy {
      10             : namespace Extensions {
      11             : namespace TransportSockets {
      12             : namespace Tls {
      13             : 
      14           0 : bool ConnectionInfoImplBase::peerCertificatePresented() const {
      15           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
      16           0 :   return cert != nullptr;
      17           0 : }
      18             : 
      19           0 : absl::Span<const std::string> ConnectionInfoImplBase::uriSanLocalCertificate() const {
      20           0 :   if (!cached_uri_san_local_certificate_.empty()) {
      21           0 :     return cached_uri_san_local_certificate_;
      22           0 :   }
      23             : 
      24             :   // The cert object is not owned.
      25           0 :   X509* cert = SSL_get_certificate(ssl());
      26           0 :   if (!cert) {
      27           0 :     ASSERT(cached_uri_san_local_certificate_.empty());
      28           0 :     return cached_uri_san_local_certificate_;
      29           0 :   }
      30           0 :   cached_uri_san_local_certificate_ = Utility::getSubjectAltNames(*cert, GEN_URI);
      31           0 :   return cached_uri_san_local_certificate_;
      32           0 : }
      33             : 
      34           0 : absl::Span<const std::string> ConnectionInfoImplBase::dnsSansLocalCertificate() const {
      35           0 :   if (!cached_dns_san_local_certificate_.empty()) {
      36           0 :     return cached_dns_san_local_certificate_;
      37           0 :   }
      38             : 
      39           0 :   X509* cert = SSL_get_certificate(ssl());
      40           0 :   if (!cert) {
      41           0 :     ASSERT(cached_dns_san_local_certificate_.empty());
      42           0 :     return cached_dns_san_local_certificate_;
      43           0 :   }
      44           0 :   cached_dns_san_local_certificate_ = Utility::getSubjectAltNames(*cert, GEN_DNS);
      45           0 :   return cached_dns_san_local_certificate_;
      46           0 : }
      47             : 
      48           0 : absl::Span<const std::string> ConnectionInfoImplBase::ipSansLocalCertificate() const {
      49           0 :   if (!cached_ip_san_local_certificate_.empty()) {
      50           0 :     return cached_ip_san_local_certificate_;
      51           0 :   }
      52             : 
      53           0 :   X509* cert = SSL_get_certificate(ssl());
      54           0 :   if (!cert) {
      55           0 :     ASSERT(cached_ip_san_local_certificate_.empty());
      56           0 :     return cached_ip_san_local_certificate_;
      57           0 :   }
      58           0 :   cached_ip_san_local_certificate_ = Utility::getSubjectAltNames(*cert, GEN_IPADD);
      59           0 :   return cached_ip_san_local_certificate_;
      60           0 : }
      61             : 
      62           0 : const std::string& ConnectionInfoImplBase::sha256PeerCertificateDigest() const {
      63           0 :   if (!cached_sha_256_peer_certificate_digest_.empty()) {
      64           0 :     return cached_sha_256_peer_certificate_digest_;
      65           0 :   }
      66           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
      67           0 :   if (!cert) {
      68           0 :     ASSERT(cached_sha_256_peer_certificate_digest_.empty());
      69           0 :     return cached_sha_256_peer_certificate_digest_;
      70           0 :   }
      71             : 
      72           0 :   std::vector<uint8_t> computed_hash(SHA256_DIGEST_LENGTH);
      73           0 :   unsigned int n;
      74           0 :   X509_digest(cert.get(), EVP_sha256(), computed_hash.data(), &n);
      75           0 :   RELEASE_ASSERT(n == computed_hash.size(), "");
      76           0 :   cached_sha_256_peer_certificate_digest_ = Hex::encode(computed_hash);
      77           0 :   return cached_sha_256_peer_certificate_digest_;
      78           0 : }
      79             : 
      80           0 : const std::string& ConnectionInfoImplBase::sha1PeerCertificateDigest() const {
      81           0 :   if (!cached_sha_1_peer_certificate_digest_.empty()) {
      82           0 :     return cached_sha_1_peer_certificate_digest_;
      83           0 :   }
      84           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
      85           0 :   if (!cert) {
      86           0 :     ASSERT(cached_sha_1_peer_certificate_digest_.empty());
      87           0 :     return cached_sha_1_peer_certificate_digest_;
      88           0 :   }
      89             : 
      90           0 :   std::vector<uint8_t> computed_hash(SHA_DIGEST_LENGTH);
      91           0 :   unsigned int n;
      92           0 :   X509_digest(cert.get(), EVP_sha1(), computed_hash.data(), &n);
      93           0 :   RELEASE_ASSERT(n == computed_hash.size(), "");
      94           0 :   cached_sha_1_peer_certificate_digest_ = Hex::encode(computed_hash);
      95           0 :   return cached_sha_1_peer_certificate_digest_;
      96           0 : }
      97             : 
      98           0 : const std::string& ConnectionInfoImplBase::urlEncodedPemEncodedPeerCertificate() const {
      99           0 :   if (!cached_url_encoded_pem_encoded_peer_certificate_.empty()) {
     100           0 :     return cached_url_encoded_pem_encoded_peer_certificate_;
     101           0 :   }
     102           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     103           0 :   if (!cert) {
     104           0 :     ASSERT(cached_url_encoded_pem_encoded_peer_certificate_.empty());
     105           0 :     return cached_url_encoded_pem_encoded_peer_certificate_;
     106           0 :   }
     107             : 
     108           0 :   bssl::UniquePtr<BIO> buf(BIO_new(BIO_s_mem()));
     109           0 :   RELEASE_ASSERT(buf != nullptr, "");
     110           0 :   RELEASE_ASSERT(PEM_write_bio_X509(buf.get(), cert.get()) == 1, "");
     111           0 :   const uint8_t* output;
     112           0 :   size_t length;
     113           0 :   RELEASE_ASSERT(BIO_mem_contents(buf.get(), &output, &length) == 1, "");
     114           0 :   absl::string_view pem(reinterpret_cast<const char*>(output), length);
     115           0 :   cached_url_encoded_pem_encoded_peer_certificate_ = absl::StrReplaceAll(
     116           0 :       pem, {{"\n", "%0A"}, {" ", "%20"}, {"+", "%2B"}, {"/", "%2F"}, {"=", "%3D"}});
     117           0 :   return cached_url_encoded_pem_encoded_peer_certificate_;
     118           0 : }
     119             : 
     120           0 : const std::string& ConnectionInfoImplBase::urlEncodedPemEncodedPeerCertificateChain() const {
     121           0 :   if (!cached_url_encoded_pem_encoded_peer_cert_chain_.empty()) {
     122           0 :     return cached_url_encoded_pem_encoded_peer_cert_chain_;
     123           0 :   }
     124             : 
     125           0 :   STACK_OF(X509)* cert_chain = SSL_get_peer_full_cert_chain(ssl());
     126           0 :   if (cert_chain == nullptr) {
     127           0 :     ASSERT(cached_url_encoded_pem_encoded_peer_cert_chain_.empty());
     128           0 :     return cached_url_encoded_pem_encoded_peer_cert_chain_;
     129           0 :   }
     130             : 
     131           0 :   for (uint64_t i = 0; i < sk_X509_num(cert_chain); i++) {
     132           0 :     X509* cert = sk_X509_value(cert_chain, i);
     133             : 
     134           0 :     bssl::UniquePtr<BIO> buf(BIO_new(BIO_s_mem()));
     135           0 :     RELEASE_ASSERT(buf != nullptr, "");
     136           0 :     RELEASE_ASSERT(PEM_write_bio_X509(buf.get(), cert) == 1, "");
     137           0 :     const uint8_t* output;
     138           0 :     size_t length;
     139           0 :     RELEASE_ASSERT(BIO_mem_contents(buf.get(), &output, &length) == 1, "");
     140             : 
     141           0 :     absl::string_view pem(reinterpret_cast<const char*>(output), length);
     142           0 :     cached_url_encoded_pem_encoded_peer_cert_chain_ = absl::StrCat(
     143           0 :         cached_url_encoded_pem_encoded_peer_cert_chain_,
     144           0 :         absl::StrReplaceAll(
     145           0 :             pem, {{"\n", "%0A"}, {" ", "%20"}, {"+", "%2B"}, {"/", "%2F"}, {"=", "%3D"}}));
     146           0 :   }
     147           0 :   return cached_url_encoded_pem_encoded_peer_cert_chain_;
     148           0 : }
     149             : 
     150           0 : absl::Span<const std::string> ConnectionInfoImplBase::uriSanPeerCertificate() const {
     151           0 :   if (!cached_uri_san_peer_certificate_.empty()) {
     152           0 :     return cached_uri_san_peer_certificate_;
     153           0 :   }
     154             : 
     155           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     156           0 :   if (!cert) {
     157           0 :     ASSERT(cached_uri_san_peer_certificate_.empty());
     158           0 :     return cached_uri_san_peer_certificate_;
     159           0 :   }
     160           0 :   cached_uri_san_peer_certificate_ = Utility::getSubjectAltNames(*cert, GEN_URI);
     161           0 :   return cached_uri_san_peer_certificate_;
     162           0 : }
     163             : 
     164           0 : absl::Span<const std::string> ConnectionInfoImplBase::dnsSansPeerCertificate() const {
     165           0 :   if (!cached_dns_san_peer_certificate_.empty()) {
     166           0 :     return cached_dns_san_peer_certificate_;
     167           0 :   }
     168             : 
     169           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     170           0 :   if (!cert) {
     171           0 :     ASSERT(cached_dns_san_peer_certificate_.empty());
     172           0 :     return cached_dns_san_peer_certificate_;
     173           0 :   }
     174           0 :   cached_dns_san_peer_certificate_ = Utility::getSubjectAltNames(*cert, GEN_DNS);
     175           0 :   return cached_dns_san_peer_certificate_;
     176           0 : }
     177             : 
     178           0 : absl::Span<const std::string> ConnectionInfoImplBase::ipSansPeerCertificate() const {
     179           0 :   if (!cached_ip_san_peer_certificate_.empty()) {
     180           0 :     return cached_ip_san_peer_certificate_;
     181           0 :   }
     182             : 
     183           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     184           0 :   if (!cert) {
     185           0 :     ASSERT(cached_ip_san_peer_certificate_.empty());
     186           0 :     return cached_ip_san_peer_certificate_;
     187           0 :   }
     188           0 :   cached_ip_san_peer_certificate_ = Utility::getSubjectAltNames(*cert, GEN_IPADD);
     189           0 :   return cached_ip_san_peer_certificate_;
     190           0 : }
     191             : 
     192           0 : uint16_t ConnectionInfoImplBase::ciphersuiteId() const {
     193           0 :   const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
     194           0 :   if (cipher == nullptr) {
     195           0 :     return 0xffff;
     196           0 :   }
     197             : 
     198             :   // From the OpenSSL docs:
     199             :   //    SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to
     200             :   //    get the cipher suite value.
     201           0 :   return static_cast<uint16_t>(SSL_CIPHER_get_id(cipher));
     202           0 : }
     203             : 
     204           0 : std::string ConnectionInfoImplBase::ciphersuiteString() const {
     205           0 :   const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
     206           0 :   if (cipher == nullptr) {
     207           0 :     return {};
     208           0 :   }
     209             : 
     210           0 :   return SSL_CIPHER_get_name(cipher);
     211           0 : }
     212             : 
     213           0 : const std::string& ConnectionInfoImplBase::tlsVersion() const {
     214           0 :   if (!cached_tls_version_.empty()) {
     215           0 :     return cached_tls_version_;
     216           0 :   }
     217           0 :   cached_tls_version_ = SSL_get_version(ssl());
     218           0 :   return cached_tls_version_;
     219           0 : }
     220             : 
     221           0 : const std::string& ConnectionInfoImplBase::alpn() const {
     222           0 :   if (alpn_.empty()) {
     223           0 :     const unsigned char* proto;
     224           0 :     unsigned int proto_len;
     225           0 :     SSL_get0_alpn_selected(ssl(), &proto, &proto_len);
     226           0 :     if (proto != nullptr) {
     227           0 :       alpn_ = std::string(reinterpret_cast<const char*>(proto), proto_len);
     228           0 :     }
     229           0 :   }
     230           0 :   return alpn_;
     231           0 : }
     232             : 
     233           0 : const std::string& ConnectionInfoImplBase::sni() const {
     234           0 :   if (sni_.empty()) {
     235           0 :     const char* proto = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
     236           0 :     if (proto != nullptr) {
     237           0 :       sni_ = std::string(proto);
     238           0 :     }
     239           0 :   }
     240           0 :   return sni_;
     241           0 : }
     242             : 
     243           0 : const std::string& ConnectionInfoImplBase::serialNumberPeerCertificate() const {
     244           0 :   if (!cached_serial_number_peer_certificate_.empty()) {
     245           0 :     return cached_serial_number_peer_certificate_;
     246           0 :   }
     247           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     248           0 :   if (!cert) {
     249           0 :     ASSERT(cached_serial_number_peer_certificate_.empty());
     250           0 :     return cached_serial_number_peer_certificate_;
     251           0 :   }
     252           0 :   cached_serial_number_peer_certificate_ = Utility::getSerialNumberFromCertificate(*cert.get());
     253           0 :   return cached_serial_number_peer_certificate_;
     254           0 : }
     255             : 
     256           0 : const std::string& ConnectionInfoImplBase::issuerPeerCertificate() const {
     257           0 :   if (!cached_issuer_peer_certificate_.empty()) {
     258           0 :     return cached_issuer_peer_certificate_;
     259           0 :   }
     260           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     261           0 :   if (!cert) {
     262           0 :     ASSERT(cached_issuer_peer_certificate_.empty());
     263           0 :     return cached_issuer_peer_certificate_;
     264           0 :   }
     265           0 :   cached_issuer_peer_certificate_ = Utility::getIssuerFromCertificate(*cert);
     266           0 :   return cached_issuer_peer_certificate_;
     267           0 : }
     268             : 
     269           0 : const std::string& ConnectionInfoImplBase::subjectPeerCertificate() const {
     270           0 :   if (!cached_subject_peer_certificate_.empty()) {
     271           0 :     return cached_subject_peer_certificate_;
     272           0 :   }
     273           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     274           0 :   if (!cert) {
     275           0 :     ASSERT(cached_subject_peer_certificate_.empty());
     276           0 :     return cached_subject_peer_certificate_;
     277           0 :   }
     278           0 :   cached_subject_peer_certificate_ = Utility::getSubjectFromCertificate(*cert);
     279           0 :   return cached_subject_peer_certificate_;
     280           0 : }
     281             : 
     282           0 : const std::string& ConnectionInfoImplBase::subjectLocalCertificate() const {
     283           0 :   if (!cached_subject_local_certificate_.empty()) {
     284           0 :     return cached_subject_local_certificate_;
     285           0 :   }
     286           0 :   X509* cert = SSL_get_certificate(ssl());
     287           0 :   if (!cert) {
     288           0 :     ASSERT(cached_subject_local_certificate_.empty());
     289           0 :     return cached_subject_local_certificate_;
     290           0 :   }
     291           0 :   cached_subject_local_certificate_ = Utility::getSubjectFromCertificate(*cert);
     292           0 :   return cached_subject_local_certificate_;
     293           0 : }
     294             : 
     295           0 : absl::optional<SystemTime> ConnectionInfoImplBase::validFromPeerCertificate() const {
     296           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     297           0 :   if (!cert) {
     298           0 :     return absl::nullopt;
     299           0 :   }
     300           0 :   return Utility::getValidFrom(*cert);
     301           0 : }
     302             : 
     303           0 : absl::optional<SystemTime> ConnectionInfoImplBase::expirationPeerCertificate() const {
     304           0 :   bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl()));
     305           0 :   if (!cert) {
     306           0 :     return absl::nullopt;
     307           0 :   }
     308           0 :   return Utility::getExpirationTime(*cert);
     309           0 : }
     310             : 
     311           0 : const std::string& ConnectionInfoImplBase::sessionId() const {
     312           0 :   if (!cached_session_id_.empty()) {
     313           0 :     return cached_session_id_;
     314           0 :   }
     315           0 :   SSL_SESSION* session = SSL_get_session(ssl());
     316           0 :   if (session == nullptr) {
     317           0 :     ASSERT(cached_session_id_.empty());
     318           0 :     return cached_session_id_;
     319           0 :   }
     320             : 
     321           0 :   unsigned int session_id_length = 0;
     322           0 :   const uint8_t* session_id = SSL_SESSION_get_id(session, &session_id_length);
     323           0 :   cached_session_id_ = Hex::encode(session_id, session_id_length);
     324           0 :   return cached_session_id_;
     325           0 : }
     326             : 
     327             : } // namespace Tls
     328             : } // namespace TransportSockets
     329             : } // namespace Extensions
     330             : } // namespace Envoy

Generated by: LCOV version 1.15