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 2016/04/13 09:05:31 UTC

directory-kerby git commit: DIRKRB-533 Implementing ApRequest and ApResponse.

Repository: directory-kerby
Updated Branches:
  refs/heads/trunk ddd4112f8 -> 752799ec9


DIRKRB-533 Implementing ApRequest and ApResponse.


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

Branch: refs/heads/trunk
Commit: 752799ec930b77e2099a8940f249f81703541897
Parents: ddd4112
Author: plusplusjiajia <ji...@intel.com>
Authored: Wed Apr 13 15:10:30 2016 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Wed Apr 13 15:10:30 2016 +0800

----------------------------------------------------------------------
 .../kerby/kerberos/kerb/request/ApRequest.java  | 130 +++++++++++++++++++
 .../kerberos/kerb/response/ApResponse.java      |  80 ++++++++++++
 .../kerberos/kerb/server/ApRequestTest.java     |  75 +++++++++++
 3 files changed, 285 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/752799ec/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/request/ApRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/request/ApRequest.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/request/ApRequest.java
new file mode 100644
index 0000000..82666a6
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/request/ApRequest.java
@@ -0,0 +1,130 @@
+/**
+ *  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.request;
+
+import org.apache.kerby.kerberos.kerb.KrbErrorCode;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerby.kerberos.kerb.type.KerberosTime;
+import org.apache.kerby.kerberos.kerb.type.ap.ApOption;
+import org.apache.kerby.kerberos.kerb.type.ap.ApOptions;
+import org.apache.kerby.kerberos.kerb.type.ap.ApReq;
+import org.apache.kerby.kerberos.kerb.type.ap.Authenticator;
+import org.apache.kerby.kerberos.kerb.type.base.EncryptedData;
+import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.type.base.KeyUsage;
+import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
+import org.apache.kerby.kerberos.kerb.type.ticket.EncTicketPart;
+import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
+import org.apache.kerby.kerberos.kerb.type.ticket.Ticket;
+
+/**
+ * A wrapper for ApReq request
+ * The client principal and sgt ticket are needed to create ApReq message.
+ */
+public class ApRequest {
+
+    private PrincipalName clientPrincipal;
+    private SgtTicket sgtTicket;
+    private ApReq apReq;
+
+    public ApRequest(PrincipalName clientPrincipal, SgtTicket sgtTicket) {
+        this.clientPrincipal = clientPrincipal;
+        this.sgtTicket = sgtTicket;
+    }
+
+    public ApReq getApReq() throws KrbException {
+        if (apReq == null) {
+            apReq = makeApReq();
+        }
+        return apReq;
+    }
+
+    public void setApReq(ApReq apReq) {
+        this.apReq = apReq;
+    }
+
+    private ApReq makeApReq() throws KrbException {
+        ApReq apReq = new ApReq();
+
+        Authenticator authenticator = makeAuthenticator();
+        EncryptionKey sessionKey = sgtTicket.getSessionKey();
+        EncryptedData authData = EncryptionUtil.seal(authenticator,
+                sessionKey, KeyUsage.AP_REQ_AUTH);
+        apReq.setEncryptedAuthenticator(authData);
+        apReq.setAuthenticator(authenticator);
+        apReq.setTicket(sgtTicket.getTicket());
+        ApOptions apOptions = new ApOptions();
+        apOptions.setFlag(ApOption.USE_SESSION_KEY);
+        apReq.setApOptions(apOptions);
+
+        return apReq;
+    }
+
+    /*
+     * Make the Authenticator for ApReq.
+     */
+    private Authenticator makeAuthenticator() throws KrbException {
+        Authenticator authenticator = new Authenticator();
+        authenticator.setAuthenticatorVno(5);
+        authenticator.setCname(clientPrincipal);
+        authenticator.setCrealm(sgtTicket.getRealm());
+        authenticator.setCtime(KerberosTime.now());
+        authenticator.setCusec(0);
+        authenticator.setSubKey(sgtTicket.getSessionKey());
+
+        return authenticator;
+    }
+
+    /*
+     *  Validate the ApReq.
+     */
+    public static void validate(EncryptionKey encKey, ApReq apReq) throws KrbException {
+        Ticket ticket = apReq.getTicket();
+
+        if (encKey == null) {
+            throw new KrbException(KrbErrorCode.KRB_AP_ERR_NOKEY);
+        }
+        EncTicketPart encPart = EncryptionUtil.unseal(ticket.getEncryptedEncPart(),
+                encKey, KeyUsage.KDC_REP_TICKET, EncTicketPart.class);
+        ticket.setEncPart(encPart);
+
+        unsealAuthenticator(encPart.getKey(), apReq);
+
+        Authenticator authenticator = apReq.getAuthenticator();
+        if (!authenticator.getCname().equals(ticket.getEncPart().getCname())) {
+            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADMATCH);
+        }
+        if (!authenticator.getCrealm().equals(ticket.getEncPart().getCrealm())) {
+            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADMATCH);
+        }
+    }
+
+    /*
+     *  Unseal the authenticator through the encryption key from ticket
+     */
+    public static void unsealAuthenticator(EncryptionKey encKey, ApReq apReq) throws KrbException {
+        EncryptedData authData = apReq.getEncryptedAuthenticator();
+
+        Authenticator authenticator = EncryptionUtil.unseal(authData,
+                encKey, KeyUsage.AP_REQ_AUTH, Authenticator.class);
+        apReq.setAuthenticator(authenticator);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/752799ec/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/response/ApResponse.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/response/ApResponse.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/response/ApResponse.java
new file mode 100644
index 0000000..2d01004
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/response/ApResponse.java
@@ -0,0 +1,80 @@
+/**
+ *  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.response;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerby.kerberos.kerb.request.ApRequest;
+import org.apache.kerby.kerberos.kerb.type.KerberosTime;
+import org.apache.kerby.kerberos.kerb.type.ap.ApRep;
+import org.apache.kerby.kerberos.kerb.type.ap.ApReq;
+import org.apache.kerby.kerberos.kerb.type.ap.EncAPRepPart;
+import org.apache.kerby.kerberos.kerb.type.base.EncryptedData;
+import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.type.base.KeyUsage;
+
+/**
+ * A wrapper for ApRep request.
+ */
+public class ApResponse {
+    private ApReq apReq;
+    private ApRep apRep;
+    EncryptionKey encryptionKey;
+
+    public ApResponse(ApReq apReq, EncryptionKey encryptionKey) {
+        this.apReq = apReq;
+        this.encryptionKey = encryptionKey;
+    }
+
+    public ApRep getApRep() throws KrbException {
+        ApRequest.validate(encryptionKey, apReq);
+
+        if (apRep == null) {
+            apRep = makeApRep();
+        }
+        return apRep;
+    }
+
+    public void setApRep(ApRep apRep) {
+        this.apRep = apRep;
+    }
+
+    /*
+     *  The KRB_AP_REP message contains the Kerberos protocol version number,
+     *  the message type, and an encrypted time-stamp.
+     */
+    private ApRep makeApRep() throws KrbException {
+
+        ApRep apRep = new ApRep();
+        EncAPRepPart encAPRepPart = new EncAPRepPart();
+        // This field contains the current time on the client's host.
+        encAPRepPart.setCtime(KerberosTime.now());
+        // This field contains the microsecond part of the client's timestamp.
+        encAPRepPart.setCusec((int) KerberosTime.now().getTimeInSeconds());
+        encAPRepPart.setSubkey(apReq.getAuthenticator().getSubKey());
+        encAPRepPart.setSeqNumber(0);
+        apRep.setEncRepPart(encAPRepPart);
+        EncryptedData encPart = EncryptionUtil.seal(encAPRepPart,
+                apReq.getAuthenticator().getSubKey(), KeyUsage.AP_REP_ENCPART);
+        apRep.setEncryptedEncPart(encPart);
+
+        return apRep;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/752799ec/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/ApRequestTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/ApRequestTest.java b/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/ApRequestTest.java
new file mode 100644
index 0000000..da868f9
--- /dev/null
+++ b/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/ApRequestTest.java
@@ -0,0 +1,75 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.server;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.request.ApRequest;
+import org.apache.kerby.kerberos.kerb.response.ApResponse;
+import org.apache.kerby.kerberos.kerb.type.ap.ApRep;
+import org.apache.kerby.kerberos.kerb.type.ap.ApReq;
+import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.type.base.KrbMessageType;
+import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
+import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
+import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ApRequestTest extends KdcTestBase {
+
+    @Test
+    public void test() throws IOException, KrbException {
+
+        TgtTicket tgt = null;
+        SgtTicket tkt = null;
+
+        try {
+            tgt = getKrbClient().requestTgt(getClientPrincipal(),
+                    getClientPassword());
+            assertThat(tgt).isNotNull();
+
+            tkt = getKrbClient().requestSgt(tgt, getServerPrincipal());
+            assertThat(tkt).isNotNull();
+        } catch (Exception e) {
+            System.out.println("Exception occurred with good password");
+            e.printStackTrace();
+            Assert.fail();
+        }
+
+        ApRequest apRequest = new ApRequest(new PrincipalName(getClientPrincipal()), tkt);
+        ApReq apReq = apRequest.getApReq();
+
+        assertThat(apReq.getPvno()).isEqualTo(5);
+        assertThat(apReq.getMsgType()).isEqualTo(KrbMessageType.AP_REQ);
+        assertThat(apReq.getAuthenticator().getCname()).isEqualTo(tgt.getClientPrincipal());
+        assertThat(apReq.getAuthenticator().getCrealm()).isEqualTo(tgt.getRealm());
+
+        EncryptionKey encryptedKey = getKdcServer().getKadmin().getPrincipal(
+                getServerPrincipal()).getKey(tkt.getTicket().getEncryptedEncPart().getEType());
+        ApResponse apResponse = new ApResponse(apReq, encryptedKey);
+        ApRep apRep = apResponse.getApRep();
+        assertThat(apRep.getPvno()).isEqualTo(5);
+        assertThat(apRep.getMsgType()).isEqualTo(KrbMessageType.AP_REP);
+    }
+}