1e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root/* 2e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * Copyright (C) 2013 The Android Open Source Project 3e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * 4e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * you may not use this file except in compliance with the License. 6e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * You may obtain a copy of the License at 7e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * 8e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 9e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * 10e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * Unless required by applicable law or agreed to in writing, software 11e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * See the License for the specific language governing permissions and 14e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * limitations under the License. 15e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root */ 16e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt; 18e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 19e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.io.IOException; 20e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.io.InputStream; 21e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.io.PushbackInputStream; 22e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.CertPath; 23e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.Certificate; 24e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.CertificateEncodingException; 25e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.CertificateException; 26e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.X509Certificate; 27f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Rootimport java.util.ArrayList; 28e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.Arrays; 29e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.Collections; 30e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.Iterator; 31e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.List; 32860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport org.conscrypt.OpenSSLX509CertificateFactory.ParsingException; 33e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 34e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootpublic class OpenSSLX509CertPath extends CertPath { 353e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root private static final byte[] PKCS7_MARKER = new byte[] { 363e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root '-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' ', 'P', 'K', 'C', 'S', '7' 373e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root }; 38e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 39e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static final int PUSHBACK_SIZE = 64; 40e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 41e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /** 42e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * Supported encoding types for CerthPath. Used by the various APIs that 43e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * encode this into bytes such as {@link #getEncoded()}. 44e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root */ 45e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private enum Encoding { 46f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root PKI_PATH("PkiPath"), 47e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root PKCS7("PKCS7"); 48e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 49e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private final String apiName; 50e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 51e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root Encoding(String apiName) { 52e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root this.apiName = apiName; 53e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 54e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 55e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root static Encoding findByApiName(String apiName) throws CertificateEncodingException { 56e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root for (Encoding element : values()) { 57e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (element.apiName.equals(apiName)) { 58e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return element; 59e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 60e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 61e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 62e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return null; 63e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 64e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 65e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 66e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /** Unmodifiable list of encodings for the API. */ 67e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static final List<String> ALL_ENCODINGS = Collections.unmodifiableList(Arrays 68e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root .asList(new String[] { 69f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root Encoding.PKI_PATH.apiName, 70f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root Encoding.PKCS7.apiName, 71e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root })); 72e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 73f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root private static final Encoding DEFAULT_ENCODING = Encoding.PKI_PATH; 74e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 75e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private final List<? extends X509Certificate> mCertificates; 76e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 77e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root static Iterator<String> getEncodingsIterator() { 78e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return ALL_ENCODINGS.iterator(); 79e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 80e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 81e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root protected OpenSSLX509CertPath(List<? extends X509Certificate> certificates) { 82e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root super("X.509"); 83e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 84e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root mCertificates = certificates; 85e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 86e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 87e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 88e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public List<? extends Certificate> getCertificates() { 89e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return Collections.unmodifiableList(mCertificates); 90e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 91e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 92e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private byte[] getEncoded(Encoding encoding) throws CertificateEncodingException { 93e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final OpenSSLX509Certificate[] certs = new OpenSSLX509Certificate[mCertificates.size()]; 94e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final long[] certRefs = new long[certs.length]; 95e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 96f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root for (int i = 0, j = certs.length - 1; j >= 0; i++, j--) { 97f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root final X509Certificate cert = mCertificates.get(i); 98f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 99f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root if (cert instanceof OpenSSLX509Certificate) { 100f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certs[j] = (OpenSSLX509Certificate) cert; 101e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } else { 102f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certs[j] = OpenSSLX509Certificate.fromX509Der(cert.getEncoded()); 103e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 104f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 105f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certRefs[j] = certs[j].getContext(); 106e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 107e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 108f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root switch (encoding) { 109f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root case PKI_PATH: 110f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return NativeCrypto.ASN1_seq_pack_X509(certRefs); 111f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root case PKCS7: 112f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return NativeCrypto.i2d_PKCS7(certRefs); 113f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root default: 114f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root throw new CertificateEncodingException("Unknown encoding"); 115f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 116e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 117e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 118e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 119e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public byte[] getEncoded() throws CertificateEncodingException { 120e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return getEncoded(DEFAULT_ENCODING); 121e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 122e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 123e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 124e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public byte[] getEncoded(String encoding) throws CertificateEncodingException { 125e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root Encoding enc = Encoding.findByApiName(encoding); 126e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (enc == null) { 127e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateEncodingException("Invalid encoding: " + encoding); 128e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 129e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 130f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return getEncoded(enc); 131e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 132e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 133e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 134e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public Iterator<String> getEncodings() { 135e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return getEncodingsIterator(); 136e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 137e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 138f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root private static CertPath fromPkiPathEncoding(InputStream inStream) throws CertificateException { 139f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(inStream); 140f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 141881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root final boolean markable = inStream.markSupported(); 142881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (markable) { 143881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root inStream.mark(PUSHBACK_SIZE); 144881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 145881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root 146f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root final long[] certRefs; 147f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root try { 148f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certRefs = NativeCrypto.ASN1_seq_unpack_X509_bio(bis.getBioContext()); 149f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } catch (Exception e) { 150881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (markable) { 151881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root try { 152881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root inStream.reset(); 153881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } catch (IOException ignored) { 154881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 155881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 156f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root throw new CertificateException(e); 157f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } finally { 15819fdf1af6bada9ebf4820839780d8713ac3824faKenny Root bis.release(); 159f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 160f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 161f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root if (certRefs == null) { 162f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList()); 163f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 164f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 165f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root final List<OpenSSLX509Certificate> certs = 166f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root new ArrayList<OpenSSLX509Certificate>(certRefs.length); 167f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root for (int i = certRefs.length - 1; i >= 0; i--) { 168f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root if (certRefs[i] == 0) { 169f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root continue; 170f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 171f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certs.add(new OpenSSLX509Certificate(certRefs[i])); 172f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 173f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 174f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return new OpenSSLX509CertPath(certs); 175f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 176f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 177e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static CertPath fromPkcs7Encoding(InputStream inStream) throws CertificateException { 178e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root try { 179e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (inStream == null || inStream.available() == 0) { 180e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList()); 181e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 182e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } catch (IOException e) { 183e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateException("Problem reading input stream", e); 184e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 185e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 186e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final boolean markable = inStream.markSupported(); 187e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (markable) { 188e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root inStream.mark(PUSHBACK_SIZE); 189e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 190e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 191e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /* Attempt to see if this is a PKCS#7 bag. */ 192e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE); 193e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root try { 194e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final byte[] buffer = new byte[PKCS7_MARKER.length]; 195e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 196e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final int len = pbis.read(buffer); 197e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (len < 0) { 198e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /* No need to reset here. The stream was empty or EOF. */ 199e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new ParsingException("inStream is empty"); 200e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 201e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root pbis.unread(buffer, 0, len); 202e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 203e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) { 204e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7PemInputStream(pbis)); 205e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 206e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 207e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7DerInputStream(pbis)); 208e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } catch (Exception e) { 209e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (markable) { 210e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root try { 211e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root inStream.reset(); 212e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } catch (IOException ignored) { 213e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 214e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 215e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateException(e); 216e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 217e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 218e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 219e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static CertPath fromEncoding(InputStream inStream, Encoding encoding) 220e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throws CertificateException { 221e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root switch (encoding) { 222f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root case PKI_PATH: 223f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return fromPkiPathEncoding(inStream); 224e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root case PKCS7: 225e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return fromPkcs7Encoding(inStream); 226e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root default: 227e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateEncodingException("Unknown encoding"); 228e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 229e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 230e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 231e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public static CertPath fromEncoding(InputStream inStream, String encoding) 232e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throws CertificateException { 233881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (inStream == null) { 2346faa71701f8f8a985db5e914369c97d511532886Kenny Root throw new CertificateException("inStream == null"); 235881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 236881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root 237e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root Encoding enc = Encoding.findByApiName(encoding); 238e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (enc == null) { 239e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateException("Invalid encoding: " + encoding); 240e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 241e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 242e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return fromEncoding(inStream, enc); 243e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 244e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 245e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public static CertPath fromEncoding(InputStream inStream) throws CertificateException { 246e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return fromEncoding(inStream, DEFAULT_ENCODING); 247e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 248e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root} 249