FileDocCategorySizeDatePackage
GeneralName.javaAPI DocAndroid 1.5 API39263Wed May 06 22:41:06 BST 2009org.apache.harmony.security.x509

GeneralName

public class GeneralName extends Object
The class encapsulates the ASN.1 DER encoding/decoding work with the GeneralName structure which is a part of X.509 certificate (as specified in RFC 3280 - Internet X.509 Public Key Infrastructure. Certificate and Certificate Revocation List (CRL) Profile. http://www.ietf.org/rfc/rfc3280.txt):

GeneralName::= CHOICE {
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER
}

OtherName::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT ANY DEFINED BY type-id
}

EDIPartyName::= SEQUENCE {
nameAssigner [0] DirectoryString OPTIONAL,
partyName [1] DirectoryString
}

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))
}

see
org.apache.harmony.security.x509.NameConstraints
see
org.apache.harmony.security.x509.GeneralSubtree

Fields Summary
public static final int
OTHER_NAME
The values of the tags of fields
public static final int
RFC822_NAME
public static final int
DNS_NAME
public static final int
X400_ADDR
public static final int
DIR_NAME
public static final int
EDIP_NAME
public static final int
UR_ID
public static final int
IP_ADDR
public static final int
REG_ID
private static org.apache.harmony.security.asn1.ASN1Type[]
nameASN1
private int
tag
private Object
name
private byte[]
encoding
private byte[]
name_encoding
public static final org.apache.harmony.security.asn1.ASN1Choice
ASN1
Constructors Summary
public GeneralName(int tag, String name)
Makes the GeneralName object from the tag type and corresponding well established string representation of the name value. The String representation of [7] iPAddress is such as: For IP v4, as specified in RFC 791, the address must contain exactly 4 byte component. For IP v6, as specified in RFC 1883, the address must contain exactly 16 byte component. If GeneralName structure is used as a part of Name Constraints extension, to represent an address range the number of address component is doubled (to 8 and 32 bytes respectively). Note that the names: [0] otherName, [3] x400Address, [5] ediPartyName have no the string representation, so exception will be thrown. To make the GeneralName object with such names use another constructor.

param
tag is an integer which value corresponds to the name type.
param
name is a name value corresponding to the tag.

        if (name == null) {
            throw new IOException(Messages.getString("security.28")); //$NON-NLS-1$
        }
        this.tag = tag;
        switch (tag) {
            case OTHER_NAME :
            case X400_ADDR :
            case EDIP_NAME :
                throw new IOException( Messages.getString("security.180", tag )); //$NON-NLS-1$ //$NON-NLS-2$
            case DNS_NAME :
                // according to RFC 3280 p.34 the DNS name should be 
                // checked against the
                // RFC 1034 p.10 (3.5. Preferred name syntax):
                checkDNS(name);
                this.name = name;
                break;
            case UR_ID :
                // check the uniformResourceIdentifier for correctness
                // according to RFC 3280 p.34
                checkURI(name);
                this.name = name;
                break;
            case RFC822_NAME :
                this.name = name;
                break;
            case REG_ID:
                this.name = oidStrToInts(name);
                break;
            case DIR_NAME :
                this.name = new Name(name);
                break;
            case IP_ADDR :
                this.name = ipStrToBytes(name);
                break;
            default:
                throw new IOException(Messages.getString("security.181", tag)); //$NON-NLS-1$ //$NON-NLS-2$
        }
    
public GeneralName(OtherName name)
TODO

param
name: OtherName

        this.tag = OTHER_NAME;
        this.name = name;
    
public GeneralName(ORAddress name)
TODO

param
name: ORAddress

        this.tag = X400_ADDR;
        this.name = name;
    
public GeneralName(org.apache.harmony.security.x501.Name name)
TODO

param
name: Name

        this.tag = DIR_NAME;
        this.name = name;
    
public GeneralName(EDIPartyName name)
TODO

param
name: EDIPartyName

        this.tag = EDIP_NAME;
        this.name = name;
    
