ASN1Implicit.java revision 897538a36c18f4db8f9f68ee566aec0bda842e9f
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 Project 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implicitly tagged ASN.1 type. 30f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a> 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ASN1Implicit extends ASN1Type { 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // primitive type of tagging 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int TAGGING_PRIMITIVE = 0; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // constructed type of tagging 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int TAGGING_CONSTRUCTED = 1; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // string type of tagging 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int TAGGING_STRING = 2; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // tagged ASN.1 type 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final ASN1Type type; 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // type of tagging. There are three of them 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 1) primitive: only primitive identifier is valid 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 2) constructed: only constructed identifier is valid 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 3) string: both identifiers are valid 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final int taggingType; 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs implicitly tagged ASN.1 type 55f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * with context-specific tag class and specified tag number. 56f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tagNumber - ASN.1 tag number 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param type - ASN.1 type to be tagged 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException - if tagNumber or type is invalid 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ASN1Implicit(int tagNumber, ASN1Type type) { 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(CLASS_CONTEXTSPECIFIC, tagNumber, type); 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs implicitly tagged ASN.1 type 67f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tagClass - ASN.1 tag class. 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tagNumber - ASN.1 tag number 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param type - ASN.1 type to be tagged 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException - if tagNumber, tagClass or type is invalid 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ASN1Implicit(int tagClass, int tagNumber, ASN1Type type) { 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(tagClass, tagNumber); 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((type instanceof ASN1Choice) || (type instanceof ASN1Any)) { 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // According to X.680: 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 'The IMPLICIT alternative shall not be used if the type 79f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // defined by "Type" is an untagged choice type or an 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // untagged open type' 81897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException("Implicit tagging can not be used for ASN.1 ANY or CHOICE type"); 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.type = type; 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (type.checkTag(type.id)) { 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (type.checkTag(type.constrId)) { 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the base encoding can be primitive ot constructed 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // use both encodings 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project taggingType = TAGGING_STRING; 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if the base encoding is primitive use primitive encoding 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project taggingType = TAGGING_PRIMITIVE; 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if the base encoding is constructed use constructed encoding 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project taggingType = TAGGING_CONSTRUCTED; 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Decode 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TODO 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean checkTag(int identifier) { 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (taggingType) { 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TAGGING_PRIMITIVE: 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return id == identifier; 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case TAGGING_CONSTRUCTED: 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return constrId == identifier; 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: // TAGGING_STRING 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return id == identifier || constrId == identifier; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TODO 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object decode(BerInputStream in) throws IOException { 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!checkTag(in.tag)) { 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME need look for tagging type 127897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new ASN1Exception("ASN.1 implicitly tagged type expected at " + 128897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes "[" + in.tagOffset + "]. Expected tag: " + Integer.toHexString(id) + ", " + 129897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes "but got " + Integer.toHexString(in.tag)); 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // substitute indentifier for further decoding 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (id == in.tag) { 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.tag = type.id; 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.tag = type.constrId; 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.content = type.decode(in); 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (in.isVerify) { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getDecodedObject(in); 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Encode 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void encodeASN(BerOutputStream out) { 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //FIXME need another way for specifying identifier to be encoded 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (taggingType == TAGGING_CONSTRUCTED) { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project out.encodeTag(constrId); 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project out.encodeTag(id); 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project encodeContent(out); 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void encodeContent(BerOutputStream out) { 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project type.encodeContent(out); 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEncodingContent(BerOutputStream out) { 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project type.setEncodingContent(out); 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 170