Home | History | Annotate | Download | only in asn1
      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 
     23 package 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 
     32 public 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