/* * Copyright (c) 2001, 2008, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.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 = 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 : 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(); }}
/*
* Copyright (c) 2001, 2008, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.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 = 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 : 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();
}
}