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 javax.security.cert;
19
20import java.io.ByteArrayInputStream;
21import java.io.InputStream;
22import java.lang.reflect.Constructor;
23import java.math.BigInteger;
24import java.security.InvalidKeyException;
25import java.security.NoSuchAlgorithmException;
26import java.security.NoSuchProviderException;
27import java.security.Principal;
28import java.security.PublicKey;
29import java.security.Security;
30import java.security.SignatureException;
31import java.security.cert.CertificateFactory;
32import java.util.Date;
33
34/**
35 * Abstract base class for X.509 certificates.
36 * <p>
37 * This represents a standard way for accessing the attributes of X.509 v1
38 * certificates.
39 * <p>
40 * Note: This package is provided only for compatibility reasons.
41 * It contains a simplified version of the java.security.cert package that was
42 * previously used by JSSE (Java SSL package). All applications that do not have
43 * to be compatible with older versions of JSSE (that is before Java SDK 1.5)
44 * should only use java.security.cert.
45 */
46public abstract class X509Certificate extends Certificate {
47
48    private static Constructor constructor;
49    static {
50        try {
51            String classname = Security.getProperty("cert.provider.x509v1");
52            Class cl = Class.forName(classname);
53            constructor = cl.getConstructor(new Class[] {InputStream.class});
54        } catch (Exception|LinkageError e) {
55        }
56    }
57
58    /**
59     * Creates a new {@code X509Certificate}.
60     */
61    public X509Certificate() {
62    }
63
64    /**
65     * Creates a new {@code X509Certificate} and initializes it from the
66     * specified input stream.
67     *
68     * @param inStream
69     *            input stream containing data to initialize the certificate.
70     * @return the certificate initialized from the specified input stream
71     * @throws CertificateException
72     *             if the certificate cannot be created or initialized.
73     */
74    public static final X509Certificate getInstance(InputStream inStream)
75                                             throws CertificateException {
76        if (inStream == null) {
77            throw new CertificateException("inStream == null");
78        }
79        if (constructor != null) {
80            try {
81                return (X509Certificate)
82                    constructor.newInstance(new Object[] {inStream});
83            } catch (ReflectiveOperationException e) {
84                throw new CertificateException(e.getMessage());
85            }
86        }
87
88        final java.security.cert.X509Certificate cert;
89        try {
90            CertificateFactory cf = CertificateFactory.getInstance("X.509");
91            cert = (java.security.cert.X509Certificate)
92                                            cf.generateCertificate(inStream);
93        } catch (java.security.cert.CertificateException e) {
94            throw new CertificateException(e.getMessage());
95        }
96
97        return new X509Certificate() {
98
99            public byte[] getEncoded() throws CertificateEncodingException {
100                try {
101                    return cert.getEncoded();
102                } catch (java.security.cert.CertificateEncodingException e) {
103                    throw new CertificateEncodingException(e.getMessage());
104                }
105            }
106
107            public void verify(PublicKey key) throws CertificateException,
108                                NoSuchAlgorithmException, InvalidKeyException,
109                                NoSuchProviderException, SignatureException {
110                try {
111                    cert.verify(key);
112                } catch (java.security.cert.CertificateException e) {
113                    throw new CertificateException(e.getMessage());
114                }
115            }
116
117            public void verify(PublicKey key, String sigProvider)
118                            throws CertificateException,
119                                NoSuchAlgorithmException, InvalidKeyException,
120                                NoSuchProviderException, SignatureException {
121                try {
122                    cert.verify(key, sigProvider);
123                } catch (java.security.cert.CertificateException e) {
124                    throw new CertificateException(e.getMessage());
125                }
126            }
127
128            public String toString() {
129                return cert.toString();
130            }
131
132            public PublicKey getPublicKey() {
133                return cert.getPublicKey();
134            }
135
136            public void checkValidity() throws CertificateExpiredException,
137                                   CertificateNotYetValidException {
138                try {
139                    cert.checkValidity();
140                } catch (java.security.cert.CertificateNotYetValidException e) {
141                    throw new CertificateNotYetValidException(e.getMessage());
142                } catch (java.security.cert.CertificateExpiredException e) {
143                    throw new CertificateExpiredException(e.getMessage());
144                }
145            }
146
147            public void checkValidity(Date date)
148                            throws CertificateExpiredException,
149                                   CertificateNotYetValidException {
150                try {
151                    cert.checkValidity(date);
152                } catch (java.security.cert.CertificateNotYetValidException e) {
153                    throw new CertificateNotYetValidException(e.getMessage());
154                } catch (java.security.cert.CertificateExpiredException e) {
155                    throw new CertificateExpiredException(e.getMessage());
156                }
157            }
158
159            public int getVersion() {
160                return 2;
161            }
162
163            public BigInteger getSerialNumber() {
164                return cert.getSerialNumber();
165            }
166
167            public Principal getIssuerDN() {
168                return cert.getIssuerDN();
169            }
170
171            public Principal getSubjectDN() {
172                return cert.getSubjectDN();
173            }
174
175            public Date getNotBefore() {
176                return cert.getNotBefore();
177            }
178
179            public Date getNotAfter() {
180                return cert.getNotAfter();
181            }
182
183            public String getSigAlgName() {
184                return cert.getSigAlgName();
185            }
186
187            public String getSigAlgOID() {
188                return cert.getSigAlgOID();
189            }
190
191            public byte[] getSigAlgParams() {
192                return cert.getSigAlgParams();
193            }
194        };
195    }
196
197    /**
198     * Creates a new {@code X509Certificate} and initializes it from the
199     * specified byte array.
200     *
201     * @param certData
202     *            byte array containing data to initialize the certificate.
203     * @return the certificate initialized from the specified byte array
204     * @throws CertificateException
205     *             if the certificate cannot be created or initialized.
206     */
207    public static final X509Certificate getInstance(byte[] certData)
208                                             throws CertificateException {
209        if (certData == null) {
210            throw new CertificateException("certData == null");
211        }
212        ByteArrayInputStream bais = new ByteArrayInputStream(certData);
213        return getInstance(bais);
214    }
215
216    /**
217     * Checks whether the certificate is currently valid.
218     * <p>
219     * The validity defined in ASN.1:
220     *
221     * <pre>
222     * validity             Validity
223     *
224     * Validity ::= SEQUENCE {
225     *      notBefore       CertificateValidityDate,
226     *      notAfter        CertificateValidityDate }
227     *
228     * CertificateValidityDate ::= CHOICE {
229     *      utcTime         UTCTime,
230     *      generalTime     GeneralizedTime }
231     * </pre>
232     *
233     * @throws CertificateExpiredException
234     *             if the certificate has expired.
235     * @throws CertificateNotYetValidException
236     *             if the certificate is not yet valid.
237     */
238    public abstract void checkValidity()
239            throws CertificateExpiredException, CertificateNotYetValidException;
240
241
242    /**
243     * Checks whether the certificate is valid at the specified date.
244     *
245     * @param date
246     *            the date to check the validity against.
247     * @throws CertificateExpiredException
248     *             if the certificate has expired.
249     * @throws CertificateNotYetValidException
250     *             if the certificate is not yet valid.
251     * @see #checkValidity()
252     */
253    public abstract void checkValidity(Date date)
254            throws CertificateExpiredException, CertificateNotYetValidException;
255
256    /**
257     * Returns the certificates {@code version} (version number).
258     * <p>
259     * The version defined is ASN.1:
260     *
261     * <pre>
262     * Version ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
263     * </pre>
264     *
265     * @return the version number.
266     */
267    public abstract int getVersion();
268
269    /**
270     * Returns the {@code serialNumber} of the certificate.
271     * <p>
272     * The ASN.1 definition of {@code serialNumber}:
273     *
274     * <pre>
275     * CertificateSerialNumber  ::=  INTEGER
276     * </pre>
277     *
278     * @return the serial number.
279     */
280    public abstract BigInteger getSerialNumber();
281
282    /**
283     * Returns the {@code issuer} (issuer distinguished name) as an
284     * implementation specific {@code Principal} object.
285     * <p>
286     * The ASN.1 definition of {@code issuer}:
287     *
288     * <pre>
289     *  issuer      Name
290     *
291     *  Name ::= CHOICE {
292     *      RDNSequence }
293     *
294     *    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
295     *
296     *    RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
297     *
298     *    AttributeTypeAndValue ::= SEQUENCE {
299     *      type     AttributeType,
300     *      value    AttributeValue }
301     *
302     *    AttributeType ::= OBJECT IDENTIFIER
303     *
304     *    AttributeValue ::= ANY DEFINED BY AttributeType
305     * </pre>
306     *
307     * @return the {@code issuer} as an implementation specific {@code
308     *         Principal}.
309     */
310    public abstract Principal getIssuerDN();
311
312    /**
313     * Returns the {@code subject} (subject distinguished name) as an
314     * implementation specific {@code Principal} object.
315     * <p>
316     * The ASN.1 definition of {@code subject}:
317     *
318     * <pre>
319     * subject      Name
320     *
321     *  Name ::= CHOICE {
322     *      RDNSequence }
323     *
324     *    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
325     *
326     *    RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
327     *
328     *    AttributeTypeAndValue ::= SEQUENCE {
329     *      type     AttributeType,
330     *      value    AttributeValue }
331     *
332     *    AttributeType ::= OBJECT IDENTIFIER
333     *
334     *    AttributeValue ::= ANY DEFINED BY AttributeType
335     * </pre>
336     *
337     * @return the {@code subject} (subject distinguished name).
338     */
339    public abstract Principal getSubjectDN();
340
341    /**
342     * Returns the {@code notBefore} date from the validity period of the
343     * certificate.
344     *
345     * @return the start of the validity period.
346     */
347    public abstract Date getNotBefore();
348
349    /**
350     * Returns the {@code notAfter} date of the validity period of the
351     * certificate.
352     *
353     * @return the end of the validity period.
354     */
355    public abstract Date getNotAfter();
356
357    /**
358     * Returns the name of the algorithm for the certificate signature.
359     *
360     * @return the signature algorithm name.
361     */
362    public abstract String getSigAlgName();
363
364    /**
365     * Returns the OID of the signature algorithm from the certificate.
366     *
367     * @return the OID of the signature algorithm.
368     */
369    public abstract String getSigAlgOID();
370
371    /**
372     * Returns the parameters of the signature algorithm in DER-encoded format.
373     *
374     * @return the parameters of the signature algorithm, or null if none are
375     *         used.
376     */
377    public abstract byte[] getSigAlgParams();
378}
379