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/05/26 07:39:36 UTC

directory-kerby git commit: [DIRKRB-124]-Implementing preauth/FAST framework.

Repository: directory-kerby
Updated Branches:
  refs/heads/master f6c9665dc -> c0f382089


[DIRKRB-124]-Implementing preauth/FAST framework.


Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/c0f38208
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/c0f38208
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/c0f38208

Branch: refs/heads/master
Commit: c0f3820890ef505529920b465084925a27b9037d
Parents: f6c9665
Author: plusplusjiajia <ji...@intel.com>
Authored: Tue May 26 13:44:17 2015 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Tue May 26 13:44:17 2015 +0800

----------------------------------------------------------------------
 .../kerb/client/preauth/KrbFastContext.java     |  86 ------------
 .../client/preauth/KrbFastRequestState.java     |  86 ++++++++++++
 .../kerb/client/request/ArmoredAsRequest.java   | 134 +++++++++++++++++--
 .../kerberos/kerb/client/request/AsRequest.java |  14 +-
 .../kerb/client/request/KdcRequest.java         |  47 ++++++-
 .../kerb/client/request/TgsRequest.java         |  26 ++--
 .../kerberos/kerb/common/CheckSumUtil.java      |  47 +++++++
 .../kerb/server/request/KdcRequest.java         |  70 ++++++++++
 8 files changed, 388 insertions(+), 122 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastContext.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastContext.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastContext.java
