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 }