codec.x501
Class Name

java.lang.Object
  |
  +--java.util.AbstractCollection
        |
        +--java.util.AbstractList
              |
              +--java.util.ArrayList
                    |
                    +--codec.asn1.ASN1AbstractCollection
                          |
                          +--codec.asn1.ASN1Sequence
                                |
                                +--codec.asn1.ASN1SequenceOf
                                      |
                                      +--codec.x501.Name
All Implemented Interfaces:
ASN1Collection, ASN1CollectionOf, ASN1Type, Cloneable, Collection, Externalizable, List, Principal, Resolver, Serializable

public class Name
extends ASN1SequenceOf
implements Principal, Resolver

This class represents the X501 Name. A Name is used to identify people or organizations. It must be written as a RFC2253 string. For example:

  CN=Steve Kille, O=ISODE Consortium, C=GB
 
With this Name an ASN1Structure as defined in Layman's Guide to ASN.1 is build.

The Principal interface method getName returns the encoded name in little-endian format in accordance with RFC2253 and the IANA assigned numbers document for Directory System Names.

If the Name is initalised with a RFC2253 conformant syntax then the attributes are encoded in the opposite order they appear in the name(in little-endian order).

If the Name is initialized by decoding a DER stream then the internal representation remains identical to the decoded data. In other words, decoding and subsequent encoding of a Name object retains the order of attributes and returns identical encodings.

Note: this class works properly only if the decode method is called in order to decode Names. Do not use constructions such as:

DERDecoder dec; Name rdn; dec = new DERDecoder(in); rdn = new Name(); dec.readCollectionOf(rdn); dec.close();
This would work in theory but this implementation makes some assumptions in order to optimise the decoding. Better use the "proper" construction:
DERDecoder dec; Name rdn; dec = new DERDecoder(in); rdn = new Name(); rdn.decode(dec); dec.close();
This should always be safe and is the preferred way of decoding ASN.1 types anyway.

Since there is only one choice at present for the Name which is RDNSequence this type does not bother to implement CHOICE as its outer type. The definition of Name according to X.501 as given in RSA Laboratories' Laymans Guide is:

Name ::= CHOICE { RDNSequence } RDNSequence ::= SEQUENCE OF RelativeDistinguishedName RelativeDistinguishedName :: = SET OF AttributeValueAssertion AttributeValueAssertion ::= SEQUENCE { AttributeType, AttributeValue } AttributeType ::= OBJECT IDENTIFIER AttributeValue ::= ANY Since the ANY type is deprecated in the '97 specification of X.680 we represent the ANY type by a generic Open Type which is the new ASN.1 way of handling this.

This class supports the full range of RFC2253 features including

