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; 26cb85d4e6605b8f26808acb6d0a3febea69bc466cAdam Vartanianimport java.security.cert.CertificateParsingException; 27e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.X509Certificate; 28f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Rootimport java.util.ArrayList; 29e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.Arrays; 30e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.Collections; 31e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.Iterator; 32e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.List; 33860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport org.conscrypt.OpenSSLX509CertificateFactory.ParsingException; 34e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 355070bdfc6277af136b7eb5fe5d0d72ad2ff6a2ebKenny Root/** 365070bdfc6277af136b7eb5fe5d0d72ad2ff6a2ebKenny Root * An implementation of {@link CertPath} based on BoringSSL. 375070bdfc6277af136b7eb5fe5d0d72ad2ff6a2ebKenny Root */ 3829916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittlerfinal class OpenSSLX509CertPath extends CertPath { 3976a5df40ae1ebb6c6d67917a222ff960d733c286Kenny Root private static final long serialVersionUID = -3249106005255170761L; 4076a5df40ae1ebb6c6d67917a222ff960d733c286Kenny Root 413e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root private static final byte[] PKCS7_MARKER = new byte[] { 423e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root '-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' ', 'P', 'K', 'C', 'S', '7' 433e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root }; 44e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 45e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static final int PUSHBACK_SIZE = 64; 46e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 47e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /** 48e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * Supported encoding types for CerthPath. Used by the various APIs that 49e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root * encode this into bytes such as {@link #getEncoded()}. 50e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root */ 51e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private enum Encoding { 52f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root PKI_PATH("PkiPath"), 53e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root PKCS7("PKCS7"); 54e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 55e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private final String apiName; 56e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 57e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root Encoding(String apiName) { 58e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root this.apiName = apiName; 59e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 60e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 61e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root static Encoding findByApiName(String apiName) throws CertificateEncodingException { 62e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root for (Encoding element : values()) { 63e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (element.apiName.equals(apiName)) { 64e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return element; 65e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 66e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 67e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 68e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return null; 69e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 70e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 71e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 72e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /** Unmodifiable list of encodings for the API. */ 73e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static final List<String> ALL_ENCODINGS = Collections.unmodifiableList(Arrays 74e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root .asList(new String[] { 75f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root Encoding.PKI_PATH.apiName, 76f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root Encoding.PKCS7.apiName, 77e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root })); 78e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 79f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root private static final Encoding DEFAULT_ENCODING = Encoding.PKI_PATH; 80e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 81e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private final List<? extends X509Certificate> mCertificates; 82e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 83e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root static Iterator<String> getEncodingsIterator() { 84e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return ALL_ENCODINGS.iterator(); 85e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 86e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 8729916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittler OpenSSLX509CertPath(List<? extends X509Certificate> certificates) { 88e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root super("X.509"); 89e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 90e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root mCertificates = certificates; 91e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 92e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 93e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 94e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public List<? extends Certificate> getCertificates() { 95e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return Collections.unmodifiableList(mCertificates); 96e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 97e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 98e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private byte[] getEncoded(Encoding encoding) throws CertificateEncodingException { 99e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final OpenSSLX509Certificate[] certs = new OpenSSLX509Certificate[mCertificates.size()]; 100e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final long[] certRefs = new long[certs.length]; 101e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 102f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root for (int i = 0, j = certs.length - 1; j >= 0; i++, j--) { 103f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root final X509Certificate cert = mCertificates.get(i); 104f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 105f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root if (cert instanceof OpenSSLX509Certificate) { 106f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certs[j] = (OpenSSLX509Certificate) cert; 107e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } else { 108f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certs[j] = OpenSSLX509Certificate.fromX509Der(cert.getEncoded()); 109e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 110f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 111f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certRefs[j] = certs[j].getContext(); 112e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 113e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 114f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root switch (encoding) { 115f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root case PKI_PATH: 116f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return NativeCrypto.ASN1_seq_pack_X509(certRefs); 117f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root case PKCS7: 118f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return NativeCrypto.i2d_PKCS7(certRefs); 119f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root default: 120f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root throw new CertificateEncodingException("Unknown encoding"); 121f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 122e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 123e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 124e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 125e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public byte[] getEncoded() throws CertificateEncodingException { 126e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return getEncoded(DEFAULT_ENCODING); 127e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 128e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 129e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 130e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public byte[] getEncoded(String encoding) throws CertificateEncodingException { 131e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root Encoding enc = Encoding.findByApiName(encoding); 132e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (enc == null) { 133e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateEncodingException("Invalid encoding: " + encoding); 134e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 135e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 136f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return getEncoded(enc); 137e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 138e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 139e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 140e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public Iterator<String> getEncodings() { 141e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return getEncodingsIterator(); 142e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 143e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 144f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root private static CertPath fromPkiPathEncoding(InputStream inStream) throws CertificateException { 14566537ee0121bdd14737191d14927da223f0809eeAdam Langley OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(inStream, true); 146f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 147881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root final boolean markable = inStream.markSupported(); 148881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (markable) { 149881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root inStream.mark(PUSHBACK_SIZE); 150881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 151881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root 152f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root final long[] certRefs; 153f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root try { 154f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root certRefs = NativeCrypto.ASN1_seq_unpack_X509_bio(bis.getBioContext()); 155f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } catch (Exception e) { 156881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (markable) { 157881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root try { 158881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root inStream.reset(); 159881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } catch (IOException ignored) { 160881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 161881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 162f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root throw new CertificateException(e); 163f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } finally { 16419fdf1af6bada9ebf4820839780d8713ac3824faKenny Root bis.release(); 165f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 166f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 167f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root if (certRefs == null) { 168f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList()); 169f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 170f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 171f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root final List<OpenSSLX509Certificate> certs = 172f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root new ArrayList<OpenSSLX509Certificate>(certRefs.length); 173f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root for (int i = certRefs.length - 1; i >= 0; i--) { 174f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root if (certRefs[i] == 0) { 175f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root continue; 176f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 177cb85d4e6605b8f26808acb6d0a3febea69bc466cAdam Vartanian try { 178cb85d4e6605b8f26808acb6d0a3febea69bc466cAdam Vartanian certs.add(new OpenSSLX509Certificate(certRefs[i])); 179cb85d4e6605b8f26808acb6d0a3febea69bc466cAdam Vartanian } catch (ParsingException e) { 180cb85d4e6605b8f26808acb6d0a3febea69bc466cAdam Vartanian throw new CertificateParsingException(e); 181cb85d4e6605b8f26808acb6d0a3febea69bc466cAdam Vartanian } 182f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 183f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 184f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return new OpenSSLX509CertPath(certs); 185f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root } 186f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root 187e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static CertPath fromPkcs7Encoding(InputStream inStream) throws CertificateException { 188e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root try { 189e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (inStream == null || inStream.available() == 0) { 190e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList()); 191e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 192e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } catch (IOException e) { 193e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateException("Problem reading input stream", e); 194e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 195e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 196e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final boolean markable = inStream.markSupported(); 197e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (markable) { 198e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root inStream.mark(PUSHBACK_SIZE); 199e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 200e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 201e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /* Attempt to see if this is a PKCS#7 bag. */ 202e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE); 203e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root try { 204e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final byte[] buffer = new byte[PKCS7_MARKER.length]; 205e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 206e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final int len = pbis.read(buffer); 207e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (len < 0) { 208e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root /* No need to reset here. The stream was empty or EOF. */ 209e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new ParsingException("inStream is empty"); 210e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 211e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root pbis.unread(buffer, 0, len); 212e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 213e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) { 214e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7PemInputStream(pbis)); 215e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 216e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 217e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7DerInputStream(pbis)); 218e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } catch (Exception e) { 219e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (markable) { 220e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root try { 221e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root inStream.reset(); 222e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } catch (IOException ignored) { 223e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 224e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 225e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateException(e); 226e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 227e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 228e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 229e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root private static CertPath fromEncoding(InputStream inStream, Encoding encoding) 230e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throws CertificateException { 231e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root switch (encoding) { 232f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root case PKI_PATH: 233f0bb425ede548a3771bb69273eb85ad7fdde1befKenny Root return fromPkiPathEncoding(inStream); 234e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root case PKCS7: 235e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return fromPkcs7Encoding(inStream); 236e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root default: 237e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateEncodingException("Unknown encoding"); 238e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 239e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 240e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 24129916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittler static CertPath fromEncoding(InputStream inStream, String encoding) 242e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throws CertificateException { 243881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (inStream == null) { 2446faa71701f8f8a985db5e914369c97d511532886Kenny Root throw new CertificateException("inStream == null"); 245881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 246881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root 247e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root Encoding enc = Encoding.findByApiName(encoding); 248e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (enc == null) { 249e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateException("Invalid encoding: " + encoding); 250e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 251e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 252e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return fromEncoding(inStream, enc); 253e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 254e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 25529916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittler static CertPath fromEncoding(InputStream inStream) throws CertificateException { 256e8eb8aedabdce4de1a870de9160a8d2ab367c4bbSergio Giro if (inStream == null) { 257e8eb8aedabdce4de1a870de9160a8d2ab367c4bbSergio Giro throw new CertificateException("inStream == null"); 258e8eb8aedabdce4de1a870de9160a8d2ab367c4bbSergio Giro } 259e8eb8aedabdce4de1a870de9160a8d2ab367c4bbSergio Giro 260e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return fromEncoding(inStream, DEFAULT_ENCODING); 261e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 262e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root} 263