001 package org.apache.commons.ssl.asn1;
002
003 import java.io.ByteArrayOutputStream;
004 import java.io.IOException;
005 import java.io.InputStream;
006 import java.io.OutputStream;
007
008 public abstract class DERGenerator
009 extends ASN1Generator {
010 private boolean _tagged = false;
011 private boolean _isExplicit;
012 private int _tagNo;
013
014 protected DERGenerator(
015 OutputStream out) {
016 super(out);
017 }
018
019 public DERGenerator(
020 OutputStream out,
021 int tagNo,
022 boolean isExplicit) {
023 super(out);
024
025 _tagged = true;
026 _isExplicit = isExplicit;
027 _tagNo = tagNo;
028 }
029
030 private void writeLength(
031 OutputStream out,
032 int length)
033 throws IOException {
034 if (length > 127) {
035 int size = 1;
036 int val = length;
037
038 while ((val >>>= 8) != 0) {
039 size++;
040 }
041
042 out.write((byte) (size | 0x80));
043
044 for (int i = (size - 1) * 8; i >= 0; i -= 8) {
045 out.write((byte) (length >> i));
046 }
047 } else {
048 out.write((byte) length);
049 }
050 }
051
052 void writeDEREncoded(
053 OutputStream out,
054 int tag,
055 byte[] bytes)
056 throws IOException {
057 out.write(tag);
058 writeLength(out, bytes.length);
059 out.write(bytes);
060 }
061
062 void writeDEREncoded(
063 int tag,
064 byte[] bytes)
065 throws IOException {
066 if (_tagged) {
067 int tagNum = _tagNo | DERTags.TAGGED;
068
069 if (_isExplicit) {
070 int newTag = _tagNo | DERTags.CONSTRUCTED | DERTags.TAGGED;
071
072 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
073
074 writeDEREncoded(bOut, tag, bytes);
075
076 writeDEREncoded(_out, newTag, bOut.toByteArray());
077 } else {
078 if ((tag & DERTags.CONSTRUCTED) != 0) {
079 writeDEREncoded(_out, tagNum | DERTags.CONSTRUCTED, bytes);
080 } else {
081 writeDEREncoded(_out, tagNum, bytes);
082 }
083 }
084 } else {
085 writeDEREncoded(_out, tag, bytes);
086 }
087 }
088
089 void writeDEREncoded(
090 OutputStream out,
091 int tag,
092 InputStream in)
093 throws IOException {
094 out.write(tag);
095
096 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
097
098 int b = 0;
099 while ((b = in.read()) >= 0) {
100 bOut.write(b);
101 }
102
103 byte[] bytes = bOut.toByteArray();
104
105 writeLength(out, bytes.length);
106 out.write(bytes);
107 }
108 }