diff options
Diffstat (limited to 'core/src/main/java/org/spongycastle/asn1/DERExternal.java')
-rw-r--r-- | core/src/main/java/org/spongycastle/asn1/DERExternal.java | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/asn1/DERExternal.java b/core/src/main/java/org/spongycastle/asn1/DERExternal.java new file mode 100644 index 00000000..5cf48f0f --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/DERExternal.java @@ -0,0 +1,294 @@ +package org.spongycastle.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 DERTaggedObject)) + { + dataValueDescriptor = (ASN1Primitive) enc; + offset++; + enc = getObjFromVector(vector, offset); + } + + if (vector.size() != offset + 1) + { + throw new IllegalArgumentException("input vector too large"); + } + + if (!(enc instanceof DERTaggedObject)) + { + throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External"); + } + DERTaggedObject obj = (DERTaggedObject)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.spongycastle.asn1.ASN1Primitive#encode(org.spongycastle.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.spongycastle.asn1.ASN1Primitive#asn1Equals(org.spongycastle.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; + } +} |