1package org.bouncycastle.asn1.x509;
2
3import org.bouncycastle.asn1.ASN1Encodable;
4import org.bouncycastle.asn1.ASN1EncodableVector;
5import org.bouncycastle.asn1.ASN1Sequence;
6import org.bouncycastle.asn1.ASN1TaggedObject;
7import org.bouncycastle.asn1.DEREncodable;
8import org.bouncycastle.asn1.DERObject;
9import org.bouncycastle.asn1.DERSequence;
10import org.bouncycastle.asn1.DERString;
11import org.bouncycastle.asn1.DERTaggedObject;
12
13/**
14 * Implementation of the RoleSyntax object as specified by the RFC3281.
15 *
16 * <pre>
17 * RoleSyntax ::= SEQUENCE {
18 *                 roleAuthority  [0] GeneralNames OPTIONAL,
19 *                 roleName       [1] GeneralName
20 *           }
21 * </pre>
22 */
23public class RoleSyntax
24    extends ASN1Encodable
25{
26    private GeneralNames roleAuthority;
27    private GeneralName roleName;
28
29    /**
30     * RoleSyntax factory method.
31     * @param obj the object used to construct an instance of <code>
32     * RoleSyntax</code>. It must be an instance of <code>RoleSyntax
33     * </code> or <code>ASN1Sequence</code>.
34     * @return the instance of <code>RoleSyntax</code> built from the
35     * supplied object.
36     * @throws java.lang.IllegalArgumentException if the object passed
37     * to the factory is not an instance of <code>RoleSyntax</code> or
38     * <code>ASN1Sequence</code>.
39     */
40    public static RoleSyntax getInstance(
41        Object obj)
42    {
43
44        if(obj == null || obj instanceof RoleSyntax)
45        {
46            return (RoleSyntax)obj;
47        }
48        else if(obj instanceof ASN1Sequence)
49        {
50            return new RoleSyntax((ASN1Sequence)obj);
51        }
52        throw new IllegalArgumentException("Unknown object in RoleSyntax factory.");
53    }
54
55    /**
56     * Constructor.
57     * @param roleAuthority the role authority of this RoleSyntax.
58     * @param roleName    the role name of this RoleSyntax.
59     */
60    public RoleSyntax(
61        GeneralNames roleAuthority,
62        GeneralName roleName)
63    {
64        if(roleName == null ||
65                roleName.getTagNo() != GeneralName.uniformResourceIdentifier ||
66                ((DERString)roleName.getName()).getString().equals(""))
67        {
68            throw new IllegalArgumentException("the role name MUST be non empty and MUST " +
69                    "use the URI option of GeneralName");
70        }
71        this.roleAuthority = roleAuthority;
72        this.roleName = roleName;
73    }
74
75    /**
76     * Constructor. Invoking this constructor is the same as invoking
77     * <code>new RoleSyntax(null, roleName)</code>.
78     * @param roleName    the role name of this RoleSyntax.
79     */
80    public RoleSyntax(
81        GeneralName roleName)
82    {
83        this(null, roleName);
84    }
85
86    /**
87     * Utility constructor. Takes a <code>String</code> argument representing
88     * the role name, builds a <code>GeneralName</code> to hold the role name
89     * and calls the constructor that takes a <code>GeneralName</code>.
90     * @param roleName
91     */
92    public RoleSyntax(
93        String roleName)
94    {
95        this(new GeneralName(GeneralName.uniformResourceIdentifier,
96                (roleName == null)? "": roleName));
97    }
98
99    /**
100     * Constructor that builds an instance of <code>RoleSyntax</code> by
101     * extracting the encoded elements from the <code>ASN1Sequence</code>
102     * object supplied.
103     * @param seq    an instance of <code>ASN1Sequence</code> that holds
104     * the encoded elements used to build this <code>RoleSyntax</code>.
105     */
106    public RoleSyntax(
107        ASN1Sequence seq)
108    {
109        if (seq.size() < 1 || seq.size() > 2)
110        {
111            throw new IllegalArgumentException("Bad sequence size: "
112                    + seq.size());
113        }
114
115        for (int i = 0; i != seq.size(); i++)
116        {
117            ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
118            switch (taggedObject.getTagNo())
119            {
120            case 0:
121                roleAuthority = GeneralNames.getInstance(taggedObject, false);
122                break;
123            case 1:
124                roleName = GeneralName.getInstance(taggedObject, false);
125                break;
126            default:
127                throw new IllegalArgumentException("Unknown tag in RoleSyntax");
128            }
129        }
130    }
131
132    /**
133     * Gets the role authority of this RoleSyntax.
134     * @return    an instance of <code>GeneralNames</code> holding the
135     * role authority of this RoleSyntax.
136     */
137    public GeneralNames getRoleAuthority()
138    {
139        return this.roleAuthority;
140    }
141
142    /**
143     * Gets the role name of this RoleSyntax.
144     * @return    an instance of <code>GeneralName</code> holding the
145     * role name of this RoleSyntax.
146     */
147    public GeneralName getRoleName()
148    {
149        return this.roleName;
150    }
151
152    /**
153     * Gets the role name as a <code>java.lang.String</code> object.
154     * @return    the role name of this RoleSyntax represented as a
155     * <code>java.lang.String</code> object.
156     */
157    public String getRoleNameAsString()
158    {
159        DERString str = (DERString)this.roleName.getName();
160
161        return str.getString();
162    }
163
164    /**
165     * Gets the role authority as a <code>String[]</code> object.
166     * @return the role authority of this RoleSyntax represented as a
167     * <code>String[]<code> array.
168     */
169    public String[] getRoleAuthorityAsString()
170    {
171        if(roleAuthority == null)
172        {
173            return new String[0];
174        }
175
176        GeneralName[] names = roleAuthority.getNames();
177        String[] namesString = new String[names.length];
178        for(int i = 0; i < names.length; i++)
179        {
180            DEREncodable value = names[i].getName();
181            if(value instanceof DERString)
182            {
183                namesString[i] = ((DERString)value).getString();
184            }
185            else
186            {
187                namesString[i] = value.toString();
188            }
189        }
190        return namesString;
191    }
192
193    /**
194     * Implementation of the method <code>toASN1Object</code> as
195     * required by the superclass <code>ASN1Encodable</code>.
196     *
197     * <pre>
198     * RoleSyntax ::= SEQUENCE {
199     *                 roleAuthority  [0] GeneralNames OPTIONAL,
200     *                 roleName       [1] GeneralName
201     *           }
202     * </pre>
203     */
204    public DERObject toASN1Object()
205    {
206        ASN1EncodableVector v = new ASN1EncodableVector();
207        if(this.roleAuthority != null)
208        {
209            v.add(new DERTaggedObject(false, 0, roleAuthority));
210        }
211        v.add(new DERTaggedObject(false, 1, roleName));
212
213        return new DERSequence(v);
214    }
215
216    public String toString()
217    {
218        StringBuffer buff = new StringBuffer("Name: " + this.getRoleNameAsString() +
219                " - Auth: ");
220        if(this.roleAuthority == null || roleAuthority.getNames().length == 0)
221        {
222            buff.append("N/A");
223        }
224        else
225        {
226            String[] names = this.getRoleAuthorityAsString();
227            buff.append('[').append(names[0]);
228            for(int i = 1; i < names.length; i++)
229            {
230                    buff.append(", ").append(names[i]);
231            }
232            buff.append(']');
233        }
234        return buff.toString();
235    }
236}
237