1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @author Alexander Y. Kleymenov
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @version $Revision$
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.security.provider.cert;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertPath;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateEncodingException;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateException;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collection;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collections;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
378c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Any;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Explicit;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Implicit;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Oid;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Sequence;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1SequenceOf;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Type;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.BerInputStream;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.pkcs7.ContentInfo;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.pkcs7.SignedData;
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.Certificate;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is an implementation of X.509 CertPath. This implementation
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provides ability to create the instance of X.509 Certification Path
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by several means:<br>
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * &nbsp;  1. It can be created over the list of X.509 certificates
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (implementations of X509Certificate class) provided in constructor.<br>
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * &nbsp;  2. It can be created by means of <code>getInstance</code> methods
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on the base of the following ASN.1 DER encoded forms:<br>
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * &nbsp;&nbsp;  - PkiPath as defined in
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ITU-T Recommendation X.509(2000) Corrigendum 1(2001)
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (can be seen at
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ftp://ftp.bull.com/pub/OSIdirectory/DefectResolution/TechnicalCorrigenda/ApprovedTechnicalCorrigendaToX.509/8%7CX.509-TC1(4th).pdf)
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <br>
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * &nbsp;&nbsp;  - PKCS #7 SignedData object provided in the form of
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ContentInfo structure. CertPath object is generated on the base of
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificates presented in <code>certificates</code> field of the SignedData
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object which in its turn is retrieved from ContentInfo structure.
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (see http://www.ietf.org/rfc/rfc2315.txt
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for more info on PKCS #7)
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <br>
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * &nbsp;
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class X509CertPathImpl extends CertPath {
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @serial
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 7989755106209515436L;
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
818c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /**
828c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Supported encoding types for CerthPath. Used by the various APIs that
838c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * encode this into bytes such as {@link #getEncoded()}.
848c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     */
858c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    private enum Encoding {
868c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        PKI_PATH("PkiPath"),
878c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        PKCS7("PKCS7");
888c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
898c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        private final String apiName;
908c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
918c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        Encoding(String apiName) {
928c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            this.apiName = apiName;
938c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        }
948c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
958c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        static Encoding findByApiName(String apiName) throws CertificateEncodingException {
968c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            for (Encoding element : values()) {
978c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                if (element.apiName.equals(apiName)) {
988c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    return element;
998c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                }
1008c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            }
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1028c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            return null;
1038c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        }
1048c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    }
1058c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1068c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /** Unmodifiable list of encodings for the API. */
1078c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    static final List<String> encodings = Collections.unmodifiableList(Arrays.asList(new String[] {
1088c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            Encoding.PKI_PATH.apiName,
1098c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            Encoding.PKCS7.apiName,
1108c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    }));
1118c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1128c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /** The list of certificates in the order of target toward trust anchor. */
1138c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    private final List<X509Certificate> certificates;
1148c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1158c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /** PkiPath encoding of the certification path. */
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] pkiPathEncoding;
1178c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1188c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /** PKCS7 encoding of the certification path. */
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] pkcs7Encoding;
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1228c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Creates an instance of X.509 CertPath over the specified list of
1238c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * certificates.
1248c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *
1258c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * @throws CertificateException if some of the object in the list is not an
1268c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *             instance of subclass of X509Certificate.
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1288c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    public X509CertPathImpl(List<? extends java.security.cert.Certificate> certs)
1298c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throws CertificateException {
130f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        super("X.509");
1318c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1328c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        final int size = certs.size();
1338c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        certificates = new ArrayList<X509Certificate>(size);
1348c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1358c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        for (int i = 0; i < size; i++) {
1368c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final java.security.cert.Certificate cert = certs.get(i);
1378c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            if (!(cert instanceof X509Certificate)) {
1388c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                throw new CertificateException("Certificate " + i + " is not an X.509 certificate");
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1408c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1418c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            certificates.add((X509Certificate) cert);
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1458c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /**
1468c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Creates an X.509 CertPath over the specified {@code certs}. The
1478c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * {@code certs} should be sorted correctly when calling into the
1488c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * constructor. Additionally, the {@code encodedPath} should match the
1498c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * expected output for the {@code type} of encoding.
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1518c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    private X509CertPathImpl(List<X509Certificate> certs, Encoding type) {
152f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        super("X.509");
1538c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        certificates = certs;
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1588c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Extract a CertPath from a PKCS#7 {@code contentInfo} object.
1598c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     */
1608c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    private static X509CertPathImpl getCertPathFromContentInfo(ContentInfo contentInfo)
1618c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throws CertificateException {
1628c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        final SignedData sd = contentInfo.getSignedData();
1638c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        if (sd == null) {
1648c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throw new CertificateException("Incorrect PKCS7 encoded form: missing signed data");
1658c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        }
1668c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1678c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        List<Certificate> certs = sd.getCertificates();
1688c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        if (certs == null) {
1698c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            certs = Collections.emptyList();
1708c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        }
1718c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1728c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        final List<X509Certificate> result = new ArrayList<X509Certificate>(certs.size());
1738c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        for (Certificate cert : certs) {
1748c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            result.add(new X509CertImpl(cert));
1758c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        }
1768c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1778c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        return new X509CertPathImpl(result, Encoding.PKCS7);
1788c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    }
1798c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
1808c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /**
1818c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Generates certification path object on the base of PkiPath encoded form
1828c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * provided via input stream.
1838c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *
1848c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * @throws CertificateException if some problems occurred during the
1858c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *         decoding.
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1879ff0e556917fd66ea30224ac89f6dea7958eda1fBrian Carlstrom    public static X509CertPathImpl getInstance(InputStream in) throws CertificateException {
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (X509CertPathImpl) ASN1.decode(in);
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
1918c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throw new CertificateException("Failed to decode CertPath", e);
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1968c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Generates certification path object on the basis of encoding provided via
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * input stream. The format of provided encoded form is specified by
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * parameter <code>encoding</code>.
1998c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException if specified encoding form is not supported,
2018c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *         or some problems occurred during the decoding.
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static X509CertPathImpl getInstance(InputStream in, String encoding)
2049ff0e556917fd66ea30224ac89f6dea7958eda1fBrian Carlstrom            throws CertificateException {
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
2068c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final Encoding encType = Encoding.findByApiName(encoding);
2078c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            if (encType == null) {
2088c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                throw new CertificateException("Unsupported encoding: " + encoding);
2098c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            }
2108c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
2118c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            switch (encType) {
2128c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                case PKI_PATH:
2138c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    return (X509CertPathImpl) ASN1.decode(in);
2148c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                case PKCS7:
2158c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    return getCertPathFromContentInfo((ContentInfo) ContentInfo.ASN1.decode(in));
2168c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                default:
2178c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    throw new CertificateException("Unsupported encoding: " + encoding);
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
2208c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throw new CertificateException("Failed to decode CertPath", e);
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Generates certification path object on the base of PkiPath
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * encoded form provided via array of bytes.
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException if some problems occurred during
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the decoding.
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2309ff0e556917fd66ea30224ac89f6dea7958eda1fBrian Carlstrom    public static X509CertPathImpl getInstance(byte[] in) throws CertificateException {
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (X509CertPathImpl) ASN1.decode(in);
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
2348c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throw new CertificateException("Failed to decode CertPath", e);
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Generates certification path object on the base of encoding provided via
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array of bytes. The format of provided encoded form is specified by
2418c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * parameter {@code encoding}.
2428c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException if specified encoding form is not supported,
2448c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *             or some problems occurred during the decoding.
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static X509CertPathImpl getInstance(byte[] in, String encoding)
2479ff0e556917fd66ea30224ac89f6dea7958eda1fBrian Carlstrom            throws CertificateException {
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
2498c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final Encoding encType = Encoding.findByApiName(encoding);
2508c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            if (encType == null) {
2518c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                throw new CertificateException("Unsupported encoding: " + encoding);
2528c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            }
2538c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
2548c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            switch (encType) {
2558c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                case PKI_PATH:
2568c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    return (X509CertPathImpl) ASN1.decode(in);
2578c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                case PKCS7:
2588c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    return getCertPathFromContentInfo((ContentInfo) ContentInfo.ASN1.decode(in));
2598c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                default:
2608c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    throw new CertificateException("Unsupported encoding: " + encoding);
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
2638c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throw new CertificateException("Failed to decode CertPath", e);
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // ---------------------------------------------------------------------
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // ---- java.security.cert.CertPath abstract method implementations ----
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // ---------------------------------------------------------------------
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.security.cert.CertPath#getCertificates()
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method documentation for more info
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2758c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    @Override
2768c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    public List<X509Certificate> getCertificates() {
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Collections.unmodifiableList(certificates);
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2818c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Returns in PkiPath format which is our default encoding.
2828c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     *
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.security.cert.CertPath#getEncoded()
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2858c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    @Override
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncoded() throws CertificateEncodingException {
2878c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        return getEncoded(Encoding.PKI_PATH);
2888c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    }
2898c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
2908c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /**
2918c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * @see #getEncoded(String)
2928c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     */
2938c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    private byte[] getEncoded(Encoding encoding) throws CertificateEncodingException {
2948c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        switch (encoding) {
2958c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            case PKI_PATH:
2968c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                if (pkiPathEncoding == null) {
2978c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    pkiPathEncoding = ASN1.encode(this);
2988c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                }
2998c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
3008c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                return pkiPathEncoding.clone();
3018c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            case PKCS7:
3028c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                if (pkcs7Encoding == null) {
3038c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    pkcs7Encoding = PKCS7_SIGNED_DATA_OBJECT.encode(this);
3048c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                }
3058c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
3068c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                return pkcs7Encoding.clone();
3078c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            default:
3088c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                throw new CertificateEncodingException("Unsupported encoding: " + encoding);
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.security.cert.CertPath#getEncoded(String)
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3158c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    @Override
316897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes    public byte[] getEncoded(String encoding) throws CertificateEncodingException {
3178c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        final Encoding encType = Encoding.findByApiName(encoding);
3188c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        if (encType == null) {
3198c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            throw new CertificateEncodingException("Unsupported encoding: " + encoding);
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
3218c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
3228c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        return getEncoded(encType);
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.security.cert.CertPath#getEncodings()
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method documentation for more info
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3298c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    @Override
3308c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    public Iterator<String> getEncodings() {
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return encodings.iterator();
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ASN.1 DER Encoder/Decoder for PkiPath structure.
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3378c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    public static final ASN1SequenceOf ASN1 = new ASN1SequenceOf(ASN1Any.getInstance()) {
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
3398c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root         * Builds the instance of X509CertPathImpl on the base of the list of
3408c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root         * ASN.1 encodings of X.509 certificates provided via PkiPath structure.
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * This method participates in decoding process.
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object getDecodedObject(BerInputStream in) throws IOException {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // retrieve the decoded content
3458c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final List<byte[]> encodedCerts = (List<byte[]>) in.content;
3468c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
3478c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final int size = encodedCerts.size();
3488c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final List<X509Certificate> certificates = new ArrayList<X509Certificate>(size);
3498c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
3508c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            for (int i = size - 1; i >= 0; i--) {
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // create the X.509 certificate on the base of its encoded form
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // and add it to the list.
3538c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                certificates.add(new X509CertImpl((Certificate) Certificate.ASN1
3548c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                        .decode(encodedCerts.get(i))));
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
3568c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // create and return the resulting object
3588c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            return new X509CertPathImpl(certificates, Encoding.PKI_PATH);
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the Collection of the encoded form of certificates contained
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * in the X509CertPathImpl object to be encoded.
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * This method participates in encoding process.
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
3668c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root        public Collection<byte[]> getValues(Object object) {
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // object to be encoded
3688c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final X509CertPathImpl cp = (X509CertPathImpl) object;
3698c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if it has no certificates in it - create the sequence of size 0
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (cp.certificates == null) {
3728c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                return Collections.emptyList();
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
3748c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
3758c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final int size = cp.certificates.size();
3768c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root            final List<byte[]> encodings = new ArrayList<byte[]>(size);
3778c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
3798c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                for (int i = size - 1; i >= 0; i--) {
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // get the encoded form of certificate and place it into the
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // list to be encoded in PkiPath format
3828c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                    encodings.add(cp.certificates.get(i).getEncoded());
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (CertificateEncodingException e) {
3858c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root                throw new IllegalArgumentException("Encoding error occurred", e);
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
3878c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return encodings;
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    };
391f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3938c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root    /**
3948c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * Encoder for PKCS#7 SignedData. It is assumed that only certificate field
3958c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     * is important all other fields contain pre-calculated encodings.
3968c6714a408efa908d45c71c8106fb1034a54c3fbKenny Root     */
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final ASN1Sequence ASN1_SIGNED_DATA = new ASN1Sequence(
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new ASN1Type[] {
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // version ,digestAlgorithms, content info
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ASN1Any.getInstance(),
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // certificates
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    new ASN1Implicit(0, ASN1),
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // set of crls is optional and is missed here
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ASN1Any.getInstance(),// signers info
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }) {
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // precalculated ASN.1 encodings for
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // version ,digestAlgorithms, content info field of SignedData
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final byte[] PRECALCULATED_HEAD = new byte[] { 0x02, 0x01,
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                0x01,// version (v1)
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                0x31, 0x00,// empty set of DigestAlgorithms
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                0x30, 0x03, 0x06, 0x01, 0x00 // empty ContentInfo with oid=0
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        };
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // precalculated empty set of SignerInfos
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final byte[] SIGNERS_INFO = new byte[] { 0x31, 0x00 };
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void getValues(Object object, Object[] values) {
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[0] = PRECALCULATED_HEAD;
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[1] = object; // pass X509CertPathImpl object
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[2] = SIGNERS_INFO;
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // stub to prevent using the instance as decoder
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object decode(BerInputStream in) throws IOException {
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    "Invalid use of encoder for PKCS#7 SignedData object");
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    };
430f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final ASN1Sequence PKCS7_SIGNED_DATA_OBJECT = new ASN1Sequence(
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new ASN1Type[] { ASN1Any.getInstance(), // contentType
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    new ASN1Explicit(0, ASN1_SIGNED_DATA) // SignedData
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }) {
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // precalculated ASN.1 encoding for SignedData object oid
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final byte[] SIGNED_DATA_OID = ASN1Oid.getInstance().encode(
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ContentInfo.SIGNED_DATA);
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void getValues(Object object, Object[] values) {
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[0] = SIGNED_DATA_OID;
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[1] = object; // pass X509CertPathImpl object
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // stub to prevent using the instance as decoder
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object decode(BerInputStream in) throws IOException {
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    "Invalid use of encoder for PKCS#7 SignedData object");
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    };
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
452