2929import java .util .List ;
3030import java .util .Locale ;
3131import java .util .regex .Pattern ;
32+ import java .nio .charset .StandardCharsets ;
3233import javax .net .ssl .HostnameVerifier ;
3334import javax .net .ssl .SSLException ;
3435import javax .net .ssl .SSLSession ;
3536import javax .security .auth .x500 .X500Principal ;
37+ import com .google .common .base .Utf8 ;
38+ import com .google .common .base .Ascii ;
3639
3740/**
3841 * A HostnameVerifier consistent with <a
@@ -63,6 +66,9 @@ private OkHostnameVerifier() {
6366
6467 @ Override
6568 public boolean verify (String host , SSLSession session ) {
69+ if (!isAscii (host )) {
70+ return false ;
71+ }
6672 try {
6773 Certificate [] certificates = session .getPeerCertificates ();
6874 return verify (host , (X509Certificate ) certificates [0 ]);
@@ -71,7 +77,7 @@ public boolean verify(String host, SSLSession session) {
7177 }
7278 }
7379
74- public boolean verify (String host , X509Certificate certificate ) {
80+ private boolean verify (String host , X509Certificate certificate ) {
7581 return verifyAsIpAddress (host )
7682 ? verifyIpAddress (host , certificate )
7783 : verifyHostName (host , certificate );
@@ -98,7 +104,7 @@ private boolean verifyIpAddress(String ipAddress, X509Certificate certificate) {
98104 * Returns true if {@code certificate} matches {@code hostName}.
99105 */
100106 private boolean verifyHostName (String hostName , X509Certificate certificate ) {
101- hostName = hostName .toLowerCase (Locale . US );
107+ hostName = Ascii .toLowerCase (hostName );
102108 boolean hasDns = false ;
103109 List <String > altNames = getSubjectAltNames (certificate , ALT_DNS_NAME );
104110 for (int i = 0 , size = altNames .size (); i < size ; i ++) {
@@ -198,7 +204,7 @@ private boolean verifyHostName(String hostName, String pattern) {
198204 }
199205 // hostName and pattern are now absolute domain names.
200206
201- pattern = pattern .toLowerCase (Locale . US );
207+ pattern = Ascii .toLowerCase (pattern );
202208 // hostName and pattern are now in lower case -- domain names are case-insensitive.
203209
204210 if (!pattern .contains ("*" )) {
@@ -254,4 +260,13 @@ private boolean verifyHostName(String hostName, String pattern) {
254260 // hostName matches pattern
255261 return true ;
256262 }
263+
264+ /**
265+ * Returns true if {@code input} is an ASCII string.
266+ * @param input the string to check.
267+ */
268+ private static boolean isAscii (String input ) {
269+ // Only ASCII characters are 1 byte in UTF-8.
270+ return Utf8 .encodedLength (input ) == input .length ();
271+ }
257272}
0 commit comments