1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.util.Arrays;
64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.util.Strings;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
9d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * DER VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
10d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * <p>
11d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * Explicit character set escape sequences are not allowed.
12d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * </p>
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERVisibleString
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Primitive
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    implements ASN1String
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
1879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro    private final byte[]  string;
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
21d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root     * Return a Visible String from the passed in object.
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
23d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root     * @param obj a DERVisibleString or an object that can be converted into one.
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the object cannot be converted.
25d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root     * @return a DERVisibleString instance, or null
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static DERVisibleString getInstance(
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null || obj instanceof DERVisibleString)
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (DERVisibleString)obj;
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        if (obj instanceof byte[])
3670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        {
3770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            try
3870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            {
3970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                return (DERVisibleString)fromByteArray((byte[])obj);
4070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            }
4170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            catch (Exception e)
4270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            {
4370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
4470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            }
4570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        }
4670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
51d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root     * Return a Visible String from a tagged object.
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object holding the object we want
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is meant to be explicitly
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *              tagged false otherwise.
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the tagged object cannot
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *               be converted.
58d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root     * @return a DERVisibleString instance, or null
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static DERVisibleString getInstance(
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject obj,
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean          explicit)
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive o = obj.getObject();
654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (explicit || o instanceof DERVisibleString)
674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return getInstance(o);
694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets());
734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
7679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro    /*
77d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root     * Basic constructor - byte encoded string.
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    DERVisibleString(
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]   string)
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.string = string;
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
86d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root     * Basic constructor
8779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro     *
8879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro     * @param string the string to be carried in the VisibleString object,
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DERVisibleString(
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String   string)
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.string = Strings.toByteArray(string);
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getString()
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return Strings.fromByteArray(string);
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public String toString()
102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return getString();
104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public byte[] getOctets()
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return Arrays.clone(string);
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    boolean isConstructed()
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return false;
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    int encodedLength()
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    void encode(
1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1OutputStream out)
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.writeEncoded(BERTags.VISIBLE_STRING, this.string);
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
128c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    boolean asn1Equals(
1294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive o)
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
131c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!(o instanceof DERVisibleString))
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return Arrays.areEqual(string, ((DERVisibleString)o).string);
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int hashCode()
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return Arrays.hashCode(string);
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
144