1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.security.cert;
19
20import java.io.ByteArrayInputStream;
21import java.math.BigInteger;
22import java.security.InvalidKeyException;
23import java.security.NoSuchAlgorithmException;
24import java.security.NoSuchProviderException;
25import java.security.Principal;
26import java.security.PublicKey;
27import java.security.SignatureException;
28import java.security.cert.CRL;
29import java.security.cert.CRLException;
30import java.security.cert.X509CRLEntry;
31import java.security.cert.X509Extension;
32import java.util.Arrays;
33import java.util.Date;
34import java.util.Set;
35import javax.security.auth.x500.X500Principal;
36
37import org.apache.harmony.security.internal.nls.Messages;
38
39/**
40 * Abstract base class for X.509 certificate revocation lists (CRL).
41 * <p>
42 * More information regarding CRL can be found in RFC 2459,
43 * "Internet X.509 Public Key Infrastructure Certificate and CRL Profile" at <a
44 * href
45 * ="http://www.ietf.org/rfc/rfc2459.txt">http://www.ietf.org/rfc/rfc2459.txt
46 * </a>.
47 */
48public abstract class X509CRL extends CRL implements X509Extension {
49
50    /**
51     * Creates a new {@code X509CRL} instance.
52     */
53    protected X509CRL() {
54        super("X.509"); //$NON-NLS-1$
55    }
56
57    /**
58     * Returns whether the specified object equals to this instance.
59     *
60     * @param other
61     *            the object to compare.
62     * @return {@code true} if the specified object is equal to this, otherwise
63     *         {@code false}.
64     */
65    public boolean equals(Object other) {
66        if (other == this) {
67            return true;
68        }
69        if (!(other instanceof X509CRL)) {
70            return false;
71        }
72        X509CRL obj = (X509CRL) other;
73        try {
74            return Arrays.equals(getEncoded(), obj.getEncoded());
75        } catch (CRLException e) {
76            return false;
77        }
78    }
79
80    /**
81     * Returns the hashcode of this CRL instance.
82     *
83     * @return the hashcode.
84     */
85    public int hashCode() {
86        try {
87            int res = 0;
88            byte[] array = getEncoded();
89            for (int i=0; i<array.length; i++) {
90                res += array[i] & 0xFF;
91            }
92            return res;
93        } catch (CRLException e) {
94            return 0;
95        }
96    }
97
98    /**
99     * Returns this CRL in ASN.1 DER encoded form.
100     *
101     * @return this CRL in ASN.1 DER encoded form.
102     * @throws CRLException
103     *             if encoding fails.
104     */
105    public abstract byte[] getEncoded() throws CRLException;
106
107
108    /**
109     * Verifies this CRL by verifying that this CRL was signed with the
110     * corresponding private key to the specified public key.
111     *
112     * @param key
113     *            the public key to verify this CRL with.
114     * @throws CRLException
115     *             if encoding or decoding fails.
116     * @throws NoSuchAlgorithmException
117     *             if a needed algorithm is not present.
118     * @throws InvalidKeyException
119     *             if the specified key is invalid.
120     * @throws NoSuchProviderException
121     *             if no provider can be found.
122     * @throws SignatureException
123     *             if errors occur on signatures.
124     */
125    public abstract void verify(PublicKey key)
126                     throws CRLException, NoSuchAlgorithmException,
127                            InvalidKeyException, NoSuchProviderException,
128                            SignatureException;
129
130    /**
131     * Verifies this CRL by verifying that this CRL was signed with the
132     * corresponding private key to the specified public key. The signature
133     * verification engine of the specified provider will be used.
134     *
135     * @param key
136     *            the public key to verify this CRL with.
137     * @param sigProvider
138     *            the name of the provider for the signature algorithm.
139     * @throws CRLException
140     *             if encoding decoding fails.
141     * @throws NoSuchAlgorithmException
142     *             if a needed algorithm is not present.
143     * @throws InvalidKeyException
144     *             if the specified key is invalid.
145     * @throws NoSuchProviderException
146     *             if the specified provider cannot be found.
147     * @throws SignatureException
148     *             if errors occur on signatures.
149     */
150    public abstract void verify(PublicKey key, String sigProvider)
151                     throws CRLException, NoSuchAlgorithmException,
152                            InvalidKeyException, NoSuchProviderException,
153                            SignatureException;
154
155    /**
156     * Returns the version number of this CRL.
157     *
158     * @return the version number of this CRL.
159     */
160    public abstract int getVersion();
161
162    /**
163     * <b>Do not use</b>, use {@link #getIssuerX500Principal()} instead. Returns
164     * the issuer as an implementation specific Principal object.
165     *
166     * @return the issuer distinguished name.
167     */
168    public abstract Principal getIssuerDN();
169
170    /**
171     * Returns the issuer distinguished name of this CRL.
172     *
173     * @return the issuer distinguished name of this CRL.
174     */
175    public X500Principal getIssuerX500Principal() {
176        try {
177            // TODO if there is no X.509 certificate provider installed
178            // should we try to access Harmony X509CRLImpl via classForName?
179            CertificateFactory factory = CertificateFactory
180                    .getInstance("X.509"); //$NON-NLS-1$
181
182            X509CRL crl = (X509CRL) factory
183                    .generateCRL(new ByteArrayInputStream(getEncoded()));
184
185            return crl.getIssuerX500Principal();
186
187        } catch (Exception e) {
188            throw new RuntimeException(Messages.getString("security.59"), e); //$NON-NLS-1$
189        }
190    }
191
192    /**
193     * Returns the {@code thisUpdate} value of this CRL.
194     *
195     * @return the {@code thisUpdate} value of this CRL.
196     */
197    public abstract Date getThisUpdate();
198
199    /**
200     * Returns the {@code nextUpdate} value of this CRL.
201     *
202     * @return the {@code nextUpdate} value of this CRL, or {@code null} if none
203     *         is present.
204     */
205    public abstract Date getNextUpdate();
206
207    /**
208     * Returns the CRL entry with the specified certificate serial number.
209     *
210     * @param serialNumber
211     *            the certificate serial number to search for a CRL entry.
212     * @return the entry for the specified certificate serial number, or {@code
213     *         null} if not found.
214     */
215    public abstract X509CRLEntry getRevokedCertificate(BigInteger serialNumber);
216
217    /**
218     * Returns the CRL entry for the specified certificate.
219     *
220     * @param certificate
221     *            the certificate to search a CRL entry for.
222     * @return the entry for the specified certificate, or {@code null} if not
223     *         found.
224     */
225    public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
226        if (certificate == null) {
227            throw new NullPointerException();
228        }
229        return getRevokedCertificate(certificate.getSerialNumber());
230    }
231
232    /**
233     * Returns the set of revoked certificates.
234     *
235     * @return the set of revoked certificates, or {@code null} if no revoked
236     *         certificates are in this CRL.
237     */
238    public abstract Set<? extends X509CRLEntry> getRevokedCertificates();
239
240    /**
241     * Returns the {@code tbsCertList} information of this CRL in DER encoded
242     * form.
243     *
244     * @return the CRL information in DER encoded form.
245     * @throws CRLException
246     *             if encoding fails.
247     */
248    public abstract byte[] getTBSCertList() throws CRLException;
249
250    /**
251     * Returns the signature bytes of this CRL.
252     *
253     * @return the signature bytes of this CRL.
254     */
255    public abstract byte[] getSignature();
256
257    /**
258     * Returns the name of the signature algorithm.
259     *
260     * @return the name of the signature algorithm.
261     */
262    public abstract String getSigAlgName();
263
264    /**
265     * Returns the OID of the signature algorithm.
266     *
267     * @return the OID of the signature algorithm.
268     */
269    public abstract String getSigAlgOID();
270
271    /**
272     * Returns the parameters of the signature algorithm in DER encoded form.
273     *
274     * @return the parameters of the signature algorithm in DER encoded form, or
275     *         {@code null} if not present.
276     */
277    public abstract byte[] getSigAlgParams();
278}
279
280