deleted file mode 100644
index 7aa031e..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastContext.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.client.preauth;
-
-import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
-import org.apache.kerby.kerberos.kerb.spec.fast.FastOptions;
-import org.apache.kerby.kerberos.kerb.spec.fast.KrbFastArmor;
-import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
-
-/**
- * Maintaining FAST processing state in client side per request.
- */
-public class KrbFastContext {
-
-    private KdcReq fastOuterRequest;
-    private EncryptionKey armorKey;
-    private KrbFastArmor fastArmor;
-    private FastOptions fastOptions;
-    private int nonce;
-    private int fastFlags;
-
-    public KdcReq getFastOuterRequest() {
-        return fastOuterRequest;
-    }
-
-    public void setFastOuterRequest(KdcReq fastOuterRequest) {
-        this.fastOuterRequest = fastOuterRequest;
-    }
-
-    public EncryptionKey getArmorKey() {
-        return armorKey;
-    }
-
-    public void setArmorKey(EncryptionKey armorKey) {
-        this.armorKey = armorKey;
-    }
-
-    public KrbFastArmor getFastArmor() {
-        return fastArmor;
-    }
-
-    public void setFastArmor(KrbFastArmor fastArmor) {
-        this.fastArmor = fastArmor;
-    }
-
-    public FastOptions getFastOptions() {
-        return fastOptions;
-    }
-
-    public void setFastOptions(FastOptions fastOptions) {
-        this.fastOptions = fastOptions;
-    }
-
-    public int getNonce() {
-        return nonce;
-    }
-
-    public void setNonce(int nonce) {
-        this.nonce = nonce;
-    }
-
-    public int getFastFlags() {
-        return fastFlags;
-    }
-
-    public void setFastFlags(int fastFlags) {
-        this.fastFlags = fastFlags;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastRequestState.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastRequestState.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastRequestState.java
new file mode 100644
index 0000000..5db3d5e
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbFastRequestState.java
@@ -0,0 +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.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth;
+
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.spec.fast.FastOptions;
+import org.apache.kerby.kerberos.kerb.spec.fast.KrbFastArmor;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
+
+/**
+ * Maintaining FAST processing state in client side per request.
+ */
+public class KrbFastRequestState {
+
+    private KdcReq fastOuterRequest;
+    private EncryptionKey armorKey;
+    private KrbFastArmor fastArmor;
+    private FastOptions fastOptions;
+    private int nonce;
+    private int fastFlags;
+
+    public KdcReq getFastOuterRequest() {
+        return fastOuterRequest;
+    }
+
+    public void setFastOuterRequest(KdcReq fastOuterRequest) {
+        this.fastOuterRequest = fastOuterRequest;
+    }
+
+    public EncryptionKey getArmorKey() {
+        return armorKey;
+    }
+
+    public void setArmorKey(EncryptionKey armorKey) {
+        this.armorKey = armorKey;
+    }
+
+    public KrbFastArmor getFastArmor() {
+        return fastArmor;
+    }
+
+    public void setFastArmor(KrbFastArmor fastArmor) {
+        this.fastArmor = fastArmor;
+    }
+
+    public FastOptions getFastOptions() {
+        return fastOptions;
+    }
+
+    public void setFastOptions(FastOptions fastOptions) {
+        this.fastOptions = fastOptions;
+    }
+
+    public int getNonce() {
+        return nonce;
+    }
+
+    public void setNonce(int nonce) {
+        this.nonce = nonce;
+    }
+
+    public int getFastFlags() {
+        return fastFlags;
+    }
+
+    public void setFastFlags(int fastFlags) {
+        this.fastFlags = fastFlags;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
index f0831ee..8ad5a88 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
@@ -19,13 +19,37 @@
  */
 package org.apache.kerby.kerberos.kerb.client.request;
 
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.ccache.Credential;
 import org.apache.kerby.kerberos.kerb.ccache.CredentialCache;
-import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
+import org.apache.kerby.kerberos.kerb.client.preauth.KrbFastRequestState;
+import org.apache.kerby.kerberos.kerb.common.CheckSumUtil;
+import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
 import org.apache.kerby.kerberos.kerb.crypto.fast.FastUtil;
+import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerby.kerberos.kerb.spec.ap.ApOptions;
+import org.apache.kerby.kerberos.kerb.spec.ap.ApReq;
+import org.apache.kerby.kerberos.kerb.spec.ap.Authenticator;
+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.EncryptedData;
 import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
+import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
+import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+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.AsReq;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
+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.ticket.Ticket;
 
 import java.io.File;
 import java.io.IOException;
@@ -35,11 +59,27 @@ import java.io.IOException;
  */
 public abstract class ArmoredAsRequest extends AsRequest {
 
+    private Credential credential;
+    private EncryptionKey subKey;
+
     public ArmoredAsRequest(KrbContext context) {
         super(context);
     }
 
     @Override
+    protected void preauth() throws KrbException {
+        makeArmorKey();
+        super.preauth();
+    }
+
+    @Override
+    public void process() throws KrbException {
+        super.process();
+        fastAsArmor();
+        getKdcReq().getPaData().addElement(makeFastEntry());
+    }
+
+    @Override
     public KOptions getPreauthOptions() {
         KOptions results = new KOptions();
 
@@ -49,27 +89,45 @@ public abstract class ArmoredAsRequest extends AsRequest {
         return results;
     }
 
+    @Override
+    public EncryptionKey getClientKey() throws KrbException {
+        return getFastRequestState().getArmorKey();
+    }
+
     /**
      * Prepare FAST armor key.
      * @return
      * @throws KrbException
      */
     protected EncryptionKey makeArmorKey() throws KrbException {
-        EncryptionKey subKey = null;
-        EncryptionKey armorCacheKey = getArmorCacheKey();
-        EncryptionKey armorKey = FastUtil.cf2(subKey, "subkeyarmor", armorCacheKey, "ticketarmor");
+        getCredential();
 
+        EncryptionKey armorCacheKey = getArmorCacheKey();
+        subKey = getSubKey(armorCacheKey.getKeyType());
+        EncryptionKey armorKey = FastUtil.cf2(subKey, "subkeyarmor",
+            armorCacheKey, "ticketarmor");
+        getFastRequestState().setArmorKey(armorKey);
         return armorKey;
     }
 
+    protected EncryptionKey getSubKey(EncryptionType type) throws KrbException {
+        return EncryptionHandler.random2Key(type);
+    }
+
     /**
      * Get armor cache key.
      * @return armor cache key
      * @throws KrbException
      */
     protected EncryptionKey getArmorCacheKey() throws KrbException {
+        EncryptionKey armorCacheKey = credential.getKey();
+
+        return armorCacheKey;
+    }
+
+    private void getCredential() throws KrbException {
         KOptions preauthOptions = getPreauthOptions();
-        String ccache = preauthOptions.getStringOption(KrbOption.KRB5_CACHE);
+        String ccache = preauthOptions.getStringOption(KrbOption.ARMOR_CACHE);
         File ccacheFile = new File(ccache);
         CredentialCache cc = null;
         try {
@@ -77,9 +135,67 @@ public abstract class ArmoredAsRequest extends AsRequest {
         } catch (IOException e) {
             throw new KrbException("Failed to load armor cache file");
         }
-        EncryptionKey armorCacheKey =
-                cc.getCredentials().iterator().next().getKey();
+        // TODO: get the right credential.
+        this.credential = cc.getCredentials().iterator().next();
+    }
 
-        return armorCacheKey;
+    public void fastAsArmor() throws KrbException {
+        KrbFastRequestState state = getFastRequestState();
+        state.setArmorKey(getArmorKey());
+        state.setFastArmor(fastArmorApRequest(subKey, credential));
+        KdcReq fastOuterRequest = new AsReq();
+        fastOuterRequest.setReqBody(getKdcReq().getReqBody());
+        fastOuterRequest.setPaData(null);
+        state.setFastOuterRequest(fastOuterRequest);
+        setFastRequestState(state);
+
+        setOuterRequestBody(state.getFastOuterRequest().encode());
+    }
+
+    private PaDataEntry makeFastEntry() throws KrbException {
+        KrbFastRequestState state = getFastRequestState();
+
+        KrbFastReq fastReq = new KrbFastReq();
+        fastReq.setKdcReqBody(getKdcReq().getReqBody());
+        fastReq.setFastOptions(state.getFastOptions());
+
+        KrbFastArmoredReq armoredReq = new KrbFastArmoredReq();
+        armoredReq.setArmor(state.getFastArmor());
+        CheckSum reqCheckSum = CheckSumUtil.makeCheckSumWithKey(CheckSumType.NONE,
+            getOuterRequestBody(), state.getArmorKey(), KeyUsage.FAST_REQ_CHKSUM);
+        armoredReq.setReqChecksum(reqCheckSum);
+        armoredReq.setEncryptedFastReq(EncryptionUtil.seal(fastReq, state.getArmorKey(),
+            KeyUsage.FAST_ENC));
+
+        PaDataEntry paDataEntry = new PaDataEntry();
+        paDataEntry.setPaDataType(PaDataType.FX_FAST);
+        paDataEntry.setPaDataValue(armoredReq.encode());
+
+        return paDataEntry;
+    }
+
+     public static KrbFastArmor fastArmorApRequest(EncryptionKey subKey, Credential credential)
+        throws KrbException {
+        KrbFastArmor fastArmor = new KrbFastArmor();
+        fastArmor.setArmorType(ArmorType.ARMOR_AP_REQUEST);
+        ApReq apReq = makeApReq(subKey, credential);
+        fastArmor.setArmorValue(apReq.encode());
+        return fastArmor;
+    }
+
+    private static ApReq makeApReq(EncryptionKey subKey, Credential credential)
+        throws KrbException {
+        ApReq apReq = new ApReq();
+        ApOptions apOptions = new ApOptions();
+        apReq.setApOptions(apOptions);
+        Ticket ticket = credential.getTicket();
+        apReq.setTicket(ticket);
+        Authenticator authenticator = makeAuthenticator(credential.getClientName(),
+            credential.getClientRealm(), subKey);
+        apReq.setAuthenticator(authenticator);
+        EncryptedData authnData = EncryptionUtil.seal(authenticator,
+            credential.getKey(), KeyUsage.AP_REQ_AUTH);
+        apReq.setEncryptedAuthenticator(authnData);
+        return apReq;
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/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 47c09e3..5aeba91 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
@@ -20,12 +20,20 @@
 package org.apache.kerby.kerberos.kerb.client.request;
 
 import org.apache.kerby.kerberos.kerb.KrbErrorCode;
+import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.ccache.CredentialCache;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.common.KrbUtil;
-import org.apache.kerby.kerberos.kerb.spec.base.*;
-import org.apache.kerby.kerberos.kerb.spec.kdc.*;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.spec.base.HostAddress;
+import org.apache.kerby.kerberos.kerb.spec.base.HostAddresses;
+import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
+import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+import org.apache.kerby.kerberos.kerb.spec.kdc.AsReq;
+import org.apache.kerby.kerberos.kerb.spec.kdc.EncAsRepPart;
+import org.apache.kerby.kerberos.kerb.spec.kdc.EncKdcRepPart;
+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.ticket.TgtTicket;
 
 import java.io.File;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
index 0abb5a4..e017376 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
@@ -22,13 +22,20 @@ package org.apache.kerby.kerberos.kerb.client.request;
 import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.client.preauth.KrbFastContext;
+import org.apache.kerby.kerberos.kerb.client.preauth.KrbFastRequestState;
 import org.apache.kerby.kerberos.kerb.client.preauth.PreauthContext;
 import org.apache.kerby.kerberos.kerb.client.preauth.PreauthHandler;
 import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
 import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
 import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
-import org.apache.kerby.kerberos.kerb.spec.base.*;
+import org.apache.kerby.kerberos.kerb.spec.ap.Authenticator;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptedData;
+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.HostAddress;
+import org.apache.kerby.kerberos.kerb.spec.base.HostAddresses;
+import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
+import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
 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;
@@ -60,8 +67,9 @@ public abstract class KdcRequest {
     private KdcRep kdcRep;
     protected Map<String, Object> credCache;
     private PreauthContext preauthContext;
-    private KrbFastContext fastContext;
+    private KrbFastRequestState fastRequestState;
     private EncryptionKey asKey;
+    private byte[] outerRequestBody;
 
     private boolean isRetrying;
 
@@ -71,7 +79,23 @@ public abstract class KdcRequest {
         this.credCache = new HashMap<String, Object>();
         this.preauthContext = context.getPreauthHandler()
                 .preparePreauthContext(this);
-        this.fastContext = new KrbFastContext();
+        this.fastRequestState = new KrbFastRequestState();
+    }
+
+    public KrbFastRequestState getFastRequestState() {
+        return fastRequestState;
+    }
+
+    public void setFastRequestState(KrbFastRequestState state) {
+        this.fastRequestState = state;
+    }
+
+    public byte[] getOuterRequestBody() {
+        return outerRequestBody;
+    }
+
+    public void setOuterRequestBody(byte[] outerRequestBody) {
+        this.outerRequestBody = outerRequestBody;
     }
 
     public void setSessionData(Object sessionData) {
@@ -319,7 +343,7 @@ public abstract class KdcRequest {
      * Get a pointer to the FAST armor key, or NULL if the client is not using FAST.
      */
     public EncryptionKey getArmorKey() {
-        return fastContext.getArmorKey();
+        return fastRequestState.getArmorKey();
     }
 
     /**
@@ -353,4 +377,15 @@ public abstract class KdcRequest {
     public void cacheValue(String key, Object value) {
         credCache.put(key, value);
     }
-}
+
+    protected static Authenticator makeAuthenticator(PrincipalName clientName, String clientRealm, EncryptionKey subKey)
+        throws KrbException {
+        Authenticator authenticator = new Authenticator();
+        authenticator.setCname(clientName);
+        authenticator.setCrealm(clientRealm);
+        authenticator.setCtime(KerberosTime.now());
+        authenticator.setCusec(0);
+        authenticator.setSubKey(subKey);
+        return authenticator;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
index 10b4dbb..c9d1144 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
@@ -19,10 +19,9 @@
  */
 package org.apache.kerby.kerberos.kerb.client.request;
 
+import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
 import org.apache.kerby.kerberos.kerb.spec.ap.ApOptions;
 import org.apache.kerby.kerberos.kerb.spec.ap.ApReq;
 import org.apache.kerby.kerberos.kerb.spec.ap.Authenticator;
@@ -30,7 +29,11 @@ import org.apache.kerby.kerberos.kerb.spec.base.EncryptedData;
 import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
 import org.apache.kerby.kerberos.kerb.spec.base.KeyUsage;
 import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
-import org.apache.kerby.kerberos.kerb.spec.kdc.*;
+import org.apache.kerby.kerberos.kerb.spec.kdc.EncTgsRepPart;
+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.kdc.TgsRep;
+import org.apache.kerby.kerberos.kerb.spec.kdc.TgsReq;
 import org.apache.kerby.kerberos.kerb.spec.pa.PaDataType;
 import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
 import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
@@ -85,7 +88,8 @@ public class TgsRequest extends KdcRequest {
     private ApReq makeApReq() throws KrbException {
         ApReq apReq = new ApReq();
 
-        Authenticator authenticator = makeAuthenticator();
+        Authenticator authenticator = makeAuthenticator(tgt.getClientPrincipal(), tgt.getRealm(),
+            tgt.getSessionKey());
         EncryptionKey sessionKey = tgt.getSessionKey();
         EncryptedData authnData = EncryptionUtil.seal(authenticator,
                 sessionKey, KeyUsage.TGS_REQ_AUTH);
@@ -98,20 +102,6 @@ public class TgsRequest extends KdcRequest {
         return apReq;
     }
 
-    private Authenticator makeAuthenticator() {
-        Authenticator authenticator = new Authenticator();
-        authenticator.setCname(tgt.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);

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java
new file mode 100644
index 0000000..1231ef4
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java
@@ -0,0 +1,47 @@
+/**
+ *  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.common;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.crypto.CheckSumHandler;
+import org.apache.kerby.kerberos.kerb.crypto.EncTypeHandler;
+import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
+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.KeyUsage;
+
+public class CheckSumUtil {
+
+    public static CheckSum makeCheckSum(CheckSumType checkSumType, byte[] input)
+        throws KrbException {
+        return CheckSumHandler.checksum(checkSumType, input);
+    }
+
+    public static CheckSum makeCheckSumWithKey(CheckSumType checkSumType, byte[] input,
+                                               EncryptionKey key, KeyUsage usage)
+        throws KrbException {
+        if (checkSumType == CheckSumType.NONE) {
+            EncTypeHandler handler = EncryptionHandler.getEncHandler(key.getKeyType());
+            checkSumType = handler.checksumType();
+        }
+        return CheckSumHandler.checksumWithKey(checkSumType, input, key.getKeyData(), usage);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c0f38208/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 bd9a43d..82cce78 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
@@ -22,17 +22,27 @@ package org.apache.kerby.kerberos.kerb.server.request;
 import org.apache.kerby.kerberos.kerb.*;
 import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
 import org.apache.kerby.kerberos.kerb.common.KrbUtil;
+import org.apache.kerby.kerberos.kerb.crypto.CheckSumHandler;
+import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerby.kerberos.kerb.crypto.fast.FastUtil;
 import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
 import org.apache.kerby.kerberos.kerb.server.KdcContext;
 import org.apache.kerby.kerberos.kerb.server.preauth.KdcFastContext;
 import org.apache.kerby.kerberos.kerb.server.preauth.PreauthContext;
 import org.apache.kerby.kerberos.kerb.server.preauth.PreauthHandler;
+import org.apache.kerby.kerberos.kerb.spec.ap.ApReq;
+import org.apache.kerby.kerberos.kerb.spec.ap.Authenticator;
 import org.apache.kerby.kerberos.kerb.spec.base.*;
+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.KdcRep;
 import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
 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.ticket.EncTicketPart;
 import org.apache.kerby.kerberos.kerb.spec.ticket.Ticket;
 
 import java.net.InetAddress;
@@ -59,6 +69,7 @@ public abstract class KdcRequest {
     private PreauthContext preauthContext;
     private KdcFastContext fastContext;
     private PrincipalName serverPrincipal;
+    private byte[] innerBodyout;
 
     public KdcRequest(KdcReq kdcReq, KdcContext kdcContext) {
         this.kdcReq = kdcReq;
@@ -83,6 +94,7 @@ public abstract class KdcRequest {
 
     public void process() throws KrbException {
         checkVersion();
+        kdcFindFast();
         checkClient();
         checkServer();
         preauth();
@@ -91,6 +103,56 @@ public abstract class KdcRequest {
         makeReply();
     }
 
+    private void kdcFindFast() throws KrbException {
+
+        PaData paData = getKdcReq().getPaData();
+        for (PaDataEntry paEntry : paData.getElements()) {
+            if (paEntry.getPaDataType() == PaDataType.FX_FAST) {
+                KrbFastArmoredReq fastArmoredReq = KrbCodec.decode(paEntry.getPaDataValue(),
+                    KrbFastArmoredReq.class);
+                KrbFastArmor fastArmor = fastArmoredReq.getArmor();
+                armorApRequest(fastArmor);
+
+                EncryptedData encryptedData = fastArmoredReq.getEncryptedFastReq();
+                KrbFastReq fastReq = KrbCodec.decode(
+                    EncryptionHandler.decrypt(encryptedData, getArmorKey(), KeyUsage.FAST_ENC),
+                    KrbFastReq.class);
+                innerBodyout = fastReq.getKdcReqBody().encode();
+
+                // TODO: get checksumed date in stream
+                CheckSum checkSum = fastArmoredReq.getReqChecksum();
+                CheckSumHandler.verifyWithKey(checkSum, getKdcReq().getReqBody().encode(),
+                    getArmorKey().getKeyData(), KeyUsage.FAST_REQ_CHKSUM);
+            }
+        }
+    }
+
+    private void armorApRequest(KrbFastArmor fastArmor) throws KrbException {
+        if (fastArmor.getArmorType() == ArmorType.ARMOR_AP_REQUEST) {
+            ApReq apReq = KrbCodec.decode(fastArmor.getArmorValue(), ApReq.class);
+
+            Ticket ticket = apReq.getTicket();
+            EncryptionType encType = ticket.getEncryptedEncPart().getEType();
+            EncryptionKey tgsKey = getTgsEntry().getKeys().get(encType);
+            if (ticket.getTktvno() != KrbConstant.KRB_V5) {
+                throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADVERSION);
+            }
+
+            EncTicketPart encPart = EncryptionUtil.unseal(ticket.getEncryptedEncPart(),
+                tgsKey, KeyUsage.KDC_REP_TICKET, EncTicketPart.class);
+            ticket.setEncPart(encPart);
+
+            EncryptionKey encKey = ticket.getEncPart().getKey();
+
+            Authenticator authenticator = EncryptionUtil.unseal(apReq.getEncryptedAuthenticator(),
+                encKey, KeyUsage.AP_REQ_AUTH, Authenticator.class);
+
+            EncryptionKey armorKey = FastUtil.cf2(authenticator.getSubKey(), "subkeyarmor",
+                encKey, "ticketarmor");
+            setArmorKey(armorKey);
+        }
+    }
+
     public KrbIdentity getTgsEntry() {
         return tgsEntry;
     }
@@ -359,7 +421,15 @@ public abstract class KdcRequest {
         return fastContext.getArmorKey();
     }
 
+    public void setArmorKey(EncryptionKey armorKey) {
+        fastContext.setArmorKey(armorKey);
+    }
+
     public PrincipalName getServerPrincipal() {
         return serverPrincipal;
     }
+
+    public byte[] getInnerBodyout() {
+        return innerBodyout;
+    }
 }