directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From plusplusjia...@apache.org
Subject [1/2] directory-kerby git commit: DIRKRB-415 Consolidate and merge the existing kerberos-pkinit implementation in directory to Kerby.
Date Thu, 24 Sep 2015 07:07:09 GMT
Repository: directory-kerby
Updated Branches:
  refs/heads/pkinit-support 42bcec89a -> c98ab976a


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c98ab976/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/CertificateChainFactoryTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/CertificateChainFactoryTest.java
b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/CertificateChainFactoryTest.java
new file mode 100644
index 0000000..918047a
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/CertificateChainFactoryTest.java
@@ -0,0 +1,119 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+
+
+import junit.framework.TestCase;
+import org.apache.kerby.kerberos.kerb.client.preauth.pkinit.certs.CertificateChainFactory;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * Tests the dynamic generation of certificate chains.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CertificateChainFactoryTest extends TestCase
+{
+    public void setUp()
+    {
+        if ( Security.getProvider( BouncyCastleProvider.PROVIDER_NAME ) == null )
+        {
+            Security.addProvider( new BouncyCastleProvider() );
+        }
+    }
+
+
+    /**
+     * Tests construction of the client chain.
+     * 
+     * The created certificates can be displayed with a command like:
+     * 
+     * openssl pkcs12 -nodes -info -in /tmp/test.p12 > /tmp/test.cert && openssl
x509 -noout -text -in /tmp/test.cert
+     * 
+     * @throws Exception 
+     */
+    public void testClientChain() throws Exception
+    {
+        X509Certificate[] clientChain = CertificateChainFactory.getClientChain();
+
+        validateChain( clientChain );
+    }
+
+
+    /**
+     * Tests construction of the KDC chain.
+     * 
+     * The created certificates can be displayed with a command like:
+     * 
+     * openssl pkcs12 -nodes -info -in /tmp/test.p12 > /tmp/test.cert && openssl
x509 -noout -text -in /tmp/test.cert
+     * 
+     * @throws Exception 
+     */
+    public void testKdcChain() throws Exception
+    {
+        X509Certificate[] kdcChain = CertificateChainFactory.getKdcChain();
+
+        validateChain( kdcChain );
+    }
+
+
+    /**
+     * Validates a chain of {@link X509Certificate}s.
+     *
+     * @param chain
+     * @throws CertificateException
+     * @throws InvalidAlgorithmParameterException
+     */
+    private void validateChain( X509Certificate[] chain ) throws CertificateException,
+        InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException,
+        InvalidAlgorithmParameterException, CertPathValidatorException
+    {
+        List<X509Certificate> certificateList = Arrays.asList( chain );
+        CertificateFactory certificateFactory = CertificateFactory.getInstance( "X.509" );
+        CertPath certPath = certificateFactory.generateCertPath( certificateList );
+
+        CertPathValidator cpv = CertPathValidator.getInstance( "PKIX", "BC" );
+
+        TrustAnchor trustAnchor = new TrustAnchor( chain[chain.length - 1], null );
+
+        PKIXParameters parameters = new PKIXParameters( Collections.singleton( trustAnchor
) );
+        parameters.setRevocationEnabled( false );
+
+        cpv.validate( certPath, parameters );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c98ab976/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java
b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java
new file mode 100644
index 0000000..da436c1
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhGroupTest.java
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+
+import junit.framework.TestCase;
+
+/**
+ * "When using the Diffie-Hellman key agreement method, implementations MUST
+ * support Oakley 1024-bit Modular Exponential (MODP) well-known group 2
+ * [RFC2412] and Oakley 2048-bit MODP well-known group 14 [RFC3526] and
+ * SHOULD support Oakley 4096-bit MODP well-known group 16 [RFC3526]."
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DhGroupTest extends TestCase
+{
+    /**
+     * Tests that the translation of the hex representation of the prime modulus
+     * resulted in the expected bit length.
+     */
+    public void testPrimeBitLengths()
+    {
+        assertEquals( 1024, DhGroup.MODP_GROUP2.getP().bitLength() );
+        assertEquals( 2048, DhGroup.MODP_GROUP14.getP().bitLength() );
+        assertEquals( 4096, DhGroup.MODP_GROUP16.getP().bitLength() );
+    }
+
+    /**
+     * Tests the generator values.
+     */
+    public void testGeneratorValues()
+    {
+        assertEquals( 2, DhGroup.MODP_GROUP2.getG().intValue() );
+        assertEquals( 2, DhGroup.MODP_GROUP14.getG().intValue() );
+        assertEquals( 2, DhGroup.MODP_GROUP16.getG().intValue() );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c98ab976/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java
b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java
new file mode 100644
index 0000000..c3055cf
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/DhKeyAgreementTest.java
@@ -0,0 +1,109 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+
+
+import junit.framework.TestCase;
+
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+
+/**
+ * Tests the Diffie-Hellman key agreement protocol between a client and server.
+ * <p/>
+ * Generating a Secret Key Using the Diffie-Hellman Key Agreement Algorithm
+ * <p/>
+ * Two parties use a key agreement protocol to generate identical secret keys for
+ * encryption without ever having to transmit the secret key. The protocol works
+ * by both parties agreeing on a set of values (a prime, a base, and a private
+ * value) which are used to generate a key pair.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DhKeyAgreementTest extends TestCase {
+    private static SecureRandom secureRandom = new SecureRandom();
+
+
+    /**
+     * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
+     * well-known group 2 [RFC2412].
+     *
+     * @throws Exception
+     */
+    public void testPreGeneratedDhParams() throws Exception {
+        DhClient client = new DhClient();
+        DhServer server = new DhServer();
+
+        byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2);
+        byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc);
+
+        server.generateKey(null, null);
+
+        client.doPhase(serverPubKeyEnc);
+
+        client.generateKey(null, null);
+
+        byte[] clearText = "This is just an example".getBytes();
+
+        byte[] cipherText = server.encryptAes(clearText);
+        byte[] recovered = client.decryptAes(cipherText);
+
+        assertTrue(Arrays.equals(clearText, recovered));
+    }
+
+
+    /**
+     * Tests Diffie-Hellman using Oakley 1024-bit Modular Exponential (MODP)
+     * well-known group 2 [RFC2412], including the optional DH nonce.
+     * <p/>
+     * "This nonce string MUST be as long as the longest key length of the symmetric
+     * key types that the client supports.  This nonce MUST be chosen randomly."
+     *
+     * @throws Exception
+     */
+    public void testPreGeneratedDhParamsWithNonce() throws Exception {
+        byte[] clientDhNonce = new byte[16];
+        secureRandom.nextBytes(clientDhNonce);
+
+        byte[] serverDhNonce = new byte[16];
+        secureRandom.nextBytes(serverDhNonce);
+
+        DhClient client = new DhClient();
+        DhServer server = new DhServer();
+
+        byte[] clientPubKeyEnc = client.init(DhGroup.MODP_GROUP2);
+        byte[] serverPubKeyEnc = server.initAndDoPhase(clientPubKeyEnc);
+
+        server.generateKey(clientDhNonce, serverDhNonce);
+
+        client.doPhase(serverPubKeyEnc);
+
+        client.generateKey(clientDhNonce, serverDhNonce);
+
+        byte[] clearText = "This is just an example".getBytes();
+
+        byte[] cipherText = server.encryptAes(clearText);
+        byte[] recovered = client.decryptAes(cipherText);
+
+        assertTrue(Arrays.equals(clearText, recovered));
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c98ab976/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/EnvelopedDataEngineTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/EnvelopedDataEngineTest.java
b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/EnvelopedDataEngineTest.java
new file mode 100644
index 0000000..83b6050
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/EnvelopedDataEngineTest.java
@@ -0,0 +1,133 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+
+import junit.framework.TestCase;
+import org.apache.kerby.kerberos.kerb.client.preauth.pkinit.certs.CertificateChainFactory;
+import org.bouncycastle.cms.CMSEnvelopedData;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.util.Arrays;
+
+
+/**
+ * Tests the use of {@link CMSEnvelopedData}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class EnvelopedDataEngineTest extends TestCase
+{
+    /** The log for this class. */
+    private static final Logger log = LoggerFactory.getLogger( EnvelopedDataEngineTest.class
);
+
+    /** Certificate used to encrypt the data. */
+    private X509Certificate certificate;
+
+    /** Private key used to decrypt the data. */
+    private PrivateKey privateKey;
+
+
+    public void setUp() throws Exception
+    {
+        if ( Security.getProvider( BouncyCastleProvider.PROVIDER_NAME ) == null )
+        {
+            Security.addProvider( new BouncyCastleProvider() );
+        }
+
+        //getCaFromFile( "/tmp/testCa.p12", "password", "Test CA" );
+        getCaFromFactory();
+    }
+
+
+    /**
+     * Tests that enveloped data wrapping and unwrapping works.
+     *
+     * @throws Exception
+     */
+    public void testEnvelopedData() throws Exception
+    {
+        byte[] dataToEnvelope = "Hello".getBytes();
+
+        byte[] envelopedDataBytes = EnvelopedDataEngine.getEnvelopedReplyKeyPack( dataToEnvelope,
certificate );
+        byte[] unenvelopedData = EnvelopedDataEngine.getUnenvelopedData( envelopedDataBytes,
certificate, privateKey );
+
+        assertTrue( Arrays.equals( dataToEnvelope, unenvelopedData ) );
+    }
+
+
+    void getCaFromFactory() throws Exception
+    {
+        X509Certificate[] clientChain = CertificateChainFactory.getClientChain();
+        certificate = clientChain[0];
+
+        privateKey = CertificateChainFactory.getClientPrivateKey();
+    }
+
+
+    void getCaFromFile( String caFile, String caPassword, String caAlias ) throws KeyStoreException,
+        NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException,
UnrecoverableKeyException,
+        InvalidKeyException, SignatureException, NoSuchProviderException
+    {
+        // Open the keystore.
+        KeyStore caKs = KeyStore.getInstance( "PKCS12" );
+        caKs.load( new FileInputStream( new File( caFile ) ), caPassword.toCharArray() );
+
+        // Load the private key from the keystore.
+        privateKey = ( RSAPrivateCrtKey ) caKs.getKey( caAlias, caPassword.toCharArray()
);
+
+        if ( privateKey == null )
+        {
+            throw new IllegalStateException( "Got null key from keystore!" );
+        }
+
+        // Load the certificate from the keystore.
+        certificate = ( X509Certificate ) caKs.getCertificate( caAlias );
+
+        if ( certificate == null )
+        {
+            throw new IllegalStateException( "Got null cert from keystore!" );
+        }
+
+        log.debug( "Successfully loaded key and certificate having DN '{}'.", certificate.getSubjectDN().getName()
);
+
+        // Verify.
+        certificate.verify( certificate.getPublicKey() );
+        log.debug( "Successfully verified CA certificate with its own public key." );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c98ab976/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java
b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java
new file mode 100644
index 0000000..8a2c0ce
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/OctetString2KeyTest.java
@@ -0,0 +1,230 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+
+/**
+ * From RFC 4556:
+ * 
+ * "Appendix B.  Test Vectors
+ * 
+ * Function octetstring2key() is defined in Section 3.2.3.1.  This section describes
+ * a few sets of test vectors that would be useful for implementers of octetstring2key()."
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class OctetString2KeyTest extends TestCase
+{
+    /**
+     * Set 1:
+     * =====
+     * Input octet string x is:
+     * 
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     * 
+     * Output of K-truncate() when the key size is 32 octets:
+     * 
+     *   5e e5 0d 67 5c 80 9f e5 9e 4a 77 62 c5 4b 65 83
+     *   75 47 ea fb 15 9b d8 cd c7 5f fc a5 91 1e 4c 41
+     */
+    public void testSet1()
+    {
+        byte[] inputOctetString = new byte[16 * 16];
+
+        byte[] expectedOutput =
+            { ( byte ) 0x5e, ( byte ) 0xe5, ( byte ) 0x0d, ( byte ) 0x67, ( byte ) 0x5c,
( byte ) 0x80, ( byte ) 0x9f,
+                ( byte ) 0xe5, ( byte ) 0x9e, ( byte ) 0x4a, ( byte ) 0x77, ( byte ) 0x62,
( byte ) 0xc5,
+                ( byte ) 0x4b, ( byte ) 0x65, ( byte ) 0x83, ( byte ) 0x75, ( byte ) 0x47,
( byte ) 0xea,
+                ( byte ) 0xfb, ( byte ) 0x15, ( byte ) 0x9b, ( byte ) 0xd8, ( byte ) 0xcd,
( byte ) 0xc7,
+                ( byte ) 0x5f, ( byte ) 0xfc, ( byte ) 0xa5, ( byte ) 0x91, ( byte ) 0x1e,
( byte ) 0x4c, ( byte ) 0x41 };
+
+        int keySize = 32 * 8;
+
+        byte[] result = OctetString2Key.kTruncate( keySize, inputOctetString );
+
+        assertTrue( Arrays.equals( result, expectedOutput ) );
+    }
+
+
+    /**
+     * Set 2:
+     * =====
+     * Input octet string x is:
+     * 
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     *   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+     * 
+     * Output of K-truncate() when the key size is 32 octets:
+     * 
+     *   ac f7 70 7c 08 97 3d df db 27 cd 36 14 42 cc fb
+     *   a3 55 c8 88 4c b4 72 f3 7d a6 36 d0 7d 56 78 7e
+     */
+    public void testSet2()
+    {
+        byte[] inputOctetString = new byte[16 * 8];
+
+        byte[] expectedOutput =
+            { ( byte ) 0xac, ( byte ) 0xf7, ( byte ) 0x70, ( byte ) 0x7c, ( byte ) 0x08,
( byte ) 0x97, ( byte ) 0x3d,
+                ( byte ) 0xdf, ( byte ) 0xdb, ( byte ) 0x27, ( byte ) 0xcd, ( byte ) 0x36,
( byte ) 0x14,
+                ( byte ) 0x42, ( byte ) 0xcc, ( byte ) 0xfb, ( byte ) 0xa3, ( byte ) 0x55,
( byte ) 0xc8,
+                ( byte ) 0x88, ( byte ) 0x4c, ( byte ) 0xb4, ( byte ) 0x72, ( byte ) 0xf3,
( byte ) 0x7d,
+                ( byte ) 0xa6, ( byte ) 0x36, ( byte ) 0xd0, ( byte ) 0x7d, ( byte ) 0x56,
( byte ) 0x78, ( byte ) 0x7e };
+
+        int keySize = 32 * 8;
+
+        byte[] result = OctetString2Key.kTruncate( keySize, inputOctetString );
+
+        assertTrue( Arrays.equals( result, expectedOutput ) );
+    }
+
+
+    /**
+     * Set 3:
+     * ======
+     * Input octet string x is:
+     * 
+     *   00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+     *   10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
+     *   0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
+     *   0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c
+     *   0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b
+     *   0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a
+     *   0b 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08 09
+     *   0a 0b 0c 0d 0e 0f 10 00 01 02 03 04 05 06 07 08
+     * 
+     * Output of K-truncate() when the key size is 32 octets:
+     * 
+     *   c4 42 da 58 5f cb 80 e4 3b 47 94 6f 25 40 93 e3
+     *   73 29 d9 90 01 38 0d b7 83 71 db 3a cf 5c 79 7e
+     */
+    public void testSet3()
+    {
+        byte[] inputOctetString =
+            { ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x02, ( byte ) 0x03, ( byte ) 0x04,
( byte ) 0x05, ( byte ) 0x06,
+                ( byte ) 0x07, ( byte ) 0x08, ( byte ) 0x09, ( byte ) 0x0a, ( byte ) 0x0b,
( byte ) 0x0c,
+                ( byte ) 0x0d, ( byte ) 0x0e, ( byte ) 0x0f, ( byte ) 0x10, ( byte ) 0x00,
( byte ) 0x01,
+                ( byte ) 0x02, ( byte ) 0x03, ( byte ) 0x04, ( byte ) 0x05, ( byte ) 0x06,
( byte ) 0x07,
+                ( byte ) 0x08, ( byte ) 0x09, ( byte ) 0x0a, ( byte ) 0x0b, ( byte ) 0x0c,
( byte ) 0x0d,
+                ( byte ) 0x0e, ( byte ) 0x0f, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x01,
( byte ) 0x02,
+                ( byte ) 0x03, ( byte ) 0x04, ( byte ) 0x05, ( byte ) 0x06, ( byte ) 0x07,
( byte ) 0x08,
+                ( byte ) 0x09, ( byte ) 0x0a, ( byte ) 0x0b, ( byte ) 0x0c, ( byte ) 0x0d,
( byte ) 0x0e,
+                ( byte ) 0x0f, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x02,
( byte ) 0x03,
+                ( byte ) 0x04, ( byte ) 0x05, ( byte ) 0x06, ( byte ) 0x07, ( byte ) 0x08,
( byte ) 0x09,
+                ( byte ) 0x0a, ( byte ) 0x0b, ( byte ) 0x0c, ( byte ) 0x0d, ( byte ) 0x0e,
( byte ) 0x0f,
+                ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x02, ( byte ) 0x03,
( byte ) 0x04,
+                ( byte ) 0x05, ( byte ) 0x06, ( byte ) 0x07, ( byte ) 0x08, ( byte ) 0x09,
( byte ) 0x0a,
+                ( byte ) 0x0b, ( byte ) 0x0c, ( byte ) 0x0d, ( byte ) 0x0e, ( byte ) 0x0f,
( byte ) 0x10,
+                ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x02, ( byte ) 0x03, ( byte ) 0x04,
( byte ) 0x05,
+                ( byte ) 0x06, ( byte ) 0x07, ( byte ) 0x08, ( byte ) 0x09, ( byte ) 0x0a,
( byte ) 0x0b,
+                ( byte ) 0x0c, ( byte ) 0x0d, ( byte ) 0x0e, ( byte ) 0x0f, ( byte ) 0x10,
( byte ) 0x00,
+                ( byte ) 0x01, ( byte ) 0x02, ( byte ) 0x03, ( byte ) 0x04, ( byte ) 0x05,
( byte ) 0x06,
+                ( byte ) 0x07, ( byte ) 0x08, ( byte ) 0x09, ( byte ) 0x0a, ( byte ) 0x0b,
( byte ) 0x0c,
+                ( byte ) 0x0d, ( byte ) 0x0e, ( byte ) 0x0f, ( byte ) 0x10, ( byte ) 0x00,
( byte ) 0x01,
+                ( byte ) 0x02, ( byte ) 0x03, ( byte ) 0x04, ( byte ) 0x05, ( byte ) 0x06,
( byte ) 0x07, ( byte ) 0x08 };
+
+        byte[] expectedOutput =
+            { ( byte ) 0xc4, ( byte ) 0x42, ( byte ) 0xda, ( byte ) 0x58, ( byte ) 0x5f,
( byte ) 0xcb, ( byte ) 0x80,
+                ( byte ) 0xe4, ( byte ) 0x3b, ( byte ) 0x47, ( byte ) 0x94, ( byte ) 0x6f,
( byte ) 0x25,
+                ( byte ) 0x40, ( byte ) 0x93, ( byte ) 0xe3, ( byte ) 0x73, ( byte ) 0x29,
( byte ) 0xd9,
+                ( byte ) 0x90, ( byte ) 0x01, ( byte ) 0x38, ( byte ) 0x0d, ( byte ) 0xb7,
( byte ) 0x83,
+                ( byte ) 0x71, ( byte ) 0xdb, ( byte ) 0x3a, ( byte ) 0xcf, ( byte ) 0x5c,
( byte ) 0x79, ( byte ) 0x7e };
+
+        int keySize = 32 * 8;
+
+        byte[] result = OctetString2Key.kTruncate( keySize, inputOctetString );
+
+        assertTrue( Arrays.equals( result, expectedOutput ) );
+    }
+
+
+    /**
+     * Set 4:
+     * =====
+     * Input octet string x is:
+     * 
+     *   00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+     *   10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
+     *   0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
+     *   0e 0f 10 00 01 02 03 04 05 06 07 08 09 0a 0b 0c
+     *   0d 0e 0f 10 00 01 02 03 04 05 06 07 08
+     * 
+     * Output of K-truncate() when the key size is 32 octets:
+     * 
+     *   00 53 95 3b 84 c8 96 f4 eb 38 5c 3f 2e 75 1c 4a
+     *   59 0e d6 ff ad ca 6f f6 4f 47 eb eb 8d 78 0f fc
+     */
+    public void testSet4()
+    {
+        byte[] inputOctetString =
+            { ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x02, ( byte ) 0x03, ( byte ) 0x04,
( byte ) 0x05, ( byte ) 0x06,
+                ( byte ) 0x07, ( byte ) 0x08, ( byte ) 0x09, ( byte ) 0x0a, ( byte ) 0x0b,
( byte ) 0x0c,
+                ( byte ) 0x0d, ( byte ) 0x0e, ( byte ) 0x0f, ( byte ) 0x10, ( byte ) 0x00,
( byte ) 0x01,
+                ( byte ) 0x02, ( byte ) 0x03, ( byte ) 0x04, ( byte ) 0x05, ( byte ) 0x06,
( byte ) 0x07,
+                ( byte ) 0x08, ( byte ) 0x09, ( byte ) 0x0a, ( byte ) 0x0b, ( byte ) 0x0c,
( byte ) 0x0d,
+                ( byte ) 0x0e, ( byte ) 0x0f, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x01,
( byte ) 0x02,
+                ( byte ) 0x03, ( byte ) 0x04, ( byte ) 0x05, ( byte ) 0x06, ( byte ) 0x07,
( byte ) 0x08,
+                ( byte ) 0x09, ( byte ) 0x0a, ( byte ) 0x0b, ( byte ) 0x0c, ( byte ) 0x0d,
( byte ) 0x0e,
+                ( byte ) 0x0f, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x02,
( byte ) 0x03,
+                ( byte ) 0x04, ( byte ) 0x05, ( byte ) 0x06, ( byte ) 0x07, ( byte ) 0x08,
( byte ) 0x09,
+                ( byte ) 0x0a, ( byte ) 0x0b, ( byte ) 0x0c, ( byte ) 0x0d, ( byte ) 0x0e,
( byte ) 0x0f,
+                ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x02, ( byte ) 0x03,
( byte ) 0x04,
+                ( byte ) 0x05, ( byte ) 0x06, ( byte ) 0x07, ( byte ) 0x08 };
+
+        byte[] expectedOutput =
+            { ( byte ) 0x00, ( byte ) 0x53, ( byte ) 0x95, ( byte ) 0x3b, ( byte ) 0x84,
( byte ) 0xc8, ( byte ) 0x96,
+                ( byte ) 0xf4, ( byte ) 0xeb, ( byte ) 0x38, ( byte ) 0x5c, ( byte ) 0x3f,
( byte ) 0x2e,
+                ( byte ) 0x75, ( byte ) 0x1c, ( byte ) 0x4a, ( byte ) 0x59, ( byte ) 0x0e,
( byte ) 0xd6,
+                ( byte ) 0xff, ( byte ) 0xad, ( byte ) 0xca, ( byte ) 0x6f, ( byte ) 0xf6,
( byte ) 0x4f,
+                ( byte ) 0x47, ( byte ) 0xeb, ( byte ) 0xeb, ( byte ) 0x8d, ( byte ) 0x78,
( byte ) 0x0f, ( byte ) 0xfc };
+
+        int keySize = 32 * 8;
+
+        byte[] result = OctetString2Key.kTruncate( keySize, inputOctetString );
+
+        assertTrue( Arrays.equals( result, expectedOutput ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c98ab976/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngineTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngineTest.java
b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngineTest.java
new file mode 100644
index 0000000..9dd007d
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/SignedDataEngineTest.java
@@ -0,0 +1,135 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
+
+
+import junit.framework.TestCase;
+import org.apache.kerby.kerberos.kerb.client.preauth.pkinit.certs.CertificateChainFactory;
+import org.bouncycastle.cms.CMSSignedData;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateCrtKey;
+
+/**
+ * Tests the use of {@link CMSSignedData}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class SignedDataEngineTest extends TestCase
+{
+    /** The log for this class. */
+    private static final Logger log = LoggerFactory.getLogger( SignedDataEngineTest.class
);
+
+    private static final String ID_DATA = "1.2.840.113549.1.7.1";
+
+    /** Certificate used to verify the signature. */
+    private X509Certificate certificate;
+
+    /** Private key used to sign the data. */
+    private PrivateKey privateKey;
+
+
+    public void setUp() throws Exception
+    {
+        if ( Security.getProvider( "BC" ) == null )
+        {
+            Security.addProvider( new BouncyCastleProvider() );
+        }
+
+        //getCaFromFile( "/tmp/testCa.p12", "password", "Test CA" );
+        getCaFromFactory();
+    }
+
+
+    /**
+     * Tests that signed data signature validation works.
+     *
+     * @throws Exception
+     */
+    public void testSignedData() throws Exception
+    {
+        byte[] data = "Hello".getBytes();
+
+        byte[] signedDataBytes = SignedDataEngine.getSignedData( privateKey, certificate,
data, ID_DATA );
+
+        CMSSignedData signedData = new CMSSignedData( signedDataBytes );
+
+        assertTrue(SignedDataEngine.validateSignedData( signedData ));
+    }
+
+
+    void getCaFromFactory() throws Exception
+    {
+        X509Certificate[] clientChain = CertificateChainFactory.getClientChain();
+        certificate = clientChain[0];
+
+        privateKey = CertificateChainFactory.getClientPrivateKey();
+    }
+
+
+    void getCaFromFile( String caFile, String caPassword, String caAlias ) throws KeyStoreException,
+        NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException,
UnrecoverableKeyException,
+        InvalidKeyException, SignatureException, NoSuchProviderException
+    {
+        // Open the keystore.
+        KeyStore caKs = KeyStore.getInstance( "PKCS12" );
+        caKs.load( new FileInputStream( new File( caFile ) ), caPassword.toCharArray() );
+
+        // Load the private key from the keystore.
+        privateKey = ( RSAPrivateCrtKey ) caKs.getKey( caAlias, caPassword.toCharArray()
);
+
+        if ( privateKey == null )
+        {
+            throw new IllegalStateException( "Got null key from keystore!" );
+        }
+
+        // Load the certificate from the keystore.
+        certificate = ( X509Certificate ) caKs.getCertificate( caAlias );
+
+        if ( certificate == null )
+        {
+            throw new IllegalStateException( "Got null cert from keystore!" );
+        }
+
+        log.debug( "Successfully loaded CA key and certificate. CA DN is '{}'.", certificate.getSubjectDN().getName()
);
+
+        // Verify.
+        certificate.verify( certificate.getPublicKey() );
+        log.debug( "Successfully verified CA certificate with its own public key." );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c98ab976/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/certs/CertificateChainFactoryTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/certs/CertificateChainFactoryTest.java
b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/certs/CertificateChainFactoryTest.java
new file mode 100644
index 0000000..531fd07
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/test/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/certs/CertificateChainFactoryTest.java
@@ -0,0 +1,116 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.preauth.pkinit.certs;
+
+import junit.framework.TestCase;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests the dynamic generation of certificate chains.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CertificateChainFactoryTest extends TestCase
+{
+    public void setUp()
+    {
+        if ( Security.getProvider( BouncyCastleProvider.PROVIDER_NAME ) == null )
+        {
+            Security.addProvider( new BouncyCastleProvider() );
+        }
+    }
+
+
+    /**
+     * Tests construction of the client chain.
+     * 
+     * The created certificates can be displayed with a command like:
+     * 
+     * openssl pkcs12 -nodes -info -in /tmp/test.p12 > /tmp/test.cert && openssl
x509 -noout -text -in /tmp/test.cert
+     * 
+     * @throws Exception 
+     */
+    public void testClientChain() throws Exception
+    {
+        X509Certificate[] clientChain = CertificateChainFactory.getClientChain();
+
+        validateChain( clientChain );
+    }
+
+
+    /**
+     * Tests construction of the KDC chain.
+     * 
+     * The created certificates can be displayed with a command like:
+     * 
+     * openssl pkcs12 -nodes -info -in /tmp/test.p12 > /tmp/test.cert && openssl
x509 -noout -text -in /tmp/test.cert
+     * 
+     * @throws Exception 
+     */
+    public void testKdcChain() throws Exception
+    {
+        X509Certificate[] kdcChain = CertificateChainFactory.getKdcChain();
+
+        validateChain( kdcChain );
+    }
+
+
+    /**
+     * Validates a chain of {@link X509Certificate}s.
+     *
+     * @param chain
+     * @throws CertificateException
+     * @throws InvalidAlgorithmParameterException
+     */
+    private void validateChain( X509Certificate[] chain ) throws CertificateException,
+        InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException,
+        InvalidAlgorithmParameterException, CertPathValidatorException
+    {
+        List<X509Certificate> certificateList = Arrays.asList( chain );
+        CertificateFactory certificateFactory = CertificateFactory.getInstance( "X.509" );
+        CertPath certPath = certificateFactory.generateCertPath( certificateList );
+
+        CertPathValidator cpv = CertPathValidator.getInstance( "PKIX", "BC" );
+
+        TrustAnchor trustAnchor = new TrustAnchor( chain[chain.length - 1], null );
+
+        PKIXParameters parameters = new PKIXParameters( Collections.singleton( trustAnchor
) );
+        parameters.setRevocationEnabled( false );
+
+        cpv.validate( certPath, parameters );
+    }
+}


Mime
View raw message