public GeneralName(byte[] name)
Constructor for type [7] iPAddress. name is an array of bytes such as: For IP v4, as specified in RFC 791, the address must contain exactly 4 byte component. For IP v6, as specified in RFC 1883, the address must contain exactly 16 byte component. If GeneralName structure is used as a part of Name Constraints extension, to represent an address range the number of address component is doubled (to 8 and 32 bytes respectively).

        int length = name.length;
        if (length != 4 && length != 8 && length != 16 && length != 32) {
            throw new IllegalArgumentException(
                    Messages.getString("security.182")); //$NON-NLS-1$
        }
        this.tag = IP_ADDR;
        this.name = new byte[name.length];
        System.arraycopy(name, 0, this.name, 0, name.length);
    
public GeneralName(int tag, byte[] name)
Constructs an object representing the value of GeneralName.

param
tag is an integer which value corresponds to the name type (0-8),
param
name is a DER encoded for of the name value

        if (name == null) {
            throw new NullPointerException(Messages.getString("security.28")); //$NON-NLS-1$
        }
        if ((tag < 0) || (tag > 8)) {
            throw new IOException(Messages.getString("security.183", tag)); //$NON-NLS-1$
        }
        this.tag = tag;
        this.name_encoding = new byte[name.length];
        System.arraycopy(name, 0, this.name_encoding, 0, name.length);
        this.name = nameASN1[tag].decode(this.name_encoding);
    
