Skip to content
Permalink
Browse files
8273670: Remove weak etypes from default krb5 etype list
Reviewed-by: valeriep, mullan
  • Loading branch information
wangweij committed Oct 5, 2021
1 parent c391e59 commit 03d3c0338437bf10b631881c8910ca85985742f6
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 100 deletions.
@@ -48,17 +48,39 @@
public abstract class EType {

private static final boolean DEBUG = Krb5.DEBUG;
private static boolean allowWeakCrypto;

// etypes supported by JDK, including weak ones
private static int[] supportedETypes;
// common default etypes if not defined in krb5.conf
private static int[] defaultETypes;

static {
initStatic();
}

public static void initStatic() {
boolean allowed = false;

int maxKeyLength = 0;
try {
maxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
} catch (Exception e) {
// should not happen
}

defaultETypes = maxKeyLength >= 256
? new int[] {
EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96,
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
EncryptedData.ETYPE_AES256_CTS_HMAC_SHA384_192,
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA256_128, }
: new int[] {
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA256_128, };

boolean allowWeakCrypto = false;
try {
Config cfg = Config.getInstance();
allowed = cfg.getBooleanObject("libdefaults", "allow_weak_crypto")
allowWeakCrypto = cfg.getBooleanObject("libdefaults", "allow_weak_crypto")
== Boolean.TRUE;
} catch (Exception exc) {
if (DEBUG) {
@@ -67,7 +89,17 @@ public static void initStatic() {
exc.getMessage());
}
}
allowWeakCrypto = allowed;

if (allowWeakCrypto) {
int[] result = Arrays.copyOf(defaultETypes, defaultETypes.length + 4);
result[defaultETypes.length] = EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD;
result[defaultETypes.length + 1] = EncryptedData.ETYPE_ARCFOUR_HMAC;
result[defaultETypes.length + 2] = EncryptedData.ETYPE_DES_CBC_CRC;
result[defaultETypes.length + 3] = EncryptedData.ETYPE_DES_CBC_MD5;
supportedETypes = result;
} else {
supportedETypes = defaultETypes;
}
}

public static EType getInstance (int eTypeConst)
@@ -196,50 +228,9 @@ public byte[] decryptedData(byte[] data) {
return result;
}

// Note: the first 2 entries of BUILTIN_ETYPES and BUILTIN_ETYPES_NOAES256
// should be kept DES-related. They will be removed when allow_weak_crypto
// is set to false.

private static final int[] BUILTIN_ETYPES = new int[] {
EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96,
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
EncryptedData.ETYPE_AES256_CTS_HMAC_SHA384_192,
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA256_128,
EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD,
EncryptedData.ETYPE_ARCFOUR_HMAC,
EncryptedData.ETYPE_DES_CBC_CRC,
EncryptedData.ETYPE_DES_CBC_MD5,
};

private static final int[] BUILTIN_ETYPES_NOAES256 = new int[] {
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
EncryptedData.ETYPE_AES128_CTS_HMAC_SHA256_128,
EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD,
EncryptedData.ETYPE_ARCFOUR_HMAC,
EncryptedData.ETYPE_DES_CBC_CRC,
EncryptedData.ETYPE_DES_CBC_MD5,
};


// used in Config
public static int[] getBuiltInDefaults() {
int allowed = 0;
try {
allowed = Cipher.getMaxAllowedKeyLength("AES");
} catch (Exception e) {
// should not happen
}
int[] result;
if (allowed < 256) {
result = BUILTIN_ETYPES_NOAES256;
} else {
result = BUILTIN_ETYPES;
}
if (!allowWeakCrypto) {
// The last 4 etypes are now weak ones
return Arrays.copyOfRange(result, 0, result.length - 4);
}
return result;
return defaultETypes.clone();
}

/**
@@ -312,8 +303,7 @@ public static boolean isSupported(int eTypeConst, int[] config) {
}

public static boolean isSupported(int eTypeConst) {
int[] enabledETypes = getBuiltInDefaults();
return isSupported(eTypeConst, enabledETypes);
return isSupported(eTypeConst, supportedETypes);
}

/**
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@@ -47,7 +47,8 @@ public static void main(String[] args) throws Exception {

KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
"default_keytab_name = " + OneKDC.KTAB,
"allow_weak_crypto = true");
"allow_weak_crypto = true",
"permitted_enctypes = aes256-cts arcfour-hmac des-cbc-crc des-cbc-md5");
Config.refresh();

// Rewrite to include DES keys
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, 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
@@ -72,11 +72,8 @@ public OneKDC(String etype) throws Exception {

String extraConfig = "";
if (etype != null) {
extraConfig += "default_tkt_enctypes=" + etype
+ "\ndefault_tgs_enctypes=" + etype;
if (etype.startsWith("des")) {
extraConfig += "\nallow_weak_crypto = true";
}
extraConfig += "permitted_enctypes=" + etype
+ "\nallow_weak_crypto = true";
}
KDC.saveConfig(KRB5_CONF, this,
"forwardable = true",
@@ -50,7 +50,8 @@ public static void main(String[] args) throws Exception {
kdc.addPrincipal(OneKDC.USER, OneKDC.PASS);
kdc.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
"allow_weak_crypto = true");
"allow_weak_crypto = true",
"permitted_enctypes = aes256-cts arcfour-hmac");
System.setProperty("java.security.krb5.conf", OneKDC.KRB5_CONF);
Config.refresh();

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, 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
@@ -48,8 +48,8 @@ public static void main(String[] args) throws Exception {
check("e", null);
check("f", null);

if (!Arrays.stream(EType.getBuiltInDefaults())
.anyMatch(n -> n < 4)) {
if (!Arrays.stream(EType.getDefaults("default_tkt_enctypes"))
.anyMatch(n -> n == 23)) {
throw new Exception();
}
}
@@ -4,4 +4,5 @@ b = FALSE
c = YES
d = no
e = nothing
default_tkt_enctypes = rc4-hmac
allow_weak_crypto = yes
@@ -22,61 +22,83 @@
*/
/*
* @test
* @bug 6844909 8012679 8139348
* @bug 6844909 8012679 8139348 8273670
* @modules java.security.jgss/sun.security.krb5
* java.security.jgss/sun.security.krb5.internal.crypto
* @library /test/lib
* @run main/othervm WeakCrypto
* @run main/othervm WeakCrypto true
* @run main/othervm WeakCrypto false
* @summary support allow_weak_crypto in krb5.conf
*/

import java.lang.Exception;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

import jdk.test.lib.Asserts;
import sun.security.krb5.Config;
import sun.security.krb5.EncryptionKey;
import sun.security.krb5.internal.crypto.EType;
import sun.security.krb5.EncryptedData;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;

public class WeakCrypto {
public static void main(String[] args) throws Exception {

static List<Integer> weakOnes = List.of(
EncryptedData.ETYPE_DES_CBC_CRC,
EncryptedData.ETYPE_DES_CBC_MD5,
EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD,
EncryptedData.ETYPE_ARCFOUR_HMAC
);
System.setProperty("java.security.krb5.conf", "tmp.conf");

public static void main(String[] args) throws Exception {
test(null, null,
18, 17, 20, 19); // the defaults
test(false, null,
18, 17, 20, 19); // the defaults
test(true, null,
18, 17, 20, 19); // the defaults

String conf = "[libdefaults]\n" +
(args.length > 0 ? ("allow_weak_crypto = " + args[0]) : "");
Files.write(Paths.get("krb5.conf"), conf.getBytes());
System.setProperty("java.security.krb5.conf", "krb5.conf");
String strongAndWeak = "aes256-cts aes128-cts aes256-sha2 aes128-sha2" +
" des3-hmac-sha1 arcfour-hmac des-cbc-crc des-cbc-md5";
test(null, strongAndWeak, 18, 17, 20, 19);
test(false, strongAndWeak, 18, 17, 20, 19);
test(true, strongAndWeak, 18, 17, 20, 19, 16, 23, 1, 3);

// expected number of supported weak etypes
int expected = 0;
if (args.length != 0 && args[0].equals("true")) {
expected = weakOnes.size();
}
String anotherOrder = "aes256-cts aes256-sha2 aes128-cts aes128-sha2" +
" des3-hmac-sha1 arcfour-hmac des-cbc-crc des-cbc-md5";
test(null, anotherOrder, 18, 20, 17, 19);
test(false, anotherOrder, 18, 20, 17, 19);
test(true, anotherOrder, 18, 20, 17, 19, 16, 23, 1, 3);

// Ensure EType.getBuiltInDefaults() has the correct etypes
if (Arrays.stream(EType.getBuiltInDefaults())
.filter(weakOnes::contains)
.count() != expected) {
throw new Exception("getBuiltInDefaults fails");
}
String two = "aes256-cts arcfour-hmac";
test(null, two, 18);
test(false, two, 18);
test(true, two, 18, 23);
}

/**
* Writes a krb5.conf and makes sure it's correctly parsed.
*
* @param allowWeak if "allow_weak_crypto = true" should be written
* @param etypes redefined "default_tkt_enctypes"
* @param expected expected etypes
*/
static void test(Boolean allowWeak, String etypes, int... expected) throws Exception {

// Ensure keys generated have the correct etypes
if (Arrays.stream(EncryptionKey.acquireSecretKeys(
"password".toCharArray(), "salt"))
.map(EncryptionKey::getEType)
.filter(weakOnes::contains)
.count() != expected) {
throw new Exception("acquireSecretKeys fails");
String s = "[libdefaults]\n";
if (allowWeak != null) {
s += "allow_weak_crypto = " + allowWeak + "\n";
}
if (etypes != null) {
s += "default_tkt_enctypes = " + etypes;
}
Files.write(Path.of("tmp.conf"), s.getBytes(StandardCharsets.UTF_8));
Config.refresh();

// Check internal config read
int[] config = EType.getDefaults("default_tkt_enctypes");
Asserts.assertTrue(Arrays.equals(config, expected),
"config: " + Arrays.toString(config));

// Check actual etypes used
int[] generated = Arrays.stream(EncryptionKey.acquireSecretKeys(
"password".toCharArray(), "salt"))
.mapToInt(EncryptionKey::getEType)
.toArray();
Asserts.assertTrue(Arrays.equals(generated, expected),
"generated: " + Arrays.toString(generated));
}
}

1 comment on commit 03d3c03

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 03d3c03 Oct 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.