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