docs: public void verify(String host, X509Certificate cert, long serverThreadId) throws SSLException {
      if (host == null) {
        return; //no validation if no host (possible for name pipe)
      }
      String lowerCaseHost = host.toLowerCase(Locale.ROOT);
      try {
        //***********************************************************
        // RFC 6125 : check Subject Alternative Name (SAN)
        //***********************************************************
        SubjectAltNames subjectAltNames = getSubjectAltNames(cert);
        if (!subjectAltNames.isEmpty()) {
  
          //***********************************************************
          // Host is IPv4 : Check corresponding entries in subject alternative names
          //***********************************************************
          if (Utils.isIPv4(lowerCaseHost)) {
            for (GeneralName entry : subjectAltNames.getGeneralNames()) {
              if (logger.isTraceEnabled()) {
                logger.trace("Conn={}. IPv4 verification of hostname : type={} value={} to {}",
                    serverThreadId,
                    entry.extension,
                    entry.value,
                    lowerCaseHost);
              }
  
              if (entry.extension == Extension.IP && lowerCaseHost.equals(entry.value)) {
                return;
              }
            }
          } else if (Utils.isIPv6(lowerCaseHost)) {
            //***********************************************************
            // Host is IPv6 : Check corresponding entries in subject alternative names
            //***********************************************************
            String normalisedHost = normaliseAddress(lowerCaseHost);
            for (GeneralName entry : subjectAltNames.getGeneralNames()) {
              if (logger.isTraceEnabled()) {
                logger.trace("Conn={}. IPv6 verification of hostname : type={} value={} to {}",
                    serverThreadId,
                    entry.extension,
                    entry.value,
                    lowerCaseHost);
              }
  
              if (entry.extension == Extension.IP
                  && !Utils.isIPv4(entry.value)
                  && normalisedHost.equals(normaliseAddress(entry.value))) {
                return;
              }
            }
          } else {
            //***********************************************************
            // Host is not IP = DNS : Check corresponding entries in alternative subject names
            //***********************************************************
            for (GeneralName entry : subjectAltNames.getGeneralNames()) {
              if (logger.isTraceEnabled()) {
                logger.trace("Conn={}. DNS verification of hostname : type={} value={} to {}",
                    serverThreadId,
                    entry.extension,
                    entry.value,
                    lowerCaseHost);
              }
  
              if (entry.extension == Extension.DNS
                  && matchDns(lowerCaseHost, entry.value.toLowerCase(Locale.ROOT))) {
                return;
              }
            }
          }
        }
  
        //***********************************************************
        // RFC 2818 : legacy fallback using CN (recommendation is using alt-names)
        //***********************************************************
        X500Principal subjectPrincipal = cert.getSubjectX500Principal();
        String cn = extractCommonName(subjectPrincipal.getName(X500Principal.RFC2253));
  
        if (cn == null) {
          if (subjectAltNames.isEmpty()) {
            throw new SSLException("CN not found in certificate principal \"{}" + subjectPrincipal
                + "\" and certificate doesn't contain SAN");
          } else {
            throw new SSLException("CN not found in certificate principal \"" + subjectPrincipal
                + "\" and " + normalizedHostMsg(lowerCaseHost) + " doesn't correspond to "
                + subjectAltNames.toString());
          }
        }
  
        String normalizedCn = cn.toLowerCase(Locale.ROOT);
        if (logger.isTraceEnabled()) {
          logger.trace("Conn={}. DNS verification of hostname : CN={} to {}", serverThreadId,
              normalizedCn, lowerCaseHost);
        }
        if (!matchDns(lowerCaseHost, normalizedCn)) {
          String errorMsg =
              normalizedHostMsg(lowerCaseHost) + " doesn't correspond to certificate CN \""
                  + normalizedCn + "\"";
          if (!subjectAltNames.isEmpty()) {
            errorMsg += " and " + subjectAltNames.toString();
          }
          throw new SSLException(errorMsg);
        }
  
      } catch (CertificateParsingException cpe) {
        throw new SSLException("certificate parsing error : " + cpe.getMessage());
      }
    }