directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From erodrig...@apache.org
Subject svn commit: r580522 - in /directory/sandbox/erodriguez/kerberos-pkinit/src: main/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngine.java test/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngineTest.java
Date Sat, 29 Sep 2007 00:20:19 GMT
Author: erodriguez
Date: Fri Sep 28 17:20:18 2007
New Revision: 580522

URL: http://svn.apache.org/viewvc?rev=580522&view=rev
Log:
Cryptographic Message Syntax (CMS) Signed Data support for PKINIT:
o  Helper class for working with Signed Data.
o  Test case for the above.

Added:
    directory/sandbox/erodriguez/kerberos-pkinit/src/main/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngine.java
  (with props)
    directory/sandbox/erodriguez/kerberos-pkinit/src/test/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngineTest.java
  (with props)

Added: directory/sandbox/erodriguez/kerberos-pkinit/src/main/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngine.java
URL: http://svn.apache.org/viewvc/directory/sandbox/erodriguez/kerberos-pkinit/src/main/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngine.java?rev=580522&view=auto
==============================================================================
--- directory/sandbox/erodriguez/kerberos-pkinit/src/main/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngine.java
(added)
+++ directory/sandbox/erodriguez/kerberos-pkinit/src/main/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngine.java
Fri Sep 28 17:20:18 2007
@@ -0,0 +1,203 @@
+/*
+ *  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.directory.server.kerberos.pkinit;
+
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.apache.directory.server.kerberos.pkinit.io.AuthPack;
+import org.apache.directory.server.kerberos.pkinit.io.KdcDhKeyInfo;
+import org.apache.directory.server.kerberos.pkinit.io.ReplyKeyPack;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSProcessableByteArray;
+import org.bouncycastle.cms.CMSSignedData;
+import org.bouncycastle.cms.CMSSignedDataGenerator;
+import org.bouncycastle.cms.CMSSignedGenerator;
+import org.bouncycastle.cms.SignerInformation;
+import org.bouncycastle.cms.SignerInformationStore;
+
+
+/**
+ * Encapsulates working with PKINIT signed data structures.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class SignedDataEngine
+{
+    private static final String ID_PKINIT_AUTHDATA = "1.3.6.1.5.2.3.1";
+    private static final String ID_PKINIT_DHKEYDATA = "1.3.6.1.5.2.3.2";
+    private static final String ID_PKINIT_RKEYDATA = "1.3.6.1.5.2.3.3";
+
+
+    /**
+     * Uses a private key to sign data in a CMS SignedData structure and returns
+     * the encoded CMS SignedData as bytes.
+     * 
+     * 'signedAuthPack' contains a CMS type ContentInfo encoded according to [RFC3852].
+     * 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.
+     * 
+     * @param privateKey
+     * @param certificate
+     * @param authPack
+     * @return The CMS SignedData bytes.
+     * @throws NoSuchAlgorithmException
+     * @throws NoSuchProviderException
+     * @throws InvalidAlgorithmParameterException
+     * @throws CertStoreException
+     * @throws CMSException
+     * @throws IOException
+     */
+    public static byte[] getSignedAuthPack( PrivateKey privateKey, X509Certificate certificate,
AuthPack authPack )
+        throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException,
+        CertStoreException, CMSException, IOException
+    {
+        return getSignedData( privateKey, certificate, authPack.getEncoded(), ID_PKINIT_AUTHDATA
);
+    }
+
+
+    /**
+     * Uses a private key to sign data in a CMS SignedData structure and returns
+     * the encoded CMS SignedData as bytes.
+     * 
+     * 'dhSignedData' contains a CMS type ContentInfo encoded according to [RFC3852].
+     * 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-DHKeyData (1.3.6.1.5.2.3.2),
+     * and the eContent field contains the DER encoding of the type KDCDHKeyInfo.
+     * 
+     * @param privateKey
+     * @param certificate
+     * @param kdcDhKeyInfo
+     * @return The CMS SignedData bytes.
+     * @throws NoSuchAlgorithmException
+     * @throws NoSuchProviderException
+     * @throws InvalidAlgorithmParameterException
+     * @throws CertStoreException
+     * @throws CMSException
+     * @throws IOException
+     */
+    public static byte[] getSignedKdcDhKeyInfo( PrivateKey privateKey, X509Certificate certificate,
+        KdcDhKeyInfo kdcDhKeyInfo ) throws NoSuchAlgorithmException, NoSuchProviderException,
+        InvalidAlgorithmParameterException, CertStoreException, CMSException, IOException
+    {
+        return getSignedData( privateKey, certificate, kdcDhKeyInfo.getEncoded(), ID_PKINIT_DHKEYDATA
);
+    }
+
+
+    /**
+     * Uses a private key to sign data in a CMS SignedData structure and returns
+     * the encoded CMS SignedData as bytes.
+     * 
+     * Selected when public key encryption is used.
+     * 
+     * The eContentType field for the inner type SignedData (when unencrypted) is
+     * id-pkinit-rkeyData (1.3.6.1.5.2.3.3) and the eContent field contains the
+     * DER encoding of the type ReplyKeyPack.
+     * 
+     * @param privateKey
+     * @param certificate
+     * @param replyKeyPack
+     * @return The CMS SignedData bytes.
+     * @throws NoSuchAlgorithmException
+     * @throws NoSuchProviderException
+     * @throws InvalidAlgorithmParameterException
+     * @throws CertStoreException
+     * @throws CMSException
+     * @throws IOException
+     */
+    public static byte[] getSignedReplyKeyPack( PrivateKey privateKey, X509Certificate certificate,
+        ReplyKeyPack replyKeyPack ) throws NoSuchAlgorithmException, NoSuchProviderException,
+        InvalidAlgorithmParameterException, CertStoreException, CMSException, IOException
+    {
+        return getSignedData( privateKey, certificate, replyKeyPack.getEncoded(), ID_PKINIT_RKEYDATA
);
+    }
+
+
+    static byte[] getSignedData( PrivateKey privateKey, X509Certificate certificate, byte[]
dataToSign,
+        String eContentType ) throws NoSuchAlgorithmException, NoSuchProviderException,
+        InvalidAlgorithmParameterException, CertStoreException, CMSException, IOException
+    {
+        CMSSignedDataGenerator signedGenerator = new CMSSignedDataGenerator();
+        signedGenerator.addSigner( privateKey, certificate, CMSSignedGenerator.DIGEST_SHA1
);
+
+        Collection<X509Certificate> certList = Collections.singletonList( certificate
);
+
+        CertStore certStore = CertStore.getInstance( "Collection", new CollectionCertStoreParameters(
certList ), "BC" );
+        signedGenerator.addCertificatesAndCRLs( certStore );
+
+        CMSProcessableByteArray cmsByteArray = new CMSProcessableByteArray( dataToSign );
+        CMSSignedData signedData = signedGenerator.generate( eContentType, cmsByteArray,
true, "BC" );
+
+        return signedData.getEncoded();
+    }
+
+
+    /**
+     * Validates a CMS SignedData using the public key corresponding to the private
+     * key used to sign the structure.
+     *
+     * @param signedData
+     * @return true if the signature is valid.
+     * @throws Exception
+     */
+    @SuppressWarnings("unchecked")
+    public static boolean validateSignedData( CMSSignedData signedData ) throws Exception
+    {
+        CertStore certs = signedData.getCertificatesAndCRLs( "Collection", "BC" );
+
+        SignerInformationStore signers = signedData.getSignerInfos();
+        Collection<SignerInformation> c = signers.getSigners();
+        Iterator<SignerInformation> it = c.iterator();
+
+        while ( it.hasNext() )
+        {
+            SignerInformation signer = it.next();
+
+            Collection<? extends Certificate> certCollection = certs.getCertificates(
signer.getSID() );
+            Iterator<? extends Certificate> certIt = certCollection.iterator();
+            X509Certificate cert = ( X509Certificate ) certIt.next();
+
+            if ( signer.verify( cert.getPublicKey(), "BC" ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}

Propchange: directory/sandbox/erodriguez/kerberos-pkinit/src/main/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngine.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/erodriguez/kerberos-pkinit/src/test/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngineTest.java
URL: http://svn.apache.org/viewvc/directory/sandbox/erodriguez/kerberos-pkinit/src/test/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngineTest.java?rev=580522&view=auto
==============================================================================
--- directory/sandbox/erodriguez/kerberos-pkinit/src/test/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngineTest.java
(added)
+++ directory/sandbox/erodriguez/kerberos-pkinit/src/test/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngineTest.java
Fri Sep 28 17:20:18 2007
@@ -0,0 +1,137 @@
+/*
+ *  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.directory.server.kerberos.pkinit;
+
+
+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 junit.framework.TestCase;
+
+import org.apache.directory.server.kerberos.pkinit.certs.CertificateChainFactory;
+import org.bouncycastle.cms.CMSSignedData;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * 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 );
+
+        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." );
+    }
+}

Propchange: directory/sandbox/erodriguez/kerberos-pkinit/src/test/java/org/apache/directory/server/kerberos/pkinit/SignedDataEngineTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message