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