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