提交 7e1aff59 编写于 作者: W weijun

8014310: JAAS/Krb5LoginModule using des encytypes failure with NPE after JDK-8012679

Reviewed-by: valeriep
上级 ad63d151
...@@ -761,22 +761,23 @@ public class Config { ...@@ -761,22 +761,23 @@ public class Config {
} }
/** /**
* Returns the default encryption types. * Returns all etypes specified in krb5.conf for the given configName,
* * or all the builtin defaults. This result is always non-empty.
* If no etypes are found, an exception is thrown.
*/ */
public int[] defaultEtype(String enctypes) { public int[] defaultEtype(String configName) throws KrbException {
String default_enctypes; String default_enctypes;
default_enctypes = get("libdefaults", enctypes); default_enctypes = get("libdefaults", configName);
String delim = " ";
StringTokenizer st;
int[] etype; int[] etype;
if (default_enctypes == null) { if (default_enctypes == null) {
if (DEBUG) { if (DEBUG) {
System.out.println("Using builtin default etypes for " + System.out.println("Using builtin default etypes for " +
enctypes); configName);
} }
etype = EType.getBuiltInDefaults(); etype = EType.getBuiltInDefaults();
} else { } else {
String delim = " ";
StringTokenizer st;
for (int j = 0; j < default_enctypes.length(); j++) { for (int j = 0; j < default_enctypes.length(); j++) {
if (default_enctypes.substring(j, j + 1).equals(",")) { if (default_enctypes.substring(j, j + 1).equals(",")) {
// only two delimiters are allowed to use // only two delimiters are allowed to use
...@@ -791,17 +792,13 @@ public class Config { ...@@ -791,17 +792,13 @@ public class Config {
int type; int type;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
type = Config.getType(st.nextToken()); type = Config.getType(st.nextToken());
if ((type != -1) && if (type != -1 && EType.isSupported(type)) {
(EType.isSupported(type))) {
ls.add(type); ls.add(type);
} }
} }
if (ls.isEmpty()) { if (ls.isEmpty()) {
if (DEBUG) { throw new KrbException("no supported default etypes for "
System.out.println( + configName);
"no supported default etypes for " + enctypes);
}
return null;
} else { } else {
etype = new int[ls.size()]; etype = new int[ls.size()];
for (int i = 0; i < etype.length; i++) { for (int i = 0; i < etype.length; i++) {
...@@ -811,7 +808,7 @@ public class Config { ...@@ -811,7 +808,7 @@ public class Config {
} }
if (DEBUG) { if (DEBUG) {
System.out.print("default etypes for " + enctypes + ":"); System.out.print("default etypes for " + configName + ":");
for (int i = 0; i < etype.length; i++) { for (int i = 0; i < etype.length; i++) {
System.out.print(" " + etype[i]); System.out.print(" " + etype[i]);
} }
......
...@@ -97,36 +97,6 @@ public class EncryptionKey ...@@ -97,36 +97,6 @@ public class EncryptionKey
return new EncryptionKey(keyValue, keyType, kvno); return new EncryptionKey(keyValue, keyType, kvno);
} }
/**
* Obtains the latest version of the secret key of
* the principal from a keytab.
*
* @param princ the principal whose secret key is desired
* @param keytab the path to the keytab file. A value of null
* will be accepted to indicate that the default path should be
* searched.
* @returns the secret key or null if none was found.
*/
/*
// Replaced by acquireSecretKeys
public static EncryptionKey acquireSecretKey(PrincipalName princ,
String keytab)
throws KrbException, IOException {
if (princ == null) {
throw new IllegalArgumentException(
"Cannot have null pricipal name to look in keytab.");
}
KeyTab ktab = KeyTab.getInstance(keytab);
if (ktab == null)
return null;
return ktab.readServiceKey(princ);
}
*/
/** /**
* Obtains all versions of the secret key of the principal from a * Obtains all versions of the secret key of the principal from a
* keytab. * keytab.
...@@ -208,9 +178,6 @@ public class EncryptionKey ...@@ -208,9 +178,6 @@ public class EncryptionKey
String salt) throws KrbException { String salt) throws KrbException {
int[] etypes = EType.getDefaults("default_tkt_enctypes"); int[] etypes = EType.getDefaults("default_tkt_enctypes");
if (etypes == null) {
etypes = EType.getBuiltInDefaults();
}
EncryptionKey[] encKeys = new EncryptionKey[etypes.length]; EncryptionKey[] encKeys = new EncryptionKey[etypes.length];
for (int i = 0; i < etypes.length; i++) { for (int i = 0; i < etypes.length; i++) {
......
...@@ -490,10 +490,6 @@ public class KrbApReq { ...@@ -490,10 +490,6 @@ public class KrbApReq {
// Check that key is one of the permitted types // Check that key is one of the permitted types
private static void checkPermittedEType(int target) throws KrbException { private static void checkPermittedEType(int target) throws KrbException {
int[] etypes = EType.getDefaults("permitted_enctypes"); int[] etypes = EType.getDefaults("permitted_enctypes");
if (etypes == null) {
throw new KrbException(
"No supported encryption types listed in permitted_enctypes");
}
if (!EType.isSupported(target, etypes)) { if (!EType.isSupported(target, etypes)) {
throw new KrbException(EType.toString(target) + throw new KrbException(EType.toString(target) +
" encryption type not in permitted_enctypes list"); " encryption type not in permitted_enctypes list");
......
...@@ -291,8 +291,7 @@ public class KrbTgsReq { ...@@ -291,8 +291,7 @@ public class KrbTgsReq {
Ticket[] additionalTickets, Ticket[] additionalTickets,
EncryptionKey subKey, EncryptionKey subKey,
PAData extraPA) PAData extraPA)
throws Asn1Exception, IOException, KdcErrException, KrbApErrException, throws IOException, KrbException, UnknownHostException {
UnknownHostException, KrbCryptoException {
KerberosTime req_till = null; KerberosTime req_till = null;
if (till == null) { if (till == null) {
req_till = new KerberosTime(0); req_till = new KerberosTime(0);
...@@ -314,10 +313,6 @@ public class KrbTgsReq { ...@@ -314,10 +313,6 @@ public class KrbTgsReq {
int[] req_eTypes = null; int[] req_eTypes = null;
if (eTypes == null) { if (eTypes == null) {
req_eTypes = EType.getDefaults("default_tgs_enctypes"); req_eTypes = EType.getDefaults("default_tgs_enctypes");
if (req_eTypes == null) {
throw new KrbCryptoException(
"No supported encryption types listed in default_tgs_enctypes");
}
} else { } else {
req_eTypes = eTypes; req_eTypes = eTypes;
} }
......
...@@ -230,11 +230,14 @@ public abstract class EType { ...@@ -230,11 +230,14 @@ public abstract class EType {
/** /**
* Retrieves the default etypes from the configuration file, or * Retrieves the default etypes from the configuration file, or
* if that's not available, return the built-in list of default etypes. * if that's not available, return the built-in list of default etypes.
* This result is always non-empty. If no etypes are found,
* an exception is thrown.
*/ */
// used in KrbAsReq, KeyTab public static int[] getDefaults(String configName)
public static int[] getDefaults(String configName) { throws KrbException {
Config config = null;
try { try {
return Config.getInstance().defaultEtype(configName); config = Config.getInstance();
} catch (KrbException exc) { } catch (KrbException exc) {
if (DEBUG) { if (DEBUG) {
System.out.println("Exception while getting " + System.out.println("Exception while getting " +
...@@ -243,6 +246,7 @@ public abstract class EType { ...@@ -243,6 +246,7 @@ public abstract class EType {
} }
return getBuiltInDefaults(); return getBuiltInDefaults();
} }
return config.defaultEtype(configName);
} }
/** /**
...@@ -254,12 +258,8 @@ public abstract class EType { ...@@ -254,12 +258,8 @@ public abstract class EType {
* we have keys. * we have keys.
*/ */
public static int[] getDefaults(String configName, EncryptionKey[] keys) public static int[] getDefaults(String configName, EncryptionKey[] keys)
throws KrbException { throws KrbException {
int[] answer = getDefaults(configName); int[] answer = getDefaults(configName);
if (answer == null) {
throw new KrbException("No supported encryption types listed in "
+ configName);
}
List<Integer> list = new ArrayList<>(answer.length); List<Integer> list = new ArrayList<>(answer.length);
for (int i = 0; i < answer.length; i++) { for (int i = 0; i < answer.length; i++) {
......
...@@ -279,8 +279,7 @@ public class KeyTab implements KeyTabConstants { ...@@ -279,8 +279,7 @@ public class KeyTab implements KeyTabConstants {
/** /**
* Reads all keys for a service from the keytab file that have * Reads all keys for a service from the keytab file that have
* etypes that have been configured for use. If there are multiple * etypes that have been configured for use.
* keys with same etype, the one with the highest kvno is returned.
* @param service the PrincipalName of the requested service * @param service the PrincipalName of the requested service
* @return an array containing all the service keys, never null * @return an array containing all the service keys, never null
*/ */
...@@ -313,35 +312,12 @@ public class KeyTab implements KeyTabConstants { ...@@ -313,35 +312,12 @@ public class KeyTab implements KeyTabConstants {
size = keys.size(); size = keys.size();
EncryptionKey[] retVal = keys.toArray(new EncryptionKey[size]); EncryptionKey[] retVal = keys.toArray(new EncryptionKey[size]);
// Sort keys according to default_tkt_enctypes // Sort the keys by kvno. Sometimes we must choose a single key (say,
if (DEBUG) { // generate encrypted timestamp in AS-REQ). A key with a higher KVNO
System.out.println("Ordering keys wrt default_tkt_enctypes list"); // sounds like a newer one.
}
final int[] etypes = EType.getDefaults("default_tkt_enctypes");
// Sort the keys, k1 is preferred than k2 if:
// 1. k1's etype appears earlier in etypes than k2's
// 2. If same, k1's KVNO is higher
Arrays.sort(retVal, new Comparator<EncryptionKey>() { Arrays.sort(retVal, new Comparator<EncryptionKey>() {
@Override @Override
public int compare(EncryptionKey o1, EncryptionKey o2) { public int compare(EncryptionKey o1, EncryptionKey o2) {
if (etypes != null) {
int o1EType = o1.getEType();
int o2EType = o2.getEType();
if (o1EType != o2EType) {
for (int i=0; i<etypes.length; i++) {
if (etypes[i] == o1EType) {
return -1;
} else if (etypes[i] == o2EType) {
return 1;
}
}
// Neither o1EType nor o2EType in default_tkt_enctypes,
// therefore won't be used in AS-REQ. We do not care
// about their order, use kvno is OK.
}
}
return o2.getKeyVersionNumber().intValue() return o2.getKeyVersionNumber().intValue()
- o1.getKeyVersionNumber().intValue(); - o1.getKeyVersionNumber().intValue();
} }
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
import org.ietf.jgss.GSSName; import org.ietf.jgss.GSSName;
import sun.security.jgss.GSSUtil; import sun.security.jgss.GSSUtil;
import sun.security.krb5.Config; import sun.security.krb5.Config;
import sun.security.krb5.KrbException;
import sun.security.krb5.internal.crypto.EType; import sun.security.krb5.internal.crypto.EType;
/** /**
...@@ -84,12 +85,10 @@ public class BasicKrb5Test { ...@@ -84,12 +85,10 @@ public class BasicKrb5Test {
// Creates and starts the KDC. This line must be put ahead of etype check // Creates and starts the KDC. This line must be put ahead of etype check
// since the check needs a krb5.conf. // since the check needs a krb5.conf.
new OneKDC(etype).writeJAASConf(); try {
new OneKDC(etype).writeJAASConf();
System.out.println("Testing etype " + etype); } catch (KrbException ke) {
if (etype != null && !EType.isSupported(Config.getType(etype))) { System.out.println("Testing etype " + etype + "Not supported.");
// aes256 is not enabled on all systems
System.out.println("Not supported.");
return; return;
} }
......
...@@ -67,10 +67,19 @@ public class OneKDC extends KDC { ...@@ -67,10 +67,19 @@ public class OneKDC extends KDC {
addPrincipalRandKey("krbtgt/" + REALM); addPrincipalRandKey("krbtgt/" + REALM);
addPrincipalRandKey(SERVER); addPrincipalRandKey(SERVER);
addPrincipalRandKey(BACKEND); addPrincipalRandKey(BACKEND);
String extraConfig = "";
if (etype != null) {
extraConfig += "default_tkt_enctypes=" + etype
+ "\ndefault_tgs_enctypes=" + etype;
if (etype.startsWith("des")) {
extraConfig += "\nallow_weak_crypto = true";
}
}
KDC.saveConfig(KRB5_CONF, this, KDC.saveConfig(KRB5_CONF, this,
"forwardable = true", "forwardable = true",
"default_keytab_name = " + KTAB, "default_keytab_name = " + KTAB,
etype == null ? "" : "default_tkt_enctypes=" + etype + "\ndefault_tgs_enctypes=" + etype); extraConfig);
System.setProperty("java.security.krb5.conf", KRB5_CONF); System.setProperty("java.security.krb5.conf", KRB5_CONF);
// Whatever krb5.conf had been loaded before, we reload ours now. // Whatever krb5.conf had been loaded before, we reload ours now.
Config.refresh(); Config.refresh();
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8014310
* @summary JAAS/Krb5LoginModule using des encytypes failure with NPE after JDK-8012679
* @compile -XDignore.symbol.file OnlyDesLogin.java
* @run main/othervm OnlyDesLogin
*/
import sun.security.krb5.Config;
import javax.security.auth.login.LoginException;
public class OnlyDesLogin {
public static void main(String[] args) throws Exception {
OneKDC kdc = new OneKDC(null);
kdc.writeJAASConf();
KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
"default_tkt_enctypes=des-cbc-md5",
"default_tgs_enctypes=des-cbc-md5",
"permitted_enctypes=des-cbc-md5");
Config.refresh();
try {
Context.fromJAAS("client");
throw new Exception("What?");
} catch (LoginException le) {
// This is OK
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册