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