X509CertImpl.java revision ef6370c1b62edf75dc7c3e5411468b55627e037d
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; 523e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstromimport org.apache.harmony.xnet.provider.jsse.NativeCrypto; 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 */ 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class X509CertImpl extends X509Certificate { 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @serial 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 2972248729446736154L; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the core object to be wrapped in X509Certificate 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Certificate certificate; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to speed up access to the info, the following fields 74ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom // cache values retrieved from the certificate object, 75ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom // initialized using the "single-check idiom". 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final TBSCertificate tbsCert; 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Extensions extensions; 78ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile long notBefore = -1; 79ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile long notAfter = -1; 80ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile BigInteger serialNumber; 81ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile X500Principal issuer; 82ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile X500Principal subject; 83ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile byte[] tbsCertificate; 84ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile byte[] signature; 85ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile String sigAlgName; 86ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile String sigAlgOID; 87ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile byte[] sigAlgParams; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates whether the signature algorithm parameters are null 89ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile boolean nullSigAlgParams; 90ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private volatile PublicKey publicKey; 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // encoding of the certificate 935bd2429e5d62e7885c717bda72e789f2649837beBob Lee private volatile byte[] encoding; 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ---------------------- Constructors ------------------------------- 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs the instance on the base of ASN.1 encoded 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * form of X.509 certificate provided via stream parameter. 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param in input stream containing ASN.1 encoded form of certificate. 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws CertificateException if some decoding problems occur. 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public X509CertImpl(InputStream in) throws CertificateException { 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // decode the Certificate object 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.certificate = (Certificate) Certificate.ASN1.decode(in); 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cache the values of TBSCertificate and Extensions 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tbsCert = certificate.getTbsCertificate(); 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.extensions = tbsCert.getExtensions(); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new CertificateException(e); 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs the instance on the base of existing Certificate object to 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be wrapped. 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public X509CertImpl(Certificate certificate) { 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.certificate = certificate; 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cache the values of TBSCertificate and Extensions 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tbsCert = certificate.getTbsCertificate(); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.extensions = tbsCert.getExtensions(); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs the instance on the base of ASN.1 encoded 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * form of X.509 certificate provided via array of bytes. 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param encoding byte array containing ASN.1 encoded form of certificate. 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if some decoding problems occur. 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public X509CertImpl(byte[] encoding) throws IOException { 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this((Certificate) Certificate.ASN1.decode(encoding)); 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ----------------- Public methods implementations ------------------ 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#checkValidity() 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 146ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom public void checkValidity() 147ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom throws CertificateExpiredException, CertificateNotYetValidException { 148ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom checkValidity(System.currentTimeMillis()); 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#checkValidity(Date) 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void checkValidity(Date date) 156ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom throws CertificateExpiredException, CertificateNotYetValidException { 157ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom checkValidity(date.getTime()); 158ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom } 159ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom 160ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private void checkValidity(long time) 161ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom throws CertificateExpiredException, CertificateNotYetValidException { 162ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (time < getNotBeforeInternal()) { 163ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom throw new CertificateNotYetValidException("current time: " + new Date(time) 164ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom + ", validation time: " + new Date(getNotBeforeInternal())); 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 166ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (time > getNotAfterInternal()) { 167ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom throw new CertificateExpiredException("current time: " + new Date(time) 168ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom + ", expiration time: " + new Date(getNotAfterInternal())); 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getVersion() 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getVersion() { 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return tbsCert.getVersion() + 1; 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSerialNumber() 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public BigInteger getSerialNumber() { 185ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom BigInteger result = serialNumber; 186ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 187ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom serialNumber = result = tbsCert.getSerialNumber(); 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 189ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getIssuerDN() 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Principal getIssuerDN() { 197ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return getIssuerX500Principal(); 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getIssuerX500Principal() 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public X500Principal getIssuerX500Principal() { 205ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom X500Principal result = issuer; 206ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the issuer's principal 208ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom issuer = result = tbsCert.getIssuer().getX500Principal(); 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 210ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSubjectDN() 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Principal getSubjectDN() { 218ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return getSubjectX500Principal(); 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSubjectX500Principal() 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public X500Principal getSubjectX500Principal() { 226ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom X500Principal result = subject; 227ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the subject's principal 229ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom subject = result = tbsCert.getSubject().getX500Principal(); 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 231ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getNotBefore() 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Date getNotBefore() { 239ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return new Date(getNotBeforeInternal()); 240ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom } 241ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private long getNotBeforeInternal() { 242ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom long result = notBefore; 243ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == -1) { 244ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom notBefore = result = tbsCert.getValidity().getNotBefore().getTime(); 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 246ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getNotAfter() 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Date getNotAfter() { 254ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return new Date(getNotAfterInternal()); 255ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom } 256ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private long getNotAfterInternal() { 257ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom long result = notAfter; 258ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == -1) { 259ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom notAfter = result = tbsCert.getValidity().getNotAfter().getTime(); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 261ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getTBSCertificate() 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 268ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom public byte[] getTBSCertificate() throws CertificateEncodingException { 269ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return getTbsCertificateInternal().clone(); 270ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom } 271ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private byte[] getTbsCertificateInternal() { 272ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom byte[] result = tbsCertificate; 273ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 274ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom tbsCertificate = result = tbsCert.getEncoded(); 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSignature() 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getSignature() { 284ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return getSignatureInternal().clone(); 285ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom } 286ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private byte[] getSignatureInternal() { 287ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom byte[] result = signature; 288ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 289ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom signature = result = certificate.getSignatureValue(); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSigAlgName() 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getSigAlgName() { 299ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom String result = sigAlgName; 300ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 301ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom String sigAlgOIDLocal = getSigAlgOID(); 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the name of the signing algorithm 303ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom result = AlgNameMapper.map2AlgName(sigAlgOIDLocal); 304ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if could not be found, use OID as a name 306ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom result = sigAlgOIDLocal; 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 308ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom sigAlgName = result; 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 310ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSigAlgOID() 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getSigAlgOID() { 318ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom String result = sigAlgOID; 319ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if info was not retrieved (and cached), do it: 321ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom sigAlgOID = result = tbsCert.getSignature().getAlgorithm(); 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 323ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSigAlgParams() 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getSigAlgParams() { 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nullSigAlgParams) { 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 334ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom byte[] result = sigAlgParams; 335ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 336ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom result = tbsCert.getSignature().getParameters(); 337ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nullSigAlgParams = true; 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 341ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom sigAlgParams = result; 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 343ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getIssuerUniqueID() 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean[] getIssuerUniqueID() { 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return tbsCert.getIssuerUniqueID(); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSubjectUniqueID() 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean[] getSubjectUniqueID() { 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return tbsCert.getSubjectUniqueID(); 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getKeyUsage() 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean[] getKeyUsage() { 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.valueOfKeyUsage(); 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getExtendedKeyUsage() 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public List/*<String>*/ getExtendedKeyUsage() 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws CertificateParsingException { 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.valueOfExtendedKeyUsage(); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new CertificateParsingException(e); 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getBasicConstraints() 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getBasicConstraints() { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Integer.MAX_VALUE; 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.valueOfBasicConstrains(); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getSubjectAlternativeNames() 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Collection/*<List<?>>*/ getSubjectAlternativeNames() 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws CertificateParsingException { 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Retrieve the extension value from the cached extensions object 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // This extension is not checked for correctness during 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // certificate generation, so now it can throw exception 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.valueOfSubjectAlternativeName(); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new CertificateParsingException(e); 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Certificate#getIssuerAlternativeNames() 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Collection/*FIXME <List<?>>*/ getIssuerAlternativeNames() 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws CertificateParsingException { 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Retrieve the extension value from the cached extensions object 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // This extension is not checked for correctness during 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // certificate generation, so now it can throw exception 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.valueOfIssuerAlternativeName(); 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new CertificateParsingException(e); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ----- java.security.cert.Certificate methods implementations ------ 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.Certificate#getEncoded() 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getEncoded() throws CertificateEncodingException { 447ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return getEncodedInternal().clone(); 448ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom } 449ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom private byte[] getEncodedInternal() throws CertificateEncodingException { 450ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom byte[] result = encoding; 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (encoding == null) { 452ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom encoding = result = certificate.getEncoded(); 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.Certificate#getPublicKey() 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public PublicKey getPublicKey() { 462ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom PublicKey result = publicKey; 463ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (result == null) { 464ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom publicKey = result = tbsCert.getSubjectPublicKeyInfo().getPublicKey(); 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom return result; 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.Certificate#toString() 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return certificate.toString(); 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Verifies the signature of the certificate. 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.Certificate#verify(PublicKey) 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void verify(PublicKey key) 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws CertificateException, NoSuchAlgorithmException, 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidKeyException, NoSuchProviderException, 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SignatureException { 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (getSigAlgName().endsWith("withRSA")) { 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fastVerify(key); 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Signature signature = Signature.getInstance(getSigAlgName()); 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project signature.initVerify(key); 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the encoding of the TBSCertificate structure 494ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom byte[] tbsCertificateLocal = getTbsCertificateInternal(); 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // compute and verify the signature 496ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom signature.update(tbsCertificateLocal, 0, tbsCertificateLocal.length); 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!signature.verify(certificate.getSignatureValue())) { 498897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new SignatureException("Signature was not verified"); 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Verifies the signature of the certificate. 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.Certificate#verify(PublicKey,String) 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void verify(PublicKey key, String sigProvider) 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws CertificateException, NoSuchAlgorithmException, 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidKeyException, NoSuchProviderException, 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SignatureException { 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (getSigAlgName().endsWith("withRSA")) { 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fastVerify(key); 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 515f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Signature signature = 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Signature.getInstance(getSigAlgName(), sigProvider); 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project signature.initVerify(key); 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the encoding of the TBSCertificate structure 520ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom byte[] tbsCertificateLocal = getTbsCertificateInternal(); 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // compute and verify the signature 522ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom signature.update(tbsCertificateLocal, 0, tbsCertificateLocal.length); 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!signature.verify(certificate.getSignatureValue())) { 524897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new SignatureException("Signature was not verified"); 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implements a faster RSA verification method that delegates to OpenSSL 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * native code. In all other aspects it behaves just like the ordinary 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link verify} method. 532f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key The RSA public key to use 534f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SignatureException If the verification fails. 536f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @throws InvalidKeyException 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void fastVerify(PublicKey key) throws SignatureException, 53987eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob InvalidKeyException, NoSuchAlgorithmException { 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(key instanceof RSAPublicKey)) { 541897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new InvalidKeyException("key is not an instance of RSAPublicKey"); 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project RSAPublicKey rsaKey = (RSAPublicKey) key; 544f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String algorithm = getSigAlgName(); 54687eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob 54787eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob // We don't support MD2 anymore. This needs to also check for aliases 54887eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob // and OIDs. 54987eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob if ("MD2withRSA".equalsIgnoreCase(algorithm) || 55087eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob "MD2withRSAEncryption".equalsIgnoreCase(algorithm) || 55187eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob "1.2.840.113549.1.1.2".equalsIgnoreCase(algorithm) || 55287eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob "MD2/RSA".equalsIgnoreCase(algorithm)) { 55387eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob throw new NoSuchAlgorithmException(algorithm); 55487eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob } 55587eb4de6347e1be029cde77dd43ad9b1af901472Urs Grob 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i = algorithm.indexOf("with"); 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project algorithm = algorithm.substring(i + 4) + "-" + algorithm.substring(0, i); 558f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 559ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom byte[] tbsCertificateLocal = getTbsCertificateInternal(); 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] sig = certificate.getSignatureValue(); 561ef6370c1b62edf75dc7c3e5411468b55627e037dBrian Carlstrom if (!NativeCrypto.verifySignature(tbsCertificateLocal, sig, algorithm, rsaKey)) { 562897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new SignatureException("Signature was not verified"); 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ----- java.security.cert.X509Extension methods implementations ---- 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Extension#getNonCriticalExtensionOIDs() 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set getNonCriticalExtensionOIDs() { 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the info from the cached extensions object 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.getNonCriticalExtensions(); 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Extension#getCriticalExtensionOIDs() 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set getCriticalExtensionOIDs() { 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the info from the cached extensions object 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.getCriticalExtensions(); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Extension#getExtensionValue(String) 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getExtensionValue(String oid) { 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the info from the cached extensions object 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Extension ext = extensions.getExtensionByOID(oid); 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (ext == null) ? null : ext.getRawExtnValue(); 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.security.cert.X509Extension#hasUnsupportedCriticalExtension() 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information. 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasUnsupportedCriticalExtension() { 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extensions == null) { 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // retrieve the info from the cached extensions object 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return extensions.hasUnsupportedCritical(); 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 620