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.x509;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.math.BigInteger;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Date;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.x500.X500Principal;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Explicit;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Integer;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Sequence;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1SequenceOf;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Type;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.BerInputStream;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x501.Name;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
41f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * The class encapsulates the ASN.1 DER encoding/decoding work
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with TBSCertList structure which is the part of X.509 CRL
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (as specified in RFC 3280 -
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Internet X.509 Public Key Infrastructure.
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Certificate and Certificate Revocation List (CRL) Profile.
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  http://www.ietf.org/rfc/rfc3280.txt):
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre>
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   TBSCertList  ::=  SEQUENCE  {
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        version                 Version OPTIONAL,
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *                                     -- if present, MUST be v2
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        signature               AlgorithmIdentifier,
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        issuer                  Name,
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        thisUpdate              Time,
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        nextUpdate              Time OPTIONAL,
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        revokedCertificates     SEQUENCE OF SEQUENCE  {
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *             userCertificate         CertificateSerialNumber,
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *             revocationDate          Time,
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *             crlEntryExtensions      Extensions OPTIONAL
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *                                           -- if present, MUST be v2
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *                                  }  OPTIONAL,
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *                                           -- if present, MUST be v2
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre>
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
675c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilsonpublic final class TBSCertList {
685c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the value of version field of the structure */
69f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    private final int version;
705c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the value of signature field of the structure */
71f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    private final AlgorithmIdentifier signature;
725c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the value of issuer field of the structure */
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Name issuer;
745c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the value of thisUpdate of the structure */
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Date thisUpdate;
765c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the value of nextUpdate of the structure */
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Date nextUpdate;
785c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the value of revokedCertificates of the structure */
795c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    private final List<RevokedCertificate> revokedCertificates;
805c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the value of crlExtensions field of the structure */
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Extensions crlExtensions;
825c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the ASN.1 encoded form of TBSCertList */
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] encoding;
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static class RevokedCertificate {
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final BigInteger userCertificate;
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final Date revocationDate;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final Extensions crlEntryExtensions;
89f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private boolean issuerRetrieved;
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private X500Principal issuer;
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private byte[] encoding;
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public RevokedCertificate(BigInteger userCertificate,
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Date revocationDate, Extensions crlEntryExtensions) {
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.userCertificate = userCertificate;
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.revocationDate = revocationDate;
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.crlEntryExtensions = crlEntryExtensions;
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Extensions getCrlEntryExtensions() {
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return crlEntryExtensions;
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public BigInteger getUserCertificate() {
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return userCertificate;
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Date getRevocationDate() {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return revocationDate;
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the value of Certificate Issuer Extension, if it is
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * presented.
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public X500Principal getIssuer() {
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (crlEntryExtensions == null) {
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!issuerRetrieved) {
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
123f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    issuer =
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        crlEntryExtensions.valueOfCertificateIssuerExtension();
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (IOException e) {
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    e.printStackTrace();
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                issuerRetrieved = true;
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return issuer;
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
132f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public byte[] getEncoded() {
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (encoding == null) {
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                encoding = ASN1.encode(this);
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return encoding;
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
139f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean equals(Object rc) {
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(rc instanceof RevokedCertificate)) {
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            RevokedCertificate rcert = (RevokedCertificate) rc;
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return userCertificate.equals(rcert.userCertificate)
146f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                && ((revocationDate.getTime() / 1000)
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        == (rcert.revocationDate.getTime() / 1000))
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && ((crlEntryExtensions == null)
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ? rcert.crlEntryExtensions == null
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    : crlEntryExtensions.equals(rcert.crlEntryExtensions));
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
152f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
1532f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        public int hashCode() {
1549efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes            return userCertificate.hashCode() * 37 + (int)revocationDate.getTime() / 1000
1559efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes                    + (crlEntryExtensions == null ? 0 : crlEntryExtensions.hashCode());
1562f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        }
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1588216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        public void dumpValue(StringBuilder sb, String prefix) {
1598216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes            sb.append(prefix).append("Certificate Serial Number: ").append(userCertificate).append('\n');
1608216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes            sb.append(prefix).append("Revocation Date: ").append(revocationDate);
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (crlEntryExtensions != null) {
1628216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes                sb.append('\n').append(prefix).append("CRL Entry Extensions: [");
1638216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes                crlEntryExtensions.dumpValue(sb, prefix + "  ");
1648216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes                sb.append(prefix).append(']');
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
167f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
1682f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        public static final ASN1Sequence ASN1 = new ASN1Sequence(
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                new ASN1Type[] {ASN1Integer.getInstance(), Time.ASN1,
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Extensions.ASN1}) {
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                setOptional(2);
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1755c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            @Override protected Object getDecodedObject(BerInputStream in) {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object[] values = (Object[]) in.content;
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return new RevokedCertificate(
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            new BigInteger((byte[]) values[0]),
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            (Date) values[1],
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            (Extensions) values[2]
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        );
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1845c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            @Override protected void getValues(Object object, Object[] values) {
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                RevokedCertificate rcert = (RevokedCertificate) object;
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                values[0] = rcert.userCertificate.toByteArray();
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                values[1] = rcert.revocationDate;
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                values[2] = rcert.crlEntryExtensions;
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        };
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1935c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** Constructs the object with associated ASN.1 encoding */
194f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    private TBSCertList(int version, AlgorithmIdentifier signature,
195f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            Name issuer, Date thisUpdate, Date nextUpdate,
1965c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            List<RevokedCertificate> revokedCertificates, Extensions crlExtensions,
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte[] encoding) {
198f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        this.version = version;
199f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        this.signature = signature;
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.issuer = issuer;
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.thisUpdate = thisUpdate;
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.nextUpdate = nextUpdate;
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.revokedCertificates = revokedCertificates;
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.crlExtensions = crlExtensions;
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.encoding = encoding;
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of version field of the structure.
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getVersion() {
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return version;
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of signature field of the structure.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public AlgorithmIdentifier getSignature() {
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return signature;
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
221f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of issuer field of the structure.
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Name getIssuer() {
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return issuer;
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
228f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of thisUpdate field of the structure.
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Date getThisUpdate() {
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return thisUpdate;
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
235f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of nextUpdate field of the structure.
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Date getNextUpdate() {
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return nextUpdate;
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
242f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of revokedCertificates field of the structure.
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2465c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    public List<RevokedCertificate> getRevokedCertificates() {
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return revokedCertificates;
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of crlExtensions field of the structure.
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Extensions getCrlExtensions() {
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return crlExtensions;
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns ASN.1 encoded form of this X.509 TBSCertList value.
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncoded() {
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding == null) {
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            encoding = ASN1.encode(this);
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return encoding;
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
266f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
2675c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    @Override public boolean equals(Object other) {
2685c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        if (!(other instanceof TBSCertList)) {
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2715c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        TBSCertList that = (TBSCertList) other;
2725c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        return version == that.version
2735c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            && signature.equals(that.signature)
2745c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            && Arrays.equals(issuer.getEncoded(), that.issuer.getEncoded())
2755c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            && thisUpdate.getTime() / 1000
2765c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                    == that.thisUpdate.getTime() / 1000
2775c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            && (nextUpdate == null
2785c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                    ? that.nextUpdate == null
2795c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                    : nextUpdate.getTime() / 1000
2805c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                        == that.nextUpdate.getTime() / 1000)
2815c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            && ((revokedCertificates == null || that.revokedCertificates == null)
2825c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                && revokedCertificates == that.revokedCertificates
2835c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                || revokedCertificates.equals(that.revokedCertificates))
2845c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            && (crlExtensions == null
2855c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                    ? that.crlExtensions == null
2865c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                    : crlExtensions.equals(that.crlExtensions));
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
288f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
2895c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    @Override public int hashCode() {
2909efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        return ((version * 37 + signature.hashCode()) * 37
291196f44e24830d0e7fd17eba627704a162eba779eElliott Hughes                + Arrays.hashCode(issuer.getEncoded())) * 37
2929efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes                + (int)thisUpdate.getTime() / 1000;
2932f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2958216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes    public void dumpValue(StringBuilder sb) {
2968216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        sb.append("X.509 CRL v").append(version);
2978216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        sb.append("\nSignature Algorithm: [");
2988216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        signature.dumpValue(sb);
2998216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        sb.append(']');
3008216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        sb.append("\nIssuer: ").append(issuer.getName(X500Principal.RFC2253));
3018216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        sb.append("\n\nThis Update: ").append(thisUpdate);
3028216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes        sb.append("\nNext Update: ").append(nextUpdate).append('\n');
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (revokedCertificates != null) {
3048216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes            sb.append("\nRevoked Certificates: ").append(revokedCertificates.size()).append(" [");
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int number = 1;
3065c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            for (RevokedCertificate revokedCertificate : revokedCertificates) {
3078216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes                sb.append("\n  [").append(number++).append(']');
3088216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes                revokedCertificate.dumpValue(sb, "  ");
3098216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes                sb.append('\n');
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
3118216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes            sb.append("]\n");
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (crlExtensions != null) {
3148216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes            sb.append("\nCRL Extensions: ").append(crlExtensions.size()).append(" [");
3158216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes            crlExtensions.dumpValue(sb, "  ");
3168216dc1fd9d31867770439985c3d66570330e4c7Elliott Hughes            sb.append("]\n");
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * X.509 TBSCertList encoder/decoder.
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ASN1Integer.getInstance(), // version
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            AlgorithmIdentifier.ASN1,  // signature
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Name.ASN1, // issuer
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Time.ASN1, // thisUpdate
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Time.ASN1, // nextUpdate
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new ASN1SequenceOf(RevokedCertificate.ASN1), // revokedCertificates
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new ASN1Explicit(0, Extensions.ASN1) // crlExtensions
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }) {
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        {
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setOptional(0);
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setOptional(4);
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setOptional(5);
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setOptional(6);
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3395c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        @Override protected Object getDecodedObject(BerInputStream in) throws IOException {
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object[] values = (Object[]) in.content;
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new TBSCertList(
342f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        (values[0] == null)
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            ? 1
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            : ASN1Integer.toIntValue(values[0])+1,
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        (AlgorithmIdentifier) values[1],
346f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        (Name) values[2],
347f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        (Date) values[3],
348f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        (Date) values[4],
3495c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson                        (List<RevokedCertificate>) values[5],
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        (Extensions) values[6],
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        in.getEncoded()
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    );
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3555c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        @Override protected void getValues(Object object, Object[] values) {
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            TBSCertList tbs = (TBSCertList) object;
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[0] = (tbs.version > 1)
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? ASN1Integer.fromIntValue(tbs.version - 1) : null;
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[1] = tbs.signature;
360f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            values[2] = tbs.issuer;
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[3] = tbs.thisUpdate;
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[4] = tbs.nextUpdate;
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[5] = tbs.revokedCertificates;
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[6] = tbs.crlExtensions;
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    };
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
368