001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Vladimir N. Molotkov, Stepan M. Mishura
020: * @version $Revision$
021: */package org.apache.harmony.security.asn1;
022:
023: /**
024: * Encodes ASN.1 types with BER (X.690)
025: *
026: * @see http://asn1.elibel.tm.fr/en/standards/index.htm
027: */
028:
029: public class BerOutputStream {
030:
031: /**
032: * Encoded byte array
033: */
034: public byte[] encoded;
035:
036: /**
037: * current offset
038: */
039: protected int offset;
040:
041: /**
042: * Current encoded length
043: */
044: public int length;
045:
046: /**
047: * Current encoded content
048: */
049: public Object content;
050:
051: public BerOutputStream() {
052: }
053:
054: public final void encodeTag(int tag) {
055:
056: encoded[offset++] = (byte) tag; //FIXME long form?
057:
058: if (length > 127) { //long form
059: int eLen = length >> 8;
060: byte numOctets = 1;
061: for (; eLen > 0; eLen = eLen >> 8) {
062: numOctets++;
063: }
064:
065: encoded[offset] = (byte) (numOctets | 0x80);
066: offset++;
067:
068: eLen = length;
069: int numOffset = offset + numOctets - 1;
070: for (int i = 0; i < numOctets; i++, eLen = eLen >> 8) {
071: encoded[numOffset - i] = (byte) eLen; //FIXME long value?
072: }
073: offset += numOctets;
074: } else { //short form
075: encoded[offset++] = (byte) length;
076: }
077: }
078:
079: public void encodeANY() {
080: System.arraycopy(content, 0, encoded, offset, length);
081: offset += length;
082: }
083:
084: public void encodeBitString() {
085: //FIXME check encoding
086: BitString bStr = (BitString) content;
087: encoded[offset] = (byte) bStr.unusedBits;
088: System
089: .arraycopy(bStr.bytes, 0, encoded, offset + 1,
090: length - 1);
091: offset += length;
092: }
093:
094: public void encodeBoolean() {
095: if (((Boolean) content).booleanValue()) {
096: encoded[offset] = (byte) 0xFF;
097: } else {
098: encoded[offset] = 0x00;
099: }
100: offset++;
101: }
102:
103: public void encodeChoice(ASN1Choice choice) {
104: throw new RuntimeException("Is not implemented yet"); //FIXME
105: }
106:
107: public void encodeExplicit(ASN1Explicit explicit) {
108: throw new RuntimeException("Is not implemented yet"); //FIXME
109: }
110:
111: public void encodeGeneralizedTime() {
112: System.arraycopy(content, 0, encoded, offset, length);
113: offset += length;
114: }
115:
116: public void encodeUTCTime() {
117: System.arraycopy(content, 0, encoded, offset, length);
118: offset += length;
119: }
120:
121: public void encodeInteger() {
122: System.arraycopy(content, 0, encoded, offset, length);
123: offset += length;
124: }
125:
126: public void encodeOctetString() {
127: System.arraycopy(content, 0, encoded, offset, length);
128: offset += length;
129: }
130:
131: public void encodeOID() {
132:
133: int[] oid = (int[]) content;
134:
135: int oidLen = length;
136:
137: // all subidentifiers except first
138: int elem;
139: for (int i = oid.length - 1; i > 1; i--, oidLen--) {
140: elem = oid[i];
141: if (elem > 127) {
142: encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
143: elem = elem >> 7;
144: for (; elem > 0;) {
145: oidLen--;
146: encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
147: elem = elem >> 7;
148: }
149: } else {
150: encoded[offset + oidLen - 1] = (byte) elem;
151: }
152: }
153:
154: // first subidentifier
155: elem = oid[0] * 40 + oid[1];
156: if (elem > 127) {
157: encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
158: elem = elem >> 7;
159: for (; elem > 0;) {
160: oidLen--;
161: encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
162: elem = elem >> 7;
163: }
164: } else {
165: encoded[offset + oidLen - 1] = (byte) elem;
166: }
167:
168: offset += length;
169: }
170:
171: public void encodeSequence(ASN1Sequence sequence) {
172: throw new RuntimeException("Is not implemented yet"); //FIXME
173: }
174:
175: public void encodeSequenceOf(ASN1SequenceOf sequenceOf) {
176: throw new RuntimeException("Is not implemented yet"); //FIXME
177: }
178:
179: public void encodeSet(ASN1Set set) {
180: throw new RuntimeException("Is not implemented yet"); //FIXME
181: }
182:
183: public void encodeSetOf(ASN1SetOf setOf) {
184: throw new RuntimeException("Is not implemented yet"); //FIXME
185: }
186:
187: public void encodeString() {
188: System.arraycopy(content, 0, encoded, offset, length);
189: offset += length;
190: }
191:
192: /*
193: * LENGTH
194: */
195:
196: public void getChoiceLength(ASN1Choice choice) {
197: throw new RuntimeException("Is not implemented yet"); //FIXME
198: }
199:
200: public void getExplicitLength(ASN1Explicit sequence) {
201: throw new RuntimeException("Is not implemented yet"); //FIXME
202: }
203:
204: public void getSequenceLength(ASN1Sequence sequence) {
205: throw new RuntimeException("Is not implemented yet"); //FIXME
206: }
207:
208: public void getSequenceOfLength(ASN1SequenceOf sequence) {
209: throw new RuntimeException("Is not implemented yet"); //FIXME
210: }
211:
212: public void getSetLength(ASN1Set set) {
213: throw new RuntimeException("Is not implemented yet"); //FIXME
214: }
215:
216: public void getSetOfLength(ASN1SetOf setOf) {
217: throw new RuntimeException("Is not implemented yet"); //FIXME
218: }
219:
220: public int getStringLength(Object object) {
221: throw new RuntimeException("Is not implemented yet"); //FIXME
222: }
223: }
|