directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dran...@apache.org
Subject [11/42] directory-kerberos git commit: Initially import Haox codebase (https://github.com/drankye/haox)
Date Sat, 10 Jan 2015 13:30:55 GMT
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java
new file mode 100644
index 0000000..c905218
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java
@@ -0,0 +1,38 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class AsRequestWithCert extends AsRequest {
+
+    public static final String ANONYMOUS_PRINCIPAL = "ANONYMOUS@WELLKNOWN:ANONYMOUS";
+
+    public AsRequestWithCert(KrbContext context) {
+        super(context);
+
+        setAllowedPreauth(PaDataType.PK_AS_REQ);
+    }
+
+    @Override
+    public void process() throws KrbException {
+        throw new RuntimeException("To be implemented");
+    }
+
+    @Override
+    public KrbOptions getPreauthOptions() {
+        KrbOptions results = new KrbOptions();
+
+        KrbOptions krbOptions = getKrbOptions();
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_CERTIFICATE));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_ANCHORS));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_PRIVATE_KEY));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_IDENTITY));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_USING_RSA));
+
+        return results;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java
new file mode 100644
index 0000000..bc9c1ab
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java
@@ -0,0 +1,31 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class AsRequestWithPasswd extends AsRequest {
+
+    public AsRequestWithPasswd(KrbContext context) {
+        super(context);
+
+        setAllowedPreauth(PaDataType.ENC_TIMESTAMP);
+    }
+
+    public String getPassword() {
+        return getKrbOptions().getStringOption(KrbOption.USER_PASSWD);
+    }
+
+    @Override
+    public EncryptionKey getClientKey() throws KrbException {
+        if (super.getClientKey() == null) {
+            EncryptionKey tmpKey = EncryptionHandler.string2Key(getClientPrincipal().getName(),
+                    getPassword(), getChosenEncryptionType());
+            setClientKey(tmpKey);
+        }
+        return super.getClientKey();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java
new file mode 100644
index 0000000..2e792f0
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java
@@ -0,0 +1,33 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class AsRequestWithToken extends AsRequest {
+
+    public AsRequestWithToken(KrbContext context) {
+        super(context);
+
+        setAllowedPreauth(PaDataType.TOKEN_REQUEST);
+    }
+
+    @Override
+    public void process() throws KrbException {
+        throw new RuntimeException("To be implemented");
+    }
+
+    @Override
+    public KrbOptions getPreauthOptions() {
+        KrbOptions results = new KrbOptions();
+
+        KrbOptions krbOptions = getKrbOptions();
+        results.add(krbOptions.getOption(KrbOption.TOKEN_USING_IDTOKEN));
+        results.add(krbOptions.getOption(KrbOption.TOKEN_USER_ID_TOKEN));
+        results.add(krbOptions.getOption(KrbOption.TOKEN_USER_AC_TOKEN));
+
+        return results;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java
new file mode 100644
index 0000000..ac7b732
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java
@@ -0,0 +1,339 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.client.preauth.FastContext;
+import org.apache.kerberos.kerb.client.preauth.PreauthContext;
+import org.apache.kerberos.kerb.client.preauth.PreauthHandler;
+import org.apache.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerberos.kerb.spec.common.*;
+import org.apache.kerberos.kerb.spec.kdc.KdcOptions;
+import org.apache.kerberos.kerb.spec.kdc.KdcRep;
+import org.apache.kerberos.kerb.spec.kdc.KdcReq;
+import org.apache.kerberos.kerb.spec.kdc.KdcReqBody;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.haox.transport.Transport;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A wrapper for KdcReq request
+ */
+public abstract class KdcRequest {
+    private KrbContext context;
+    private Transport transport;
+
+    private KrbOptions krbOptions;
+    private PrincipalName serverPrincipal;
+    private List<HostAddress> hostAddresses = new ArrayList<HostAddress>();
+    private KdcOptions kdcOptions = new KdcOptions();
+    private List<EncryptionType> encryptionTypes;
+    private EncryptionType chosenEncryptionType;
+    private int chosenNonce;
+    private KdcReq kdcReq;
+    private KdcRep kdcRep;
+    protected Map<String, Object> credCache;
+    private PreauthContext preauthContext;
+    private FastContext fastContext;
+    private EncryptionKey asKey;
+
+    private KrbError errorReply;
+    private boolean isRetrying;
+
+    public KdcRequest(KrbContext context) {
+        this.context = context;
+        this.isRetrying = false;
+        this.credCache = new HashMap<String, Object>();
+        this.preauthContext = context.getPreauthHandler()
+                .preparePreauthContext(this);
+        this.fastContext = new FastContext();
+    }
+
+    public void setTransport(Transport transport) {
+        this.transport = transport;
+    }
+
+    public Transport getTransport() {
+        return this.transport;
+    }
+
+    public void setKrbOptions(KrbOptions options) {
+        this.krbOptions = options;
+    }
+
+    public KrbOptions getKrbOptions() {
+        return krbOptions;
+    }
+
+    public boolean isRetrying() {
+        return isRetrying;
+    }
+
+    public void setAsKey(EncryptionKey asKey) {
+        this.asKey = asKey;
+    }
+
+    public EncryptionKey getAsKey() throws KrbException {
+        return asKey;
+    }
+
+    public void setAllowedPreauth(PaDataType paType) {
+        preauthContext.setAllowedPaType(paType);
+    }
+
+    public Map<String, Object> getCredCache() {
+        return credCache;
+    }
+
+    public void setPreauthRequired(boolean preauthRequired) {
+        preauthContext.setPreauthRequired(preauthRequired);
+    }
+
+    public PreauthContext getPreauthContext() {
+        return preauthContext;
+    }
+
+    protected void loadCredCache() {
+        // TODO
+    }
+
+    public KdcReq getKdcReq() {
+        return kdcReq;
+    }
+
+    public void setKdcReq(KdcReq kdcReq) {
+        this.kdcReq = kdcReq;
+    }
+
+    public KdcRep getKdcRep() {
+        return kdcRep;
+    }
+
+    public void setKdcRep(KdcRep kdcRep) {
+        this.kdcRep = kdcRep;
+    }
+
+    protected KdcReqBody makeReqBody() throws KrbException {
+        KdcReqBody body = new KdcReqBody();
+
+        long startTime = System.currentTimeMillis();
+        body.setFrom(new KerberosTime(startTime));
+
+        PrincipalName cName = null;
+        cName = getClientPrincipal();
+        body.setCname(cName);
+
+        body.setRealm(cName.getRealm());
+
+        PrincipalName sName = getServerPrincipal();
+        body.setSname(sName);
+
+        body.setTill(new KerberosTime(startTime + getTicketValidTime()));
+
+        int nonce = generateNonce();
+        body.setNonce(nonce);
+        setChosenNonce(nonce);
+
+        body.setKdcOptions(getKdcOptions());
+
+        HostAddresses addresses = getHostAddresses();
+        if (addresses != null) {
+            body.setAddresses(addresses);
+        }
+
+        body.setEtypes(getEncryptionTypes());
+
+        return body;
+    }
+
+    public KdcOptions getKdcOptions() {
+        return kdcOptions;
+    }
+
+    public HostAddresses getHostAddresses() {
+        HostAddresses addresses = null;
+        if (!hostAddresses.isEmpty()) {
+            addresses = new HostAddresses();
+            for(HostAddress ha : hostAddresses) {
+                addresses.addElement(ha);
+            }
+        }
+        return addresses;
+    }
+
+    public KrbContext getContext() {
+        return context;
+    }
+
+    protected byte[] decryptWithClientKey(EncryptedData data, KeyUsage usage) throws KrbException {
+        return EncryptionHandler.decrypt(data, getClientKey(), usage);
+    }
+
+    public void setContext(KrbContext context) {
+        this.context = context;
+    }
+
+    public void setHostAddresses(List<HostAddress> hostAddresses) {
+        this.hostAddresses = hostAddresses;
+    }
+
+    public void setKdcOptions(KdcOptions kdcOptions) {
+        this.kdcOptions = kdcOptions;
+    }
+
+    public abstract PrincipalName getClientPrincipal();
+
+    public PrincipalName getServerPrincipal() {
+        return serverPrincipal;
+    }
+
+    public void setServerPrincipal(PrincipalName serverPrincipal) {
+        this.serverPrincipal = serverPrincipal;
+    }
+
+    public List<EncryptionType> getEncryptionTypes() {
+        if (encryptionTypes == null) {
+            encryptionTypes = context.getConfig().getEncryptionTypes();
+        }
+        return encryptionTypes;
+    }
+
+    public void setEncryptionTypes(List<EncryptionType> encryptionTypes) {
+        this.encryptionTypes = encryptionTypes;
+    }
+
+    public EncryptionType getChosenEncryptionType() {
+        return chosenEncryptionType;
+    }
+
+    public void setChosenEncryptionType(EncryptionType chosenEncryptionType) {
+        this.chosenEncryptionType = chosenEncryptionType;
+    }
+
+    public int generateNonce() {
+        return context.generateNonce();
+    }
+
+    public int getChosenNonce() {
+        return chosenNonce;
+    }
+
+    public void setChosenNonce(int nonce) {
+        this.chosenNonce = nonce;
+    }
+
+    public abstract EncryptionKey getClientKey() throws KrbException;
+
+    public long getTicketValidTime() {
+        return context.getTicketValidTime();
+    }
+
+    public KerberosTime getTicketTillTime() {
+        long now = System.currentTimeMillis();
+        return new KerberosTime(now + KerberosTime.MINUTE * 60 * 1000);
+    }
+
+    public void addHost(String hostNameOrIpAddress) throws UnknownHostException {
+        InetAddress address = InetAddress.getByName(hostNameOrIpAddress);
+        hostAddresses.add(new HostAddress(address));
+    }
+
+    public void process() throws KrbException {
+        preauth();
+    }
+
+    public abstract void processResponse(KdcRep kdcRep) throws KrbException;
+
+    public KrbOptions getPreauthOptions() {
+        return new KrbOptions();
+    }
+
+    protected void preauth() throws KrbException {
+        loadCredCache();
+
+        List<EncryptionType> etypes = getEncryptionTypes();
+        if (etypes.isEmpty()) {
+            throw new KrbException("No encryption type is configured and available");
+        }
+        EncryptionType encryptionType = etypes.iterator().next();
+        setChosenEncryptionType(encryptionType);
+
+        getPreauthHandler().preauth(this);
+    }
+
+    protected PreauthHandler getPreauthHandler() {
+        return getContext().getPreauthHandler();
+    }
+
+    /**
+     * Indicate interest in the AS key.
+     */
+    public void needAsKey() throws KrbException {
+        EncryptionKey clientKey = getClientKey();
+        if (clientKey == null) {
+            throw new RuntimeException("Client key should be prepared or prompted at this time!");
+        }
+        setAsKey(clientKey);
+    }
+
+    /**
+     * Get the enctype expected to be used to encrypt the encrypted portion of
+     * the AS_REP packet.  When handling a PREAUTH_REQUIRED error, this
+     * typically comes from etype-info2.  When handling an AS reply, it is
+     * initialized from the AS reply itself.
+     */
+    public EncryptionType getEncType() {
+
+        return getChosenEncryptionType();
+    }
+
+    public void askQuestion(String question, String challenge) {
+        preauthContext.getUserResponser().askQuestion(question, challenge);
+    }
+
+    /**
+     * Get a pointer to the FAST armor key, or NULL if the client is not using FAST.
+     */
+    public EncryptionKey getArmorKey() {
+        return fastContext.armorKey;
+    }
+
+    /**
+     * Get the current time for use in a preauth response.  If
+     * allow_unauth_time is true and the library has been configured to allow
+     * it, the current time will be offset using unauthenticated timestamp
+     * information received from the KDC in the preauth-required error, if one
+     * has been received.  Otherwise, the timestamp in a preauth-required error
+     * will only be used if it is protected by a FAST channel.  Only set
+     * allow_unauth_time if using an unauthenticated time offset would not
+     * create a security issue.
+     */
+    public KerberosTime getPreauthTime() {
+        return KerberosTime.now();
+    }
+
+    /**
+     * Get a state item from an input ccache, which may allow it
+     * to retrace the steps it took last time.  The returned data string is an
+     * alias and should not be freed.
+     */
+    public Object getCacheValue(String key) {
+        return credCache.get(key);
+    }
+
+    /**
+     * Set a state item which will be recorded to an output
+     * ccache, if the calling application supplied one.  Both key and data
+     * should be valid UTF-8 text.
+     */
+    public void cacheValue(String key, Object value) {
+        credCache.put(key, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java
new file mode 100644
index 0000000..60c3ad3
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java
@@ -0,0 +1,117 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerberos.kerb.spec.ap.ApOptions;
+import org.apache.kerberos.kerb.spec.ap.ApReq;
+import org.apache.kerberos.kerb.spec.ap.Authenticator;
+import org.apache.kerberos.kerb.spec.common.EncryptedData;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+import org.apache.kerberos.kerb.spec.common.PrincipalName;
+import org.apache.kerberos.kerb.spec.kdc.*;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerberos.kerb.spec.ticket.TgtTicket;
+
+public class TgsRequest extends KdcRequest {
+    private TgtTicket tgt;
+    private ApReq apReq;
+
+    public TgsRequest(KrbContext context, TgtTicket tgtTicket) {
+        super(context);
+        this.tgt = tgtTicket;
+
+        setAllowedPreauth(PaDataType.TGS_REQ);
+    }
+
+    public PrincipalName getClientPrincipal() {
+        return tgt.getClientPrincipal();
+    }
+
+    @Override
+    public EncryptionKey getClientKey() throws KrbException {
+        return getSessionKey();
+    }
+
+    public EncryptionKey getSessionKey() {
+        return tgt.getSessionKey();
+    }
+
+    @Override
+    protected void preauth() throws KrbException {
+        apReq = makeApReq();
+        super.preauth();
+    }
+
+    @Override
+    public void process() throws KrbException {
+        super.process();
+
+        TgsReq tgsReq = new TgsReq();
+
+        KdcReqBody tgsReqBody = makeReqBody();
+        tgsReq.setReqBody(tgsReqBody);
+        tgsReq.setPaData(getPreauthContext().getOutputPaData());
+
+        setKdcReq(tgsReq);
+    }
+
+    private ApReq makeApReq() throws KrbException {
+        ApReq apReq = new ApReq();
+
+        Authenticator authenticator = makeAuthenticator();
+        EncryptionKey sessionKey = tgt.getSessionKey();
+        EncryptedData authnData = EncryptionUtil.seal(authenticator,
+                sessionKey, KeyUsage.TGS_REQ_AUTH);
+        apReq.setEncryptedAuthenticator(authnData);
+
+        apReq.setTicket(tgt.getTicket());
+        ApOptions apOptions = new ApOptions();
+        apReq.setApOptions(apOptions);
+
+        return apReq;
+    }
+
+    private Authenticator makeAuthenticator() {
+        Authenticator authenticator = new Authenticator();
+        authenticator.setCname(getClientPrincipal());
+        authenticator.setCrealm(tgt.getRealm());
+
+        authenticator.setCtime(KerberosTime.now());
+        authenticator.setCusec(0);
+
+        EncryptionKey sessionKey = tgt.getSessionKey();
+        authenticator.setSubKey(sessionKey);
+
+        return authenticator;
+    }
+
+    @Override
+    public void processResponse(KdcRep kdcRep) throws KrbException {
+        setKdcRep(kdcRep);
+
+        TgsRep tgsRep = (TgsRep) getKdcRep();
+        EncTgsRepPart encTgsRepPart = EncryptionUtil.unseal(tgsRep.getEncryptedEncPart(),
+                getSessionKey(),
+                KeyUsage.TGS_REP_ENCPART_SESSKEY, EncTgsRepPart.class);
+
+        tgsRep.setEncPart(encTgsRepPart);
+
+        if (getChosenNonce() != encTgsRepPart.getNonce()) {
+            throw new KrbException("Nonce didn't match");
+        }
+    }
+
+    public ServiceTicket getServiceTicket() {
+        ServiceTicket serviceTkt = new ServiceTicket(getKdcRep().getTicket(),
+                (EncTgsRepPart) getKdcRep().getEncPart());
+        return serviceTkt;
+    }
+
+    public ApReq getApReq() {
+        return apReq;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-client/src/main/resources/kdc-krb5.conf
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/resources/kdc-krb5.conf b/haox-kerb/kerb-client/src/main/resources/kdc-krb5.conf
new file mode 100644
index 0000000..d118dd1
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/resources/kdc-krb5.conf
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+[libdefaults]
+    default_realm = {0}
+    udp_preference_limit = 1
+
+[realms]
+    {0} = '{'
+        kdc = {1}:{2}
+    '}'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-client/src/main/resources/kdc.ldiff
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/resources/kdc.ldiff b/haox-kerb/kerb-client/src/main/resources/kdc.ldiff
new file mode 100644
index 0000000..e344131
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/resources/kdc.ldiff
@@ -0,0 +1,30 @@
+dn: ou=users,dc=${0},dc=${1}
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: uid=krbtgt,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3}
+krb5KeyVersionNumber: 0
+
+dn: uid=ldap,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: LDAP
+sn: Service
+uid: ldap
+userPassword: secret
+krb5PrincipalName: ldap/${4}@${2}.${3}
+krb5KeyVersionNumber: 0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/pom.xml
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/pom.xml b/haox-kerb/kerb-common/pom.xml
new file mode 100644
index 0000000..9d43089
--- /dev/null
+++ b/haox-kerb/kerb-common/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.haox</groupId>
+        <artifactId>haox-kerb</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>kerb-common</artifactId>
+
+    <name>Haox-kerb Common</name>
+    <description>Haox-kerb Common facilities for both client and server</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>haox-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>haox-event</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>kerb-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>kerb-crypto</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/KrbThrow.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/KrbThrow.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/KrbThrow.java
new file mode 100644
index 0000000..ed6ebaf
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/KrbThrow.java
@@ -0,0 +1,16 @@
+package org.apache.kerberos.kerb;
+
+public class KrbThrow {
+
+    public static KrbException out(MessageCode messageCode) throws KrbException {
+        throw new KrbException(Message.getMessage(messageCode));
+    }
+
+    public static void out(MessageCode messageCode, Exception e) throws KrbException {
+        throw new KrbException(Message.getMessage(messageCode), e);
+    }
+
+    public static void out(MessageCode messageCode, String message) throws KrbException {
+        throw new KrbException(Message.getMessage(messageCode) + ":" + message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/Message.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/Message.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/Message.java
new file mode 100644
index 0000000..f3f807c
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/Message.java
@@ -0,0 +1,24 @@
+package org.apache.kerberos.kerb;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Message {
+    private static Map<MessageCode, String> entries = new HashMap<MessageCode, String>();
+
+    public static void init() {
+
+    }
+
+    public static void define(MessageCode code, String message) {
+        entries.put(code, message);
+    }
+
+    public static String getMessage(MessageCode code) {
+        String msg = entries.get(code);
+        if (msg == null) {
+            msg = code.getCodeName();
+        }
+        return msg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/MessageCode.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/MessageCode.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/MessageCode.java
new file mode 100644
index 0000000..a33aa5c
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/MessageCode.java
@@ -0,0 +1,5 @@
+package org.apache.kerberos.kerb;
+
+public interface MessageCode {
+    public String getCodeName();
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/EncryptionUtil.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/EncryptionUtil.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/EncryptionUtil.java
new file mode 100644
index 0000000..020f6b4
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/EncryptionUtil.java
@@ -0,0 +1,79 @@
+package org.apache.kerberos.kerb.common;
+
+import org.apache.haox.asn1.type.AbstractAsn1Type;
+import org.apache.haox.asn1.type.Asn1Type;
+import org.apache.kerberos.kerb.codec.KrbCodec;
+import org.apache.kerberos.kerb.crypto.EncTypeHandler;
+import org.apache.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.EncryptedData;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EncryptionUtil {
+
+    public static List<EncryptionKey> generateKeys(List<EncryptionType> encryptionTypes) throws KrbException {
+        List<EncryptionKey> results = new ArrayList<EncryptionKey>(encryptionTypes.size());
+        EncryptionKey encKey;
+        for (EncryptionType eType : encryptionTypes) {
+            encKey = EncryptionHandler.random2Key(eType);
+            results.add(encKey);
+        }
+
+        return results;
+    }
+
+    public static List<EncryptionKey> generateKeys(String principal, String passwd,
+                                                   List<EncryptionType> encryptionTypes) throws KrbException {
+        List<EncryptionKey> results = new ArrayList<EncryptionKey>(encryptionTypes.size());
+        EncryptionKey encKey;
+        for (EncryptionType eType : encryptionTypes) {
+            encKey = EncryptionHandler.string2Key(principal, passwd, eType);
+            results.add(encKey);
+        }
+
+        return results;
+    }
+
+    public static EncryptionType getBestEncryptionType(List<EncryptionType> requestedTypes,
+                                                       List<EncryptionType> configuredTypes) {
+        for (EncryptionType encryptionType : configuredTypes) {
+            if (requestedTypes.contains(encryptionType)) {
+                return encryptionType;
+            }
+        }
+
+        return null;
+    }
+
+    public static EncryptedData seal(AbstractAsn1Type asn1Type,
+                                     EncryptionKey key, KeyUsage usage) throws KrbException {
+        byte[] encoded = asn1Type.encode();
+        EncryptedData encrypted = EncryptionHandler.encrypt(encoded, key, usage);
+        return encrypted;
+    }
+
+    public static <T extends Asn1Type> T unseal(EncryptedData encrypted, EncryptionKey key,
+                                          KeyUsage usage, Class<T> krbType) throws KrbException {
+        byte[] encoded = EncryptionHandler.decrypt(encrypted, key, usage);
+        return KrbCodec.decode(encoded, krbType);
+    }
+
+    public static byte[] encrypt(EncryptionKey key,
+          byte[] plaintext, int usage) throws KrbException {
+        EncTypeHandler encType = EncryptionHandler.getEncHandler(key.getKeyType());
+        byte[] cipherData = encType.encrypt(plaintext, key.getKeyData(), usage);
+        return cipherData;
+    }
+
+    public static byte[] decrypt(EncryptionKey key,
+           byte[] cipherData, int usage) throws KrbException {
+        EncTypeHandler encType = EncryptionHandler.getEncHandler(key.getKeyType());
+        byte[] plainData = encType.decrypt(cipherData, key.getKeyData(), usage);
+        return plainData;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbConfHelper.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbConfHelper.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbConfHelper.java
new file mode 100644
index 0000000..fb37813
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbConfHelper.java
@@ -0,0 +1,23 @@
+package org.apache.kerberos.kerb.common;
+
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class KrbConfHelper {
+
+    public static List<EncryptionType> getEncryptionTypes(List<String> encTypeNames) {
+        List<EncryptionType> results = new ArrayList<EncryptionType>(encTypeNames.size());
+
+        EncryptionType etype;
+        for (String etypeName : encTypeNames) {
+            etype = EncryptionType.fromName(etypeName);
+            if (etype != EncryptionType.NONE) {
+                results.add(etype);
+            }
+        }
+        return results;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbErrorUtil.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbErrorUtil.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbErrorUtil.java
new file mode 100644
index 0000000..89ffbf5
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbErrorUtil.java
@@ -0,0 +1,48 @@
+package org.apache.kerberos.kerb.common;
+
+import org.apache.kerberos.kerb.spec.common.*;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class KrbErrorUtil {
+
+    public static List<EncryptionType> getEtypes(KrbError error) throws IOException {
+        MethodData methodData = new MethodData();
+        methodData.decode(error.getEdata());
+
+        for( PaDataEntry pd : methodData.getElements()) {
+            if( pd.getPaDataType() == PaDataType.ETYPE_INFO2 ) {
+                return getEtypes2(pd.getPaDataValue());
+            }
+            else if( pd.getPaDataType() == PaDataType.ETYPE_INFO ) {
+                return getEtypes(pd.getPaDataValue());
+            }
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    private static List<EncryptionType> getEtypes(byte[] data) throws IOException {
+        EtypeInfo info = new EtypeInfo();
+        info.decode(data);
+        List<EncryptionType> results = new ArrayList<EncryptionType>();
+        for( EtypeInfoEntry entry : info.getElements() ) {
+            results.add(entry.getEtype());
+        }
+        return results;
+    }
+
+    private static List<EncryptionType> getEtypes2(byte[] data) throws IOException {
+        EtypeInfo2 info2 = new EtypeInfo2();
+        info2.decode(data);
+        List<EncryptionType> results = new ArrayList<EncryptionType>();
+        for( EtypeInfo2Entry entry : info2.getElements() ) {
+            results.add(entry.getEtype());
+        }
+        return results;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbStreamingDecoder.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbStreamingDecoder.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbStreamingDecoder.java
new file mode 100644
index 0000000..bb91f14
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbStreamingDecoder.java
@@ -0,0 +1,23 @@
+package org.apache.kerberos.kerb.common;
+
+import org.apache.haox.transport.tcp.DecodingCallback;
+import org.apache.haox.transport.tcp.StreamingDecoder;
+
+import java.nio.ByteBuffer;
+
+public class KrbStreamingDecoder implements StreamingDecoder {
+
+    @Override
+    public void decode(ByteBuffer streamingBuffer, DecodingCallback callback) {
+        if (streamingBuffer.remaining() >= 4) {
+            int len = streamingBuffer.getInt();
+            if (streamingBuffer.remaining() >= len) {
+                callback.onMessageComplete(len + 4);
+            } else {
+                callback.onMoreDataNeeded(len + 4);
+            }
+        } else {
+            callback.onMoreDataNeeded();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbUtil.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbUtil.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbUtil.java
new file mode 100644
index 0000000..749fb94
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/common/KrbUtil.java
@@ -0,0 +1,30 @@
+package org.apache.kerberos.kerb.common;
+
+import org.apache.kerberos.kerb.codec.KrbCodec;
+import org.apache.kerberos.kerb.spec.common.KrbMessage;
+import org.apache.haox.transport.Transport;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class KrbUtil {
+
+    public static void sendMessage(KrbMessage message, Transport transport) {
+        int bodyLen = message.encodingLength();
+        ByteBuffer buffer = ByteBuffer.allocate(bodyLen + 4);
+        buffer.putInt(bodyLen);
+        message.encode(buffer);
+        buffer.flip();
+        transport.sendMessage(buffer);
+    }
+
+    public static KrbMessage decodeMessage(ByteBuffer message) throws IOException {
+        int bodyLen = message.getInt();
+        assert (message.remaining() >= bodyLen);
+
+        KrbMessage krbMessage = KrbCodec.decodeMessage(message);
+
+        return krbMessage;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlag.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlag.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlag.java
new file mode 100644
index 0000000..bacbf46
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlag.java
@@ -0,0 +1,30 @@
+package org.apache.kerberos.kerb.preauth;
+
+import org.apache.kerberos.kerb.spec.KrbEnum;
+
+public enum PaFlag implements KrbEnum {
+    NONE(-1),
+    PA_REAL(0x01),
+    PA_INFO(0x02);
+
+    private final int value;
+
+    private PaFlag(int value) {
+        this.value = value;
+    }
+
+    @Override
+    public int getValue() {
+        return value;
+    }
+
+    public static PaFlag fromValue(int value) {
+        for (KrbEnum e : values()) {
+            if (e.getValue() == value) {
+                return (PaFlag) e;
+            }
+        }
+
+        return NONE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlags.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlags.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlags.java
new file mode 100644
index 0000000..2ef4e84
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PaFlags.java
@@ -0,0 +1,18 @@
+package org.apache.kerberos.kerb.preauth;
+
+import org.apache.kerberos.kerb.spec.common.KrbFlags;
+
+public class PaFlags extends KrbFlags {
+
+    public PaFlags() {
+        this(0);
+    }
+
+    public PaFlags(int value) {
+        setFlags(value);
+    }
+
+    public boolean isReal() {
+        return isFlagSet(PaFlag.PA_REAL);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PluginRequestContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PluginRequestContext.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PluginRequestContext.java
new file mode 100644
index 0000000..288164c
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PluginRequestContext.java
@@ -0,0 +1,8 @@
+package org.apache.kerberos.kerb.preauth;
+
+/**
+ * Per request per module
+ */
+public interface PluginRequestContext {
+    // Nothing here, just as a type mark
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PreauthPluginMeta.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PreauthPluginMeta.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PreauthPluginMeta.java
new file mode 100644
index 0000000..d7c8724
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/PreauthPluginMeta.java
@@ -0,0 +1,13 @@
+package org.apache.kerberos.kerb.preauth;
+
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public interface PreauthPluginMeta {
+
+    public String getName();
+
+    public int getVersion();
+
+    public PaDataType[] getPaTypes();
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/EncTsPreauthMeta.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/EncTsPreauthMeta.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/EncTsPreauthMeta.java
new file mode 100644
index 0000000..390bdc3
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/EncTsPreauthMeta.java
@@ -0,0 +1,26 @@
+package org.apache.kerberos.kerb.preauth.builtin;
+
+import org.apache.kerberos.kerb.preauth.PreauthPluginMeta;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class EncTsPreauthMeta implements PreauthPluginMeta {
+
+    private static String NAME = "encrypted_timestamp";
+    private static int VERSION = 1;
+    private static PaDataType[] PA_TYPES = new PaDataType[] {
+            PaDataType.ENC_TIMESTAMP
+    };
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    public int getVersion() {
+        return VERSION;
+    }
+
+    public PaDataType[] getPaTypes() {
+        return PA_TYPES;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/TgtPreauthMeta.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/TgtPreauthMeta.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/TgtPreauthMeta.java
new file mode 100644
index 0000000..d6a4662
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/builtin/TgtPreauthMeta.java
@@ -0,0 +1,29 @@
+package org.apache.kerberos.kerb.preauth.builtin;
+
+import org.apache.kerberos.kerb.preauth.PreauthPluginMeta;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+/**
+ * A faked preauth module for TGS request handling
+ */
+public class TgtPreauthMeta implements PreauthPluginMeta {
+
+    private static String NAME = "TGT_preauth";
+    private static int VERSION = 1;
+    private static PaDataType[] PA_TYPES = new PaDataType[] {
+            PaDataType.TGS_REQ
+    };
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    public int getVersion() {
+        return VERSION;
+    }
+
+    public PaDataType[] getPaTypes() {
+        return PA_TYPES;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityOpts.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityOpts.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityOpts.java
new file mode 100644
index 0000000..a45e025
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityOpts.java
@@ -0,0 +1,25 @@
+package org.apache.kerberos.kerb.preauth.pkinit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class IdentityOpts {
+
+    // From MIT Krb5 _pkinit_identity_opts
+    public String identity;
+    public List<String> AltIdentities = new ArrayList<String>(1);
+    public List<String> anchors = new ArrayList<String>(4);
+    public List<String> intermediates = new ArrayList<String>(2);
+    public List<String> crls = new ArrayList<String>(2);
+    public String ocsp;
+    public IdentityType idType;
+    public String certFile;
+    public String keyFile;
+
+    // PKCS11
+    public String p11ModuleName;
+    public int slotid;
+    public String tokenLabel;
+    public String certId;
+    public String certLabel;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityType.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityType.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityType.java
new file mode 100644
index 0000000..e62098b
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/IdentityType.java
@@ -0,0 +1,10 @@
+package org.apache.kerberos.kerb.preauth.pkinit;
+
+public enum IdentityType {
+    NONE,
+    FILE,
+    DIR,
+    PKCS11,
+    PKCS12,
+    ENVVAR,
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitIdenity.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitIdenity.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitIdenity.java
new file mode 100644
index 0000000..753011b
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitIdenity.java
@@ -0,0 +1,109 @@
+package org.apache.kerberos.kerb.preauth.pkinit;
+
+import org.apache.kerberos.kerb.spec.common.PrincipalName;
+
+public class PkinitIdenity {
+
+    public static void processIdentityOption(IdentityOpts identityOpts, String value) {
+        IdentityType idType = IdentityType.NONE;
+        String residual = null;
+        if (value.contains(":")) {
+            if (value.startsWith("FILE:")) {
+                idType = IdentityType.FILE;
+            } else if (value.startsWith("PKCS11:")) {
+                idType = IdentityType.PKCS11;
+            } else if (value.startsWith("PKCS12:")) {
+                idType = IdentityType.PKCS12;
+            } else if (value.startsWith("DIR:")) {
+                idType = IdentityType.DIR;
+            } else if (value.startsWith("ENV:")) {
+                idType = IdentityType.ENVVAR;
+            } else {
+                throw new RuntimeException("Invalid Identity option format: " + value);
+            }
+        } else {
+            residual = value;
+            idType = IdentityType.FILE;
+        }
+
+        identityOpts.idType = idType;
+        switch (idType) {
+            case ENVVAR:
+                processIdentityOption(identityOpts, System.getenv(residual));
+                break;
+            case FILE:
+                parseFileOption(identityOpts, residual);
+                break;
+            case PKCS11:
+                parsePkcs11Option(identityOpts, residual);
+                break;
+            case PKCS12:
+                parsePkcs12Option(identityOpts, residual);
+                break;
+            case DIR:
+                identityOpts.certFile = residual;
+                break;
+        }
+    }
+
+    public static void parseFileOption(IdentityOpts identityOpts, String residual) {
+        String[] parts = residual.split(",");
+        String certName = null;
+        String keyName = null;
+
+        certName = parts[0];
+        if (parts.length > 1) {
+            keyName = parts[1];
+        }
+
+        identityOpts.certFile = certName;
+        identityOpts.keyFile = keyName;
+    }
+
+    public static void parsePkcs12Option(IdentityOpts identityOpts, String residual) {
+        identityOpts.certFile = residual;
+        identityOpts.keyFile = residual;
+    }
+
+    public static void parsePkcs11Option(IdentityOpts identityOpts, String residual) {
+        // TODO
+    }
+
+    public static void loadCerts(IdentityOpts identityOpts, PrincipalName principal) {
+        switch (identityOpts.idType) {
+            case FILE:
+                loadCertsFromFile(identityOpts, principal);
+                break;
+            case DIR:
+                loadCertsFromDir(identityOpts, principal);
+                break;
+            case PKCS11:
+                loadCertsAsPkcs11(identityOpts, principal);
+                break;
+            case PKCS12:
+                loadCertsAsPkcs12(identityOpts, principal);
+                break;
+        }
+    }
+
+    private static void loadCertsAsPkcs12(IdentityOpts identityOpts, PrincipalName principal) {
+
+    }
+
+    private static void loadCertsAsPkcs11(IdentityOpts identityOpts, PrincipalName principal) {
+
+    }
+
+    private static void loadCertsFromDir(IdentityOpts identityOpts, PrincipalName principal) {
+
+    }
+
+    private static void loadCertsFromFile(IdentityOpts identityOpts, PrincipalName principal) {
+
+    }
+
+    public static void initialize(IdentityOpts identityOpts, PrincipalName principal) {
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitPreauthMeta.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitPreauthMeta.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitPreauthMeta.java
new file mode 100644
index 0000000..8fe593a
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PkinitPreauthMeta.java
@@ -0,0 +1,27 @@
+package org.apache.kerberos.kerb.preauth.pkinit;
+
+import org.apache.kerberos.kerb.preauth.PreauthPluginMeta;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class PkinitPreauthMeta implements PreauthPluginMeta {
+
+    private static String NAME = "PKINIT";
+    private static int VERSION = 1;
+    private static PaDataType[] PA_TYPES = new PaDataType[] {
+            PaDataType.PK_AS_REQ,
+            PaDataType.PK_AS_REP,
+    };
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    public int getVersion() {
+        return VERSION;
+    }
+
+    public PaDataType[] getPaTypes() {
+        return PA_TYPES;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PluginOpts.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PluginOpts.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PluginOpts.java
new file mode 100644
index 0000000..7aae8d7
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/pkinit/PluginOpts.java
@@ -0,0 +1,48 @@
+package org.apache.kerberos.kerb.preauth.pkinit;
+
+import org.apache.haox.asn1.type.Asn1ObjectIdentifier;
+import org.apache.kerberos.kerb.spec.pa.pkinit.AlgorithmIdentifiers;
+import org.apache.kerberos.kerb.spec.pa.pkinit.TrustedCertifiers;
+import org.apache.kerberos.kerb.spec.x509.AlgorithmIdentifier;
+
+public class PluginOpts {
+
+    // From MIT Krb5 _pkinit_plg_opts
+
+    // require EKU checking (default is true)
+    public boolean requireEku = true;
+    // accept secondary EKU (default is false)
+    public boolean acceptSecondaryEku = false;
+    // allow UPN-SAN instead of pkinit-SAN
+    public boolean allowUpn = true;
+    // selects DH or RSA based pkinit
+    public boolean usingRsa = true;
+    // 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.
+    // The acceptable values are 1024, 2048, and 4096. The default is 2048.
+    public int dhMinBits = 2048;
+
+    public AlgorithmIdentifiers createSupportedCMSTypes() {
+        AlgorithmIdentifiers cmsAlgorithms = new AlgorithmIdentifiers();
+        AlgorithmIdentifier des3Alg = new AlgorithmIdentifier();
+        cmsAlgorithms.add(des3Alg);
+
+        String oidStr = "DES3-OID";
+        Asn1ObjectIdentifier des3Oid = new Asn1ObjectIdentifier(oidStr);
+        des3Alg.setAlgorithm(des3Oid);
+        des3Alg.setParameters(null);
+
+        return cmsAlgorithms;
+    }
+
+    public TrustedCertifiers createTrustedCertifiers() {
+        TrustedCertifiers trustedCertifiers = new TrustedCertifiers();
+
+        return trustedCertifiers;
+    }
+
+    public byte[] createIssuerAndSerial() {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/token/TokenPreauthMeta.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/token/TokenPreauthMeta.java b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/token/TokenPreauthMeta.java
new file mode 100644
index 0000000..de3d5dc
--- /dev/null
+++ b/haox-kerb/kerb-common/src/main/java/org/apache/kerberos/kerb/preauth/token/TokenPreauthMeta.java
@@ -0,0 +1,27 @@
+package org.apache.kerberos.kerb.preauth.token;
+
+import org.apache.kerberos.kerb.preauth.PreauthPluginMeta;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class TokenPreauthMeta implements PreauthPluginMeta {
+
+    private static String NAME = "TokenPreauth";
+    private static int VERSION = 1;
+    private static PaDataType[] PA_TYPES = new PaDataType[] {
+            PaDataType.TOKEN_CHALLENGE,
+            PaDataType.TOKEN_REQUEST
+    };
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    public int getVersion() {
+        return VERSION;
+    }
+
+    public PaDataType[] getPaTypes() {
+        return PA_TYPES;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/pom.xml
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/pom.xml b/haox-kerb/kerb-core-test/pom.xml
new file mode 100644
index 0000000..bb7b730
--- /dev/null
+++ b/haox-kerb/kerb-core-test/pom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.haox</groupId>
+        <artifactId>haox-kerb</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>kerb-core-test</artifactId>
+
+    <name>haox-kerb-coreTest</name>
+    <description>Kerb core tests</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>haox-asn1</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>kerb-core</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>kerb-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/aes128-kerberos-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/aes128-kerberos-data b/haox-kerb/kerb-core-test/src/main/resources/aes128-kerberos-data
new file mode 100644
index 0000000..7f3b582
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/aes128-kerberos-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/aes128-key-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/aes128-key-data b/haox-kerb/kerb-core-test/src/main/resources/aes128-key-data
new file mode 100644
index 0000000..4ba2540
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/main/resources/aes128-key-data
@@ -0,0 +1 @@
+����\���U�s�7"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/aes128-spnego-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/aes128-spnego-data b/haox-kerb/kerb-core-test/src/main/resources/aes128-spnego-data
new file mode 100644
index 0000000..13c89e6
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/aes128-spnego-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/aes256-kerberos-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/aes256-kerberos-data b/haox-kerb/kerb-core-test/src/main/resources/aes256-kerberos-data
new file mode 100644
index 0000000..b7d539f
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/aes256-kerberos-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/aes256-key-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/aes256-key-data b/haox-kerb/kerb-core-test/src/main/resources/aes256-key-data
new file mode 100644
index 0000000..24792c1
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/aes256-key-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/aes256-spnego-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/aes256-spnego-data b/haox-kerb/kerb-core-test/src/main/resources/aes256-spnego-data
new file mode 100644
index 0000000..6a7e55c
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/aes256-spnego-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/des-kerberos-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/des-kerberos-data b/haox-kerb/kerb-core-test/src/main/resources/des-kerberos-data
new file mode 100644
index 0000000..3db6963
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/des-kerberos-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/des-key-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/des-key-data b/haox-kerb/kerb-core-test/src/main/resources/des-key-data
new file mode 100644
index 0000000..84a0c50
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/main/resources/des-key-data
@@ -0,0 +1 @@
+��2^�L�
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/des-pac-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/des-pac-data b/haox-kerb/kerb-core-test/src/main/resources/des-pac-data
new file mode 100644
index 0000000..7408111
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/des-pac-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/des-spnego-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/des-spnego-data b/haox-kerb/kerb-core-test/src/main/resources/des-spnego-data
new file mode 100644
index 0000000..04a56e8
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/des-spnego-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/exceptions.properties
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/exceptions.properties b/haox-kerb/kerb-core-test/src/main/resources/exceptions.properties
new file mode 100644
index 0000000..1695c63
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/main/resources/exceptions.properties
@@ -0,0 +1,39 @@
+object.cast.fail=Unable to cast object from {0} to {1}.
+
+spnego.token.empty=Empty SPNego token.
+spnego.token.invalid=Not a valid SPNego token: {0}.
+spnego.token.malformed=Malformed SPNego token.
+spnego.field.invalid=Not a valid SPNego token field: {0}.
+
+
+kerberos.object.cast=Unable to cast Kerberos object from {0} to {1}.
+kerberos.token.empty=Empty Kerberos token.
+kerberos.token.invalid=Not a Kerberos token.
+kerberos.token.malformed=Malformed Kerberos token.
+kerberos.kdcReq.empty=Empty message.
+kerberos.kdcReq.invalid=Not a KRB_AP_REQ message.
+kerberos.ticket.empty=Empty Kerberos ticket.
+kerberos.ticket.invalid=Not a Kerberos v5 ticket.
+kerberos.ticket.malformed=Malformed Kerberos ticket.
+kerberos.field.invalid=Not a valid Kerberos ticket field: {0}.
+kerberos.field.malformed=Malformed Kerberos ticket field.
+kerberos.key.notfound=Unable to find appropriate key of type {0}.
+kerberos.version.invalid=Invalid version of Kerberos ticket: {0}.
+kerberos.login.fail=Unable to get server keys.
+kerberos.decrypt.fail=Unable to decrypt encrypted data using key of type {0}.
+
+pac.token.empty=Empty PAC token.
+pac.token.malformed=Malformed PAC token.
+pac.logoninfo.malformed=Malformed PAC logon info.
+pac.signature.malformed=Malformed PAC signature.
+pac.signature.invalid=Invalid PAC signature.
+pac.string.notempty=String not empty while expected null.
+pac.string.malformed.size=Inconsistent string lengths.
+pac.string.invalid.size=Inconsistent string size: {1}, expecting {0}.
+pac.groups.invalid.size=Group count ({0}) doesn't match the real number of groups ({1}) in the PAC.
+pac.extrasids.invalid.size=Extra SID count ({0}) doesn't match the real number of extra SID ({1}) in the PAC.
+pac.resourcegroups.invalid.size=Resource group count ({0}) doesn't match the real number of resource groups ({1}) in the PAC.
+pac.sid.malformed.size=Inconsistent SID length.
+pac.subauthority.malformed.size=Incorrect byte array length: {0}; must be multiple of 4.
+pac.version.invalid=Invalid version of PAC token: {0}.
+pac.check.fail=Unable to check PAC signature.

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/rc4-kerberos-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/rc4-kerberos-data b/haox-kerb/kerb-core-test/src/main/resources/rc4-kerberos-data
new file mode 100644
index 0000000..6be7086
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/rc4-kerberos-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/rc4-key-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/rc4-key-data b/haox-kerb/kerb-core-test/src/main/resources/rc4-key-data
new file mode 100644
index 0000000..64f9d9c
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/main/resources/rc4-key-data
@@ -0,0 +1 @@
+l�܇y#�l�mv��k�
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/rc4-pac-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/rc4-pac-data b/haox-kerb/kerb-core-test/src/main/resources/rc4-pac-data
new file mode 100644
index 0000000..df45f91
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/rc4-pac-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/rc4-spnego-data
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/rc4-spnego-data b/haox-kerb/kerb-core-test/src/main/resources/rc4-spnego-data
new file mode 100644
index 0000000..91cbe26
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/rc4-spnego-data differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/main/resources/server.keytab
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/main/resources/server.keytab b/haox-kerb/kerb-core-test/src/main/resources/server.keytab
new file mode 100644
index 0000000..b44347c
Binary files /dev/null and b/haox-kerb/kerb-core-test/src/main/resources/server.keytab differ

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/README.txt
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/README.txt b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/README.txt
new file mode 100644
index 0000000..f1e0a3f
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/README.txt
@@ -0,0 +1,5 @@
+This project is simple for integration testing purpose. It's inspired by and originated from JaasLaunge.
+Eventually I will replace most of the codes by mine or get the granting permission of the author.
+
+http://jaaslounge.sourceforge.net/
+

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/AuthzDataUtil.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/AuthzDataUtil.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/AuthzDataUtil.java
new file mode 100644
index 0000000..da2a610
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/AuthzDataUtil.java
@@ -0,0 +1,48 @@
+package org.apache.kerberos.kerb.codec.kerberos;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.codec.pac.Pac;
+import org.apache.kerberos.kerb.spec.common.AuthorizationData;
+import org.apache.kerberos.kerb.spec.common.AuthorizationDataEntry;
+import org.apache.kerberos.kerb.spec.common.AuthorizationType;
+
+import java.io.IOException;
+import java.util.List;
+
+public class AuthzDataUtil {
+
+    public static Pac getPac(AuthorizationData authzData, byte[] serverKey) throws IOException, KrbException {
+        AuthorizationDataEntry ifRelevantAd = null;
+        for (AuthorizationDataEntry entry : authzData.getElements()) {
+            if (entry.getAuthzType() == AuthorizationType.AD_IF_RELEVANT) {
+                ifRelevantAd = entry;
+                break;
+            }
+        }
+
+        if (ifRelevantAd != null) {
+            List<AuthorizationDataEntry> entries = decode(ifRelevantAd);
+            for (AuthorizationDataEntry entry : entries) {
+                if (entry.getAuthzType() == AuthorizationType.AD_WIN2K_PAC) {
+                    return decodeAsPac(entry, serverKey);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public static List<AuthorizationDataEntry> decode(AuthorizationDataEntry entry) throws IOException {
+        AuthorizationData authzData = new AuthorizationData();
+        authzData.decode(entry.getAuthzData());
+        return authzData.getElements();
+    }
+
+    public static Pac decodeAsPac(AuthorizationDataEntry entry, byte[] key) throws IOException, KrbException {
+        if (entry.getAuthzType() != AuthorizationType.AD_WIN2K_PAC) {
+            throw new IllegalArgumentException("Not AD_WIN2K_PAC type: " + entry.getAuthzType().name());
+        }
+
+        return new Pac(entry.getAuthzData(), key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosApRequest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosApRequest.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosApRequest.java
new file mode 100644
index 0000000..61eb109
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosApRequest.java
@@ -0,0 +1,32 @@
+package org.apache.kerberos.kerb.codec.kerberos;
+
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.codec.KrbCodec;
+import org.apache.kerberos.kerb.spec.ap.ApOptions;
+import org.apache.kerberos.kerb.spec.ap.ApReq;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+
+import java.io.IOException;
+
+public class KerberosApRequest {
+    private ApReq apReq;
+    private KerberosTicket ticket;
+
+    public KerberosApRequest(byte[] token, EncryptionKey key) throws Exception {
+        if(token.length <= 0) {
+            throw new IOException("kerberos request empty");
+        }
+
+        apReq = KrbCodec.decode(token, ApReq.class);
+        ticket = new KerberosTicket(apReq.getTicket(), apReq.getApOptions(), key);
+    }
+
+    public ApOptions getApOptions() throws KrbException {
+        return apReq.getApOptions();
+    }
+
+    public KerberosTicket getTicket() {
+        return ticket;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosConstants.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosConstants.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosConstants.java
new file mode 100644
index 0000000..52d4a8e
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosConstants.java
@@ -0,0 +1,25 @@
+package org.apache.kerberos.kerb.codec.kerberos;
+
+public interface KerberosConstants {
+
+    static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
+    static final String KERBEROS_VERSION = "5";
+
+    static final String KERBEROS_AP_REQ = "14";
+    
+    static final int AF_INTERNET = 2;
+    static final int AF_CHANET = 5;
+    static final int AF_XNS = 6;
+    static final int AF_ISO = 7;
+    
+    static final int AUTH_DATA_RELEVANT = 1;
+    static final int AUTH_DATA_PAC = 128;
+
+    static final int DES_ENC_TYPE = 3;
+    static final int RC4_ENC_TYPE = 23;
+    static final String RC4_ALGORITHM = "ARCFOUR";
+    static final String HMAC_ALGORITHM = "HmacMD5";
+    static final int CONFOUNDER_SIZE = 8;
+    static final int CHECKSUM_SIZE = 16;
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosCredentials.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosCredentials.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosCredentials.java
new file mode 100644
index 0000000..1d0acdb
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosCredentials.java
@@ -0,0 +1,36 @@
+package org.apache.kerberos.kerb.codec.kerberos;
+
+import org.apache.kerberos.kerb.keytab.Keytab;
+import org.apache.kerberos.kerb.keytab.KeytabEntry;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+import org.apache.kerberos.kerb.spec.common.PrincipalName;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class KerberosCredentials {
+
+    private static Keytab keytab;
+
+    private static void init() throws IOException {
+        InputStream kis = KerberosCredentials.class.getResourceAsStream("/server.keytab");
+        keytab = new Keytab();
+        keytab.load(kis);
+    }
+
+    public static EncryptionKey getServerKey(EncryptionType etype) throws IOException {
+        if (keytab == null) {
+            init();
+        }
+
+        for (PrincipalName principal : keytab.getPrincipals()) {
+            for (KeytabEntry entry : keytab.getKeytabEntries(principal)) {
+                if (entry.getKey().getKeyType() == etype) {
+                    return entry.getKey();
+                }
+            }
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosTicket.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosTicket.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosTicket.java
new file mode 100644
index 0000000..66ed831
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosTicket.java
@@ -0,0 +1,67 @@
+package org.apache.kerberos.kerb.codec.kerberos;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.codec.KrbCodec;
+import org.apache.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerberos.kerb.spec.ap.ApOptions;
+import org.apache.kerberos.kerb.spec.common.AuthorizationData;
+import org.apache.kerberos.kerb.spec.common.EncryptedData;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+import org.apache.kerberos.kerb.spec.ticket.EncTicketPart;
+import org.apache.kerberos.kerb.spec.ticket.Ticket;
+
+import java.util.Arrays;
+
+public class KerberosTicket {
+    private String serverPrincipalName;
+    private String serverRealm;
+    private Ticket ticket;
+
+    public KerberosTicket(Ticket ticket, ApOptions apOptions, EncryptionKey key)
+            throws Exception {
+        this.ticket = ticket;
+
+        byte[] decrypted = EncryptionHandler.decrypt(
+                ticket.getEncryptedEncPart(), key, KeyUsage.KDC_REP_TICKET);
+
+        EncTicketPart encPart = KrbCodec.decode(decrypted, EncTicketPart.class);
+        ticket.setEncPart(encPart);
+
+        /**
+         * Also test encryption by the way
+         */
+        EncryptedData encrypted = EncryptionHandler.encrypt(
+                decrypted, key, KeyUsage.KDC_REP_TICKET);
+
+        byte[] decrypted2 = EncryptionHandler.decrypt(
+                encrypted, key, KeyUsage.KDC_REP_TICKET);
+        if (!Arrays.equals(decrypted, decrypted2)) {
+            throw new KrbException("Encryption checking failed after decryption");
+        }
+    }
+
+    public String getUserPrincipalName() throws KrbException {
+        return ticket.getEncPart().getCname().getName();
+    }
+
+    public String getUserRealm() throws KrbException {
+        return ticket.getEncPart().getCrealm();
+    }
+
+    public String getServerPrincipalName() throws KrbException {
+        return ticket.getSname().getName();
+    }
+
+    public String getServerRealm() throws KrbException {
+        return ticket.getRealm();
+    }
+
+    public AuthorizationData getAuthorizationData() throws KrbException {
+        return ticket.getEncPart().getAuthorizationData();
+    }
+
+    public Ticket getTicket() {
+        return ticket;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosToken.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosToken.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosToken.java
new file mode 100644
index 0000000..8398f74
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/kerberos/KerberosToken.java
@@ -0,0 +1,39 @@
+package org.apache.kerberos.kerb.codec.kerberos;
+
+import org.apache.haox.asn1.Asn1InputBuffer;
+import org.apache.haox.asn1.type.Asn1Item;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+
+import java.io.IOException;
+
+public class KerberosToken {
+
+    private KerberosApRequest apRequest;
+
+    public KerberosToken(byte[] token) throws Exception {
+        this(token, null);
+    }
+
+    public KerberosToken(byte[] token, EncryptionKey key) throws Exception {
+
+        if(token.length <= 0)
+            throw new IOException("kerberos.token.empty");
+
+        Asn1InputBuffer buffer = new Asn1InputBuffer(token);
+
+        Asn1Item value = (Asn1Item) buffer.read();
+        if(! value.isAppSpecific() && ! value.isConstructed())
+            throw new IOException("kerberos.token.malformed");
+
+        buffer = new Asn1InputBuffer(value.getBodyContent());
+        buffer.skipNext();
+
+        buffer.skipBytes(2);
+
+        apRequest = new KerberosApRequest(buffer.readAllLeftBytes(), key);
+    }
+
+    public KerberosApRequest getApRequest() {
+        return apRequest;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/Pac.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/Pac.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/Pac.java
new file mode 100644
index 0000000..0761999
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/Pac.java
@@ -0,0 +1,94 @@
+package org.apache.kerberos.kerb.codec.pac;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.crypto.CheckSumHandler;
+import org.apache.kerberos.kerb.spec.common.CheckSum;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+public class Pac {
+
+    private PacLogonInfo logonInfo;
+    private PacCredentialType credentialType;
+    private PacSignature serverSignature;
+    private PacSignature kdcSignature;
+
+    public Pac(byte[] data, byte[] key) throws KrbException {
+        byte[] checksumData = data.clone();
+        try {
+            PacDataInputStream pacStream = new PacDataInputStream(new DataInputStream(
+                    new ByteArrayInputStream(data)));
+
+            if(data.length <= 8)
+                throw new IOException("pac.token.empty");
+
+            int bufferCount = pacStream.readInt();
+            int version = pacStream.readInt();
+
+            if(version != PacConstants.PAC_VERSION) {
+                Object[] args = new Object[]{version};
+                throw new IOException("pac.version.invalid");
+            }
+
+            for(int bufferIndex = 0; bufferIndex < bufferCount; bufferIndex++) {
+                int bufferType = pacStream.readInt();
+                int bufferSize = pacStream.readInt();
+                long bufferOffset = pacStream.readLong();
+                byte[] bufferData = new byte[bufferSize];
+                System.arraycopy(data, (int)bufferOffset, bufferData, 0, bufferSize);
+
+                switch (bufferType) {
+                case PacConstants.LOGON_INFO:
+                    // PAC Credential Information
+                    logonInfo = new PacLogonInfo(bufferData);
+                    break;
+                case PacConstants.CREDENTIAL_TYPE:
+                    // PAC Credential Type
+                    credentialType = new PacCredentialType(bufferData);
+                    break;
+                case PacConstants.SERVER_CHECKSUM:
+                    // PAC Server Signature
+                    serverSignature = new PacSignature(bufferData);
+                    // Clear signature from checksum copy
+                    for(int i = 0; i < bufferSize; i++)
+                        checksumData[(int)bufferOffset + 4 + i] = 0;
+                    break;
+                case PacConstants.PRIVSVR_CHECKSUM:
+                    // PAC KDC Signature
+                    kdcSignature = new PacSignature(bufferData);
+                    // Clear signature from checksum copy
+                    for(int i = 0; i < bufferSize; i++)
+                        checksumData[(int)bufferOffset + 4 + i] = 0;
+                    break;
+                default:
+                }
+            }
+        } catch(IOException e) {
+            throw new KrbException("pac.token.malformed", e);
+        }
+
+        CheckSum checksum = new CheckSum(serverSignature.getType(), serverSignature.getChecksum());
+        if (! CheckSumHandler.verifyWithKey(checksum, checksumData, key, KeyUsage.APP_DATA_CKSUM)) {
+            throw new KrbException("Check sum verifying failed");
+        }
+    }
+
+    public PacLogonInfo getLogonInfo() {
+        return logonInfo;
+    }
+
+    public PacCredentialType getCredentialType() {
+        return credentialType;
+    }
+
+    public PacSignature getServerSignature() {
+        return serverSignature;
+    }
+
+    public PacSignature getKdcSignature() {
+        return kdcSignature;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacConstants.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacConstants.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacConstants.java
new file mode 100644
index 0000000..3ade7b2
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacConstants.java
@@ -0,0 +1,20 @@
+package org.apache.kerberos.kerb.codec.pac;
+
+public interface PacConstants {
+
+    static final int PAC_VERSION = 0;
+
+    static final int LOGON_INFO = 1;
+    static final int CREDENTIAL_TYPE = 2;
+    static final int SERVER_CHECKSUM = 6;
+    static final int PRIVSVR_CHECKSUM = 7;
+
+    static final int LOGON_EXTRA_SIDS = 0x20;
+    static final int LOGON_RESOURCE_GROUPS = 0x200;
+
+    static final long FILETIME_BASE = -11644473600000L;
+
+    static final int MD5_KRB_SALT = 17;
+    static final int MD5_BLOCK_LENGTH = 64;
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacCredentialType.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacCredentialType.java b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacCredentialType.java
new file mode 100644
index 0000000..75fe338
--- /dev/null
+++ b/haox-kerb/kerb-core-test/src/test/java/org/apache/kerberos/kerb/codec/pac/PacCredentialType.java
@@ -0,0 +1,22 @@
+package org.apache.kerberos.kerb.codec.pac;
+
+import java.io.IOException;
+
+public class PacCredentialType {
+
+    private static final int MINIMAL_BUFFER_SIZE = 32;
+
+    private byte[] credentialType;
+
+    public PacCredentialType(byte[] data) throws IOException {
+        credentialType = data;
+        if(!isCredentialTypeCorrect()) {
+            throw new IOException("pac.credentialtype.malformed");
+        }
+    }
+
+    public boolean isCredentialTypeCorrect() {
+        return credentialType != null && credentialType.length < MINIMAL_BUFFER_SIZE;
+    }
+
+}


Mime
View raw message