The string output is canonicalized. Everything that can be resolved by this class (e.g., keywords for attribute types) is resolved. The following attribute types are supported per default (cf. RFC3383:

Version:
"$Id: Name.java,v 1.9 2007/08/30 08:45:05 pebinger Exp $"
Author:
Volker Roth, Jan Peters
See Also:
Serialized Form

Field Summary
protected  HashMap a2oid_
          Mapping from acronyms to OID.
protected static boolean allowDefaultEncoding_
          flag that determines, how the Name class shall behave, either as usual with a default encoding or forcing all Name using classes to use the new constructor.
protected static int defaultEncoding_
          Determines in what kind of encoding all Name objects will be encoded as long as no special constructors are used.
static int IA5_ENCODING
          Constant for IA5Encoding of the Name
static String MATCH_ALL
          The "match all" pattern symbol.
protected  HashMap oid2a_
          Mapping from OID to acronyms.
static int PRINTABLE_ENCODING
          Constant for Printable Encoding of the Name
static int T61_ENCODING
          Constant for Teletex (T61) Encoding of the Name
static int UTF8_ENCODING
          Constant for UTF8Encoding of the Name
 
Fields inherited from class java.util.AbstractList
modCount
 
Constructor Summary
Name()
          This constructor calls the initASN1Structure() method, do create an empty structure for a Relative Distinguished Name object.
Name(String rfc2253String)
          Deprecated.  
Name(String rfc2253String, int encType)
          special constructor, that overrides the global EncodingType.
 
Method Summary
 boolean add(ASN1Set o)
          This method adds the given object to this Name if it is a valid RDN (a set with enclosed sequences with an OID and non null attribute value each).
 void clear()
          Clears this name instance.
static Name clone(Name source)
          Deprecated.  
static Name clone(Principal sourcePrincipal)
          Deprecated.  
 void decode(Decoder dec)
          This method reads the DER encoded ASN.1 sequence into a hashmap.
 Hashtable divide()
          Added by Jens Zoerkler function divides the Name into his RDN parts and puts them into a Hashtable, where the key is the RDNs identifier and value is the value of the RDN.
 boolean equals(Object o)
          Compares this object with the given one.
 List getAVAList()
          This method returns the Name as a list of AVA instances.
 int getCurrentEncoding()
          Returns the encoding type that is currently set.
static int getEncodingType()
          Returns the default encoding type.
 String getName()
          This method returns the name of this principal.
protected  Hashtable getNameTable()
          This function returns a Hashtable object with the following properties: The keys are the attribute type/value entries defined in this Name object.
 Map getOIDs()
          Returns a map containing the OID/Key-Pairs (default plus user defined), which are accepted as keys of the instance's distinguished Name.
 List getReverseAVAList()
          This method returns the Name as a list of AVA instances.
 String getReverseName()
          This method returns the name of this principal.
protected  void initMaps()
          This method initializes the hashmaps, which are needed to create the ASN1Structure Tree.
 boolean isPatternMatch(Name name)
          Compares the given Name with this Name for equality, where an asterisk ('*') attribute value in this Name matches any corresponding attribute value of the given Name.
 ASN1Type newElement()
          This method returns a new set of AttributeValueAssertions (AVA).
 boolean partOf(Name name)
          This method checks whether this Name is contained in the given Name.
 boolean registerOID(int[] oid, String key)
          Register user defined OID/Key-Pairs which are accepted as keys of the instance's distinguished Name.
 void resetOIDs()
          Resets all user defined OID/Key-Pairs, which are accepted as keys of the instance's distinguished Name.
 ASN1Type resolve(ASN1Type caller)
          Resolves AttributeValueAssertions for the component RDNs of this Name.
static void setEncodingType(int encType)
          Sets the default encoding type for all further Name objects.
 String toString()
          Returns the String representation.
 
Methods inherited from class codec.asn1.ASN1SequenceOf
getElementType
 
Methods inherited from class codec.asn1.ASN1Sequence
getTag
 
Methods inherited from class codec.asn1.ASN1AbstractCollection
checkConstraints, encode, getCollection, getConstraint, getTagClass, getValue, isExplicit, isOptional, isType, readExternal, setConstraint, setExplicit, setOptional, writeExternal
 
Methods inherited from class java.util.ArrayList
add, add, addAll, addAll, clone, contains, ensureCapacity, get, indexOf, isEmpty, lastIndexOf, remove, removeRange, set, size, toArray, toArray, trimToSize
 
Methods inherited from class java.util.AbstractList
hashCode, iterator, listIterator, listIterator, subList
 
Methods inherited from class java.util.AbstractCollection
containsAll, remove, removeAll, retainAll
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface java.security.Principal
hashCode
 
Methods inherited from interface codec.asn1.ASN1Collection
getCollection
 
Methods inherited from interface codec.asn1.ASN1Type
checkConstraints, encode, getConstraint, getTag, getTagClass, getValue, isExplicit, isOptional, isType, setConstraint, setExplicit, setOptional
 
Methods inherited from interface java.util.Collection
add, addAll, contains, containsAll, hashCode, isEmpty, iterator, remove, removeAll, retainAll, size, toArray, toArray
 
Methods inherited from interface java.util.List
containsAll, hashCode, iterator, listIterator, listIterator, remove, removeAll, retainAll, subList
 

Field Detail

MATCH_ALL

public static final String MATCH_ALL
The "match all" pattern symbol.

IA5_ENCODING

public static final int IA5_ENCODING
Constant for IA5Encoding of the Name

PRINTABLE_ENCODING

public static final int PRINTABLE_ENCODING
Constant for Printable Encoding of the Name

T61_ENCODING

public static final int T61_ENCODING
Constant for Teletex (T61) Encoding of the Name

UTF8_ENCODING

public static final int UTF8_ENCODING
Constant for UTF8Encoding of the Name

allowDefaultEncoding_

protected static final boolean allowDefaultEncoding_
flag that determines, how the Name class shall behave, either as usual with a default encoding or forcing all Name using classes to use the new constructor.

defaultEncoding_

protected static int defaultEncoding_
Determines in what kind of encoding all Name objects will be encoded as long as no special constructors are used. Default is UTF8 Encoding.

a2oid_

protected HashMap a2oid_
Mapping from acronyms to OID.

oid2a_

protected HashMap oid2a_
Mapping from OID to acronyms.
Constructor Detail

Name

public Name()
This constructor calls the initASN1Structure() method, do create an empty structure for a Relative Distinguished Name object. Used incase one wants to use the clone function for Name.

Name

public Name(String rfc2253String)
     throws BadNameException
Deprecated.  

This constructor parses the given String according to RFC2253 and builds the internal ASN.1 representation of it in big-endian order (most significant attribute first). This is the order used for encoding the name.

Any names parsed with instances of this class remain in the order they were encoded in order not to invalidate any digital signatures on the encoded representation when writing the encoded instance back to some output stream.

Parameters:
rfc2253String - String of RFC2253 representation.

Name

public Name(String rfc2253String,
            int encType)
     throws BadNameException
special constructor, that overrides the global EncodingType. To use, if during the runtime mixed encodingtypes are needed.
Parameters:
rfc2253String - String of RFC2253 representation.
encType - The encoding type for strings. If -1, the default encoding is used.
Throws:
BadNameException -  
Method Detail

setEncodingType

public static void setEncodingType(int encType)
                            throws BadNameException
Sets the default encoding type for all further Name objects. If the parameter is out of the allowed range of encodings, an Exception is thrown.
Parameters:
encType -  
Throws:
BadNameException -  

getEncodingType

public static int getEncodingType()
Returns the default encoding type.
Returns:
the default encoding type.

clear

public void clear()
Clears this name instance.
Overrides:
clear in class ArrayList

registerOID

public boolean registerOID(int[] oid,
                           String key)
Register user defined OID/Key-Pairs which are accepted as keys of the instance's distinguished Name.
Parameters:
oid - the OID to register as Integer array.
key - the corresponding key as String.
Returns:
true if neither the OID nor the key has already been registered, or is part of the default mapping. Otherwise, false is returned.

getOIDs

public Map getOIDs()
Returns a map containing the OID/Key-Pairs (default plus user defined), which are accepted as keys of the instance's distinguished Name.
Returns:
A map containing OID/Key-Entries.

resetOIDs

public void resetOIDs()
Resets all user defined OID/Key-Pairs, which are accepted as keys of the instance's distinguished Name.

initMaps

protected void initMaps()
This method initializes the hashmaps, which are needed to create the ASN1Structure Tree.

getCurrentEncoding

public int getCurrentEncoding()
Returns the encoding type that is currently set.
Returns:
the encoding type that is currently set.

toString

public String toString()
Returns the String representation. This implementation simply calles getName.
Specified by:
toString in interface Principal
Overrides:
toString in class ASN1AbstractCollection
Returns:
The String representation.

getName

public String getName()
This method returns the name of this principal. The order is little-endian (least significant attribute first).
Specified by:
getName in interface Principal
Returns:
Name of this principal

getAVAList

public List getAVAList()
This method returns the Name as a list of AVA instances. The order is the same as the order in which the AVA instances appear in the code.

getReverseAVAList

public List getReverseAVAList()
This method returns the Name as a list of AVA instances. The order is the opposite as the order in which the AVA instances appear in the code.

getReverseName

public String getReverseName()
This method returns the name of this principal. The order is the reverse order of method getName().
Returns:
Name of this principal in reverse order of encoding.

resolve

public ASN1Type resolve(ASN1Type caller)
Resolves AttributeValueAssertions for the component RDNs of this Name. This method is for internal use only. Do not call it or bad things will happen. You have been warned.

This method basically registers the AVAs of the RDNs so that the internal Open Types can be discarded after decoding. This makes some objects available for garbage collection that are not required anymore.

Specified by:
resolve in interface Resolver
Parameters:
caller - The calling RDN.
Returns:
The AVA instance that is added to the calling RDN in the decoding process.

decode

public void decode(Decoder dec)
            throws ASN1Exception,
                   IOException
This method reads the DER encoded ASN.1 sequence into a hashmap. The implementation uses a (perfectly legal) trick. Method newElement adds the AttributeValueAssertions instances to a temporary list which is processed at the end of this method. The temporary list is used to eliminate Open Types that are not required any more after decoding in a way that saves us laborious descending in the various depths of the Name.

Overrides:
decode in class ASN1SequenceOf
Parameters:
dec - The Decoder to use.
Throws:
ASN1Exception - if the expected ANS1Type cannot be found.

add

public boolean add(ASN1Set o)
This method adds the given object to this Name if it is a valid RDN (a set with enclosed sequences with an OID and non null attribute value each).
Parameters:
o - The RDN to add.
Returns:
true. This method accepts multiple elements which are the same, and adheres to the contract of add(Object) for collections.
Throws:
IllegalArgumentException - if the given object is not a valid RDN.

newElement

public ASN1Type newElement()
This method returns a new set of AttributeValueAssertions (AVA).
Overrides:
newElement in class ASN1SequenceOf
Returns:
The new instance to decode.

equals

public boolean equals(Object o)
Compares this object with the given one. Both objects are equal if o is a Principal and the name of this object equals the name of o (or the reverse).

Both distinguished names must have the same order of RDNs and AVAs withing RDNs. Strictly speaking, a RDN is a set of AVAs so the comparison should tolerate that. However, this is not yet implemented.

In order to make the comparison more robust, this method converts the given object into a Name object unless it is already of that class. Then the string representation of the resulting object is compared to the name of this object.

Specified by:
equals in interface Principal
Overrides:
equals in class AbstractList
Parameters:
o - The object to compare with.
Returns:
true iff this instance equals the given one.

isPatternMatch

public boolean isPatternMatch(Name name)
Compares the given Name with this Name for equality, where an asterisk ('*') attribute value in this Name matches any corresponding attribute value of the given Name. All AVAs must appear in both Name instances and their keys must match. If an AVA of this Name has a sibling then the corresponding AVA of the given Name must also have a sibling.

Please note that currently, the order of AVAs is important even though an RDN is defined as a set of AVAs. Please also note that this Name is the pattern. This is important so that attackers may not get names certified that contain the "match all" pattern as an attribute value e.g., "O=*".

Parameters:
name - The Name to which this pattern is compared.

partOf

public boolean partOf(Name name)
This method checks whether this Name is contained in the given Name. true is returned, iff all AVA defined in this Name are also defined in the given Name with the same order (going from the last AVA in the Name's String represenation to the first). AVA siblings have the same order. AVAs are compared by attribute type and value (ignoring the case of attribute type letters).

Examples:

   name1: CN=foo + EMAILADDRESS=foo@bar.net, O=company
   name2: CN=foo, EMAILADDRESS=foo@bar.net, O=company
   name3: cn=foo, o=company
   name4: o=company
   name5: EMAILADDRESS=foo@bar.net
   name1.partOf(name1) == true
   name1.partOf(name2) == false
   name3.partOf(name1) == true
   name3.partOf(name2) == false
   name4.partOf(name1) == true
   name4.partOf(name3) == true
   name5.partOf(name1) == false
   name5.partOf(name2) == false
 
Parameters:
name - The Name to compare with.
Returns:
true iff all known attributes of this Name are also defined in the given Name, and the corresponding values are equal (ignoring case).

clone

public static Name clone(Name source)
                  throws IllegalArgumentException
Deprecated.  

Clone the given Name.
Parameters:
source -  
Returns:
the cloned Name

clone

public static Name clone(Principal sourcePrincipal)
                  throws BadNameException,
                         IllegalArgumentException
Deprecated.  

Clone the Name from given Principal.
Parameters:
sourcePrincipal -  
Returns:
the cloned Name
Throws:
BadNameException -  

divide

public Hashtable divide()
Added by Jens Zoerkler function divides the Name into his RDN parts and puts them into a Hashtable, where the key is the RDNs identifier and value is the value of the RDN.
Returns:
Hashtable

getNameTable

protected Hashtable getNameTable()
This function returns a Hashtable object with the following properties:
  • The keys are the attribute type/value entries defined in this Name object. If the same type/value entry is used more than once in the Name object, its key is extended with a trailing number to distinguish the single AVAs.
  • Each value is a vector of two elements; the first element is the corresponding attribute type and the second element is the order in which they are read from the parser with respect to ",", which means that if two pairs: (attribute type = attribute value) are separated by "," their order will be different and if two pairs are separarted by "+" then they will have the same order.
Examples:
   (new Name("DC=www, DC=www + DC=WWW")).getNameTable(true)
   -> [ (DC=WWW|1), (DC=www|1), (DC1=www|2) ]
 
Returns:
the Hashtable.


Copyright © Fraunhofer Gesellschaft. All Rights Reserved.