blob: abbbbfb7727b275637afd0bc0ea68784c2ed1b02 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.kerby.kerberos.kerb.crypto;
import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
import org.apache.kerby.util.HexUtil;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.junit.Assume.assumeTrue;
/**
* By ref. MIT krb5 t_str2key.c and RFC3961 test vectors
*
* String 2 key test with known values.
*/
public class String2keyTest {
static class TestCase {
EncryptionType encType;
String password;
String salt;
String param;
String answer;
boolean allowWeak;
TestCase(EncryptionType encType, String password, String salt, String param,
String answer, boolean allowWeak) {
this.encType = encType;
this.password = password;
this.salt = salt;
this.param = param;
this.answer = answer;
this.allowWeak = allowWeak;
}
}
/**
* Test vectors from RFC 3961 appendix A.2.
*/
@Test
public void test_DES_CBC_CRC_0() {
performTest(new TestCase(
EncryptionType.DES_CBC_CRC,
"password",
"ATHENA.MIT.EDUraeburn",
"00",
"CBC22FAE235298E3",
false));
}
@Test
public void test_DES_CBC_CRC_1() {
performTest(new TestCase(
EncryptionType.DES_CBC_CRC,
"potatoe",
"WHITEHOUSE.GOVdanny",
"00",
"DF3D32A74FD92A01",
false));
}
@Test
public void test_DES_CBC_CRC_2() {
performTest(new TestCase(
EncryptionType.DES_CBC_CRC,
toUtf8("F09D849E"),
"EXAMPLE.COMpianist",
"00",
"4FFB26BAB0CD9413",
false));
}
@Test
public void test_DES_CBC_CRC_3() {
performTest(new TestCase(
EncryptionType.DES_CBC_CRC,
toUtf8("C39F"),
"ATHENA.MIT.EDUJuri" + toUtf8("C5A169C487"),
"00",
"62C81A5232B5E69D",
false));
}
@Test
public void test_DES_CBC_CRC_4() {
performTest(new TestCase(
EncryptionType.DES_CBC_CRC,
"11119999",
"AAAAAAAA",
"00",
"984054d0f1a73e31",
false));
}
@Test
public void test_DES_CBC_CRC_5() {
performTest(new TestCase(
EncryptionType.DES_CBC_CRC,
"NNNN6666",
"FFFFAAAA",
"00",
"C4BF6B25ADF7A4F8",
false));
}
// Test vectors from RFC 3961 appendix A.4.
@Test
public void test_DES3_CBC_SHA1_0() {
performTest(new TestCase(
EncryptionType.DES3_CBC_SHA1,
"password",
"ATHENA.MIT.EDUraeburn",
null,
"850BB51358548CD05E86768C"
+ "313E3BFEF7511937DCF72C3E",
false));
}
@Test
public void test_DES3_CBC_SHA1_1() {
performTest(new TestCase(
EncryptionType.DES3_CBC_SHA1,
"potatoe",
"WHITEHOUSE.GOVdanny",
null,
"DFCD233DD0A43204EA6DC437"
+ "FB15E061B02979C1F74F377A",
false));
}
@Test
public void test_DES3_CBC_SHA1_2() {
performTest(new TestCase(
EncryptionType.DES3_CBC_SHA1,
"penny",
"EXAMPLE.COMbuckaroo",
null,
"6D2FCDF2D6FBBC3DDCADB5DA"
+ "5710A23489B0D3B69D5D9D4A",
false));
}
@Test
public void test_DES3_CBC_SHA1_3() {
performTest(new TestCase(
EncryptionType.DES3_CBC_SHA1,
toUtf8("C39F"),
"ATHENA.MIT.EDUJuri" + toUtf8("C5A169C487"),
null,
"16D5A40E1CE3BACB61B9DCE0"
+ "0470324C831973A7B952FEB0",
false));
}
@Test
public void test_DES3_CBC_SHA1_4() {
performTest(new TestCase(
EncryptionType.DES3_CBC_SHA1,
toUtf8("F09D849E"),
"EXAMPLE.COMpianist",
null,
"85763726585DBC1CCE6EC43E"
+ "1F751F07F1C4CBB098F40B19",
false));
}
// Test vectors from RFC 3962 appendix B.
@Test
public void test_AES128_CTS_HMAC_SHA1_96_0() {
performTest(new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"42263C6E89F4FC28B8DF68EE09799F15",
true));
}
@Test
public void test_AES128_CTS_HMAC_SHA1_96_1() {
performTest(new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"C651BF29E2300AC27FA469D693BDDA13",
true));
}
@Test
public void test_AES128_CTS_HMAC_SHA1_96_2() {
performTest(new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"4C01CD46D632D01E6DBE230A01ED642A",
true));
}
@Test
public void test_AES128_CTS_HMAC_SHA1_96_3() {
performTest(new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"password",
toUtf8("1234567878563412"),
"00000005",
"E9B23D52273747DD5C35CB55BE619D8E",
true));
}
@Test
public void test_AES128_CTS_HMAC_SHA1_96_4() {
performTest(new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"CB8005DC5F90179A7F02104C0018751D",
true));
}
@Test
public void test_AES128_CTS_HMAC_SHA1_96_5() {
performTest(new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
toUtf8("F09D849E"),
"EXAMPLE.COMpianist",
"00000032", // 50
"F149C1F2E154A73452D43E7FE62A56E5",
true));
}
@Test
public void test_AES128_CTS_HMAC_SHA1_96_6() {
performTest(new TestCase(
EncryptionType.AES128_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"59D1BB789A828B1AA54EF9C2883F69ED",
true));
}
@Test
public void test_AES256_CTS_HMAC_SHA1_96_0() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"FE697B52BC0D3CE14432BA036A92E65B"
+ "BB52280990A2FA27883998D72AF30161",
true));
}
@Test
public void test_AES256_CTS_HMAC_SHA1_96_1() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"A2E16D16B36069C135D5E9D2E25F8961"
+ "02685618B95914B467C67622225824FF",
true));
}
@Test
public void test_AES256_CTS_HMAC_SHA1_96_2() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"55A6AC740AD17B4846941051E1E8B0A7"
+ "548D93B0AB30A8BC3FF16280382B8C2A",
true));
}
@Test
public void test_AES256_CTS_HMAC_SHA1_96_3() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"password",
toUtf8("1234567878563412"),
"00000005",
"97A4E786BE20D81A382D5EBC96D5909C"
+ "ABCDADC87CA48F574504159F16C36E31",
true));
}
@Test
public void test_AES256_CTS_HMAC_SHA1_96_4() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"89ADEE3608DB8BC71F1BFBFE459486B0"
+ "5618B70CBAE22092534E56C553BA4B34",
true));
}
@Test
public void test_AES256_CTS_HMAC_SHA1_96_5() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"D78C5C9CB872A8C9DAD4697F0BB5B2D2"
+ "1496C82BEB2CAEDA2112FCEEA057401B",
true));
}
@Test
public void test_AES256_CTS_HMAC_SHA1_96_6() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
toUtf8("F09D849E"),
"EXAMPLE.COMpianist",
"00000032", // 50
"4B6D9839F84406DF1F09CC166DB4B83C"
+ "571848B784A3D6BDC346589A3E393F9E",
true));
}
// Check for KRB5_ERR_BAD_S2K_PARAMS return when weak iteration counts are forbidden
@Test
public void test_AES256_CTS_HMAC_SHA1_96_7() {
assumeTrue(EncryptionHandler.isAES256Enabled());
performTest(new TestCase(
EncryptionType.AES256_CTS_HMAC_SHA1_96,
toUtf8("F09D849E"),
"EXAMPLE.COMpianist",
"00000032", // 50
"4B6D9839F84406DF1F09CC166DB4B83C"
+ "571848B784A3D6BDC346589A3E393F9E",
false));
}
// The same inputs applied to Camellia enctypes.
@Test
public void test_CAMELLIA128_CTS_CMAC_0() {
performTest(new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"57D0297298FFD9D35DE5A47FB4BDE24B",
true));
}
@Test
public void test_CAMELLIA128_CTS_CMAC_1() {
performTest(new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"73F1B53AA0F310F93B1DE8CCAA0CB152",
true));
}
@Test
public void test_CAMELLIA128_CTS_CMAC_2() {
performTest(new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"8E571145452855575FD916E7B04487AA",
true));
}
@Test
public void test_CAMELLIA128_CTS_CMAC_3() {
performTest(new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"password",
toUtf8("1234567878563412"),
"00000005",
"00498FD916BFC1C2B1031C170801B381",
true));
}
@Test
public void test_CAMELLIA128_CTS_CMAC_4() {
performTest(new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"8BF6C3EF709B981DBB585D086843BE05",
true));
}
@Test
public void test_CAMELLIA128_CTS_CMAC_5() {
performTest(new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"5752AC8D6AD1CCFE8430B312871C2F74",
true));
}
@Test
public void test_CAMELLIA128_CTS_CMAC_6() {
performTest(new TestCase(
EncryptionType.CAMELLIA128_CTS_CMAC,
toUtf8("f09d849e"),
"EXAMPLE.COMpianist",
"00000032", // 50
"CC75C7FD260F1C1658011FCC0D560616",
true));
}
@Test
public void test_CAMELLIA256_CTS_CMAC_1() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000001",
"B9D6828B2056B7BE656D88A123B1FAC6"
+ "8214AC2B727ECF5F69AFE0C4DF2A6D2C",
true));
}
@Test
public void test_CAMELLIA256_CTS_CMAC_2() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"00000002",
"83FC5866E5F8F4C6F38663C65C87549F"
+ "342BC47ED394DC9D3CD4D163ADE375E3",
true));
}
@Test
public void test_CAMELLIA256_CTS_CMAC_3() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
"ATHENA.MIT.EDUraeburn",
"000004B0", // 1200
"77F421A6F25E138395E837E5D85D385B"
+ "4C1BFD772E112CD9208CE72A530B15E6",
true));
}
@Test
public void test_CAMELLIA256_CTS_CMAC_4() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"password",
toUtf8("1234567878563412"),
"00000005",
"11083A00BDFE6A41B2F19716D6202F0A"
+ "FA94289AFE8B27A049BD28B1D76C389A",
true));
}
@Test
public void test_CAMELLIA256_CTS_CMAC_5() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase equals block size",
"000004B0", // 1200
"119FE2A1CB0B1BE010B9067A73DB63ED"
+ "4665B4E53A98D178035DCFE843A6B9B0",
true));
}
@Test
public void test_CAMELLIA256_CTS_CMAC_6() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pass phrase exceeds block size",
"000004B0", // 1200
"614D5DFC0BA6D390B412B89AE4D5B088"
+ "B612B316510994679DDB4383C7126DDF",
true));
}
@Test
public void test_CAMELLIA256_CTS_CMAC_7() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
toUtf8("f09d849e"),
"EXAMPLE.COMpianist",
"00000032", // 50
"163B768C6DB148B4EEC7163DF5AED70E"
+ "206B68CEC078BC069ED68A7ED36B1ECC",
true));
}
// Check for KRB5_ERR_BAD_S2K_PARAMS return when weak iteration counts are forbidden.
@Test
public void test_CAMELLIA256_CTS_CMAC_8() {
performTest(new TestCase(
EncryptionType.CAMELLIA256_CTS_CMAC,
toUtf8("f09d849e"),
"EXAMPLE.COMpianist",
"00000032", // 50
"163B768C6DB148B4EEC7163DF5AED70E"
+ "206B68CEC078BC069ED68A7ED36B1ECC",
false));
}
/**
* Convert hex string into password
*/
private static String toUtf8(String string) {
return new String(HexUtil.hex2bytes(string), StandardCharsets.UTF_8); // Per spec
}
/**
* Perform all the checks for a testcase
*/
private void performTest(TestCase testCase) {
//assertThat(EncryptionHandler.isImplemented(testCase.encType)).isTrue();
if (!EncryptionHandler.isImplemented(testCase.encType)) {
System.err.println("Not implemented yet: " + testCase.encType.getDisplayName());
return;
}
try {
assertThat(testWith(testCase)).isTrue();
} catch (Exception e) {
fail(e.getMessage());
}
}
/**
* Do the actual test work
*/
private boolean testWith(TestCase tc) throws Exception {
byte[] answer = HexUtil.hex2bytes(tc.answer);
byte[] params = tc.param != null ? HexUtil.hex2bytes(tc.param) : null;
EncryptionKey outkey = EncryptionHandler.string2Key(tc.password, tc.salt, params, tc.encType);
if (!Arrays.equals(answer, outkey.getKeyData())) {
System.err.println("failed with:" + tc.salt);
System.err.println("outKey:" + HexUtil.bytesToHex(outkey.getKeyData()));
System.err.println("answer:" + tc.answer);
return false;
}
return true;
}
}