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 Projectimport java.io.IOException; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This abstract class is the super class for all ASN.1 types 31f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a> 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class ASN1Type implements ASN1Constants { 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 365c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** Integer representation of primitive identifier. */ 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int id; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 395c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** Integer representation of constructed identifier. */ 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int constrId; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a primitive, universal ASN.1 type. 44f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tagNumber - ASN.1 tag number 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException - if tagNumber is invalid 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ASN1Type(int tagNumber) { 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(CLASS_UNIVERSAL, tagNumber); 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs an ASN.1 type. 54f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tagClass - tag class. MUST be 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * CLASS_UNIVERSAL, CLASS_APPLICATION, CLASS_CONTEXTSPECIFIC, CLASS_PRIVATE 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tagNumber - ASN.1 tag number. 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException - if tagClass or tagNumber is invalid 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ASN1Type(int tagClass, int tagNumber) { 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tagNumber < 0) { 62897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException("tagNumber < 0"); 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tagClass != CLASS_UNIVERSAL && tagClass != CLASS_APPLICATION 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && tagClass != CLASS_CONTEXTSPECIFIC 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && tagClass != CLASS_PRIVATE) { 68897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException("invalid tagClass"); 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tagNumber < 31) { 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // short form 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.id = tagClass + tagNumber; 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // long form 76897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException("tag long form not implemented"); 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.constrId = this.id + PC_CONSTRUCTED; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Object decode(byte[] encoded) throws IOException { 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return decode(new DerInputStream(encoded)); 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Object decode(byte[] encoded, int offset, int encodingLen) 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return decode(new DerInputStream(encoded, offset, encodingLen)); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Object decode(InputStream in) throws IOException { 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return decode(new DerInputStream(in)); 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void verify(byte[] encoded) throws IOException { 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DerInputStream decoder = new DerInputStream(encoded); 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decoder.setVerify(); 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decode(decoder); 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void verify(InputStream in) throws IOException { 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DerInputStream decoder = new DerInputStream(in); 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decoder.setVerify(); 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decode(decoder); 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] encode(Object object) { 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DerOutputStream out = new DerOutputStream(this, object); 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return out.encoded; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Decodes ASN.1 type. 113f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1145c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson * @throws IOException if an I/O error occurs or the end of the stream is reached 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract Object decode(BerInputStream in) throws IOException; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tests provided identifier. 120f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1215c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson * @param identifier identifier to be verified 1225c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson * @return true if identifier is associated with this ASN.1 type 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean checkTag(int identifier); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates decoded object. 128f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Derived classes should override this method to provide creation for a 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * selected class of objects during decoding. 131f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default implementation returns an object created by decoding stream. 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Object getDecodedObject(BerInputStream in) throws IOException { 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return in.content; 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Encodes ASN.1 type. 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract void encodeASN(BerOutputStream out); 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract void encodeContent(BerOutputStream out); 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract void setEncodingContent(BerOutputStream out); 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getEncodedLength(BerOutputStream out) { //FIXME name 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //tag length 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int len = 1; //FIXME tag length = 1. what about long form? 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //for (; tag > 0; tag = tag >> 8, len++); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // length length :-) 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project len++; 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (out.length > 127) { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project len++; 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int cur = out.length >> 8; cur > 0; len++) { 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cur = cur >> 8; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project len += out.length; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return len; 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1665c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson @Override public String toString() { 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // TODO decide whether this method is necessary 1685c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson return getClass().getName() + "(tag: 0x" + Integer.toHexString(0xff & this.id) + ")"; 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 171