@@ -1403,70 +1403,63 @@ private String parseCommonName(String distinguishedName) {
14031403 private boolean validateServerName (String nameInCert ) {
14041404 // Failed to get the common name from DN or empty CN
14051405 if (null == nameInCert ) {
1406- if (logger .isLoggable (Level .FINER ))
1406+ if (logger .isLoggable (Level .FINER )) {
14071407 logger .finer (logContext + " Failed to parse the name from the certificate or name is empty." );
1408+ }
14081409 return false ;
14091410 }
1410-
1411- int wildcardIndex = nameInCert .indexOf ("*" );
1412-
1413- // Respect wildcard. If wildcardIndex is larger than -1, then we have a wildcard.
1414- if (wildcardIndex >= 0 ) {
1415- // We do not allow wildcards to exist past the first period.
1416- if (wildcardIndex > nameInCert .indexOf ("." )) {
1417- return false ;
1418- }
1419-
1420- // We do not allow wildcards in IDNs.
1421- if (nameInCert .startsWith ("xn--" )) {
1422- return false ;
1423- }
1424-
1425- /* We do not allow * plus a top-level domain.
1426- * This if statement counts the number of .s in the nameInCert. If it's 1 or less, then reject it.
1427- * This also catches cases where nameInCert is just *
1428- */
1429- if ((nameInCert .length () - nameInCert .replace ("." , "" ).length ()) <= 1 ) {
1430- return false ;
1411+ // We do not allow wildcards in IDNs (xn--).
1412+ if (!nameInCert .startsWith ("xn--" ) && nameInCert .contains ("*" )) {
1413+ int hostIndex = 0 , certIndex = 0 , match = 0 , startIndex = -1 , periodCount = 0 ;
1414+ while (hostIndex < hostName .length ()) {
1415+ if ('.' == hostName .charAt (hostIndex )) {
1416+ periodCount ++;
1417+ }
1418+ if (certIndex < nameInCert .length () && hostName .charAt (hostIndex ) == nameInCert .charAt (certIndex )) {
1419+ hostIndex ++;
1420+ certIndex ++;
1421+ } else if (certIndex < nameInCert .length () && '*' == nameInCert .charAt (certIndex )) {
1422+ startIndex = certIndex ;
1423+ match = hostIndex ;
1424+ certIndex ++;
1425+ } else if (startIndex != -1 && 0 == periodCount ) {
1426+ certIndex = startIndex + 1 ;
1427+ match ++;
1428+ hostIndex = match ;
1429+ } else {
1430+ logFailMessage (nameInCert );
1431+ return false ;
1432+ }
14311433 }
1432-
1433- String certBeforeWildcard = nameInCert .substring (0 , wildcardIndex );
1434- int firstPeriodAfterWildcard = nameInCert .indexOf ("." , wildcardIndex );
1435- String certAfterWildcard ;
1436-
1437- if (firstPeriodAfterWildcard < 0 ) {
1438- /* if we get something like peter.database.c*, then make certAfterWildcard empty so that we accept
1439- * anything after *.
1440- * both startsWith("") and endswith("") will always resolve to "true".
1441- */
1442- certAfterWildcard = "" ;
1434+ if (nameInCert .length () == certIndex && periodCount > 1 ) {
1435+ logSuccessMessage (nameInCert );
1436+ return true ;
14431437 } else {
1444- certAfterWildcard = nameInCert .substring (firstPeriodAfterWildcard );
1445- }
1446-
1447- if (hostName .startsWith (certBeforeWildcard ) && hostName .endsWith (certAfterWildcard )) {
1448- // now, find the string that the wildcard covers. If it contains any periods, reject it.
1449- int wildcardCoveredStringIndexStart = hostName .indexOf (certBeforeWildcard ) + certBeforeWildcard .length ();
1450- int wildcardCoveredStringIndexEnd = hostName .lastIndexOf (certAfterWildcard );
1451- if (!hostName .substring (wildcardCoveredStringIndexStart , wildcardCoveredStringIndexEnd ).contains ("." )) {
1452- return true ;
1453- }
1438+ logFailMessage (nameInCert );
1439+ return false ;
14541440 }
14551441 }
1456-
14571442 // Verify that the name in certificate matches exactly with the host name
14581443 if (!nameInCert .equals (hostName )) {
1459- if (logger .isLoggable (Level .FINER ))
1460- logger .finer (logContext + " The name in certificate " + nameInCert
1461- + " does not match with the server name " + hostName + "." );
1444+ logFailMessage (nameInCert );
14621445 return false ;
14631446 }
1447+ logSuccessMessage (nameInCert );
1448+ return true ;
1449+ }
14641450
1465- if (logger .isLoggable (Level .FINER ))
1451+ private void logFailMessage (String nameInCert ) {
1452+ if (logger .isLoggable (Level .FINER )) {
1453+ logger .finer (logContext + " The name in certificate " + nameInCert
1454+ + " does not match with the server name " + hostName + "." );
1455+ }
1456+ }
1457+
1458+ private void logSuccessMessage (String nameInCert ) {
1459+ if (logger .isLoggable (Level .FINER )) {
14661460 logger .finer (logContext + " The name in certificate:" + nameInCert + " validated against server name "
14671461 + hostName + "." );
1468-
1469- return true ;
1462+ }
14701463 }
14711464
14721465 public void checkClientTrusted (X509Certificate [] chain , String authType ) throws CertificateException {
@@ -4637,8 +4630,8 @@ void writeTVPRows(TVP value) throws SQLServerException {
46374630 SQLServerError databaseError = new SQLServerError ();
46384631 databaseError .setFromTDS (tdsReader );
46394632
4640- SQLServerException .makeFromDatabaseError (con , null , databaseError .getErrorMessage (), databaseError ,
4641- false );
4633+ SQLServerException .makeFromDatabaseError (con , null , databaseError .getErrorMessage (),
4634+ databaseError , false );
46424635 }
46434636
46444637 command .setInterruptsEnabled (true );
0 commit comments