1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.jce.provider; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.BufferedInputStream; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayInputStream; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayOutputStream; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.InputStream; 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.OutputStreamWriter; 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.NoSuchProviderException; 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertPath; 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.Certificate; 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateEncodingException; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateException; 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateFactory; 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.X509Certificate; 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.ArrayList; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Collections; 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration; 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Iterator; 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.List; 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.ListIterator; 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport javax.security.auth.x500.X500Principal; 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Encodable; 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1EncodableVector; 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1InputStream; 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence; 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERInteger; 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERObject; 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSequence; 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSet; 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.ContentInfo; 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.SignedData; 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// BEGIN android-removed 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// import org.bouncycastle.openssl.PEMWriter; 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// END android-removed 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * CertPath implementation for X.509 certificates. 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <br /> 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class PKIXCertPath 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends CertPath 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final List certPathEncodings; 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam List encodings = new ArrayList(); 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encodings.add("PkiPath"); 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encodings.add("PEM"); 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encodings.add("PKCS7"); 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certPathEncodings = Collections.unmodifiableList(encodings); 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private List certificates; 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param certs 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private List sortCerts( 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam List certs) 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (certs.size() < 2) 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return certs; 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X500Principal issuer = ((X509Certificate)certs.get(0)).getIssuerX500Principal(); 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean okay = true; 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 1; i != certs.size(); i++) 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509Certificate cert = (X509Certificate)certs.get(i); 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (issuer.equals(cert.getSubjectX500Principal())) 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam issuer = ((X509Certificate)certs.get(i)).getIssuerX500Principal(); 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam okay = false; 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (okay) 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return certs; 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // find end-entity cert 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam List retList = new ArrayList(certs.size()); 96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom List orig = new ArrayList(certs); 97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i < certs.size(); i++) 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509Certificate cert = (X509Certificate)certs.get(i); 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean found = false; 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X500Principal subject = cert.getSubjectX500Principal(); 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int j = 0; j != certs.size(); j++) 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509Certificate c = (X509Certificate)certs.get(j); 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (c.getIssuerX500Principal().equals(subject)) 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam found = true; 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!found) 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam retList.add(cert); 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certs.remove(i); 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // can only have one end entity cert - something's wrong, give up. 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (retList.size() > 1) 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 125c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return orig; 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != retList.size(); i++) 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam issuer = ((X509Certificate)retList.get(i)).getIssuerX500Principal(); 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int j = 0; j < certs.size(); j++) 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509Certificate c = (X509Certificate)certs.get(j); 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (issuer.equals(c.getSubjectX500Principal())) 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam retList.add(c); 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certs.remove(j); 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // make sure all certificates are accounted for. 145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (certs.size() > 0) 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 147c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return orig; 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return retList; 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKIXCertPath(List certificates) 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super("X.509"); 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.certificates = sortCerts(new ArrayList(certificates)); 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Creates a CertPath of the specified type. 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * This constructor is protected because most users should use 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a CertificateFactory to create CertPaths. 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKIXCertPath( 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InputStream inStream, 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String encoding) 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateException 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super("X.509"); 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (encoding.equalsIgnoreCase("PkiPath")) 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1InputStream derInStream = new ASN1InputStream(inStream); 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERObject derObject = derInStream.readObject(); 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!(derObject instanceof ASN1Sequence)) 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new CertificateException("input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath"); 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = ((ASN1Sequence)derObject).getObjects(); 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certificates = new ArrayList(); 1826e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom CertificateFactory certFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 185c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1Encodable element = (ASN1Encodable)e.nextElement(); 186c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] encoded = element.getEncoded(ASN1Encodable.DER); 187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom certificates.add(0, certFactory.generateCertificate( 188c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom new ByteArrayInputStream(encoded))); 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (encoding.equalsIgnoreCase("PKCS7") || encoding.equalsIgnoreCase("PEM")) 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam inStream = new BufferedInputStream(inStream); 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certificates = new ArrayList(); 1956e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom CertificateFactory certFactory= CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate cert; 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while ((cert = certFactory.generateCertificate(inStream)) != null) 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certificates.add(cert); 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new CertificateException("unsupported encoding: " + encoding); 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException ex) 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new CertificateException("IOException throw while decoding CertPath:\n" + ex.toString()); 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (NoSuchProviderException ex) 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new CertificateException("BouncyCastle provider not found while trying to get a CertificateFactory:\n" + ex.toString()); 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.certificates = sortCerts(certificates); 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Returns an iteration of the encodings supported by this 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * certification path, with the default encoding 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * first. Attempts to modify the returned Iterator via its 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * remove method result in an UnsupportedOperationException. 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return an Iterator over the names of the supported encodings (as Strings) 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Iterator getEncodings() 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return certPathEncodings.iterator(); 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Returns the encoded form of this certification path, using 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * the default encoding. 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return the encoded bytes 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception CertificateEncodingException if an encoding error occurs 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public byte[] getEncoded() 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateEncodingException 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Iterator iter = getEncodings(); 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (iter.hasNext()) 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object enc = iter.next(); 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (enc instanceof String) 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return getEncoded((String)enc); 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Returns the encoded form of this certification path, using 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * the specified encoding. 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param encoding the name of the encoding to use 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return the encoded bytes 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception CertificateEncodingException if an encoding error 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * occurs or the encoding requested is not supported 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public byte[] getEncoded(String encoding) 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateEncodingException 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (encoding.equalsIgnoreCase("PkiPath")) 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector v = new ASN1EncodableVector(); 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ListIterator iter = certificates.listIterator(certificates.size()); 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (iter.hasPrevious()) 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam v.add(toASN1Object((X509Certificate)iter.previous())); 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return toDEREncoded(new DERSequence(v)); 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (encoding.equalsIgnoreCase("PKCS7")) 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ContentInfo encInfo = new ContentInfo(PKCSObjectIdentifiers.data, null); 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector v = new ASN1EncodableVector(); 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != certificates.size(); i++) 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam v.add(toASN1Object((X509Certificate)certificates.get(i))); 287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SignedData sd = new SignedData( 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new DERInteger(1), 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new DERSet(), 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encInfo, 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new DERSet(v), 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam null, 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new DERSet()); 296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return toDEREncoded(new ContentInfo( 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCSObjectIdentifiers.signedData, sd)); 299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // BEGIN android-removed 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // else if (encoding.equalsIgnoreCase("PEM")) 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // { 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut)); 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // try 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // { 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // for (int i = 0; i != certificates.size(); i++) 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // { 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // pWrt.writeObject(certificates.get(i)); 311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // } 312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // pWrt.close(); 314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // } 315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // catch (Exception e) 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // { 317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // throw new CertificateEncodingException("can't encode certificate for PEM encoded path"); 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // } 319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // return bOut.toByteArray(); 321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // } 322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // END android-removed 323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new CertificateEncodingException("unsupported encoding: " + encoding); 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Returns the list of certificates in this certification 331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * path. The List returned must be immutable and thread-safe. 332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return an immutable List of Certificates (may be empty, but not null) 334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public List getCertificates() 336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return Collections.unmodifiableList(new ArrayList(certificates)); 338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Return a DERObject containing the encoded certificate. 342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param cert the X509Certificate object to be encoded 344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return the DERObject 346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private DERObject toASN1Object( 348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509Certificate cert) 349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateEncodingException 350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new ASN1InputStream(cert.getEncoded()).readObject(); 354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new CertificateEncodingException("Exception while encoding certificate: " + e.toString()); 358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private byte[] toDEREncoded(ASN1Encodable obj) 362b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws CertificateEncodingException 363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 364b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 366c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return obj.getEncoded(ASN1Encodable.DER); 367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException e) 369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 370c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new CertificateEncodingException("Exception thrown: " + e); 371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 374