| 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; |
| } |
| } |