001package org.apache.commons.ssl.org.bouncycastle.asn1.x509;
002
003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Enumerated;
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
010import org.apache.commons.ssl.org.bouncycastle.asn1.DERBitString;
011import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
012
013/**
014 * ObjectDigestInfo ASN.1 structure used in v2 attribute certificates.
015 * 
016 * <pre>
017 *  
018 *    ObjectDigestInfo ::= SEQUENCE {
019 *         digestedObjectType  ENUMERATED {
020 *                 publicKey            (0),
021 *                 publicKeyCert        (1),
022 *                 otherObjectTypes     (2) },
023 *                         -- otherObjectTypes MUST NOT
024 *                         -- be used in this profile
025 *         otherObjectTypeID   OBJECT IDENTIFIER OPTIONAL,
026 *         digestAlgorithm     AlgorithmIdentifier,
027 *         objectDigest        BIT STRING
028 *    }
029 *   
030 * </pre>
031 * 
032 */
033public class ObjectDigestInfo
034    extends ASN1Object
035{
036    /**
037     * The public key is hashed.
038     */
039    public final static int publicKey = 0;
040
041    /**
042     * The public key certificate is hashed.
043     */
044    public final static int publicKeyCert = 1;
045
046    /**
047     * An other object is hashed.
048     */
049    public final static int otherObjectDigest = 2;
050
051    ASN1Enumerated digestedObjectType;
052
053    ASN1ObjectIdentifier otherObjectTypeID;
054
055    AlgorithmIdentifier digestAlgorithm;
056
057    DERBitString objectDigest;
058
059    public static ObjectDigestInfo getInstance(
060        Object obj)
061    {
062        if (obj instanceof ObjectDigestInfo)
063        {
064            return (ObjectDigestInfo)obj;
065        }
066
067        if (obj != null)
068        {
069            return new ObjectDigestInfo(ASN1Sequence.getInstance(obj));
070        }
071
072        return null;
073    }
074
075    public static ObjectDigestInfo getInstance(
076        ASN1TaggedObject obj,
077        boolean          explicit)
078    {
079        return getInstance(ASN1Sequence.getInstance(obj, explicit));
080    }
081
082    /**
083     * Constructor from given details.
084     * <p>
085     * If <code>digestedObjectType</code> is not {@link #publicKeyCert} or
086     * {@link #publicKey} <code>otherObjectTypeID</code> must be given,
087     * otherwise it is ignored.
088     * 
089     * @param digestedObjectType The digest object type.
090     * @param otherObjectTypeID The object type ID for
091     *            <code>otherObjectDigest</code>.
092     * @param digestAlgorithm The algorithm identifier for the hash.
093     * @param objectDigest The hash value.
094     */
095    public ObjectDigestInfo(
096        int digestedObjectType,
097        ASN1ObjectIdentifier otherObjectTypeID,
098        AlgorithmIdentifier digestAlgorithm,
099        byte[] objectDigest)
100    {
101        this.digestedObjectType = new ASN1Enumerated(digestedObjectType);
102        if (digestedObjectType == otherObjectDigest)
103        {
104            this.otherObjectTypeID = otherObjectTypeID;
105        }
106
107        this.digestAlgorithm = digestAlgorithm;
108        this.objectDigest = new DERBitString(objectDigest);
109    }
110
111    private ObjectDigestInfo(
112        ASN1Sequence seq)
113    {
114        if (seq.size() > 4 || seq.size() < 3)
115        {
116            throw new IllegalArgumentException("Bad sequence size: "
117                + seq.size());
118        }
119
120        digestedObjectType = ASN1Enumerated.getInstance(seq.getObjectAt(0));
121
122        int offset = 0;
123
124        if (seq.size() == 4)
125        {
126            otherObjectTypeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(1));
127            offset++;
128        }
129
130        digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset));
131
132        objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset));
133    }
134
135    public ASN1Enumerated getDigestedObjectType()
136    {
137        return digestedObjectType;
138    }
139
140    public ASN1ObjectIdentifier getOtherObjectTypeID()
141    {
142        return otherObjectTypeID;
143    }
144
145    public AlgorithmIdentifier getDigestAlgorithm()
146    {
147        return digestAlgorithm;
148    }
149
150    public DERBitString getObjectDigest()
151    {
152        return objectDigest;
153    }
154
155    /**
156     * Produce an object suitable for an ASN1OutputStream.
157     * 
158     * <pre>
159     *  
160     *    ObjectDigestInfo ::= SEQUENCE {
161     *         digestedObjectType  ENUMERATED {
162     *                 publicKey            (0),
163     *                 publicKeyCert        (1),
164     *                 otherObjectTypes     (2) },
165     *                         -- otherObjectTypes MUST NOT
166     *                         -- be used in this profile
167     *         otherObjectTypeID   OBJECT IDENTIFIER OPTIONAL,
168     *         digestAlgorithm     AlgorithmIdentifier,
169     *         objectDigest        BIT STRING
170     *    }
171     *   
172     * </pre>
173     */
174    public ASN1Primitive toASN1Primitive()
175    {
176        ASN1EncodableVector v = new ASN1EncodableVector();
177
178        v.add(digestedObjectType);
179
180        if (otherObjectTypeID != null)
181        {
182            v.add(otherObjectTypeID);
183        }
184
185        v.add(digestAlgorithm);
186        v.add(objectDigest);
187
188        return new DERSequence(v);
189    }
190}