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/12/02 03:22:38 UTC

directory-kerby git commit: Add the kdc san verify.

Repository: directory-kerby
Updated Branches:
  refs/heads/pkinit-support 7a9723943 -> 96f46482e


Add the kdc san verify.


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

Branch: refs/heads/pkinit-support
Commit: 96f46482ef7b1ab4eb6bf45a468acb3f16b76e53
Parents: 7a97239
Author: plusplusjiajia <ji...@intel.com>
Authored: Wed Dec 2 10:28:06 2015 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Wed Dec 2 10:28:06 2015 +0800

----------------------------------------------------------------------
 .../client/preauth/pkinit/PkinitPreauth.java    |  7 +-
 .../kerb/client/request/AsRequestWithCert.java  | 13 ++-
 .../kerb/preauth/pkinit/PkinitCrypto.java       | 93 +++++++++++++++++---
 .../server/preauth/pkinit/PkinitPreauth.java    | 15 ++--
 .../apache/kerby/x509/type/GeneralNames.java    |  3 +
 5 files changed, 106 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/96f46482/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
index 0394888..0080fad 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
@@ -68,8 +68,6 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 
-
-
 public class PkinitPreauth extends AbstractPreauthPlugin {
     private static final Logger LOG = LoggerFactory.getLogger(PkinitPreauth.class);
 
@@ -239,9 +237,9 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
         pkAuthen.setCusec(cusec);
         pkAuthen.setCtime(ctime);
         pkAuthen.setNonce(nonce);
-//        pkAuthen.setPaChecksum(checkSum.getChecksum());
+        pkAuthen.setPaChecksum(checkSum.getChecksum());
 
-        pkAuthen.setPaChecksum(checkSum.encode());
+//        pkAuthen.setPaChecksum(checkSum.encode());
 
         authPack.setPkAuthenticator(pkAuthen);
 
@@ -342,6 +340,7 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
         } catch (IOException e) {
             e.printStackTrace();
         }
+//        signedDataBytes = PkinitCrypto.cmsSignedDataCreate(authPack.encode());
 
         return signedDataBytes;
     }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/96f46482/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
index c023e29..524255a 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
@@ -25,10 +25,12 @@ import org.apache.kerby.kerberos.kerb.KrbCodec;
 import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
+import org.apache.kerby.kerberos.kerb.common.KrbUtil;
 import org.apache.kerby.kerberos.kerb.crypto.dh.DhClient;
 import org.apache.kerby.kerberos.kerb.preauth.pkinit.CMSMessageType;
 import org.apache.kerby.kerberos.kerb.preauth.pkinit.PkinitCrypto;
 import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
 import org.apache.kerby.kerberos.kerb.type.kdc.AsReq;
 import org.apache.kerby.kerberos.kerb.type.kdc.KdcOption;
 import org.apache.kerby.kerberos.kerb.type.kdc.KdcRep;
