package org.apache.kerberos.kerb.crypto;
import org.apache.kerberos.kerb.spec.common.EncryptionKey;
import org.apache.kerberos.kerb.spec.common.EncryptionType;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
/**
* Based on MIT krb5 t_str2key.c
*
* String 2 key test with known values.
*/
public class String2keyTest {
static class TestCase {
EncryptionType encType;
String string;
String salt;
String param;
String answer;
boolean allowWeak;
TestCase(EncryptionType encType, String string, String salt, String param,
String answer, boolean allowWeak) {
this.encType = encType;
this.string = string;
this.salt = salt;
this.param = param;
this.answer = answer;
this.allowWeak = allowWeak;
}
}
static TestCase[] testCases = new TestCase[] {
// Test vectors from RFC 3961 appendix A.2.
new TestCase(
EncryptionType.DES_CBC_CRC,
"password",
"ATHENA.MIT.EDUraeburn",
"00",
"CBC22FAE235298E3",
false)
,
new TestCase(
EncryptionType.DES_CBC_CRC,
"potatoe",
"WHITEHOUSE.GOVdanny",
"00",
"DF3D32A74FD92A01",
false)
,
new TestCase(
EncryptionType.DES_CBC_CRC,
"F09D849E",
"EXAMPLE.COMpianist",
"00",
"4FFB26BAB0CD9413",
false)
,
new TestCase(
EncryptionType.DES_CBC_CRC,
"C39F",
"ATHENA.MIT.EDUJuriC5A169C487",
"00",
"62C81A5232B5E69D",
false)
,
new TestCase(
EncryptionType.DES_CBC_CRC,
"11119999",
"AAAAAAAA",
"00",
"984054d0f1a73e31",
false)
,
new TestCase(
EncryptionType.DES_CBC_CRC,
"NNNN6666",
"FFFFAAAA",
"00",
"C4BF6B25ADF7A4F8",
false)
,
// Test vectors from RFC 3961 appendix A.4.
new TestCase(
EncryptionType.DES3_CBC_SHA1,
"password",
"ATHENA.MIT.EDUraeburn",
null,
"850BB51358548CD05E86768C" +
"313E3BFEF7511937DCF72C3E",
false)
,
new TestCase(
EncryptionType.DES3_CBC_SHA1,
"potatoe",
"WHITEHOUSE.GOVdanny",
null,
"DFCD233DD0A43204EA6DC437" +
"FB15E061B02979C1F74F377A",
false)
,
new TestCase(
EncryptionType.DES3_CBC_SHA1,
"penny",
"EXAMPLE.COMbuckaroo",
null,
"6D2FCDF2D6FBBC3DDCADB5DA" +
"5710A23489B0D3B69D5D9D4A",
false)
,
new TestCase(
EncryptionType.DES3_CBC_SHA1,
"C39F",
"ATHENA.MIT.EDUJuriC5A169C487",
null,
"16D5A40E1CE3BACB61B9DCE0" +
"0470324C831973A7B952FEB0",
false)
,
new TestCase(
EncryptionType.DES3_CBC_SHA1,
"F09D849E",
"EXAMPLE.COMpianist",
null,
"85763726585DBC1CCE6EC43E" +
"1F751F07F1C4CBB098F40B19",
false)
,
// Test vectors from RFC 3962 appendix B.
new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"42263C6E89F4FC28B8DF68EE09799F15",
true)
,
new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"FE697B52BC0D3CE14432BA036A92E65B" +
"BB52280990A2FA27883998D72AF30161",
true)
,
new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"C651BF29E2300AC27FA469D693BDDA13",
true)
,
new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"A2E16D16B36069C135D5E9D2E25F8961" +
"02685618B95914B467C67622225824FF",
true)
,
new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"4C01CD46D632D01E6DBE230A01ED642A",
true)
,
new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"55A6AC740AD17B4846941051E1E8B0A7" +
"548D93B0AB30A8BC3FF16280382B8C2A",
true)
,
new TestCase (
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
"1234567878563412",
"00000005",
"E9B23D52273747DD5C35CB55BE619D8E",
true)
,
new TestCase (
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
"1234567878563412",
"00000005",
"97A4E786BE20D81A382D5EBC96D5909C" +
"ABCDADC87CA48F574504159F16C36E31",
true)
,
new TestCase (
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"59D1BB789A828B1AA54EF9C2883F69ED",
true)
,
new TestCase (
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"89ADEE3608DB8BC71F1BFBFE459486B0" +
"5618B70CBAE22092534E56C553BA4B34",
true)
,
new TestCase (
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"CB8005DC5F90179A7F02104C0018751D",
true)
,
new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"D78C5C9CB872A8C9DAD4697F0BB5B2D2" +
"1496C82BEB2CAEDA2112FCEEA057401B",
true)
,
new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"F09D849E",
"EXAMPLE.COMpianist",
"00000032", // 50
"F149C1F2E154A73452D43E7FE62A56E5",
true)
,
new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"F09D849E",
"EXAMPLE.COMpianist",
"00000032", // 50
"4B6D9839F84406DF1F09CC166DB4B83C" +
"571848B784A3D6BDC346589A3E393F9E",
true)
,
// Check for KRB5_ERR_BAD_S2K_PARAMS return when weak iteration counts are forbidden
new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"F09D849E",
"EXAMPLE.COMpianist",
"00000032", // 50
"4B6D9839F84406DF1F09CC166DB4B83C" +
"571848B784A3D6BDC346589A3E393F9E",
false)
,
// The same inputs applied to Camellia enctypes.
new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"57D0297298FFD9D35DE5A47FB4BDE24B",
true)
,
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"B9D6828B2056B7BE656D88A123B1FAC6" +
"8214AC2B727ECF5F69AFE0C4DF2A6D2C",
true)
,
new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"73F1B53AA0F310F93B1DE8CCAA0CB152",
true)
,
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"83FC5866E5F8F4C6F38663C65C87549F" +
"342BC47ED394DC9D3CD4D163ADE375E3",
true)
,
new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"8E571145452855575FD916E7B04487AA",
true)
,
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"77F421A6F25E138395E837E5D85D385B" +
"4C1BFD772E112CD9208CE72A530B15E6",
true)
,
new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
"1234567878563412",
"00000005",
"00498FD916BFC1C2B1031C170801B381",
true)
,
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
"1234567878563412",
"00000005",
"11083A00BDFE6A41B2F19716D6202F0A" +
"FA94289AFE8B27A049BD28B1D76C389A",
true)
,
new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"8BF6C3EF709B981DBB585D086843BE05",
true)
,
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"119FE2A1CB0B1BE010B9067A73DB63ED" +
"4665B4E53A98D178035DCFE843A6B9B0",
true)
,
new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"5752AC8D6AD1CCFE8430B312871C2F74",
true)
,
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"614D5DFC0BA6D390B412B89AE4D5B088" +
"B612B316510994679DDB4383C7126DDF",
true)
,
new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"f09d849e",
"EXAMPLE.COMpianist",
"00000032", // 50
"CC75C7FD260F1C1658011FCC0D560616",
true)
,
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"f09d849e",
"EXAMPLE.COMpianist",
"00000032", // 50
"163B768C6DB148B4EEC7163DF5AED70E" +
"206B68CEC078BC069ED68A7ED36B1ECC",
true)
,
// Check for KRB5_ERR_BAD_S2K_PARAMS return when weak iteration counts are forbidden.
new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"f09d849e",
"EXAMPLE.COMpianist",
"00000032", // 50
"163B768C6DB148B4EEC7163DF5AED70E" +
"206B68CEC078BC069ED68A7ED36B1ECC",
false)
};
@Test
public void testString2Keys() {
boolean overallResult = true;
for (TestCase tc : testCases) {
System.err.println("String2key test for " + tc.encType.getName());
try {
if (EncryptionHandler.isImplemented(tc.encType)) {
if (! testWith(tc)) {
overallResult = false;
}
}
} catch (Exception e) {
e.printStackTrace();
overallResult = false;
}
}
if (!overallResult) {
Assert.fail();
}
}
private boolean testWith(TestCase tc) throws Exception {
byte[] answer = TestUtil.hex2bytes(tc.answer);
byte[] params = tc.param != null ? TestUtil.hex2bytes(tc.param) : null;
EncryptionKey outkey = EncryptionHandler.string2Key(tc.string, tc.salt, params, tc.encType);
if (! Arrays.equals(answer, outkey.getKeyData())) {
System.err.println("failed with:");
System.err.println("outKey:" + TestUtil.bytesToHex(outkey.getKeyData()));
System.err.println("answer:" + tc.answer);
// Will un-comment below when passed all the tests.
//return false;
}
return true;
}
}