X509CertImpl.java revision 487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37
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.math.BigInteger;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.InvalidKeyException;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchAlgorithmException;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchProviderException;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Principal;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PublicKey;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Signature;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.SignatureException;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateEncodingException;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateException;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateExpiredException;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateNotYetValidException;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateParsingException;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate;
4112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstromimport java.security.interfaces.RSAPublicKey;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collection;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Date;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.x500.X500Principal;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.utils.AlgNameMapper;
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.Certificate;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.Extension;
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.Extensions;
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.TBSCertificate;
52487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstromimport org.apache.harmony.xnet.provider.jsse.OpenSSLSignature;
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is an implementation of X509Certificate. It wraps
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the instance of org.apache.harmony.security.x509.Certificate
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * built on the base of provided ASN.1 DER encoded form of
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Certificate structure (as specified in RFC 3280
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.ietf.org/rfc/rfc3280.txt).
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see org.apache.harmony.security.x509.Certificate
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
635c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilsonpublic final class X509CertImpl extends X509Certificate {
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
655c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** @serial */
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 2972248729446736154L;
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
685c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the core object to be wrapped in X509Certificate */
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Certificate certificate;
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // to speed up access to the info, the following fields
72ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    // cache values retrieved from the certificate object,
73ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    // initialized using the "single-check idiom".
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final TBSCertificate tbsCert;
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Extensions extensions;
76ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile long notBefore = -1;
77ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile long notAfter = -1;
78ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile BigInteger serialNumber;
79ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile X500Principal issuer;
80ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile X500Principal subject;
81ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile byte[] tbsCertificate;
82ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile byte[] signature;
83ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile String sigAlgName;
84ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile String sigAlgOID;
85ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile byte[] sigAlgParams;
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // indicates whether the signature algorithm parameters are null
87ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile boolean nullSigAlgParams;
88ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private volatile PublicKey publicKey;
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // encoding of the certificate
915bd2429e5d62e7885c717bda72e789f2649837beBob Lee    private volatile byte[] encoding;
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs the instance on the base of ASN.1 encoded
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * form of X.509 certificate provided via stream parameter.
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param in input stream containing ASN.1 encoded form of certificate.
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException if some decoding problems occur.
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X509CertImpl(InputStream in) throws CertificateException {
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // decode the Certificate object
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.certificate = (Certificate) Certificate.ASN1.decode(in);
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // cache the values of TBSCertificate and Extensions
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.tbsCert = certificate.getTbsCertificate();
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.extensions = tbsCert.getExtensions();
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new CertificateException(e);
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs the instance on the base of existing Certificate object to
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * be wrapped.
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X509CertImpl(Certificate certificate) {
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.certificate = certificate;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // cache the values of TBSCertificate and Extensions
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tbsCert = certificate.getTbsCertificate();
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.extensions = tbsCert.getExtensions();
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs the instance on the base of ASN.1 encoded
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * form of X.509 certificate provided via array of bytes.
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param encoding byte array containing ASN.1 encoded form of certificate.
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException if some decoding problems occur.
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X509CertImpl(byte[] encoding) throws IOException {
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this((Certificate) Certificate.ASN1.decode(encoding));
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
132ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    public void checkValidity()
133ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            throws CertificateExpiredException, CertificateNotYetValidException {
134ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        checkValidity(System.currentTimeMillis());
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void checkValidity(Date date)
138ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            throws CertificateExpiredException, CertificateNotYetValidException {
139ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        checkValidity(date.getTime());
140ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    }
141ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom
142ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private void checkValidity(long time)
143ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            throws CertificateExpiredException, CertificateNotYetValidException {
144ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (time < getNotBeforeInternal()) {
145ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            throw new CertificateNotYetValidException("current time: " + new Date(time)
146ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom                + ", validation time: " + new Date(getNotBeforeInternal()));
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
148ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (time > getNotAfterInternal()) {
149ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            throw new CertificateExpiredException("current time: " + new Date(time)
150ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom                + ", expiration time: " + new Date(getNotAfterInternal()));
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getVersion() {
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return tbsCert.getVersion() + 1;
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigInteger getSerialNumber() {
159ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        BigInteger result = serialNumber;
160ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
161ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            serialNumber = result = tbsCert.getSerialNumber();
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
163ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Principal getIssuerDN() {
167ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return getIssuerX500Principal();
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X500Principal getIssuerX500Principal() {
171ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        X500Principal result = issuer;
172ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // retrieve the issuer's principal
174ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            issuer = result = tbsCert.getIssuer().getX500Principal();
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
176ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Principal getSubjectDN() {
180ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return getSubjectX500Principal();
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X500Principal getSubjectX500Principal() {
184ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        X500Principal result = subject;
185ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // retrieve the subject's principal
187ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            subject = result = tbsCert.getSubject().getX500Principal();
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
189ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Date getNotBefore() {
193ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return new Date(getNotBeforeInternal());
194ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    }
1955c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson
196ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private long getNotBeforeInternal() {
197ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        long result = notBefore;
198ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == -1) {
199ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            notBefore = result = tbsCert.getValidity().getNotBefore().getTime();
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
201ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Date getNotAfter() {
205ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return new Date(getNotAfterInternal());
206ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    }
2075c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson
208ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private long getNotAfterInternal() {
209ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        long result = notAfter;
210ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == -1) {
211ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            notAfter = result = tbsCert.getValidity().getNotAfter().getTime();
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
213ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
216ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    public byte[] getTBSCertificate() throws CertificateEncodingException {
217ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return getTbsCertificateInternal().clone();
218ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    }
2195c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson
220ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private byte[] getTbsCertificateInternal() {
221ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        byte[] result = tbsCertificate;
222ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
223ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            tbsCertificate = result = tbsCert.getEncoded();
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getSignature() {
229ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return getSignatureInternal().clone();
230ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    }
2315c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson
232ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private byte[] getSignatureInternal() {
233ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        byte[] result = signature;
234ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
235ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            signature = result = certificate.getSignatureValue();
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getSigAlgName() {
241ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        String result = sigAlgName;
242ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
243ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            String sigAlgOIDLocal = getSigAlgOID();
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // retrieve the name of the signing algorithm
245ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            result = AlgNameMapper.map2AlgName(sigAlgOIDLocal);
246ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            if (result == null) {
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // if could not be found, use OID as a name
248ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom                result = sigAlgOIDLocal;
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
250ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            sigAlgName = result;
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
252ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getSigAlgOID() {
256ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        String result = sigAlgOID;
257ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if info was not retrieved (and cached), do it:
259ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            sigAlgOID = result = tbsCert.getSignature().getAlgorithm();
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
261ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getSigAlgParams() {
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nullSigAlgParams) {
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
268ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        byte[] result = sigAlgParams;
269ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
270ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            result = tbsCert.getSignature().getParameters();
271ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            if (result == null) {
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                nullSigAlgParams = true;
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
275ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            sigAlgParams = result;
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
277ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean[] getIssuerUniqueID() {
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return tbsCert.getIssuerUniqueID();
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean[] getSubjectUniqueID() {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return tbsCert.getSubjectUniqueID();
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean[] getKeyUsage() {
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return extensions.valueOfKeyUsage();
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2955c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    public List<String> getExtendedKeyUsage()
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                throws CertificateParsingException {
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return extensions.valueOfExtendedKeyUsage();
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new CertificateParsingException(e);
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getBasicConstraints() {
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return Integer.MAX_VALUE;
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return extensions.valueOfBasicConstrains();
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3145c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Retrieve the extension value from the cached extensions object
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // This extension is not checked for correctness during
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // certificate generation, so now it can throw exception
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return extensions.valueOfSubjectAlternativeName();
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new CertificateParsingException(e);
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.security.cert.X509Certificate#getIssuerAlternativeNames()
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method documentation for more information.
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3325c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Retrieve the extension value from the cached extensions object
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // This extension is not checked for correctness during
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // certificate generation, so now it can throw exception
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return extensions.valueOfIssuerAlternativeName();
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new CertificateParsingException(e);
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3464280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public byte[] getEncoded() throws CertificateEncodingException {
347ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return getEncodedInternal().clone();
348ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    }
349ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom    private byte[] getEncodedInternal() throws CertificateEncodingException {
350ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        byte[] result = encoding;
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding == null) {
352ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            encoding = result = certificate.getEncoded();
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3574280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public PublicKey getPublicKey() {
358ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        PublicKey result = publicKey;
359ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        if (result == null) {
360ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom            publicKey = result = tbsCert.getSubjectPublicKeyInfo().getPublicKey();
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
362ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        return result;
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3654280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public String toString() {
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return certificate.toString();
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3694280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public void verify(PublicKey key)
3704280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom            throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
3714280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom            NoSuchProviderException, SignatureException {
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
373487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        Signature signature;
374487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        try {
375487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom            signature = OpenSSLSignature.getInstance(getSigAlgName());
376487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        } catch (NoSuchAlgorithmException ignored) {
377487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom            signature = Signature.getInstance(getSigAlgName());
378487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        }
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        signature.initVerify(key);
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // retrieve the encoding of the TBSCertificate structure
381ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        byte[] tbsCertificateLocal = getTbsCertificateInternal();
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // compute and verify the signature
383ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        signature.update(tbsCertificateLocal, 0, tbsCertificateLocal.length);
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!signature.verify(certificate.getSignatureValue())) {
385897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new SignatureException("Signature was not verified");
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3894280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public void verify(PublicKey key, String sigProvider)
3904280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom            throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
3914280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom            NoSuchProviderException, SignatureException {
392f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
393487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        Signature signature;
394487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        try {
395487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom            if (sigProvider == null) {
396487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom                signature = OpenSSLSignature.getInstance(getSigAlgName());
397487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom            } else {
398487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom                signature = Signature.getInstance(getSigAlgName(), sigProvider);
399487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom            }
400487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        } catch (NoSuchAlgorithmException ignored) {
401487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom            signature = Signature.getInstance(getSigAlgName(), sigProvider);
402487c58a9ff0cb4c6e074b2f5d99a0c3efa54fa37Brian Carlstrom        }
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        signature.initVerify(key);
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // retrieve the encoding of the TBSCertificate structure
405ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        byte[] tbsCertificateLocal = getTbsCertificateInternal();
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // compute and verify the signature
407ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom        signature.update(tbsCertificateLocal, 0, tbsCertificateLocal.length);
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!signature.verify(certificate.getSignatureValue())) {
409897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new SignatureException("Signature was not verified");
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4134280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public Set<String> getNonCriticalExtensionOIDs() {
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // retrieve the info from the cached extensions object
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return extensions.getNonCriticalExtensions();
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4214280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public Set<String> getCriticalExtensionOIDs() {
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // retrieve the info from the cached extensions object
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return extensions.getCriticalExtensions();
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4294280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public byte[] getExtensionValue(String oid) {
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // retrieve the info from the cached extensions object
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Extension ext = extensions.getExtensionByOID(oid);
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (ext == null) ? null : ext.getRawExtnValue();
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4384280237a545e7482b6ea954fd862878867b8f896Brian Carlstrom    @Override public boolean hasUnsupportedCriticalExtension() {
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extensions == null) {
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // retrieve the info from the cached extensions object
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return extensions.hasUnsupportedCritical();
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
447