151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 27b63247eb7ae2638740bd13f370bdcf9d3603407Przemyslaw Szczepaniak * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.security.util; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.math.BigInteger; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Date; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.IOUtils; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Represents a single DER-encoded value. DER encoding rules are a subset 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the "Basic" Encoding Rules (BER), but they only support a single way 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ("Definite" encoding) to encode any given value. 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>All DER-encoded data are triples <em>{type, length, data}</em>. This 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class represents such tagged values as they have been read (or constructed), 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and provides structured access to the encoded data. 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>At this time, this class supports only a subset of the types of DER 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data encodings which are defined. That subset is sufficient for parsing 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * most X.509 certificates, and working with selected additional formats 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (such as PKCS #10 certificate requests, and some kinds of PKCS #7 data). 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A note with respect to T61/Teletex strings: From RFC 1617, section 4.1.3 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and RFC 3280, section 4.1.2.4., we assume that this kind of string will 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * contain ISO-8859-1 characters only. 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author David Brownell 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Amit Kapoor 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Hemma Prafullchandra 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class DerValue { 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** The tag class types */ 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final byte TAG_UNIVERSAL = (byte)0x000; 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final byte TAG_APPLICATION = (byte)0x040; 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final byte TAG_CONTEXT = (byte)0x080; 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final byte TAG_PRIVATE = (byte)0x0c0; 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** The DER tag of the value; one of the tag_ constants. */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte tag; 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected DerInputBuffer buffer; 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The DER-encoded data of the value, never null 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final DerInputStream data; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int length; 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75f5a241465eef5d8b4edaaeccc63680e1ea65bb18Przemyslaw Szczepaniak // BEGIN Android-added: Original encoded form needed for APKs parsing/validation 76ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin /** 77ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin * The original encoded form of the whole value (tag, length, and value) 78ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin * or null if the form was not provided or was not retained during parsing. 79ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin */ 80ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin private byte[] originalEncodedForm; 81f5a241465eef5d8b4edaaeccc63680e1ea65bb18Przemyslaw Szczepaniak // END Android-added: Original encoded form needed for APKs parsing/validation 82ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The type starts at the first byte of the encoding, and 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is one of these tag_* values. That may be all the type 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data that is needed. 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * These tags are the "universal" tags ... they mean the same 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in all contexts. (Mask with 0x1f -- five bits.) 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "BOOLEAN" value. */ 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_Boolean = 0x01; 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "INTEGER" value. */ 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_Integer = 0x02; 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "BIT STRING" value. */ 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_BitString = 0x03; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "OCTET STRING" value. */ 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_OctetString = 0x04; 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "NULL" value. */ 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_Null = 0x05; 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "OBJECT IDENTIFIER" value. */ 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_ObjectId = 0x06; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value including an ASN.1 "ENUMERATED" value */ 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_Enumerated = 0x0A; 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "UTF8String" value. */ 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_UTF8String = 0x0C; 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value including a "printable" string */ 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_PrintableString = 0x13; 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value including a "teletype" string */ 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_T61String = 0x14; 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value including an ASCII string */ 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_IA5String = 0x16; 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "UTCTime" value. */ 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_UtcTime = 0x17; 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "GeneralizedTime" value. */ 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_GeneralizedTime = 0x18; 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "GenerallString" value. */ 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_GeneralString = 0x1B; 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "UniversalString" value. */ 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_UniversalString = 0x1C; 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Tag value indicating an ASN.1 "BMPString" value. */ 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_BMPString = 0x1E; 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // CONSTRUCTED seq/set 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tag value indicating an ASN.1 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "SEQUENCE" (zero to N elements, order is significant). 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_Sequence = 0x30; 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tag value indicating an ASN.1 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "SEQUENCE OF" (one to N elements, order is significant). 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_SequenceOf = 0x30; 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tag value indicating an ASN.1 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "SET" (zero to N members, order does not matter). 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_Set = 0x31; 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tag value indicating an ASN.1 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "SET OF" (one to N members, order does not matter). 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final static byte tag_SetOf = 0x31; 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * These values are the high order bits for the other kinds of tags. 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true if the tag class is UNIVERSAL. 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isUniversal() { return ((tag & 0x0c0) == 0x000); } 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true if the tag class is APPLICATION. 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isApplication() { return ((tag & 0x0c0) == 0x040); } 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true iff the CONTEXT SPECIFIC bit is set in the type tag. 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This is associated with the ASN.1 "DEFINED BY" syntax. 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isContextSpecific() { return ((tag & 0x0c0) == 0x080); } 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true iff the CONTEXT SPECIFIC TAG matches the passed tag. 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isContextSpecific(byte cntxtTag) { 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isContextSpecific()) { 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((tag & 0x01f) == cntxtTag); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isPrivate() { return ((tag & 0x0c0) == 0x0c0); } 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Returns true iff the CONSTRUCTED bit is set in the type tag. */ 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isConstructed() { return ((tag & 0x020) == 0x020); } 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true iff the CONSTRUCTED TAG matches the passed tag. 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isConstructed(byte constructedTag) { 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConstructed()) { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((tag & 0x01f) == constructedTag); 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a PrintableString or UTF8string DER value from a string 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DerValue(String value) throws IOException { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isPrintableString = true; 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < value.length(); i++) { 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isPrintableStringChar(value.charAt(i))) { 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isPrintableString = false; 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data = init(isPrintableString ? tag_PrintableString : tag_UTF8String, value); 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a string type DER value from a String object 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param stringTag the tag for the DER value to create 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param value the String object to use for the DER value 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DerValue(byte stringTag, String value) throws IOException { 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data = init(stringTag, value); 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a DerValue from a tag and some DER-encoded data. 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param tag the DER type tag 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param data the DER-encoded data 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DerValue(byte tag, byte[] data) { 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.tag = tag; 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer = new DerInputBuffer(data.clone()); 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski length = data.length; 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.data = new DerInputStream(buffer); 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.data.mark(Integer.MAX_VALUE); 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * package private 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 254f5a241465eef5d8b4edaaeccc63680e1ea65bb18Przemyslaw Szczepaniak // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation 255ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin DerValue(DerInputBuffer in, boolean originalEncodedFormRetained) 256ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin throws IOException { 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // XXX must also parse BER-encoded constructed 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // values such as sequences, sets... 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 260ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin int startPosInInput = in.getPos(); 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tag = (byte)in.read(); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte lenByte = (byte)in.read(); 2637b63247eb7ae2638740bd13f370bdcf9d3603407Przemyslaw Szczepaniak length = DerInputStream.getLength(lenByte, in); 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (length == -1) { // indefinite length encoding found 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerInputBuffer inbuf = in.dup(); 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int readLen = inbuf.available(); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int offset = 2; // for tag and length bytes 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] indefData = new byte[readLen + offset]; 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski indefData[0] = tag; 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski indefData[1] = lenByte; 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DataInputStream dis = new DataInputStream(inbuf); 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dis.readFully(indefData, offset, readLen); 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dis.close(); 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerIndefLenConverter derIn = new DerIndefLenConverter(); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inbuf = new DerInputBuffer(derIn.convert(indefData)); 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != inbuf.read()) 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ("Indefinite length encoding not supported"); 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski length = DerInputStream.getLength(inbuf); 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer = inbuf.dup(); 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.truncate(length); 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data = new DerInputStream(buffer); 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // indefinite form is encoded by sending a length field with a 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // length of 0. - i.e. [1000|0000]. 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the object is ended by sending two zero bytes. 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.skip(length + offset); 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer = in.dup(); 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.truncate(length); 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data = new DerInputStream(buffer); 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.skip(length); 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 295ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin 296ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin if (originalEncodedFormRetained) { 297ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin int consumed = in.getPos() - startPosInInput; 298ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin originalEncodedForm = in.getSlice(startPosInInput, consumed); 299ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin } 300f5a241465eef5d8b4edaaeccc63680e1ea65bb18Przemyslaw Szczepaniak // END Android-changed: Original encoded form needed for APKs parsing/validation 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an ASN.1/DER encoded datum from a buffer. The 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * entire buffer must hold exactly one datum, including 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * its tag and length. 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param buf buffer holding a single DER-encoded datum. 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DerValue(byte[] buf) throws IOException { 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data = init(true, new ByteArrayInputStream(buf)); 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an ASN.1/DER encoded datum from part of a buffer. 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * That part of the buffer must hold exactly one datum, including 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * its tag and length. 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param buf the buffer 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param offset start point of the single DER-encoded dataum 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param length how many bytes are in the encoded datum 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DerValue(byte[] buf, int offset, int len) throws IOException { 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data = init(true, new ByteArrayInputStream(buf, offset, len)); 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an ASN1/DER encoded datum from an input stream. The 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream may have additional data following the encoded datum. 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In case of indefinite length encoded datum, the input stream 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * must hold only one datum. 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in the input stream holding a single DER datum, 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * which may be followed by additional data 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DerValue(InputStream in) throws IOException { 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data = init(false, in); 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private DerInputStream init(byte stringTag, String value) throws IOException { 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String enc = null; 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tag = stringTag; 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (stringTag) { 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case tag_PrintableString: 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case tag_IA5String: 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case tag_GeneralString: 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski enc = "ASCII"; 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case tag_T61String: 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski enc = "ISO-8859-1"; 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case tag_BMPString: 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski enc = "UnicodeBigUnmarked"; 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case tag_UTF8String: 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski enc = "UTF8"; 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // TBD: Need encoder for UniversalString before it can 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // be handled. 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Unsupported DER string type"); 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] buf = value.getBytes(enc); 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski length = buf.length; 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer = new DerInputBuffer(buf); 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerInputStream result = new DerInputStream(buffer); 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result.mark(Integer.MAX_VALUE); 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result; 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * helper routine 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private DerInputStream init(boolean fullyBuffered, InputStream in) 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException { 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tag = (byte)in.read(); 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte lenByte = (byte)in.read(); 3827b63247eb7ae2638740bd13f370bdcf9d3603407Przemyslaw Szczepaniak length = DerInputStream.getLength(lenByte, in); 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (length == -1) { // indefinite length encoding found 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int readLen = in.available(); 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int offset = 2; // for tag and length bytes 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] indefData = new byte[readLen + offset]; 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski indefData[0] = tag; 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski indefData[1] = lenByte; 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DataInputStream dis = new DataInputStream(in); 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dis.readFully(indefData, offset, readLen); 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dis.close(); 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerIndefLenConverter derIn = new DerIndefLenConverter(); 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in = new ByteArrayInputStream(derIn.convert(indefData)); 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != in.read()) 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ("Indefinite length encoding not supported"); 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski length = DerInputStream.getLength(in); 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fullyBuffered && in.available() != length) 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("extra data given to DerValue constructor"); 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] bytes = IOUtils.readFully(in, length, true); 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer = new DerInputBuffer(bytes); 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new DerInputStream(buffer); 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Encode an ASN1/DER encoded datum onto a DER output stream. 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void encode(DerOutputStream out) 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException { 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(tag); 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.putLength(length); 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // XXX yeech, excess copies ... DerInputBuffer.write(OutStream) 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (length > 0) { 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] value = new byte[length]; 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // always synchronized on data 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (data) { 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.reset(); 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buffer.read(value) != length) { 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("short DER value read (encode)"); 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(value); 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final DerInputStream getData() { 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return data; 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final byte getTag() { 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return tag; 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 BOOLEAN 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the boolean held in this DER value 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean getBoolean() throws IOException { 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_Boolean) { 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getBoolean, not a BOOLEAN " + tag); 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (length != 1) { 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getBoolean, invalid length " 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + length); 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buffer.read() != 0) { 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 OBJECT IDENTIFIER. 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the OID held in this DER value 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ObjectIdentifier getOID() throws IOException { 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_ObjectId) 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getOID, not an OID " + tag); 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new ObjectIdentifier(buffer); 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] append(byte[] a, byte[] b) { 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (a == null) 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return b; 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] ret = new byte[a.length + b.length]; 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(a, 0, ret, 0, a.length); 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(b, 0, ret, a.length, b.length); 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ret; 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 OCTET STRING 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the octet string held in this DER value 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getOctetString() throws IOException { 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] bytes; 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_OctetString && !isConstructed(tag_OctetString)) { 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getOctetString, not an Octet String: " + tag); 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bytes = new byte[length]; 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Note: do not tempt to call buffer.read(bytes) at all. There's a 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // known bug that it returns -1 instead of 0. 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (length == 0) { 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bytes; 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buffer.read(bytes) != length) 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("short read on DerValue buffer"); 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isConstructed()) { 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerInputStream in = new DerInputStream(bytes); 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bytes = null; 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (in.available() != 0) { 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bytes = append(bytes, in.getOctetString()); 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bytes; 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 INTEGER value as an integer. 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the integer held in this DER value. 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getInteger() throws IOException { 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_Integer) { 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getInteger, not an int " + tag); 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getInteger(data.available()); 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 INTEGER value as a BigInteger. 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the integer held in this DER value as a BigInteger. 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public BigInteger getBigInteger() throws IOException { 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_Integer) 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getBigInteger, not an int " + tag); 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getBigInteger(data.available(), false); 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 INTEGER value as a positive BigInteger. 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This is just to deal with implementations that incorrectly encode 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * some values as negative. 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the integer held in this DER value as a BigInteger. 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public BigInteger getPositiveBigInteger() throws IOException { 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_Integer) 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getBigInteger, not an int " + tag); 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getBigInteger(data.available(), true); 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 ENUMERATED value. 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the integer held in this DER value. 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getEnumerated() throws IOException { 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_Enumerated) { 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getEnumerated, incorrect tag: " 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + tag); 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getInteger(data.available()); 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 BIT STRING value. The bit string must be byte-aligned. 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the bit string held in this value 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getBitString() throws IOException { 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_BitString) 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getBitString, not a bit string " + tag); 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getBitString(); 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 BIT STRING value that need not be byte-aligned. 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a BitArray representing the bit string held in this value 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public BitArray getUnalignedBitString() throws IOException { 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_BitString) 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getBitString, not a bit string " + tag); 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getUnalignedBitString(); 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the name component as a Java string, regardless of its 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * encoding restrictions (ASCII, T61, Printable, IA5, BMP, UTF8). 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // TBD: Need encoder for UniversalString before it can be handled. 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getAsString() throws IOException { 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag == tag_UTF8String) 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getUTF8String(); 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (tag == tag_PrintableString) 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getPrintableString(); 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (tag == tag_T61String) 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getT61String(); 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (tag == tag_IA5String) 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getIA5String(); 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (tag == tag_UniversalString) 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getUniversalString(); 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (tag == tag_BMPString) 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getBMPString(); 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (tag == tag_GeneralString) 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getGeneralString(); 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 BIT STRING value, with the tag assumed implicit 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * based on the parameter. The bit string must be byte-aligned. 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @params tagImplicit if true, the tag is assumed implicit. 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the bit string held in this value 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getBitString(boolean tagImplicit) throws IOException { 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!tagImplicit) { 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_BitString) 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getBitString, not a bit string " 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + tag); 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getBitString(); 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 BIT STRING value, with the tag assumed implicit 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * based on the parameter. The bit string need not be byte-aligned. 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @params tagImplicit if true, the tag is assumed implicit. 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the bit string held in this value 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public BitArray getUnalignedBitString(boolean tagImplicit) 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException { 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!tagImplicit) { 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_BitString) 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getBitString, not a bit string " 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + tag); 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getUnalignedBitString(); 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Helper routine to return all the bytes contained in the 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DerInputStream associated with this object. 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getDataBytes() throws IOException { 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] retVal = new byte[length]; 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (data) { 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data.reset(); 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data.getBytes(retVal); 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return retVal; 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 STRING value 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the printable string held in this value 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getPrintableString() 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException { 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_PrintableString) 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getPrintableString, not a string " + tag); 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new String(getDataBytes(), "ASCII"); 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 T61 (Teletype) STRING value 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the teletype string held in this value 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getT61String() throws IOException { 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_T61String) 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getT61String, not T61 " + tag); 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new String(getDataBytes(), "ISO-8859-1"); 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an ASN.1 IA5 (ASCII) STRING value 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the ASCII string held in this value 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getIA5String() throws IOException { 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_IA5String) 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getIA5String, not IA5 " + tag); 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new String(getDataBytes(), "ASCII"); 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the ASN.1 BMP (Unicode) STRING value as a Java string. 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a string corresponding to the encoded BMPString held in 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this value 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getBMPString() throws IOException { 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_BMPString) 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getBMPString, not BMP " + tag); 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // BMPString is the same as Unicode in big endian, unmarked 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // format. 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new String(getDataBytes(), "UnicodeBigUnmarked"); 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the ASN.1 UTF-8 STRING value as a Java String. 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a string corresponding to the encoded UTF8String held in 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this value 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getUTF8String() throws IOException { 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_UTF8String) 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getUTF8String, not UTF-8 " + tag); 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new String(getDataBytes(), "UTF8"); 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the ASN.1 GENERAL STRING value as a Java String. 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a string corresponding to the encoded GeneralString held in 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this value 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getGeneralString() throws IOException { 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_GeneralString) 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getGeneralString, not GeneralString " + tag); 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new String(getDataBytes(), "ASCII"); 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a Date if the DerValue is UtcTime. 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the Date held in this DER value 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Date getUTCTime() throws IOException { 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_UtcTime) { 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("DerValue.getUTCTime, not a UtcTime: " + tag); 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getUTCTime(data.available()); 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a Date if the DerValue is GeneralizedTime. 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the Date held in this DER value 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Date getGeneralizedTime() throws IOException { 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != tag_GeneralizedTime) { 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException( 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "DerValue.getGeneralizedTime, not a GeneralizedTime: " + tag); 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buffer.getGeneralizedTime(data.available()); 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true iff the other object is a DER value which 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is bitwise equal to this one. 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param other the object being compared with this one 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(Object other) { 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (other instanceof DerValue) 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return equals((DerValue)other); 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Bitwise equality comparison. DER encoded values have a single 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * encoding, so that bitwise equality of the encoded values is an 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * efficient way to establish equivalence of the unencoded values. 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param other the object being compared with this one 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(DerValue other) { 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (this == other) { 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag != other.tag) { 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (data == other.data) { 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // make sure the order of lock is always consistent to avoid a deadlock 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (System.identityHashCode(this.data) 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski > System.identityHashCode(other.data)) ? 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski doEquals(this, other): 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski doEquals(other, this); 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Helper for public method equals() 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static boolean doEquals(DerValue d1, DerValue d2) { 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (d1.data) { 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (d2.data) { 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d1.data.reset(); 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d2.data.reset(); 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return d1.buffer.equals(d2.buffer); 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a printable representation of the value. 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return printable representation of the value 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String str = getAsString(); 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (str != null) 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "\"" + str + "\""; 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag == tag_Null) 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "[DerValue, null]"; 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag == tag_ObjectId) 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "OID." + getOID(); 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // integers 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "[DerValue, tag = " + tag 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + ", length = " + length + "]"; 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("misformatted DER value"); 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 841f5a241465eef5d8b4edaaeccc63680e1ea65bb18Przemyslaw Szczepaniak // BEGIN Android-added: Original encoded form needed for APKs parsing/validation 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 843ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin * Returns the original encoded form or {@code null} if the form was not 844ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin * retained or is not available. 845ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin */ 846ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin public byte[] getOriginalEncodedForm() { 847ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin return (originalEncodedForm != null) 848ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin ? originalEncodedForm.clone() : null; 849ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin } 850f5a241465eef5d8b4edaaeccc63680e1ea65bb18Przemyslaw Szczepaniak // END Android-added: Original encoded form needed for APKs parsing/validation 851ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin 852ddde3e18b22acdaecb883794f5c8e21f0b87bf2fAlex Klyubin /** 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a DER-encoded value, such that if it's passed to the 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DerValue constructor, a value equivalent to "this" is returned. 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return DER-encoded value, including tag and length. 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] toByteArray() throws IOException { 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerOutputStream out = new DerOutputStream(); 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encode(out); 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data.reset(); 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return out.toByteArray(); 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For "set" and "sequence" types, this function may be used 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to return a DER stream of the members of the set or sequence. 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This operation is not supported for primitive types such as 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * integers or bit strings. 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DerInputStream toDerInputStream() throws IOException { 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag == tag_Sequence || tag == tag_Set) 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new DerInputStream(buffer); 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("toDerInputStream rejects tag type " + tag); 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the length of the encoded value. 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int length() { 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return length; 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Determine if a character is one of the permissible characters for 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * PrintableString: 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A-Z, a-z, 0-9, space, apostrophe (39), left and right parentheses, 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * plus sign, comma, hyphen, period, slash, colon, equals sign, 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and question mark. 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Characters that are *not* allowed in PrintableString include 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exclamation point, quotation mark, number sign, dollar sign, 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * percent sign, ampersand, asterisk, semicolon, less than sign, 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * greater than sign, at sign, left and right square brackets, 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * backslash, circumflex (94), underscore, back quote (96), 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * left and right curly brackets, vertical line, tilde, 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the control codes (0-31 and 127). 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This list is based on X.680 (the ASN.1 spec). 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static boolean isPrintableStringChar(char ch) { 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (ch >= '0' && ch <= '9')) { 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (ch) { 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ' ': /* space */ 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '\'': /* apostrophe */ 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '(': /* left paren */ 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ')': /* right paren */ 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '+': /* plus */ 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ',': /* comma */ 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '-': /* hyphen */ 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '.': /* period */ 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '/': /* slash */ 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ':': /* colon */ 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '=': /* equals */ 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '?': /* question mark */ 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Create the tag of the attribute. 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @params class the tag class type, one of UNIVERSAL, CONTEXT, 93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * APPLICATION or PRIVATE 93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @params form if true, the value is constructed, otherwise it 93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is primitive. 93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @params val the tag value 93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static byte createTag(byte tagClass, boolean form, byte val) { 93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte tag = (byte)(tagClass | val); 93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (form) { 93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tag |= (byte)0x20; 94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (tag); 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Set the tag of the attribute. Commonly used to reset the 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * tag value used for IMPLICIT encodings. 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @params tag the tag value 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void resetTag(byte tag) { 95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.tag = tag; 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a hashcode for this DerValue. 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a hashcode for this DerValue. 95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int hashCode() { 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return toString().hashCode(); 96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 963