diff options
Diffstat (limited to 'core/src/main/java/org/spongycastle/asn1/DERGenerator.java')
-rw-r--r-- | core/src/main/java/org/spongycastle/asn1/DERGenerator.java | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/asn1/DERGenerator.java b/core/src/main/java/org/spongycastle/asn1/DERGenerator.java new file mode 100644 index 00000000..da6d6545 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/DERGenerator.java @@ -0,0 +1,119 @@ +package org.spongycastle.asn1; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.spongycastle.util.io.Streams; + +public abstract class DERGenerator + extends ASN1Generator +{ + private boolean _tagged = false; + private boolean _isExplicit; + private int _tagNo; + + protected DERGenerator( + OutputStream out) + { + super(out); + } + + public DERGenerator( + OutputStream out, + int tagNo, + boolean isExplicit) + { + super(out); + + _tagged = true; + _isExplicit = isExplicit; + _tagNo = tagNo; + } + + private void writeLength( + OutputStream out, + int length) + throws IOException + { + if (length > 127) + { + int size = 1; + int val = length; + + while ((val >>>= 8) != 0) + { + size++; + } + + out.write((byte)(size | 0x80)); + + for (int i = (size - 1) * 8; i >= 0; i -= 8) + { + out.write((byte)(length >> i)); + } + } + else + { + out.write((byte)length); + } + } + + void writeDEREncoded( + OutputStream out, + int tag, + byte[] bytes) + throws IOException + { + out.write(tag); + writeLength(out, bytes.length); + out.write(bytes); + } + + void writeDEREncoded( + int tag, + byte[] bytes) + throws IOException + { + if (_tagged) + { + int tagNum = _tagNo | BERTags.TAGGED; + + if (_isExplicit) + { + int newTag = _tagNo | BERTags.CONSTRUCTED | BERTags.TAGGED; + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + writeDEREncoded(bOut, tag, bytes); + + writeDEREncoded(_out, newTag, bOut.toByteArray()); + } + else + { + if ((tag & BERTags.CONSTRUCTED) != 0) + { + writeDEREncoded(_out, tagNum | BERTags.CONSTRUCTED, bytes); + } + else + { + writeDEREncoded(_out, tagNum, bytes); + } + } + } + else + { + writeDEREncoded(_out, tag, bytes); + } + } + + void writeDEREncoded( + OutputStream out, + int tag, + InputStream in) + throws IOException + { + writeDEREncoded(out, tag, Streams.readAll(in)); + } +} |