6885204: JSSE should not require Kerberos to be present
authorvinnie
Mon, 05 Oct 2009 23:42:48 +0100
changeset 3957 c8fdb8fad795
parent 3956 2586d23078e4
child 3958 b8acd5ee4f4f
6885204: JSSE should not require Kerberos to be present Reviewed-by: wetmore, alanb
jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java
jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java
jdk/src/share/classes/sun/security/ssl/CipherSuite.java
jdk/src/share/classes/sun/security/ssl/JsseJce.java
--- a/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java	Mon Oct 05 16:45:55 2009 +0100
+++ b/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java	Mon Oct 05 23:42:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -116,7 +116,10 @@
         try {
             String serverName;
             Principal principal = getPeerPrincipal(session);
-            if (principal instanceof KerberosPrincipal) {
+            // X.500 principal or Kerberos principal.
+            // (Use ciphersuite check to determine whether Kerberos is present.)
+            if (session.getCipherSuite().startsWith("TLS_KRB5") &&
+                    principal instanceof KerberosPrincipal) {
                 serverName =
                     HostnameChecker.getServerName((KerberosPrincipal)principal);
             } else {
--- a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Mon Oct 05 16:45:55 2009 +0100
+++ b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Mon Oct 05 23:42:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -461,12 +461,16 @@
         }
 
         Certificate[] peerCerts = null;
+        String cipher = session.getCipherSuite();
         try {
             HostnameChecker checker = HostnameChecker.getInstance(
                                                 HostnameChecker.TYPE_TLS);
 
             Principal principal = getPeerPrincipal();
-            if (principal instanceof KerberosPrincipal) {
+            // X.500 principal or Kerberos principal.
+            // (Use ciphersuite check to determine whether Kerberos is present.)
+            if (cipher.startsWith("TLS_KRB5") &&
+                    principal instanceof KerberosPrincipal) {
                 if (!checker.match(host, (KerberosPrincipal)principal)) {
                     throw new SSLPeerUnverifiedException("Hostname checker" +
                                 " failed for Kerberos");
@@ -499,7 +503,6 @@
             // ignore
         }
 
-        String cipher = session.getCipherSuite();
         if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) {
             return;
         } else if ((hostnameVerifier != null) &&
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java	Mon Oct 05 16:45:55 2009 +0100
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java	Mon Oct 05 23:42:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,7 +74,7 @@
     // Flag indicating if CipherSuite availability can change dynamically.
     // This is the case when we rely on a JCE cipher implementation that
     // may not be available in the installed JCE providers.
-    // It is true because we do not have a Java ECC implementation.
+    // It is true because we might not have an ECC or Kerberos implementation.
     final static boolean DYNAMIC_AVAILABILITY = true;
 
     private final static boolean ALLOW_ECC = Debug.getBooleanProperty
@@ -278,14 +278,22 @@
         KeyExchange(String name, boolean allowed) {
             this.name = name;
             this.allowed = allowed;
-            this.alwaysAvailable = allowed && (name.startsWith("EC") == false);
+            this.alwaysAvailable = allowed &&
+                (!name.startsWith("EC")) && (!name.startsWith("KRB"));
         }
 
         boolean isAvailable() {
             if (alwaysAvailable) {
                 return true;
             }
-            return allowed && JsseJce.isEcAvailable();
+
+            if (name.startsWith("EC")) {
+                return (allowed && JsseJce.isEcAvailable());
+            } else if (name.startsWith("KRB")) {
+                return (allowed && JsseJce.isKerberosAvailable());
+            } else {
+                return allowed;
+            }
         }
 
         public String toString() {
--- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Mon Oct 05 16:45:55 2009 +0100
+++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Mon Oct 05 23:42:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,6 +64,29 @@
     // If yes, then all the EC based crypto we need is available.
     private static volatile Boolean ecAvailable;
 
+    // Flag indicating whether Kerberos crypto is available.
+    // If true, then all the Kerberos-based crypto we need is available.
+    private final static boolean kerberosAvailable;
+    static {
+        boolean temp;
+        try {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                    public Void run() throws Exception {
+                        // Test for Kerberos using the bootstrap class loader
+                        Class.forName("sun.security.krb5.PrincipalName", true,
+                                null);
+                        return null;
+                    }
+                });
+            temp = true;
+
+        } catch (Exception e) {
+            temp = false;
+        }
+        kerberosAvailable = temp;
+    }
+
     static {
         // force FIPS flag initialization
         // Because isFIPS() is synchronized and cryptoProvider is not modified
@@ -187,6 +210,10 @@
         ecAvailable = null;
     }
 
+    static boolean isKerberosAvailable() {
+        return kerberosAvailable;
+    }
+
     /**
      * Return an JCE cipher implementation for the specified algorithm.
      */