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