mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8187443: Forest Consolidation: Move files to unified layout
Reviewed-by: darcy, ihse
This commit is contained in:
parent
270fe13182
commit
3789983e89
56923 changed files with 3 additions and 15727 deletions
|
@ -0,0 +1,513 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2014, 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 javax.security.auth.x500;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import sun.security.x509.X500Name;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* <p> This class represents an X.500 {@code Principal}.
|
||||
* {@code X500Principal}s are represented by distinguished names such as
|
||||
* "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US".
|
||||
*
|
||||
* <p> This class can be instantiated by using a string representation
|
||||
* of the distinguished name, or by using the ASN.1 DER encoded byte
|
||||
* representation of the distinguished name. The current specification
|
||||
* for the string representation of a distinguished name is defined in
|
||||
* <a href="http://tools.ietf.org/html/rfc2253">RFC 2253: Lightweight
|
||||
* Directory Access Protocol (v3): UTF-8 String Representation of
|
||||
* Distinguished Names</a>. This class, however, accepts string formats from
|
||||
* both RFC 2253 and <a href="http://tools.ietf.org/html/rfc1779">RFC 1779:
|
||||
* A String Representation of Distinguished Names</a>, and also recognizes
|
||||
* attribute type keywords whose OIDs (Object Identifiers) are defined in
|
||||
* <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
|
||||
* Public Key Infrastructure Certificate and CRL Profile</a>.
|
||||
*
|
||||
* <p> The string representation for this {@code X500Principal}
|
||||
* can be obtained by calling the {@code getName} methods.
|
||||
*
|
||||
* <p> Note that the {@code getSubjectX500Principal} and
|
||||
* {@code getIssuerX500Principal} methods of
|
||||
* {@code X509Certificate} return X500Principals representing the
|
||||
* issuer and subject fields of the certificate.
|
||||
*
|
||||
* @see java.security.cert.X509Certificate
|
||||
* @since 1.4
|
||||
*/
|
||||
public final class X500Principal implements Principal, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -500463348111345721L;
|
||||
|
||||
/**
|
||||
* RFC 1779 String format of Distinguished Names.
|
||||
*/
|
||||
public static final String RFC1779 = "RFC1779";
|
||||
/**
|
||||
* RFC 2253 String format of Distinguished Names.
|
||||
*/
|
||||
public static final String RFC2253 = "RFC2253";
|
||||
/**
|
||||
* Canonical String format of Distinguished Names.
|
||||
*/
|
||||
public static final String CANONICAL = "CANONICAL";
|
||||
|
||||
/**
|
||||
* The X500Name representing this principal.
|
||||
*
|
||||
* NOTE: this field is reflectively accessed from within X500Name.
|
||||
*/
|
||||
private transient X500Name thisX500Name;
|
||||
|
||||
/**
|
||||
* Creates an X500Principal by wrapping an X500Name.
|
||||
*
|
||||
* NOTE: The constructor is package private. It is intended to be accessed
|
||||
* using privileged reflection from classes in sun.security.*.
|
||||
* Currently referenced from sun.security.x509.X500Name.asX500Principal().
|
||||
*/
|
||||
X500Principal(X500Name x500Name) {
|
||||
thisX500Name = x500Name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from a string representation of
|
||||
* an X.500 distinguished name (ex:
|
||||
* "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US").
|
||||
* The distinguished name must be specified using the grammar defined in
|
||||
* RFC 1779 or RFC 2253 (either format is acceptable).
|
||||
*
|
||||
* <p>This constructor recognizes the attribute type keywords
|
||||
* defined in RFC 1779 and RFC 2253
|
||||
* (and listed in {@link #getName(String format) getName(String format)}),
|
||||
* as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
|
||||
* GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object
|
||||
* Identifiers (OIDs) are defined in RFC 5280.
|
||||
* Any other attribute type must be specified as an OID.
|
||||
*
|
||||
* <p>This implementation enforces a more restrictive OID syntax than
|
||||
* defined in RFC 1779 and 2253. It uses the more correct syntax defined in
|
||||
* <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
|
||||
* specifies that OIDs contain at least 2 digits:
|
||||
*
|
||||
* <p>{@code numericoid = number 1*( DOT number ) }
|
||||
*
|
||||
* @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
|
||||
* @exception NullPointerException if the {@code name}
|
||||
* is {@code null}
|
||||
* @exception IllegalArgumentException if the {@code name}
|
||||
* is improperly specified
|
||||
*/
|
||||
public X500Principal(String name) {
|
||||
this(name, Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from a string representation of
|
||||
* an X.500 distinguished name (ex:
|
||||
* "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US").
|
||||
* The distinguished name must be specified using the grammar defined in
|
||||
* RFC 1779 or RFC 2253 (either format is acceptable).
|
||||
*
|
||||
* <p> This constructor recognizes the attribute type keywords specified
|
||||
* in {@link #X500Principal(String)} and also recognizes additional
|
||||
* keywords that have entries in the {@code keywordMap} parameter.
|
||||
* Keyword entries in the keywordMap take precedence over the default
|
||||
* keywords recognized by {@code X500Principal(String)}. Keywords
|
||||
* MUST be specified in all upper-case, otherwise they will be ignored.
|
||||
* Improperly specified keywords are ignored; however if a keyword in the
|
||||
* name maps to an improperly specified Object Identifier (OID), an
|
||||
* {@code IllegalArgumentException} is thrown. It is permissible to
|
||||
* have 2 different keywords that map to the same OID.
|
||||
*
|
||||
* <p>This implementation enforces a more restrictive OID syntax than
|
||||
* defined in RFC 1779 and 2253. It uses the more correct syntax defined in
|
||||
* <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
|
||||
* specifies that OIDs contain at least 2 digits:
|
||||
*
|
||||
* <p>{@code numericoid = number 1*( DOT number ) }
|
||||
*
|
||||
* @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
|
||||
* @param keywordMap an attribute type keyword map, where each key is a
|
||||
* keyword String that maps to a corresponding object identifier in String
|
||||
* form (a sequence of nonnegative integers separated by periods). The map
|
||||
* may be empty but never {@code null}.
|
||||
* @exception NullPointerException if {@code name} or
|
||||
* {@code keywordMap} is {@code null}
|
||||
* @exception IllegalArgumentException if the {@code name} is
|
||||
* improperly specified or a keyword in the {@code name} maps to an
|
||||
* OID that is not in the correct form
|
||||
* @since 1.6
|
||||
*/
|
||||
public X500Principal(String name, Map<String, String> keywordMap) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
("provided.null.name"));
|
||||
}
|
||||
if (keywordMap == null) {
|
||||
throw new NullPointerException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
("provided.null.keyword.map"));
|
||||
}
|
||||
|
||||
try {
|
||||
thisX500Name = new X500Name(name, keywordMap);
|
||||
} catch (Exception e) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input name: " + name);
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from a distinguished name in
|
||||
* ASN.1 DER encoded form. The ASN.1 notation for this structure is as
|
||||
* follows.
|
||||
* <pre>{@code
|
||||
* Name ::= CHOICE {
|
||||
* RDNSequence }
|
||||
*
|
||||
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET SIZE (1 .. MAX) 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>
|
||||
*
|
||||
* @param name a byte array containing the distinguished name in ASN.1
|
||||
* DER encoded form
|
||||
* @throws IllegalArgumentException if an encoding error occurs
|
||||
* (incorrect form for DN)
|
||||
*/
|
||||
public X500Principal(byte[] name) {
|
||||
try {
|
||||
thisX500Name = new X500Name(name);
|
||||
} catch (Exception e) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input name");
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from an {@code InputStream}
|
||||
* containing the distinguished name in ASN.1 DER encoded form.
|
||||
* The ASN.1 notation for this structure is supplied in the
|
||||
* documentation for
|
||||
* {@link #X500Principal(byte[] name) X500Principal(byte[] name)}.
|
||||
*
|
||||
* <p> The read position of the input stream is positioned
|
||||
* to the next available byte after the encoded distinguished name.
|
||||
*
|
||||
* @param is an {@code InputStream} containing the distinguished
|
||||
* name in ASN.1 DER encoded form
|
||||
*
|
||||
* @exception NullPointerException if the {@code InputStream}
|
||||
* is {@code null}
|
||||
* @exception IllegalArgumentException if an encoding error occurs
|
||||
* (incorrect form for DN)
|
||||
*/
|
||||
public X500Principal(InputStream is) {
|
||||
if (is == null) {
|
||||
throw new NullPointerException("provided null input stream");
|
||||
}
|
||||
|
||||
try {
|
||||
if (is.markSupported())
|
||||
is.mark(is.available() + 1);
|
||||
DerValue der = new DerValue(is);
|
||||
thisX500Name = new X500Name(der.data);
|
||||
} catch (Exception e) {
|
||||
if (is.markSupported()) {
|
||||
try {
|
||||
is.reset();
|
||||
} catch (IOException ioe) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input stream " +
|
||||
("and unable to reset input stream"));
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input stream");
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the X.500 distinguished name using
|
||||
* the format defined in RFC 2253.
|
||||
*
|
||||
* <p>This method is equivalent to calling
|
||||
* {@code getName(X500Principal.RFC2253)}.
|
||||
*
|
||||
* @return the distinguished name of this {@code X500Principal}
|
||||
*/
|
||||
public String getName() {
|
||||
return getName(X500Principal.RFC2253);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the X.500 distinguished name
|
||||
* using the specified format. Valid values for the format are
|
||||
* "RFC1779", "RFC2253", and "CANONICAL" (case insensitive).
|
||||
*
|
||||
* <p> If "RFC1779" is specified as the format,
|
||||
* this method emits the attribute type keywords defined in
|
||||
* RFC 1779 (CN, L, ST, O, OU, C, STREET).
|
||||
* Any other attribute type is emitted as an OID.
|
||||
*
|
||||
* <p> If "RFC2253" is specified as the format,
|
||||
* this method emits the attribute type keywords defined in
|
||||
* RFC 2253 (CN, L, ST, O, OU, C, STREET, DC, UID).
|
||||
* Any other attribute type is emitted as an OID.
|
||||
* Under a strict reading, RFC 2253 only specifies a UTF-8 string
|
||||
* representation. The String returned by this method is the
|
||||
* Unicode string achieved by decoding this UTF-8 representation.
|
||||
*
|
||||
* <p> If "CANONICAL" is specified as the format,
|
||||
* this method returns an RFC 2253 conformant string representation
|
||||
* with the following additional canonicalizations:
|
||||
*
|
||||
* <ol>
|
||||
* <li> Leading zeros are removed from attribute types
|
||||
* that are encoded as dotted decimal OIDs
|
||||
* <li> DirectoryString attribute values of type
|
||||
* PrintableString and UTF8String are not
|
||||
* output in hexadecimal format
|
||||
* <li> DirectoryString attribute values of types
|
||||
* other than PrintableString and UTF8String
|
||||
* are output in hexadecimal format
|
||||
* <li> Leading and trailing white space characters
|
||||
* are removed from non-hexadecimal attribute values
|
||||
* (unless the value consists entirely of white space characters)
|
||||
* <li> Internal substrings of one or more white space characters are
|
||||
* converted to a single space in non-hexadecimal
|
||||
* attribute values
|
||||
* <li> Relative Distinguished Names containing more than one
|
||||
* Attribute Value Assertion (AVA) are output in the
|
||||
* following order: an alphabetical ordering of AVAs
|
||||
* containing standard keywords, followed by a numeric
|
||||
* ordering of AVAs containing OID keywords.
|
||||
* <li> The only characters in attribute values that are escaped are
|
||||
* those which section 2.4 of RFC 2253 states must be escaped
|
||||
* (they are escaped using a preceding backslash character)
|
||||
* <li> The entire name is converted to upper case
|
||||
* using {@code String.toUpperCase(Locale.US)}
|
||||
* <li> The entire name is converted to lower case
|
||||
* using {@code String.toLowerCase(Locale.US)}
|
||||
* <li> The name is finally normalized using normalization form KD,
|
||||
* as described in the Unicode Standard and UAX #15
|
||||
* </ol>
|
||||
*
|
||||
* <p> Additional standard formats may be introduced in the future.
|
||||
*
|
||||
* @param format the format to use
|
||||
*
|
||||
* @return a string representation of this {@code X500Principal}
|
||||
* using the specified format
|
||||
* @throws IllegalArgumentException if the specified format is invalid
|
||||
* or null
|
||||
*/
|
||||
public String getName(String format) {
|
||||
if (format != null) {
|
||||
if (format.equalsIgnoreCase(RFC1779)) {
|
||||
return thisX500Name.getRFC1779Name();
|
||||
} else if (format.equalsIgnoreCase(RFC2253)) {
|
||||
return thisX500Name.getRFC2253Name();
|
||||
} else if (format.equalsIgnoreCase(CANONICAL)) {
|
||||
return thisX500Name.getRFC2253CanonicalName();
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("invalid format specified");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the X.500 distinguished name
|
||||
* using the specified format. Valid values for the format are
|
||||
* "RFC1779" and "RFC2253" (case insensitive). "CANONICAL" is not
|
||||
* permitted and an {@code IllegalArgumentException} will be thrown.
|
||||
*
|
||||
* <p>This method returns Strings in the format as specified in
|
||||
* {@link #getName(String)} and also emits additional attribute type
|
||||
* keywords for OIDs that have entries in the {@code oidMap}
|
||||
* parameter. OID entries in the oidMap take precedence over the default
|
||||
* OIDs recognized by {@code getName(String)}.
|
||||
* Improperly specified OIDs are ignored; however if an OID
|
||||
* in the name maps to an improperly specified keyword, an
|
||||
* {@code IllegalArgumentException} is thrown.
|
||||
*
|
||||
* <p> Additional standard formats may be introduced in the future.
|
||||
*
|
||||
* <p> Warning: additional attribute type keywords may not be recognized
|
||||
* by other implementations; therefore do not use this method if
|
||||
* you are unsure if these keywords will be recognized by other
|
||||
* implementations.
|
||||
*
|
||||
* @param format the format to use
|
||||
* @param oidMap an OID map, where each key is an object identifier in
|
||||
* String form (a sequence of nonnegative integers separated by periods)
|
||||
* that maps to a corresponding attribute type keyword String.
|
||||
* The map may be empty but never {@code null}.
|
||||
* @return a string representation of this {@code X500Principal}
|
||||
* using the specified format
|
||||
* @throws IllegalArgumentException if the specified format is invalid,
|
||||
* null, or an OID in the name maps to an improperly specified keyword
|
||||
* @throws NullPointerException if {@code oidMap} is {@code null}
|
||||
* @since 1.6
|
||||
*/
|
||||
public String getName(String format, Map<String, String> oidMap) {
|
||||
if (oidMap == null) {
|
||||
throw new NullPointerException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
("provided.null.OID.map"));
|
||||
}
|
||||
if (format != null) {
|
||||
if (format.equalsIgnoreCase(RFC1779)) {
|
||||
return thisX500Name.getRFC1779Name(oidMap);
|
||||
} else if (format.equalsIgnoreCase(RFC2253)) {
|
||||
return thisX500Name.getRFC2253Name(oidMap);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("invalid format specified");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distinguished name in ASN.1 DER encoded form. The ASN.1
|
||||
* notation for this structure is supplied in the documentation for
|
||||
* {@link #X500Principal(byte[] name) X500Principal(byte[] name)}.
|
||||
*
|
||||
* <p>Note that the byte array returned is cloned to protect against
|
||||
* subsequent modifications.
|
||||
*
|
||||
* @return a byte array containing the distinguished name in ASN.1 DER
|
||||
* encoded form
|
||||
*/
|
||||
public byte[] getEncoded() {
|
||||
try {
|
||||
return thisX500Name.getEncoded();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("unable to get encoding", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a user-friendly string representation of this
|
||||
* {@code X500Principal}.
|
||||
*
|
||||
* @return a string representation of this {@code X500Principal}
|
||||
*/
|
||||
public String toString() {
|
||||
return thisX500Name.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified {@code Object} with this
|
||||
* {@code X500Principal} for equality.
|
||||
*
|
||||
* <p> Specifically, this method returns {@code true} if
|
||||
* the {@code Object} <i>o</i> is an {@code X500Principal}
|
||||
* and if the respective canonical string representations
|
||||
* (obtained via the {@code getName(X500Principal.CANONICAL)} method)
|
||||
* of this object and <i>o</i> are equal.
|
||||
*
|
||||
* <p> This implementation is compliant with the requirements of RFC 5280.
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* {@code X500Principal}
|
||||
*
|
||||
* @return {@code true} if the specified {@code Object} is equal
|
||||
* to this {@code X500Principal}, {@code false} otherwise
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof X500Principal == false) {
|
||||
return false;
|
||||
}
|
||||
X500Principal other = (X500Principal)o;
|
||||
return this.thisX500Name.equals(other.thisX500Name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hash code for this {@code X500Principal}.
|
||||
*
|
||||
* <p> The hash code is calculated via:
|
||||
* {@code getName(X500Principal.CANONICAL).hashCode()}
|
||||
*
|
||||
* @return a hash code for this {@code X500Principal}
|
||||
*/
|
||||
public int hashCode() {
|
||||
return thisX500Name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the X500Principal object to a stream.
|
||||
*
|
||||
* @serialData this {@code X500Principal} is serialized
|
||||
* by writing out its DER-encoded form
|
||||
* (the value of {@code getEncoded} is serialized).
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws IOException {
|
||||
s.writeObject(thisX500Name.getEncodedInternal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this object from a stream (i.e., deserializes it).
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException,
|
||||
java.io.NotActiveException,
|
||||
ClassNotFoundException {
|
||||
|
||||
// re-create thisX500Name
|
||||
thisX500Name = new X500Name((byte[])s.readObject());
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue