001package org.apache.commons.ssl.org.bouncycastle.asn1.x509.sigi;
002
003import java.math.BigInteger;
004import java.util.Enumeration;
005
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1GeneralizedTime;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
013import org.apache.commons.ssl.org.bouncycastle.asn1.DERPrintableString;
014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
015import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
016import org.apache.commons.ssl.org.bouncycastle.asn1.x500.DirectoryString;
017
018/**
019 * Contains personal data for the otherName field in the subjectAltNames
020 * extension.
021 *
022 * <pre>
023 *     PersonalData ::= SEQUENCE {
024 *       nameOrPseudonym NameOrPseudonym,
025 *       nameDistinguisher [0] INTEGER OPTIONAL,
026 *       dateOfBirth [1] GeneralizedTime OPTIONAL,
027 *       placeOfBirth [2] DirectoryString OPTIONAL,
028 *       gender [3] PrintableString OPTIONAL,
029 *       postalAddress [4] DirectoryString OPTIONAL
030 *       }
031 * </pre>
032 *
033 * @see org.bouncycastle.asn1.x509.sigi.NameOrPseudonym
034 * @see org.bouncycastle.asn1.x509.sigi.SigIObjectIdentifiers
035 */
036public class PersonalData
037    extends ASN1Object
038{
039    private NameOrPseudonym nameOrPseudonym;
040    private BigInteger nameDistinguisher;
041    private ASN1GeneralizedTime dateOfBirth;
042    private DirectoryString placeOfBirth;
043    private String gender;
044    private DirectoryString postalAddress;
045
046    public static PersonalData getInstance(Object obj)
047    {
048        if (obj == null || obj instanceof PersonalData)
049        {
050            return (PersonalData)obj;
051        }
052
053        if (obj instanceof ASN1Sequence)
054        {
055            return new PersonalData((ASN1Sequence)obj);
056        }
057
058        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
059    }
060
061    /**
062     * Constructor from ASN1Sequence.
063     * <p>
064     * The sequence is of type NameOrPseudonym:
065     * <pre>
066     *     PersonalData ::= SEQUENCE {
067     *       nameOrPseudonym NameOrPseudonym,
068     *       nameDistinguisher [0] INTEGER OPTIONAL,
069     *       dateOfBirth [1] GeneralizedTime OPTIONAL,
070     *       placeOfBirth [2] DirectoryString OPTIONAL,
071     *       gender [3] PrintableString OPTIONAL,
072     *       postalAddress [4] DirectoryString OPTIONAL
073     *       }
074     * </pre>
075     * </p>
076     * @param seq The ASN.1 sequence.
077     */
078    private PersonalData(ASN1Sequence seq)
079    {
080        if (seq.size() < 1)
081        {
082            throw new IllegalArgumentException("Bad sequence size: "
083                + seq.size());
084        }
085
086        Enumeration e = seq.getObjects();
087
088        nameOrPseudonym = NameOrPseudonym.getInstance(e.nextElement());
089
090        while (e.hasMoreElements())
091        {
092            ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement());
093            int tag = o.getTagNo();
094            switch (tag)
095            {
096                case 0:
097                    nameDistinguisher = ASN1Integer.getInstance(o, false).getValue();
098                    break;
099                case 1:
100                    dateOfBirth = ASN1GeneralizedTime.getInstance(o, false);
101                    break;
102                case 2:
103                    placeOfBirth = DirectoryString.getInstance(o, true);
104                    break;
105                case 3:
106                    gender = DERPrintableString.getInstance(o, false).getString();
107                    break;
108                case 4:
109                    postalAddress = DirectoryString.getInstance(o, true);
110                    break;
111                default:
112                    throw new IllegalArgumentException("Bad tag number: " + o.getTagNo());
113            }
114        }
115    }
116
117    /**
118     * Constructor from a given details.
119     *
120     * @param nameOrPseudonym   Name or pseudonym.
121     * @param nameDistinguisher Name distinguisher.
122     * @param dateOfBirth       Date of birth.
123     * @param placeOfBirth      Place of birth.
124     * @param gender            Gender.
125     * @param postalAddress     Postal Address.
126     */
127    public PersonalData(NameOrPseudonym nameOrPseudonym,
128                        BigInteger nameDistinguisher, ASN1GeneralizedTime dateOfBirth,
129                        DirectoryString placeOfBirth, String gender, DirectoryString postalAddress)
130    {
131        this.nameOrPseudonym = nameOrPseudonym;
132        this.dateOfBirth = dateOfBirth;
133        this.gender = gender;
134        this.nameDistinguisher = nameDistinguisher;
135        this.postalAddress = postalAddress;
136        this.placeOfBirth = placeOfBirth;
137    }
138
139    public NameOrPseudonym getNameOrPseudonym()
140    {
141        return nameOrPseudonym;
142    }
143
144    public BigInteger getNameDistinguisher()
145    {
146        return nameDistinguisher;
147    }
148
149    public ASN1GeneralizedTime getDateOfBirth()
150    {
151        return dateOfBirth;
152    }
153
154    public DirectoryString getPlaceOfBirth()
155    {
156        return placeOfBirth;
157    }
158
159    public String getGender()
160    {
161        return gender;
162    }
163
164    public DirectoryString getPostalAddress()
165    {
166        return postalAddress;
167    }
168
169    /**
170     * Produce an object suitable for an ASN1OutputStream.
171     * <p>
172     * Returns:
173     * <pre>
174     *     PersonalData ::= SEQUENCE {
175     *       nameOrPseudonym NameOrPseudonym,
176     *       nameDistinguisher [0] INTEGER OPTIONAL,
177     *       dateOfBirth [1] GeneralizedTime OPTIONAL,
178     *       placeOfBirth [2] DirectoryString OPTIONAL,
179     *       gender [3] PrintableString OPTIONAL,
180     *       postalAddress [4] DirectoryString OPTIONAL
181     *       }
182     * </pre>
183     *
184     * @return a DERObject
185     */
186    public ASN1Primitive toASN1Primitive()
187    {
188        ASN1EncodableVector vec = new ASN1EncodableVector();
189        vec.add(nameOrPseudonym);
190        if (nameDistinguisher != null)
191        {
192            vec.add(new DERTaggedObject(false, 0, new ASN1Integer(nameDistinguisher)));
193        }
194        if (dateOfBirth != null)
195        {
196            vec.add(new DERTaggedObject(false, 1, dateOfBirth));
197        }
198        if (placeOfBirth != null)
199        {
200            vec.add(new DERTaggedObject(true, 2, placeOfBirth));
201        }
202        if (gender != null)
203        {
204            vec.add(new DERTaggedObject(false, 3, new DERPrintableString(gender, true)));
205        }
206        if (postalAddress != null)
207        {
208            vec.add(new DERTaggedObject(true, 4, postalAddress));
209        }
210        return new DERSequence(vec);
211    }
212}