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