// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // 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 for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package netscape.security.x509; import java.io.IOException; import java.security.Principal; import java.util.Arrays; import java.util.Enumeration; import java.util.Vector; import netscape.security.util.DerInputStream; import netscape.security.util.DerOutputStream; import netscape.security.util.DerValue; import netscape.security.util.ObjectIdentifier; /** * 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. * *
* This class exposes only partial X.500 name functionality. Most
* notably, it works best if Relative Distinguished Names only have one
* (unique) attribute each, and if only the most common attributes need
* to be visible to applications. This limitation, and others, will
* be lifted over time.
*
* @author David Brownell
* @author Amit Kapoor
* @author Hemma Prafullchandra
* @version 1.35
* @see GeneralName
* @see GeneralNames
* @see GeneralNameInterface
* @see RDN
* @see AVA
* @see LdapDNStrConverter
*/
public class X500Name implements Principal, GeneralNameInterface {
/**
*
*/
private static final long serialVersionUID = -730790062013191108L;
/**
* Constructs a name from a Ldap DN string, such
* as &lb;CN=Dave, OU=JavaSoft, O=Sun Microsystems, C=US&rb;. The
* older "/C=US/O=Sun Microsystems, Inc/OU=JavaSoft/CN=Dave" syntax
* is not currently supported. (The former is RFC 1779 style.)
*
* @param ldapDNString a Ldap DN String e.g. as defined in RFC1779
*/
public X500Name(String ldapDNString)
throws IOException {
X500Name x500name;
if (ldapDNString == null || ldapDNString.equals("")) {
clear();
return;
}
x500name = LdapDNStrConverter.getDefault().parseDN(ldapDNString);
names = x500name.getNames();
}
/**
* Constructs a X500Name from a Ldap DN String using the specified
* LdapDNStrConverter. Also use the input tags.
*
* @see LdapDNStrConverter
*
* @param ldapDNString a Ldap DN String e.g. as defined in RFC1779.
* @param ldapDNStrConverter A LdapDNStrConverter
*/
public X500Name(String ldapDNString, LdapDNStrConverter ldapDNStrConverter, byte[] tags)
throws IOException {
if (ldapDNString == null || ldapDNString.equals("")) {
clear();
return;
}
X500Name x500name;
x500name = ldapDNStrConverter.parseDN(ldapDNString, tags);
names = x500name.getNames();
}
public X500Name(String ldapDNString, byte[] tags)
throws IOException {
if (ldapDNString == null || ldapDNString.equals("")) {
clear();
return;
}
X500Name x500name;
x500name = LdapDNStrConverter.getDefault().parseDN(ldapDNString, tags);
names = x500name.getNames();
}
/**
* Constructs a X500Name from a Ldap DN String using the specified
* LdapDNStrConverter.
*
* @see LdapDNStrConverter
*
* @param ldapDNString a Ldap DN String e.g. as defined in RFC1779.
* @param ldapDNStrConverter A LdapDNStrConverter
*/
public X500Name(String ldapDNString,
LdapDNStrConverter ldapDNStrConverter)
throws IOException {
if (ldapDNString == null || ldapDNString.equals("")) {
clear();
return;
}
X500Name x500name;
x500name = ldapDNStrConverter.parseDN(ldapDNString);
names = x500name.getNames();
}
/**
* Constructs a X500Name from fields common in enterprise application
* environments.
*
* @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 {
DirStrConverter dirStrConverter = new DirStrConverter();
PrintableConverter printableConverter = new PrintableConverter();
AVA[] assertion = new AVA[1]; // array is cloned in constructors.
int i = 4;
names = new RDN[i];
/*
* NOTE: it's only on output that little-endian
* ordering is used.
*/
assertion[0] = new AVA(commonName_oid,
dirStrConverter.getValue(commonName));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(orgUnitName_oid,
dirStrConverter.getValue(organizationUnit));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(orgName_oid,
dirStrConverter.getValue(organizationName));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(countryName_oid,
printableConverter.getValue(country));
names[--i] = new RDN(assertion);
}
/**
* Constructs a X500Name from fields common in Internet application
* environments.
*
* @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 {
DirStrConverter dirStrConverter = new DirStrConverter();
PrintableConverter printableConverter = new PrintableConverter();
AVA[] assertion = new AVA[1]; // array is cloned in constructors.
int i = 6;
names = new RDN[i];
/*
* NOTE: it's only on output that little-endian
* ordering is used.
*/
assertion[0] = new AVA(commonName_oid,
dirStrConverter.getValue(commonName));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(orgUnitName_oid,
dirStrConverter.getValue(organizationUnit));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(orgName_oid,
dirStrConverter.getValue(organizationName));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(localityName_oid,
dirStrConverter.getValue(localityName));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(stateName_oid,
dirStrConverter.getValue(stateName));
names[--i] = new RDN(assertion);
assertion[0] = new AVA(countryName_oid,
printableConverter.getValue(country));
names[--i] = new RDN(assertion);
}
/**
* 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 {
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);
}
/**
* Constructs a X500Name from array of RDN. The RDNs are expected to
* be in big endian order i.e. most significant first.
*
* @param rdns an array of RDN.
*/
public X500Name(RDN[] rdns)
throws IOException {
names = rdns.clone();
}
/**
* convenience method.
*
* @param rdns a vector of rdns.
*/
public X500Name(Vector