x500name.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,406 行 · 第 1/3 页

JAVA
1,406
字号
/* * @(#)X500Name.java	1.54 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program 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.    *    * This program 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 at /legal/license.txt).    *    * 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 or visit www.sun.com if you need additional   * information or have any questions.  * */package sun.security.x509;import java.lang.reflect.*;import java.io.IOException;import java.io.StringReader;import java.security.PrivilegedExceptionAction;import java.security.AccessController;import java.security.Principal;import java.util.*;import sun.security.util.*;import sun.security.pkcs.PKCS9Attribute;import javax.security.auth.x500.X500Principal;/** * Note:  As of 1.4, the public class, * javax.security.auth.x500.X500Principal, * should be used when parsing, generating, and comparing X.500 DNs. * This class contains other useful methods for checking name constraints * and retrieving DNs by keyword. * * <p> X.500 names are used to identify entities, such as those which are * identified by X.509 certificates.  They are world-wide, hierarchical, * and descriptive.  Entities can be identified by attributes, and in * some systems can be searched for according to those attributes. * <p> * The ASN.1 for this is: * <pre> * GeneralName ::= CHOICE { * .... *     directoryName                   [4]     Name, * .... * Name ::= CHOICE { *   RDNSequence } * * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName * * RelativeDistinguishedName ::= *   SET OF AttributeTypeAndValue * * AttributeTypeAndValue ::= SEQUENCE { *   type     AttributeType, *   value    AttributeValue } * * AttributeType ::= OBJECT IDENTIFIER * * AttributeValue ::= ANY DEFINED BY AttributeType * .... * DirectoryString ::= CHOICE { *       teletexString           TeletexString (SIZE (1..MAX)), *       printableString         PrintableString (SIZE (1..MAX)), *       universalString         UniversalString (SIZE (1..MAX)), *       utf8String              UTF8String (SIZE (1.. MAX)), *       bmpString               BMPString (SIZE (1..MAX)) } * </pre> * <p> * This specification requires only a subset of the name comparison * functionality specified in the X.500 series of specifications.  The * requirements for conforming implementations are as follows: * <ol TYPE=a> * <li>attribute values encoded in different types (e.g., *    PrintableString and BMPString) may be assumed to represent *    different strings; * <p> * <li>attribute values in types other than PrintableString are case *    sensitive (this permits matching of attribute values as binary *    objects); * <p> * <li>attribute values in PrintableString are not case sensitive *    (e.g., "Marianne Swanson" is the same as "MARIANNE SWANSON"); and * <p> * <li>attribute values in PrintableString are compared after *    removing leading and trailing white space and converting internal *    substrings of one or more consecutive white space characters to a *    single space. * </ol> * <p> * These name comparison rules permit a certificate user to validate * certificates issued using languages or encodings unfamiliar to the * certificate user. * <p> * In addition, implementations of this specification MAY use these * comparison rules to process unfamiliar attribute types for name * chaining. This allows implementations to process certificates with * unfamiliar attributes in the issuer name. * <p> * Note that the comparison rules defined in the X.500 series of * specifications indicate that the character sets used to encode data * in distinguished names are irrelevant.  The characters themselves are * compared without regard to encoding. Implementations of the profile * are permitted to use the comparison algorithm defined in the X.500 * series.  Such an implementation will recognize a superset of name * matches recognized by the algorithm specified above. * <p> * Note that instances of this class are immutable. * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.47 * @see GeneralName * @see GeneralNames * @see GeneralNameInterface */public class X500Name implements GeneralNameInterface, Principal {        private String dn; // roughly RFC 1779 DN, or null    private String rfc1779Dn; // RFC 1779 compliant DN, or null    private String rfc2253Dn; // RFC 2253 DN, or null    private String canonicalDn; // canonical RFC 2253 DN or null    private RDN[] names;	// RDNs (never null)    private X500Principal x500Principal;    private byte[] encoded;        // cached immutable list of the RDNs and all the AVAs    private volatile List rdnList, allAvaList;    /**     * Constructs a name from a conventionally formatted string, such     * as "CN=Dave, OU=JavaSoft, O=Sun Microsystems, C=US".     * (RFC 1779 or RFC 2253 style).     *     * @param DN X.500 Distinguished Name     */    public X500Name(String dname) throws IOException {	parseDN(dname);    }        /**     * Constructs a name from a string formatted according to format.     * Currently, the formats DEFAULT and RFC2253 are supported.     * DEFAULT is the default format used by the X500Name(String)     * constructor. RFC2253 is format strictly according to RFC2253     * without extensions.     *     * @param DN X.500 Distinguished Name     */    public X500Name(String dname, String format) throws IOException {        if (dname == null) {	    throw new NullPointerException("Name must not be null");	}        if (format.equalsIgnoreCase("RFC2253")) { 	    parseRFC2253DN(dname);	} else if (format.equalsIgnoreCase("DEFAULT")) {	    parseDN(dname);	} else {	    throw new IOException("Unsupported format " + format);	}    }        /**     * Constructs a name from fields common in enterprise application     * environments.     *     * <P><EM><STRONG>NOTE:</STRONG>  The behaviour when any of     * these strings contain characters outside the ASCII range     * is unspecified in currently relevant standards.</EM>     *     * @param commonName common name of a person, e.g. "Vivette Davis"     * @param organizationUnit small organization name, e.g. "Purchasing"     * @param organizationName large organization name, e.g. "Onizuka, Inc."     * @param country two letter country code, e.g. "CH"     */    public X500Name(String commonName, String organizationUnit,                     String organizationName, String country)    throws IOException {	names = new RDN[4];	/*	 * NOTE:  it's only on output that little-endian	 * ordering is used.	 */	names[3] = new RDN(1);	names[3].assertion[0] = new AVA(commonName_oid,		new DerValue(commonName));	names[2] = new RDN(1);	names[2].assertion[0] = new AVA(orgUnitName_oid,		new DerValue(organizationUnit));	names[1] = new RDN(1);	names[1].assertion[0] = new AVA(orgName_oid,		new DerValue(organizationName));	names[0] = new RDN(1);	names[0].assertion[0] = new AVA(countryName_oid,		new DerValue(country));    }    /**     * Constructs a name from fields common in Internet application     * environments.     *     * <P><EM><STRONG>NOTE:</STRONG>  The behaviour when any of     * these strings contain characters outside the ASCII range     * is unspecified in currently relevant standards.</EM>     *     * @param commonName common name of a person, e.g. "Vivette Davis"     * @param organizationUnit small organization name, e.g. "Purchasing"     * @param organizationName large organization name, e.g. "Onizuka, Inc."     * @param localityName locality (city) name, e.g. "Palo Alto"     * @param stateName state name, e.g. "California"     * @param country two letter country code, e.g. "CH"     */    public X500Name(String commonName, String organizationUnit,                    String organizationName, String localityName,                    String stateName, String country)    throws IOException {	names = new RDN[6];	/*	 * NOTE:  it's only on output that little-endian	 * ordering is used.	 */	names[5] = new RDN(1);	names[5].assertion[0] = new AVA(commonName_oid,		new DerValue(commonName));	names[4] = new RDN(1);	names[4].assertion[0] = new AVA(orgUnitName_oid,		new DerValue(organizationUnit));	names[3] = new RDN(1);	names[3].assertion[0] = new AVA(orgName_oid,		new DerValue(organizationName));	names[2] = new RDN(1);	names[2].assertion[0] = new AVA(localityName_oid,		new DerValue(localityName));	names[1] = new RDN(1);	names[1].assertion[0] = new AVA(stateName_oid,		new DerValue(stateName));	names[0] = new RDN(1);	names[0].assertion[0] = new AVA(countryName_oid,		new DerValue(country));    }    /**     * Constructs a name from an array of relative distinguished names     *     * @param rdnArray array of relative distinguished names     * @throws IOException on error     */    public X500Name(RDN[] rdnArray) throws IOException {        if (rdnArray == null) {            names = new RDN[0];	} else {	    names = (RDN[])rdnArray.clone();	    for (int i = 0; i < names.length; i++) {		if (names[i] == null) {		    throw new IOException("Cannot create an X500Name");		}	 	    }	}    }    /**     * Constructs a name from an ASN.1 encoded value.  The encoding     * of the name in the stream uses DER (a BER/1 subset).     *     * @param value a DER-encoded value holding an X.500 name.     */    public X500Name(DerValue value) throws IOException {	//Note that toDerInputStream uses only the buffer (data) and not	//the tag, so an empty SEQUENCE (OF) will yield an empty DerInputStream	this(value.toDerInputStream());    }    /**     * Constructs a name from an ASN.1 encoded input stream.  The encoding     * of the name in the stream uses DER (a BER/1 subset).     *     * @param in DER-encoded data holding an X.500 name.     */    public X500Name(DerInputStream in) throws IOException {	parseDER(in);    }    /**     *  Constructs a name from an ASN.1 encoded byte array.     *     * @param name DER-encoded byte array holding an X.500 name.     */    public X500Name(byte[] name) throws IOException {        DerInputStream in = new DerInputStream(name);        parseDER(in);    }        /**     * Return an immutable List of all RDNs in this X500Name.     */    public List rdns() {	List list = rdnList;	if (list == null) {	    list = Collections.unmodifiableList(Arrays.asList(names));	    rdnList = list;	}	return list;    }        /**     * Return the number of RDNs in this X500Name.     */    public int size() {	return names.length;    }        /**     * Return an immutable List of the the AVAs contained in all the     * RDNs of this X500Name.     */    public List allAvas() {	List list = allAvaList;	if (list == null) {	    list = new ArrayList();	    for (int i = 0; i < names.length; i++) {		list.addAll(names[i].avas());	    }	}	return list;    }        /**     * Return the total number of AVAs contained in all the RDNs of     * this X500Name.     */    public int avaSize() {	return allAvas().size();    }        /**     * Return whether this X500Name is empty. An X500Name is not empty     * if it has at least one RDN containing at least one AVA.     */    public boolean isEmpty() {	int n = names.length;	if (n == 0) {	    return true;	}	for (int i = 0; i < n; i++) {	    if (names[i].assertion.length != 0) {		return false;	    }	}	return true;    }    /**     * Calculates a hash code value for the object.  Objects     * which are equal will also have the same hashcode.     */    public int hashCode() {	return getRFC2253CanonicalName().hashCode();    }    /**     * Compares this name with another, for equality.     *     * @return true iff the names are identical.     */    public boolean equals(Object obj) {	if (this == obj) {	    return true;	}	if (obj instanceof X500Name == false) {	    return false;	}	X500Name other = (X500Name)obj;	// if we already have the canonical forms, compare now	if ((this.canonicalDn != null) && (other.canonicalDn != null)) {	    return this.canonicalDn.equals(other.canonicalDn);	}	// quick check that number of RDNs and AVAs match before canonicalizing	int n = this.names.length;	if (n != other.names.length) {	    return false;	}	for (int i = 0; i < n; i++) {	    RDN r1 = this.names[i];	    RDN r2 = other.names[i];	    if (r1.assertion.length != r2.assertion.length) {		return false;	    }	}	// definite check via canonical form	String thisCanonical = this.getRFC2253CanonicalName();	String otherCanonical = other.getRFC2253CanonicalName();	return thisCanonical.equals(otherCanonical);    }    /*     * Returns the name component as a Java string, regardless of its     * encoding restrictions.     */    private String getString(DerValue attribute) throws IOException {        if (attribute == null)            return null;	String	value = attribute.getAsString();	if (value == null)	    throw new IOException("not a DER string encoding, "		    + attribute.tag);	else	    return value;    }    /**     * Return type of GeneralName.     */    public int getType() {        return (GeneralNameInterface.NAME_DIRECTORY);    }    /**     * Returns a "Country" name component.  If more than one     * such attribute exists, the topmost one is returned.     *     * @return "C=" component of the name, if any.     */    public String getCountry() throws IOException {	DerValue attr = findAttribute(countryName_oid);	return getString(attr);    }    /**     * Returns an "Organization" name component.  If more than     * one such attribute exists, the topmost one is returned.     *     * @return "O=" component of the name, if any.     */    public String getOrganization() throws IOException {	DerValue attr = findAttribute(orgName_oid);	return getString(attr);    }    /**     * Returns an "Organizational Unit" name component.  If more     * than one such attribute exists, the topmost one is returned.     *     * @return "OU=" component of the name, if any.     */    public String getOrganizationalUnit() throws IOException {	DerValue attr = findAttribute(orgUnitName_oid);	return getString(attr);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?