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/24 08:48:51 UTC
[1/2] directory-kerby git commit: Add some implemention of pkinit
anonymous.
Repository: directory-kerby
Updated Branches:
refs/heads/pkinit-support f6d5088bc -> 146967182
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 9672883..1120665 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
@@ -27,7 +27,8 @@ public enum NameType implements KrbEnum {
NT_SRV_INST(2),
NT_SRV_HST(3),
NT_SRV_XHST(4),
- NT_UID(5);
+ NT_UID(5),
+ KRB5_NT_WELLKNOWN(11);
private int value;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/AlgorithmIdentifier.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/AlgorithmIdentifier.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/AlgorithmIdentifier.java
index ed7a736..6f5d1b2 100644
--- a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/AlgorithmIdentifier.java
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/AlgorithmIdentifier.java
@@ -20,11 +20,9 @@
package org.apache.kerby.kerberos.kerb.spec.cms;
-import org.apache.kerby.asn1.type.Asn1Any;
import org.apache.kerby.asn1.type.Asn1FieldInfo;
import org.apache.kerby.asn1.type.Asn1ObjectIdentifier;
import org.apache.kerby.asn1.type.Asn1SequenceType;
-import org.apache.kerby.asn1.type.Asn1Type;
/**
AlgorithmIdentifier ::= SEQUENCE {
@@ -38,7 +36,7 @@ public class AlgorithmIdentifier extends Asn1SequenceType {
static Asn1FieldInfo[] fieldInfos = new Asn1FieldInfo[] {
new Asn1FieldInfo(ALGORITHM, -1, Asn1ObjectIdentifier.class),
- new Asn1FieldInfo(PARAMETERS, -1, Asn1Any.class)
+ new Asn1FieldInfo(PARAMETERS, -1, DHParameter.class)
};
public AlgorithmIdentifier() {
@@ -53,11 +51,11 @@ public class AlgorithmIdentifier extends Asn1SequenceType {
setFieldAs(ALGORITHM, algorithm);
}
- public Asn1Type getParameters() {
- return getFieldAsAny(PARAMETERS);
+ public DHParameter getParameters() {
+ return getFieldAs(PARAMETERS, DHParameter.class);
}
- public void setParameters(Asn1Type parameters) {
+ public void setParameters(DHParameter parameters) {
setFieldAsAny(PARAMETERS, parameters);
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/DHParameter.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/DHParameter.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/DHParameter.java
new file mode 100644
index 0000000..6e4f81d
--- /dev/null
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/DHParameter.java
@@ -0,0 +1,51 @@
+package org.apache.kerby.kerberos.kerb.spec.cms;
+
+import org.apache.kerby.asn1.type.Asn1FieldInfo;
+import org.apache.kerby.asn1.type.Asn1Integer;
+import org.apache.kerby.asn1.type.Asn1SequenceType;
+
+import java.math.BigInteger;
+
+public class DHParameter extends Asn1SequenceType {
+
+ private static final int P = 0;
+ private static final int G = 1;
+ private static final int Q = 2;
+
+ static Asn1FieldInfo[] fieldInfos = new Asn1FieldInfo[] {
+ new Asn1FieldInfo(P, -1, Asn1Integer.class),
+ new Asn1FieldInfo(G, -1, Asn1Integer.class),
+ new Asn1FieldInfo(Q, -1, Asn1Integer.class),
+ };
+
+ public DHParameter() {
+ super(fieldInfos);
+ }
+
+ public void setP(BigInteger p) {
+ setFieldAsBigInteger(P, p);
+ }
+
+ public BigInteger getP() {
+ Asn1Integer p = getFieldAs(P, Asn1Integer.class);
+ return p.getValue();
+ }
+
+ public void setG(BigInteger g) {
+ setFieldAsBigInteger(G, g);
+ }
+
+ public BigInteger getG() {
+ Asn1Integer g = getFieldAs(G, Asn1Integer.class);
+ return g.getValue();
+ }
+
+ public void setQ(BigInteger q) {
+ setFieldAsBigInteger(Q, q);
+ }
+
+ public BigInteger getQ() {
+ Asn1Integer q = getFieldAs(Q, Asn1Integer.class);
+ return q.getValue();
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/SubjectPublicKeyInfo.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/SubjectPublicKeyInfo.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/SubjectPublicKeyInfo.java
index e6e4392..d273da7 100644
--- a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/SubjectPublicKeyInfo.java
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/cms/SubjectPublicKeyInfo.java
@@ -50,8 +50,8 @@ public class SubjectPublicKeyInfo extends Asn1SequenceType {
setFieldAs(ALGORITHM, algorithm);
}
- public byte[] getSubjectPubKey() {
- return getFieldAsOctets(SUBJECT_PUBLIC_KEY);
+ public Asn1BitString getSubjectPubKey() {
+ return getFieldAs(SUBJECT_PUBLIC_KEY, Asn1BitString.class);
}
public void setSubjectPubKey(byte[] subjectPubKey) {
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 0e9504e..d21217d 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
@@ -62,4 +62,12 @@ public class KdcDHKeyInfo extends KrbSequenceType {
public void setNonce(int nonce) {
setFieldAsInt(NONCE, nonce);
}
+
+ public KerberosTime getDHKeyExpiration() {
+ return getFieldAsTime(DH_KEY_EXPIRATION);
+ }
+
+ public void setDHKeyExpiration(KerberosTime time) {
+ setFieldAs(DH_KEY_EXPIRATION, time);
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
index 82b8dfd..8d1565e 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
@@ -174,4 +174,14 @@ public class KdcConfig extends Conf {
public List<String> getIssuers() {
return Arrays.asList(KrbConfHelper.getStringArrayUnderSection(this, KdcConfigKey.ISSUERS));
}
+
+ public List<String> getPkinitAnchors() {
+ return Arrays.asList(KrbConfHelper.getStringArrayUnderSection(this,
+ KdcConfigKey.PKINIT_ANCHORS));
+ }
+
+ public String getPkinitIdentity() {
+ return KrbConfHelper.getStringUnderSection(this,
+ KdcConfigKey.PKINIT_IDENTITY);
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
index 178d19d..5e7d8a4 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
@@ -51,7 +51,9 @@ public enum KdcConfigKey implements SectionConfigKey {
KDC_MAX_DGRAM_REPLY_SIZE(4096, "kdcdefaults"),
VERIFY_KEY(null, "kdcdefaults"),
DECRYPTION_KEY(null, "kdcdefaults"),
- ISSUERS(null, "kdcdefaults");
+ ISSUERS(null, "kdcdefaults"),
+ PKINIT_IDENTITY(null, "libdefaults"),
+ PKINIT_ANCHORS(null, "libdefaults");
private Object defaultValue;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthContext.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthContext.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthContext.java
index 551e1b3..51e14e2 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthContext.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthContext.java
@@ -19,15 +19,19 @@
*/
package org.apache.kerby.kerberos.kerb.server.preauth;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.spec.pa.PaData;
+
import java.util.ArrayList;
import java.util.List;
public class PreauthContext {
private boolean preauthRequired = true;
private List<PreauthHandle> handles = new ArrayList<PreauthHandle>(5);
+ private PaData outputPaData;
public PreauthContext() {
-
+ this.outputPaData = new PaData();
}
public boolean isPreauthRequired() {
@@ -41,4 +45,12 @@ public class PreauthContext {
public List<PreauthHandle> getHandles() {
return handles;
}
+
+ public void reset() {
+ this.outputPaData = new PaData();
+ }
+
+ public PaData getOutputPaData() throws KrbException {
+ return outputPaData;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthHandler.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthHandler.java
index cff6ba6..baa6324 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthHandler.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/PreauthHandler.java
@@ -23,6 +23,7 @@ import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.server.KdcContext;
import org.apache.kerby.kerberos.kerb.server.preauth.builtin.EncTsPreauth;
import org.apache.kerby.kerberos.kerb.server.preauth.builtin.TgtPreauth;
+import org.apache.kerby.kerberos.kerb.server.preauth.pkinit.PkinitPreauth;
import org.apache.kerby.kerberos.kerb.server.preauth.token.TokenPreauth;
import org.apache.kerby.kerberos.kerb.server.request.KdcRequest;
import org.apache.kerby.kerberos.kerb.spec.pa.PaData;
@@ -54,6 +55,9 @@ public class PreauthHandler {
preauth = new TokenPreauth();
preauths.add(preauth);
+
+ preauth = new PkinitPreauth();
+ preauths.add(preauth);
}
/**
@@ -70,6 +74,7 @@ public class PreauthHandler {
PreauthContext preauthContext = new PreauthContext();
KdcContext kdcContext = kdcRequest.getKdcContext();
+ initWith(kdcContext);
preauthContext.setPreauthRequired(kdcContext.getConfig().isPreauthRequired());
for (KdcPreauth preauth : preauths) {
@@ -133,4 +138,13 @@ public class PreauthHandler {
}
return false;
}
+
+ public static boolean isPkinit(PaData paData) {
+ for (PaDataEntry paEntry : paData.getElements()) {
+ if (paEntry.getPaDataType() == PaDataType.PK_AS_REQ) {
+ return true;
+ }
+ }
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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
new file mode 100644
index 0000000..d8bf903
--- /dev/null
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/DhServer.java
@@ -0,0 +1,133 @@
+/*
+ * 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/14696718/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
new file mode 100644
index 0000000..9829642
--- /dev/null
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/OctetString2Key.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.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/14696718/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java
index 9fb9e51..137b64f 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java
@@ -1,30 +1,31 @@
/**
- * 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.
- *
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.kerby.kerberos.kerb.preauth.pkinit.IdentityOpts;
+import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitPlgCryptoContext;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.PluginOpts;
public class PkinitKdcContext {
- public PluginOpts pluginOpts;
- public IdentityOpts identityOpts;
+ public PkinitPlgCryptoContext cryptoctx = new PkinitPlgCryptoContext();
+ public PluginOpts pluginOpts = new PluginOpts();
+ public IdentityOpts identityOpts = new IdentityOpts();
public String realm;
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 08baa0e..54f0693 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
@@ -1,42 +1,86 @@
/**
- * 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.
- *
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.kerby.asn1.type.Asn1Integer;
import org.apache.kerby.kerberos.kerb.KrbCodec;
+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.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.PkinitPreauthMeta;
import org.apache.kerby.kerberos.kerb.server.KdcContext;
import org.apache.kerby.kerberos.kerb.server.preauth.AbstractPreauthPlugin;
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.PrincipalName;
+import org.apache.kerby.kerberos.kerb.spec.cms.DHParameter;
+import org.apache.kerby.kerberos.kerb.spec.cms.SubjectPublicKeyInfo;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcOption;
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.AuthPack;
+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.apache.kerby.kerberos.kerb.spec.pa.pkinit.PaPkAsReq;
+import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.PkAuthenticator;
+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;
+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;
+import java.util.List;
import java.util.Map;
+import java.util.Scanner;
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());
@@ -50,6 +94,10 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
PkinitKdcContext tmp = new PkinitKdcContext();
tmp.realm = kdcContext.getKdcRealm();
+
+ String pkinitIdentity = kdcContext.getConfig().getPkinitIdentity();
+ tmp.identityOpts.identity = pkinitIdentity;
+
pkinitContexts.put(kdcContext.getKdcRealm(), tmp);
}
@@ -66,18 +114,129 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
public boolean verify(KdcRequest kdcRequest, PluginRequestContext requestContext,
PaDataEntry paData) throws KrbException {
+ LOG.info("pkinit verify padata: entered!");
+
PkinitRequestContext reqCtx = (PkinitRequestContext) requestContext;
- PkinitKdcContext pkinitContext = findContext(kdcRequest.getServerPrincipal());
+ PrincipalName serverPrincipal = kdcRequest.getServerEntry().getPrincipal();
+ kdcRequest.setServerPrincipal(serverPrincipal);
+ PkinitKdcContext pkinitContext = findContext(serverPrincipal);
if (pkinitContext == null) {
return false;
}
reqCtx.paType = paData.getPaDataType();
if (paData.getPaDataType() == PaDataType.PK_AS_REQ) {
+
+ LOG.info("processing PK_AS_REQ");
PaPkAsReq paPkAsReq = KrbCodec.decode(paData.getPaDataValue(), PaPkAsReq.class);
- if (paPkAsReq == null) {
- return false;
+
+ byte[] signedAuthPack = paPkAsReq.getSignedAuthPack();
+ PKCS7 pkcs7 = null;
+ try {
+ pkcs7 = PkinitCrypto.verifyCMSSignedData(pkinitContext.cryptoctx,
+ CMSMessageType.CMS_SIGN_CLIENT, signedAuthPack);
+ } catch (IOException e) {
+ e.getMessage();
+ }
+
+ Boolean isSigned = PkinitCrypto.isSigned(pkcs7);
+ if (isSigned) {
+ //TODO
+ LOG.info("Signed data.");
+ } else {
+ PrincipalName clientPrincial = kdcRequest.getClientEntry().getPrincipal();
+ PrincipalName anonymousPrincipal = KrbUtil.makeAnonymousPrincipal();
+
+ /* If anonymous requests are being used, adjust the realm of the client principal. */
+ if (kdcRequest.getKdcOptions().isFlagSet(KdcOption.REQUEST_ANONYMOUS)
+ && !KrbUtil.pricipalCompareIgnoreRealm(clientPrincial, anonymousPrincipal)) {
+ String errMsg = "Pkinit request not signed, but client not anonymous.";
+ LOG.error(errMsg);
+ throw new KrbException(KrbErrorCode.KDC_ERR_PREAUTH_FAILED, errMsg);
+ }
}
+
+ ContentInfo contentInfo = pkcs7.getContentInfo();
+ AuthPack authPack = null;
+ try {
+ authPack = KrbCodec.decode(contentInfo.getContentBytes(), AuthPack.class);
+ } catch (IOException e) {
+ LOG.error("failed to decode AuthPack " + e.getMessage());
+ }
+
+ PkAuthenticator pkAuthenticator = authPack.getPkAuthenticator();
+
+ checkClockskew(kdcRequest, pkAuthenticator.getCtime());
+ DHParameter dhParameter = null;
+ if (authPack.getClientPublicValue() != null) {
+ dhParameter = authPack.getClientPublicValue().getAlgorithm().getParameters();
+ PkinitCrypto.serverCheckDH(pkinitContext.pluginOpts, pkinitContext.cryptoctx, dhParameter);
+ } else if (!isSigned) {
+ /*Anonymous pkinit requires DH*/
+ String errMessage = "Anonymous pkinit without DH public value not supported.";
+ LOG.error(errMessage);
+ throw new KrbException(KrbErrorCode.KDC_ERR_PREAUTH_FAILED, errMessage);
+ }
+
+ CheckSum expectedCheckSum = null;
+ try {
+ expectedCheckSum = CheckSumUtil.makeCheckSum(CheckSumType.NIST_SHA,
+ kdcRequest.getKdcReq().getReqBody().encode());
+ } 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())) {
+ LOG.debug("Received checksum type: " + receivedCheckSum.getCksumtype()
+ + ", received checksum length: " + receivedCheckSum.encodingLength()
+ + ", expected checksum type: " + expectedCheckSum.getCksumtype()
+ + ", expected checksum length: " + expectedCheckSum.encodingLength());
+ String errorMessage = "Failed to match the checksum.";
+ LOG.error(errorMessage);
+ 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);
+
+ 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();
+ }
+
+ DhServer server = new DhServer();
+ DHPublicKey serverPubKey = null;
+ try {
+ serverPubKey = (DHPublicKey) server.initAndDoPhase(dhPublicKey.getEncoded());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ server.generateKey(null, null);
+
+ String identity = pkinitContext.identityOpts.identity;
+
+ PaPkAsRep paPkAsRep = makePaPkAsRep(serverPubKey, identity);
+ PaDataEntry paDataEntry = makeEntry(paPkAsRep);
+
+ kdcRequest.getPreauthContext().getOutputPaData().add(paDataEntry);
}
return true;
@@ -90,4 +249,109 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
}
return null;
}
+
+ /**
+ * Make padata entry.
+ *
+ * @param paPkAsRep The PaPkAsRep
+ * @return PaDataEntry to be made.
+ */
+ private PaDataEntry makeEntry(PaPkAsRep paPkAsRep) throws KrbException {
+
+ PaDataEntry paDataEntry = new PaDataEntry();
+ paDataEntry.setPaDataType(PaDataType.PK_AS_REP);
+ paDataEntry.setPaDataValue(paPkAsRep.encode());
+ return paDataEntry;
+ }
+
+ private PaPkAsRep makePaPkAsRep(DHPublicKey severPubKey, String identityString) {
+
+ List<String> identityList = Arrays.asList(identityString.split(","));
+
+ List<X509Certificate> certificates = new ArrayList<>();
+ for (String identity : identityList) {
+ File file = new File(identity);
+
+ try {
+ Scanner scanner = new Scanner(file);
+ String found = scanner.findInLine("CERTIFICATE");
+
+ if (found != null) {
+ InputStream res = null;
+ try {
+ res = new FileInputStream(identity);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ X509Certificate certificate = null;
+ try {
+ certificate = (X509Certificate) CertificateHelper.loadCerts(res).iterator().next();
+ } catch (KrbException e) {
+ e.printStackTrace();
+ }
+ certificates.add(certificate);
+ }
+ } catch (FileNotFoundException e) {
+ e.getMessage();
+ }
+ }
+
+ PaPkAsRep paPkAsRep = new PaPkAsRep();
+
+ DHRepInfo dhRepInfo = new DHRepInfo();
+
+ KdcDHKeyInfo kdcDhKeyInfo = new KdcDHKeyInfo();
+
+ Asn1Integer publickey = new Asn1Integer(severPubKey.getY());
+ kdcDhKeyInfo.setSubjectPublicKey(publickey.encode());
+ kdcDhKeyInfo.setNonce(1);
+ kdcDhKeyInfo.setDHKeyExpiration(
+ new KerberosTime(System.currentTimeMillis() + KerberosTime.DAY));
+
+ ByteArrayOutputStream signedData = null;
+ try {
+ signedData = cmsSignedDataCreate(kdcDhKeyInfo, certificates);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ dhRepInfo.setDHSignedData(signedData.toByteArray());
+
+ paPkAsRep.setDHRepInfo(dhRepInfo);
+// paPkAsRep.setEncKeyPack("enckey".getBytes());
+
+ 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;
+
+ if (!time.isInClockSkew(clockSkew)) {
+ throw new KrbException(KrbErrorCode.KDC_ERR_PREAUTH_FAILED);
+ } else {
+ return true;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 2765673..6ccd774 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
@@ -129,6 +129,10 @@ public class AsRequest extends KdcRequest {
clientKey, KeyUsage.AS_REP_ENCPART);
reply.setEncryptedEncPart(encryptedData);
+ if (isPkinit()) {
+ reply.setPaData(getPreauthContext().getOutputPaData());
+ }
+
setReply(reply);
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 521ab51..2a014b1 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
@@ -54,6 +54,8 @@ import org.apache.kerby.kerberos.kerb.spec.fast.ArmorType;
import org.apache.kerby.kerberos.kerb.spec.fast.KrbFastArmor;
import org.apache.kerby.kerberos.kerb.spec.fast.KrbFastArmoredReq;
import org.apache.kerby.kerberos.kerb.spec.fast.KrbFastReq;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcOption;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcOptions;
import org.apache.kerby.kerberos.kerb.spec.kdc.KdcRep;
import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
import org.apache.kerby.kerberos.kerb.spec.pa.PaData;
@@ -92,6 +94,7 @@ public abstract class KdcRequest {
private byte[] innerBodyout;
private AuthToken token;
private Boolean isToken = false;
+ private Boolean isPkinit = false;
private EncryptionKey sessionKey;
/**
@@ -167,6 +170,9 @@ public abstract class KdcRequest {
checkClient();
checkServer();
} else {
+ if (PreauthHandler.isPkinit(getKdcReq().getPaData())) {
+ isPkinit = true;
+ }
checkClient();
checkServer();
preauth();
@@ -537,10 +543,17 @@ public abstract class KdcRequest {
PaData preAuthData = request.getPaData();
if (isPreauthRequired()) {
+ if (getKdcOptions().isFlagSet(KdcOption.REQUEST_ANONYMOUS) && !isPkinit) {
+ LOG.info("Need PKINIT.");
+ KrbError krbError = makePreAuthenticationError(kdcContext, request,
+ KrbErrorCode.KDC_ERR_PREAUTH_REQUIRED, true);
+ throw new KdcRecoverableException(krbError);
+ }
+
if (preAuthData == null || preAuthData.isEmpty()) {
LOG.info("The preauth data is empty.");
KrbError krbError = makePreAuthenticationError(kdcContext, request,
- KrbErrorCode.KDC_ERR_PREAUTH_REQUIRED);
+ KrbErrorCode.KDC_ERR_PREAUTH_REQUIRED, false);
throw new KdcRecoverableException(krbError);
} else {
getPreauthHandler().verify(this, preAuthData);
@@ -646,7 +659,7 @@ public abstract class KdcRequest {
* @return The krb error reply to client
*/
protected KrbError makePreAuthenticationError(KdcContext kdcContext, KdcReq request,
- KrbErrorCode errorCode)
+ KrbErrorCode errorCode, boolean pkinit)
throws KrbException {
List<EncryptionType> encryptionTypes = kdcContext.getConfig().getEncryptionTypes();
List<EncryptionType> clientEtypes = request.getReqBody().getEtypes();
@@ -685,6 +698,11 @@ public abstract class KdcRequest {
}
methodData.add(new PaDataEntry(PaDataType.ETYPE_INFO2, encTypeInfo2));
+ if(pkinit) {
+ methodData.add(new PaDataEntry(PaDataType.PK_AS_REQ, "empty".getBytes()));
+ methodData.add(new PaDataEntry(PaDataType.PK_AS_REP, "empty".getBytes()));
+ }
+
KrbError krbError = new KrbError();
krbError.setErrorCode(errorCode);
byte[] encodedData = KrbCodec.encode(methodData);
@@ -782,4 +800,12 @@ public abstract class KdcRequest {
protected AuthToken getToken() {
return token;
}
+
+ protected boolean isPkinit() {
+ return isPkinit;
+ }
+
+ public KdcOptions getKdcOptions() {
+ return kdcReq.getReqBody().getKdcOptions();
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
----------------------------------------------------------------------
diff --git a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
index a89e4f5..5ea108a 100644
--- a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
+++ b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
@@ -116,6 +116,7 @@ public class KinitTool {
if (ktOptions.contains(KinitOption.ANONYMOUS)) {
ktOptions.add(KrbOption.USE_PKINIT_ANONYMOUS);
+ ktOptions.add(KrbOption.PKINIT_X509_ANCHORS);
} else if (!ktOptions.contains(KinitOption.USE_KEYTAB)) {
//If not request tickets by keytab than by password.
ktOptions.add(KinitOption.USE_PASSWD);
[2/2] directory-kerby git commit: Add some implemention of pkinit
anonymous.
Posted by pl...@apache.org.
Add some implemention of pkinit anonymous.
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/14696718
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/14696718
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/14696718
Branch: refs/heads/pkinit-support
Commit: 146967182411d0bce1d48e7ce8499184f8f7fb1c
Parents: f6d5088
Author: plusplusjiajia <ji...@intel.com>
Authored: Tue Nov 24 15:55:04 2015 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Tue Nov 24 15:55:04 2015 +0800
----------------------------------------------------------------------
docs/kerby-checkstyle.xml | 2 +-
.../org/apache/kerby/asn1/UniversalTag.java | 3 +-
.../kerby/asn1/type/Asn1CollectionType.java | 5 +
kerby-dist/kdc-dist/conf/kdc.conf | 4 +-
kerby-dist/tool-dist/conf/krb5.conf | 5 +-
kerby-dist/tool-dist/pom.xml | 5 +
.../kerby/kerberos/kdc/WithCertKdcTest.java | 41 +++
.../kerby/kerberos/kerb/client/KrbClient.java | 4 +-
.../kerby/kerberos/kerb/client/KrbHandler.java | 1 +
.../client/impl/AbstractInternalKrbClient.java | 7 +-
.../kerb/client/preauth/PreauthHandler.java | 3 +-
.../kerb/client/preauth/pkinit/DhClient.java | 6 +-
.../kerb/client/preauth/pkinit/DhServer.java | 4 +-
.../client/preauth/pkinit/PkinitContext.java | 3 +-
.../client/preauth/pkinit/PkinitCrypto.java | 144 ---------
.../client/preauth/pkinit/PkinitPreauth.java | 164 ++++++++--
.../preauth/pkinit/PkinitRequestOpts.java | 2 +-
.../client/preauth/pkinit/SignedDataEngine.java | 95 +++---
.../kerb/client/preauth/pkinit/Util.java | 153 ++++++++++
.../kerberos/kerb/client/request/AsRequest.java | 8 +-
.../kerb/client/request/AsRequestWithCert.java | 49 ++-
.../preauth/pkinit/DhKeyAgreementTest.java | 68 ++++-
.../kerby/kerberos/kerb/common/KrbUtil.java | 63 ++--
.../kerb/preauth/pkinit/CMSMessageType.java | 59 ++++
.../kerb/preauth/pkinit/CertificateHelper.java | 45 +++
.../kerb/preauth/pkinit/PkinitCrypto.java | 170 +++++++++++
.../preauth/pkinit/PkinitPlgCryptoContext.java | 141 +++++++++
.../kerb/preauth/pkinit/PluginOpts.java | 2 +-
.../kerby/kerberos/kerb/spec/base/KrbFlags.java | 4 +-
.../kerby/kerberos/kerb/spec/base/NameType.java | 3 +-
.../kerb/spec/cms/AlgorithmIdentifier.java | 10 +-
.../kerberos/kerb/spec/cms/DHParameter.java | 51 ++++
.../kerb/spec/cms/SubjectPublicKeyInfo.java | 4 +-
.../kerb/spec/pa/pkinit/KdcDHKeyInfo.java | 8 +
.../kerby/kerberos/kerb/server/KdcConfig.java | 10 +
.../kerberos/kerb/server/KdcConfigKey.java | 4 +-
.../kerb/server/preauth/PreauthContext.java | 14 +-
.../kerb/server/preauth/PreauthHandler.java | 14 +
.../kerb/server/preauth/pkinit/DhServer.java | 133 ++++++++
.../server/preauth/pkinit/OctetString2Key.java | 93 ++++++
.../server/preauth/pkinit/PkinitKdcContext.java | 39 +--
.../server/preauth/pkinit/PkinitPreauth.java | 304 +++++++++++++++++--
.../kerberos/kerb/server/request/AsRequest.java | 4 +
.../kerb/server/request/KdcRequest.java | 30 +-
.../kerby/kerberos/tool/kinit/KinitTool.java | 1 +
45 files changed, 1680 insertions(+), 302 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/docs/kerby-checkstyle.xml
----------------------------------------------------------------------
diff --git a/docs/kerby-checkstyle.xml b/docs/kerby-checkstyle.xml
index 3538cd6..6af4748 100644
--- a/docs/kerby-checkstyle.xml
+++ b/docs/kerby-checkstyle.xml
@@ -67,7 +67,7 @@
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
- <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+ <!--module name="IllegalImport"/--> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-asn1/src/main/java/org/apache/kerby/asn1/UniversalTag.java
----------------------------------------------------------------------
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/UniversalTag.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/UniversalTag.java
index 7bc1868..d007dac 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/UniversalTag.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/UniversalTag.java
@@ -26,7 +26,7 @@ package org.apache.kerby.asn1;
*/
public enum UniversalTag {
UNKNOWN (-1),
- CHOICE (-2), // Only for internal using
+ CHOICE (0x20), // Only for internal using
BER_UNDEFINED_LENGTH(0), // Used to encode undefined length with BER
BOOLEAN (0x01),
INTEGER (0x02),
@@ -118,6 +118,7 @@ public enum UniversalTag {
case 0x1D : return CHARACTER_STRING;
case 0x1E : return BMP_STRING;
case 0x1F : return RESERVED_31;
+ case 0x20 : return CHOICE;
default : return UNKNOWN;
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java
----------------------------------------------------------------------
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java
index 194ae8c..f5be6c6 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java
@@ -24,6 +24,7 @@ import org.apache.kerby.asn1.TagClass;
import org.apache.kerby.asn1.TaggingOption;
import java.io.IOException;
+import java.math.BigInteger;
import java.nio.ByteBuffer;
/**
@@ -180,6 +181,10 @@ public abstract class Asn1CollectionType extends AbstractAsn1Type<Asn1Collection
setFieldAs(index, new Asn1Integer(value));
}
+ protected void setFieldAsBigInteger(int index, BigInteger value) {
+ setFieldAs(index, new Asn1Integer(value));
+ }
+
protected Asn1Type getFieldAsAny(int index) {
Asn1Any any = getFieldAs(index, Asn1Any.class);
if (any != null) {
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-dist/kdc-dist/conf/kdc.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/kdc-dist/conf/kdc.conf b/kerby-dist/kdc-dist/conf/kdc.conf
index ac72940..e92345a 100644
--- a/kerby-dist/kdc-dist/conf/kdc.conf
+++ b/kerby-dist/kdc-dist/conf/kdc.conf
@@ -18,6 +18,6 @@
[kdcdefaults]
kdc_host = localhost
- kdc_udp_port = 8014
- kdc_tcp_port = 8015
+ kdc_udp_port = 88
+ kdc_tcp_port = 88
kdc_realm = EXAMPLE.COM
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-dist/tool-dist/conf/krb5.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/tool-dist/conf/krb5.conf b/kerby-dist/tool-dist/conf/krb5.conf
index 698daac..e857b84 100644
--- a/kerby-dist/tool-dist/conf/krb5.conf
+++ b/kerby-dist/tool-dist/conf/krb5.conf
@@ -19,5 +19,6 @@
[libdefaults]
kdc_realm = EXAMPLE.COM
default_realm = EXAMPLE.COM
- kdc_udp_port = 8014
- kdc_tcp_port = 8015
+ kdc_udp_port = 88
+ kdc_tcp_port = 88
+ pkinit_anchors = /etc/krb5/cacert.pem
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-dist/tool-dist/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-dist/tool-dist/pom.xml b/kerby-dist/tool-dist/pom.xml
index 7bf67ce..f8e8ec0 100644
--- a/kerby-dist/tool-dist/pom.xml
+++ b/kerby-dist/tool-dist/pom.xml
@@ -64,6 +64,11 @@
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ <version>1.52</version>
+ </dependency>
</dependencies>
<profiles>
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 7947a63..201e736 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
@@ -22,13 +22,16 @@ package org.apache.kerby.kerberos.kdc;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.KrbRuntime;
import org.apache.kerby.kerberos.kerb.provider.PkiLoader;
+import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
import org.apache.kerby.kerberos.kerb.server.KdcTestBase;
import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
import org.apache.kerby.kerberos.provider.pki.KerbyPkiProvider;
import org.junit.Before;
+import org.junit.Test;
import java.io.InputStream;
+import java.net.URL;
import java.security.PrivateKey;
import java.security.cert.Certificate;
@@ -49,6 +52,7 @@ public class WithCertKdcTest extends KdcTestBase {
private String serverPrincipal;
private Certificate userCert;
private PrivateKey userKey;
+ private Certificate caCert;
@Before
public void setUp() throws Exception {
@@ -59,12 +63,49 @@ public class WithCertKdcTest extends KdcTestBase {
}
@Override
+ protected void configKdcSeverAndClient() {
+ super.configKdcSeverAndClient();
+
+ String pkinitIdentity = getClass().getResource("/kdccert.pem").getPath() + ","
+ + getClass().getResource("/kdckey.pem").getPath();
+ getKdcServer().getKdcConfig().setString(KdcConfigKey.PKINIT_IDENTITY, pkinitIdentity);
+ }
+
+ @Override
protected void setUpClient() throws Exception {
super.setUpClient();
loadCredentials();
}
+ @Override
+ protected void createPrincipals() throws KrbException {
+ super.createPrincipals();
+ //Anonymity support is not enabled by default.
+ //To enable it, you must create the principal WELLKNOWN/ANONYMOUS
+ getKdcServer().createPrincipal("WELLKNOWN/ANONYMOUS");
+ }
+
+ @Test
+ public void testAnonymity() throws Exception {
+
+ getKrbClient().init();
+
+ URL url = getClass().getResource("/cacert.pem");
+ TgtTicket tgt = null;
+ try {
+ tgt = getKrbClient().requestTgtWithPkintAnonymous(url.getPath());
+ } catch (KrbException te) {
+ assertThat(te.getMessage().contains("timeout")).isTrue();
+ return;
+ }
+ assertThat(tgt).isNull();
+
+ serverPrincipal = getServerPrincipal();
+ ServiceTicket tkt = getKrbClient().requestServiceTicketWithTgt(tgt, serverPrincipal);
+ assertThat(tkt).isNull();
+ }
+
//@Test
public void testKdc() throws Exception {
assertThat(userCert).isNotNull();
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
index b5ec953..0b61f80 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
@@ -214,9 +214,11 @@ public class KrbClient {
* @return TGT
* @throws KrbException e
*/
- public TgtTicket requestTgtWithPkintAnonymous() throws KrbException {
+ public TgtTicket requestTgtWithPkintAnonymous(String certificatePath) throws KrbException {
KOptions requestOptions = new KOptions();
requestOptions.add(KrbOption.USE_PKINIT_ANONYMOUS);
+ requestOptions.add(KrbOption.CLIENT_PRINCIPAL, "WELLKNOWN/ANONYMOUS");
+ requestOptions.add(KrbOption.PKINIT_X509_ANCHORS, certificatePath);
return requestTgtWithOptions(requestOptions);
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java
index 89eb1f5..7e6f928 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java
@@ -108,6 +108,7 @@ public abstract class KrbHandler {
KrbMessageType messageType = kdcRep.getMsgType();
if (messageType == KrbMessageType.AS_REP) {
+
kdcRequest.processResponse((KdcRep) kdcRep);
} else if (messageType == KrbMessageType.TGS_REP) {
kdcRequest.processResponse((KdcRep) kdcRep);
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 2c55ff8..baf97d8 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
@@ -33,6 +33,7 @@ import org.apache.kerby.kerberos.kerb.client.request.AsRequestWithToken;
import org.apache.kerby.kerberos.kerb.client.request.TgsRequest;
import org.apache.kerby.kerberos.kerb.client.request.TgsRequestWithTgt;
import org.apache.kerby.kerberos.kerb.client.request.TgsRequestWithToken;
+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.ticket.ServiceTicket;
import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
@@ -98,7 +99,11 @@ public abstract class AbstractInternalKrbClient implements InternalKrbClient {
String principal = requestOptions.getStringOption(
KrbOption.CLIENT_PRINCIPAL);
principal = fixPrincipal(principal);
- asRequest.setClientPrincipal(new PrincipalName(principal));
+ PrincipalName principalName = new PrincipalName(principal);
+ if (requestOptions.contains(KrbOption.USE_PKINIT_ANONYMOUS)) {
+ principalName.setNameType(NameType.KRB5_NT_WELLKNOWN);
+ }
+ asRequest.setClientPrincipal(principalName);
}
asRequest.setKrbOptions(requestOptions);
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
index 7494a5c..3eda45e 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
@@ -87,6 +87,7 @@ public class PreauthHandler {
return;
}
+ setPreauthOptions(kdcRequest, kdcRequest.getPreauthOptions());
if (!preauthContext.hasInputPaData()) {
tryFirst(kdcRequest, preauthContext.getOutputPaData());
return;
@@ -94,8 +95,6 @@ public class PreauthHandler {
// attemptETypeInfo(kdcRequest, preauthContext.getInputPaData());
- setPreauthOptions(kdcRequest, kdcRequest.getPreauthOptions());
-
prepareUserResponses(kdcRequest, preauthContext.getInputPaData());
preauthContext.getUserResponser().respondQuestions();
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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
index ca2be20..834da2f 100644
--- 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
@@ -23,6 +23,7 @@ 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;
@@ -47,7 +48,7 @@ class DhClient {
private SecretKey clientAesKey;
- byte[] init(DHParameterSpec dhParamSpec) throws Exception {
+ 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);
@@ -58,7 +59,8 @@ class DhClient {
clientKeyAgree.init(clientKpair.getPrivate());
// The client encodes its public key, and sends it over to the server.
- return clientKpair.getPublic().getEncoded();
+// return clientKpair.getPublic().getEncoded();
+ return (DHPublicKey) clientKpair.getPublic();
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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
index 0c8aa0d..60084ea 100644
--- 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
@@ -49,7 +49,7 @@ class DhServer {
private SecretKey serverAesKey;
- byte[] initAndDoPhase(byte[] clientPubKeyEnc) throws Exception {
+ 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.
@@ -80,7 +80,7 @@ class DhServer {
serverKeyAgree.doPhase(clientPubKey, true);
// The server encodes its public key, and sends it over to the client.
- return serverKpair.getPublic().getEncoded();
+ return serverKpair.getPublic();
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitContext.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitContext.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitContext.java
index 3e4f136..685ecfa 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitContext.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitContext.java
@@ -19,11 +19,12 @@
package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.IdentityOpts;
+import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitPlgCryptoContext;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.PluginOpts;
public class PkinitContext {
+ public PkinitPlgCryptoContext cryptoctx = new PkinitPlgCryptoContext();
public PluginOpts pluginOpts = new PluginOpts();
public IdentityOpts identityOpts = new IdentityOpts();
-
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitCrypto.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitCrypto.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitCrypto.java
deleted file mode 100644
index 34e3558..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitCrypto.java
+++ /dev/null
@@ -1,144 +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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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 org.apache.kerby.kerberos.kerb.KrbException;
-
-import javax.crypto.spec.DHParameterSpec;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-
-public class PkinitCrypto {
-
- /*
- * http://www.ietf.org/rfc/rfc2409.txt
- * This group is assigned id 2.
- * The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
- */
- public static BigInteger getPkinit1024Prime() {
- StringBuffer sb = new StringBuffer();
- sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
- sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
- sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
- sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
- sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381");
- sb.append("FFFFFFFFFFFFFFFF");
-
- return new BigInteger(sb.toString(), 16);
- }
-
- /*
- * http://www.ietf.org/rfc/rfc3526.txt
- * 2048-bit MODP Group
- * This group is assigned id 14.
- * This prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
- */
- public static BigInteger getPkinit2048Prime() {
- 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");
-
- return new BigInteger(sb.toString(), 16);
- }
-
- /*
- * http://www.ietf.org/rfc/rfc3526.txt
- * 4096-bit MODP Group
- * This group is assigned id 16.
- * This prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
- */
- public static BigInteger getPkinit4096Prime() {
- 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");
-
- return new BigInteger(sb.toString(), 16);
- }
-
- public static DHParameterSpec createDHParameterSpec(int dhSize) throws KrbException {
- BigInteger g = BigInteger.valueOf(2);
- BigInteger p = null;
-
- switch (dhSize) {
- case 1024:
- p = getPkinit1024Prime();
- break;
- case 2048:
- p = getPkinit2048Prime();
- break;
- case 4096:
- p = getPkinit4096Prime();
- break;
- default:
- throw new KrbException("Unsupported dh size:" + dhSize);
- }
-
- return new DHParameterSpec(p, g);
- }
-
- public static KeyPair getKeyPair(DHParameterSpec dhParameterSpec) {
- String algo = "DH";
- KeyPairGenerator keyPairGenerator = null;
- try {
- keyPairGenerator = KeyPairGenerator.getInstance(algo);
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- if (keyPairGenerator != null) {
- try {
- keyPairGenerator.initialize(dhParameterSpec);
- } catch (InvalidAlgorithmParameterException e) {
- e.printStackTrace();
- }
- }
- return keyPairGenerator.generateKeyPair();
- }
-}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 8f2cea0..fa362f4 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
@@ -20,32 +20,51 @@
package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
import org.apache.kerby.KOptions;
+import org.apache.kerby.asn1.type.Asn1Integer;
+import org.apache.kerby.asn1.type.Asn1ObjectIdentifier;
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.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.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.PkinitIdenity;
import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitPreauthMeta;
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.EncryptionType;
-import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+import org.apache.kerby.kerberos.kerb.spec.cms.AlgorithmIdentifier;
+import org.apache.kerby.kerberos.kerb.spec.cms.DHParameter;
+import org.apache.kerby.kerberos.kerb.spec.cms.SubjectPublicKeyInfo;
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.AuthPack;
-import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.DHNonce;
import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.PaPkAsReq;
import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.PkAuthenticator;
import org.apache.kerby.kerberos.kerb.spec.pa.pkinit.TrustedCertifiers;
-import org.apache.kerby.kerberos.kerb.spec.cms.SubjectPublicKeyInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.List;
-@SuppressWarnings("PMD")
public class PkinitPreauth extends AbstractPreauthPlugin {
+ private static final Logger LOG = LoggerFactory.getLogger(PkinitPreauth.class);
private PkinitContext pkinitContext;
@@ -87,8 +106,15 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
}
if (options.contains(KrbOption.PKINIT_X509_ANCHORS)) {
- pkinitContext.identityOpts.anchors.add(
- options.getStringOption(KrbOption.PKINIT_X509_ANCHORS));
+ String anchorsString = options.getStringOption(KrbOption.PKINIT_X509_ANCHORS);
+
+ List<String> anchors;
+ if (anchorsString == null) {
+ anchors = kdcRequest.getContext().getConfig().getPkinitAnchors();
+ } else {
+ anchors = Arrays.asList(anchorsString);
+ }
+ pkinitContext.identityOpts.anchors.addAll(anchors);
}
if (options.contains(KrbOption.PKINIT_USING_RSA)) {
@@ -123,6 +149,11 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
PluginRequestContext requestContext,
PaData outPadata) throws KrbException {
+ long now = System.currentTimeMillis();
+ PaPkAsReq paPkAsReq = makePaPkAsReq(kdcRequest,
+ (PkinitRequestContext) requestContext,
+ 1, new KerberosTime(now), 1, null);
+ outPadata.addElement(makeEntry(paPkAsReq));
}
/**
@@ -163,51 +194,127 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
}
- private PaPkAsReq makePaPkAsReq(PkinitContext pkinitContext, PkinitRequestContext reqCtx,
- KerberosTime ctime, int cusec, int nonce, byte[] checksum,
- PrincipalName client, PrincipalName server) {
+ private PaPkAsReq makePaPkAsReq(KdcRequest kdcRequest,
+ PkinitRequestContext reqCtx,
+ int cusec, KerberosTime ctime, int nonce, byte[] checksum) {
PaPkAsReq paPkAsReq = new PaPkAsReq();
AuthPack authPack = new AuthPack();
- SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo();
PkAuthenticator pkAuthen = new PkAuthenticator();
boolean usingRsa = reqCtx.requestOpts.usingRsa;
reqCtx.paType = PaDataType.PK_AS_REQ;
- pkAuthen.setCtime(ctime);
pkAuthen.setCusec(cusec);
+ pkAuthen.setCtime(ctime);
pkAuthen.setNonce(nonce);
- pkAuthen.setPaChecksum(checksum);
+
+ 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);
- DHNonce dhNonce = new DHNonce();
- authPack.setClientDhNonce(dhNonce);
- authPack.setClientPublicValue(pubInfo);
- authPack.setsupportedCmsTypes(pkinitContext.pluginOpts.createSupportedCMSTypes());
+// authPack.setsupportedCmsTypes(pkinitContext.pluginOpts.createSupportedCMSTypes());
- if (usingRsa) {
+ if (!usingRsa) {
System.out.println(); // DH case
+
+ AlgorithmIdentifier dhAlg = new AlgorithmIdentifier();
+
+// byte[] dh_oid = new byte[]{0, 7, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0xce,
+// (byte) 0x3e, (byte) 0x02, (byte) 0x01};
+// String dhOidStr = Utf8.toString(dh_oid);
+// String dhOidStr = "0.7.42.840.10046.2.1";
+
+ String content = "0x06 07 2A 86 48 ce 3e 02 01";
+ Asn1ObjectIdentifier decoded = new Asn1ObjectIdentifier();
+ decoded.getEncodingOption().useDer();
+ try {
+ decoded.decode(Util.hex2bytes(content));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ dhAlg.setAlgorithm(decoded);
+
+ DhClient client = new DhClient();
+
+ DHPublicKey clientPubKey = null;
+ try {
+ clientPubKey = client.init(DhGroup.MODP_GROUP14);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ DHParameterSpec spec = clientPubKey.getParams();
+ BigInteger q = spec.getP().shiftRight(1);
+ DHParameter dhParameter = new DHParameter();
+ dhParameter.setP(spec.getP());
+ dhParameter.setG(spec.getG());
+ dhParameter.setQ(q);
+ dhAlg.setParameters(dhParameter);
+
+ SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo();
+ pubInfo.setAlgorithm(dhAlg);
+
+ Asn1Integer publickey = new Asn1Integer(clientPubKey.getY());
+ pubInfo.setSubjectPubKey(publickey.encode());
+
+ authPack.setClientPublicValue(pubInfo);
+
+// DHNonce dhNonce = new DHNonce();
+// authPack.setClientDhNonce(dhNonce);
+
} else {
authPack.setClientPublicValue(null);
}
- byte[] signedAuthPack = signAuthPack(pkinitContext, reqCtx, authPack);
+ byte[] signedAuthPack = signAuthPack(kdcRequest, reqCtx, authPack);
+
paPkAsReq.setSignedAuthPack(signedAuthPack);
TrustedCertifiers trustedCertifiers = pkinitContext.pluginOpts.createTrustedCertifiers();
paPkAsReq.setTrustedCertifiers(trustedCertifiers);
- byte[] kdcPkId = pkinitContext.pluginOpts.createIssuerAndSerial();
- paPkAsReq.setKdcPkId(kdcPkId);
+// byte[] kdcPkId = pkinitContext.pluginOpts.createIssuerAndSerial();
+// paPkAsReq.setKdcPkId(kdcPkId);
return paPkAsReq;
}
- private byte[] signAuthPack(PkinitContext pkinitContext,
+ private byte[] signAuthPack(KdcRequest kdcRequest,
PkinitRequestContext reqCtx, AuthPack authPack) {
- return null;
+
+ List<String> anchors = pkinitContext.identityOpts.anchors;
+
+ InputStream res = null;
+ try {
+ res = new FileInputStream(anchors.get(0));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ X509Certificate certificate = null;
+ try {
+ certificate = (X509Certificate) CertificateHelper.loadCerts(res).iterator().next();
+ } catch (KrbException e) {
+ e.printStackTrace();
+ }
+
+ byte[] signedDataBytes = new byte[0];
+ try {
+ signedDataBytes = SignedDataEngine.cmsSignedDataCreate(authPack, certificate).toByteArray();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return signedDataBytes;
}
private void processReply(KdcRequest kdcRequest,
@@ -263,4 +370,17 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
return paFlags;
}
+ /**
+ * Make padata entry.
+ *
+ * @param paPkAsReq The PaPkAsReq
+ * @return PaDataEntry to be made.
+ */
+ private PaDataEntry makeEntry(PaPkAsReq paPkAsReq) throws KrbException {
+
+ PaDataEntry paDataEntry = new PaDataEntry();
+ paDataEntry.setPaDataType(PaDataType.PK_AS_REQ);
+ paDataEntry.setPaDataValue(paPkAsReq.encode());
+ return paDataEntry;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java
index 97e989f..9796f78 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java
@@ -30,7 +30,7 @@ public class PkinitRequestOpts {
// allow UPN-SAN instead of pkinit-SAN
public boolean allowUpn = true;
// selects DH or RSA based pkinit
- public boolean usingRsa = true;
+ public boolean usingRsa = false;
// require CRL for a CA (default is false)
public boolean requireCrlChecking = false;
// initial request DH modulus size (default=1024)
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngine.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngine.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngine.java
index c245579..4d2aef8 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngine.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngine.java
@@ -32,20 +32,22 @@ import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
-import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
+import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
-import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
-
+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 java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
import java.security.PrivateKey;
-import java.security.cert.CertStoreException;
+import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -80,16 +82,14 @@ public class SignedDataEngine {
* @param certificate
* @param authPack
* @return The CMS SignedData bytes.
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- * @throws InvalidAlgorithmParameterException
- * @throws CertStoreException
+ * @throws OperatorCreationException
+ * @throws CertificateEncodingException
* @throws CMSException
* @throws IOException
*/
- public static byte[] getSignedAuthPack(PrivateKey privateKey, X509Certificate certificate, AuthPack authPack)
- throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException,
- CertStoreException, CMSException, IOException, OperatorCreationException, CertificateEncodingException {
+ public static byte[] getSignedAuthPack(PrivateKey privateKey, X509Certificate certificate,
+ AuthPack authPack)
+ throws OperatorCreationException, CertificateEncodingException, CMSException, IOException {
return getSignedData(privateKey, certificate, authPack.encode(), ID_PKINIT_AUTHDATA);
}
@@ -109,18 +109,14 @@ public class SignedDataEngine {
* @param certificate
* @param kdcDhKeyInfo
* @return The CMS SignedData bytes.
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- * @throws InvalidAlgorithmParameterException
- * @throws CertStoreException
+ * @throws OperatorCreationException
+ * @throws CertificateEncodingException
* @throws CMSException
* @throws IOException
*/
public static byte[] getSignedKdcDhKeyInfo(PrivateKey privateKey, X509Certificate certificate,
KdcDHKeyInfo kdcDhKeyInfo)
- throws NoSuchAlgorithmException, NoSuchProviderException,
- InvalidAlgorithmParameterException, CertStoreException, CMSException, IOException,
- OperatorCreationException, CertificateEncodingException {
+ throws OperatorCreationException, CertificateEncodingException, CMSException, IOException {
return getSignedData(privateKey, certificate, kdcDhKeyInfo.encode(), ID_PKINIT_DHKEYDATA);
}
@@ -139,37 +135,38 @@ public class SignedDataEngine {
* @param certificate
* @param replyKeyPack
* @return The CMS SignedData bytes.
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- * @throws InvalidAlgorithmParameterException
- * @throws CertStoreException
+ * @throws OperatorCreationException
+ * @throws CertificateEncodingException
* @throws CMSException
* @throws IOException
*/
public static byte[] getSignedReplyKeyPack(PrivateKey privateKey, X509Certificate certificate,
ReplyKeyPack replyKeyPack)
- throws NoSuchAlgorithmException, NoSuchProviderException,
- InvalidAlgorithmParameterException, CertStoreException, CMSException, IOException,
- OperatorCreationException, CertificateEncodingException {
+ throws OperatorCreationException, CertificateEncodingException, CMSException, IOException {
return getSignedData(privateKey, certificate, replyKeyPack.encode(), ID_PKINIT_RKEYDATA);
}
static byte[] getSignedData(PrivateKey privateKey, X509Certificate certificate, byte[] dataToSign,
- String eContentType) throws NoSuchAlgorithmException, NoSuchProviderException,
- InvalidAlgorithmParameterException, CertStoreException, CMSException, IOException,
- CertificateEncodingException, OperatorCreationException {
+ String eContentType) throws IOException, OperatorCreationException,
+ CertificateEncodingException, CMSException {
+
+ if (Security.getProvider("BC") == null) {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
List certList = new ArrayList();
certList.add(certificate);
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
- ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC")
- .build(privateKey);
- gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
- new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
- .build(contentSigner, certificate));
+
+ gen.addSignerInfoGenerator(
+ new JcaSimpleSignerInfoGeneratorBuilder()
+ .setProvider("BC")
+ .build("SHA1withRSA", privateKey, certificate));
+
gen.addCertificates(certs);
ASN1ObjectIdentifier asn1ObjectIdentifier = new ASN1ObjectIdentifier(eContentType);
@@ -217,4 +214,26 @@ public class SignedDataEngine {
}
return true;
}
+
+ 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(AuthPack authPack,
+ X509Certificate certificate) throws IOException {
+
+ ObjectIdentifier oid = new ObjectIdentifier(ID_PKINIT_AUTHDATA);
+ ContentInfo contentInfo = createContentInfo(authPack.encode(), oid);
+
+ X509Certificate[] certificates = {certificate};
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0], contentInfo, certificates, new SignerInfo[0]);
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ p7.encodeSignedData(bytes);
+ return bytes;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/Util.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/Util.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/Util.java
new file mode 100644
index 0000000..672264a
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/Util.java
@@ -0,0 +1,153 @@
+/**
+ * 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;
+
+public class Util {
+
+ static final String HEX_CHARS_STR = "0123456789ABCDEF";
+ static final char[] HEX_CHARS = HEX_CHARS_STR.toCharArray();
+
+ /**
+ * Convert bytes into format as:
+ * 0x02 02 00 80
+ */
+ public static String bytesToHex(byte[] bytes) {
+ int len = bytes.length * 2;
+ len += bytes.length; // for ' ' appended for each char
+ len += 2; // for '0x' prefix
+ char[] hexChars = new char[len];
+ hexChars[0] = '0';
+ hexChars[1] = 'x';
+ for (int j = 0; j < bytes.length; j++) {
+ int v = bytes[j] & 0xFF;
+ hexChars[j * 3 + 2] = HEX_CHARS[v >>> 4];
+ hexChars[j * 3 + 3] = HEX_CHARS[v & 0x0F];
+ hexChars[j * 3 + 4] = ' ';
+ }
+
+ return new String(hexChars);
+ }
+
+ /**
+ * Convert hex string like follows into byte array
+ * 0x02 02 00 80
+ */
+ public static byte[] hex2bytes(String hexString) {
+ if (hexString == null) {
+ throw new IllegalArgumentException("Invalid hex string to convert : null");
+ }
+
+ char[] hexStr = hexString.toCharArray();
+
+ if (hexStr.length < 4) {
+ throw new IllegalArgumentException("Invalid hex string to convert : length below 4");
+ }
+
+ if (hexStr[0] != '0' || (hexStr[1] != 'x') && (hexStr[1] != 'X')) {
+ throw new IllegalArgumentException("Invalid hex string to convert : not starting with '0x'");
+ }
+
+ byte[] bytes = new byte[(hexStr.length - 1) / 3];
+ int pos = 0;
+ boolean high = false;
+ boolean prefix = true;
+
+ for (char c : hexStr) {
+ if (prefix) {
+ if (c == 'x' || c == 'X') {
+ prefix = false;
+ }
+
+ continue;
+ }
+
+ switch (c) {
+ case ' ' :
+ if (high) {
+ // We have had only the high part
+ throw new IllegalArgumentException("Invalid hex string to convert");
+ }
+
+ // A hex pair has been decoded
+ pos++;
+ high = false;
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (high) {
+ bytes[pos] += (byte) (c - '0');
+ } else {
+ bytes[pos] = (byte) ((c - '0') << 4);
+ }
+
+ high = !high;
+ break;
+
+ case 'a' :
+ case 'b' :
+ case 'c' :
+ case 'd' :
+ case 'e' :
+ case 'f' :
+ if (high) {
+ bytes[pos] += (byte) (c - 'a' + 10);
+ } else {
+ bytes[pos] = (byte) ((c - 'a' + 10) << 4);
+ }
+
+ high = !high;
+ break;
+
+ case 'A' :
+ case 'B' :
+ case 'C' :
+ case 'D' :
+ case 'E' :
+ case 'F' :
+ if (high) {
+ bytes[pos] += (byte) (c - 'A' + 10);
+ } else {
+ bytes[pos] = (byte) ((c - 'A' + 10) << 4);
+ }
+
+ high = !high;
+ break;
+
+ default :
+ throw new IllegalArgumentException("Invalid hex string to convert");
+ }
+ }
+
+ if (high) {
+ throw new IllegalArgumentException("Invalid hex string to convert");
+ }
+
+ return bytes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 75216a8..f6ff7f8 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
@@ -89,8 +89,11 @@ public class AsRequest extends KdcRequest {
PrincipalName clientPrincipal = getKdcRep().getCname();
String clientRealm = getKdcRep().getCrealm();
clientPrincipal.setRealm(clientRealm);
- if (!getKrbOptions().contains(KrbOption.TOKEN_USER_ID_TOKEN)
- && !clientPrincipal.equals(getClientPrincipal())) {
+
+ if (!(getKrbOptions().contains(KrbOption.USE_PKINIT_ANONYMOUS)
+ && KrbUtil.pricipalCompareIgnoreRealm(clientPrincipal, getClientPrincipal()))
+ && !getKrbOptions().contains(KrbOption.TOKEN_USER_ID_TOKEN)
+ && !clientPrincipal.equals(getClientPrincipal())) {
throw new KrbException(KrbErrorCode.KDC_ERR_CLIENT_NAME_MISMATCH);
}
@@ -147,4 +150,5 @@ public class AsRequest extends KdcRequest {
return cc;
}
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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 ef2808f..4b7525b 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
@@ -19,11 +19,19 @@
*/
package org.apache.kerby.kerberos.kerb.client.request;
-import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.client.KrbOption;
import org.apache.kerby.KOptions;
+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.spec.kdc.AsReq;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcOption;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcRep;
+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.PaPkAsRep;
public class AsRequestWithCert extends AsRequest {
@@ -33,11 +41,20 @@ public class AsRequestWithCert extends AsRequest {
super(context);
setAllowedPreauth(PaDataType.PK_AS_REQ);
+ getKdcOptions().setFlag(KdcOption.REQUEST_ANONYMOUS);
}
@Override
public void process() throws KrbException {
- throw new RuntimeException("To be implemented");
+ KdcReqBody body = makeReqBody();
+ AsReq asReq = new AsReq();
+ asReq.setReqBody(body);
+ setKdcReq(asReq);
+
+ preauth();
+
+ asReq.setPaData(getPreauthContext().getOutputPaData());
+ setKdcReq(asReq);
}
@Override
@@ -54,4 +71,30 @@ public class AsRequestWithCert extends AsRequest {
return results;
}
+ @Override
+ public void processResponse(KdcRep kdcRep) throws KrbException {
+
+ PaData paData = kdcRep.getPaData();
+ for (PaDataEntry paEntry : paData.getElements()) {
+ if (paEntry.getPaDataType() == PaDataType.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();
+
+ }
+ }
+
+ super.processResponse(kdcRep);
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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
index c3055cf..54b2b5b 100644
--- 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
@@ -22,7 +22,14 @@ 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;
@@ -42,7 +49,6 @@ import java.util.Arrays;
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].
@@ -53,8 +59,8 @@ public class DhKeyAgreementTest extends TestCase {
DhClient client = new DhClient();
DhServer server = new DhServer();
- byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2);
- byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc);
+ byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2).getEncoded();
+ byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc).getEncoded();
server.generateKey(null, null);
@@ -90,8 +96,8 @@ public class DhKeyAgreementTest extends TestCase {
DhClient client = new DhClient();
DhServer server = new DhServer();
- byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2);
- byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc);
+ byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2).getEncoded();
+ byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc).getEncoded();
server.generateKey(clientDhNonce, serverDhNonce);
@@ -106,4 +112,56 @@ public class DhKeyAgreementTest extends TestCase {
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/14696718/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 0610807..e6dd9db 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
@@ -1,30 +1,36 @@
/**
- * 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.
- *
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.common;
import org.apache.kerby.kerberos.kerb.KrbConstant;
+import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.spec.base.NameType;
import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
public class KrbUtil {
+ public static final String ANONYMOUS_PRINCIPAL = "ANONYMOUS@WELLKNOWN:ANONYMOUS";
+ /** First component of NT_WELLKNOWN principals */
+ public static final String KRB5_WELLKNOWN_NAMESTR = "WELLKNOWN";
+ public static final String KRB5_ANONYMOUS_PRINCSTR = "ANONYMOUS";
+ public static final String KRB5_ANONYMOUS_REALMSTR = "WELLKNOWN:ANONYMOUS";
+
/**
* Construct TGS principal name.
* @param realm The realm
@@ -45,4 +51,27 @@ public class KrbUtil {
return new PrincipalName(nameString, NameType.NT_PRINCIPAL);
}
+ public static boolean pricipalCompareIgnoreRealm(PrincipalName princ1, PrincipalName princ2)
+ throws KrbException {
+
+ if (princ1 != null && princ2 != null) {
+ princ1.setRealm(null);
+ princ2.setRealm(null);
+ if (princ1.getName().equals(princ2.getName())) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ throw new KrbException("principal can't be null.");
+ }
+ }
+
+ public static PrincipalName makeAnonymousPrincipal() {
+ PrincipalName principalName = new PrincipalName(KRB5_WELLKNOWN_NAMESTR + "/" + KRB5_ANONYMOUS_PRINCSTR);
+ principalName.setRealm(KRB5_ANONYMOUS_REALMSTR);
+ principalName.setNameType(NameType.NT_PRINCIPAL);
+ return principalName;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CMSMessageType.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CMSMessageType.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CMSMessageType.java
new file mode 100644
index 0000000..683b52f
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CMSMessageType.java
@@ -0,0 +1,59 @@
+/**
+ * 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.preauth.pkinit;
+
+public enum CMSMessageType {
+ UNKNOWN (-1),
+ CMS_SIGN_CLIENT (0x01),
+ CMS_SIGN_SERVER (0x03),
+ CMS_ENVEL_SERVER (0x04);
+
+
+ /** The type value */
+ private int value;
+
+ /**
+ * Create an instance of this class
+ */
+ private CMSMessageType(int value) {
+ this.value = value;
+ }
+
+ /**
+ * @return The associated type value
+ */
+ public int getValue() {
+ return value;
+ }
+
+ /**
+ * Retrieve the UniversalTag associated with a given value
+ * @param value The integer value
+ * @return The associated UniversalTag
+ */
+ public static CMSMessageType fromValue(int value) {
+ switch (value) {
+ case 0x01 : return CMS_SIGN_CLIENT;
+ case 0x03 : return CMS_SIGN_SERVER;
+ case 0x04 : return CMS_ENVEL_SERVER;
+ default : return UNKNOWN;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CertificateHelper.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CertificateHelper.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CertificateHelper.java
new file mode 100644
index 0000000..9731907
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/CertificateHelper.java
@@ -0,0 +1,45 @@
+/**
+ * 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.preauth.pkinit;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.io.InputStream;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class CertificateHelper {
+
+ public static List<Certificate> loadCerts(InputStream inputStream) throws KrbException {
+ CertificateFactory certFactory = null;
+ try {
+ certFactory = CertificateFactory.getInstance("X.509");
+ Collection<? extends Certificate> certs = (Collection<? extends Certificate>)
+ certFactory.generateCertificates(inputStream);
+ return new ArrayList<Certificate>(certs);
+ } catch (CertificateException e) {
+ throw new KrbException("Failed to load certificates", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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
new file mode 100644
index 0000000..c74a4de
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
@@ -0,0 +1,170 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.preauth.pkinit;
+
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.ParsingException;
+import sun.security.util.ObjectIdentifier;
+
+import javax.crypto.spec.DHParameterSpec;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+
+public class PkinitCrypto {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PkinitCrypto.class);
+
+ public static KeyPair getKeyPair(DHParameterSpec dhParameterSpec) {
+ String algo = "DH";
+ KeyPairGenerator keyPairGenerator = null;
+ try {
+ keyPairGenerator = KeyPairGenerator.getInstance(algo);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ if (keyPairGenerator != null) {
+ try {
+ keyPairGenerator.initialize(dhParameterSpec);
+ } catch (InvalidAlgorithmParameterException e) {
+ e.printStackTrace();
+ }
+ }
+ return keyPairGenerator.generateKeyPair();
+ }
+
+ public static PKCS7 verifyCMSSignedData(PkinitPlgCryptoContext cryptoctx, CMSMessageType cmsMsgType,
+ byte[] signedData)
+ throws IOException, KrbException {
+
+ ObjectIdentifier oid = pkinitPKCS7Type2OID(cryptoctx, cmsMsgType);
+ if (oid == null) {
+ throw new KrbException("Can't get the right oid ");
+ }
+
+ /* decode received CMS message */
+ PKCS7 pkcs7 = null;
+ try {
+ pkcs7 = new PKCS7(signedData);
+ } catch (ParsingException e) {
+ e.printStackTrace();
+ }
+ if (pkcs7 == null) {
+ LOG.error("failed to decode message");
+ throw new KrbException("failed to decode message");
+ }
+
+ ObjectIdentifier etype = pkcs7.getContentInfo().getContentType();
+
+ if (oid.equals(etype)) {
+ LOG.info("CMS Verification successful");
+ } else {
+ LOG.error("Wrong oid in eContentType");
+ throw new KrbException(KrbErrorCode.KDC_ERR_PREAUTH_FAILED, "Wrong oid in eContentType");
+ }
+
+ return pkcs7;
+ }
+
+ public static boolean isSigned(PKCS7 pkcs7) {
+ /* Not actually signed; anonymous case */
+ if (pkcs7.getSignerInfos().length == 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+
+ public static ObjectIdentifier pkinitPKCS7Type2OID(PkinitPlgCryptoContext cryptoctx,
+ CMSMessageType cmsMsgType) throws IOException {
+ switch (cmsMsgType) {
+ case UNKNOWN:
+ return null;
+ case CMS_SIGN_CLIENT:
+ return cryptoctx.getIdPkinitAuthDataOID();
+ case CMS_SIGN_SERVER:
+ return cryptoctx.getIdPkinitDHKeyDataOID();
+ case CMS_ENVEL_SERVER:
+ return cryptoctx.getIdPkinitRkeyDataOID();
+ default:
+ return null;
+ }
+ }
+
+ public static void serverCheckDH(PluginOpts pluginOpts, PkinitPlgCryptoContext cryptoctx,
+ DHParameter dhParameter) throws KrbException {
+ /* KDC SHOULD check to see if the key parameters satisfy its policy */
+ int dhPrimeBits = dhParameter.getP().bitLength();
+ if (dhPrimeBits < pluginOpts.dhMinBits) {
+ String errMsg = "client sent dh params with " + dhPrimeBits
+ + "bits, we require " + pluginOpts.dhMinBits;
+ LOG.error(errMsg);
+ throw new KrbException(KrbErrorCode.KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED, errMsg);
+ }
+ checkDHWellknown(cryptoctx, dhParameter, dhPrimeBits);
+ }
+
+ public static boolean checkDHWellknown(PkinitPlgCryptoContext cryptoctx,
+ DHParameter dhParameter, int dhPrimeBits) throws KrbException {
+ boolean valid = false;
+ switch (dhPrimeBits) {
+ case 1024:
+ /* Oakley MODP group 2 */
+ case 2048:
+ /* Oakley MODP group 14 */
+ case 4096:
+ /* Oakley MODP group 16 */
+ valid = pkinitCheckDhParams(cryptoctx.createDHParameterSpec(dhPrimeBits), dhParameter);
+ break;
+ default:
+ break;
+ }
+ return valid;
+ }
+
+ /**
+ * Check parameters against a well-known DH group
+ *
+ * @param dh1 The DHParameterSpec
+ * @param dh2 The DHParameter
+ */
+
+ public static boolean pkinitCheckDhParams(DHParameterSpec dh1, DHParameter dh2) {
+
+ if (!dh1.getP().equals(dh2.getP())) {
+ LOG.error("p is not well-known group dhparameter");
+ return false;
+ }
+ if (!dh1.getG().equals(dh2.getG())) {
+ LOG.error("bad g dhparameter");
+ return false;
+ }
+ LOG.info("Good dhparams", dh1.getP().bitLength());
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/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
new file mode 100644
index 0000000..f70d081
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitPlgCryptoContext.java
@@ -0,0 +1,141 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.preauth.pkinit;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import sun.security.util.ObjectIdentifier;
+
+import javax.crypto.spec.DHParameterSpec;
+import java.io.IOException;
+import java.math.BigInteger;
+
+public class PkinitPlgCryptoContext {
+ private static final String ID_PKINIT_AUTHDATA = "1.3.6.1.5.2.3.1";
+ private static final String ID_PKINIT_DHKEYDATA = "1.3.6.1.5.2.3.2";
+ private static final String ID_PKINIT_RKEYDATA = "1.3.6.1.5.2.3.3";
+
+
+ /*
+ * http://www.ietf.org/rfc/rfc2409.txt
+ * This group is assigned id 2.
+ * The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ */
+ public BigInteger getPkinit1024Prime() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1");
+ sb.append("29024E088A67CC74020BBEA63B139B22514A08798E3404DD");
+ sb.append("EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245");
+ sb.append("E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED");
+ sb.append("EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381");
+ sb.append("FFFFFFFFFFFFFFFF");
+
+ return new BigInteger(sb.toString(), 16);
+ }
+
+ /*
+ * http://www.ietf.org/rfc/rfc3526.txt
+ * 2048-bit MODP Group
+ * This group is assigned id 14.
+ * This prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ */
+ public BigInteger getPkinit2048Prime() {
+ 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");
+
+ return new BigInteger(sb.toString(), 16);
+ }
+
+ /*
+ * http://www.ietf.org/rfc/rfc3526.txt
+ * 4096-bit MODP Group
+ * This group is assigned id 16.
+ * This prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ */
+ public BigInteger getPkinit4096Prime() {
+ 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");
+
+ return new BigInteger(sb.toString(), 16);
+ }
+
+ public DHParameterSpec createDHParameterSpec(int dhSize) throws KrbException {
+ BigInteger g = BigInteger.valueOf(2);
+ BigInteger p = null;
+
+ switch (dhSize) {
+ case 1024:
+ p = getPkinit1024Prime();
+ break;
+ case 2048:
+ p = getPkinit2048Prime();
+ break;
+ case 4096:
+ p = getPkinit4096Prime();
+ break;
+ default:
+ throw new KrbException("Unsupported dh size:" + dhSize);
+ }
+
+ return new DHParameterSpec(p, g);
+ }
+
+
+ public ObjectIdentifier getIdPkinitAuthDataOID() throws IOException {
+ return new ObjectIdentifier(ID_PKINIT_AUTHDATA);
+ }
+
+ public ObjectIdentifier getIdPkinitDHKeyDataOID() throws IOException {
+ return new ObjectIdentifier(ID_PKINIT_DHKEYDATA);
+ }
+
+ public ObjectIdentifier getIdPkinitRkeyDataOID() throws IOException {
+ return new ObjectIdentifier(ID_PKINIT_RKEYDATA);
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PluginOpts.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PluginOpts.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PluginOpts.java
index 0cc34f2..ae303bf 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PluginOpts.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PluginOpts.java
@@ -35,7 +35,7 @@ public class PluginOpts {
// allow UPN-SAN instead of pkinit-SAN
public boolean allowUpn = true;
// selects DH or RSA based pkinit
- public boolean usingRsa = true;
+ public boolean usingRsa = false;
// require CRL for a CA (default is false)
public boolean requireCrlChecking = false;
// the size of the Diffie-Hellman key the client will attempt to use.
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/14696718/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/KrbFlags.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/KrbFlags.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/KrbFlags.java
index b84992c..79d3323 100644
--- a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/KrbFlags.java
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/spec/base/KrbFlags.java
@@ -30,7 +30,6 @@ import java.io.IOException;
-- but no fewer than 32
*/
public class KrbFlags extends Asn1BitString {
- private static final int MAX_SIZE = 32;
private int flags;
public KrbFlags() {
@@ -90,7 +89,8 @@ public class KrbFlags extends Asn1BitString {
}
private int flagPos(int flag) {
- return MAX_SIZE - 1 - flag;
+// return MAX_SIZE - 1 - flag;
+ return Integer.numberOfTrailingZeros(flag);
}
private void flags2Value() {