You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/01/22 22:47:49 UTC
[10/45] directory-kerberos git commit: DIRKRB-149 New layout
structure with the new name "Apache Kerby"
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd4Enc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd4Enc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd4Enc.java
new file mode 100644
index 0000000..8deee52
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd4Enc.java
@@ -0,0 +1,39 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.crypto.cksum.provider.Md4Provider;
+import org.apache.kerby.kerberos.kerb.spec.common.CheckSumType;
+import org.apache.kerby.kerberos.kerb.spec.common.EncryptionType;
+
+public class DesCbcMd4Enc extends DesCbcEnc {
+
+ public DesCbcMd4Enc() {
+ super(new Md4Provider());
+ }
+
+ public EncryptionType eType() {
+ return EncryptionType.DES_CBC_MD4;
+ }
+
+ public CheckSumType checksumType() {
+ return CheckSumType.RSA_MD4_DES;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd5Enc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd5Enc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd5Enc.java
new file mode 100644
index 0000000..e87955d
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcMd5Enc.java
@@ -0,0 +1,39 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.crypto.cksum.provider.Md5Provider;
+import org.apache.kerby.kerberos.kerb.spec.common.CheckSumType;
+import org.apache.kerby.kerberos.kerb.spec.common.EncryptionType;
+
+public class DesCbcMd5Enc extends DesCbcEnc {
+
+ public DesCbcMd5Enc() {
+ super(new Md5Provider());
+ }
+
+ public EncryptionType eType() {
+ return EncryptionType.DES_CBC_MD5;
+ }
+
+ public CheckSumType checksumType() {
+ return CheckSumType.RSA_MD5_DES;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java
new file mode 100644
index 0000000..47168cb
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java
@@ -0,0 +1,43 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+/**
+ * krb5_enc_provider
+ */
+public interface EncryptProvider {
+
+ public int keyInputSize(); //input size to make key
+ public int keySize(); //output key size
+ public int blockSize(); //crypto block size
+
+ public void encrypt(byte[] key, byte[] cipherState, byte[] data) throws KrbException;
+ public void decrypt(byte[] key, byte[] cipherState, byte[] data) throws KrbException;
+ public void encrypt(byte[] key, byte[] data) throws KrbException;
+ public void decrypt(byte[] key, byte[] data) throws KrbException;
+ public byte[] cbcMac(byte[] key, byte[] iv, byte[] data) throws KrbException;
+ public boolean supportCbcMac();
+
+ public byte[] initState(byte[] key, int keyUsage);
+ public void cleanState();
+ public void cleanKey();
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
new file mode 100644
index 0000000..890c7ca
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
@@ -0,0 +1,53 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.crypto.Cmac;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public abstract class KeKiCmacEnc extends KeKiEnc {
+
+ public KeKiCmacEnc(EncryptProvider encProvider) {
+ super(encProvider, null);
+ }
+
+ @Override
+ public int paddingSize() {
+ return 0;
+ }
+
+ @Override
+ public int checksumSize() {
+ return encProvider().blockSize();
+ }
+
+ @Override
+ protected byte[] makeChecksum(byte[] key, byte[] data, int hashSize)
+ throws KrbException {
+
+ // generate hash
+ byte[] hash = Cmac.cmac(encProvider(), key, data);
+
+ // truncate hash
+ byte[] output = new byte[hashSize];
+ System.arraycopy(hash, 0, output, 0, hashSize);
+ return output;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java
new file mode 100644
index 0000000..9e562c7
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java
@@ -0,0 +1,129 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.KrbErrorCode;
+import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.Confounder;
+import org.apache.kerby.kerberos.kerb.crypto.cksum.HashProvider;
+import org.apache.kerby.kerberos.kerb.crypto.key.DkKeyMaker;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public abstract class KeKiEnc extends AbstractEncTypeHandler {
+
+ public KeKiEnc(EncryptProvider encProvider,
+ HashProvider hashProvider) {
+ super(encProvider, hashProvider);
+ }
+
+ @Override
+ public int paddingSize() {
+ return 0;
+ }
+
+
+ @Override
+ protected void encryptWith(byte[] workBuffer, int[] workLens,
+ byte[] key, byte[] iv, int usage) throws KrbException {
+ int confounderLen = workLens[0];
+ int checksumLen = workLens[1];
+ int inputLen = workLens[2];
+ int paddingLen = workLens[3];
+
+ byte[] Ke, Ki;
+ byte[] constant = new byte[5];
+ constant[0] = (byte) ((usage>>24)&0xff);
+ constant[1] = (byte) ((usage>>16)&0xff);
+ constant[2] = (byte) ((usage>>8)&0xff);
+ constant[3] = (byte) (usage&0xff);
+ constant[4] = (byte) 0xaa;
+ Ke = ((DkKeyMaker) keyMaker()).dk(key, constant);
+ constant[4] = (byte) 0x55;
+ Ki = ((DkKeyMaker) keyMaker()).dk(key, constant);
+
+ /**
+ * Instead of E(Confounder | Checksum | Plaintext | Padding),
+ * E(Confounder | Plaintext | Padding) | Checksum,
+ * so need to adjust the workBuffer arrangement
+ */
+
+ byte[] tmpEnc = new byte[confounderLen + inputLen + paddingLen];
+ // confounder
+ byte[] confounder = Confounder.makeBytes(confounderLen);
+ System.arraycopy(confounder, 0, tmpEnc, 0, confounderLen);
+
+ // data
+ System.arraycopy(workBuffer, confounderLen + checksumLen,
+ tmpEnc, confounderLen, inputLen);
+
+ // padding
+ for (int i = confounderLen + inputLen; i < paddingLen; ++i) {
+ tmpEnc[i] = 0;
+ }
+
+ // checksum & encrypt
+ byte[] checksum;
+ checksum = makeChecksum(Ki, tmpEnc, checksumLen);
+ encProvider().encrypt(Ke, iv, tmpEnc);
+
+ System.arraycopy(tmpEnc, 0, workBuffer, 0, tmpEnc.length);
+ System.arraycopy(checksum, 0, workBuffer, tmpEnc.length, checksum.length);
+ }
+
+ @Override
+ protected byte[] decryptWith(byte[] workBuffer, int[] workLens,
+ byte[] key, byte[] iv, int usage) throws KrbException {
+ int confounderLen = workLens[0];
+ int checksumLen = workLens[1];
+ int dataLen = workLens[2];
+
+ byte[] Ke, Ki;
+ byte[] constant = new byte[5];
+ BytesUtil.int2bytes(usage, constant, 0, true);
+ constant[4] = (byte) 0xaa;
+ Ke = ((DkKeyMaker) keyMaker()).dk(key, constant);
+ constant[4] = (byte) 0x55;
+ Ki = ((DkKeyMaker) keyMaker()).dk(key, constant);
+
+ // decrypt and verify checksum
+
+ byte[] tmpEnc = new byte[confounderLen + dataLen];
+ System.arraycopy(workBuffer, 0,
+ tmpEnc, 0, confounderLen + dataLen);
+ byte[] checksum = new byte[checksumLen];
+ System.arraycopy(workBuffer, confounderLen + dataLen,
+ checksum, 0, checksumLen);
+
+ byte[] newChecksum;
+ encProvider().decrypt(Ke, iv, tmpEnc);
+ newChecksum = makeChecksum(Ki, tmpEnc, checksumLen);
+
+ if (! checksumEqual(checksum, newChecksum)) {
+ throw new KrbException(KrbErrorCode.KRB_AP_ERR_BAD_INTEGRITY);
+ }
+
+ byte[] data = new byte[dataLen];
+ System.arraycopy(tmpEnc, confounderLen, data, 0, dataLen);
+ return data;
+ }
+
+ protected abstract byte[] makeChecksum(byte[] key, byte[] data, int hashSize)
+ throws KrbException;
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
new file mode 100644
index 0000000..70f49c0
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
@@ -0,0 +1,50 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.crypto.Hmac;
+import org.apache.kerby.kerberos.kerb.crypto.cksum.HashProvider;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public abstract class KeKiHmacSha1Enc extends KeKiEnc {
+
+ public KeKiHmacSha1Enc(EncryptProvider encProvider,
+ HashProvider hashProvider) {
+ super(encProvider, hashProvider);
+ }
+
+ @Override
+ public int paddingSize() {
+ return 0;
+ }
+
+ @Override
+ protected byte[] makeChecksum(byte[] key, byte[] data, int hashSize)
+ throws KrbException {
+
+ // generate hash
+ byte[] hash = Hmac.hmac(hashProvider(), key, data);
+
+ // truncate hash
+ byte[] output = new byte[hashSize];
+ System.arraycopy(hash, 0, output, 0, hashSize);
+ return output;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
new file mode 100644
index 0000000..126edaf
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
@@ -0,0 +1,149 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.KrbErrorCode;
+import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.Confounder;
+import org.apache.kerby.kerberos.kerb.crypto.Rc4;
+import org.apache.kerby.kerberos.kerb.crypto.Hmac;
+import org.apache.kerby.kerberos.kerb.crypto.cksum.provider.Md5Provider;
+import org.apache.kerby.kerberos.kerb.crypto.enc.provider.Rc4Provider;
+import org.apache.kerby.kerberos.kerb.crypto.key.Rc4KeyMaker;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.spec.common.CheckSumType;
+import org.apache.kerby.kerberos.kerb.spec.common.EncryptionType;
+
+public class Rc4HmacEnc extends AbstractEncTypeHandler {
+ private boolean exportable;
+
+ public Rc4HmacEnc() {
+ this(false);
+ }
+
+ public Rc4HmacEnc(boolean exportable) {
+ super(new Rc4Provider(), new Md5Provider());
+ keyMaker(new Rc4KeyMaker(this.encProvider()));
+ this.exportable = exportable;
+ }
+
+ public EncryptionType eType() {
+ return EncryptionType.ARCFOUR_HMAC;
+ }
+
+ @Override
+ public int confounderSize() {
+ return 8;
+ }
+
+ @Override
+ public int paddingSize() {
+ return 0;
+ }
+
+ public CheckSumType checksumType() {
+ return CheckSumType.HMAC_MD5_ARCFOUR;
+ }
+
+ protected void encryptWith(byte[] workBuffer, int[] workLens,
+ byte[] key, byte[] iv, int usage) throws KrbException {
+ int confounderLen = workLens[0];
+ int checksumLen = workLens[1];
+ int dataLen = workLens[2];
+
+ /**
+ * Instead of E(Confounder | Checksum | Plaintext | Padding),
+ * Checksum | E(Confounder | Plaintext)
+ */
+
+ // confounder
+ byte[] confounder = Confounder.makeBytes(confounderLen);
+ System.arraycopy(confounder, 0, workBuffer, checksumLen, confounderLen);
+
+ // no padding
+
+ /* checksum and encryption */
+ byte[] usageKey = makeUsageKey(key, usage);
+
+ byte[] checksum = Hmac.hmac(hashProvider(), usageKey, workBuffer,
+ checksumLen, confounderLen + dataLen);
+
+ byte[] encKey = makeEncKey(usageKey, checksum);
+
+ byte[] tmpEnc = new byte[confounderLen + dataLen];
+ System.arraycopy(workBuffer, checksumLen,
+ tmpEnc, 0, confounderLen + dataLen);
+ encProvider().encrypt(encKey, iv, tmpEnc);
+ System.arraycopy(checksum, 0, workBuffer, 0, checksumLen);
+ System.arraycopy(tmpEnc, 0, workBuffer, checksumLen, tmpEnc.length);
+ }
+
+ protected byte[] makeUsageKey(byte[] key, int usage) throws KrbException {
+ byte[] salt = Rc4.getSalt(usage, exportable);
+ byte[] usageKey = Hmac.hmac(hashProvider(), key, salt);
+ return usageKey;
+ }
+
+ protected byte[] makeEncKey(byte[] usageKey, byte[] checksum) throws KrbException {
+ byte[] tmpKey = usageKey;
+
+ if (exportable) {
+ tmpKey = BytesUtil.duplicate(usageKey);
+ for (int i = 0; i < 9; ++i) {
+ tmpKey[i + 7] = (byte) 0xab;
+ }
+ }
+
+ byte[] encKey = Hmac.hmac(hashProvider(), tmpKey, checksum);
+ return encKey;
+ }
+
+ @Override
+ protected byte[] decryptWith(byte[] workBuffer, int[] workLens,
+ byte[] key, byte[] iv, int usage) throws KrbException {
+ int confounderLen = workLens[0];
+ int checksumLen = workLens[1];
+ int dataLen = workLens[2];
+
+ /* checksum and decryption */
+ byte[] usageKey = makeUsageKey(key, usage);
+
+ byte[] checksum = new byte[checksumLen];
+ System.arraycopy(workBuffer, 0, checksum, 0, checksumLen);
+
+ byte[] encKey = makeEncKey(usageKey, checksum);
+
+ byte[] tmpEnc = new byte[confounderLen + dataLen];
+ System.arraycopy(workBuffer, checksumLen,
+ tmpEnc, 0, confounderLen + dataLen);
+ encProvider().decrypt(encKey, iv, tmpEnc);
+
+ byte[] newChecksum = Hmac.hmac(hashProvider(), usageKey, tmpEnc);
+ if (! checksumEqual(checksum, newChecksum)) {
+ throw new KrbException(KrbErrorCode.KRB_AP_ERR_BAD_INTEGRITY);
+ }
+
+ byte[] data = new byte[dataLen];
+ System.arraycopy(tmpEnc, confounderLen,
+ data, 0, dataLen);
+
+ return data;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java
new file mode 100644
index 0000000..42799a3
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java
@@ -0,0 +1,33 @@
+/**
+ * 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.enc;
+
+import org.apache.kerby.kerberos.kerb.spec.common.EncryptionType;
+
+public class Rc4HmacExpEnc extends Rc4HmacEnc {
+
+ public Rc4HmacExpEnc() {
+ super(true);
+ }
+
+ public EncryptionType eType() {
+ return EncryptionType.ARCFOUR_HMAC_EXP;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
new file mode 100644
index 0000000..2fcca14
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
@@ -0,0 +1,99 @@
+/**
+ * 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.enc.provider;
+
+import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public abstract class AbstractEncryptProvider implements EncryptProvider {
+ private int blockSize;
+ private int keyInputSize;
+ private int keySize;
+
+ public AbstractEncryptProvider(int blockSize, int keyInputSize, int keySize) {
+ this.blockSize = blockSize;
+ this.keyInputSize = keyInputSize;
+ this.keySize = keySize;
+ }
+
+ @Override
+ public int keyInputSize() {
+ return keyInputSize;
+ }
+
+ @Override
+ public int keySize() {
+ return keySize;
+ }
+
+ @Override
+ public int blockSize() {
+ return blockSize;
+ }
+
+ @Override
+ public byte[] initState(byte[] key, int keyUsage) {
+ return new byte[0];
+ }
+
+ @Override
+ public void encrypt(byte[] key, byte[] cipherState, byte[] data) throws KrbException {
+ doEncrypt(data, key, cipherState, true);
+ }
+
+ @Override
+ public void decrypt(byte[] key, byte[] cipherState, byte[] data) throws KrbException {
+ doEncrypt(data, key, cipherState, false);
+ }
+
+ @Override
+ public void encrypt(byte[] key, byte[] data) throws KrbException {
+ byte[] cipherState = new byte[blockSize()];
+ encrypt(key, cipherState, data);
+ }
+
+ @Override
+ public void decrypt(byte[] key, byte[] data) throws KrbException {
+ byte[] cipherState = new byte[blockSize()];
+ decrypt(key, cipherState, data);
+ }
+
+ protected abstract void doEncrypt(byte[] data, byte[] key, byte[] cipherState, boolean encrypt) throws KrbException;
+
+ @Override
+ public byte[] cbcMac(byte[] key, byte[] iv, byte[] data) throws KrbException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean supportCbcMac() {
+ return false;
+ }
+
+ @Override
+ public void cleanState() {
+
+ }
+
+ @Override
+ public void cleanKey() {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes128Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes128Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes128Provider.java
new file mode 100644
index 0000000..2e23a99
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes128Provider.java
@@ -0,0 +1,27 @@
+/**
+ * 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.enc.provider;
+
+public class Aes128Provider extends AesProvider {
+
+ public Aes128Provider() {
+ super(16, 16, 16);
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes256Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes256Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes256Provider.java
new file mode 100644
index 0000000..f6eb4d6
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Aes256Provider.java
@@ -0,0 +1,27 @@
+/**
+ * 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.enc.provider;
+
+public class Aes256Provider extends AesProvider {
+
+ public Aes256Provider() {
+ super(16, 32, 32);
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AesProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AesProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AesProvider.java
new file mode 100644
index 0000000..004c30e
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AesProvider.java
@@ -0,0 +1,62 @@
+/**
+ * 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.enc.provider;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.GeneralSecurityException;
+
+public abstract class AesProvider extends AbstractEncryptProvider {
+
+ public AesProvider(int blockSize, int keyInputSize, int keySize) {
+ super(blockSize, keyInputSize, keySize);
+ }
+
+ @Override
+ protected void doEncrypt(byte[] data, byte[] key,
+ byte[] cipherState, boolean encrypt) throws KrbException {
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("AES/CTS/NoPadding");
+ } catch (GeneralSecurityException e) {
+ KrbException ke = new KrbException("JCE provider may not be installed. "
+ + e.getMessage());
+ ke.initCause(e);
+ throw ke;
+ }
+
+ try {
+ SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
+ IvParameterSpec param = new IvParameterSpec(cipherState);
+
+ cipher.init(encrypt ?
+ Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey, param);
+ byte[] output = cipher.doFinal(data);
+ System.arraycopy(output, 0, data, 0, output.length);
+ } catch (GeneralSecurityException e) {
+ KrbException ke = new KrbException(e.getMessage());
+ ke.initCause(e);
+ throw ke;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java
new file mode 100644
index 0000000..e015dc4
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java
@@ -0,0 +1,27 @@
+/**
+ * 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.enc.provider;
+
+public class Camellia128Provider extends CamelliaProvider {
+
+ public Camellia128Provider() {
+ super(16, 16, 16);
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java
new file mode 100644
index 0000000..8b0eeac
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java
@@ -0,0 +1,27 @@
+/**
+ * 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.enc.provider;
+
+public class Camellia256Provider extends CamelliaProvider {
+
+ public Camellia256Provider() {
+ super(16, 32, 32);
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
new file mode 100644
index 0000000..d3b69a6
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
@@ -0,0 +1,58 @@
+/**
+ * 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.enc.provider;
+
+import org.apache.kerby.kerberos.kerb.crypto.Camellia;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public abstract class CamelliaProvider extends AbstractEncryptProvider {
+
+ public CamelliaProvider(int blockSize, int keyInputSize, int keySize) {
+ super(blockSize, keyInputSize, keySize);
+ }
+
+ @Override
+ protected void doEncrypt(byte[] data, byte[] key,
+ byte[] cipherState, boolean encrypt) throws KrbException {
+
+ Camellia cipher = new Camellia();
+ cipher.setKey(encrypt, key);
+ if (encrypt) {
+ cipher.encrypt(data, cipherState);
+ } else {
+ cipher.decrypt(data, cipherState);
+ }
+ }
+
+ @Override
+ public boolean supportCbcMac() {
+ return true;
+ }
+
+ @Override
+ public byte[] cbcMac(byte[] key, byte[] cipherState, byte[] data) {
+ Camellia cipher = new Camellia();
+ cipher.setKey(true, key);
+
+ int blocksNum = data.length / blockSize();
+ cipher.cbcEnc(data, 0, blocksNum, cipherState);
+ return data;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Des3Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Des3Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Des3Provider.java
new file mode 100644
index 0000000..51a2be5
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Des3Provider.java
@@ -0,0 +1,65 @@
+/**
+ * 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.enc.provider;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+import java.security.GeneralSecurityException;
+import java.security.spec.KeySpec;
+
+public class Des3Provider extends AbstractEncryptProvider {
+
+ public Des3Provider() {
+ super(8, 21, 24);
+ }
+
+ @Override
+ protected void doEncrypt(byte[] input, byte[] key,
+ byte[] cipherState, boolean encrypt) throws KrbException {
+
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("DESede/CBC/NoPadding");
+ } catch (GeneralSecurityException e) {
+ throw new KrbException("Failed to init cipher", e);
+ }
+
+ try {
+ IvParameterSpec params = new IvParameterSpec(cipherState);
+ KeySpec skSpec = new DESedeKeySpec(key, 0);
+
+ SecretKeyFactory skf = SecretKeyFactory.getInstance("desede");
+ SecretKey secretKey = skf.generateSecret(skSpec);
+
+ cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey, params);
+
+ byte[] output = cipher.doFinal(input);
+ System.arraycopy(output, 0, input, 0, output.length);
+ } catch (GeneralSecurityException e) {
+ throw new KrbException("Failed to doEncrypt", e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/DesProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/DesProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/DesProvider.java
new file mode 100644
index 0000000..0a03027
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/DesProvider.java
@@ -0,0 +1,98 @@
+/**
+ * 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.enc.provider;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.GeneralSecurityException;
+
+public class DesProvider extends AbstractEncryptProvider {
+
+ public DesProvider() {
+ super(8, 7, 8);
+ }
+
+ @Override
+ protected void doEncrypt(byte[] input, byte[] key,
+ byte[] cipherState, boolean encrypt) throws KrbException {
+
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ } catch (GeneralSecurityException e) {
+ throw new KrbException("Failed to init cipher", e);
+ }
+ IvParameterSpec params = new IvParameterSpec(cipherState);
+ SecretKeySpec skSpec = new SecretKeySpec(key, "DES");
+ try {
+ SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
+ SecretKey sk = (SecretKey) skSpec;
+
+ cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, sk, params);
+
+ byte[] output = cipher.doFinal(input);
+ System.arraycopy(output, 0, input, 0, output.length);
+ } catch (GeneralSecurityException e) {
+ KrbException ke = new KrbException(e.getMessage());
+ ke.initCause(e);
+ throw ke;
+ }
+ }
+
+ @Override
+ public byte[] cbcMac(byte[] key, byte[] cipherState, byte[] data) throws KrbException {
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ } catch (GeneralSecurityException e) {
+ throw new KrbException("Failed to init cipher", e);
+ }
+ IvParameterSpec params = new IvParameterSpec(cipherState);
+ SecretKeySpec skSpec = new SecretKeySpec(key, "DES");
+
+ byte[] output = null;
+ try {
+ SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
+ // SecretKey sk = skf.generateSecret(skSpec);
+ SecretKey sk = (SecretKey) skSpec;
+ cipher.init(Cipher.ENCRYPT_MODE, sk, params);
+ for (int i = 0; i < data.length / 8; i++) {
+ output = cipher.doFinal(data, i * 8, 8);
+ cipher.init(Cipher.ENCRYPT_MODE, sk, (new IvParameterSpec(output)));
+ }
+ }
+ catch (GeneralSecurityException e) {
+ KrbException ke = new KrbException(e.getMessage());
+ ke.initCause(e);
+ throw ke;
+ }
+ return output;
+ }
+
+ @Override
+ public boolean supportCbcMac() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Rc4Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Rc4Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Rc4Provider.java
new file mode 100644
index 0000000..b00cf4f
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/Rc4Provider.java
@@ -0,0 +1,49 @@
+/**
+ * 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.enc.provider;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.GeneralSecurityException;
+
+public class Rc4Provider extends AbstractEncryptProvider {
+
+ public Rc4Provider() {
+ super(1, 16, 16);
+ }
+
+ @Override
+ protected void doEncrypt(byte[] data, byte[] key,
+ byte[] cipherState, boolean encrypt) throws KrbException {
+ try {
+ Cipher cipher = Cipher.getInstance("ARCFOUR");
+ SecretKeySpec secretKey = new SecretKeySpec(key, "ARCFOUR");
+ cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey);
+ byte[] output = cipher.doFinal(data);
+ System.arraycopy(output, 0, data, 0, output.length);
+ } catch (GeneralSecurityException e) {
+ KrbException ke = new KrbException(e.getMessage());
+ ke.initCause(e);
+ throw ke;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java
new file mode 100644
index 0000000..3c2cf9c
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java
@@ -0,0 +1,93 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.io.UnsupportedEncodingException;
+
+public abstract class AbstractKeyMaker implements KeyMaker {
+
+ protected static final byte[] KERBEROS_CONSTANT = "kerberos".getBytes();
+
+ private EncryptProvider encProvider;
+
+ public AbstractKeyMaker(EncryptProvider encProvider) {
+ this.encProvider = encProvider;
+ }
+
+ protected EncryptProvider encProvider() {
+ return encProvider;
+ }
+
+ @Override
+ public byte[] random2Key(byte[] randomBits) throws KrbException {
+ return new byte[0];
+ }
+
+ /**
+ * Visible for test
+ */
+ public static byte[] makePasswdSalt(String password, String salt) {
+ char[] chars = new char[password.length() + salt.length()];
+ System.arraycopy(password.toCharArray(), 0, chars, 0, password.length());
+ System.arraycopy(salt.toCharArray(), 0, chars, password.length(), salt.length());
+
+ try {
+ return new String(chars).getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Character decoding failed", e);
+ }
+ }
+
+ protected static int getIterCount(byte[] param, int defCount) {
+ int iterCount = defCount;
+
+ if (param != null) {
+ if (param.length != 4) {
+ throw new IllegalArgumentException("Invalid param to str2Key");
+ }
+ iterCount = BytesUtil.bytes2int(param, 0, true);
+ }
+
+ return iterCount;
+ }
+
+ protected static byte[] getSaltBytes(String salt, String pepper)
+ throws UnsupportedEncodingException {
+ byte[] saltBytes = salt.getBytes("UTF-8");
+ if (pepper != null && ! pepper.isEmpty()) {
+ byte[] pepperBytes = pepper.getBytes("UTF-8");
+ int len = saltBytes.length;
+ len += 1 + pepperBytes.length;
+ byte[] results = new byte[len];
+ System.arraycopy(pepperBytes, 0, results, 0, pepperBytes.length);
+ results[pepperBytes.length] = (byte) 0;
+ System.arraycopy(saltBytes, 0,
+ results, pepperBytes.length + 1, saltBytes.length);
+
+ return results;
+ } else {
+ return saltBytes;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java
new file mode 100644
index 0000000..8b385da
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java
@@ -0,0 +1,65 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.crypto.Pbkdf;
+import org.apache.kerby.kerberos.kerb.crypto.enc.provider.AesProvider;
+
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+
+public class AesKeyMaker extends DkKeyMaker {
+
+ public AesKeyMaker(AesProvider encProvider) {
+ super(encProvider);
+ }
+
+ @Override
+ public byte[] random2Key(byte[] randomBits) throws KrbException {
+ return randomBits;
+ }
+
+ @Override
+ public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+ int iterCount = getIterCount(param, 4096);
+
+ byte[] saltBytes = null;
+ try {
+ saltBytes = getSaltBytes(salt, null);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ int keySize = encProvider().keySize();
+ byte[] random = new byte[0];
+ try {
+ random = Pbkdf.PBKDF2(string.toCharArray(), saltBytes, iterCount, keySize);
+ } catch (GeneralSecurityException e) {
+ throw new KrbException("PBKDF2 failed", e);
+ }
+
+ byte[] tmpKey = random2Key(random);
+ byte[] result = dk(tmpKey, KERBEROS_CONSTANT);
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
new file mode 100644
index 0000000..4feb7c5
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
@@ -0,0 +1,121 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.Cmac;
+import org.apache.kerby.kerberos.kerb.crypto.Pbkdf;
+import org.apache.kerby.kerberos.kerb.crypto.enc.provider.CamelliaProvider;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+
+public class CamelliaKeyMaker extends DkKeyMaker {
+
+ public CamelliaKeyMaker(CamelliaProvider encProvider) {
+ super(encProvider);
+ }
+
+ @Override
+ public byte[] random2Key(byte[] randomBits) throws KrbException {
+ return randomBits;
+ }
+
+ @Override
+ public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+ int iterCount = getIterCount(param, 32768);
+
+ byte[] saltBytes = null;
+ try {
+ saltBytes = getSaltBytes(salt, getPepper());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ int keySize = encProvider().keySize();
+ byte[] random = new byte[0];
+ try {
+ random = Pbkdf.PBKDF2(string.toCharArray(), saltBytes, iterCount, keySize);
+ } catch (GeneralSecurityException e) {
+ throw new KrbException("PBKDF2 failed", e);
+ }
+
+ byte[] tmpKey = random2Key(random);
+ byte[] result = dk(tmpKey, KERBEROS_CONSTANT);
+
+ return result;
+ }
+
+ private String getPepper() {
+ int keySize = encProvider().keySize();
+ String pepper = keySize == 16 ? "camellia128-cts-cmac" : "camellia256-cts-cmac";
+ return pepper;
+ }
+
+ /*
+ * NIST SP800-108 KDF in feedback mode (section 5.2).
+ */
+ @Override
+ protected byte[] dr(byte[] key, byte[] constant) throws KrbException {
+
+ int blocksize = encProvider().blockSize();
+ int keyInuptSize = encProvider().keyInputSize();
+ byte[] keyBytes = new byte[keyInuptSize];
+ byte[] Ki;
+
+ int len = 0;
+ // K(i-1): the previous block of PRF output, initially all-zeros.
+ len += blocksize;
+ // four-byte big-endian binary string giving the block counter
+ len += 4;
+ // the fixed derived-key input
+ len += constant.length;
+ // 0x00: separator byte
+ len += 1;
+ // four-byte big-endian binary string giving the output length
+ len += 4;
+
+ Ki = new byte[len];
+ System.arraycopy(constant, 0, Ki, blocksize + 4, constant.length);
+ BytesUtil.int2bytes(keyInuptSize * 8, Ki, len - 4, true);
+
+ int i, n = 0;
+ byte[] tmp;
+ for (i = 1, n = 0; n < keyInuptSize; i++) {
+ // Update the block counter
+ BytesUtil.int2bytes(i, Ki, blocksize, true);
+
+ // Compute a CMAC checksum, update Ki with the result
+ tmp = Cmac.cmac(encProvider(), key, Ki);
+ System.arraycopy(tmp, 0, Ki, 0, blocksize);
+
+ if (n + blocksize >= keyInuptSize) {
+ System.arraycopy(Ki, 0, keyBytes, n, keyInuptSize - n);
+ break;
+ }
+
+ System.arraycopy(Ki, 0, keyBytes, n, blocksize);
+ n += blocksize;
+ }
+
+ return keyBytes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java
new file mode 100644
index 0000000..06caeb8
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java
@@ -0,0 +1,79 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.crypto.Des;
+import org.apache.kerby.kerberos.kerb.crypto.Nfold;
+import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
+
+public class Des3KeyMaker extends DkKeyMaker {
+
+ public Des3KeyMaker(EncryptProvider encProvider) {
+ super(encProvider);
+ }
+
+ @Override
+ public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+ byte[] utf8Bytes = makePasswdSalt(string, salt);
+ int keyInputSize = encProvider().keyInputSize();
+ byte[] tmpKey = random2Key(Nfold.nfold(utf8Bytes, keyInputSize));
+ return dk(tmpKey, KERBEROS_CONSTANT);
+ }
+
+ @Override
+ public byte[] random2Key(byte[] randomBits) throws KrbException {
+ if (randomBits.length != encProvider().keyInputSize()) {
+ throw new KrbException("Invalid random bits, not of correct bytes size");
+ }
+ /**
+ * Ref. k5_rand2key_des3 in random_to_key.c in MIT krb5
+ * Take the seven bytes, move them around into the top 7 bits of the
+ * 8 key bytes, then compute the parity bits. Do this three times.
+ */
+ byte[] key = new byte[encProvider().keySize()];
+ int nthByte;
+ int tmp;
+ for (int i = 0; i < 3; i++) {
+ System.arraycopy(randomBits, i * 7, key, i * 8, 7);
+ nthByte = i * 8;
+
+ key[nthByte + 7] = (byte) (((key[nthByte + 0] & 1) << 1) |
+ ((key[nthByte + 1] & 1) << 2) |
+ ((key[nthByte + 2] & 1) << 3) |
+ ((key[nthByte + 3] & 1) << 4) |
+ ((key[nthByte + 4] & 1) << 5) |
+ ((key[nthByte + 5] & 1) << 6) |
+ ((key[nthByte + 6] & 1) << 7));
+
+ for (int j = 0; j < 8; j++) {
+ tmp = key[nthByte + j] & 0xfe;
+ tmp |= (Integer.bitCount(tmp) & 1) ^ 1;
+ key[nthByte + j] = (byte) tmp;
+ }
+ }
+
+ for (int i = 0; i < 3; i++) {
+ Des.fixKey(key, i * 8, 8);
+ }
+
+ return key;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java
new file mode 100644
index 0000000..2528b0d
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java
@@ -0,0 +1,282 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.Des;
+import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
+
+public class DesKeyMaker extends AbstractKeyMaker {
+
+ public DesKeyMaker(EncryptProvider encProvider) {
+ super(encProvider);
+ }
+
+ @Override
+ public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+ String error = null;
+ int type = 0;
+
+ if (param != null) {
+ if (param.length != 1) {
+ error = "Invalid param to S2K";
+ }
+ type = param[0];
+ if (type != 0 && type != 1) {
+ error = "Invalid param to S2K";
+ }
+ }
+ if (type == 1) {
+ error = "AFS not supported yet";
+ }
+
+ if (error != null) {
+ throw new KrbException(error);
+ }
+
+ byte[] key = toKey(string, salt);
+ return key;
+ }
+
+ /**
+ mit_des_string_to_key(string,salt) {
+ odd = 1;
+ s = string | salt;
+ tempstring = 0; // 56-bit string
+ pad(s); // with nulls to 8 byte boundary
+ for (8byteblock in s) {
+ 56bitstring = removeMSBits(8byteblock);
+ if (odd == 0) reverse(56bitstring);
+ odd = ! odd;
+ tempstring = tempstring XOR 56bitstring;
+ }
+ tempkey = key_correction(add_parity_bits(tempstring));
+ key = key_correction(DES-CBC-check(s,tempkey));
+ return(key);
+ }
+ */
+ private byte[] toKey(String string, String salt) throws KrbException {
+ byte[] bytes = makePasswdSalt(string, salt);
+ // padded with zero-valued octets to a multiple of eight octets.
+ byte[] paddedBytes = BytesUtil.padding(bytes, 8);
+
+ byte[] fanFoldedKey = fanFold(string, salt, paddedBytes);
+
+ byte[] intermediateKey = intermediateKey(fanFoldedKey);
+
+ byte[] key = desEncryptedKey(intermediateKey, paddedBytes);
+ keyCorrection(key);
+
+ return key;
+ }
+
+ /**
+ * Visible for test
+ */
+ public static byte[] fanFold(String string, String salt, byte[] paddedBytes) {
+ if (paddedBytes == null) {
+ byte[] bytes = makePasswdSalt(string, salt);
+ // padded with zero-valued octets to a multiple of eight octets.
+ paddedBytes = BytesUtil.padding(bytes, 8);
+ }
+
+ int blocksOfbytes8 = paddedBytes.length / 8;
+ boolean odd = true;
+ byte[] bits56 = new byte[8];
+ byte[] tempString = new byte[8];
+ for (int i = 0; i < blocksOfbytes8; ++i) {
+ System.arraycopy(paddedBytes, 8 * i, bits56, 0, 8);
+ removeMSBits(bits56);
+ if (!odd) {
+ reverse(bits56);
+ }
+ odd = !odd;
+ BytesUtil.xor(bits56, 0, tempString);
+ }
+
+ return tempString;
+ }
+
+ /**
+ * Visible for test
+ */
+ public static byte[] intermediateKey(byte[] fanFoldedKey) {
+ byte[] keyBytes = addParityBits(fanFoldedKey);
+ keyCorrection(keyBytes);
+
+ return keyBytes;
+ }
+
+ private byte[] desEncryptedKey(byte[] intermediateKey, byte[] originalBytes) throws KrbException {
+ byte[] resultKey = null;
+ if (encProvider().supportCbcMac()) {
+ resultKey = encProvider().cbcMac(intermediateKey, intermediateKey, originalBytes);
+ } else {
+ throw new KrbException("cbcMac should be supported by the provider: "
+ + encProvider().getClass());
+ }
+
+ keyCorrection(resultKey);
+
+ return resultKey;
+ }
+
+ /**
+ * Note this isn't hit any test yet, and very probably problematic
+ */
+ @Override
+ public byte[] random2Key(byte[] randomBits) throws KrbException {
+ if (randomBits.length != encProvider().keyInputSize()) {
+ throw new KrbException("Invalid random bits, not of correct bytes size");
+ }
+
+ byte[] keyBytes = addParityBits(randomBits);
+ keyCorrection(keyBytes);
+
+ return keyBytes;
+ }
+
+ // Processing an 8bytesblock
+ private static byte[] removeMSBits(byte[] bits56) {
+ /**
+ Treats a 64 bit block as 8 octets and removes the MSB in
+ each octet (in big endian mode) and concatenates the result.
+ E.g., the input octet string:
+ 01110000 01100001 11110011 01110011 11110111 01101111 11110010 01100100
+ =>
+ 1110000 1100001 1110011 1110011 1110111 1101111 1110010 1100100
+ */
+
+ /**
+ * We probably do nothing here, just pretending the MSB bit to be discarded,
+ * and ensure the MSB will not be used in the following processing.
+ */
+
+ return bits56;
+ }
+
+ // Processing an 56bitblock
+ private static void reverse(byte[] bits56) {
+ /**
+ Treats a 56-bit block as a binary string and reverses it.
+ E.g., the input string:
+ 1000001 1010100 1001000 1000101 1001110 1000001 0101110 1001101
+ =>
+ 1000001 0010101 0001001 1010001 0111001 1000001 0101110 1011001
+ =>
+ 1011001 0111010 1000001 0111001 1010001 0001001 0010101 1000001
+ */
+
+ // Reversing in a 7bit
+ int t1, t2;
+ byte bt;
+ for (int i = 0; i < 8; ++i) {
+ bt = bits56[i];
+
+ t1 = (bt >> 6) & 1;
+ t2 = (bt >> 0) & 1;
+ if (t1 != t2) bt ^= (1 << 6 | 1 << 0);
+
+ t1 = (bt >> 5) & 1;
+ t2 = (bt >> 1) & 1;
+ if (t1 != t2) bt ^= (1 << 5 | 1 << 1);
+
+ t1 = (bt >> 4) & 1;
+ t2 = (bt >> 2) & 1;
+ if (t1 != t2) bt ^= (1 << 4 | 1 << 2);
+
+ bits56[i] = bt;
+ }
+
+ // Reversing the 8 7bit
+ bt = bits56[7];
+ bits56[7] = bits56[0];
+ bits56[0] = bt;
+
+ bt = bits56[6];
+ bits56[6] = bits56[1];
+ bits56[1] = bt;
+
+ bt = bits56[5];
+ bits56[5] = bits56[2];
+ bits56[2] = bt;
+
+ bt = bits56[4];
+ bits56[4] = bits56[3];
+ bits56[3] = bt;
+ }
+
+ private static byte[] addParityBits(byte[] bits56) {
+ /**
+ Copies a 56-bit block into a 64-bit block, left shifts
+ content in each octet, and add DES parity bit.
+ E.g., the input string:
+ 1100000 0001111 0011100 0110100 1000101 1100100 0110110 0010111
+ =>
+ 11000001 00011111 00111000 01101000 10001010 11001000 01101101 00101111
+ */
+ byte bt;
+ for (int i = 0; i < 8; i++) {
+ bits56[i] <<= 1;
+ }
+
+ addParity(bits56);
+
+ return bits56;
+ }
+
+ private static void keyCorrection(byte[] key) {
+ addParity(key);
+ Des.fixKey(key, 0, key.length);
+ }
+
+ private static int smask(int step) {
+ return (1 << step) - 1;
+ }
+
+ private static byte pstep(byte x, int step) {
+ return (byte) ((x & smask(step)) ^ ((x >> step) & smask(step)));
+ }
+
+ private static byte parityChar(byte abyte) {
+ //#define smask(step) ((1<<step)-1)
+ //#define pstep(x,step) (((x)&smask(step))^(((x)>>step)&smask(step)))
+ //#define parity_char(x) pstep(pstep(pstep((x),4),2),1)
+ return pstep(pstep(pstep(abyte, 4), 2), 1);
+ }
+
+ private static void addParity(byte[] key) {
+ for (int i = 0; i < key.length; ++i) {
+ key[i] &= 0xfe;
+ key[i] |= 1 ^ parityChar(key[i]);
+ }
+ }
+
+ // Returns true if the key has correct des parity
+ private static boolean checkKeyParity(byte[] key) {
+ for (int i = 0; i < key.length; ++i) {
+ if ((key[i] & 1) == parityChar((byte) (key[i] & 0xfe))) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java
new file mode 100644
index 0000000..a1a515d
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java
@@ -0,0 +1,73 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.crypto.Nfold;
+import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
+
+public abstract class DkKeyMaker extends AbstractKeyMaker {
+
+ public DkKeyMaker(EncryptProvider encProvider) {
+ super(encProvider);
+ }
+
+ // DK(Key, Constant) = random-to-key(DR(Key, Constant))
+ public byte[] dk(byte[] key, byte[] constant) throws KrbException {
+ return random2Key(dr(key, constant));
+ }
+
+ /*
+ * K1 = E(Key, n-fold(Constant), initial-cipher-state)
+ * K2 = E(Key, K1, initial-cipher-state)
+ * K3 = E(Key, K2, initial-cipher-state)
+ * K4 = ...
+ * DR(Key, Constant) = k-truncate(K1 | K2 | K3 | K4 ...)
+ */
+ protected byte[] dr(byte[] key, byte[] constant) throws KrbException {
+
+ int blocksize = encProvider().blockSize();
+ int keyInuptSize = encProvider().keyInputSize();
+ byte[] keyBytes = new byte[keyInuptSize];
+ byte[] Ki;
+
+ if (constant.length != blocksize) {
+ Ki = Nfold.nfold(constant, blocksize);
+ } else {
+ Ki = new byte[constant.length];
+ System.arraycopy(constant, 0, Ki, 0, constant.length);
+ }
+
+ int n = 0, len;
+ while (n < keyInuptSize) {
+ encProvider().encrypt(key, Ki);
+
+ if (n + blocksize >= keyInuptSize) {
+ System.arraycopy(Ki, 0, keyBytes, n, keyInuptSize - n);
+ break;
+ }
+
+ System.arraycopy(Ki, 0, keyBytes, n, blocksize);
+ n += blocksize;
+ }
+
+ return keyBytes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/KeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/KeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/KeyMaker.java
new file mode 100644
index 0000000..8538c14
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/KeyMaker.java
@@ -0,0 +1,29 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public interface KeyMaker {
+
+ public byte[] str2key(String string, String salt, byte[] param) throws KrbException;
+
+ public byte[] random2Key(byte[] randomBits) throws KrbException;
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Rc4KeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Rc4KeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Rc4KeyMaker.java
new file mode 100644
index 0000000..85e8ba2
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Rc4KeyMaker.java
@@ -0,0 +1,52 @@
+/**
+ * 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.key;
+
+import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import sun.security.provider.MD4;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+
+public class Rc4KeyMaker extends AbstractKeyMaker {
+
+ public Rc4KeyMaker(EncryptProvider encProvider) {
+ super(encProvider);
+ }
+
+ @Override
+ public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+
+ if (param != null && param.length > 0) {
+ throw new RuntimeException("Invalid param to str2Key");
+ }
+
+ try {
+ byte[] passwd = string.getBytes("UTF-16LE"); // to unicode
+ MessageDigest md = MD4.getInstance();
+ md.update(passwd);
+ return md.digest();
+ } catch (UnsupportedEncodingException e) {
+ throw new KrbException("str2key failed", e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf b/kerby-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf
new file mode 100644
index 0000000..d118dd1
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+[libdefaults]
+ default_realm = {0}
+ udp_preference_limit = 1
+
+[realms]
+ {0} = '{'
+ kdc = {1}:{2}
+ '}'
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/ceacb982/kerby-kerb/kerb-crypto/src/main/resources/kdc.ldiff
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/resources/kdc.ldiff b/kerby-kerb/kerb-crypto/src/main/resources/kdc.ldiff
new file mode 100644
index 0000000..bc989c3
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/resources/kdc.ldiff
@@ -0,0 +1,46 @@
+# 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.
+dn: ou=users,dc=${0},dc=${1}
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: uid=krbtgt,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3}
+krb5KeyVersionNumber: 0
+
+dn: uid=ldap,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: LDAP
+sn: Service
+uid: ldap
+userPassword: secret
+krb5PrincipalName: ldap/${4}@${2}.${3}
+krb5KeyVersionNumber: 0