Index: modules/security/src/test/java/common/org/apache/harmony/security/tests/java/security/cert/CertificateFactoryTest.java =================================================================== --- modules/security/src/test/java/common/org/apache/harmony/security/tests/java/security/cert/CertificateFactoryTest.java (revision 0) +++ modules/security/src/test/java/common/org/apache/harmony/security/tests/java/security/cert/CertificateFactoryTest.java (revision 0) @@ -0,0 +1,222 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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. + */ + +/** + * @author Alexander Y. Kleymenov + * @version $Revision$ + */ + +package org.apache.harmony.security.tests.java.security.cert; + +import java.io.ByteArrayInputStream; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.cert.CertificateFactory; +import java.security.cert.X509CRL; +import java.security.cert.X509Certificate; +import java.security.spec.X509EncodedKeySpec; +import java.util.Collection; +import java.util.Iterator; +import org.apache.harmony.luni.util.Base64; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * X.509 CertificateFactory provider implementation test.
+ * See RFC 3280 (http://www.ietf.org/rfc/rfc3280.txt) for + * more information on X.509, and + * http://www.rsasecurity.com/rsalabs/node.asp?id=2129 + * for more information on PKCS #7. + * The testing data was generated by use of classes from + * org.apache.harmony.security.x509 package. + */ +public class CertificateFactoryTest extends TestCase { + + /** + * Base64 encoded PKCS7 SignedObject containing two X.509 CRLs. + */ + private static String pkcs7so = + "MIIHBQYJKoZIhvcNAQcCoIIG9jCCBvICAQExADALBgkqhkiG9w0BBwGg" + + "ggUkMIICjjCCAk6gAwIBAgICAiswCQYHKoZIzjgEAzAdMRswGQYDVQQK" + + "ExJDZXJ0aWZpY2F0ZSBJc3N1ZXIwHhcNMDYwNTE4MDUxMzQzWhcNMzMx" + + "MDA3MDQxNzM5WjAdMRswGQYDVQQKExJDZXJ0aWZpY2F0ZSBJc3N1ZXIw" + + "ggG4MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YR" + + "t1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv" + + "8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7D" + + "AjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi" + + "64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeC" + + "Z1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjg" + + "o64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8Gkotm" + + "XoB7VSVkAUw7/s9JKgOBhQACgYEA8EFZqbP1i1VG045DPX+glAxnOs3C" + + "PKiX9vnqWbDh4EVANHgCq9fwsuFModO1OTc0tA7CY386PJKGppcELlva" + + "foPw6Qsp59980E7mwa6deTmdwdjXH9uP7/niZ4hVA+xHiFXl4oJeroq/" + + "/pcNOCjo7ZujYc954kDiyUsGBsP0uaejHjAcMBoGA1UdEQEB/wQQMA6B" + + "DHJmY0A4MjIuTmFtZTAJBgcqhkjOOAQDAy8AMCwCFB5XdhSOXmUNJfRL" + + "l5gYDo4XsZeJAhR6Yueam/MwyEcA8/SG1Xr1/WJnlDCCAo4wggJOoAMC" + + "AQICAgIrMAkGByqGSM44BAMwHTEbMBkGA1UEChMSQ2VydGlmaWNhdGUg" + + "SXNzdWVyMB4XDTA2MDUxODA1MTM0M1oXDTMzMTAwNzA0MTczOVowHTEb" + + "MBkGA1UEChMSQ2VydGlmaWNhdGUgSXNzdWVyMIIBuDCCASwGByqGSM44" + + "BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp" + + "RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7" + + "ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith" + + "1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+Gg" + + "hdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB" + + "gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/oh" + + "NWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoD" + + "gYUAAoGBAPBBWamz9YtVRtOOQz1/oJQMZzrNwjyol/b56lmw4eBFQDR4" + + "AqvX8LLhTKHTtTk3NLQOwmN/OjyShqaXBC5b2n6D8OkLKefffNBO5sGu" + + "nXk5ncHY1x/bj+/54meIVQPsR4hV5eKCXq6Kv/6XDTgo6O2bo2HPeeJA" + + "4slLBgbD9Lmnox4wHDAaBgNVHREBAf8EEDAOgQxyZmNAODIyLk5hbWUw" + + "CQYHKoZIzjgEAwMvADAsAhQeV3YUjl5lDSX0S5eYGA6OF7GXiQIUemLn" + + "mpvzMMhHAPP0htV69f1iZ5ShggGyMIHWMIGWAgEBMAkGByqGSM44BAMw" + + "FTETMBEGA1UEChMKQ1JMIElzc3VlchcNMDYwNTE4MDUxMzQ0WhcNMDYw" + + "NTE4MDUxNTI0WjBAMD4CAgIrFw0wNjA1MTgwNTEzNDVaMCkwCgYDVR0V" + + "BAMKAQEwGwYDVR0YBBQYEjIwMDYwNTE4MDUxMzQ0Ljg5WqAPMA0wCwYD" + + "VR0UBAQCAhFcMAkGByqGSM44BAMDMAAwLQIVAIkFZCysgzWYGxIXf+pc" + + "jMDniwHyAhQfeuU5AQucvJKodpN+yfbQRoFEHTCB1jCBlgIBATAJBgcq" + + "hkjOOAQDMBUxEzARBgNVBAoTCkNSTCBJc3N1ZXIXDTA2MDUxODA1MTM0" + + "NFoXDTA2MDUxODA1MTUyNFowQDA+AgICKxcNMDYwNTE4MDUxMzQ1WjAp" + + "MAoGA1UdFQQDCgEBMBsGA1UdGAQUGBIyMDA2MDUxODA1MTM0NC44OVqg" + + "DzANMAsGA1UdFAQEAgIRXDAJBgcqhkjOOAQDAzAAMC0CFQCJBWQsrIM1" + + "mBsSF3/qXIzA54sB8gIUH3rlOQELnLySqHaTfsn20EaBRB0xAA=="; + + /** + * Base64 encoded Public Key for signature verification. + * Key corresponds to the CRLs and Certificates in PKCS7 SignedObject. + */ + private static String b64PublicKeySpec = + "MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2" + + "EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00" + + "b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208Ue" + + "wwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC" + + "ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0H" + + "gmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o" + + "4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKL" + + "Zl6Ae1UlZAFMO/7PSSoDgYUAAoGBAPBBWamz9YtVRtOOQz1/oJQMZzrN" + + "wjyol/b56lmw4eBFQDR4AqvX8LLhTKHTtTk3NLQOwmN/OjyShqaXBC5b" + + "2n6D8OkLKefffNBO5sGunXk5ncHY1x/bj+/54meIVQPsR4hV5eKCXq6K" + + "v/6XDTgo6O2bo2HPeeJA4slLBgbD9Lmn"; + + /** + * The name of the algorithm used for Certificate/CRL signing. + */ + private static String publicKeyAlgorithm = "DSA"; + + /** + * The public key to verify generated Certificates and CRLs. + */ + private static PublicKey publicKey; + + static { + try { + X509EncodedKeySpec publicKeySpec = + new X509EncodedKeySpec( + Base64.decode(b64PublicKeySpec.getBytes())); + KeyFactory keyFactory = + KeyFactory.getInstance(publicKeyAlgorithm); + publicKey = keyFactory.generatePublic(publicKeySpec); + } catch (NoSuchAlgorithmException e) { + // provider is not installed, will not verify the generated data + publicKey = null; + } catch (Exception e) { + // problems with a representation of the key + e.printStackTrace(); + publicKey = null; + } + } + + /** + * generateCRLs method testing. + */ + public void testGenerateCRLs() throws Exception { + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + + // Testing the CRLs generation on the base of PKCS7 SignedData object + ByteArrayInputStream bais = new ByteArrayInputStream( + Base64.decode(pkcs7so.getBytes())); + + Collection crls = factory.generateCRLs(bais); + assertNotNull("Factory returned null on correct PKCS7 data", crls); + assertEquals("The size of collection differs from expected", + 2, crls.size()); + + if (publicKey != null) { + // verify the signatures + for (Iterator i = crls.iterator(); i.hasNext();) { + ((X509CRL) i.next()).verify(publicKey); + } + } + } + + /** + * generateCertificates method testing. + */ + public void testGenerateCertificates() throws Exception { + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + + // Testing the Certificates generation + // on the base of PKCS7 SignedData object + ByteArrayInputStream bais = new ByteArrayInputStream( + Base64.decode(pkcs7so.getBytes())); + + Collection certs = factory.generateCertificates(bais); + assertNotNull("Factory returned null on correct PKCS7 data", certs); + assertEquals("The size of collection differs from expected", + 2, certs.size()); + + if (publicKey != null) { + // verify the signatures + for (Iterator i = certs.iterator(); i.hasNext();) { + ((X509Certificate) i.next()).verify(publicKey); + } + } + } + + /** + * generateCertificates method testing. + */ + public void testGenerateCertPath() throws Exception { + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + + // Testing the CertPath generation + // on the base of PKCS7 SignedData object + ByteArrayInputStream bais = new ByteArrayInputStream( + Base64.decode(pkcs7so.getBytes())); + + Collection certPath = + factory.generateCertPath(bais, "PKCS7").getCertificates(); + assertEquals("The size of collection differs from expected", + 2, certPath.size()); + + if (publicKey != null) { + // verify the signatures + for (Iterator i = certPath.iterator(); i.hasNext();) { + ((X509Certificate) i.next()).verify(publicKey); + } + } + } + + public static Test suite() { + return new TestSuite(CertificateFactoryTest.class); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } +} Index: modules/security/src/main/java/common/org/apache/harmony/security/asn1/BerInputStream.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/asn1/BerInputStream.java (revision 410439) +++ modules/security/src/main/java/common/org/apache/harmony/security/asn1/BerInputStream.java (working copy) @@ -185,7 +185,7 @@ * @return next decoded tag * @throws IOException - if error occured */ - protected int next() throws IOException { + public int next() throws IOException { tagOffset = offset; Index: modules/security/src/main/java/common/org/apache/harmony/security/asn1/DerInputStream.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/asn1/DerInputStream.java (revision 410439) +++ modules/security/src/main/java/common/org/apache/harmony/security/asn1/DerInputStream.java (working copy) @@ -48,7 +48,7 @@ /** * @see org.apache.harmony.security.asn1.BerInputStream#next() */ - protected final int next() throws IOException { + public final int next() throws IOException { int tag = super.next(); Index: modules/security/src/main/java/common/org/apache/harmony/security/pkcs7/SignedData.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/pkcs7/SignedData.java (revision 410439) +++ modules/security/src/main/java/common/org/apache/harmony/security/pkcs7/SignedData.java (working copy) @@ -31,6 +31,7 @@ import org.apache.harmony.security.asn1.BerInputStream; import org.apache.harmony.security.x509.AlgorithmIdentifier; import org.apache.harmony.security.x509.Certificate; +import org.apache.harmony.security.x509.CertificateList; /** @@ -73,6 +74,10 @@ return certificates; } + public List getCRLs() { + return crls; + } + public List getSignerInfos() { return signerInfos; } @@ -105,7 +110,7 @@ new ASN1SetOf(AlgorithmIdentifier.ASN1), ContentInfo.ASN1, new ASN1Implicit(0, new ASN1SetOf(Certificate.ASN1)), - new ASN1Implicit(1, new ASN1SetOf(ASN1Any.getInstance())), + new ASN1Implicit(1, new ASN1SetOf(CertificateList.ASN1)), new ASN1SetOf(SignerInfo.ASN1) }) { { @@ -113,6 +118,16 @@ setOptional(4); // crls is optional } + protected void getValues(Object object, Object[] values) { + SignedData sd = (SignedData) object; + values[0] = new byte[] {(byte)sd.version}; + values[1] = sd.digestAlgorithms; + values[2] = sd.contentInfo; + values[3] = sd.certificates; + values[4] = sd.crls; + values[5] = sd.signerInfos; + } + protected Object getDecodedObject(BerInputStream in) { Object[] values = (Object[]) in.content; return new SignedData( @@ -126,4 +141,4 @@ } }; -} \ No newline at end of file +} Index: modules/security/src/main/java/common/org/apache/harmony/security/provider/cert/X509CertPathImpl.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/provider/cert/X509CertPathImpl.java (revision 410439) +++ modules/security/src/main/java/common/org/apache/harmony/security/provider/cert/X509CertPathImpl.java (working copy) @@ -176,7 +176,11 @@ // empty chain of certificates certs = new ArrayList(); } - return new X509CertPathImpl(certs, PKCS7, ci.getEncoded()); + List result = new ArrayList(); + for (int i=0; i