Methods Summary
public static voidcheckDNS(java.lang.String dns)
Checks the correctness of the string representation of DNS name. The correctness is checked as specified in RFC 1034 p. 10.

        byte[] bytes = dns.toLowerCase().getBytes();
        // indicates if it is a first letter of the label
        boolean first_letter = true;
        for (int i=0; i<bytes.length; i++) {
            byte ch = bytes[i];
            if (first_letter) {
                if (ch > 'z" || ch < 'a") {
                    throw new IOException(Messages.getString("security.184", //$NON-NLS-1$
                            (char)ch, dns));
                }
                first_letter = false;
                continue;
            }
            if (!((ch >= 'a" && ch <= 'z") || (ch >= '0" && ch <= '9")
                    || (ch == '-") || (ch == '."))) {
                throw new IOException(Messages.getString("security.185", dns)); //$NON-NLS-1$
            }
            if (ch == '.") {
                // check the end of the previous label, it should not
                // be '-' sign
                if (bytes[i-i] == '-") {
                    throw new IOException(
                            Messages.getString("security.186", dns)); //$NON-NLS-1$
                }
                first_letter = true;
            }
        }
    
public static voidcheckURI(java.lang.String uri)
Checks the correctness of the string representation of URI name. The correctness is checked as pointed out in RFC 3280 p. 34.

        try {
            URI ur = new URI(uri);
            if ((ur.getScheme() == null) 
                    || (ur.getRawSchemeSpecificPart().length() == 0)) {
                throw new IOException(Messages.getString("security.187", uri)); //$NON-NLS-1$
            }
            if (!ur.isAbsolute()) {
                throw new IOException(Messages.getString("security.188", uri)); //$NON-NLS-1$
            }
        } catch (URISyntaxException e) {
            throw (IOException) new IOException(
                    Messages.getString("security.189", uri)).initCause(e);//$NON-NLS-1$
                    
        }
    
public booleanequals(java.lang.Object _gname)
TODO

param
_gname: Object
return

        if (!(_gname instanceof GeneralName)) {
            return false;
        }
        GeneralName gname = (GeneralName) _gname;
        if (this.tag != gname.tag) {
            return false;
        }
        switch(tag) {
            case RFC822_NAME:
            case DNS_NAME:
            case UR_ID:
                return ((String) name).equalsIgnoreCase(
                        (String) gname.getName());
            case REG_ID:
                return Arrays.equals((int[]) name, (int[]) gname.name);
            case IP_ADDR: 
                // iPAddress [7], check by using ranges.
                return Arrays.equals((byte[]) name, (byte[]) gname.name);
            case DIR_NAME: 
            case X400_ADDR:
            case OTHER_NAME:
            case EDIP_NAME:
                return Arrays.equals(getEncoded(), gname.getEncoded());
            default:
                // should never happen
        }
        //System.out.println(false);
        return false;
    
public java.util.ListgetAsList()
Gets a list representation of this GeneralName object. The first entry of the list is an Integer object representing the type of mane (0-8), and the second entry is a value of the name: string or ASN.1 DER encoded form depending on the type as follows: rfc822Name, dNSName, uniformResourceIdentifier names are returned as Strings, using the string formats for those types (rfc 3280) IP v4 address names are returned using dotted quad notation. IP v6 address names are returned in the form "p1:p2:...:p8", where p1-p8 are hexadecimal values representing the eight 16-bit pieces of the address. registeredID name are returned as Strings represented as a series of nonnegative integers separated by periods. And directory names (distinguished names) are returned in RFC 2253 string format. otherName, X400Address, ediPartyName returned as byte arrays containing the ASN.1 DER encoded form of the name.

        ArrayList result = new ArrayList();
        result.add(new Integer(tag));
        switch (tag) {
            case OTHER_NAME:
                result.add(((OtherName) name).getEncoded());
                break;
            case RFC822_NAME:
            case DNS_NAME:
            case UR_ID:
                result.add(name); // String
                break;
            case REG_ID:
                result.add(ObjectIdentifier.toString((int[]) name));
                break;
            case X400_ADDR:
                result.add(((ORAddress) name).getEncoded());
                break;
            case DIR_NAME: // directoryName is returned as a String
                result.add(((Name) name).getName(X500Principal.RFC2253));
                break;
            case EDIP_NAME:
                result.add(((EDIPartyName) name).getEncoded());
                break;
            case IP_ADDR: //iPAddress is returned as a String, not as a byte array
                result.add(ipBytesToStr((byte[]) name));
                break;
            default:
                // should never happen
        }
        return Collections.unmodifiableList(result);
    
private java.lang.StringgetBytesAsString(byte[] data)

        String result = ""; //$NON-NLS-1$
        for (int i=0; i<data.length; i++) {
            String tail = Integer.toHexString(0x00ff & data[i]);
            if (tail.length() == 1) {
                tail = "0" + tail;  //$NON-NLS-1$
            }
            result += tail + " "; //$NON-NLS-1$
        }
        return result;
    
public byte[]getEncoded()
Returns ASN.1 encoded form of this X.509 GeneralName value.

return
a byte array containing ASN.1 encode form.

        if (encoding == null) {
            encoding = ASN1.encode(this);
        }
        return encoding;
    
public byte[]getEncodedName()

return
the encoded value of the name without the tag associated with the name in the GeneralName structure
throws
IOException

        if (name_encoding == null) {
            name_encoding = nameASN1[tag].encode(name);
        }
        return name_encoding;
    
public java.lang.ObjectgetName()

return
the value of the name. The class of name object depends on the tag as follows: [0] otherName - OtherName object, [1] rfc822Name - String object, [2] dNSName - String object, [3] x400Address - ORAddress object, [4] directoryName - instance of Name object, [5] ediPartyName - EDIPartyName object, [6] uniformResourceIdentifier - String object, [7] iPAddress - array of bytes such as: For IP v4, as specified in RFC 791, the address must contain exactly 4 byte component. For IP v6, as specified in RFC 1883, the address must contain exactly 16 byte component. If GeneralName structure is used as a part of Name Constraints extension, to represent an address range the number of address component is doubled (to 8 and 32 bytes respectively). [8] registeredID - String.

        return name;
    
public intgetTag()
Returns the tag of the name in the structure

return
the tag of the name

        return tag;
    
public static java.lang.StringipBytesToStr(byte[] ip)
Helper method. Converts the byte array representation of ip address to the String.

param
ip : byte array representation of ip address If the length of byte array 4 then it represents an IP v4 and the output String will be in the dotted quad form. If the length is 16 then it represents an IP v6 and the output String will be returned in format "p1:p2:...:p8", where p1-p8 are hexadecimal values representing the eight 16-bit pieces of the address. If the length is 8 or 32 then it represents an address range (RFC 1519) and the output String will contain 2 IP address divided by "/"
return
String representation of ip address

        String result = ""; //$NON-NLS-1$
        if (ip.length < 9) { // IP v4
            for (int i=0; i<ip.length; i++) {
                result += Integer.toString(ip[i] & 0xff);
                if (i != ip.length-1) {
                    result += (i == 3) ? "/": "."; //$NON-NLS-1$ //$NON-NLS-2$
                }
            }
        } else {
            for (int i=0; i<ip.length; i++) {
                result += Integer.toHexString(0x00ff & ip[i]);
                if ((i % 2 != 0) && (i != ip.length-1)) {
                    result += (i == 15) ? "/": ":"; //$NON-NLS-1$ //$NON-NLS-2$
                }
            }
        }
        return result;
    
public static byte[]ipStrToBytes(java.lang.String ip)
Helper method. Converts the String representation of IP address to the array of bytes. IP addresses are expected in two versions:
IPv4 - in dot-decimal notation
IPv6 - in colon hexadecimal notation
Also method works with the ranges of the addresses represented as 2 addresses separated by '/' character.

param
address : String representation of IP address
return
byte representation of IP address

        boolean isIPv4 = (ip.indexOf('.") > 0);
        // number of components (should be 4 or 8)
        int num_components = (isIPv4) ? 4 : 16;
        if (ip.indexOf('/") > 0) {
            num_components *= 2; // this is a range of addresses
        }
        // the resulting array
        byte[] result = new byte[num_components];
        byte[] ip_bytes = ip.getBytes();
        // number of address component to be read
        int component = 0;
        // if it is reading the second bound of a range
        boolean reading_second_bound = false;
        if (isIPv4) {
            // IPv4 address is expected in the form of dot-decimal notation:
            //      1.100.2.200
            // or in the range form:
            //      1.100.2.200/1.100.3.300
            int i = 0;
            while (i < ip_bytes.length) {
                int digits = 0;
                // the value of the address component
                int value = 0;
                while ((i < ip_bytes.length) && (ip_bytes[i] >= '0")
                        && (ip_bytes[i] <= '9")) {
                    digits++;
                    if (digits > 3) {
                        throw new IOException(Messages.getString("security.18B", ip)); //$NON-NLS-1$
                    }
                    value = 10 * value + (ip_bytes[i] - 48);
                    i++;
                }
                if (digits == 0) {
                    // ip_bytes[i] is not a number
                    throw new IOException(Messages.getString("security.18C", ip));//$NON-NLS-1$
                }
                result[component] = (byte) value;
                component++;
                if (i >= ip_bytes.length) {
                    // no more bytes
                    break;
                }
                // check the reached delimiter
                if ((ip_bytes[i] != '." && ip_bytes[i] != '/")) {
                    throw new IOException(Messages.getString("security.18C", ip)); //$NON-NLS-1$
                }
                // check the correctness of the range
                if (ip_bytes[i] == '/") {
                    if (reading_second_bound) {
                        // more than 2 bounds in the range
                        throw new IOException(Messages.getString("security.18C", ip)); //$NON-NLS-1$
                    }
                    if (component != 4) {
                        throw new IOException(Messages.getString("security.18D", ip)); //$NON-NLS-1$
                    }
                    reading_second_bound = true;
                }
                // check the number of the components
                if (component > ((reading_second_bound) ? 7 : 3)) {
                    throw new IOException(Messages.getString("security.18D", ip)); //$NON-NLS-1$
                }
                i++;
            }
            // check the number of read components
            if (component != num_components) {
                throw new IOException(Messages.getString("security.18D", ip)); //$NON-NLS-1$
            }
        } else {
            // IPv6 address is expected in the form of
            // colon hexadecimal notation:
            // 010a:020b:3337:1000:FFFA:ABCD:9999:0000
            // or in a range form:
            // 010a:020b:3337:1000:FFFA:ABCD:9999:0000/010a:020b:3337:1000:FFFA:ABCD:9999:1111
            if (ip_bytes.length != 39 && ip_bytes.length != 79) {
                // incorrect length of the string representation
                throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
            }
            int value = 0;
            // indicates the reading of the second half of byte
            boolean second_hex = false;
            // if the delimiter (':' or '/') is expected
            boolean expect_delimiter = false;
            for (int i=0; i<ip_bytes.length; i++) {
                byte bytik = ip_bytes[i];
                if ((bytik >= '0") && (bytik <= '9")) {
                    value = (bytik - 48); // '0':0, '1':1, ... , '9':9
                } else if ((bytik >= 'A") && (bytik <= 'F")) {
                    value = (bytik - 55); // 'A':10, 'B':11, ... , 'F':15
                } else if ((bytik >= 'a") && (bytik <= 'f")) {
                    value = (bytik - 87); // 'a':10, 'b':11, ... , 'f':15
                } else if (second_hex) {
                    // second hex value of a byte is expected but was not read
                    // (it is the situation like: ...ABCD:A:ABCD...)
                    throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
                } else if ((bytik == ':") || (bytik == '/")) {
                    if (component % 2 == 1) {
                        // second byte of the component is omitted 
                        // (it is the situation like: ... ABDC:AB:ABCD ...)
                        throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
                    }
                    if (bytik == '/") {
                        if (reading_second_bound) {
                            // more than 2 bounds in the range
                            throw new IOException(
                                    Messages.getString("security.18E", ip)); //$NON-NLS-1$
                        }
                        if (component != 16) {
                            // check the number of read components
                            throw new IOException(Messages.getString("security.18F", ip)); //$NON-NLS-1$
                        }
                        reading_second_bound = true;
                    }
                    expect_delimiter = false;
                    continue;
                } else {
                    throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
                }
                if (expect_delimiter) { // delimiter is expected but was not read
                    throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
                }
                if (!second_hex) {
                    // first half of byte has been read
                    result[component] = (byte) (value << 4);
                    second_hex = true;
                } else {
                    // second half of byte has been read
                    result[component] = (byte)
                        ((result[component] & 0xFF) | value);
                    // delimiter is expected if 2 bytes were read
                    expect_delimiter = (component % 2 == 1);
                    second_hex = false;
                    component++;
                }
            }
            // check the correctness of the read address:
            if (second_hex || (component % 2 == 1)) {
                throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
            }
        }
        return result;
    
public booleanisAcceptable(org.apache.harmony.security.x509.GeneralName gname)
Checks if the other general name is acceptable by this object. The name is acceptable if it has the same type name and its name value is equal to name value of this object. Also the name is acceptable if this general name object is a part of name constraints and the specified name is satisfied the restriction provided by this object (for more detail see section 4.2.1.11 of rfc 3280). Note that for X400Address [3] check procedure is unclear so method just checks the equality of encoded forms. For otherName [0], ediPartyName [5], and registeredID [8] the check procedure if not defined by rfc 3280 and for names of these types this method also checks only for equality of encoded forms.

        if (this.tag != gname.getTag()) {
            return false;
        }
        switch (this.tag) {
            case RFC822_NAME:
                // Mail address [1]: 
                // a@b.c - particular address is acceptable by the same address,
                // or by b.c - host name.
                return ((String) gname.getName()).toLowerCase()
                    .endsWith(((String) name).toLowerCase());
            case DNS_NAME:
                // DNS name [2] that can be constructed by simply adding 
                // to the left hand side of the name satisfies the name 
                // constraint: aaa.aa.aa satisfies to aaa.aa.aa, aa.aa, ..
                String dns = (String) name;
                String _dns = (String) gname.getName();
                if (dns.equalsIgnoreCase(_dns)) {
                    return true;
                } else {
                    return _dns.toLowerCase().endsWith("." + dns.toLowerCase()); //$NON-NLS-1$
                }
            case UR_ID:
                // For URIs the constraint ".xyz.com" is satisfied by both 
                // abc.xyz.com and abc.def.xyz.com.  However, the constraint 
                // ".xyz.com" is not satisfied by "xyz.com".  
                // When the constraint does not begin with a period, it
                // specifies a host.
                // Extract the host from URI:
                String uri = (String) name;
                int begin = uri.indexOf("://")+3; //$NON-NLS-1$
                int end = uri.indexOf('/", begin);
                String host = (end == -1) 
                                ? uri.substring(begin)
                                : uri.substring(begin, end);
                uri = (String) gname.getName();
                begin = uri.indexOf("://")+3; //$NON-NLS-1$
                end = uri.indexOf('/", begin);
                String _host = (end == -1) 
                                ? uri.substring(begin)
                                : uri.substring(begin, end);
                if (host.startsWith(".")) { //$NON-NLS-1$
                    return _host.toLowerCase().endsWith(host.toLowerCase());
                } else {
                    return host.equalsIgnoreCase(_host);
                }
            case IP_ADDR: 
                // iPAddress [7], check by using ranges.
                byte[] address = (byte[]) name;
                byte[] _address = (byte[]) gname.getName();
                int length = address.length;
                int _length = _address.length;
                if (length == _length) {
                    return Arrays.equals(address, _address);
                } else if (length == 2*_length) {
                    for (int i=0; i<_address.length; i++) {
                        if ((_address[i] < address[i]) 
                                || (_address[i] > address[i+_length])) {
                            return false;
                        }
                    }
                    return true;
                } else {
                    return false;
                }
            case DIR_NAME: 
                // FIXME: false:
                // directoryName according to 4.1.2.4
                // comparing the encoded forms of the names
                //TODO:
                //Legacy implementations exist where an RFC 822 name 
                //is embedded in the subject distinguished name in an 
                //attribute of type EmailAddress
            case X400_ADDR:
            case OTHER_NAME:
            case EDIP_NAME:
            case REG_ID:
                return Arrays.equals(getEncoded(), gname.getEncoded());
            default:
                // should never happen
        }
        return true;
    
public static int[]oidStrToInts(java.lang.String oid)
Converts OID into array of bytes.

        byte[] bytes = oid.getBytes();
        if (bytes[bytes.length-1] == '.") {
            throw new IOException(Messages.getString("security.56", oid)); //$NON-NLS-1$
        }
        int[] result = new int[bytes.length/2+1]; // best case: a.b.c.d.e
        int number = 0; // the number of OID's components
        for (int i=0; i<bytes.length; i++) {
            int value = 0;
            int pos = i;
            while ((i < bytes.length) && (bytes[i] >= '0")
                        && (bytes[i] <= '9")) {
                value = 10 * value + (bytes[i++] - 48);
            }
            if (i == pos) {
                // the number was not read
                throw new IOException(Messages.getString("security.56", oid)); //$NON-NLS-1$
            }
            result[number++] = value;
            if (i >= bytes.length) {
                break;
            }
            if (bytes[i] != '.") {
                throw new IOException(Messages.getString("security.56", oid)); //$NON-NLS-1$
            }
        }
        if (number < 2) {
            throw new IOException(Messages.getString("security.18A", oid));//$NON-NLS-1$
        }
        int[] res = new int[number];
        for (int i=0; i<number; i++) {
            res[i] = result[i];
        }
        return res;
    
public java.lang.StringtoString()
TODO

return

        String result = ""; //$NON-NLS-1$
        switch (tag) {
            case OTHER_NAME:
                result = "otherName[0]: "  //$NON-NLS-1$
                         + getBytesAsString(getEncoded());
                break;
            case RFC822_NAME:
                result = "rfc822Name[1]: " + name; //$NON-NLS-1$
                break;
            case DNS_NAME:
                result = "dNSName[2]: " + name; //$NON-NLS-1$
                break;
            case UR_ID:
                result = "uniformResourceIdentifier[6]: " + name; //$NON-NLS-1$
                break;
            case REG_ID:
                result = "registeredID[8]: " + ObjectIdentifier.toString((int[]) name); //$NON-NLS-1$
                break;
            case X400_ADDR:
                result = "x400Address[3]: "  //$NON-NLS-1$
                         + getBytesAsString(getEncoded());
                break;
            case DIR_NAME: 
                result = "directoryName[4]: "  //$NON-NLS-1$
                         + ((Name) name).getName(X500Principal.RFC2253);
                break;
            case EDIP_NAME:
                result = "ediPartyName[5]: "  //$NON-NLS-1$
                         + getBytesAsString(getEncoded());
                break;
            case IP_ADDR: 
                result = "iPAddress[7]: " + ipBytesToStr((byte[]) name); //$NON-NLS-1$
                break;
            default:
                // should never happen
        }
        return result;