diff options
Diffstat (limited to 'core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java')
-rw-r--r-- | core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java b/core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java new file mode 100644 index 00000000..1af0a433 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java @@ -0,0 +1,147 @@ +package org.bouncycastle.asn1; + +import java.io.IOException; +import java.util.Enumeration; + +/** + * BER TaggedObject - in ASN.1 notation this is any object preceded by + * a [n] where n is some number - these are assumed to follow the construction + * rules (as with sequences). + */ +public class BERTaggedObject + extends ASN1TaggedObject +{ + /** + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public BERTaggedObject( + int tagNo, + ASN1Encodable obj) + { + super(true, tagNo, obj); + } + + /** + * @param explicit true if an explicitly tagged object. + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public BERTaggedObject( + boolean explicit, + int tagNo, + ASN1Encodable obj) + { + super(explicit, tagNo, obj); + } + + /** + * create an implicitly tagged object that contains a zero + * length sequence. + */ + public BERTaggedObject( + int tagNo) + { + super(false, tagNo, new BERSequence()); + } + + boolean isConstructed() + { + if (!empty) + { + if (explicit) + { + return true; + } + else + { + ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); + + return primitive.isConstructed(); + } + } + else + { + return true; + } + } + + int encodedLength() + throws IOException + { + if (!empty) + { + ASN1Primitive primitive = obj.toASN1Primitive(); + int length = primitive.encodedLength(); + + if (explicit) + { + return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length; + } + else + { + // header length already in calculation + length = length - 1; + + return StreamUtil.calculateTagLength(tagNo) + length; + } + } + else + { + return StreamUtil.calculateTagLength(tagNo) + 1; + } + } + + void encode( + ASN1OutputStream out) + throws IOException + { + out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); + out.write(0x80); + + if (!empty) + { + if (!explicit) + { + Enumeration e; + if (obj instanceof ASN1OctetString) + { + if (obj instanceof BEROctetString) + { + e = ((BEROctetString)obj).getObjects(); + } + else + { + ASN1OctetString octs = (ASN1OctetString)obj; + BEROctetString berO = new BEROctetString(octs.getOctets()); + e = berO.getObjects(); + } + } + else if (obj instanceof ASN1Sequence) + { + e = ((ASN1Sequence)obj).getObjects(); + } + else if (obj instanceof ASN1Set) + { + e = ((ASN1Set)obj).getObjects(); + } + else + { + throw new RuntimeException("not implemented: " + obj.getClass().getName()); + } + + while (e.hasMoreElements()) + { + out.writeObject((ASN1Encodable)e.nextElement()); + } + } + else + { + out.writeObject(obj); + } + } + + out.write(0x00); + out.write(0x00); + } +} |