Home | History | Annotate | Download | only in asn1
      1 package org.bouncycastle.asn1;
      2 
      3 import java.io.ByteArrayOutputStream;
      4 import java.io.IOException;
      5 
      6 /**
      7  * Class representing the DER-type External
      8  */
      9 public class DERExternal
     10     extends ASN1Object
     11 {
     12     private DERObjectIdentifier directReference;
     13     private DERInteger indirectReference;
     14     private ASN1Object dataValueDescriptor;
     15     private int encoding;
     16     private DERObject externalContent;
     17 
     18     public DERExternal(ASN1EncodableVector vector)
     19     {
     20         int offset = 0;
     21 
     22         DERObject enc = getObjFromVector(vector, offset);
     23         if (enc instanceof DERObjectIdentifier)
     24         {
     25             directReference = (DERObjectIdentifier)enc;
     26             offset++;
     27             enc = getObjFromVector(vector, offset);
     28         }
     29         if (enc instanceof DERInteger)
     30         {
     31             indirectReference = (DERInteger) enc;
     32             offset++;
     33             enc = getObjFromVector(vector, offset);
     34         }
     35         if (!(enc instanceof DERTaggedObject))
     36         {
     37             dataValueDescriptor = (ASN1Object) enc;
     38             offset++;
     39             enc = getObjFromVector(vector, offset);
     40         }
     41 
     42         if (vector.size() != offset + 1)
     43         {
     44             throw new IllegalArgumentException("input vector too large");
     45         }
     46 
     47         if (!(enc instanceof DERTaggedObject))
     48         {
     49             throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
     50         }
     51         DERTaggedObject obj = (DERTaggedObject)enc;
     52         setEncoding(obj.getTagNo());
     53         externalContent = obj.getObject();
     54     }
     55 
     56     private DERObject getObjFromVector(ASN1EncodableVector v, int index)
     57     {
     58         if (v.size() <= index)
     59         {
     60             throw new IllegalArgumentException("too few objects in input vector");
     61         }
     62 
     63         return v.get(index).getDERObject();
     64     }
     65     /**
     66      * Creates a new instance of DERExternal
     67      * See X.690 for more informations about the meaning of these parameters
     68      * @param directReference The direct reference or <code>null</code> if not set.
     69      * @param indirectReference The indirect reference or <code>null</code> if not set.
     70      * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
     71      * @param externalData The external data in its encoded form.
     72      */
     73     public DERExternal(DERObjectIdentifier directReference, DERInteger indirectReference, ASN1Object dataValueDescriptor, DERTaggedObject externalData)
     74     {
     75         this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.getDERObject());
     76     }
     77 
     78     /**
     79      * Creates a new instance of DERExternal.
     80      * See X.690 for more informations about the meaning of these parameters
     81      * @param directReference The direct reference or <code>null</code> if not set.
     82      * @param indirectReference The indirect reference or <code>null</code> if not set.
     83      * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
     84      * @param encoding The encoding to be used for the external data
     85      * @param externalData The external data
     86      */
     87     public DERExternal(DERObjectIdentifier directReference, DERInteger indirectReference, ASN1Object dataValueDescriptor, int encoding, DERObject externalData)
     88     {
     89         setDirectReference(directReference);
     90         setIndirectReference(indirectReference);
     91         setDataValueDescriptor(dataValueDescriptor);
     92         setEncoding(encoding);
     93         setExternalContent(externalData.getDERObject());
     94     }
     95 
     96     /* (non-Javadoc)
     97      * @see java.lang.Object#hashCode()
     98      */
     99     public int hashCode()
    100     {
    101         int ret = 0;
    102         if (directReference != null)
    103         {
    104             ret = directReference.hashCode();
    105         }
    106         if (indirectReference != null)
    107         {
    108             ret ^= indirectReference.hashCode();
    109         }
    110         if (dataValueDescriptor != null)
    111         {
    112             ret ^= dataValueDescriptor.hashCode();
    113         }
    114         ret ^= externalContent.hashCode();
    115         return ret;
    116     }
    117 
    118     /* (non-Javadoc)
    119      * @see org.bouncycastle.asn1.DERObject#encode(org.bouncycastle.asn1.DEROutputStream)
    120      */
    121     void encode(DEROutputStream out)
    122         throws IOException
    123     {
    124         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    125         if (directReference != null)
    126         {
    127             baos.write(directReference.getDEREncoded());
    128         }
    129         if (indirectReference != null)
    130         {
    131             baos.write(indirectReference.getDEREncoded());
    132         }
    133         if (dataValueDescriptor != null)
    134         {
    135             baos.write(dataValueDescriptor.getDEREncoded());
    136         }
    137         DERTaggedObject obj = new DERTaggedObject(encoding, externalContent);
    138         baos.write(obj.getDEREncoded());
    139         out.writeEncoded(DERTags.CONSTRUCTED, DERTags.EXTERNAL, baos.toByteArray());
    140     }
    141 
    142     /* (non-Javadoc)
    143      * @see org.bouncycastle.asn1.ASN1Object#asn1Equals(org.bouncycastle.asn1.DERObject)
    144      */
    145     boolean asn1Equals(DERObject o)
    146     {
    147         if (!(o instanceof DERExternal))
    148         {
    149             return false;
    150         }
    151         if (this == o)
    152         {
    153             return true;
    154         }
    155         DERExternal other = (DERExternal)o;
    156         if (directReference != null)
    157         {
    158             if (other.directReference == null || !other.directReference.equals(directReference))
    159             {
    160                 return false;
    161             }
    162         }
    163         if (indirectReference != null)
    164         {
    165             if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
    166             {
    167                 return false;
    168             }
    169         }
    170         if (dataValueDescriptor != null)
    171         {
    172             if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
    173             {
    174                 return false;
    175             }
    176         }
    177         return externalContent.equals(other.externalContent);
    178     }
    179 
    180     /**
    181      * Returns the data value descriptor
    182      * @return The descriptor
    183      */
    184     public ASN1Object getDataValueDescriptor()
    185     {
    186         return dataValueDescriptor;
    187     }
    188 
    189     /**
    190      * Returns the direct reference of the external element
    191      * @return The reference
    192      */
    193     public DERObjectIdentifier getDirectReference()
    194     {
    195         return directReference;
    196     }
    197 
    198     /**
    199      * Returns the encoding of the content. Valid values are
    200      * <ul>
    201      * <li><code>0</code> single-ASN1-type</li>
    202      * <li><code>1</code> OCTET STRING</li>
    203      * <li><code>2</code> BIT STRING</li>
    204      * </ul>
    205      * @return The encoding
    206      */
    207     public int getEncoding()
    208     {
    209         return encoding;
    210     }
    211 
    212     /**
    213      * Returns the content of this element
    214      * @return The content
    215      */
    216     public DERObject getExternalContent()
    217     {
    218         return externalContent;
    219     }
    220 
    221     /**
    222      * Returns the indirect reference of this element
    223      * @return The reference
    224      */
    225     public DERInteger getIndirectReference()
    226     {
    227         return indirectReference;
    228     }
    229 
    230     /**
    231      * Sets the data value descriptor
    232      * @param dataValueDescriptor The descriptor
    233      */
    234     private void setDataValueDescriptor(ASN1Object dataValueDescriptor)
    235     {
    236         this.dataValueDescriptor = dataValueDescriptor;
    237     }
    238 
    239     /**
    240      * Sets the direct reference of the external element
    241      * @param directReferemce The reference
    242      */
    243     private void setDirectReference(DERObjectIdentifier directReferemce)
    244     {
    245         this.directReference = directReferemce;
    246     }
    247 
    248     /**
    249      * Sets the encoding of the content. Valid values are
    250      * <ul>
    251      * <li><code>0</code> single-ASN1-type</li>
    252      * <li><code>1</code> OCTET STRING</li>
    253      * <li><code>2</code> BIT STRING</li>
    254      * </ul>
    255      * @param encoding The encoding
    256      */
    257     private void setEncoding(int encoding)
    258     {
    259         if (encoding < 0 || encoding > 2)
    260         {
    261             throw new IllegalArgumentException("invalid encoding value: " + encoding);
    262         }
    263         this.encoding = encoding;
    264     }
    265 
    266     /**
    267      * Sets the content of this element
    268      * @param externalContent The content
    269      */
    270     private void setExternalContent(DERObject externalContent)
    271     {
    272         this.externalContent = externalContent;
    273     }
    274 
    275     /**
    276      * Sets the indirect reference of this element
    277      * @param indirectReference The reference
    278      */
    279     private void setIndirectReference(DERInteger indirectReference)
    280     {
    281         this.indirectReference = indirectReference;
    282     }
    283 }
    284