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 public class BerOutputStream {
     32 
     33     /** Encoded byte array */
     34     public byte[] encoded;
     35 
     36     /** current offset */
     37     protected int offset;
     38 
     39     /** Current encoded length */
     40     public int length;
     41 
     42     /** Current encoded content */
     43     public Object content;
     44 
     45     public final void encodeTag(int tag) {
     46         encoded[offset++] = (byte) tag; //FIXME long form?
     47 
     48         if (length > 127) { //long form
     49             int eLen = length >> 8;
     50             byte numOctets = 1;
     51             for (; eLen > 0; eLen = eLen >> 8) {
     52                 numOctets++;
     53             }
     54 
     55             encoded[offset] = (byte) (numOctets | 0x80);
     56             offset++;
     57 
     58             eLen = length;
     59             int numOffset = offset + numOctets - 1;
     60             for (int i = 0; i < numOctets; i++, eLen = eLen >> 8) {
     61                 encoded[numOffset - i] = (byte) eLen; //FIXME long value?
     62             }
     63             offset += numOctets;
     64         } else { //short form
     65             encoded[offset++] = (byte) length;
     66         }
     67     }
     68 
     69     public void encodeANY() {
     70         System.arraycopy(content, 0, encoded, offset, length);
     71         offset += length;
     72     }
     73 
     74     public void encodeBitString() {
     75         //FIXME check encoding
     76         BitString bStr = (BitString) content;
     77         encoded[offset] = (byte) bStr.unusedBits;
     78         System.arraycopy(bStr.bytes, 0, encoded, offset + 1, length - 1);
     79         offset += length;
     80     }
     81 
     82     public void encodeBoolean() {
     83         if ((Boolean) content) {
     84             encoded[offset] = (byte) 0xFF;
     85         } else {
     86             encoded[offset] = 0x00;
     87         }
     88         offset++;
     89     }
     90 
     91     public void encodeChoice(ASN1Choice choice) {
     92         throw new RuntimeException("Is not implemented yet"); //FIXME
     93     }
     94 
     95     public void encodeExplicit(ASN1Explicit explicit) {
     96         throw new RuntimeException("Is not implemented yet"); //FIXME
     97     }
     98 
     99     public void encodeGeneralizedTime() {
    100         System.arraycopy(content, 0, encoded, offset, length);
    101         offset += length;
    102     }
    103 
    104     public void encodeUTCTime() {
    105         System.arraycopy(content, 0, encoded, offset, length);
    106         offset += length;
    107     }
    108 
    109     public void encodeInteger() {
    110         System.arraycopy(content, 0, encoded, offset, length);
    111         offset += length;
    112     }
    113 
    114     public void encodeOctetString() {
    115         System.arraycopy(content, 0, encoded, offset, length);
    116         offset += length;
    117     }
    118 
    119     public void encodeOID() {
    120 
    121         int[] oid = (int[]) content;
    122 
    123         int oidLen = length;
    124 
    125         // all subidentifiers except first
    126         int elem;
    127         for (int i = oid.length - 1; i > 1; i--, oidLen--) {
    128             elem = oid[i];
    129             if (elem > 127) {
    130                 encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
    131                 elem = elem >> 7;
    132                 for (; elem > 0;) {
    133                     oidLen--;
    134                     encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
    135                     elem = elem >> 7;
    136                 }
    137             } else {
    138                 encoded[offset + oidLen - 1] = (byte) elem;
    139             }
    140         }
    141 
    142         // first subidentifier
    143         elem = oid[0] * 40 + oid[1];
    144         if (elem > 127) {
    145             encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
    146             elem = elem >> 7;
    147             for (; elem > 0;) {
    148                 oidLen--;
    149                 encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
    150                 elem = elem >> 7;
    151             }
    152         } else {
    153             encoded[offset + oidLen - 1] = (byte) elem;
    154         }
    155 
    156         offset += length;
    157     }
    158 
    159     public void encodeSequence(ASN1Sequence sequence) {
    160         throw new RuntimeException("Is not implemented yet"); //FIXME
    161     }
    162 
    163     public void encodeSequenceOf(ASN1SequenceOf sequenceOf) {
    164         throw new RuntimeException("Is not implemented yet"); //FIXME
    165     }
    166 
    167     public void encodeSet(ASN1Set set) {
    168         throw new RuntimeException("Is not implemented yet"); //FIXME
    169     }
    170 
    171     public void encodeSetOf(ASN1SetOf setOf) {
    172         throw new RuntimeException("Is not implemented yet"); //FIXME
    173     }
    174 
    175     public void encodeString() {
    176         System.arraycopy(content, 0, encoded, offset, length);
    177         offset += length;
    178     }
    179 
    180     public void getChoiceLength(ASN1Choice choice) {
    181         throw new RuntimeException("Is not implemented yet"); //FIXME
    182     }
    183 
    184     public void getExplicitLength(ASN1Explicit sequence) {
    185         throw new RuntimeException("Is not implemented yet"); //FIXME
    186     }
    187 
    188     public void getSequenceLength(ASN1Sequence sequence) {
    189         throw new RuntimeException("Is not implemented yet"); //FIXME
    190     }
    191 
    192     public void getSequenceOfLength(ASN1SequenceOf sequence) {
    193         throw new RuntimeException("Is not implemented yet"); //FIXME
    194     }
    195 
    196     public void getSetLength(ASN1Set set) {
    197         throw new RuntimeException("Is not implemented yet"); //FIXME
    198     }
    199 
    200     public void getSetOfLength(ASN1SetOf setOf) {
    201         throw new RuntimeException("Is not implemented yet"); //FIXME
    202     }
    203 }
    204