151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 26f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.security.x509; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.OutputStream; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.math.BigInteger; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.*; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.*; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.Certificate; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*; 35d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Rootimport java.util.concurrent.ConcurrentHashMap; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport javax.security.auth.x500.X500Principal; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.HexDumpEncoder; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.*; 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.provider.X509Factory; 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The X509CertImpl class represents an X.509 certificate. These certificates 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are widely used to support authentication and other functionality in 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Internet security systems. Common applications include Privacy Enhanced 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Mail (PEM), Transport Layer Security (SSL), code signing for trusted 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * software distribution, and Secure Electronic Transactions (SET). There 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is a commercial infrastructure ready to manage large scale deployments 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of X.509 identity certificates. 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>These certificates are managed and vouched for by <em>Certificate 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Authorities</em> (CAs). CAs are services which create certificates by 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * placing data in the X.509 standard format and then digitally signing 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that data. Such signatures are quite difficult to forge. CAs act as 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * trusted third parties, making introductions between agents who have no 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * direct knowledge of each other. CA certificates are either signed by 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * themselves, or by some other CA such as a "root" CA. 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>RFC 1422 is very informative, though it does not describe much 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the recent work being done with X.509 certificates. That includes 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a 1996 version (X.509v3) and a variety of enhancements being made to 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * facilitate an explosion of personal certificates used as "Internet 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Drivers' Licences", or with SET for credit card transactions. 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>More recent work includes the IETF PKIX Working Group efforts, 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * especially RFC2459. 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Dave Brownell 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Amit Kapoor 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Hemma Prafullchandra 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see X509CertInfo 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class X509CertImpl extends X509Certificate implements DerEncoder { 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final long serialVersionUID = -3457612960190864406L; 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String DOT = "."; 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Public attribute names. 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String NAME = "x509"; 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String INFO = X509CertInfo.NAME; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String ALG_ID = "algorithm"; 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String SIGNATURE = "signature"; 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String SIGNED_CERT = "signed_cert"; 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The following are defined for ease-of-use. These 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are the most frequently retrieved attributes. 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // x509.info.subject.dname 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String SUBJECT_DN = NAME + DOT + INFO + DOT + 93d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.SUBJECT + DOT + X509CertInfo.DN_NAME; 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // x509.info.issuer.dname 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String ISSUER_DN = NAME + DOT + INFO + DOT + 96d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.ISSUER + DOT + X509CertInfo.DN_NAME; 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // x509.info.serialNumber.number 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String SERIAL_ID = NAME + DOT + INFO + DOT + 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X509CertInfo.SERIAL_NUMBER + DOT + 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateSerialNumber.NUMBER; 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // x509.info.key.value 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String PUBLIC_KEY = NAME + DOT + INFO + DOT + 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X509CertInfo.KEY + DOT + 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateX509Key.KEY; 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // x509.info.version.value 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String VERSION = NAME + DOT + INFO + DOT + 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X509CertInfo.VERSION + DOT + 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateVersion.VERSION; 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // x509.algorithm 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String SIG_ALG = NAME + DOT + ALG_ID; 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // x509.signature 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String SIG = NAME + DOT + SIGNATURE; 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // when we sign and decode we set this to true 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this is our means to make certificates immutable 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean readOnly = false; 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Certificate data, and its envelope 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] signedCert = null; 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected X509CertInfo info = null; 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected AlgorithmId algId = null; 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected byte[] signature = null; 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // recognized extension OIDS 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String KEY_USAGE_OID = "2.5.29.15"; 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String EXTENDED_KEY_USAGE_OID = "2.5.29.37"; 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String BASIC_CONSTRAINT_OID = "2.5.29.19"; 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String SUBJECT_ALT_NAME_OID = "2.5.29.17"; 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String ISSUER_ALT_NAME_OID = "2.5.29.18"; 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String AUTH_INFO_ACCESS_OID = "1.3.6.1.5.5.7.1.1"; 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // number of standard key usage bits. 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int NUM_STANDARD_KEY_USAGE = 9; 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // SubjectAlterntativeNames cache 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Collection<List<?>> subjectAlternativeNames; 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // IssuerAlternativeNames cache 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Collection<List<?>> issuerAlternativeNames; 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ExtendedKeyUsage cache 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private List<String> extKeyUsage; 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // AuthorityInformationAccess cache 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Set<AccessDescription> authInfoAccess; 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * PublicKey that has previously been used to verify 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the signature of this certificate. Null if the certificate has not 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * yet been verified. 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private PublicKey verifiedPublicKey; 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If verifiedPublicKey is not null, name of the provider used to 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * successfully verify the signature of this certificate, or the 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * empty String if no provider was explicitly specified. 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String verifiedProvider; 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If verifiedPublicKey is not null, result of the verification using 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * verifiedPublicKey and verifiedProvider. If true, verification was 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * successful, if false, it failed. 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean verificationResult; 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Default constructor. 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public X509CertImpl() { } 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Unmarshals a certificate from its encoded form, parsing the 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * encoded bytes. This form of constructor is used by agents which 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * need to examine and use certificate contents. That is, this is 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * one of the more commonly used constructors. Note that the buffer 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * must include only a certificate, and no "garbage" may be left at 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the end. If you need to ignore data at the end of a certificate, 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * use another constructor. 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param certData the encoded bytes, with no trailing padding. 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on parsing and initialization errors. 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public X509CertImpl(byte[] certData) throws CertificateException { 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parse(new DerValue(certData)); 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signedCert = null; 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Unable to initialize, " + e, e); 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1956975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // BEGIN Android-removed 1966975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer /* 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unmarshals an X.509 certificate from an input stream. If the 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate is RFC1421 hex-encoded, then it must begin with 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the line X509Factory.BEGIN_CERT and end with the line 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * X509Factory.END_CERT. 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in an input stream holding at least one certificate that may 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be either DER-encoded or RFC1421 hex-encoded version of the 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DER-encoded certificate. 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on parsing and initialization errors. 2077b5c7bb3e2ac90c7622a1ce42d4a7d149cc63ad9Sergio Giro * 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public X509CertImpl(InputStream in) throws CertificateException { 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue der = null; 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski BufferedInputStream inBuffered = new BufferedInputStream(in); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // First try reading stream as HEX-encoded DER-encoded bytes, 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // since not mistakable for raw DER 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inBuffered.mark(Integer.MAX_VALUE); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski der = readRFC1421Cert(inBuffered); 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Next, try reading stream as raw DER-encoded bytes 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inBuffered.reset(); 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski der = new DerValue(inBuffered); 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe1) { 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Input stream must be " + 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "either DER-encoded bytes " + 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "or RFC1421 hex-encoded " + 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DER-encoded bytes: " + 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ioe1.getMessage(), ioe1); 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parse(der); 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signedCert = null; 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Unable to parse DER value of " + 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "certificate, " + ioe, ioe); 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * read input stream as HEX-encoded DER-encoded bytes 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in InputStream to read 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @returns DerValue corresponding to decoded HEX-encoded bytes 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if stream can not be interpreted as RFC1421 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * encoded bytes 2487b5c7bb3e2ac90c7622a1ce42d4a7d149cc63ad9Sergio Giro * 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private DerValue readRFC1421Cert(InputStream in) throws IOException { 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue der = null; 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String line = null; 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski BufferedReader certBufferedReader = 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new BufferedReader(new InputStreamReader(in, "ASCII")); 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski line = certBufferedReader.readLine(); 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe1) { 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Unable to read InputStream: " + 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ioe1.getMessage()); 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (line.equals(X509Factory.BEGIN_CERT)) { 2617b5c7bb3e2ac90c7622a1ce42d4a7d149cc63ad9Sergio Giro /* stream appears to be hex-encoded bytes * 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ByteArrayOutputStream decstream = new ByteArrayOutputStream(); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((line = certBufferedReader.readLine()) != null) { 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (line.equals(X509Factory.END_CERT)) { 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski der = new DerValue(decstream.toByteArray()); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 269cf4cc555d38c0771e88b7a3945a51d6492bcad47Sergio Giro decstream.write(Base64.getMimeDecoder().decode(line)); 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe2) { 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Unable to read InputStream: " 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + ioe2.getMessage()); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("InputStream is not RFC1421 hex-encoded " + 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DER bytes"); 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return der; 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 2826975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer */ 2836975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // END Android-removed 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Construct an initialized X509 Certificate. The certificate is stored 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in raw form and has to be signed to be useful. 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @params info the X509CertificateInfo which the Certificate is to be 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * created from. 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public X509CertImpl(X509CertInfo certInfo) { 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.info = certInfo; 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Unmarshal a certificate from its encoded form, parsing a DER value. 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This form of constructor is used by agents which need to examine 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and use certificate contents. 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param derVal the der value containing the encoded cert. 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on parsing and initialization errors. 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public X509CertImpl(DerValue derVal) throws CertificateException { 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parse(derVal); 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signedCert = null; 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Unable to initialize, " + e, e); 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 314b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * Unmarshal a certificate from its encoded form, parsing a DER value. 315b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * This form of constructor is used by agents which need to examine 316b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * and use certificate contents. 317b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * 318b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * @param derVal the der value containing the encoded cert. 319b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * @exception CertificateException on parsing and initialization errors. 320b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin */ 321b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin public X509CertImpl(DerValue derVal, byte[] encoded) 322b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin throws CertificateException { 323b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin try { 324b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin parse(derVal, encoded); 325b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin } catch (IOException e) { 326b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin signedCert = null; 327b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin throw new CertificateException("Unable to initialize, " + e, e); 328b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin } 329b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin } 330b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin 331b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin /** 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Appends the certificate to an output stream. 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param out an input stream to which the certificate is appended. 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateEncodingException on encoding errors. 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void encode(OutputStream out) 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateEncodingException { 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signedCert == null) 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateEncodingException( 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "Null certificate to encode"); 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(signedCert.clone()); 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateEncodingException(e.toString()); 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DER encode this object onto an output stream. 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Implements the <code>DerEncoder</code> interface. 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param out the output stream on which to write the DER encoding. 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException on encoding error. 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void derEncode(OutputStream out) throws IOException { 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signedCert == null) 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Null certificate to encode"); 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(signedCert.clone()); 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the encoded form of this certificate. It is 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * assumed that each certificate type would have only a single 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * form of encoding; for example, X.509 certificates would 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be encoded as ASN.1 DER. 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateEncodingException if an encoding error occurs. 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getEncoded() throws CertificateEncodingException { 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getEncodedInternal().clone(); 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returned the encoding as an uncloned byte array. Callers must 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * guarantee that they neither modify it nor expose it to untrusted 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * code. 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getEncodedInternal() throws CertificateEncodingException { 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signedCert == null) { 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateEncodingException( 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "Null certificate to encode"); 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return signedCert; 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Throws an exception if the certificate was not signed using the 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * verification key provided. Successfully verifying a certificate 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * does <em>not</em> indicate that one should trust the entity which 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it represents. 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param key the public key used for verification. 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception InvalidKeyException on incorrect key. 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchAlgorithmException on unsupported signature 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * algorithms. 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchProviderException if there's no default provider. 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SignatureException on signature errors. 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on encoding errors. 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void verify(PublicKey key) 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException, NoSuchAlgorithmException, 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InvalidKeyException, NoSuchProviderException, SignatureException { 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verify(key, ""); 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Throws an exception if the certificate was not signed using the 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * verification key provided. Successfully verifying a certificate 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * does <em>not</em> indicate that one should trust the entity which 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it represents. 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param key the public key used for verification. 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param sigProvider the name of the provider. 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchAlgorithmException on unsupported signature 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * algorithms. 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception InvalidKeyException on incorrect key. 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchProviderException on incorrect provider. 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SignatureException on signature errors. 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on encoding errors. 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void verify(PublicKey key, String sigProvider) 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException, NoSuchAlgorithmException, 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InvalidKeyException, NoSuchProviderException, SignatureException { 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sigProvider == null) { 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigProvider = ""; 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((verifiedPublicKey != null) && verifiedPublicKey.equals(key)) { 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this certificate has already been verified using 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this public key. Make sure providers match, too. 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sigProvider.equals(verifiedProvider)) { 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (verificationResult) { 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SignatureException("Signature does not match."); 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signedCert == null) { 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateEncodingException("Uninitialized certificate"); 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Verify the signature ... 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Signature sigVerf = null; 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sigProvider.length() == 0) { 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigVerf = Signature.getInstance(algId.getName()); 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigVerf = Signature.getInstance(algId.getName(), sigProvider); 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigVerf.initVerify(key); 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] rawCert = info.getEncodedInfo(); 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigVerf.update(rawCert, 0, rawCert.length); 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // verify may throw SignatureException for invalid encodings, etc. 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verificationResult = sigVerf.verify(signature); 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verifiedPublicKey = key; 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verifiedProvider = sigProvider; 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (verificationResult == false) { 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SignatureException("Signature does not match."); 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 4696f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * Throws an exception if the certificate was not signed using the 4706f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * verification key provided. This method uses the signature verification 4716f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * engine supplied by the specified provider. Note that the specified 4726f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * Provider object does not have to be registered in the provider list. 4736f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * Successfully verifying a certificate does <em>not</em> indicate that one 4746f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * should trust the entity which it represents. 4756f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * 4766f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * @param key the public key used for verification. 4776f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * @param sigProvider the provider. 4786f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * 4796f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * @exception NoSuchAlgorithmException on unsupported signature 4806f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * algorithms. 4816f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * @exception InvalidKeyException on incorrect key. 4826f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * @exception SignatureException on signature errors. 4836f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * @exception CertificateException on encoding errors. 4846f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root */ 4856f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root public synchronized void verify(PublicKey key, Provider sigProvider) 4866f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root throws CertificateException, NoSuchAlgorithmException, 4876f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root InvalidKeyException, SignatureException { 4886f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root if (signedCert == null) { 4896f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root throw new CertificateEncodingException("Uninitialized certificate"); 4906f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root } 4916f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root // Verify the signature ... 4926f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root Signature sigVerf = null; 4936f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root if (sigProvider == null) { 4946f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root sigVerf = Signature.getInstance(algId.getName()); 4956f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root } else { 4966f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root sigVerf = Signature.getInstance(algId.getName(), sigProvider); 4976f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root } 4986f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root sigVerf.initVerify(key); 4996f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root 5006f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root byte[] rawCert = info.getEncodedInfo(); 5016f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root sigVerf.update(rawCert, 0, rawCert.length); 5026f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root 5036f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root // verify may throw SignatureException for invalid encodings, etc. 5046f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root verificationResult = sigVerf.verify(signature); 5056f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root verifiedPublicKey = key; 5066f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root 5076f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root if (verificationResult == false) { 5086f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root throw new SignatureException("Signature does not match."); 5096f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root } 5106f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root } 5116f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root 5126f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root /** 5136f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * This static method is the default implementation of the 5146f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * verify(PublicKey key, Provider sigProvider) method in X509Certificate. 5156f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * Called from java.security.cert.X509Certificate.verify(PublicKey key, 5166f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root * Provider sigProvider) 5176f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root */ 5186f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root public static void verify(X509Certificate cert, PublicKey key, 5196f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root Provider sigProvider) throws CertificateException, 5206f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root NoSuchAlgorithmException, InvalidKeyException, SignatureException { 5216f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root cert.verify(key, sigProvider); 5226f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root } 5236f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root 5246f31965522c21a5c47296b31d67cc07cb3c65748Kenny Root /** 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an X.509 certificate, and signs it using the given key 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (associating a signature algorithm and an X.500 name). 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This operation is used to implement the certificate generation 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * functionality of a certificate authority. 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param key the private key used for signing. 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param algorithm the name of the signature algorithm used. 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception InvalidKeyException on incorrect key. 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchAlgorithmException on unsupported signature 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * algorithms. 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchProviderException if there's no default provider. 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SignatureException on signature errors. 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on encoding errors. 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void sign(PrivateKey key, String algorithm) 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException, NoSuchAlgorithmException, 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InvalidKeyException, NoSuchProviderException, SignatureException { 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sign(key, algorithm, null); 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an X.509 certificate, and signs it using the given key 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (associating a signature algorithm and an X.500 name). 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This operation is used to implement the certificate generation 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * functionality of a certificate authority. 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param key the private key used for signing. 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param algorithm the name of the signature algorithm used. 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param provider the name of the provider. 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchAlgorithmException on unsupported signature 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * algorithms. 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception InvalidKeyException on incorrect key. 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NoSuchProviderException on incorrect provider. 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SignatureException on signature errors. 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on encoding errors. 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void sign(PrivateKey key, String algorithm, String provider) 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException, NoSuchAlgorithmException, 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InvalidKeyException, NoSuchProviderException, SignatureException { 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readOnly) 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateEncodingException( 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "cannot over-write existing certificate"); 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Signature sigEngine = null; 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((provider == null) || (provider.length() == 0)) 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigEngine = Signature.getInstance(algorithm); 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigEngine = Signature.getInstance(algorithm, provider); 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigEngine.initSign(key); 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // in case the name is reset 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski algId = AlgorithmId.get(sigEngine.getAlgorithm()); 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerOutputStream out = new DerOutputStream(); 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerOutputStream tmp = new DerOutputStream(); 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // encode certificate info 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski info.encode(tmp); 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] rawCert = tmp.toByteArray(); 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // encode algorithm identifier 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski algId.encode(tmp); 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Create and encode the signature itself. 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigEngine.update(rawCert, 0, rawCert.length); 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signature = sigEngine.sign(); 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmp.putBitString(signature); 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Wrap the signed data in a SEQUENCE { data, algorithm, sig } 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(DerValue.tag_Sequence, tmp); 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signedCert = out.toByteArray(); 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readOnly = true; 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateEncodingException(e.toString()); 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Checks that the certificate is currently valid, i.e. the current 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * time is within the specified validity period. 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateExpiredException if the certificate has expired. 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateNotYetValidException if the certificate is not 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * yet valid. 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void checkValidity() 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateExpiredException, CertificateNotYetValidException { 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date date = new Date(); 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkValidity(date); 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Checks that the specified date is within the certificate's 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * validity period, or basically if the certificate would be 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * valid at the specified date/time. 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param date the Date to check against to see if this certificate 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is valid at that date/time. 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateExpiredException if the certificate has expired 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with respect to the <code>date</code> supplied. 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateNotYetValidException if the certificate is not 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * yet valid with respect to the <code>date</code> supplied. 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void checkValidity(Date date) 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateExpiredException, CertificateNotYetValidException { 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateValidity interval = null; 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski interval = (CertificateValidity)info.get(CertificateValidity.NAME); 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateNotYetValidException("Incorrect validity period"); 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (interval == null) 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateNotYetValidException("Null validity period"); 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski interval.valid(date); 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return the requested attribute from the certificate. 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note that the X509CertInfo is not cloned for performance reasons. 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Callers must ensure that they do not modify it. All other 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * attributes are cloned. 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the attribute. 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateParsingException on invalid attribute identifier. 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object get(String name) 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateParsingException { 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X509AttributeName attr = new X509AttributeName(name); 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String id = attr.getPrefix(); 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(id.equalsIgnoreCase(NAME))) { 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException("Invalid root of " 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + "attribute name, expected [" + NAME + 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "], received " + "[" + id + "]"); 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski attr = new X509AttributeName(attr.getSuffix()); 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski id = attr.getPrefix(); 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (id.equalsIgnoreCase(INFO)) { 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) { 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (attr.getSuffix() != null) { 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return info.get(attr.getSuffix()); 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException(e.toString()); 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (CertificateException e) { 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException(e.toString()); 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return info; 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (id.equalsIgnoreCase(ALG_ID)) { 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return(algId); 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (id.equalsIgnoreCase(SIGNATURE)) { 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signature != null) 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return signature.clone(); 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (id.equalsIgnoreCase(SIGNED_CERT)) { 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signedCert != null) 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return signedCert.clone(); 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException("Attribute name not " 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + "recognized or get() not allowed for the same: " + id); 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Set the requested attribute in the certificate. 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the attribute. 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param obj the value of the attribute. 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on invalid attribute identifier. 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException on encoding error of attribute. 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void set(String name, Object obj) 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException, IOException { 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check if immutable 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readOnly) 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("cannot over-write existing" 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + " certificate"); 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X509AttributeName attr = new X509AttributeName(name); 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String id = attr.getPrefix(); 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(id.equalsIgnoreCase(NAME))) { 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Invalid root of attribute name," 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + " expected [" + NAME + "], received " + id); 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski attr = new X509AttributeName(attr.getSuffix()); 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski id = attr.getPrefix(); 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (id.equalsIgnoreCase(INFO)) { 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (attr.getSuffix() == null) { 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(obj instanceof X509CertInfo)) { 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Attribute value should" 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + " be of type X509CertInfo."); 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski info = (X509CertInfo)obj; 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signedCert = null; //reset this as certificate data has changed 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski info.set(attr.getSuffix(), obj); 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signedCert = null; //reset this as certificate data has changed 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Attribute name not recognized or " + 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "set() not allowed for the same: " + id); 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Delete the requested attribute from the certificate. 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the attribute. 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateException on invalid attribute identifier. 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException on other errors. 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void delete(String name) 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException, IOException { 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check if immutable 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readOnly) 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("cannot over-write existing" 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + " certificate"); 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X509AttributeName attr = new X509AttributeName(name); 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String id = attr.getPrefix(); 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(id.equalsIgnoreCase(NAME))) { 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Invalid root of attribute name," 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + " expected [" 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + NAME + "], received " + id); 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski attr = new X509AttributeName(attr.getSuffix()); 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski id = attr.getPrefix(); 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (id.equalsIgnoreCase(INFO)) { 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (attr.getSuffix() != null) { 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski info = null; 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski info.delete(attr.getSuffix()); 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (id.equalsIgnoreCase(ALG_ID)) { 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski algId = null; 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (id.equalsIgnoreCase(SIGNATURE)) { 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signature = null; 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (id.equalsIgnoreCase(SIGNED_CERT)) { 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signedCert = null; 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Attribute name not recognized or " + 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "delete() not allowed for the same: " + id); 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return an enumeration of names of attributes existing within this 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * attribute. 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Enumeration<String> getElements() { 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski AttributeNameEnumeration elements = new AttributeNameEnumeration(); 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski elements.addElement(NAME + DOT + INFO); 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski elements.addElement(NAME + DOT + ALG_ID); 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski elements.addElement(NAME + DOT + SIGNATURE); 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski elements.addElement(NAME + DOT + SIGNED_CERT); 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return elements.elements(); 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return the name of this attribute. 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getName() { 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return(NAME); 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a printable representation of the certificate. This does not 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * contain all the information available to distinguish this from any 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * other certificate. The certificate must be fully constructed 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * before this function may be called. 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null || algId == null || signature == null) 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ""; 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuilder sb = new StringBuilder(); 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("[\n"); 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(info.toString() + "\n"); 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(" Algorithm: [" + algId.toString() + "]\n"); 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HexDumpEncoder encoder = new HexDumpEncoder(); 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append(" Signature:\n" + encoder.encodeBuffer(signature)); 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sb.append("\n]"); 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return sb.toString(); 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the strongly typed gets, as per java.security.cert.X509Certificate 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the publickey from this certificate. 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the publickey. 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PublicKey getPublicKey() { 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PublicKey key = (PublicKey)info.get(CertificateX509Key.NAME 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + DOT + CertificateX509Key.KEY); 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return key; 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the version number from the certificate. 85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the version number, i.e. 1, 2 or 3. 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getVersion() { 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int vers = ((Integer)info.get(CertificateVersion.NAME 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + DOT + CertificateVersion.VERSION)).intValue(); 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return vers+1; 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the serial number from the certificate. 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the serial number. 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public BigInteger getSerialNumber() { 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SerialNumber ser = getSerialNumberObject(); 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ser != null ? ser.getNumber() : null; 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the serial number from the certificate as 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a SerialNumber object. 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the serial number. 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SerialNumber getSerialNumberObject() { 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SerialNumber ser = (SerialNumber)info.get( 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateSerialNumber.NAME + DOT + 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateSerialNumber.NUMBER); 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ser; 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the subject distinguished name from the certificate. 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the subject name. 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Principal getSubjectDN() { 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 906d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root Principal subject = (Principal)info.get(X509CertInfo.SUBJECT + DOT + 907d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.DN_NAME); 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return subject; 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get subject name as X500Principal. Overrides implementation in 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * X509Certificate with a slightly more efficient version that is 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * also aware of X509CertImpl mutability. 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public X500Principal getSubjectX500Principal() { 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) { 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X500Principal subject = (X500Principal)info.get( 925d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.SUBJECT + DOT + 926d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root "x500principal"); 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return subject; 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the issuer distinguished name from the certificate. 93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the issuer name. 93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Principal getIssuerDN() { 93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 942d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root Principal issuer = (Principal)info.get(X509CertInfo.ISSUER + DOT + 943d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.DN_NAME); 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return issuer; 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get issuer name as X500Principal. Overrides implementation in 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * X509Certificate with a slightly more efficient version that is 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * also aware of X509CertImpl mutability. 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public X500Principal getIssuerX500Principal() { 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) { 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X500Principal issuer = (X500Principal)info.get( 961d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.ISSUER + DOT + 962d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root "x500principal"); 96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return issuer; 96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the notBefore date from the validity period of the certificate. 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the start date of the validity period. 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Date getNotBefore() { 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date d = (Date) info.get(CertificateValidity.NAME + DOT + 97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateValidity.NOT_BEFORE); 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return d; 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the notAfter date from the validity period of the certificate. 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the end date of the validity period. 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Date getNotAfter() { 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date d = (Date) info.get(CertificateValidity.NAME + DOT + 99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateValidity.NOT_AFTER); 99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return d; 99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the DER encoded certificate informations, the 100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>tbsCertificate</code> from this certificate. 100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This can be used to verify the signature independently. 100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the DER encoded certificate information. 100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception CertificateEncodingException if an encoding error occurs. 101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getTBSCertificate() throws CertificateEncodingException { 101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info != null) { 101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return info.getEncodedInfo(); 101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateEncodingException("Uninitialized certificate"); 101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the raw Signature bits from the certificate. 102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the signature. 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getSignature() { 102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signature == null) 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] dup = new byte[signature.length]; 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(signature, 0, dup, 0, dup.length); 102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return dup; 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the signature algorithm name for the certificate 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * signature algorithm. 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For example, the string "SHA-1/DSA" or "DSS". 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the signature algorithm name. 103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getSigAlgName() { 103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (algId == null) 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (algId.getName()); 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the signature algorithm OID string from the certificate. 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For example, the string "1.2.840.10040.4.3" 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the signature algorithm oid string. 104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getSigAlgOID() { 105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (algId == null) 105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier oid = algId.getOID(); 105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (oid.toString()); 105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the DER encoded signature algorithm parameters from this 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate's signature algorithm. 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the DER encoded signature algorithm parameters, or 106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * null if no parameters are present. 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getSigAlgParams() { 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (algId == null) 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return algId.getEncodedParams(); 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the Issuer Unique Identity from the certificate. 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the Issuer Unique Identity. 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean[] getIssuerUniqueID() { 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski UniqueIdentity id = (UniqueIdentity)info.get( 1084d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.ISSUER_ID); 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (id == null) 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (id.getId()); 108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the Subject Unique Identity from the certificate. 109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the Subject Unique Identity. 109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean[] getSubjectUniqueID() { 110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski UniqueIdentity id = (UniqueIdentity)info.get( 1104d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root X509CertInfo.SUBJECT_ID); 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (id == null) 110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (id.getId()); 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1114d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root public KeyIdentifier getAuthKeyId() { 1115d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root AuthorityKeyIdentifierExtension aki 1116d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root = getAuthorityKeyIdentifierExtension(); 1117d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root if (aki != null) { 1118d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root try { 1119d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root return (KeyIdentifier)aki.get( 1120d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root AuthorityKeyIdentifierExtension.KEY_ID); 1121d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } catch (IOException ioe) {} // not possible 1122d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 1123d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root return null; 1124d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 1125d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root 1126d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root /** 1127d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root * Returns the subject's key identifier, or null 1128d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root */ 1129d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root public KeyIdentifier getSubjectKeyId() { 1130d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root SubjectKeyIdentifierExtension ski = getSubjectKeyIdentifierExtension(); 1131d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root if (ski != null) { 1132d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root try { 1133d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root return (KeyIdentifier)ski.get( 1134d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root SubjectKeyIdentifierExtension.KEY_ID); 1135d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } catch (IOException ioe) {} // not possible 1136d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 1137d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root return null; 1138d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 1139d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get AuthorityKeyIdentifier extension 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return AuthorityKeyIdentifier object or null (if no such object 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in certificate) 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public AuthorityKeyIdentifierExtension getAuthorityKeyIdentifierExtension() 114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (AuthorityKeyIdentifierExtension) 114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.AuthorityKey_Id); 114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get BasicConstraints extension 115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return BasicConstraints object or null (if no such object in 115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate) 115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public BasicConstraintsExtension getBasicConstraintsExtension() { 115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (BasicConstraintsExtension) 115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.BasicConstraints_Id); 115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get CertificatePoliciesExtension 116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return CertificatePoliciesExtension or null (if no such object in 116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate) 116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CertificatePoliciesExtension getCertificatePoliciesExtension() { 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (CertificatePoliciesExtension) 116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.CertificatePolicies_Id); 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get ExtendedKeyUsage extension 117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return ExtendedKeyUsage extension object or null (if no such object 117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in certificate) 117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ExtendedKeyUsageExtension getExtendedKeyUsageExtension() { 117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (ExtendedKeyUsageExtension) 117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.ExtendedKeyUsage_Id); 117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get IssuerAlternativeName extension 118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return IssuerAlternativeName object or null (if no such object in 118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate) 118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public IssuerAlternativeNameExtension getIssuerAlternativeNameExtension() { 118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (IssuerAlternativeNameExtension) 118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.IssuerAlternativeName_Id); 118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get NameConstraints extension 119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return NameConstraints object or null (if no such object in certificate) 119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public NameConstraintsExtension getNameConstraintsExtension() { 119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (NameConstraintsExtension) 119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.NameConstraints_Id); 119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get PolicyConstraints extension 120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return PolicyConstraints object or null (if no such object in 120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate) 120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PolicyConstraintsExtension getPolicyConstraintsExtension() { 120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (PolicyConstraintsExtension) 120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.PolicyConstraints_Id); 120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get PolicyMappingsExtension extension 121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return PolicyMappingsExtension object or null (if no such object 121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in certificate) 121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PolicyMappingsExtension getPolicyMappingsExtension() { 121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (PolicyMappingsExtension) 121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.PolicyMappings_Id); 121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get PrivateKeyUsage extension 122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return PrivateKeyUsage object or null (if no such object in certificate) 122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PrivateKeyUsageExtension getPrivateKeyUsageExtension() { 122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (PrivateKeyUsageExtension) 122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.PrivateKeyUsage_Id); 122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get SubjectAlternativeName extension 123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return SubjectAlternativeName object or null (if no such object in 123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate) 123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SubjectAlternativeNameExtension getSubjectAlternativeNameExtension() 123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (SubjectAlternativeNameExtension) 123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.SubjectAlternativeName_Id); 123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get SubjectKeyIdentifier extension 124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return SubjectKeyIdentifier object or null (if no such object in 124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate) 124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SubjectKeyIdentifierExtension getSubjectKeyIdentifierExtension() { 124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (SubjectKeyIdentifierExtension) 124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.SubjectKey_Id); 124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get CRLDistributionPoints extension 125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return CRLDistributionPoints object or null (if no such object in 125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate) 125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CRLDistributionPointsExtension getCRLDistributionPointsExtension() { 125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (CRLDistributionPointsExtension) 125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.CRLDistributionPoints_Id); 125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return true if a critical extension is found that is 126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not supported, otherwise return false. 126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasUnsupportedCriticalExtension() { 126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) 126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions exts = (CertificateExtensions)info.get( 126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions.NAME); 127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (exts == null) 127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return exts.hasUnsupportedCriticalExtension(); 127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets a Set of the extension(s) marked CRITICAL in the 128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate. In the returned set, each extension is 128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * represented by its OID string. 128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a set of the extension oid strings in the 128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate that are marked critical. 128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Set<String> getCriticalExtensionOIDs() { 128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) { 128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions exts = (CertificateExtensions)info.get( 129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions.NAME); 129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (exts == null) { 129451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Set<String> extSet = new TreeSet<>(); 129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (Extension ex : exts.getAllExtensions()) { 129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ex.isCritical()) { 129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extSet.add(ex.getExtensionId().toString()); 130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return extSet; 130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets a Set of the extension(s) marked NON-CRITICAL in the 131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate. In the returned set, each extension is 131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * represented by its OID string. 131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 131351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a set of the extension oid strings in the 131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * certificate that are NOT marked critical. 131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 131651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Set<String> getNonCriticalExtensionOIDs() { 131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) { 131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 132051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions exts = (CertificateExtensions)info.get( 132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions.NAME); 132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (exts == null) { 132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Set<String> extSet = new TreeSet<>(); 132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (Extension ex : exts.getAllExtensions()) { 132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!ex.isCritical()) { 132951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extSet.add(ex.getExtensionId().toString()); 133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extSet.addAll(exts.getUnparseableExtensions().keySet()); 133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return extSet; 133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the extension identified by the given ObjectIdentifier 134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param oid the Object Identifier value for the extension. 134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return Extension or null if certificate does not contain this 134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * extension 134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Extension getExtension(ObjectIdentifier oid) { 134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) { 134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 135051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions extensions; 135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extensions = (CertificateExtensions)info.get(CertificateExtensions.NAME); 135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (CertificateException ce) { 135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (extensions == null) { 135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Extension ex = extensions.getExtension(oid.toString()); 136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ex != null) { 136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ex; 136351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (Extension ex2: extensions.getAllExtensions()) { 136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ex2.getExtensionId().equals((Object)oid)) { 136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski //XXXX May want to consider cloning this 136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ex2; 136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* no such extension in this certificate */ 137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Extension getUnparseableExtension(ObjectIdentifier oid) { 137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (info == null) { 138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions extensions; 138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 138551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extensions = (CertificateExtensions)info.get(CertificateExtensions.NAME); 138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (CertificateException ce) { 138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (extensions == null) { 139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 139151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return extensions.getUnparseableExtensions().get(oid.toString()); 139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the DER encoded extension identified by the given 140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * oid String. 140251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 140351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param oid the Object Identifier value for the extension. 140451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 140551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getExtensionValue(String oid) { 140651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 140751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier findOID = new ObjectIdentifier(oid); 140851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String extAlias = OIDMap.getName(findOID); 140951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Extension certExt = null; 141051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions exts = (CertificateExtensions)info.get( 141151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateExtensions.NAME); 141251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 141351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (extAlias == null) { // may be unknown 141451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // get the extensions, search thru' for this oid 141551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (exts == null) { 141651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 141751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 141851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 141951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (Extension ex : exts.getAllExtensions()) { 142051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier inCertOID = ex.getExtensionId(); 142151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inCertOID.equals((Object)findOID)) { 142251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski certExt = ex; 142351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 142451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 142551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 142651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { // there's sub-class that can handle this extension 142751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 142851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski certExt = (Extension)this.get(extAlias); 142951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (CertificateException e) { 143051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // get() throws an Exception instead of returning null, ignore 143151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 143251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 143351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (certExt == null) { 143451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (exts != null) { 143551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski certExt = exts.getUnparseableExtensions().get(oid); 143651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 143751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (certExt == null) { 143851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 143951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 144051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 144151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] extData = certExt.getExtensionValue(); 144251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (extData == null) { 144351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 144451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 144551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerOutputStream out = new DerOutputStream(); 144651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.putOctetString(extData); 144751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return out.toByteArray(); 144851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 144951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 145051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 145151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 145251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 145351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 145451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get a boolean array representing the bits of the KeyUsage extension, 145551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (oid = 2.5.29.15). 145651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the bit values of this extension as an array of booleans. 145751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 145851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean[] getKeyUsage() { 145951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 146051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String extAlias = OIDMap.getName(PKIXExtensions.KeyUsage_Id); 146151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (extAlias == null) 146251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 146351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 146451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski KeyUsageExtension certExt = (KeyUsageExtension)this.get(extAlias); 146551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (certExt == null) 146651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 146751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 146851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean[] ret = certExt.getBits(); 146951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ret.length < NUM_STANDARD_KEY_USAGE) { 147051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean[] usageBits = new boolean[NUM_STANDARD_KEY_USAGE]; 147151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(ret, 0, usageBits, 0, ret.length); 147251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ret = usageBits; 147351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 147451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ret; 147551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 147651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 147751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 147851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 147951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 148051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 148151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method are the overridden implementation of 148251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getExtendedKeyUsage method in X509Certificate in the Sun 148351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provider. It is better performance-wise since it returns cached 148451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * values. 148551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 148651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized List<String> getExtendedKeyUsage() 148751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateParsingException { 148851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readOnly && extKeyUsage != null) { 148951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return extKeyUsage; 149051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 149151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ExtendedKeyUsageExtension ext = getExtendedKeyUsageExtension(); 149251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ext == null) { 149351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 149451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 149551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extKeyUsage = 149651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Collections.unmodifiableList(ext.getExtendedKeyUsage()); 149751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return extKeyUsage; 149851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 149951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 150051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 150151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 150251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This static method is the default implementation of the 150351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getExtendedKeyUsage method in X509Certificate. A 150451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * X509Certificate provider generally should overwrite this to 150551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provide among other things caching for better performance. 150651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 150751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static List<String> getExtendedKeyUsage(X509Certificate cert) 150851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateParsingException { 150951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 151051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] ext = cert.getExtensionValue(EXTENDED_KEY_USAGE_OID); 151151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ext == null) 151251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 151351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue val = new DerValue(ext); 151451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] data = val.getOctetString(); 151551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 151651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ExtendedKeyUsageExtension ekuExt = 151751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new ExtendedKeyUsageExtension(Boolean.FALSE, data); 151851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableList(ekuExt.getExtendedKeyUsage()); 151951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 152051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException(ioe); 152151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 152451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 152551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the certificate constraints path length from the 152651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the critical BasicConstraints extension, (oid = 2.5.29.19). 152751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the length of the constraint. 152851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 152951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getBasicConstraints() { 153051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 153151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String extAlias = OIDMap.getName(PKIXExtensions.BasicConstraints_Id); 153251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (extAlias == null) 153351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 153451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski BasicConstraintsExtension certExt = 153551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (BasicConstraintsExtension)this.get(extAlias); 153651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (certExt == null) 153751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 153851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 153951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (((Boolean)certExt.get(BasicConstraintsExtension.IS_CA) 154051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ).booleanValue() == true) 154151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((Integer)certExt.get( 154251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski BasicConstraintsExtension.PATH_LEN)).intValue(); 154351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 154451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 154551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 154651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 154751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 154851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 154951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 155051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 155151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Converts a GeneralNames structure into an immutable Collection of 155251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * alternative names (subject or issuer) in the form required by 155351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #getSubjectAlternativeNames} or 155451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #getIssuerAlternativeNames}. 155551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 155651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param names the GeneralNames to be converted 155751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return an immutable Collection of alternative names 155851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 155951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Collection<List<?>> makeAltNames(GeneralNames names) { 156051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (names.isEmpty()) { 156151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.<List<?>>emptySet(); 156251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 156351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<List<?>> newNames = new ArrayList<>(); 156451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (GeneralName gname : names.names()) { 156551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GeneralNameInterface name = gname.getName(); 156651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<Object> nameEntry = new ArrayList<>(2); 156751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(Integer.valueOf(name.getType())); 156851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (name.getType()) { 156951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case GeneralNameInterface.NAME_RFC822: 157051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(((RFC822Name) name).getName()); 157151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 157251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case GeneralNameInterface.NAME_DNS: 157351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(((DNSName) name).getName()); 157451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 157551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case GeneralNameInterface.NAME_DIRECTORY: 157651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(((X500Name) name).getRFC2253Name()); 157751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 157851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case GeneralNameInterface.NAME_URI: 157951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(((URIName) name).getName()); 158051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 158151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case GeneralNameInterface.NAME_IP: 158251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 158351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(((IPAddressName) name).getName()); 158451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 158551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // IPAddressName in cert is bogus 158651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException("IPAddress cannot be parsed", 158751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ioe); 158851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 158951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 159051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case GeneralNameInterface.NAME_OID: 159151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(((OIDName) name).getOID().toString()); 159251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 159351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 159451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add DER encoded form 159551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerOutputStream derOut = new DerOutputStream(); 159651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 159751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.encode(derOut); 159851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 159951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // should not occur since name has already been decoded 160051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // from cert (this would indicate a bug in our code) 160151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException("name cannot be encoded", ioe); 160251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 160351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntry.add(derOut.toByteArray()); 160451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 160551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 160651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newNames.add(Collections.unmodifiableList(nameEntry)); 160751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 160851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableCollection(newNames); 160951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 161051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 161151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 161251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Checks a Collection of altNames and clones any name entries of type 161351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte []. 161451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ // only partially generified due to javac bug 161551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Collection<List<?>> cloneAltNames(Collection<List<?>> altNames) { 161651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean mustClone = false; 161751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (List<?> nameEntry : altNames) { 161851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nameEntry.get(1) instanceof byte[]) { 161951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // must clone names 162051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mustClone = true; 162151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 162251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 162351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mustClone) { 162451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<List<?>> namesCopy = new ArrayList<>(); 162551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (List<?> nameEntry : altNames) { 162651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object nameObject = nameEntry.get(1); 162751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nameObject instanceof byte[]) { 162851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<Object> nameEntryCopy = 162951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new ArrayList<>(nameEntry); 163051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameEntryCopy.set(1, ((byte[])nameObject).clone()); 163151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski namesCopy.add(Collections.unmodifiableList(nameEntryCopy)); 163251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 163351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski namesCopy.add(nameEntry); 163451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 163551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 163651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableCollection(namesCopy); 163751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 163851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return altNames; 163951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 164051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 164151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 164251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 164351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method are the overridden implementation of 164451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getSubjectAlternativeNames method in X509Certificate in the Sun 164551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provider. It is better performance-wise since it returns cached 164651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * values. 164751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 164851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized Collection<List<?>> getSubjectAlternativeNames() 164951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateParsingException { 165051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // return cached value if we can 165151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readOnly && subjectAlternativeNames != null) { 165251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cloneAltNames(subjectAlternativeNames); 165351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 165451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SubjectAlternativeNameExtension subjectAltNameExt = 165551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getSubjectAlternativeNameExtension(); 165651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (subjectAltNameExt == null) { 165751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 165851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 165951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GeneralNames names; 166051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 1661d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root names = subjectAltNameExt.get( 166251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SubjectAlternativeNameExtension.SUBJECT_NAME); 166351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 166451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // should not occur 166551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.<List<?>>emptySet(); 166651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 166751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski subjectAlternativeNames = makeAltNames(names); 166851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return subjectAlternativeNames; 166951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 167051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 167151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 167251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This static method is the default implementation of the 167351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getSubjectAlternaitveNames method in X509Certificate. A 167451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * X509Certificate provider generally should overwrite this to 167551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provide among other things caching for better performance. 167651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 167751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static Collection<List<?>> getSubjectAlternativeNames(X509Certificate cert) 167851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateParsingException { 167951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 168051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] ext = cert.getExtensionValue(SUBJECT_ALT_NAME_OID); 168151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ext == null) { 168251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 168351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 168451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue val = new DerValue(ext); 168551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] data = val.getOctetString(); 168651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 168751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SubjectAlternativeNameExtension subjectAltNameExt = 168851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new SubjectAlternativeNameExtension(Boolean.FALSE, 168951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data); 169051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 169151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GeneralNames names; 169251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 1693d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root names = subjectAltNameExt.get( 169451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SubjectAlternativeNameExtension.SUBJECT_NAME); 169551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 169651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // should not occur 169751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.<List<?>>emptySet(); 169851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 169951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return makeAltNames(names); 170051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 170151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException(ioe); 170251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 170351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 170451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 170551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 170651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method are the overridden implementation of 170751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getIssuerAlternativeNames method in X509Certificate in the Sun 170851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provider. It is better performance-wise since it returns cached 170951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * values. 171051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 171151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized Collection<List<?>> getIssuerAlternativeNames() 171251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateParsingException { 171351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // return cached value if we can 171451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readOnly && issuerAlternativeNames != null) { 171551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cloneAltNames(issuerAlternativeNames); 171651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 171751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IssuerAlternativeNameExtension issuerAltNameExt = 171851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getIssuerAlternativeNameExtension(); 171951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (issuerAltNameExt == null) { 172051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 172151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 172251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GeneralNames names; 172351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 1724d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root names = issuerAltNameExt.get( 172551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IssuerAlternativeNameExtension.ISSUER_NAME); 172651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 172751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // should not occur 172851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.<List<?>>emptySet(); 172951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 173051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski issuerAlternativeNames = makeAltNames(names); 173151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return issuerAlternativeNames; 173251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 173351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 173451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 173551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This static method is the default implementation of the 173651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getIssuerAlternaitveNames method in X509Certificate. A 173751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * X509Certificate provider generally should overwrite this to 173851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provide among other things caching for better performance. 173951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 174051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static Collection<List<?>> getIssuerAlternativeNames(X509Certificate cert) 174151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateParsingException { 174251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 174351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] ext = cert.getExtensionValue(ISSUER_ALT_NAME_OID); 174451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ext == null) { 174551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 174651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 174751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 174851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue val = new DerValue(ext); 174951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] data = val.getOctetString(); 175051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 175151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IssuerAlternativeNameExtension issuerAltNameExt = 175251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new IssuerAlternativeNameExtension(Boolean.FALSE, 175351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data); 175451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GeneralNames names; 175551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 1756d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root names = issuerAltNameExt.get( 175751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IssuerAlternativeNameExtension.ISSUER_NAME); 175851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 175951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // should not occur 176051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.<List<?>>emptySet(); 176151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 176251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return makeAltNames(names); 176351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 176451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException(ioe); 176551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 176651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 176751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 176851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public AuthorityInfoAccessExtension getAuthorityInfoAccessExtension() { 176951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (AuthorityInfoAccessExtension) 177051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getExtension(PKIXExtensions.AuthInfoAccess_Id); 177151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 177251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 177351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /************************************************************/ 177451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 177551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 177651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Cert is a SIGNED ASN.1 macro, a three elment sequence: 177751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 177851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * - Data to be signed (ToBeSigned) -- the "raw" cert 177951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * - Signature algorithm (SigAlgId) 178051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * - The signature bits 178151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 178251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This routine unmarshals the certificate, saving the signature 178351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parts away for later verification. 178451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 178551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void parse(DerValue val) 178651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException, IOException { 1787b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin parse( 1788b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin val, 1789b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin null // use re-encoded form of val as the encoded form 1790b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin ); 1791b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin } 1792b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin 1793b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin /* 1794b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * Cert is a SIGNED ASN.1 macro, a three elment sequence: 1795b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * 1796b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * - Data to be signed (ToBeSigned) -- the "raw" cert 1797b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * - Signature algorithm (SigAlgId) 1798b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * - The signature bits 1799b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * 1800b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * This routine unmarshals the certificate, saving the signature 1801b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin * parts away for later verification. 1802b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin */ 1803b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin private void parse(DerValue val, byte[] originalEncodedForm) 1804b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin throws CertificateException, IOException { 180551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check if can over write the certificate 180651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readOnly) 180751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException( 180851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "cannot over-write existing certificate"); 180951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 181051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (val.data == null || val.tag != DerValue.tag_Sequence) 181151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException( 181251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "invalid DER-encoded certificate data"); 181351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1814b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin signedCert = 1815b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin (originalEncodedForm != null) 1816b0d4380094f020749b77df93bf9d11b6fda8d483Alex Klyubin ? originalEncodedForm : val.toByteArray(); 181751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue[] seq = new DerValue[3]; 181851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 181951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski seq[0] = val.data.getDerValue(); 182051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski seq[1] = val.data.getDerValue(); 182151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski seq[2] = val.data.getDerValue(); 182251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 182351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (val.data.available() != 0) { 182451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException("signed overrun, bytes = " 182551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + val.data.available()); 182651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 182751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (seq[0].tag != DerValue.tag_Sequence) { 182851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException("signed fields invalid"); 182951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 183051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 183151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski algId = AlgorithmId.parse(seq[1]); 183251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signature = seq[2].getBitString(); 183351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 183451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (seq[1].data.available() != 0) { 183551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException("algid field overrun"); 183651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 183751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (seq[2].data.available() != 0) 183851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateParsingException("signed fields overrun"); 183951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 184051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The CertificateInfo 184151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski info = new X509CertInfo(seq[0]); 184251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 184351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the "inner" and "outer" signature algorithms must match 184451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski AlgorithmId infoSigAlg = (AlgorithmId)info.get( 184551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateAlgorithmId.NAME 184651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + DOT + 184751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CertificateAlgorithmId.ALGORITHM); 184851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (! algId.equals(infoSigAlg)) 184951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CertificateException("Signature algorithm mismatch"); 185051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readOnly = true; 185151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 185251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 185351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 185451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Extract the subject or issuer X500Principal from an X509Certificate. 185551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Parses the encoded form of the cert to preserve the principal's 185651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ASN.1 encoding. 185751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 185851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static X500Principal getX500Principal(X509Certificate cert, 185951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean getIssuer) throws Exception { 186051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] encoded = cert.getEncoded(); 186151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerInputStream derIn = new DerInputStream(encoded); 186251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue tbsCert = derIn.getSequence(3)[0]; 186351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerInputStream tbsIn = tbsCert.data; 186451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue tmp; 186551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmp = tbsIn.getDerValue(); 186651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // skip version number if present 186751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tmp.isContextSpecific((byte)0)) { 186851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmp = tbsIn.getDerValue(); 186951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 187051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // tmp always contains serial number now 187151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmp = tbsIn.getDerValue(); // skip signature 187251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmp = tbsIn.getDerValue(); // issuer 187351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (getIssuer == false) { 187451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmp = tbsIn.getDerValue(); // skip validity 187551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmp = tbsIn.getDerValue(); // subject 187651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 187751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] principalBytes = tmp.toByteArray(); 187851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new X500Principal(principalBytes); 187951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 188051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 188151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 188251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Extract the subject X500Principal from an X509Certificate. 188351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Called from java.security.cert.X509Certificate.getSubjectX500Principal(). 188451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 188551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static X500Principal getSubjectX500Principal(X509Certificate cert) { 188651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 188751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getX500Principal(cert, false); 188851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 188951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException("Could not parse subject", e); 189051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 189151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 189251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 189351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 189451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Extract the issuer X500Principal from an X509Certificate. 189551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Called from java.security.cert.X509Certificate.getIssuerX500Principal(). 189651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 189751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static X500Principal getIssuerX500Principal(X509Certificate cert) { 189851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 189951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getX500Principal(cert, true); 190051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 190151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException("Could not parse issuer", e); 190251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 190351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 190451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 190551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 190651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returned the encoding of the given certificate for internal use. 190751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Callers must guarantee that they neither modify it nor expose it 190851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to untrusted code. Uses getEncodedInternal() if the certificate 190951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is instance of X509CertImpl, getEncoded() otherwise. 191051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 191151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static byte[] getEncodedInternal(Certificate cert) 191251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateEncodingException { 191351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cert instanceof X509CertImpl) { 191451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((X509CertImpl)cert).getEncodedInternal(); 191551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 191651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cert.getEncoded(); 191751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 191851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 191951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 192051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 192151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Utility method to convert an arbitrary instance of X509Certificate 192251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to a X509CertImpl. Does a cast if possible, otherwise reparses 192351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the encoding. 192451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 192551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static X509CertImpl toImpl(X509Certificate cert) 192651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws CertificateException { 192751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cert instanceof X509CertImpl) { 192851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (X509CertImpl)cert; 192951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 193051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return X509Factory.intern(cert); 193151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 193251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 193351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 193451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 193551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Utility method to test if a certificate is self-issued. This is 193651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the case iff the subject and issuer X500Principals are equal. 193751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 193851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static boolean isSelfIssued(X509Certificate cert) { 193951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X500Principal subject = cert.getSubjectX500Principal(); 194051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski X500Principal issuer = cert.getIssuerX500Principal(); 194151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return subject.equals(issuer); 194251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 194351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 194451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 194551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Utility method to test if a certificate is self-signed. This is 194651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the case iff the subject and issuer X500Principals are equal 194751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * AND the certificate's subject public key can be used to verify 194851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the certificate. In case of exception, returns false. 194951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 195051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static boolean isSelfSigned(X509Certificate cert, 195151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String sigProvider) { 195251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isSelfIssued(cert)) { 195351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 195451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sigProvider == null) { 195551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cert.verify(cert.getPublicKey()); 195651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 195751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cert.verify(cert.getPublicKey(), sigProvider); 195851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 195951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 196051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 196151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // In case of exception, return false 196251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 196351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 196451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 196551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1966d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root 1967d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root private ConcurrentHashMap<String,String> fingerprints = 1968d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root new ConcurrentHashMap<>(2); 1969d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root 19706975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer// BEGIN Android-removed 19716975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer// public String getFingerprint(String algorithm) { 19726975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer// return fingerprints.computeIfAbsent(algorithm, 19738b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak// x -> getFingerprint(x, this)); 19746975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer// } 19756975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer// END Android-removed 1976d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root 1977d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root /** 1978d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root * Gets the requested finger print of the certificate. The result 1979d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root * only contains 0-9 and A-F. No small case, no colon. 1980d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root */ 19818b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak public static String getFingerprint(String algorithm, 19828b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak X509Certificate cert) { 1983d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root String fingerPrint = ""; 1984d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root try { 19858b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak byte[] encCertInfo = cert.getEncoded(); 19868b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak MessageDigest md = MessageDigest.getInstance(algorithm); 1987d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root byte[] digest = md.digest(encCertInfo); 1988d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root StringBuffer buf = new StringBuffer(); 1989d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root for (int i = 0; i < digest.length; i++) { 1990d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root byte2hex(digest[i], buf); 1991d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 1992d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root fingerPrint = buf.toString(); 1993d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } catch (NoSuchAlgorithmException | CertificateEncodingException e) { 1994d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root // ignored 1995d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 1996d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root return fingerPrint; 1997d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 1998d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root 1999d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root /** 2000d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root * Converts a byte to hex digit and writes to the supplied buffer 2001d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root */ 2002d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root private static void byte2hex(byte b, StringBuffer buf) { 2003d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', 2004d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 2005d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root int high = ((b & 0xf0) >> 4); 2006d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root int low = (b & 0x0f); 2007d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root buf.append(hexChars[high]); 2008d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root buf.append(hexChars[low]); 2009d7819a81f8b1b8d1a6b26329e4aa5f046afbf1f6Kenny Root } 201051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 2011