14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.jcajce.provider.asymmetric.x509; 2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.InputStream; 5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.PushbackInputStream; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CRL; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CRLException; 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertPath; 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateException; 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateFactorySpi; 11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.cert.CertificateParsingException; 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.X509Certificate; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.ArrayList; 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Collection; 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Iterator; 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.List; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1InputStream; 194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier; 204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Sequence; 214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Set; 224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1TaggedObject; 234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.pkcs.SignedData; 25e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstromimport org.bouncycastle.asn1.x509.Certificate; 264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.CertificateList; 274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * class for dealing with X509 certificates. 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p> 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * objects. 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic class CertificateFactory 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends CertificateFactorySpi 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE"); 39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL"); 40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private ASN1Set sData = null; 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int sDataObjectCount = 0; 434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private InputStream currentStream = null; 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private ASN1Set sCrlData = null; 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int sCrlDataObjectCount = 0; 474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private InputStream currentCrlStream = null; 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private java.security.cert.Certificate readDERCertificate( 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1InputStream dIn) 51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException, CertificateParsingException 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (seq.size() > 1 564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom sData = SignedData.getInstance(ASN1Sequence.getInstance( 614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates(); 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return getCertificate(); 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new X509CertificateObject( 68e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom Certificate.getInstance(seq)); 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private java.security.cert.Certificate getCertificate() 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws CertificateParsingException 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (sData != null) 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom while (sDataObjectCount < sData.size()) 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Object obj = sData.getObjectAt(sDataObjectCount++); 79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (obj instanceof ASN1Sequence) 81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new X509CertificateObject( 83e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom Certificate.getInstance(obj)); 84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return null; 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private java.security.cert.Certificate readPEMCertificate( 924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom InputStream in) 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException, CertificateParsingException 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1Sequence seq = PEM_CERT_PARSER.readPEMObject(in); 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (seq != null) 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new X509CertificateObject( 100e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom Certificate.getInstance(seq)); 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom protected CRL createCRL(CertificateList c) 107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws CRLException 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new X509CRLObject(c); 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private CRL readPEMCRL( 1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom InputStream in) 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException, CRLException 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 116c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1Sequence seq = PEM_CRL_PARSER.readPEMObject(in); 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 118c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (seq != null) 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 120c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return createCRL( 121c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom CertificateList.getInstance(seq)); 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 127c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private CRL readDERCRL( 1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1InputStream aIn) 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException, CRLException 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Sequence seq = (ASN1Sequence)aIn.readObject(); 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (seq.size() > 1 1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData)) 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom sCrlData = SignedData.getInstance(ASN1Sequence.getInstance( 1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs(); 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 141c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return getCRL(); 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return createCRL( 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CertificateList.getInstance(seq)); 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 149c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private CRL getCRL() 150c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws CRLException 151c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 152c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size()) 153c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 154c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return null; 155c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 156c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 157c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return createCRL( 158c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom CertificateList.getInstance( 1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom sCrlData.getObjectAt(sCrlDataObjectCount++))); 160c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 161c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Generates a certificate object and initializes it with the data 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * read from the input stream inStream. 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public java.security.cert.Certificate engineGenerateCertificate( 1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom InputStream in) 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateException 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (currentStream == null) 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam currentStream = in; 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sData = null; 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sDataObjectCount = 0; 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (currentStream != in) // reset if input stream has changed 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam currentStream = in; 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sData = null; 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sDataObjectCount = 0; 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (sData != null) 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (sDataObjectCount != sData.size()) 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return getCertificate(); 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sData = null; 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sDataObjectCount = 0; 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 199c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PushbackInputStream pis = new PushbackInputStream(in); 200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int tag = pis.read(); 201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (tag == -1) 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 206c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom pis.unread(tag); 208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (tag != 0x30) // assume ascii PEM encoded. 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return readPEMCertificate(pis); 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 2154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return readDERCertificate(new ASN1InputStream(pis)); 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 2204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new ExCertificateException(e); 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Returns a (possibly empty) collection view of the certificates 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * read from the given input stream inStream. 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Collection engineGenerateCertificates( 2294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom InputStream inStream) 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateException 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 2324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom java.security.cert.Certificate cert; 2334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom List certs = new ArrayList(); 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while ((cert = engineGenerateCertificate(inStream)) != null) 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certs.add(cert); 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return certs; 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Generates a certificate revocation list (CRL) object and initializes 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * it with the data read from the input stream inStream. 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public CRL engineGenerateCRL( 2484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom InputStream inStream) 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CRLException 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (currentCrlStream == null) 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam currentCrlStream = inStream; 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sCrlData = null; 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sCrlDataObjectCount = 0; 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (currentCrlStream != inStream) // reset if input stream has changed 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam currentCrlStream = inStream; 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sCrlData = null; 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sCrlDataObjectCount = 0; 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (sCrlData != null) 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 268c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (sCrlDataObjectCount != sCrlData.size()) 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 270c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return getCRL(); 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sCrlData = null; 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sCrlDataObjectCount = 0; 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 279c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 280c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PushbackInputStream pis = new PushbackInputStream(inStream); 281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int tag = pis.read(); 282c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 283c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (tag == -1) 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 285c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return null; 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 287c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 288c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom pis.unread(tag); 289c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 290c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (tag != 0x30) // assume ascii PEM encoded. 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 292c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return readPEMCRL(pis); 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 295c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { // lazy evaluate to help processing of large CRLs 2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return readDERCRL(new ASN1InputStream(pis, true)); 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (CRLException e) 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw e; 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new CRLException(e.toString()); 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Returns a (possibly empty) collection view of the CRLs read from 311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * the given input stream inStream. 312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The inStream may contain a sequence of DER-encoded CRLs, or 314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the 315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * only signficant field being crls. In particular the signature 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * and the contents are ignored. 317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Collection engineGenerateCRLs( 3194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom InputStream inStream) 320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CRLException 321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom CRL crl; 3234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom List crls = new ArrayList(); 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while ((crl = engineGenerateCRL(inStream)) != null) 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam crls.add(crl); 328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return crls; 331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Iterator engineGetCertPathEncodings() 334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 335200c44f2dde27abe81d5125f893e6b6ed9b69674Kenny Root return PKIXCertPath.certPathEncodings.iterator(); 336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public CertPath engineGenerateCertPath( 339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InputStream inStream) 340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateException 341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return engineGenerateCertPath(inStream, "PkiPath"); 343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public CertPath engineGenerateCertPath( 346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InputStream inStream, 347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String encoding) 348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateException 349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new PKIXCertPath(inStream, encoding); 351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public CertPath engineGenerateCertPath( 354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam List certificates) 355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateException 356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Iterator iter = certificates.iterator(); 358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj; 359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (iter.hasNext()) 360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam obj = iter.next(); 362b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj != null) 363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 364b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!(obj instanceof X509Certificate)) 365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 366c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString()); 367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new PKIXCertPath(certificates); 371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 3724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private class ExCertificateException 3744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom extends CertificateException 3754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private Throwable cause; 3774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ExCertificateException(Throwable cause) 3794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this.cause = cause; 3814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ExCertificateException(String msg, Throwable cause) 3844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom super(msg); 3864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this.cause = cause; 3884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public Throwable getCause() 3914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return cause; 3934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 396