You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2015/11/27 09:06:22 UTC
[1/2] directory-kerby git commit: Add some code of the anonymous
pkinit.
Repository: directory-kerby
Updated Branches:
refs/heads/pkinit-support bdca83946 -> b9485672c
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhClient.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhClient.java
new file mode 100644
index 0000000..207570a
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhClient.java
@@ -0,0 +1,128 @@
+/*
+ * 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.dh;
+
+import org.apache.kerby.kerberos.kerb.crypto.EncTypeHandler;
+import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
+import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+
+
+/**
+ * The client-side of Diffie-Hellman key agreement for Kerberos PKINIT.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DhClient {
+
+ private KeyAgreement clientKeyAgree;
+ private EncryptionKey clientKey;
+ private DHParameterSpec dhParameterSpec;
+
+
+ public DHParameterSpec getDhParam() {
+ return dhParameterSpec;
+ }
+
+ public DHPublicKey init(DHParameterSpec dhParamSpec) throws Exception {
+ dhParameterSpec = dhParamSpec;
+ // The client creates its own DH key pair, using the DH parameters from above.
+ KeyPairGenerator clientKpairGen = KeyPairGenerator.getInstance("DH");
+ clientKpairGen.initialize(dhParamSpec);
+ KeyPair clientKpair = clientKpairGen.generateKeyPair();
+
+ // The client creates and initializes its DH KeyAgreement object.
+ clientKeyAgree = KeyAgreement.getInstance("DH");
+ clientKeyAgree.init(clientKpair.getPrivate());
+
+ // The client encodes its public key, and sends it over to the server.
+ return (DHPublicKey) clientKpair.getPublic();
+ }
+
+
+ public void doPhase(byte[] serverPubKeyEnc) throws Exception {
+ /*
+ * The client uses the server's public key for the first (and only) phase
+ * of its version of the DH protocol. Before it can do so, it has to
+ * instantiate a DH public key from the server's encoded key material.
+ */
+ KeyFactory clientKeyFac = KeyFactory.getInstance("DH");
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(serverPubKeyEnc);
+ PublicKey serverPubKey = clientKeyFac.generatePublic(x509KeySpec);
+
+ clientKeyAgree.doPhase(serverPubKey, true);
+ }
+
+ public EncryptionKey generateKey(byte[] clientDhNonce, byte[] serverDhNonce, EncryptionType type) {
+ // ZZ length will be same as public key.
+ byte[] dhSharedSecret = clientKeyAgree.generateSecret();
+ byte[] x = dhSharedSecret;
+
+ if (clientDhNonce != null && clientDhNonce.length > 0
+ && serverDhNonce != null && serverDhNonce.length > 0) {
+ x = concatenateBytes(dhSharedSecret, clientDhNonce);
+ x = concatenateBytes(x, serverDhNonce);
+ }
+
+ byte[] secret = OctetString2Key.kTruncate(dhSharedSecret.length, x);
+
+ clientKey = new EncryptionKey(type, secret);
+
+ return clientKey;
+ }
+
+ /**
+ * Decrypt
+ *
+ * @param cipherText
+ * @return
+ * @throws Exception
+ */
+ public byte[] decrypt(byte[] cipherText, KeyUsage usage) throws Exception {
+ // Use the secret key to encrypt/decrypt data.
+ EncTypeHandler encType = EncryptionHandler.getEncHandler(clientKey.getKeyType());
+ return encType.decrypt(cipherText, clientKey.getKeyData(), usage.getIntValue());
+ }
+
+ private byte[] concatenateBytes(byte[] array1, byte[] array2) {
+ byte[] concatenatedBytes = new byte[array1.length + array2.length];
+
+ for (int i = 0; i < array1.length; i++) {
+ concatenatedBytes[i] = array1[i];
+ }
+
+ for (int j = array1.length; j < concatenatedBytes.length; j++) {
+ concatenatedBytes[j] = array2[j - array1.length];
+ }
+
+ return concatenatedBytes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroup.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroup.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroup.java
new file mode 100644
index 0000000..ba92589
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroup.java
@@ -0,0 +1,138 @@
+/*
+ * 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.dh;
+
+
+import javax.crypto.spec.DHParameterSpec;
+import java.math.BigInteger;
+
+
+/**
+ * "When using the Diffie-Hellman key agreement method, implementations MUST
+ * support Oakley 1024-bit Modular Exponential (MODP) well-known group 2
+ * [RFC2412] and Oakley 2048-bit MODP well-known group 14 [RFC3526] and
+ * SHOULD support Oakley 4096-bit MODP well-known group 16 [RFC3526]."
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DhGroup {
+ /**
+ * From:
+ * The OAKLEY Key Determination Protocol
+ * http://www.ietf.org/rfc/rfc2412.txt
+ * <p/>
+ * Well-Known Group 2: A 1024 bit prime
+ * This group is assigned id 2 (two).
+ * The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ * The generator is 2 (decimal)
+ */
+ public static final DHParameterSpec MODP_GROUP2;
+
+ static {
+ StringBuffer sb = new StringBuffer();
+ sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
+ sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
+ sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
+ sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
+ sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381");
+ sb.append("FFFFFFFFFFFFFFFF");
+
+ BigInteger prime = new BigInteger(sb.toString(), 16);
+ BigInteger generator = BigInteger.valueOf(2);
+
+ MODP_GROUP2 = new DHParameterSpec(prime, generator);
+ }
+
+ /**
+ * From:
+ * More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)
+ * http://www.ietf.org/rfc/rfc3526.txt
+ * <p/>
+ * 2048-bit MODP Group
+ * This group is assigned id 14.
+ * This prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ * The generator is: 2.
+ */
+ public static final DHParameterSpec MODP_GROUP14;
+
+ static {
+ StringBuffer sb = new StringBuffer();
+ sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
+ sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
+ sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
+ sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
+ sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D");
+ sb.append("C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F");
+ sb.append("83655D23DCA3AD961C62F356208552BB9ED529077096966D");
+ sb.append("670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B");
+ sb.append("E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9");
+ sb.append("DE2BCBF6955817183995497CEA956AE515D2261898FA0510");
+ sb.append("15728E5A8AACAA68FFFFFFFFFFFFFFFF");
+
+ BigInteger prime = new BigInteger(sb.toString(), 16);
+ BigInteger generator = BigInteger.valueOf(2);
+
+ MODP_GROUP14 = new DHParameterSpec(prime, generator);
+ }
+
+ /**
+ * From:
+ * More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)
+ * http://www.ietf.org/rfc/rfc3526.txt
+ * <p/>
+ * 4096-bit MODP Group
+ * This group is assigned id 16.
+ * This prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ * The generator is: 2.
+ */
+ public static final DHParameterSpec MODP_GROUP16;
+
+ static {
+ StringBuffer sb = new StringBuffer();
+ sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
+ sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
+ sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
+ sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
+ sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D");
+ sb.append("C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F");
+ sb.append("83655D23DCA3AD961C62F356208552BB9ED529077096966D");
+ sb.append("670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B");
+ sb.append("E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9");
+ sb.append("DE2BCBF6955817183995497CEA956AE515D2261898FA0510");
+ sb.append("15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64");
+ sb.append("ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7");
+ sb.append("ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B");
+ sb.append("F12FFA06D98A0864D87602733EC86A64521F2B18177B200C");
+ sb.append("BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31");
+ sb.append("43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7");
+ sb.append("88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA");
+ sb.append("2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6");
+ sb.append("287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED");
+ sb.append("1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9");
+ sb.append("93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199");
+ sb.append("FFFFFFFFFFFFFFFF");
+
+ BigInteger prime = new BigInteger(sb.toString(), 16);
+ BigInteger generator = BigInteger.valueOf(2);
+
+ MODP_GROUP16 = new DHParameterSpec(prime, generator);
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhServer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhServer.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhServer.java
new file mode 100644
index 0000000..3104da7
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhServer.java
@@ -0,0 +1,126 @@
+/*
+ * 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.dh;
+
+import org.apache.kerby.kerberos.kerb.crypto.EncTypeHandler;
+import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
+import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+
+
+/**
+ * The server-side of Diffie-Hellman key agreement for Kerberos PKINIT.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DhServer {
+
+ private KeyAgreement serverKeyAgree;
+ private EncryptionKey serverKey;
+
+ public PublicKey initAndDoPhase(byte[] clientPubKeyEnc) throws Exception {
+ /*
+ * The server has received the client's public key in encoded format. The
+ * server instantiates a DH public key from the encoded key material.
+ */
+ KeyFactory serverKeyFac = KeyFactory.getInstance("DH");
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(clientPubKeyEnc);
+ PublicKey clientPubKey = serverKeyFac.generatePublic(x509KeySpec);
+
+ /*
+ * The server gets the DH parameters associated with the client's public
+ * key. The server must use the same parameters when it generates its own key pair.
+ */
+ DHParameterSpec dhParamSpec = ((DHPublicKey) clientPubKey).getParams();
+
+ // The server creates its own DH key pair.
+ KeyPairGenerator serverKpairGen = KeyPairGenerator.getInstance("DH");
+ serverKpairGen.initialize(dhParamSpec);
+ KeyPair serverKpair = serverKpairGen.generateKeyPair();
+
+ // The server creates and initializes its DH KeyAgreement object.
+ serverKeyAgree = KeyAgreement.getInstance("DH");
+ serverKeyAgree.init(serverKpair.getPrivate());
+
+ /*
+ * The server uses the client's public key for the only phase of its
+ * side of the DH protocol.
+ */
+ serverKeyAgree.doPhase(clientPubKey, true);
+
+ // The server encodes its public key, and sends it over to the client.
+ return serverKpair.getPublic();
+ }
+
+ public EncryptionKey generateKey(byte[] clientDhNonce, byte[] serverDhNonce, EncryptionType type) {
+ // ZZ length will be same as public key.
+ byte[] dhSharedSecret = serverKeyAgree.generateSecret();
+ byte[] x = dhSharedSecret;
+
+ if (clientDhNonce != null && clientDhNonce.length > 0
+ && serverDhNonce != null && serverDhNonce.length > 0) {
+ x = concatenateBytes(dhSharedSecret, clientDhNonce);
+ x = concatenateBytes(x, serverDhNonce);
+ }
+
+ byte[] secret = OctetString2Key.kTruncate(dhSharedSecret.length, x);
+ serverKey = new EncryptionKey(type, secret);
+
+ return serverKey;
+ }
+
+ /**
+ * Encrypt
+ *
+ * @param clearText
+ * @return The cipher text.
+ * @throws Exception
+ */
+ public byte[] encrypt(byte[] clearText, KeyUsage usage) throws Exception {
+ // Use the secret key to encrypt/decrypt data.
+ EncTypeHandler encType = EncryptionHandler.getEncHandler(serverKey.getKeyType());
+ return encType.decrypt(clearText, serverKey.getKeyData(), usage.getIntValue());
+ }
+
+ private byte[] concatenateBytes(byte[] array1, byte[] array2) {
+ byte[] concatenatedBytes = new byte[array1.length + array2.length];
+
+ for (int i = 0; i < array1.length; i++) {
+ concatenatedBytes[i] = array1[i];
+ }
+
+ for (int j = array1.length; j < concatenatedBytes.length; j++) {
+ concatenatedBytes[j] = array2[j - array1.length];
+ }
+
+ return concatenatedBytes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2Key.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2Key.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2Key.java
new file mode 100644
index 0000000..32715ff
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2Key.java
@@ -0,0 +1,91 @@
+/*
+ * 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.dh;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * From RFC 4556:
+ * <p/>
+ * Define the function octetstring2key() as follows:
+ * <p/>
+ * octetstring2key(x) == random-to-key(K-truncate(
+ * SHA1(0x00 | x) |
+ * SHA1(0x01 | x) |
+ * SHA1(0x02 | x) |
+ * ...
+ * ))
+ * <p/>
+ * where x is an octet string; | is the concatenation operator; 0x00,
+ * 0x01, 0x02, etc. are each represented as a single octet; random-
+ * to-key() is an operation that generates a protocol key from a
+ * bitstring of length K; and K-truncate truncates its input to the
+ * first K bits. Both K and random-to-key() are as defined in the
+ * kcrypto profile [RFC3961] for the enctype of the AS reply key.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class OctetString2Key {
+ /**
+ * Performs the function K-truncate to generate the AS reply key k.
+ *
+ * @param k
+ * @param x
+ * @return The AS reply key value.
+ */
+ public static byte[] kTruncate(int k, byte[] x) {
+ int numberOfBytes = k / 8;
+ byte[] result = new byte[numberOfBytes];
+
+ int count = 0;
+ byte[] filler = calculateIntegrity((byte) count, x);
+
+ int position = 0;
+
+ for (int i = 0; i < numberOfBytes; i++) {
+ if (position < filler.length) {
+ result[i] = filler[position];
+ position++;
+ } else {
+ count++;
+ filler = calculateIntegrity((byte) count, x);
+ position = 0;
+ result[i] = filler[position];
+ position++;
+ }
+ }
+
+ return result;
+ }
+
+
+ private static byte[] calculateIntegrity(byte count, byte[] data) {
+ try {
+ MessageDigest digester = MessageDigest.getInstance("SHA1");
+ digester.update(count);
+
+ return digester.digest(data);
+ } catch (NoSuchAlgorithmException nsae) {
+ return new byte[0];
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroupTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroupTest.java b/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroupTest.java
new file mode 100644
index 0000000..3061bb8
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhGroupTest.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.dh;
+
+import junit.framework.TestCase;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhGroup;
+
+/**
+ * "When using the Diffie-Hellman key agreement method, implementations MUST
+ * support Oakley 1024-bit Modular Exponential (MODP) well-known group 2
+ * [RFC2412] and Oakley 2048-bit MODP well-known group 14 [RFC3526] and
+ * SHOULD support Oakley 4096-bit MODP well-known group 16 [RFC3526]."
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DhGroupTest extends TestCase {
+ /**
+ * Tests that the translation of the hex representation of the prime modulus
+ * resulted in the expected bit length.
+ */
+ public void testPrimeBitLengths() {
+ TestCase.assertEquals(1024, DhGroup.MODP_GROUP2.getP().bitLength());
+ TestCase.assertEquals(2048, DhGroup.MODP_GROUP14.getP().bitLength());
+ TestCase.assertEquals(4096, DhGroup.MODP_GROUP16.getP().bitLength());
+ }
+
+ /**
+ * Tests the generator values.
+ */
+ public void testGeneratorValues() {
+ TestCase.assertEquals(2, DhGroup.MODP_GROUP2.getG().intValue());
+ TestCase.assertEquals(2, DhGroup.MODP_GROUP14.getG().intValue());
+ TestCase.assertEquals(2, DhGroup.MODP_GROUP16.getG().intValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhKeyAgreementTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhKeyAgreementTest.java b/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhKeyAgreementTest.java
new file mode 100644
index 0000000..519faaa
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/DhKeyAgreementTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.dh;
+
+
+import junit.framework.TestCase;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhClient;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhGroup;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhServer;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
+import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+
+
+/**
+ * Tests the Diffie-Hellman key agreement protocol between a client and server.
+ * <p/>
+ * Generating a Secret Key Using the Diffie-Hellman Key Agreement Algorithm
+ * <p/>
+ * Two parties use a key agreement protocol to generate identical secret keys for
+ * encryption without ever having to transmit the secret key. The protocol works
+ * by both parties agreeing on a set of values (a prime, a base, and a private
+ * value) which are used to generate a key pair.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DhKeyAgreementTest extends TestCase {
+ private static SecureRandom secureRandom = new SecureRandom();
+
+ /**
+ * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
+ * well-known group 2 [RFC2412].
+ *
+ * @throws Exception
+ */
+ public void testPreGeneratedDhParams() throws Exception {
+ DhClient client = new DhClient();
+ DhServer server = new DhServer();
+
+ byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2).getEncoded();
+ byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc).getEncoded();
+
+ server.generateKey(null, null, EncryptionType.AES128_CTS_HMAC_SHA1_96);
+
+ client.doPhase(serverPubKeyEnc);
+
+ client.generateKey(null, null, EncryptionType.AES128_CTS_HMAC_SHA1_96);
+
+ byte[] clearText = "This is just an example".getBytes();
+
+ byte[] cipherText = server.encrypt(clearText, KeyUsage.UNKNOWN);
+ byte[] recovered = client.decrypt(cipherText, KeyUsage.UNKNOWN);
+
+ assertTrue(Arrays.equals(clearText, recovered));
+ }
+
+
+ /**
+ * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
+ * well-known group 2 [RFC2412], including the optional DH nonce.
+ * <p/>
+ * "This nonce string MUST be as long as the longest key length of the symmetric
+ * key types that the client supports. This nonce MUST be chosen randomly."
+ *
+ * @throws Exception
+ */
+ public void testPreGeneratedDhParamsWithNonce() throws Exception {
+ byte[] clientDhNonce = new byte[16];
+ secureRandom.nextBytes(clientDhNonce);
+
+ byte[] serverDhNonce = new byte[16];
+ secureRandom.nextBytes(serverDhNonce);
+
+ DhClient client = new DhClient();
+ DhServer server = new DhServer();
+
+ byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2).getEncoded();
+ byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc).getEncoded();
+
+ server.generateKey(clientDhNonce, serverDhNonce, EncryptionType.AES128_CTS_HMAC_SHA1_96);
+
+ client.doPhase(serverPubKeyEnc);
+
+ client.generateKey(clientDhNonce, serverDhNonce, EncryptionType.AES128_CTS_HMAC_SHA1_96);
+
+ byte[] clearText = "This is just an example".getBytes();
+
+ byte[] cipherText = server.encrypt(clearText, KeyUsage.UNKNOWN);
+ byte[] recovered = client.decrypt(cipherText, KeyUsage.UNKNOWN);
+
+ assertTrue(Arrays.equals(clearText, recovered));
+ }
+
+
+ /**
+ * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
+ * well-known group 2 [RFC2412].
+ *
+ * @throws Exception
+ */
+ public void testGeneratedDhParams() throws Exception {
+ DhClient client = new DhClient();
+ DhServer server = new DhServer();
+
+ DHPublicKey clientPubKey = client.init(DhGroup.MODP_GROUP14);
+ DHParameterSpec spec = clientPubKey.getParams();
+
+ BigInteger y = clientPubKey.getY();
+ BigInteger p = spec.getP();
+ BigInteger g = spec.getG();
+ DHPublicKeySpec dhPublicKeySpec = new DHPublicKeySpec(y, p, g);
+
+ KeyFactory keyFactory = null;
+ try {
+ keyFactory = KeyFactory.getInstance("DH");
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ DHPublicKey dhPublicKey = null;
+ try {
+ dhPublicKey = (DHPublicKey) keyFactory.generatePublic(dhPublicKeySpec);
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ }
+
+ byte[] serverPubKeyEnc = null;
+ try {
+ serverPubKeyEnc = server.initAndDoPhase(dhPublicKey.getEncoded()).getEncoded();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ server.generateKey(null, null, EncryptionType.AES128_CTS_HMAC_SHA1_96);
+
+ client.doPhase(serverPubKeyEnc);
+
+ client.generateKey(null, null, EncryptionType.AES128_CTS_HMAC_SHA1_96);
+
+ byte[] clearText = "This is just an example".getBytes();
+
+ byte[] cipherText = server.encrypt(clearText, KeyUsage.UNKNOWN);
+ byte[] recovered = client.decrypt(cipherText, KeyUsage.UNKNOWN);
+
+ assertTrue(Arrays.equals(clearText, recovered));
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2KeyTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2KeyTest.java b/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2KeyTest.java
new file mode 100644
index 0000000..b1dca2d
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/test/java/org/apache/kerby/kerberos/kerb/crypto/dh/OctetString2KeyTest.java
@@ -0,0 +1,225 @@
+/*
+ * 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.dh;
+
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+
+/**
+ * From RFC 4556:
+ * <p/>
+ * "Appendix B. Test Vectors
+ * <p/>
+ * Function octetstring2key() is defined in Section 3.2.3.1. This section describes
+ * a few sets of test vectors that would be useful for implementers of octetstring2key()."
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class OctetString2KeyTest extends TestCase {
+ /**
+ * Set 1:
+ * =====
+ * Input octet string x is:
+ * <p/>
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * <p/>
+ * Output of K-truncate() when the key size is 32 octets:
+ * <p/>
+ * 5e e5 0d 67 5c 80 9f e5 9e 4a 77 62 c5 4b 65 83
+ * 75 47 ea fb 15 9b d8 cd c7 5f fc a5 91 1e 4c 41
+ */
+ public void testSet1() {
+ byte[] inputOctetString = new byte[16 * 16];
+
+ byte[] expectedOutput =
+ {(byte) 0x5e, (byte) 0xe5, (byte) 0x0d, (byte) 0x67, (byte) 0x5c, (byte) 0x80, (byte) 0x9f,
+ (byte) 0xe5, (byte) 0x9e, (byte) 0x4a, (byte) 0x77, (byte) 0x62, (byte) 0xc5,
+ (byte) 0x4b, (byte) 0x65, (byte) 0x83, (byte) 0x75, (byte) 0x47, (byte) 0xea,
+ (byte) 0xfb, (byte) 0x15, (byte) 0x9b, (byte) 0xd8, (byte) 0xcd, (byte) 0xc7,
+ (byte) 0x5f, (byte) 0xfc, (byte) 0xa5, (byte) 0x91, (byte) 0x1e, (byte) 0x4c, (byte) 0x41};
+
+ int keySize = 32 * 8;
+
+ byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
+
+ assertTrue(Arrays.equals(result, expectedOutput));
+ }
+
+
+ /**
+ * Set 2:
+ * =====
+ * Input octet string x is:
+ * <p/>
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * <p/>
+ * Output of K-truncate() when the key size is 32 octets:
+ * <p/>
+ * ac f7 70 7c 08 97 3d df db 27 cd 36 14 42 cc fb
+ * a3 55 c8 88 4c b4 72 f3 7d a6 36 d0 7d 56 78 7e
+ */
+ public void testSet2() {
+ byte[] inputOctetString = new byte[16 * 8];
+
+ byte[] expectedOutput =
+ {(byte) 0xac, (byte) 0xf7, (byte) 0x70, (byte) 0x7c, (byte) 0x08, (byte) 0x97, (byte) 0x3d,
+ (byte) 0xdf, (byte) 0xdb, (byte) 0x27, (byte) 0xcd, (byte) 0x36, (byte) 0x14,
+ (byte) 0x42, (byte) 0xcc, (byte) 0xfb, (byte) 0xa3, (byte) 0x55, (byte) 0xc8,
+ (byte) 0x88, (byte) 0x4c, (byte) 0xb4, (byte) 0x72, (byte) 0xf3, (byte) 0x7d,
+ (byte) 0xa6, (byte) 0x36, (byte) 0xd0, (byte) 0x7d, (byte) 0x56, (byte) 0x78, (byte) 0x7e};
+
+ int keySize = 32 * 8;
+
+ byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
+
+ assertTrue(Arrays.equals(result, expectedOutput));
+ }
+
+
+ /**
+ * Set 3:
+ * ======
+ * Input octet string x is:
+ * <p/>
+ * 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+ * 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
+ * 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
+ * 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c
+ * 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b
+ * 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a
+ * 0b 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09
+ * 0a 0b 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08
+ * <p/>
+ * Output of K-truncate() when the key size is 32 octets:
+ * <p/>
+ * c4 42 da 58 5f cb 80 e4 3b 47 94 6f 25 40 93 e3
+ * 73 29 d9 90 01 38 0d b7 83 71 db 3a cf 5c 79 7e
+ */
+ public void testSet3() {
+ byte[] inputOctetString =
+ {(byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
+ (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
+ (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01,
+ (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
+ (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
+ (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02,
+ (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
+ (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
+ (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
+ (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
+ (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
+ (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+ (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a,
+ (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10,
+ (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+ (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b,
+ (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00,
+ (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
+ (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
+ (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01,
+ (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
+
+ byte[] expectedOutput =
+ {(byte) 0xc4, (byte) 0x42, (byte) 0xda, (byte) 0x58, (byte) 0x5f, (byte) 0xcb, (byte) 0x80,
+ (byte) 0xe4, (byte) 0x3b, (byte) 0x47, (byte) 0x94, (byte) 0x6f, (byte) 0x25,
+ (byte) 0x40, (byte) 0x93, (byte) 0xe3, (byte) 0x73, (byte) 0x29, (byte) 0xd9,
+ (byte) 0x90, (byte) 0x01, (byte) 0x38, (byte) 0x0d, (byte) 0xb7, (byte) 0x83,
+ (byte) 0x71, (byte) 0xdb, (byte) 0x3a, (byte) 0xcf, (byte) 0x5c, (byte) 0x79, (byte) 0x7e};
+
+ int keySize = 32 * 8;
+
+ byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
+
+ assertTrue(Arrays.equals(result, expectedOutput));
+ }
+
+
+ /**
+ * Set 4:
+ * =====
+ * Input octet string x is:
+ * <p/>
+ * 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+ * 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
+ * 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
+ * 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c
+ * 0d 0e 0f 10 00 01 02 03 04 05 06 07 08
+ * <p/>
+ * Output of K-truncate() when the key size is 32 octets:
+ * <p/>
+ * 00 53 95 3b 84 c8 96 f4 eb 38 5c 3f 2e 75 1c 4a
+ * 59 0e d6 ff ad ca 6f f6 4f 47 eb eb 8d 78 0f fc
+ */
+ public void testSet4() {
+ byte[] inputOctetString =
+ {(byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
+ (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
+ (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01,
+ (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
+ (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
+ (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02,
+ (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
+ (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
+ (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
+ (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
+ (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
+ (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+ (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
+
+ byte[] expectedOutput =
+ {(byte) 0x00, (byte) 0x53, (byte) 0x95, (byte) 0x3b, (byte) 0x84, (byte) 0xc8, (byte) 0x96,
+ (byte) 0xf4, (byte) 0xeb, (byte) 0x38, (byte) 0x5c, (byte) 0x3f, (byte) 0x2e,
+ (byte) 0x75, (byte) 0x1c, (byte) 0x4a, (byte) 0x59, (byte) 0x0e, (byte) 0xd6,
+ (byte) 0xff, (byte) 0xad, (byte) 0xca, (byte) 0x6f, (byte) 0xf6, (byte) 0x4f,
+ (byte) 0x47, (byte) 0xeb, (byte) 0xeb, (byte) 0x8d, (byte) 0x78, (byte) 0x0f, (byte) 0xfc};
+
+ int keySize = 32 * 8;
+
+ byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
+
+ assertTrue(Arrays.equals(result, expectedOutput));
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/pom.xml b/kerby-kerb/kerb-server/pom.xml
index edb355c..ddea681 100644
--- a/kerby-kerb/kerb-server/pom.xml
+++ b/kerby-kerb/kerb-server/pom.xml
@@ -47,5 +47,10 @@
<artifactId>kerb-identity</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>not-yet-commons-ssl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/Asn1InputBuffer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/Asn1InputBuffer.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/Asn1InputBuffer.java
new file mode 100644
index 0000000..ce52b52
--- /dev/null
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/Asn1InputBuffer.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.server;
+
+import org.apache.kerby.asn1.LimitedByteBuffer;
+import org.apache.kerby.asn1.type.AbstractAsn1Type;
+import org.apache.kerby.asn1.type.Asn1Item;
+import org.apache.kerby.asn1.type.Asn1Type;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Asn1 decoder. Given an input stream, it validates and parses
+ * according to ASN1 spec, and the resultant object can be read
+ * and read until exhausted.
+ */
+public class Asn1InputBuffer {
+ private final LimitedByteBuffer limitedBuffer;
+
+ /**
+ * Constructor with bytes.
+ * @param bytes The bytes
+ */
+ public Asn1InputBuffer(byte[] bytes) {
+ this(new LimitedByteBuffer(bytes));
+ }
+
+ /**
+ * Constructor with a ByteBuffer.
+ * @param byteBuffer The byte buffer
+ */
+ public Asn1InputBuffer(ByteBuffer byteBuffer) {
+ this(new LimitedByteBuffer(byteBuffer));
+ }
+
+ /**
+ * Constructor with LimitedByteBuffer.
+ * @param limitedByteBuffer The limited byte buffer
+ */
+ public Asn1InputBuffer(LimitedByteBuffer limitedByteBuffer) {
+ this.limitedBuffer = limitedByteBuffer;
+ }
+
+ /**
+ * Parse and read ASN1 object from the stream. If it's already
+ * exhausted then null will be returned to indicate the end.
+ * @return an ASN1 object if available otherwise null
+ * @throws IOException e
+ */
+ public Asn1Type read() throws IOException {
+ if (!limitedBuffer.available()) {
+ return null;
+ }
+ Asn1Item one = decodeOne(limitedBuffer);
+ if (one.isSimple()) {
+ one.decodeValueAsSimple();
+ } else if (one.isCollection()) {
+ one.decodeValueAsCollection();
+ }
+ if (one.isFullyDecoded()) {
+ return one.getValue();
+ }
+ return one;
+ }
+
+ public static Asn1Item decodeOne(LimitedByteBuffer content) throws IOException {
+ int tag = AbstractAsn1Type.readTag(content);
+ int tagNo = AbstractAsn1Type.readTagNo(content, tag);
+ int length = AbstractAsn1Type.readLength(content);
+ if (length < 0) {
+ throw new IOException("Unexpected length");
+ }
+ LimitedByteBuffer valueContent = new LimitedByteBuffer(content, length);
+// content.skip(length);
+
+ Asn1Item result = new Asn1Item(tag, tagNo, valueContent);
+ if(!result.isCollection() && !result.isAppSpecific()) {
+ content.skip(length);
+ }
+ if (result.isSimple()) {
+ result.decodeValueAsSimple();
+ }
+ return result;
+ }
+
+ /**
+ * Read from bytes.
+ *
+ * @param bytes The bytes
+ * @throws IOException e
+ */
+ public void readBytes(byte[] bytes) throws IOException {
+ limitedBuffer.readBytes(bytes);
+ }
+
+ public byte[] readAllLeftBytes() throws IOException {
+ return limitedBuffer.readAllLeftBytes();
+ }
+
+ public void skipNext() throws IOException {
+ if (limitedBuffer.available()) {
+ AbstractAsn1Type.skipOne(limitedBuffer);
+ }
+ }
+
+ public void skipBytes(int len) throws IOException {
+ if (limitedBuffer.available()) {
+ limitedBuffer.skip(len);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
index eb63a13..ad35b71 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
@@ -19,6 +19,8 @@
*/
package org.apache.kerby.kerberos.kerb.server;
+import org.apache.kerby.asn1.type.Asn1Item;
+import org.apache.kerby.asn1.type.Asn1Type;
import org.apache.kerby.kerberos.kerb.KrbCodec;
import org.apache.kerby.kerberos.kerb.KrbErrorCode;
import org.apache.kerby.kerberos.kerb.KrbException;
@@ -71,6 +73,31 @@ public class KdcHandler {
KdcRequest kdcRequest = null;
KrbMessage krbResponse;
+ ByteBuffer message = receivedMessage.duplicate();
+ Asn1InputBuffer ib = new Asn1InputBuffer(message);
+ Asn1Type body = null;
+ Asn1Type fd = null;
+ try {
+ fd = ib.read();
+ body = fd;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ while (fd != null) {
+ body = fd;
+ try {
+ fd = ib.read();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ byte[] reqBodyBytes = null;
+ try {
+ reqBodyBytes = ((Asn1Item)body).getBodyContent().readAllLeftBytes();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
try {
krbRequest = KrbCodec.decodeMessage(receivedMessage);
} catch (IOException e) {
@@ -98,6 +125,9 @@ public class KdcHandler {
}
}
+ // For checksum
+ kdcRequest.setReqBodyBytes(reqBodyBytes);
+
if (remoteAddress == null) {
throw new KrbException("Remote address is null, not available.");
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/DhServer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/DhServer.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/DhServer.java
deleted file mode 100644
index d8bf903..0000000
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/DhServer.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.server.preauth.pkinit;
-
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.SecretKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-
-
-/**
- * The server-side of Diffie-Hellman key agreement for Kerberos PKINIT.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-class DhServer {
- private static AlgorithmParameterSpec aesIv = new IvParameterSpec(new byte[16]);
-
- private KeyAgreement serverKeyAgree;
- private SecretKey serverAesKey;
-
-
- PublicKey initAndDoPhase(byte[] clientPubKeyEnc) throws Exception {
- /*
- * The server has received the client's public key in encoded format. The
- * server instantiates a DH public key from the encoded key material.
- */
- KeyFactory serverKeyFac = KeyFactory.getInstance("DH");
- X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(clientPubKeyEnc);
- PublicKey clientPubKey = serverKeyFac.generatePublic(x509KeySpec);
-
- /*
- * The server gets the DH parameters associated with the client's public
- * key. The server must use the same parameters when it generates its own key pair.
- */
- DHParameterSpec dhParamSpec = ((DHPublicKey) clientPubKey).getParams();
-
- // The server creates its own DH key pair.
- KeyPairGenerator serverKpairGen = KeyPairGenerator.getInstance("DH");
- serverKpairGen.initialize(dhParamSpec);
- KeyPair serverKpair = serverKpairGen.generateKeyPair();
-
- // The server creates and initializes its DH KeyAgreement object.
- serverKeyAgree = KeyAgreement.getInstance("DH");
- serverKeyAgree.init(serverKpair.getPrivate());
-
- /*
- * The server uses the client's public key for the only phase of its
- * side of the DH protocol.
- */
- serverKeyAgree.doPhase(clientPubKey, true);
-
- // The server encodes its public key, and sends it over to the client.
- return serverKpair.getPublic();
- }
-
-
- byte[] generateKey(byte[] clientDhNonce, byte[] serverDhNonce) {
- // ZZ length will be same as public key.
- byte[] dhSharedSecret = serverKeyAgree.generateSecret();
- byte[] x = dhSharedSecret;
-
- if (clientDhNonce != null && clientDhNonce.length > 0
- && serverDhNonce != null && serverDhNonce.length > 0) {
- x = concatenateBytes(dhSharedSecret, clientDhNonce);
- x = concatenateBytes(x, serverDhNonce);
- }
-
- byte[] secret = OctetString2Key.kTruncate(dhSharedSecret.length, x);
- serverAesKey = new SecretKeySpec(secret, 0, 16, "AES");
-
- return serverAesKey.getEncoded();
- }
-
-
- /**
- * Encrypt using AES in CTS mode.
- *
- * @param clearText
- * @return The cipher text.
- * @throws Exception
- */
- byte[] encryptAes(byte[] clearText) throws Exception {
- // Use the secret key to encrypt/decrypt data.
- Cipher serverCipher = Cipher.getInstance("AES/CTS/NoPadding");
- serverCipher.init(Cipher.ENCRYPT_MODE, serverAesKey, aesIv);
-
- return serverCipher.doFinal(clearText);
- }
-
-
- byte[] concatenateBytes(byte[] array1, byte[] array2) {
- byte[] concatenatedBytes = new byte[array1.length + array2.length];
-
- for (int i = 0; i < array1.length; i++) {
- concatenatedBytes[i] = array1[i];
- }
-
- for (int j = array1.length; j < concatenatedBytes.length; j++) {
- concatenatedBytes[j] = array2[j - array1.length];
- }
-
- return concatenatedBytes;
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/OctetString2Key.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/OctetString2Key.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/OctetString2Key.java
deleted file mode 100644
index 9829642..0000000
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/OctetString2Key.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.server.preauth.pkinit;
-
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-
-/**
- * From RFC 4556:
- * <p/>
- * Define the function octetstring2key() as follows:
- * <p/>
- * octetstring2key(x) == random-to-key(K-truncate(
- * SHA1(0x00 | x) |
- * SHA1(0x01 | x) |
- * SHA1(0x02 | x) |
- * ...
- * ))
- * <p/>
- * where x is an octet string; | is the concatenation operator; 0x00,
- * 0x01, 0x02, etc. are each represented as a single octet; random-
- * to-key() is an operation that generates a protocol key from a
- * bitstring of length K; and K-truncate truncates its input to the
- * first K bits. Both K and random-to-key() are as defined in the
- * kcrypto profile [RFC3961] for the enctype of the AS reply key.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class OctetString2Key {
- /**
- * Performs the function K-truncate to generate the AS reply key k.
- *
- * @param k
- * @param x
- * @return The AS reply key value.
- */
- public static byte[] kTruncate(int k, byte[] x) {
- int numberOfBytes = k / 8;
- byte[] result = new byte[numberOfBytes];
-
- int count = 0;
- byte[] filler = calculateIntegrity((byte) count, x);
-
- int position = 0;
-
- for (int i = 0; i < numberOfBytes; i++) {
- if (position < filler.length) {
- result[i] = filler[position];
- position++;
- } else {
- count++;
- filler = calculateIntegrity((byte) count, x);
- position = 0;
- result[i] = filler[position];
- position++;
- }
- }
-
- return result;
- }
-
-
- private static byte[] calculateIntegrity(byte count, byte[] data) {
- try {
- MessageDigest digester = MessageDigest.getInstance("SHA1");
- digester.update(count);
-
- return digester.digest(data);
- } catch (NoSuchAlgorithmException nsae) {
- return new byte[0];
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
index 54f0693..8d99bbe 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
@@ -24,10 +24,13 @@ import org.apache.kerby.kerberos.kerb.KrbErrorCode;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.common.CheckSumUtil;
import org.apache.kerby.kerberos.kerb.common.KrbUtil;
+import org.apache.kerby.kerberos.kerb.crypto.CheckSumHandler;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhServer;
import org.apache.kerby.kerberos.kerb.preauth.PluginRequestContext;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.CMSMessageType;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.CertificateHelper;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitCrypto;
+import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitPlgCryptoContext;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitPreauthMeta;
import org.apache.kerby.kerberos.kerb.server.KdcContext;
import org.apache.kerby.kerberos.kerb.server.preauth.AbstractPreauthPlugin;
@@ -35,6 +38,7 @@ import org.apache.kerby.kerberos.kerb.server.request.KdcRequest;
import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
import org.apache.kerby.kerberos.kerb.spec.base.CheckSum;
import org.apache.kerby.kerberos.kerb.spec.base.CheckSumType;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
import org.apache.kerby.kerberos.kerb.spec.cms.DHParameter;
import org.apache.kerby.kerberos.kerb.spec.cms.SubjectPublicKeyInfo;
@@ -51,13 +55,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
-import sun.security.pkcs.SignerInfo;
-import sun.security.util.DerValue;
-import sun.security.util.ObjectIdentifier;
-import sun.security.x509.AlgorithmId;
import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHPublicKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -65,10 +64,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -80,7 +76,6 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
private static final Logger LOG = LoggerFactory.getLogger(PkinitPreauth.class);
private final Map<String, PkinitKdcContext> pkinitContexts;
- private static final String ID_PKINIT_DHKEYDATA = "1.3.6.1.5.2.3.2";
public PkinitPreauth() {
super(new PkinitPreauthMeta());
@@ -133,7 +128,7 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
byte[] signedAuthPack = paPkAsReq.getSignedAuthPack();
PKCS7 pkcs7 = null;
try {
- pkcs7 = PkinitCrypto.verifyCMSSignedData(pkinitContext.cryptoctx,
+ pkcs7 = PkinitCrypto.verifyCMSSignedData(
CMSMessageType.CMS_SIGN_CLIENT, signedAuthPack);
} catch (IOException e) {
e.getMessage();
@@ -180,16 +175,18 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
CheckSum expectedCheckSum = null;
try {
+// expectedCheckSum = CheckSumUtil.makeCheckSum(CheckSumType.NIST_SHA,
+// kdcRequest.getKdcReq().getReqBody().encode());
expectedCheckSum = CheckSumUtil.makeCheckSum(CheckSumType.NIST_SHA,
- kdcRequest.getKdcReq().getReqBody().encode());
+ kdcRequest.getReqBodyBytes());
} catch (KrbException e) {
LOG.error("Unable to calculate AS REQ checksum.", e.getMessage());
}
+
CheckSum receivedCheckSum = KrbCodec.decode(pkAuthenticator.getPaChecksum(), CheckSum.class);
- if (expectedCheckSum.encodingLength() != receivedCheckSum.encodingLength()
- || !Arrays.equals(expectedCheckSum.getChecksum(), receivedCheckSum.getChecksum())) {
+ if(!CheckSumHandler.verify(receivedCheckSum, kdcRequest.getReqBodyBytes())) {
LOG.debug("Received checksum type: " + receivedCheckSum.getCksumtype()
+ ", received checksum length: " + receivedCheckSum.encodingLength()
+ ", expected checksum type: " + expectedCheckSum.getCksumtype()
@@ -199,28 +196,15 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
throw new KrbException(KrbErrorCode.KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED, errorMessage);
}
- BigInteger p = dhParameter.getP();
- BigInteger g = dhParameter.getG();
-
SubjectPublicKeyInfo publicKeyInfo = authPack.getClientPublicValue();
byte[] clientSubjectPubKey = publicKeyInfo.getSubjectPubKey().getValue();
Asn1Integer clientPubKey = KrbCodec.decode(clientSubjectPubKey, Asn1Integer.class);
BigInteger y = clientPubKey.getValue();
- DHPublicKeySpec dhPublicKeySpec = new DHPublicKeySpec(y, p, g);
+ BigInteger p = dhParameter.getP();
+ BigInteger g = dhParameter.getG();
- KeyFactory keyFactory = null;
- try {
- keyFactory = KeyFactory.getInstance("DH");
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- DHPublicKey dhPublicKey = null;
- try {
- dhPublicKey = (DHPublicKey) keyFactory.generatePublic(dhPublicKeySpec);
- } catch (InvalidKeySpecException e) {
- e.printStackTrace();
- }
+ DHPublicKey dhPublicKey = PkinitCrypto.createDHPublicKey(p, g, y);
DhServer server = new DhServer();
DHPublicKey serverPubKey = null;
@@ -229,11 +213,14 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
} catch (Exception e) {
e.printStackTrace();
}
- server.generateKey(null, null);
+ EncryptionKey secretKey = server.generateKey(null, null, kdcRequest.getEncryptionType());
+
+ // Set the DH shared key as the client key
+ kdcRequest.setClientKey(secretKey);
String identity = pkinitContext.identityOpts.identity;
- PaPkAsRep paPkAsRep = makePaPkAsRep(serverPubKey, identity);
+ PaPkAsRep paPkAsRep = makePaPkAsRep(pkinitContext.cryptoctx, serverPubKey, identity);
PaDataEntry paDataEntry = makeEntry(paPkAsRep);
kdcRequest.getPreauthContext().getOutputPaData().add(paDataEntry);
@@ -260,11 +247,13 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
PaDataEntry paDataEntry = new PaDataEntry();
paDataEntry.setPaDataType(PaDataType.PK_AS_REP);
- paDataEntry.setPaDataValue(paPkAsRep.encode());
+ //TODO CHOICE
+ paDataEntry.setPaDataValue(paPkAsRep.getDHRepInfo().encode());
return paDataEntry;
}
- private PaPkAsRep makePaPkAsRep(DHPublicKey severPubKey, String identityString) {
+ private PaPkAsRep makePaPkAsRep(PkinitPlgCryptoContext cryptoContext,
+ DHPublicKey severPubKey, String identityString) {
List<String> identityList = Arrays.asList(identityString.split(","));
@@ -297,9 +286,7 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
}
PaPkAsRep paPkAsRep = new PaPkAsRep();
-
DHRepInfo dhRepInfo = new DHRepInfo();
-
KdcDHKeyInfo kdcDhKeyInfo = new KdcDHKeyInfo();
Asn1Integer publickey = new Asn1Integer(severPubKey.getY());
@@ -308,9 +295,12 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
kdcDhKeyInfo.setDHKeyExpiration(
new KerberosTime(System.currentTimeMillis() + KerberosTime.DAY));
+
ByteArrayOutputStream signedData = null;
try {
- signedData = cmsSignedDataCreate(kdcDhKeyInfo, certificates);
+ signedData = PkinitCrypto.cmsSignedDataCreate(kdcDhKeyInfo.encode(),
+ cryptoContext.getIdPkinitDHKeyDataOID(),
+ certificates.toArray(new X509Certificate[certificates.size()]));
} catch (IOException e) {
e.printStackTrace();
}
@@ -323,28 +313,6 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
return paPkAsRep;
}
-
- public static ContentInfo createContentInfo(byte[] data, ObjectIdentifier oid) {
-
- ContentInfo contentInfo = new ContentInfo(
- oid,
- new DerValue(DerValue.tag_OctetString, data));
- return contentInfo;
- }
-
- public static ByteArrayOutputStream cmsSignedDataCreate(KdcDHKeyInfo kdcDHKeyInfo,
- List<X509Certificate> certificates) throws IOException {
-
- ObjectIdentifier oid = new ObjectIdentifier(ID_PKINIT_DHKEYDATA);
- ContentInfo contentInfo = createContentInfo(kdcDHKeyInfo.encode(), oid);
-
- PKCS7 p7 = new PKCS7(new AlgorithmId[0], contentInfo,
- certificates.toArray(new X509Certificate[certificates.size()]), new SignerInfo[0]);
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- p7.encodeSignedData(bytes);
- return bytes;
- }
-
public boolean checkClockskew(KdcRequest kdcRequest, KerberosTime time) throws KrbException {
long clockSkew = kdcRequest.getKdcContext().getConfig().getAllowableClockSkew() * 1000;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/AsRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/AsRequest.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/AsRequest.java
index 6ccd774..69f43af 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/AsRequest.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/AsRequest.java
@@ -32,6 +32,7 @@ import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
import org.apache.kerby.kerberos.kerb.spec.base.LastReq;
import org.apache.kerby.kerberos.kerb.spec.base.LastReqEntry;
import org.apache.kerby.kerberos.kerb.spec.base.LastReqType;
+import org.apache.kerby.kerberos.kerb.spec.base.NameType;
import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
import org.apache.kerby.kerberos.kerb.spec.kdc.AsRep;
import org.apache.kerby.kerberos.kerb.spec.kdc.AsReq;
@@ -80,6 +81,9 @@ public class AsRequest extends KdcRequest {
} else {
clientEntry = getEntry(clientPrincipal.getName());
}
+ if(isAnonymous()) {
+ clientEntry.setPrincipal(new PrincipalName(clientPrincipal.getName(), NameType.NT_WELLKNOWN));
+ }
if (clientEntry == null) {
LOG.warn("Can't get the client entry.");
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/KdcRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/KdcRequest.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/KdcRequest.java
index 2a014b1..ef5ee33 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/KdcRequest.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/KdcRequest.java
@@ -93,9 +93,11 @@ public abstract class KdcRequest {
private PrincipalName serverPrincipal;
private byte[] innerBodyout;
private AuthToken token;
- private Boolean isToken = false;
- private Boolean isPkinit = false;
+ private boolean isToken = false;
+ private boolean isPkinit = false;
+ private boolean isAnonymous = false;
private EncryptionKey sessionKey;
+ private byte[] bodybytes;
/**
* Get session key.
@@ -164,6 +166,7 @@ public abstract class KdcRequest {
checkVersion();
checkTgsEntry();
kdcFindFast();
+ authenticate();
if (PreauthHandler.isToken(getKdcReq().getPaData())) {
isToken = true;
preauth();
@@ -177,7 +180,6 @@ public abstract class KdcRequest {
checkServer();
preauth();
}
- authenticate();
issueTicket();
makeReply();
}
@@ -543,7 +545,7 @@ public abstract class KdcRequest {
PaData preAuthData = request.getPaData();
if (isPreauthRequired()) {
- if (getKdcOptions().isFlagSet(KdcOption.REQUEST_ANONYMOUS) && !isPkinit) {
+ if (isAnonymous && !isPkinit) {
LOG.info("Need PKINIT.");
KrbError krbError = makePreAuthenticationError(kdcContext, request,
KrbErrorCode.KDC_ERR_PREAUTH_REQUIRED, true);
@@ -805,7 +807,19 @@ public abstract class KdcRequest {
return isPkinit;
}
+ protected boolean isAnonymous() {
+ return getKdcOptions().isFlagSet(KdcOption.REQUEST_ANONYMOUS);
+ }
+
public KdcOptions getKdcOptions() {
return kdcReq.getReqBody().getKdcOptions();
}
+
+ public void setReqBodyBytes(byte[] bodyBytes) {
+ this.bodybytes = bodyBytes;
+ }
+
+ public byte[] getReqBodyBytes() {
+ return this.bodybytes;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/TicketIssuer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/TicketIssuer.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/TicketIssuer.java
index 7021c27..88db09d 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/TicketIssuer.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/request/TicketIssuer.java
@@ -31,6 +31,7 @@ import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
import org.apache.kerby.kerberos.kerb.spec.base.HostAddresses;
import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
+import org.apache.kerby.kerberos.kerb.spec.base.NameType;
import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
import org.apache.kerby.kerberos.kerb.spec.base.TransitedEncoding;
import org.apache.kerby.kerberos.kerb.spec.base.TransitedEncodingType;
@@ -218,7 +219,11 @@ public abstract class TicketIssuer {
if (kdcRequest.isToken()) {
return new PrincipalName(kdcRequest.getToken().getSubject());
} else {
- return getKdcReq().getReqBody().getCname();
+ PrincipalName principalName = getKdcReq().getReqBody().getCname();
+ if(getKdcRequest().isAnonymous()) {
+ principalName.setNameType(NameType.NT_WELLKNOWN);
+ }
+ return principalName;
}
}
[2/2] directory-kerby git commit: Add some code of the anonymous
pkinit.
Posted by pl...@apache.org.
Add some code of the anonymous pkinit.
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/b9485672
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/b9485672
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/b9485672
Branch: refs/heads/pkinit-support
Commit: b9485672c822d1aca8cea2b86fda64dc00130969
Parents: bdca839
Author: plusplusjiajia <ji...@intel.com>
Authored: Fri Nov 27 16:12:46 2015 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Fri Nov 27 16:12:46 2015 +0800
----------------------------------------------------------------------
.../kerby/kerberos/kdc/WithCertKdcTest.java | 4 +-
kerby-kerb/kerb-client/pom.xml | 5 +
.../kerby/kerberos/kerb/client/KrbConfig.java | 9 +-
.../kerberos/kerb/client/KrbConfigKey.java | 3 +-
.../client/impl/AbstractInternalKrbClient.java | 2 +-
.../preauth/pkinit/ClientConfiguration.java | 2 +
.../kerb/client/preauth/pkinit/DhClient.java | 128 -----------
.../kerb/client/preauth/pkinit/DhGroup.java | 138 ------------
.../kerb/client/preauth/pkinit/DhServer.java | 134 -----------
.../client/preauth/pkinit/OctetString2Key.java | 93 --------
.../client/preauth/pkinit/PkinitPreauth.java | 55 +++--
.../preauth/pkinit/ServerConfiguration.java | 1 +
.../kerberos/kerb/client/request/AsRequest.java | 2 +-
.../kerb/client/request/AsRequestWithCert.java | 90 ++++++--
.../kerb/client/request/KdcRequest.java | 11 +
.../kerberos/kerb/client/TestKrbConfigLoad.java | 1 +
.../kerb/client/preauth/pkinit/DhGroupTest.java | 52 -----
.../preauth/pkinit/DhKeyAgreementTest.java | 167 --------------
.../preauth/pkinit/OctetString2KeyTest.java | 225 -------------------
.../kerb-client/src/test/resources/krb5.conf | 1 +
.../kerberos/kerb/common/EncryptionUtil.java | 8 +-
.../kerby/kerberos/kerb/common/KrbUtil.java | 2 +-
.../kerb/preauth/pkinit/PkinitCrypto.java | 91 +++++++-
.../preauth/pkinit/PkinitPlgCryptoContext.java | 6 +-
.../kerby/kerberos/kerb/codec/CodecTest.java | 39 +++-
.../kerby/kerberos/kerb/spec/base/NameType.java | 2 +-
.../kerb/spec/pa/pkinit/KdcDHKeyInfo.java | 12 +-
.../kerberos/kerb/spec/ticket/TgtTicket.java | 4 +-
.../kerby/kerberos/kerb/crypto/dh/DhClient.java | 128 +++++++++++
.../kerby/kerberos/kerb/crypto/dh/DhGroup.java | 138 ++++++++++++
.../kerby/kerberos/kerb/crypto/dh/DhServer.java | 126 +++++++++++
.../kerb/crypto/dh/OctetString2Key.java | 91 ++++++++
.../kerberos/kerb/crypto/dh/DhGroupTest.java | 53 +++++
.../kerb/crypto/dh/DhKeyAgreementTest.java | 172 ++++++++++++++
.../kerb/crypto/dh/OctetString2KeyTest.java | 225 +++++++++++++++++++
kerby-kerb/kerb-server/pom.xml | 5 +
.../kerberos/kerb/server/Asn1InputBuffer.java | 129 +++++++++++
.../kerby/kerberos/kerb/server/KdcHandler.java | 30 +++
.../kerb/server/preauth/pkinit/DhServer.java | 133 -----------
.../server/preauth/pkinit/OctetString2Key.java | 93 --------
.../server/preauth/pkinit/PkinitPreauth.java | 84 +++----
.../kerberos/kerb/server/request/AsRequest.java | 4 +
.../kerb/server/request/KdcRequest.java | 22 +-
.../kerb/server/request/TicketIssuer.java | 7 +-
44 files changed, 1440 insertions(+), 1287 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
index 201e736..9b5dc5e 100644
--- a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
+++ b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
@@ -99,11 +99,11 @@ public class WithCertKdcTest extends KdcTestBase {
assertThat(te.getMessage().contains("timeout")).isTrue();
return;
}
- assertThat(tgt).isNull();
+ assertThat(tgt).isNotNull();
serverPrincipal = getServerPrincipal();
ServiceTicket tkt = getKrbClient().requestServiceTicketWithTgt(tgt, serverPrincipal);
- assertThat(tkt).isNull();
+ assertThat(tkt).isNotNull();
}
//@Test
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/pom.xml b/kerby-kerb/kerb-client/pom.xml
index 5bbc680..45dfb93 100644
--- a/kerby-kerb/kerb-client/pom.xml
+++ b/kerby-kerb/kerb-client/pom.xml
@@ -51,5 +51,10 @@
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.52</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>not-yet-commons-ssl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfig.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfig.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfig.java
index f9767c9..415d64d 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfig.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfig.java
@@ -299,12 +299,17 @@ public class KrbConfig extends Krb5Conf {
}
public List<String> getPkinitAnchors() {
- return Arrays.asList(getString(
+ return Arrays.asList(getStringArray(
KrbConfigKey.PKINIT_ANCHORS, true, LIBDEFAULT));
}
public List<String> getPkinitIdentities() {
- return Arrays.asList(getString(
+ return Arrays.asList(getStringArray(
KrbConfigKey.PKINIT_IDENTITIES, true, LIBDEFAULT));
}
+
+ public String getPkinitKdcHostName() {
+ return getString(
+ KrbConfigKey.PKINIT_KDC_HOSTNAME, true, LIBDEFAULT);
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfigKey.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfigKey.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfigKey.java
index 3f7e3ed..4d5aa1d 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfigKey.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbConfigKey.java
@@ -59,7 +59,8 @@ public enum KrbConfigKey implements ConfigKey {
+ "camellia128-cts-cmac des-cbc-crc des-cbc-md5 des-cbc-md4"),
PKINIT_ANCHORS(null),
- PKINIT_IDENTITIES(null);
+ PKINIT_IDENTITIES(null),
+ PKINIT_KDC_HOSTNAME();
private Object defaultValue;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
index 09a8632..02f9690 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
@@ -101,7 +101,7 @@ public abstract class AbstractInternalKrbClient implements InternalKrbClient {
principal = fixPrincipal(principal);
PrincipalName principalName = new PrincipalName(principal);
if (requestOptions.contains(KrbOption.USE_PKINIT_ANONYMOUS)) {
- principalName.setNameType(NameType.KRB5_NT_WELLKNOWN);
+ principalName.setNameType(NameType.NT_WELLKNOWN);
}
asRequest.setClientPrincipal(principalName);
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ClientConfiguration.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ClientConfiguration.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ClientConfiguration.java
index 6734728..70e748c 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ClientConfiguration.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ClientConfiguration.java
@@ -20,6 +20,8 @@
package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhGroup;
+
import javax.crypto.spec.DHParameterSpec;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhClient.java
deleted file mode 100644
index 834da2f..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhClient.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.client.preauth.pkinit;
-
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.SecretKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-
-
-/**
- * The client-side of Diffie-Hellman key agreement for Kerberos PKINIT.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-class DhClient {
- private static AlgorithmParameterSpec aesIv = new IvParameterSpec(new byte[16]);
-
- private KeyAgreement clientKeyAgree;
- private SecretKey clientAesKey;
-
-
- DHPublicKey init(DHParameterSpec dhParamSpec) throws Exception {
- // The client creates its own DH key pair, using the DH parameters from above.
- KeyPairGenerator clientKpairGen = KeyPairGenerator.getInstance("DH");
- clientKpairGen.initialize(dhParamSpec);
- KeyPair clientKpair = clientKpairGen.generateKeyPair();
-
- // The client creates and initializes its DH KeyAgreement object.
- clientKeyAgree = KeyAgreement.getInstance("DH");
- clientKeyAgree.init(clientKpair.getPrivate());
-
- // The client encodes its public key, and sends it over to the server.
-// return clientKpair.getPublic().getEncoded();
- return (DHPublicKey) clientKpair.getPublic();
- }
-
-
- void doPhase(byte[] serverPubKeyEnc) throws Exception {
- /*
- * The client uses the server's public key for the first (and only) phase
- * of its version of the DH protocol. Before it can do so, it has to
- * instantiate a DH public key from the server's encoded key material.
- */
- KeyFactory clientKeyFac = KeyFactory.getInstance("DH");
- X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(serverPubKeyEnc);
- PublicKey serverPubKey = clientKeyFac.generatePublic(x509KeySpec);
-
- clientKeyAgree.doPhase(serverPubKey, true);
- }
-
-
- byte[] generateKey(byte[] clientDhNonce, byte[] serverDhNonce) {
- // ZZ length will be same as public key.
- byte[] dhSharedSecret = clientKeyAgree.generateSecret();
- byte[] x = dhSharedSecret;
-
- if (clientDhNonce != null && clientDhNonce.length > 0
- && serverDhNonce != null && serverDhNonce.length > 0) {
- x = concatenateBytes(dhSharedSecret, clientDhNonce);
- x = concatenateBytes(x, serverDhNonce);
- }
-
- byte[] secret = OctetString2Key.kTruncate(dhSharedSecret.length, x);
- clientAesKey = new SecretKeySpec(secret, 0, 16, "AES");
-
- return clientAesKey.getEncoded();
- }
-
-
- /**
- * Decrypt using AES in CTS mode.
- *
- * @param cipherText
- * @return
- * @throws Exception
- */
- byte[] decryptAes(byte[] cipherText) throws Exception {
- // Use the secret key to encrypt/decrypt data.
- Cipher serverCipher = Cipher.getInstance("AES/CTS/NoPadding");
- serverCipher.init(Cipher.DECRYPT_MODE, clientAesKey, aesIv);
-
- return serverCipher.doFinal(cipherText);
- }
-
-
- byte[] concatenateBytes(byte[] array1, byte[] array2) {
- byte[] concatenatedBytes = new byte[array1.length + array2.length];
-
- for (int i = 0; i < array1.length; i++) {
- concatenatedBytes[i] = array1[i];
- }
-
- for (int j = array1.length; j < concatenatedBytes.length; j++) {
- concatenatedBytes[j] = array2[j - array1.length];
- }
-
- return concatenatedBytes;
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroup.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroup.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroup.java
deleted file mode 100644
index cf3a0df..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroup.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.client.preauth.pkinit;
-
-
-import javax.crypto.spec.DHParameterSpec;
-import java.math.BigInteger;
-
-
-/**
- * "When using the Diffie-Hellman key agreement method, implementations MUST
- * support Oakley 1024-bit Modular Exponential (MODP) well-known group 2
- * [RFC2412] and Oakley 2048-bit MODP well-known group 14 [RFC3526] and
- * SHOULD support Oakley 4096-bit MODP well-known group 16 [RFC3526]."
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class DhGroup {
- /**
- * From:
- * The OAKLEY Key Determination Protocol
- * http://www.ietf.org/rfc/rfc2412.txt
- * <p/>
- * Well-Known Group 2: A 1024 bit prime
- * This group is assigned id 2 (two).
- * The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
- * The generator is 2 (decimal)
- */
- public static final DHParameterSpec MODP_GROUP2;
-
- static {
- StringBuffer sb = new StringBuffer();
- sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
- sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
- sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
- sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
- sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381");
- sb.append("FFFFFFFFFFFFFFFF");
-
- BigInteger prime = new BigInteger(sb.toString(), 16);
- BigInteger generator = BigInteger.valueOf(2);
-
- MODP_GROUP2 = new DHParameterSpec(prime, generator);
- }
-
- /**
- * From:
- * More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)
- * http://www.ietf.org/rfc/rfc3526.txt
- * <p/>
- * 2048-bit MODP Group
- * This group is assigned id 14.
- * This prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
- * The generator is: 2.
- */
- public static final DHParameterSpec MODP_GROUP14;
-
- static {
- StringBuffer sb = new StringBuffer();
- sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
- sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
- sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
- sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
- sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D");
- sb.append("C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F");
- sb.append("83655D23DCA3AD961C62F356208552BB9ED529077096966D");
- sb.append("670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B");
- sb.append("E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9");
- sb.append("DE2BCBF6955817183995497CEA956AE515D2261898FA0510");
- sb.append("15728E5A8AACAA68FFFFFFFFFFFFFFFF");
-
- BigInteger prime = new BigInteger(sb.toString(), 16);
- BigInteger generator = BigInteger.valueOf(2);
-
- MODP_GROUP14 = new DHParameterSpec(prime, generator);
- }
-
- /**
- * From:
- * More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)
- * http://www.ietf.org/rfc/rfc3526.txt
- * <p/>
- * 4096-bit MODP Group
- * This group is assigned id 16.
- * This prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
- * The generator is: 2.
- */
- public static final DHParameterSpec MODP_GROUP16;
-
- static {
- StringBuffer sb = new StringBuffer();
- sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
- sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
- sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
- sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
- sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D");
- sb.append("C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F");
- sb.append("83655D23DCA3AD961C62F356208552BB9ED529077096966D");
- sb.append("670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B");
- sb.append("E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9");
- sb.append("DE2BCBF6955817183995497CEA956AE515D2261898FA0510");
- sb.append("15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64");
- sb.append("ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7");
- sb.append("ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B");
- sb.append("F12FFA06D98A0864D87602733EC86A64521F2B18177B200C");
- sb.append("BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31");
- sb.append("43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7");
- sb.append("88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA");
- sb.append("2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6");
- sb.append("287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED");
- sb.append("1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9");
- sb.append("93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199");
- sb.append("FFFFFFFFFFFFFFFF");
-
- BigInteger prime = new BigInteger(sb.toString(), 16);
- BigInteger generator = BigInteger.valueOf(2);
-
- MODP_GROUP16 = new DHParameterSpec(prime, generator);
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhServer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhServer.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhServer.java
deleted file mode 100644
index 60084ea..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhServer.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.client.preauth.pkinit;
-
-
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.SecretKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-
-/**
- * The server-side of Diffie-Hellman key agreement for Kerberos PKINIT.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-class DhServer {
- private static AlgorithmParameterSpec aesIv = new IvParameterSpec(new byte[16]);
-
- private KeyAgreement serverKeyAgree;
- private SecretKey serverAesKey;
-
-
- PublicKey initAndDoPhase(byte[] clientPubKeyEnc) throws Exception {
- /*
- * The server has received the client's public key in encoded format. The
- * server instantiates a DH public key from the encoded key material.
- */
- KeyFactory serverKeyFac = KeyFactory.getInstance("DH");
- X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(clientPubKeyEnc);
- PublicKey clientPubKey = serverKeyFac.generatePublic(x509KeySpec);
-
- /*
- * The server gets the DH parameters associated with the client's public
- * key. The server must use the same parameters when it generates its own key pair.
- */
- DHParameterSpec dhParamSpec = ((DHPublicKey) clientPubKey).getParams();
-
- // The server creates its own DH key pair.
- KeyPairGenerator serverKpairGen = KeyPairGenerator.getInstance("DH");
- serverKpairGen.initialize(dhParamSpec);
- KeyPair serverKpair = serverKpairGen.generateKeyPair();
-
- // The server creates and initializes its DH KeyAgreement object.
- serverKeyAgree = KeyAgreement.getInstance("DH");
- serverKeyAgree.init(serverKpair.getPrivate());
-
- /*
- * The server uses the client's public key for the only phase of its
- * side of the DH protocol.
- */
- serverKeyAgree.doPhase(clientPubKey, true);
-
- // The server encodes its public key, and sends it over to the client.
- return serverKpair.getPublic();
- }
-
-
- byte[] generateKey(byte[] clientDhNonce, byte[] serverDhNonce) {
- // ZZ length will be same as public key.
- byte[] dhSharedSecret = serverKeyAgree.generateSecret();
- byte[] x = dhSharedSecret;
-
- if (clientDhNonce != null && clientDhNonce.length > 0
- && serverDhNonce != null && serverDhNonce.length > 0) {
- x = concatenateBytes(dhSharedSecret, clientDhNonce);
- x = concatenateBytes(x, serverDhNonce);
- }
-
- byte[] secret = OctetString2Key.kTruncate(dhSharedSecret.length, x);
- serverAesKey = new SecretKeySpec(secret, 0, 16, "AES");
-
- return serverAesKey.getEncoded();
- }
-
-
- /**
- * Encrypt using AES in CTS mode.
- *
- * @param clearText
- * @return The cipher text.
- * @throws Exception
- */
- byte[] encryptAes(byte[] clearText) throws Exception {
- // Use the secret key to encrypt/decrypt data.
- Cipher serverCipher = Cipher.getInstance("AES/CTS/NoPadding");
- serverCipher.init(Cipher.ENCRYPT_MODE, serverAesKey, aesIv);
-
- return serverCipher.doFinal(clearText);
- }
-
-
- byte[] concatenateBytes(byte[] array1, byte[] array2) {
- byte[] concatenatedBytes = new byte[array1.length + array2.length];
-
- for (int i = 0; i < array1.length; i++) {
- concatenatedBytes[i] = array1[i];
- }
-
- for (int j = array1.length; j < concatenatedBytes.length; j++) {
- concatenatedBytes[j] = array2[j - array1.length];
- }
-
- return concatenatedBytes;
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2Key.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2Key.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2Key.java
deleted file mode 100644
index c9ff804..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2Key.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.client.preauth.pkinit;
-
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-
-/**
- * From RFC 4556:
- * <p/>
- * Define the function octetstring2key() as follows:
- * <p/>
- * octetstring2key(x) == random-to-key(K-truncate(
- * SHA1(0x00 | x) |
- * SHA1(0x01 | x) |
- * SHA1(0x02 | x) |
- * ...
- * ))
- * <p/>
- * where x is an octet string; | is the concatenation operator; 0x00,
- * 0x01, 0x02, etc. are each represented as a single octet; random-
- * to-key() is an operation that generates a protocol key from a
- * bitstring of length K; and K-truncate truncates its input to the
- * first K bits. Both K and random-to-key() are as defined in the
- * kcrypto profile [RFC3961] for the enctype of the AS reply key.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class OctetString2Key {
- /**
- * Performs the function K-truncate to generate the AS reply key k.
- *
- * @param k
- * @param x
- * @return The AS reply key value.
- */
- public static byte[] kTruncate(int k, byte[] x) {
- int numberOfBytes = k / 8;
- byte[] result = new byte[numberOfBytes];
-
- int count = 0;
- byte[] filler = calculateIntegrity((byte) count, x);
-
- int position = 0;
-
- for (int i = 0; i < numberOfBytes; i++) {
- if (position < filler.length) {
- result[i] = filler[position];
- position++;
- } else {
- count++;
- filler = calculateIntegrity((byte) count, x);
- position = 0;
- result[i] = filler[position];
- position++;
- }
- }
-
- return result;
- }
-
-
- private static byte[] calculateIntegrity(byte count, byte[] data) {
- try {
- MessageDigest digester = MessageDigest.getInstance("SHA1");
- digester.update(count);
-
- return digester.digest(data);
- } catch (NoSuchAlgorithmException nsae) {
- return new byte[0];
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
index fa362f4..ae8ff74 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
@@ -28,10 +28,13 @@ import org.apache.kerby.kerberos.kerb.client.KrbOption;
import org.apache.kerby.kerberos.kerb.client.preauth.AbstractPreauthPlugin;
import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
import org.apache.kerby.kerberos.kerb.common.CheckSumUtil;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhClient;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhGroup;
import org.apache.kerby.kerberos.kerb.preauth.PaFlag;
import org.apache.kerby.kerberos.kerb.preauth.PaFlags;
import org.apache.kerby.kerberos.kerb.preauth.PluginRequestContext;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.CertificateHelper;
+import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitCrypto;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitIdenity;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitPreauthMeta;
import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
@@ -61,6 +64,8 @@ import java.io.InputStream;
import java.math.BigInteger;
import java.security.cert.X509Certificate;
import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
import java.util.List;
public class PkinitPreauth extends AbstractPreauthPlugin {
@@ -149,10 +154,33 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
PluginRequestContext requestContext,
PaData outPadata) throws KrbException {
+
+
+ /* XXX PKINIT RFC says that nonce in PKAuthenticator doesn't have be the
+ * same as in the AS_REQ. However, if we pick a different nonce, then we
+ * need to remember that info when AS_REP is returned. Here choose to
+ * reuse the AS_REQ nonce.
+ */
+ int nonce = kdcRequest.getChosenNonce();
+
+ // Get the current time
long now = System.currentTimeMillis();
- PaPkAsReq paPkAsReq = makePaPkAsReq(kdcRequest,
- (PkinitRequestContext) requestContext,
- 1, new KerberosTime(now), 1, null);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(new Date(now));
+ int cusec = calendar.get(Calendar.SECOND);
+ KerberosTime ctime = new KerberosTime(now);
+ CheckSum checkSum = null;
+
+ try {
+ checkSum = CheckSumUtil.makeCheckSum(CheckSumType.NIST_SHA,
+ kdcRequest.getKdcReq().getReqBody().encode());
+ } catch (KrbException e) {
+ e.printStackTrace();
+ }
+
+
+ PaPkAsReq paPkAsReq = makePaPkAsReq(kdcRequest, (PkinitRequestContext) requestContext,
+ cusec, ctime, nonce, checkSum);
outPadata.addElement(makeEntry(paPkAsReq));
}
@@ -196,8 +224,9 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
private PaPkAsReq makePaPkAsReq(KdcRequest kdcRequest,
PkinitRequestContext reqCtx,
- int cusec, KerberosTime ctime, int nonce, byte[] checksum) {
+ int cusec, KerberosTime ctime, int nonce, CheckSum checkSum) {
+ LOG.info("Making the PK_AS_REQ.");
PaPkAsReq paPkAsReq = new PaPkAsReq();
AuthPack authPack = new AuthPack();
PkAuthenticator pkAuthen = new PkAuthenticator();
@@ -208,15 +237,8 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
pkAuthen.setCusec(cusec);
pkAuthen.setCtime(ctime);
pkAuthen.setNonce(nonce);
-
- CheckSum checkSum = null;
- try {
- checkSum = CheckSumUtil.makeCheckSum(CheckSumType.NIST_SHA,
- kdcRequest.getKdcReq().getReqBody().encode());
- } catch (KrbException e) {
- e.printStackTrace();
- }
// pkAuthen.setPaChecksum(checkSum.getChecksum());
+
pkAuthen.setPaChecksum(checkSum.encode());
authPack.setPkAuthenticator(pkAuthen);
@@ -224,7 +246,8 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
// authPack.setsupportedCmsTypes(pkinitContext.pluginOpts.createSupportedCMSTypes());
if (!usingRsa) {
- System.out.println(); // DH case
+ // DH case
+ LOG.info("DH key transport algorithm.");
AlgorithmIdentifier dhAlg = new AlgorithmIdentifier();
@@ -253,6 +276,8 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
e.printStackTrace();
}
+ kdcRequest.setDhClient(client);
+
DHParameterSpec spec = clientPubKey.getParams();
BigInteger q = spec.getP().shiftRight(1);
DHParameter dhParameter = new DHParameter();
@@ -307,9 +332,11 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
e.printStackTrace();
}
+ X509Certificate[] certificates = {certificate};
byte[] signedDataBytes = new byte[0];
try {
- signedDataBytes = SignedDataEngine.cmsSignedDataCreate(authPack, certificate).toByteArray();
+ signedDataBytes = PkinitCrypto.cmsSignedDataCreate(authPack.encode(),
+ pkinitContext.cryptoctx.getIdPkinitAuthDataOID(), certificates).toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ServerConfiguration.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ServerConfiguration.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ServerConfiguration.java
index ce15e93..5b1b58c 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ServerConfiguration.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/ServerConfiguration.java
@@ -19,6 +19,7 @@
*/
package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhGroup;
import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
import javax.crypto.spec.DHParameterSpec;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequest.java
index a38333f..e31ba8d 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequest.java
@@ -140,7 +140,7 @@ public class AsRequest extends KdcRequest {
public TgtTicket getTicket() {
TgtTicket tgtTicket = new TgtTicket(getKdcRep().getTicket(),
- (EncAsRepPart) getKdcRep().getEncPart(), getKdcRep().getCname().getName());
+ (EncAsRepPart) getKdcRep().getEncPart(), getKdcRep().getCname());
return tgtTicket;
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
index 4b7525b..71c0a15 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
@@ -20,10 +20,16 @@
package org.apache.kerby.kerberos.kerb.client.request;
import org.apache.kerby.KOptions;
+import org.apache.kerby.asn1.type.Asn1Integer;
import org.apache.kerby.kerberos.kerb.KrbCodec;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.client.KrbContext;
import org.apache.kerby.kerberos.kerb.client.KrbOption;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhClient;
+import org.apache.kerby.kerberos.kerb.preauth.pkinit.CMSMessageType;
+import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitCrypto;
+import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitPlgCryptoContext;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
import org.apache.kerby.kerberos.kerb.spec.kdc.AsReq;
import org.apache.kerby.kerberos.kerb.spec.kdc.KdcOption;
import org.apache.kerby.kerberos.kerb.spec.kdc.KdcRep;
@@ -31,10 +37,23 @@ import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReqBody;
import org.apache.kerby.kerberos.kerb.spec.pa.PaData;
import org.apache.kerby.kerberos.kerb.spec.pa.PaDataEntry;
import org.apache.kerby.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.DHNonce;
+import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.DHRepInfo;
+import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.KdcDHKeyInfo;
import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.PaPkAsRep;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.security.pkcs.ContentInfo;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.ParsingException;
+
+import javax.crypto.interfaces.DHPublicKey;
+import java.io.IOException;
+import java.math.BigInteger;
public class AsRequestWithCert extends AsRequest {
+ private static final Logger LOG = LoggerFactory.getLogger(AsRequestWithCert.class);
public static final String ANONYMOUS_PRINCIPAL = "ANONYMOUS@WELLKNOWN:ANONYMOUS";
public AsRequestWithCert(KrbContext context) {
@@ -46,7 +65,7 @@ public class AsRequestWithCert extends AsRequest {
@Override
public void process() throws KrbException {
- KdcReqBody body = makeReqBody();
+ KdcReqBody body = getReqBody();
AsReq asReq = new AsReq();
asReq.setReqBody(body);
setKdcReq(asReq);
@@ -76,25 +95,68 @@ public class AsRequestWithCert extends AsRequest {
PaData paData = kdcRep.getPaData();
for (PaDataEntry paEntry : paData.getElements()) {
+ // Parse PA-PK-AS-REP message.
if (paEntry.getPaDataType() == PaDataType.PK_AS_REP) {
+ LOG.info("processing PK_AS_REP");
PaPkAsRep paPkAsRep = KrbCodec.decode(paEntry.getPaDataValue(), PaPkAsRep.class);
- byte[] a = paPkAsRep.getEncKeyPack();
-// DHRepInfo dhRepInfo =paPkAsRep.getDHRepInfo();
-// DHNonce nonce = dhRepInfo.getServerDhNonce();
-// byte[] dhSignedData = dhRepInfo.getDHSignedData();
-// PKCS7 pkcs7 = null;
-// try {
-// pkcs7 = new PKCS7(dhSignedData);
-// } catch (ParsingException e) {
-// e.printStackTrace();
-// }
-// pkcs7.getContentInfo();
-
+ DHRepInfo dhRepInfo =paPkAsRep.getDHRepInfo();
+
+ DHNonce nonce = dhRepInfo.getServerDhNonce();
+ byte[] dhSignedData = dhRepInfo.getDHSignedData();
+ PKCS7 pkcs7 = null;
+ try {
+ pkcs7 = PkinitCrypto.verifyCMSSignedData(
+ CMSMessageType.CMS_SIGN_SERVER, dhSignedData);
+ } catch (IOException e) {
+ LOG.error("failed to verify pkcs7 signed data\n");
+ }
+
+ if (!PkinitCrypto.verifyKdcSan(getContext().getConfig().getPkinitKdcHostName(),
+ pkcs7.getCertificates())) {
+ LOG.error("Did not find an acceptable SAN in KDC certificate");
+ }
+
+
+ ContentInfo contentInfo = pkcs7.getContentInfo();
+
+ LOG.info("as_rep: DH key transport algorithm");
+ KdcDHKeyInfo kdcDHKeyInfo;
+ try {
+ kdcDHKeyInfo = KrbCodec.decode(contentInfo.getContentBytes(), KdcDHKeyInfo.class);
+ } catch (IOException e) {
+ String errMessage = "failed to decode AuthPack " + e.getMessage();
+ LOG.error(errMessage);
+ throw new KrbException(errMessage);
+ }
+
+ byte[] subjectPublicKey = kdcDHKeyInfo.getSubjectPublicKey().getValue();
+
+ Asn1Integer clientPubKey = KrbCodec.decode(subjectPublicKey, Asn1Integer.class);
+ BigInteger y = clientPubKey.getValue();
+
+ DhClient client = getDhClient();
+ BigInteger p = client.getDhParam().getP();
+ BigInteger g = client.getDhParam().getG();
+
+ DHPublicKey dhPublicKey = PkinitCrypto.createDHPublicKey(p, g, y);
+
+ EncryptionKey secretKey = null;
+ try {
+ client.doPhase(dhPublicKey.getEncoded());
+ secretKey = client.generateKey(null, null, getEncType());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ // Set the DH shared key as the client key
+ if(secretKey == null) {
+ throw new KrbException("Fail to create client key.");
+ } else {
+ setClientKey(secretKey);
+ }
}
}
-
super.processResponse(kdcRep);
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
index 33f701f..f37ef3e 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
@@ -29,6 +29,7 @@ import org.apache.kerby.kerberos.kerb.client.preauth.PreauthContext;
import org.apache.kerby.kerberos.kerb.client.preauth.PreauthHandler;
import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerby.kerberos.kerb.crypto.dh.DhClient;
import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
import org.apache.kerby.kerberos.kerb.spec.base.EncryptedData;
import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
@@ -75,6 +76,8 @@ public abstract class KdcRequest {
private boolean isRetrying;
+ private DhClient dhClient;
+
public KdcRequest(KrbContext context) {
this.context = context;
this.isRetrying = false;
@@ -409,4 +412,12 @@ public abstract class KdcRequest {
}
}
}
+
+ public void setDhClient(DhClient client) {
+ this.dhClient = client;
+ }
+
+ public DhClient getDhClient() {
+ return this.dhClient;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/TestKrbConfigLoad.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/TestKrbConfigLoad.java b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/TestKrbConfigLoad.java
index f47fde5..3f65f81 100644
--- a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/TestKrbConfigLoad.java
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/TestKrbConfigLoad.java
@@ -60,5 +60,6 @@ public class TestKrbConfigLoad {
.contains(EncryptionType.DES_CBC_CRC);
assertThat(krbConfig.getPkinitAnchors()).hasSize(1);
assertThat(krbConfig.getPkinitIdentities()).hasSize(2);
+ assertThat(krbConfig.getPkinitKdcHostName()).isEqualTo("kdc-server.example.com");
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java
deleted file mode 100644
index ba44390..0000000
--- a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.client.preauth.pkinit;
-
-import junit.framework.TestCase;
-
-/**
- * "When using the Diffie-Hellman key agreement method, implementations MUST
- * support Oakley 1024-bit Modular Exponential (MODP) well-known group 2
- * [RFC2412] and Oakley 2048-bit MODP well-known group 14 [RFC3526] and
- * SHOULD support Oakley 4096-bit MODP well-known group 16 [RFC3526]."
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class DhGroupTest extends TestCase {
- /**
- * Tests that the translation of the hex representation of the prime modulus
- * resulted in the expected bit length.
- */
- public void testPrimeBitLengths() {
- assertEquals(1024, DhGroup.MODP_GROUP2.getP().bitLength());
- assertEquals(2048, DhGroup.MODP_GROUP14.getP().bitLength());
- assertEquals(4096, DhGroup.MODP_GROUP16.getP().bitLength());
- }
-
- /**
- * Tests the generator values.
- */
- public void testGeneratorValues() {
- assertEquals(2, DhGroup.MODP_GROUP2.getG().intValue());
- assertEquals(2, DhGroup.MODP_GROUP14.getG().intValue());
- assertEquals(2, DhGroup.MODP_GROUP16.getG().intValue());
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java
deleted file mode 100644
index 54b2b5b..0000000
--- a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.client.preauth.pkinit;
-
-
-import junit.framework.TestCase;
-
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-
-/**
- * Tests the Diffie-Hellman key agreement protocol between a client and server.
- * <p/>
- * Generating a Secret Key Using the Diffie-Hellman Key Agreement Algorithm
- * <p/>
- * Two parties use a key agreement protocol to generate identical secret keys for
- * encryption without ever having to transmit the secret key. The protocol works
- * by both parties agreeing on a set of values (a prime, a base, and a private
- * value) which are used to generate a key pair.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class DhKeyAgreementTest extends TestCase {
- private static SecureRandom secureRandom = new SecureRandom();
-
- /**
- * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
- * well-known group 2 [RFC2412].
- *
- * @throws Exception
- */
- public void testPreGeneratedDhParams() throws Exception {
- DhClient client = new DhClient();
- DhServer server = new DhServer();
-
- byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2).getEncoded();
- byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc).getEncoded();
-
- server.generateKey(null, null);
-
- client.doPhase(serverPubKeyEnc);
-
- client.generateKey(null, null);
-
- byte[] clearText = "This is just an example".getBytes();
-
- byte[] cipherText = server.encryptAes(clearText);
- byte[] recovered = client.decryptAes(cipherText);
-
- assertTrue(Arrays.equals(clearText, recovered));
- }
-
-
- /**
- * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
- * well-known group 2 [RFC2412], including the optional DH nonce.
- * <p/>
- * "This nonce string MUST be as long as the longest key length of the symmetric
- * key types that the client supports. This nonce MUST be chosen randomly."
- *
- * @throws Exception
- */
- public void testPreGeneratedDhParamsWithNonce() throws Exception {
- byte[] clientDhNonce = new byte[16];
- secureRandom.nextBytes(clientDhNonce);
-
- byte[] serverDhNonce = new byte[16];
- secureRandom.nextBytes(serverDhNonce);
-
- DhClient client = new DhClient();
- DhServer server = new DhServer();
-
- byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2).getEncoded();
- byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc).getEncoded();
-
- server.generateKey(clientDhNonce, serverDhNonce);
-
- client.doPhase(serverPubKeyEnc);
-
- client.generateKey(clientDhNonce, serverDhNonce);
-
- byte[] clearText = "This is just an example".getBytes();
-
- byte[] cipherText = server.encryptAes(clearText);
- byte[] recovered = client.decryptAes(cipherText);
-
- assertTrue(Arrays.equals(clearText, recovered));
- }
-
-
- /**
- * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
- * well-known group 2 [RFC2412].
- *
- * @throws Exception
- */
- public void testGeneratedDhParams() throws Exception {
- DhClient client = new DhClient();
- DhServer server = new DhServer();
-
- DHPublicKey clientPubKey = client.init(DhGroup.MODP_GROUP14);
- DHParameterSpec spec = clientPubKey.getParams();
-
- BigInteger y = clientPubKey.getY();
- BigInteger p = spec.getP();
- BigInteger g = spec.getG();
- DHPublicKeySpec dhPublicKeySpec = new DHPublicKeySpec(y, p, g);
-
- KeyFactory keyFactory = null;
- try {
- keyFactory = KeyFactory.getInstance("DH");
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- DHPublicKey dhPublicKey = null;
- try {
- dhPublicKey = (DHPublicKey) keyFactory.generatePublic(dhPublicKeySpec);
- } catch (InvalidKeySpecException e) {
- e.printStackTrace();
- }
-
- byte[] serverPubKeyEnc = null;
- try {
- serverPubKeyEnc = server.initAndDoPhase(dhPublicKey.getEncoded()).getEncoded();
- } catch (Exception e) {
- e.printStackTrace();
- }
- server.generateKey(null, null);
-
- client.doPhase(serverPubKeyEnc);
-
- client.generateKey(null, null);
-
- byte[] clearText = "This is just an example".getBytes();
-
- byte[] cipherText = server.encryptAes(clearText);
- byte[] recovered = client.decryptAes(cipherText);
-
- assertTrue(Arrays.equals(clearText, recovered));
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java
deleted file mode 100644
index 783dae1..0000000
--- a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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.client.preauth.pkinit;
-
-
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-
-
-/**
- * From RFC 4556:
- * <p/>
- * "Appendix B. Test Vectors
- * <p/>
- * Function octetstring2key() is defined in Section 3.2.3.1. This section describes
- * a few sets of test vectors that would be useful for implementers of octetstring2key()."
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class OctetString2KeyTest extends TestCase {
- /**
- * Set 1:
- * =====
- * Input octet string x is:
- * <p/>
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * <p/>
- * Output of K-truncate() when the key size is 32 octets:
- * <p/>
- * 5e e5 0d 67 5c 80 9f e5 9e 4a 77 62 c5 4b 65 83
- * 75 47 ea fb 15 9b d8 cd c7 5f fc a5 91 1e 4c 41
- */
- public void testSet1() {
- byte[] inputOctetString = new byte[16 * 16];
-
- byte[] expectedOutput =
- {(byte) 0x5e, (byte) 0xe5, (byte) 0x0d, (byte) 0x67, (byte) 0x5c, (byte) 0x80, (byte) 0x9f,
- (byte) 0xe5, (byte) 0x9e, (byte) 0x4a, (byte) 0x77, (byte) 0x62, (byte) 0xc5,
- (byte) 0x4b, (byte) 0x65, (byte) 0x83, (byte) 0x75, (byte) 0x47, (byte) 0xea,
- (byte) 0xfb, (byte) 0x15, (byte) 0x9b, (byte) 0xd8, (byte) 0xcd, (byte) 0xc7,
- (byte) 0x5f, (byte) 0xfc, (byte) 0xa5, (byte) 0x91, (byte) 0x1e, (byte) 0x4c, (byte) 0x41};
-
- int keySize = 32 * 8;
-
- byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
-
- assertTrue(Arrays.equals(result, expectedOutput));
- }
-
-
- /**
- * Set 2:
- * =====
- * Input octet string x is:
- * <p/>
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * <p/>
- * Output of K-truncate() when the key size is 32 octets:
- * <p/>
- * ac f7 70 7c 08 97 3d df db 27 cd 36 14 42 cc fb
- * a3 55 c8 88 4c b4 72 f3 7d a6 36 d0 7d 56 78 7e
- */
- public void testSet2() {
- byte[] inputOctetString = new byte[16 * 8];
-
- byte[] expectedOutput =
- {(byte) 0xac, (byte) 0xf7, (byte) 0x70, (byte) 0x7c, (byte) 0x08, (byte) 0x97, (byte) 0x3d,
- (byte) 0xdf, (byte) 0xdb, (byte) 0x27, (byte) 0xcd, (byte) 0x36, (byte) 0x14,
- (byte) 0x42, (byte) 0xcc, (byte) 0xfb, (byte) 0xa3, (byte) 0x55, (byte) 0xc8,
- (byte) 0x88, (byte) 0x4c, (byte) 0xb4, (byte) 0x72, (byte) 0xf3, (byte) 0x7d,
- (byte) 0xa6, (byte) 0x36, (byte) 0xd0, (byte) 0x7d, (byte) 0x56, (byte) 0x78, (byte) 0x7e};
-
- int keySize = 32 * 8;
-
- byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
-
- assertTrue(Arrays.equals(result, expectedOutput));
- }
-
-
- /**
- * Set 3:
- * ======
- * Input octet string x is:
- * <p/>
- * 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
- * 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
- * 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
- * 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c
- * 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b
- * 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a
- * 0b 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09
- * 0a 0b 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08
- * <p/>
- * Output of K-truncate() when the key size is 32 octets:
- * <p/>
- * c4 42 da 58 5f cb 80 e4 3b 47 94 6f 25 40 93 e3
- * 73 29 d9 90 01 38 0d b7 83 71 db 3a cf 5c 79 7e
- */
- public void testSet3() {
- byte[] inputOctetString =
- {(byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
- (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
- (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01,
- (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
- (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
- (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02,
- (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
- (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
- (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
- (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
- (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
- (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
- (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a,
- (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10,
- (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
- (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b,
- (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00,
- (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
- (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
- (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01,
- (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
-
- byte[] expectedOutput =
- {(byte) 0xc4, (byte) 0x42, (byte) 0xda, (byte) 0x58, (byte) 0x5f, (byte) 0xcb, (byte) 0x80,
- (byte) 0xe4, (byte) 0x3b, (byte) 0x47, (byte) 0x94, (byte) 0x6f, (byte) 0x25,
- (byte) 0x40, (byte) 0x93, (byte) 0xe3, (byte) 0x73, (byte) 0x29, (byte) 0xd9,
- (byte) 0x90, (byte) 0x01, (byte) 0x38, (byte) 0x0d, (byte) 0xb7, (byte) 0x83,
- (byte) 0x71, (byte) 0xdb, (byte) 0x3a, (byte) 0xcf, (byte) 0x5c, (byte) 0x79, (byte) 0x7e};
-
- int keySize = 32 * 8;
-
- byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
-
- assertTrue(Arrays.equals(result, expectedOutput));
- }
-
-
- /**
- * Set 4:
- * =====
- * Input octet string x is:
- * <p/>
- * 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
- * 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
- * 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
- * 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c
- * 0d 0e 0f 10 00 01 02 03 04 05 06 07 08
- * <p/>
- * Output of K-truncate() when the key size is 32 octets:
- * <p/>
- * 00 53 95 3b 84 c8 96 f4 eb 38 5c 3f 2e 75 1c 4a
- * 59 0e d6 ff ad ca 6f f6 4f 47 eb eb 8d 78 0f fc
- */
- public void testSet4() {
- byte[] inputOctetString =
- {(byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
- (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
- (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01,
- (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
- (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
- (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02,
- (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
- (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
- (byte) 0x0f, (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
- (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
- (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
- (byte) 0x10, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
- (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
-
- byte[] expectedOutput =
- {(byte) 0x00, (byte) 0x53, (byte) 0x95, (byte) 0x3b, (byte) 0x84, (byte) 0xc8, (byte) 0x96,
- (byte) 0xf4, (byte) 0xeb, (byte) 0x38, (byte) 0x5c, (byte) 0x3f, (byte) 0x2e,
- (byte) 0x75, (byte) 0x1c, (byte) 0x4a, (byte) 0x59, (byte) 0x0e, (byte) 0xd6,
- (byte) 0xff, (byte) 0xad, (byte) 0xca, (byte) 0x6f, (byte) 0xf6, (byte) 0x4f,
- (byte) 0x47, (byte) 0xeb, (byte) 0xeb, (byte) 0x8d, (byte) 0x78, (byte) 0x0f, (byte) 0xfc};
-
- int keySize = 32 * 8;
-
- byte[] result = OctetString2Key.kTruncate(keySize, inputOctetString);
-
- assertTrue(Arrays.equals(result, expectedOutput));
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-client/src/test/resources/krb5.conf
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/resources/krb5.conf b/kerby-kerb/kerb-client/src/test/resources/krb5.conf
index 85bc0b0..42dde30 100644
--- a/kerby-kerb/kerb-client/src/test/resources/krb5.conf
+++ b/kerby-kerb/kerb-client/src/test/resources/krb5.conf
@@ -32,6 +32,7 @@
default_tkt_enctypes = des-cbc-crc
pkinit_anchors = FILE:/etc/krb5/cacert.pem
pkinit_identities = FILE:/etc/krb5/client.pem,/etc/krb5/clientkey.pem
+ pkinit_kdc_hostname = kdc-server.example.com
[realms]
ATHENA.MIT.EDU = {
admin_server = KERBEROS.MIT.EDU
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
index 332c96f..07893e3 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
@@ -138,16 +138,16 @@ public class EncryptionUtil {
}
public static byte[] encrypt(EncryptionKey key,
- byte[] plaintext, int usage) throws KrbException {
+ byte[] plaintext, KeyUsage usage) throws KrbException {
EncTypeHandler encType = EncryptionHandler.getEncHandler(key.getKeyType());
- byte[] cipherData = encType.encrypt(plaintext, key.getKeyData(), usage);
+ byte[] cipherData = encType.encrypt(plaintext, key.getKeyData(), usage.getIntValue());
return cipherData;
}
public static byte[] decrypt(EncryptionKey key,
- byte[] cipherData, int usage) throws KrbException {
+ byte[] cipherData, KeyUsage usage) throws KrbException {
EncTypeHandler encType = EncryptionHandler.getEncHandler(key.getKeyType());
- byte[] plainData = encType.decrypt(cipherData, key.getKeyData(), usage);
+ byte[] plainData = encType.decrypt(cipherData, key.getKeyData(), usage.getIntValue());
return plainData;
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
index ab4b8ac..b0690b2 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
@@ -70,7 +70,7 @@ public class KrbUtil {
public static PrincipalName makeAnonymousPrincipal() {
PrincipalName principalName = new PrincipalName(KRB5_WELLKNOWN_NAMESTR + "/" + KRB5_ANONYMOUS_PRINCSTR);
principalName.setRealm(KRB5_ANONYMOUS_REALMSTR);
- principalName.setNameType(NameType.NT_PRINCIPAL);
+ principalName.setNameType(NameType.NT_WELLKNOWN);
return principalName;
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
index c74a4de..b682e87 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
@@ -18,21 +18,36 @@
*/
package org.apache.kerby.kerberos.kerb.preauth.pkinit;
+import org.apache.commons.ssl.Certificates;
import org.apache.kerby.kerberos.kerb.KrbErrorCode;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.spec.cms.DHParameter;
+import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.KdcDHKeyInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.ParsingException;
+import sun.security.pkcs.SignerInfo;
+import sun.security.util.DerValue;
import sun.security.util.ObjectIdentifier;
+import sun.security.x509.AlgorithmId;
+import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.util.List;
public class PkinitCrypto {
@@ -56,11 +71,11 @@ public class PkinitCrypto {
return keyPairGenerator.generateKeyPair();
}
- public static PKCS7 verifyCMSSignedData(PkinitPlgCryptoContext cryptoctx, CMSMessageType cmsMsgType,
+ public static PKCS7 verifyCMSSignedData(CMSMessageType cmsMsgType,
byte[] signedData)
throws IOException, KrbException {
- ObjectIdentifier oid = pkinitPKCS7Type2OID(cryptoctx, cmsMsgType);
+ ObjectIdentifier oid = pkinitPKCS7Type2OID(cmsMsgType);
if (oid == null) {
throw new KrbException("Can't get the right oid ");
}
@@ -98,18 +113,16 @@ public class PkinitCrypto {
}
}
-
- public static ObjectIdentifier pkinitPKCS7Type2OID(PkinitPlgCryptoContext cryptoctx,
- CMSMessageType cmsMsgType) throws IOException {
+ public static ObjectIdentifier pkinitPKCS7Type2OID(CMSMessageType cmsMsgType) throws IOException {
switch (cmsMsgType) {
case UNKNOWN:
return null;
case CMS_SIGN_CLIENT:
- return cryptoctx.getIdPkinitAuthDataOID();
+ return PkinitPlgCryptoContext.getIdPkinitAuthDataOID();
case CMS_SIGN_SERVER:
- return cryptoctx.getIdPkinitDHKeyDataOID();
+ return PkinitPlgCryptoContext.getIdPkinitDHKeyDataOID();
case CMS_ENVEL_SERVER:
- return cryptoctx.getIdPkinitRkeyDataOID();
+ return PkinitPlgCryptoContext.getIdPkinitRkeyDataOID();
default:
return null;
}
@@ -167,4 +180,66 @@ public class PkinitCrypto {
return true;
}
+ public static DHPublicKey createDHPublicKey(BigInteger p, BigInteger g, BigInteger y) {
+ DHPublicKeySpec dhPublicKeySpec = new DHPublicKeySpec(y, p, g);
+
+ KeyFactory keyFactory = null;
+ try {
+ keyFactory = KeyFactory.getInstance("DH");
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ DHPublicKey dhPublicKey = null;
+ try {
+ dhPublicKey = (DHPublicKey) keyFactory.generatePublic(dhPublicKeySpec);
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ }
+ return dhPublicKey;
+ }
+
+ public static ByteArrayOutputStream cmsSignedDataCreate(byte[] data, ObjectIdentifier oid,
+ X509Certificate[] certificates) throws IOException {
+
+ ContentInfo contentInfo = createContentInfo(data, oid);
+
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0], contentInfo, certificates, new SignerInfo[0]);
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ p7.encodeSignedData(bytes);
+ return bytes;
+ }
+
+ public static ContentInfo createContentInfo(byte[] data, ObjectIdentifier oid) {
+
+ ContentInfo contentInfo = new ContentInfo(
+ oid,
+ new DerValue(DerValue.tag_OctetString, data));
+ return contentInfo;
+ }
+
+ public static boolean verifyKdcSan(String hostname, X509Certificate[] cert) {
+
+ if(hostname == null) {
+ LOG.info("No pkinit_kdc_hostname values found in config file");
+ } else {
+ LOG.info("pkinit_kdc_hostname values found in config file");
+ }
+
+ cryptoRetrieveCertSans(cert);
+ return true;
+ }
+
+ public static void cryptoRetrieveCertSans(X509Certificate[] cert) {
+ cryptoRetrieveX509Sans(cert);
+ }
+
+ public static void cryptoRetrieveX509Sans(X509Certificate[] cert) {
+
+ if(cert == null) {
+ LOG.info("no certificate!");
+ }
+
+ LOG.info("Looking for SANs in cert");
+ String[] subjectAlts = Certificates.getDNSSubjectAlts(cert[0]);
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitPlgCryptoContext.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitPlgCryptoContext.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitPlgCryptoContext.java
index f70d081..12d68b2 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitPlgCryptoContext.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitPlgCryptoContext.java
@@ -127,15 +127,15 @@ public class PkinitPlgCryptoContext {
}
- public ObjectIdentifier getIdPkinitAuthDataOID() throws IOException {
+ public static ObjectIdentifier getIdPkinitAuthDataOID() throws IOException {
return new ObjectIdentifier(ID_PKINIT_AUTHDATA);
}
- public ObjectIdentifier getIdPkinitDHKeyDataOID() throws IOException {
+ public static ObjectIdentifier getIdPkinitDHKeyDataOID() throws IOException {
return new ObjectIdentifier(ID_PKINIT_DHKEYDATA);
}
- public ObjectIdentifier getIdPkinitRkeyDataOID() throws IOException {
+ public static ObjectIdentifier getIdPkinitRkeyDataOID() throws IOException {
return new ObjectIdentifier(ID_PKINIT_RKEYDATA);
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-core-test/src/test/java/org/apache/kerby/kerberos/kerb/codec/CodecTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core-test/src/test/java/org/apache/kerby/kerberos/kerb/codec/CodecTest.java b/kerby-kerb/kerb-core-test/src/test/java/org/apache/kerby/kerberos/kerb/codec/CodecTest.java
index da6c7ce..d3b214a 100644
--- a/kerby-kerb/kerb-core-test/src/test/java/org/apache/kerby/kerberos/kerb/codec/CodecTest.java
+++ b/kerby-kerb/kerb-core-test/src/test/java/org/apache/kerby/kerberos/kerb/codec/CodecTest.java
@@ -19,18 +19,34 @@
*/
package org.apache.kerby.kerberos.kerb.codec;
+import org.apache.kerby.asn1.Asn1Dump;
+import org.apache.kerby.asn1.Asn1InputBuffer;
+import org.apache.kerby.asn1.LimitedByteBuffer;
+import org.apache.kerby.asn1.type.Asn1Item;
+import org.apache.kerby.asn1.type.Asn1Type;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.KrbCodec;
+import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
import org.apache.kerby.kerberos.kerb.spec.base.CheckSum;
import org.apache.kerby.kerberos.kerb.spec.base.CheckSumType;
+import org.apache.kerby.kerberos.kerb.spec.base.KrbMessageType;
+import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+import org.apache.kerby.kerberos.kerb.spec.kdc.AsReq;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReqBody;
+import org.apache.kerby.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerby.kerberos.kerb.spec.pa.PaDataType;
import org.junit.Test;
+import sun.security.krb5.internal.KDCReq;
+
+import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
public class CodecTest {
@Test
- public void testCodec() throws KrbException {
+ public void testCodec() throws KrbException, IOException {
CheckSum mcs = new CheckSum();
mcs.setCksumtype(CheckSumType.CRC32);
mcs.setChecksum(new byte[] {0x10});
@@ -42,4 +58,25 @@ public class CodecTest {
assertThat(restored.getCksumtype()).isEqualTo(mcs.getCksumtype());
assertThat(mcs.getChecksum()).isEqualTo(restored.getChecksum());
}
+
+ @Test
+ public void testDecode() throws IOException {
+ AsReq expected = new AsReq();
+
+ KdcReqBody body = new KdcReqBody();
+
+ expected.setReqBody(body);
+
+ Asn1InputBuffer ib = new Asn1InputBuffer(expected.encode());
+ Asn1Type fd1 = ib.read();
+ Asn1Type fd2 = ib.read();
+ Asn1Type fd3 = ib.read();
+ Asn1Type fd4 = ib.read();
+ Asn1Type fd5 = ib.read();
+ Asn1Type fd6 = ib.read();
+ Asn1Type fd7 = ib.read();
+ Asn1Type fd8 = ib.read();
+ Asn1Type fd9 = ib.read();
+
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/NameType.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/NameType.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/NameType.java
index 04a8648..c855603 100644
--- a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/NameType.java
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/NameType.java
@@ -28,7 +28,7 @@ public enum NameType implements Asn1EnumType {
NT_SRV_HST(3),
NT_SRV_XHST(4),
NT_UID(5),
- KRB5_NT_WELLKNOWN(11);
+ NT_WELLKNOWN(11);
private int value;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/pa/pkinit/KdcDHKeyInfo.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/pa/pkinit/KdcDHKeyInfo.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/pa/pkinit/KdcDHKeyInfo.java
index d21217d..ed01f43 100644
--- a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/pa/pkinit/KdcDHKeyInfo.java
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/pa/pkinit/KdcDHKeyInfo.java
@@ -33,12 +33,12 @@ import org.apache.kerby.kerberos.kerb.spec.KrbSequenceType;
}
*/
public class KdcDHKeyInfo extends KrbSequenceType {
- private static final int SUBJECT_PUBLICK_KEY = 0;
+ private static final int SUBJECT_PUBLIC_KEY = 0;
private static final int NONCE = 1;
private static final int DH_KEY_EXPIRATION = 2;
static Asn1FieldInfo[] fieldInfos = new Asn1FieldInfo[] {
- new Asn1FieldInfo(SUBJECT_PUBLICK_KEY, Asn1BitString.class),
+ new Asn1FieldInfo(SUBJECT_PUBLIC_KEY, Asn1BitString.class),
new Asn1FieldInfo(NONCE, Asn1Integer.class),
new Asn1FieldInfo(DH_KEY_EXPIRATION, KerberosTime.class)
};
@@ -47,12 +47,12 @@ public class KdcDHKeyInfo extends KrbSequenceType {
super(fieldInfos);
}
- public byte[] getSubjectPublicKey() {
- return getFieldAsOctets(SUBJECT_PUBLICK_KEY);
+ public Asn1BitString getSubjectPublicKey() {
+ return getFieldAs(SUBJECT_PUBLIC_KEY, Asn1BitString.class);
}
- public void setSubjectPublicKey(byte[] subjectPublicKey) {
- setFieldAsOctets(SUBJECT_PUBLICK_KEY, subjectPublicKey);
+ public void setSubjectPublicKey(byte[] subjectPubKey) {
+ setFieldAs(SUBJECT_PUBLIC_KEY, new Asn1BitString(subjectPubKey));
}
public int getNonce() {
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b9485672/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/ticket/TgtTicket.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/ticket/TgtTicket.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/ticket/TgtTicket.java
index 0a119aa..4cc97b0 100644
--- a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/ticket/TgtTicket.java
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/ticket/TgtTicket.java
@@ -25,9 +25,9 @@ import org.apache.kerby.kerberos.kerb.spec.kdc.EncAsRepPart;
public class TgtTicket extends KrbTicket {
private PrincipalName clientPrincipal;
- public TgtTicket(Ticket ticket, EncAsRepPart encKdcRepPart, String clientPrincipal) {
+ public TgtTicket(Ticket ticket, EncAsRepPart encKdcRepPart, PrincipalName clientPrincipal) {
super(ticket, encKdcRepPart);
- this.clientPrincipal = new PrincipalName(clientPrincipal);
+ this.clientPrincipal = clientPrincipal;
}
public PrincipalName getClientPrincipal() {