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 + -
显示快捷键?