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