BerOutputStream.java revision cec4dd4b1d33f78997603d0f89c0d0e56e64dbcd
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/**
19* @author Vladimir N. Molotkov, Stepan M. Mishura
20* @version $Revision$
21*/
22
23package org.apache.harmony.security.asn1;
24
25
26/**
27 * Encodes ASN.1 types with BER (X.690)
28 *
29 * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a>
30 */
31
32public class BerOutputStream {
33
34    /**
35     *  Encoded byte array
36     */
37    public byte[] encoded;
38
39    /**
40     *  current offset
41     */
42    protected int offset;
43
44    /**
45     * Current encoded length
46     */
47    public int length;
48
49    /**
50     * Current encoded content
51     */
52    public Object content;
53
54    public BerOutputStream() {
55    }
56
57    public final void encodeTag(int tag) {
58
59        encoded[offset++] = (byte) tag; //FIXME long form?
60
61        if (length > 127) { //long form
62            int eLen = length >> 8;
63            byte numOctets = 1;
64            for (; eLen > 0; eLen = eLen >> 8) {
65                numOctets++;
66            }
67
68            encoded[offset] = (byte) (numOctets | 0x80);
69            offset++;
70
71            eLen = length;
72            int numOffset = offset + numOctets - 1;
73            for (int i = 0; i < numOctets; i++, eLen = eLen >> 8) {
74                encoded[numOffset - i] = (byte) eLen; //FIXME long value?
75            }
76            offset += numOctets;
77        } else { //short form
78            encoded[offset++] = (byte) length;
79        }
80    }
81
82    public void encodeANY() {
83        System.arraycopy(content, 0, encoded, offset, length);
84        offset += length;
85    }
86
87    public void encodeBitString() {
88        //FIXME check encoding
89        BitString bStr = (BitString) content;
90        encoded[offset] = (byte) bStr.unusedBits;
91        System.arraycopy(bStr.bytes, 0, encoded, offset + 1, length - 1);
92        offset += length;
93    }
94
95    public void encodeBoolean() {
96        if (((Boolean) content).booleanValue()) {
97            encoded[offset] = (byte) 0xFF;
98        } else {
99            encoded[offset] = 0x00;
100        }
101        offset++;
102    }
103
104    public void encodeChoice(ASN1Choice choice) {
105        throw new RuntimeException("Is not implemented yet"); //FIXME
106    }
107
108    public void encodeExplicit(ASN1Explicit explicit) {
109        throw new RuntimeException("Is not implemented yet"); //FIXME
110    }
111
112    public void encodeGeneralizedTime() {
113        System.arraycopy(content, 0, encoded, offset, length);
114        offset += length;
115    }
116
117    public void encodeUTCTime() {
118        System.arraycopy(content, 0, encoded, offset, length);
119        offset += length;
120    }
121
122    public void encodeInteger() {
123        System.arraycopy(content, 0, encoded, offset, length);
124        offset += length;
125    }
126
127    public void encodeOctetString() {
128        System.arraycopy(content, 0, encoded, offset, length);
129        offset += length;
130    }
131
132    public void encodeOID() {
133
134        int[] oid = (int[]) content;
135
136        int oidLen = length;
137
138        // all subidentifiers except first
139        int elem;
140        for (int i = oid.length - 1; i > 1; i--, oidLen--) {
141            elem = oid[i];
142            if (elem > 127) {
143                encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
144                elem = elem >> 7;
145                for (; elem > 0;) {
146                    oidLen--;
147                    encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
148                    elem = elem >> 7;
149                }
150            } else {
151                encoded[offset + oidLen - 1] = (byte) elem;
152            }
153        }
154
155        // first subidentifier
156        elem = oid[0] * 40 + oid[1];
157        if (elem > 127) {
158            encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
159            elem = elem >> 7;
160            for (; elem > 0;) {
161                oidLen--;
162                encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
163                elem = elem >> 7;
164            }
165        } else {
166            encoded[offset + oidLen - 1] = (byte) elem;
167        }
168
169        offset += length;
170    }
171
172    public void encodeSequence(ASN1Sequence sequence) {
173        throw new RuntimeException("Is not implemented yet"); //FIXME
174    }
175
176    public void encodeSequenceOf(ASN1SequenceOf sequenceOf) {
177        throw new RuntimeException("Is not implemented yet"); //FIXME
178    }
179
180    public void encodeSet(ASN1Set set) {
181        throw new RuntimeException("Is not implemented yet"); //FIXME
182    }
183
184    public void encodeSetOf(ASN1SetOf setOf) {
185        throw new RuntimeException("Is not implemented yet"); //FIXME
186    }
187
188    public void encodeString() {
189        System.arraycopy(content, 0, encoded, offset, length);
190        offset += length;
191    }
192
193    /*
194     * LENGTH
195     */
196
197    public void getChoiceLength(ASN1Choice choice) {
198        throw new RuntimeException("Is not implemented yet"); //FIXME
199    }
200
201    public void getExplicitLength(ASN1Explicit sequence) {
202        throw new RuntimeException("Is not implemented yet"); //FIXME
203    }
204
205    public void getSequenceLength(ASN1Sequence sequence) {
206        throw new RuntimeException("Is not implemented yet"); //FIXME
207    }
208
209    public void getSequenceOfLength(ASN1SequenceOf sequence) {
210        throw new RuntimeException("Is not implemented yet"); //FIXME
211    }
212
213    public void getSetLength(ASN1Set set) {
214        throw new RuntimeException("Is not implemented yet"); //FIXME
215    }
216
217    public void getSetOfLength(ASN1SetOf setOf) {
218        throw new RuntimeException("Is not implemented yet"); //FIXME
219    }
220
221    public int getStringLength(Object object) {
222        throw new RuntimeException("Is not implemented yet"); //FIXME
223    }
224}
225