001package org.apache.commons.ssl.org.bouncycastle.asn1.isismtt.x509;
002
003import java.util.Enumeration;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
011import org.apache.commons.ssl.org.bouncycastle.asn1.DERPrintableString;
012import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
013import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
014import org.apache.commons.ssl.org.bouncycastle.asn1.x500.DirectoryString;
015import org.apache.commons.ssl.org.bouncycastle.asn1.x509.GeneralName;
016import org.apache.commons.ssl.org.bouncycastle.asn1.x509.IssuerSerial;
017
018/**
019 * Attribute to indicate that the certificate holder may sign in the name of a
020 * third person.
021 * <p>
022 * ISIS-MTT PROFILE: The corresponding ProcurationSyntax contains either the
023 * name of the person who is represented (subcomponent thirdPerson) or a
024 * reference to his/her base certificate (in the component signingFor,
025 * subcomponent certRef), furthermore the optional components country and
026 * typeSubstitution to indicate the country whose laws apply, and respectively
027 * the type of procuration (e.g. manager, procuration, custody).
028 * <p>
029 * ISIS-MTT PROFILE: The GeneralName MUST be of type directoryName and MAY only
030 * contain: - RFC3039 attributes, except pseudonym (countryName, commonName,
031 * surname, givenName, serialNumber, organizationName, organizationalUnitName,
032 * stateOrProvincename, localityName, postalAddress) and - SubjectDirectoryName
033 * attributes (title, dateOfBirth, placeOfBirth, gender, countryOfCitizenship,
034 * countryOfResidence and NameAtBirth).
035 * 
036 * <pre>
037 *               ProcurationSyntax ::= SEQUENCE {
038 *                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
039 *                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
040 *                 signingFor [3] EXPLICIT SigningFor 
041 *               }
042 *               
043 *               SigningFor ::= CHOICE 
044 *               { 
045 *                 thirdPerson GeneralName,
046 *                 certRef IssuerSerial 
047 *               }
048 * </pre>
049 * 
050 */
051public class ProcurationSyntax
052    extends ASN1Object
053{
054    private String country;
055    private DirectoryString typeOfSubstitution;
056
057    private GeneralName thirdPerson;
058    private IssuerSerial certRef;
059
060    public static ProcurationSyntax getInstance(Object obj)
061    {
062        if (obj == null || obj instanceof ProcurationSyntax)
063        {
064            return (ProcurationSyntax)obj;
065        }
066
067        if (obj instanceof ASN1Sequence)
068        {
069            return new ProcurationSyntax((ASN1Sequence)obj);
070        }
071
072        throw new IllegalArgumentException("illegal object in getInstance: "
073            + obj.getClass().getName());
074    }
075
076    /**
077     * Constructor from ASN1Sequence.
078     * <p>
079     * The sequence is of type ProcurationSyntax:
080     * <pre>
081     *               ProcurationSyntax ::= SEQUENCE {
082     *                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
083     *                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
084     *                 signingFor [3] EXPLICIT SigningFor
085     *               }
086     *
087     *               SigningFor ::= CHOICE
088     *               {
089     *                 thirdPerson GeneralName,
090     *                 certRef IssuerSerial
091     *               }
092     * </pre>
093     * </p>
094     * @param seq The ASN.1 sequence.
095     */
096    private ProcurationSyntax(ASN1Sequence seq)
097    {
098        if (seq.size() < 1 || seq.size() > 3)
099        {
100            throw new IllegalArgumentException("Bad sequence size: " + seq.size());
101        }
102        Enumeration e = seq.getObjects();
103
104        while (e.hasMoreElements())
105        {
106            ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement());
107            switch (o.getTagNo())
108            {
109                case 1:
110                    country = DERPrintableString.getInstance(o, true).getString();
111                    break;
112                case 2:
113                    typeOfSubstitution = DirectoryString.getInstance(o, true);
114                    break;
115                case 3:
116                    ASN1Encodable signingFor = o.getObject();
117                    if (signingFor instanceof ASN1TaggedObject)
118                    {
119                        thirdPerson = GeneralName.getInstance(signingFor);
120                    }
121                    else
122                    {
123                        certRef = IssuerSerial.getInstance(signingFor);
124                    }
125                    break;
126                default:
127                    throw new IllegalArgumentException("Bad tag number: " + o.getTagNo());
128            }
129        }
130    }
131
132    /**
133     * Constructor from a given details.
134     * <p>
135     * Either <code>generalName</code> or <code>certRef</code> MUST be
136     * <code>null</code>.
137     *
138     * @param country            The country code whose laws apply.
139     * @param typeOfSubstitution The type of procuration.
140     * @param certRef            Reference to certificate of the person who is represented.
141     */
142    public ProcurationSyntax(
143        String country,
144        DirectoryString typeOfSubstitution,
145        IssuerSerial certRef)
146    {
147        this.country = country;
148        this.typeOfSubstitution = typeOfSubstitution;
149        this.thirdPerson = null;
150        this.certRef = certRef;
151    }
152
153    /**
154     * Constructor from a given details.
155     * <p>
156     * Either <code>generalName</code> or <code>certRef</code> MUST be
157     * <code>null</code>.
158     *
159     * @param country            The country code whose laws apply.
160     * @param typeOfSubstitution The type of procuration.
161     * @param thirdPerson        The GeneralName of the person who is represented.
162     */
163    public ProcurationSyntax(
164        String country,
165        DirectoryString typeOfSubstitution,
166        GeneralName thirdPerson)
167    {
168        this.country = country;
169        this.typeOfSubstitution = typeOfSubstitution;
170        this.thirdPerson = thirdPerson;
171        this.certRef = null;
172    }
173
174    public String getCountry()
175    {
176        return country;
177    }
178
179    public DirectoryString getTypeOfSubstitution()
180    {
181        return typeOfSubstitution;
182    }
183
184    public GeneralName getThirdPerson()
185    {
186        return thirdPerson;
187    }
188
189    public IssuerSerial getCertRef()
190    {
191        return certRef;
192    }
193
194    /**
195     * Produce an object suitable for an ASN1OutputStream.
196     * <p>
197     * Returns:
198     * <pre>
199     *               ProcurationSyntax ::= SEQUENCE {
200     *                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
201     *                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
202     *                 signingFor [3] EXPLICIT SigningFor
203     *               }
204     *
205     *               SigningFor ::= CHOICE
206     *               {
207     *                 thirdPerson GeneralName,
208     *                 certRef IssuerSerial
209     *               }
210     * </pre>
211     *
212     * @return a DERObject
213     */
214    public ASN1Primitive toASN1Primitive()
215    {
216        ASN1EncodableVector vec = new ASN1EncodableVector();
217        if (country != null)
218        {
219            vec.add(new DERTaggedObject(true, 1, new DERPrintableString(country, true)));
220        }
221        if (typeOfSubstitution != null)
222        {
223            vec.add(new DERTaggedObject(true, 2, typeOfSubstitution));
224        }
225        if (thirdPerson != null)
226        {
227            vec.add(new DERTaggedObject(true, 3, thirdPerson));
228        }
229        else
230        {
231            vec.add(new DERTaggedObject(true, 3, certRef));
232        }
233
234        return new DERSequence(vec);
235    }
236}