0N/A/*
2362N/A * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.security.cert;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.security.PublicKey;
0N/A
0N/Aimport javax.security.auth.x500.X500Principal;
0N/A
0N/Aimport sun.security.x509.NameConstraintsExtension;
0N/Aimport sun.security.x509.X500Name;
0N/A
0N/A/**
0N/A * A trust anchor or most-trusted Certification Authority (CA).
0N/A * <p>
0N/A * This class represents a "most-trusted CA", which is used as a trust anchor
0N/A * for validating X.509 certification paths. A most-trusted CA includes the
0N/A * public key of the CA, the CA's name, and any constraints upon the set of
0N/A * paths which may be validated using this key. These parameters can be
0N/A * specified in the form of a trusted <code>X509Certificate</code> or as
0N/A * individual parameters.
0N/A * <p>
0N/A * <b>Concurrent Access</b>
0N/A * <p>
0N/A * <p>All <code>TrustAnchor</code> objects must be immutable and
0N/A * thread-safe. That is, multiple threads may concurrently invoke the
0N/A * methods defined in this class on a single <code>TrustAnchor</code>
0N/A * object (or more than one) with no ill effects. Requiring
0N/A * <code>TrustAnchor</code> objects to be immutable and thread-safe
0N/A * allows them to be passed around to various pieces of code without
0N/A * worrying about coordinating access. This stipulation applies to all
0N/A * public fields and methods of this class and any added or overridden
0N/A * by subclasses.
0N/A *
0N/A * @see PKIXParameters#PKIXParameters(Set)
0N/A * @see PKIXBuilderParameters#PKIXBuilderParameters(Set, CertSelector)
0N/A *
0N/A * @since 1.4
0N/A * @author Sean Mullan
0N/A */
0N/Apublic class TrustAnchor {
0N/A
0N/A private final PublicKey pubKey;
0N/A private final String caName;
0N/A private final X500Principal caPrincipal;
0N/A private final X509Certificate trustedCert;
0N/A private byte[] ncBytes;
0N/A private NameConstraintsExtension nc;
0N/A
0N/A /**
0N/A * Creates an instance of <code>TrustAnchor</code> with the specified
0N/A * <code>X509Certificate</code> and optional name constraints, which
0N/A * are intended to be used as additional constraints when validating
0N/A * an X.509 certification path.
0N/A * <p>
0N/A * The name constraints are specified as a byte array. This byte array
0N/A * should contain the DER encoded form of the name constraints, as they
0N/A * would appear in the NameConstraints structure defined in
0N/A * <a href="http://www.ietf.org/rfc/rfc3280">RFC 3280</a>
0N/A * and X.509. The ASN.1 definition of this structure appears below.
0N/A *
0N/A * <pre><code>
0N/A * NameConstraints ::= SEQUENCE {
0N/A * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
0N/A * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
0N/A *
0N/A * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
0N/A *
0N/A * GeneralSubtree ::= SEQUENCE {
0N/A * base GeneralName,
0N/A * minimum [0] BaseDistance DEFAULT 0,
0N/A * maximum [1] BaseDistance OPTIONAL }
0N/A *
0N/A * BaseDistance ::= INTEGER (0..MAX)
0N/A *
0N/A * GeneralName ::= CHOICE {
0N/A * otherName [0] OtherName,
0N/A * rfc822Name [1] IA5String,
0N/A * dNSName [2] IA5String,
0N/A * x400Address [3] ORAddress,
0N/A * directoryName [4] Name,
0N/A * ediPartyName [5] EDIPartyName,
0N/A * uniformResourceIdentifier [6] IA5String,
0N/A * iPAddress [7] OCTET STRING,
0N/A * registeredID [8] OBJECT IDENTIFIER}
0N/A * </code></pre>
0N/A * <p>
0N/A * Note that the name constraints byte array supplied is cloned to protect
0N/A * against subsequent modifications.
0N/A *
0N/A * @param trustedCert a trusted <code>X509Certificate</code>
0N/A * @param nameConstraints a byte array containing the ASN.1 DER encoding of
0N/A * a NameConstraints extension to be used for checking name constraints.
0N/A * Only the value of the extension is included, not the OID or criticality
0N/A * flag. Specify <code>null</code> to omit the parameter.
0N/A * @throws IllegalArgumentException if the name constraints cannot be
0N/A * decoded
0N/A * @throws NullPointerException if the specified
0N/A * <code>X509Certificate</code> is <code>null</code>
0N/A */
0N/A public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)
0N/A {
0N/A if (trustedCert == null)
0N/A throw new NullPointerException("the trustedCert parameter must " +
0N/A "be non-null");
0N/A this.trustedCert = trustedCert;
0N/A this.pubKey = null;
0N/A this.caName = null;
0N/A this.caPrincipal = null;
0N/A setNameConstraints(nameConstraints);
0N/A }
0N/A
0N/A /**
0N/A * Creates an instance of <code>TrustAnchor</code> where the
0N/A * most-trusted CA is specified as an X500Principal and public key.
0N/A * Name constraints are an optional parameter, and are intended to be used
0N/A * as additional constraints when validating an X.509 certification path.
0N/A * <p>
0N/A * The name constraints are specified as a byte array. This byte array
0N/A * contains the DER encoded form of the name constraints, as they
0N/A * would appear in the NameConstraints structure defined in RFC 3280
0N/A * and X.509. The ASN.1 notation for this structure is supplied in the
0N/A * documentation for
0N/A * {@link #TrustAnchor(X509Certificate, byte[])
0N/A * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
0N/A * <p>
0N/A * Note that the name constraints byte array supplied here is cloned to
0N/A * protect against subsequent modifications.
0N/A *
0N/A * @param caPrincipal the name of the most-trusted CA as X500Principal
0N/A * @param pubKey the public key of the most-trusted CA
0N/A * @param nameConstraints a byte array containing the ASN.1 DER encoding of
0N/A * a NameConstraints extension to be used for checking name constraints.
0N/A * Only the value of the extension is included, not the OID or criticality
0N/A * flag. Specify <code>null</code> to omit the parameter.
0N/A * @throws NullPointerException if the specified <code>caPrincipal</code> or
0N/A * <code>pubKey</code> parameter is <code>null</code>
0N/A * @since 1.5
0N/A */
0N/A public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey,
0N/A byte[] nameConstraints) {
0N/A if ((caPrincipal == null) || (pubKey == null)) {
0N/A throw new NullPointerException();
0N/A }
0N/A this.trustedCert = null;
0N/A this.caPrincipal = caPrincipal;
0N/A this.caName = caPrincipal.getName();
0N/A this.pubKey = pubKey;
0N/A setNameConstraints(nameConstraints);
0N/A }
0N/A
0N/A /**
0N/A * Creates an instance of <code>TrustAnchor</code> where the
0N/A * most-trusted CA is specified as a distinguished name and public key.
0N/A * Name constraints are an optional parameter, and are intended to be used
0N/A * as additional constraints when validating an X.509 certification path.
0N/A * <p>
0N/A * The name constraints are specified as a byte array. This byte array
0N/A * contains the DER encoded form of the name constraints, as they
0N/A * would appear in the NameConstraints structure defined in RFC 3280
0N/A * and X.509. The ASN.1 notation for this structure is supplied in the
0N/A * documentation for
0N/A * {@link #TrustAnchor(X509Certificate, byte[])
0N/A * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
0N/A * <p>
0N/A * Note that the name constraints byte array supplied here is cloned to
0N/A * protect against subsequent modifications.
0N/A *
0N/A * @param caName the X.500 distinguished name of the most-trusted CA in
0N/A * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
0N/A * <code>String</code> format
0N/A * @param pubKey the public key of the most-trusted CA
0N/A * @param nameConstraints a byte array containing the ASN.1 DER encoding of
0N/A * a NameConstraints extension to be used for checking name constraints.
0N/A * Only the value of the extension is included, not the OID or criticality
0N/A * flag. Specify <code>null</code> to omit the parameter.
0N/A * @throws IllegalArgumentException if the specified <code>
0N/A * caName</code> parameter is empty <code>(caName.length() == 0)</code>
0N/A * or incorrectly formatted or the name constraints cannot be decoded
0N/A * @throws NullPointerException if the specified <code>caName</code> or
0N/A * <code>pubKey</code> parameter is <code>null</code>
0N/A */
0N/A public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)
0N/A {
0N/A if (pubKey == null)
0N/A throw new NullPointerException("the pubKey parameter must be " +
0N/A "non-null");
0N/A if (caName == null)
0N/A throw new NullPointerException("the caName parameter must be " +
0N/A "non-null");
0N/A if (caName.length() == 0)
0N/A throw new IllegalArgumentException("the caName " +
0N/A "parameter must be a non-empty String");
0N/A // check if caName is formatted correctly
0N/A this.caPrincipal = new X500Principal(caName);
0N/A this.pubKey = pubKey;
0N/A this.caName = caName;
0N/A this.trustedCert = null;
0N/A setNameConstraints(nameConstraints);
0N/A }
0N/A
0N/A /**
0N/A * Returns the most-trusted CA certificate.
0N/A *
0N/A * @return a trusted <code>X509Certificate</code> or <code>null</code>
0N/A * if the trust anchor was not specified as a trusted certificate
0N/A */
0N/A public final X509Certificate getTrustedCert() {
0N/A return this.trustedCert;
0N/A }
0N/A
0N/A /**
0N/A * Returns the name of the most-trusted CA as an X500Principal.
0N/A *
0N/A * @return the X.500 distinguished name of the most-trusted CA, or
0N/A * <code>null</code> if the trust anchor was not specified as a trusted
0N/A * public key and name or X500Principal pair
0N/A * @since 1.5
0N/A */
0N/A public final X500Principal getCA() {
0N/A return this.caPrincipal;
0N/A }
0N/A
0N/A /**
0N/A * Returns the name of the most-trusted CA in RFC 2253 <code>String</code>
0N/A * format.
0N/A *
0N/A * @return the X.500 distinguished name of the most-trusted CA, or
0N/A * <code>null</code> if the trust anchor was not specified as a trusted
0N/A * public key and name or X500Principal pair
0N/A */
0N/A public final String getCAName() {
0N/A return this.caName;
0N/A }
0N/A
0N/A /**
0N/A * Returns the public key of the most-trusted CA.
0N/A *
0N/A * @return the public key of the most-trusted CA, or <code>null</code>
0N/A * if the trust anchor was not specified as a trusted public key and name
0N/A * or X500Principal pair
0N/A */
0N/A public final PublicKey getCAPublicKey() {
0N/A return this.pubKey;
0N/A }
0N/A
0N/A /**
0N/A * Decode the name constraints and clone them if not null.
0N/A */
0N/A private void setNameConstraints(byte[] bytes) {
0N/A if (bytes == null) {
0N/A ncBytes = null;
0N/A nc = null;
0N/A } else {
28N/A ncBytes = bytes.clone();
0N/A // validate DER encoding
0N/A try {
0N/A nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
0N/A } catch (IOException ioe) {
0N/A IllegalArgumentException iae =
0N/A new IllegalArgumentException(ioe.getMessage());
0N/A iae.initCause(ioe);
0N/A throw iae;
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the name constraints parameter. The specified name constraints
0N/A * are associated with this trust anchor and are intended to be used
0N/A * as additional constraints when validating an X.509 certification path.
0N/A * <p>
0N/A * The name constraints are returned as a byte array. This byte array
0N/A * contains the DER encoded form of the name constraints, as they
0N/A * would appear in the NameConstraints structure defined in RFC 3280
0N/A * and X.509. The ASN.1 notation for this structure is supplied in the
0N/A * documentation for
0N/A * {@link #TrustAnchor(X509Certificate, byte[])
0N/A * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
0N/A * <p>
0N/A * Note that the byte array returned is cloned to protect against
0N/A * subsequent modifications.
0N/A *
0N/A * @return a byte array containing the ASN.1 DER encoding of
0N/A * a NameConstraints extension used for checking name constraints,
0N/A * or <code>null</code> if not set.
0N/A */
0N/A public final byte [] getNameConstraints() {
28N/A return ncBytes == null ? null : ncBytes.clone();
0N/A }
0N/A
0N/A /**
0N/A * Returns a formatted string describing the <code>TrustAnchor</code>.
0N/A *
0N/A * @return a formatted string describing the <code>TrustAnchor</code>
0N/A */
0N/A public String toString() {
0N/A StringBuffer sb = new StringBuffer();
0N/A sb.append("[\n");
0N/A if (pubKey != null) {
0N/A sb.append(" Trusted CA Public Key: " + pubKey.toString() + "\n");
0N/A sb.append(" Trusted CA Issuer Name: "
0N/A + String.valueOf(caName) + "\n");
0N/A } else {
0N/A sb.append(" Trusted CA cert: " + trustedCert.toString() + "\n");
0N/A }
0N/A if (nc != null)
0N/A sb.append(" Name Constraints: " + nc.toString() + "\n");
0N/A return sb.toString();
0N/A }
0N/A}