@@ -99,7 +101,7 @@ public class AsRequestWithCert extends AsRequest {
 
                 PaPkAsRep paPkAsRep = KrbCodec.decode(paEntry.getPaDataValue(), PaPkAsRep.class);
 
-                DHRepInfo dhRepInfo =paPkAsRep.getDHRepInfo();
+                DHRepInfo dhRepInfo = paPkAsRep.getDHRepInfo();
 
                 DHNonce nonce = dhRepInfo.getServerDhNonce();
                 byte[] dhSignedData = dhRepInfo.getDHSignedData();
@@ -111,11 +113,16 @@ public class AsRequestWithCert extends AsRequest {
                     LOG.error("failed to verify pkcs7 signed data\n");
                 }
 
-                if (!PkinitCrypto.verifyKdcSan(getContext().getConfig().getPkinitKdcHostName(),
-                pkcs7.getCertificates())) {
+                PrincipalName kdcPrincipal = KrbUtil.makeTgsPrincipal(
+                        getContext().getConfig().getKdcRealm());
+                boolean validSan= PkinitCrypto.verifyKdcSan(
+                        getContext().getConfig().getPkinitKdcHostName(), kdcPrincipal,
+                        pkcs7.getCertificates());
+                if (!validSan) {
                     LOG.error("Did not find an acceptable SAN in KDC certificate");
                 }
 
+                LOG.info("skipping EKU check");
 
                 ContentInfo contentInfo = pkcs7.getContentInfo();
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/96f46482/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
index 2ecc1dc..48e5c78 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/preauth/pkinit/PkinitCrypto.java
@@ -18,9 +18,14 @@
  */
 package org.apache.kerby.kerberos.kerb.preauth.pkinit;
 
+import org.apache.kerby.asn1.type.Asn1ObjectIdentifier;
+import org.apache.kerby.cms.type.EncapsulatedContentInfo;
+import org.apache.kerby.kerberos.kerb.KrbCodec;
 import org.apache.kerby.kerberos.kerb.KrbErrorCode;
 import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
 import org.apache.kerby.x509.type.DHParameter;
+import org.apache.kerby.x509.type.GeneralNames;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import sun.security.pkcs.ContentInfo;
@@ -42,8 +47,12 @@ import java.security.KeyFactory;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
 import java.security.spec.InvalidKeySpecException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 
 public class PkinitCrypto {
 
@@ -205,6 +214,28 @@ public class PkinitCrypto {
         return bytes;
     }
 
+    /*
+     *
+     *   -- The contentType field of the type ContentInfo
+     *   -- is id-signedData (1.2.840.113549.1.7.2),
+     *   -- and the content field is a SignedData.
+     *   -- The eContentType field for the type SignedData is
+     *   -- id-pkinit-authData (1.3.6.1.5.2.3.1), and the
+     *   -- eContent field contains the DER encoding of the
+     *   -- type AuthPack.
+     */
+    public static byte[] cmsSignedDataCreate(byte[] data) {
+//        org.apache.kerby.cms.type.ContentInfo contentInfo = new org.apache.kerby.cms.type.ContentInfo();
+//        contentInfo.setContentType(new Asn1ObjectIdentifier("1.2.840.113549.1.7.2"));
+//        SignedData signedData = new SignedData();
+//        signedData.setEncapContentInfo(eContentInfo);
+//        contentInfo.setContent(signedData);
+        EncapsulatedContentInfo eContentInfo = new EncapsulatedContentInfo();
+        eContentInfo.setContentType(new Asn1ObjectIdentifier("1.3.6.1.5.2.3.1"));
+        eContentInfo.setContent(data);
+        return eContentInfo.encode();
+    }
+
     public static ContentInfo createContentInfo(byte[] data, ObjectIdentifier oid) {
 
         ContentInfo contentInfo = new ContentInfo(
@@ -213,7 +244,7 @@ public class PkinitCrypto {
         return contentInfo;
     }
 
-    public static boolean verifyKdcSan(String hostname, X509Certificate[] cert) {
+    public static boolean verifyKdcSan(String hostname, PrincipalName kdcPrincipal, X509Certificate[] cert) throws KrbException {
 
         if (hostname == null) {
             LOG.info("No pkinit_kdc_hostname values found in config file");
@@ -221,21 +252,63 @@ public class PkinitCrypto {
             LOG.info("pkinit_kdc_hostname values found in config file");
         }
 
-        cryptoRetrieveCertSans(cert);
-        return true;
+        try {
+            List<PrincipalName> princs = cryptoRetrieveCertSans(cert[0]);
+            if(princs != null) {
+                for (PrincipalName princ : princs) {
+                    LOG.info("PKINIT client found id-pkinit-san in KDC cert: " + princ.getName());
+                }
+                LOG.info("Checking pkinit sans.");
+
+                if (princs.contains(kdcPrincipal)) {
+                    LOG.info("pkinit san match found");
+                    return true;
+                } else {
+                    LOG.info("no pkinit san match found");
+                    return false;
+                }
+            } else {
+                return false;
+            }
+        } catch (KrbException e) {
+            String errMessage = "PKINIT client failed to decode SANs in KDC cert." + e;
+            LOG.error(errMessage);
+            throw new KrbException(KrbErrorCode.KDC_NAME_MISMATCH, errMessage);
+        }
     }
 
-    public static void cryptoRetrieveCertSans(X509Certificate[] cert) {
-        cryptoRetrieveX509Sans(cert);
+    public static List<PrincipalName> cryptoRetrieveCertSans(X509Certificate cert) throws KrbException {
+        if (cert == null) {
+            LOG.info("no certificate!");
+            return null;
+        }
+        return cryptoRetrieveX509Sans(cert);
     }
 
-    public static void cryptoRetrieveX509Sans(X509Certificate[] cert) {
+    public static List<PrincipalName> cryptoRetrieveX509Sans(X509Certificate cert) throws KrbException {
 
-        if (cert == null) {
-            LOG.info("no certificate!");
+        LOG.info("Looking for SANs in cert: " + cert.getSubjectDN());
+
+        Collection c = null;
+        try {
+            c = cert.getSubjectAlternativeNames();
+        } catch (CertificateParsingException cpe) {
+            cpe.printStackTrace();
         }
 
-        LOG.info("Looking for SANs in cert");
-        //String[] subjectAlts = Certificates.getDNSSubjectAlts(cert[0]); //TODO
+        if (c != null) {
+            Iterator it = c.iterator();
+            while (it.hasNext()) {
+                List extensionEntry = (List) it.next();
+                int type = ((Integer) extensionEntry.get(0)).intValue();
+
+                Object name = extensionEntry.get(1);
+                byte[] nameAsBytes = (byte[]) name;
+                GeneralNames generalNames = null;
+                generalNames = KrbCodec.decode(nameAsBytes, GeneralNames.class);
+//                OtherName otherName = generalNames.getElements().get(1).getOtherName();
+            }
+        }
+        return null;
     }
 }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/96f46482/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
index 5f20851..d6f482b 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
@@ -39,6 +39,7 @@ import org.apache.kerby.kerberos.kerb.type.KerberosTime;
 import org.apache.kerby.kerberos.kerb.type.base.CheckSum;
 import org.apache.kerby.kerberos.kerb.type.base.CheckSumType;
 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.kdc.KdcOption;
 import org.apache.kerby.kerberos.kerb.type.pa.PaDataEntry;
@@ -176,18 +177,16 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
 
             CheckSum expectedCheckSum = null;
             try {
-//                expectedCheckSum = CheckSumUtil.makeCheckSum(CheckSumType.NIST_SHA,
-//                        kdcRequest.getKdcReq().getReqBody().encode());
                 expectedCheckSum = CheckSumUtil.makeCheckSum(CheckSumType.NIST_SHA,
                         kdcRequest.getReqBodyBytes());
             } catch (KrbException e) {
                 LOG.error("Unable to calculate AS REQ checksum.", e.getMessage());
             }
-            CheckSum receivedCheckSum = KrbCodec.decode(pkAuthenticator.getPaChecksum(), CheckSum.class);
+            byte[] receivedCheckSumByte = pkAuthenticator.getPaChecksum();
 
-            if(!CheckSumHandler.verify(receivedCheckSum, kdcRequest.getReqBodyBytes())) {
-                LOG.debug("Received checksum type: " + receivedCheckSum.getCksumtype()
-                        + ", received checksum length: " + receivedCheckSum.encodingLength()
+            if (expectedCheckSum.getChecksum().length != receivedCheckSumByte.length
+                    || !Arrays.equals(expectedCheckSum.getChecksum(), receivedCheckSumByte)) {
+                LOG.debug("received checksum length: " + receivedCheckSumByte.length
                         + ", expected checksum type: " + expectedCheckSum.getCksumtype()
                         + ", expected checksum length: " + expectedCheckSum.encodingLength());
                 String errorMessage = "Failed to match the checksum.";
@@ -210,7 +209,7 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
             try {
                 serverPubKey = (DHPublicKey) server.initAndDoPhase(dhPublicKey.getEncoded());
             } catch (Exception e) {
-                e.printStackTrace();
+                LOG.error("Fail to create server public key.", e);
             }
             EncryptionKey secretKey = server.generateKey(null, null, kdcRequest.getEncryptionType());
 
@@ -290,7 +289,7 @@ public class PkinitPreauth extends AbstractPreauthPlugin {
 
         Asn1Integer publickey = new Asn1Integer(severPubKey.getY());
         kdcDhKeyInfo.setSubjectPublicKey(publickey.encode());
-        kdcDhKeyInfo.setNonce(1);
+        kdcDhKeyInfo.setNonce(0);
         kdcDhKeyInfo.setDHKeyExpiration(
                 new KerberosTime(System.currentTimeMillis() + KerberosTime.DAY));
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/96f46482/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralNames.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralNames.java b/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralNames.java
index 87a8027..a9940bf 100644
--- a/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralNames.java
+++ b/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralNames.java
@@ -21,6 +21,9 @@ package org.apache.kerby.x509.type;
 
 import org.apache.kerby.asn1.type.Asn1SequenceOf;
 
+/*
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ */
 public class GeneralNames extends Asn1SequenceOf<GeneralName> {
 
 }