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