CertificateFactory.java revision a198e1ecc615e26a167d0f2dca9fa7e5fc62de10
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)package org.bouncycastle.jcajce.provider.asymmetric.x509; 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.io.IOException; 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.io.InputStream; 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.io.PushbackInputStream; 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.security.cert.CRL; 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.security.cert.CRLException; 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.security.cert.CertPath; 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.security.cert.CertificateException; 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.security.cert.CertificateFactorySpi; 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.security.cert.CertificateParsingException; 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.security.cert.X509Certificate; 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.util.ArrayList; 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.util.Collection; 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.util.Iterator; 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import java.util.List; 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.ASN1InputStream; 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.ASN1ObjectIdentifier; 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.ASN1Sequence; 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.ASN1Set; 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.ASN1TaggedObject; 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.pkcs.SignedData; 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.x509.Certificate; 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import org.bouncycastle.asn1.x509.CertificateList; 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)/** 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * class for dealing with X509 certificates. 30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * <p> 315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" 328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * objects. 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) */ 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public class CertificateFactory 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) extends CertificateFactorySpi 37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE"); 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL"); 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private ASN1Set sData = null; 42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) private int sDataObjectCount = 0; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private InputStream currentStream = null; 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private ASN1Set sCrlData = null; 468abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) private int sCrlDataObjectCount = 0; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private InputStream currentCrlStream = null; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private java.security.cert.Certificate readDERCertificate( 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASN1InputStream dIn) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws IOException, CertificateParsingException 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 538abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (seq.size() > 1 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sData = SignedData.getInstance(ASN1Sequence.getInstance( 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates(); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getCertificate(); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return new X509CertificateObject( 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Certificate.getInstance(seq)); 6902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch } 7002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 7102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch private java.security.cert.Certificate getCertificate() 7202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch throws CertificateParsingException 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch if (sData != null) 7502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch { 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (sDataObjectCount < sData.size()) 77d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) { 78d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Object obj = sData.getObjectAt(sDataObjectCount++); 79d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 80d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (obj instanceof ASN1Sequence) 81d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) { 82d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return new X509CertificateObject( 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Certificate.getInstance(obj)); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 91d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) private java.security.cert.Certificate readPEMCertificate( 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputStream in) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws IOException, CertificateParsingException 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASN1Sequence seq = PEM_CERT_PARSER.readPEMObject(in); 968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (seq != null) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return new X509CertificateObject( 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Certificate.getInstance(seq)); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected CRL createCRL(CertificateList c) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws CRLException 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return new X509CRLObject(c); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private CRL readPEMCRL( 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputStream in) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws IOException, CRLException 115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) { 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASN1Sequence seq = PEM_CRL_PARSER.readPEMObject(in); 117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (seq != null) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return createCRL( 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CertificateList.getInstance(seq)); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 125a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 126a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 127a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) private CRL readDERCRL( 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASN1InputStream aIn) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws IOException, CRLException 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (seq.size() > 1 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 136d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sCrlData = SignedData.getInstance(ASN1Sequence.getInstance( 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs(); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getCRL(); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch } 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return createCRL( 146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) CertificateList.getInstance(seq)); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private CRL getCRL() 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws CRLException 1518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) { 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size()) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return null; 1551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return createCRL( 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CertificateList.getInstance( 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sCrlData.getObjectAt(sCrlDataObjectCount++))); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Generates a certificate object and initializes it with the data 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * read from the input stream inStream. 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public java.security.cert.Certificate engineGenerateCertificate( 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputStream in) 16851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) throws CertificateException 16951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) { 17051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (currentStream == null) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentStream = in; 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sData = null; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sDataObjectCount = 0; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (currentStream != in) // reset if input stream has changed 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) currentStream = in; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sData = null; 1808abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) sDataObjectCount = 0; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) try 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sData != null) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sDataObjectCount != sData.size()) 18807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 1898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return getCertificate(); 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sData = null; 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sDataObjectCount = 0; 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PushbackInputStream pis = new PushbackInputStream(in); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int tag = pis.read(); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tag == -1) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pis.unread(tag); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tag != 0x30) // assume ascii PEM encoded. 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return readPEMCertificate(pis); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return readDERCertificate(new ASN1InputStream(pis)); 21607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 2178abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) catch (Exception e) 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throw new ExCertificateException(e); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Returns a (possibly empty) collection view of the certificates 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * read from the given input stream inStream. 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public Collection engineGenerateCertificates( 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputStream inStream) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws CertificateException 231d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) { 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) java.security.cert.Certificate cert; 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) List certs = new ArrayList(); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while ((cert = engineGenerateCertificate(inStream)) != null) 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) certs.add(cert); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return certs; 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Generates a certificate revocation list (CRL) object and initializes 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * it with the data read from the input stream inStream. 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public CRL engineGenerateCRL( 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputStream inStream) 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) throws CRLException 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currentCrlStream == null) 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentCrlStream = inStream; 254d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) sCrlData = null; 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sCrlDataObjectCount = 0; 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (currentCrlStream != inStream) // reset if input stream has changed 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentCrlStream = inStream; 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sCrlData = null; 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sCrlDataObjectCount = 0; 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) try 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sCrlData != null) 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sCrlDataObjectCount != sCrlData.size()) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getCRL(); 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sCrlData = null; 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sCrlDataObjectCount = 0; 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PushbackInputStream pis = new PushbackInputStream(inStream); 281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) int tag = pis.read(); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tag == -1) 284c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) { 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 286c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pis.unread(tag); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tag != 0x30) // assume ascii PEM encoded. 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 292f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return readPEMCRL(pis); 293f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) } 294f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) else 295f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) { // lazy evaluate to help processing of large CRLs 296f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return readDERCRL(new ASN1InputStream(pis, true)); 297f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) } 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 299 catch (CRLException e) 300 { 301 throw e; 302 } 303 catch (Exception e) 304 { 305 throw new CRLException(e.toString()); 306 } 307 } 308 309 /** 310 * Returns a (possibly empty) collection view of the CRLs read from 311 * the given input stream inStream. 312 * 313 * The inStream may contain a sequence of DER-encoded CRLs, or 314 * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the 315 * only signficant field being crls. In particular the signature 316 * and the contents are ignored. 317 */ 318 public Collection engineGenerateCRLs( 319 InputStream inStream) 320 throws CRLException 321 { 322 CRL crl; 323 List crls = new ArrayList(); 324 325 while ((crl = engineGenerateCRL(inStream)) != null) 326 { 327 crls.add(crl); 328 } 329 330 return crls; 331 } 332 333 public Iterator engineGetCertPathEncodings() 334 { 335 return PKIXCertPath.certPathEncodings.iterator(); 336 } 337 338 public CertPath engineGenerateCertPath( 339 InputStream inStream) 340 throws CertificateException 341 { 342 return engineGenerateCertPath(inStream, "PkiPath"); 343 } 344 345 public CertPath engineGenerateCertPath( 346 InputStream inStream, 347 String encoding) 348 throws CertificateException 349 { 350 return new PKIXCertPath(inStream, encoding); 351 } 352 353 public CertPath engineGenerateCertPath( 354 List certificates) 355 throws CertificateException 356 { 357 Iterator iter = certificates.iterator(); 358 Object obj; 359 while (iter.hasNext()) 360 { 361 obj = iter.next(); 362 if (obj != null) 363 { 364 if (!(obj instanceof X509Certificate)) 365 { 366 throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString()); 367 } 368 } 369 } 370 return new PKIXCertPath(certificates); 371 } 372 373 private class ExCertificateException 374 extends CertificateException 375 { 376 private Throwable cause; 377 378 public ExCertificateException(Throwable cause) 379 { 380 this.cause = cause; 381 } 382 383 public ExCertificateException(String msg, Throwable cause) 384 { 385 super(msg); 386 387 this.cause = cause; 388 } 389 390 public Throwable getCause() 391 { 392 return cause; 393 } 394 } 395} 396