blob: f6c45d311cb5c40e39575b6a808335137e012951 [file] [log] [blame]
package org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* Class representing the DER-type External
*/
public class DERExternal
extends ASN1Primitive
{
private ASN1ObjectIdentifier directReference;
private ASN1Integer indirectReference;
private ASN1Primitive dataValueDescriptor;
private int encoding;
private ASN1Primitive externalContent;
public DERExternal(ASN1EncodableVector vector)
{
int offset = 0;
ASN1Primitive enc = getObjFromVector(vector, offset);
if (enc instanceof ASN1ObjectIdentifier)
{
directReference = (ASN1ObjectIdentifier)enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (enc instanceof ASN1Integer)
{
indirectReference = (ASN1Integer) enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (!(enc instanceof ASN1TaggedObject))
{
dataValueDescriptor = (ASN1Primitive) enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (vector.size() != offset + 1)
{
throw new IllegalArgumentException("input vector too large");
}
if (!(enc instanceof ASN1TaggedObject))
{
throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
}
ASN1TaggedObject obj = (ASN1TaggedObject)enc;
setEncoding(obj.getTagNo());
externalContent = obj.getObject();
}
private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
{
if (v.size() <= index)
{
throw new IllegalArgumentException("too few objects in input vector");
}
return v.get(index).toASN1Primitive();
}
/**
* Creates a new instance of DERExternal
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
}
/**
* Creates a new instance of DERExternal.
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
setDirectReference(directReference);
setIndirectReference(indirectReference);
setDataValueDescriptor(dataValueDescriptor);
setEncoding(encoding);
setExternalContent(externalData.toASN1Primitive());
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode()
{
int ret = 0;
if (directReference != null)
{
ret = directReference.hashCode();
}
if (indirectReference != null)
{
ret ^= indirectReference.hashCode();
}
if (dataValueDescriptor != null)
{
ret ^= dataValueDescriptor.hashCode();
}
ret ^= externalContent.hashCode();
return ret;
}
boolean isConstructed()
{
return true;
}
int encodedLength()
throws IOException
{
return this.getEncoded().length;
}
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
void encode(ASN1OutputStream out)
throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (directReference != null)
{
baos.write(directReference.getEncoded(ASN1Encoding.DER));
}
if (indirectReference != null)
{
baos.write(indirectReference.getEncoded(ASN1Encoding.DER));
}
if (dataValueDescriptor != null)
{
baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER));
}
DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
baos.write(obj.getEncoded(ASN1Encoding.DER));
out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
}
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive)
*/
boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof DERExternal))
{
return false;
}
if (this == o)
{
return true;
}
DERExternal other = (DERExternal)o;
if (directReference != null)
{
if (other.directReference == null || !other.directReference.equals(directReference))
{
return false;
}
}
if (indirectReference != null)
{
if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
{
return false;
}
}
if (dataValueDescriptor != null)
{
if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
{
return false;
}
}
return externalContent.equals(other.externalContent);
}
/**
* Returns the data value descriptor
* @return The descriptor
*/
public ASN1Primitive getDataValueDescriptor()
{
return dataValueDescriptor;
}
/**
* Returns the direct reference of the external element
* @return The reference
*/
public ASN1ObjectIdentifier getDirectReference()
{
return directReference;
}
/**
* Returns the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
* @return The encoding
*/
public int getEncoding()
{
return encoding;
}
/**
* Returns the content of this element
* @return The content
*/
public ASN1Primitive getExternalContent()
{
return externalContent;
}
/**
* Returns the indirect reference of this element
* @return The reference
*/
public ASN1Integer getIndirectReference()
{
return indirectReference;
}
/**
* Sets the data value descriptor
* @param dataValueDescriptor The descriptor
*/
private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
{
this.dataValueDescriptor = dataValueDescriptor;
}
/**
* Sets the direct reference of the external element
* @param directReferemce The reference
*/
private void setDirectReference(ASN1ObjectIdentifier directReferemce)
{
this.directReference = directReferemce;
}
/**
* Sets the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
* @param encoding The encoding
*/
private void setEncoding(int encoding)
{
if (encoding < 0 || encoding > 2)
{
throw new IllegalArgumentException("invalid encoding value: " + encoding);
}
this.encoding = encoding;
}
/**
* Sets the content of this element
* @param externalContent The content
*/
private void setExternalContent(ASN1Primitive externalContent)
{
this.externalContent = externalContent;
}
/**
* Sets the indirect reference of this element
* @param indirectReference The reference
*/
private void setIndirectReference(ASN1Integer indirectReference)
{
this.indirectReference = indirectReference;
}
}