summaryrefslogtreecommitdiffstats
path: root/libjava/gnu/java/security/der/DERReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/java/security/der/DERReader.java')
-rw-r--r--libjava/gnu/java/security/der/DERReader.java437
1 files changed, 0 insertions, 437 deletions
diff --git a/libjava/gnu/java/security/der/DERReader.java b/libjava/gnu/java/security/der/DERReader.java
deleted file mode 100644
index cb07f14325f..00000000000
--- a/libjava/gnu/java/security/der/DERReader.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/* DERReader.java -- parses ASN.1 DER sequences
- Copyright (C) 2003 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package gnu.java.security.der;
-
-import gnu.java.security.OID;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * This class decodes DER sequences into Java objects. The methods of
- * this class do not have knowledge of higher-levels of structure in the
- * DER stream -- such as ASN.1 constructions -- and it is therefore up
- * to the calling application to determine if the data are structured
- * properly by inspecting the {@link DERValue} that is returned.
- *
- * @author Casey Marshall (csm@gnu.org)
- */
-public class DERReader implements DER
-{
-
- // Fields.
- // ------------------------------------------------------------------------
-
- protected InputStream in;
-
- protected final ByteArrayOutputStream encBuf;
-
- // Constructor.
- // ------------------------------------------------------------------------
-
- /**
- * Create a new DER reader from a byte array.
- *
- * @param in The encoded bytes.
- */
- public DERReader(byte[] in)
- {
- this(new ByteArrayInputStream(in));
- }
-
- public DERReader (byte[] in, int off, int len)
- {
- this (new ByteArrayInputStream (in, off, len));
- }
-
- /**
- * Create a new DER readed from an input stream.
- *
- * @param in The encoded bytes.
- */
- public DERReader(InputStream in)
- {
- if (!in.markSupported())
- this.in = new BufferedInputStream(in, 16384);
- else
- this.in = in;
- encBuf = new ByteArrayOutputStream(2048);
- }
-
- // Class methods.
- // ------------------------------------------------------------------------
-
- /**
- * Convenience method for reading a single primitive value from the
- * given byte array.
- *
- * @param encoded The encoded bytes.
- * @throws IOException If the bytes do not represent an encoded
- * object.
- */
- public static DERValue read(byte[] encoded) throws IOException
- {
- return new DERReader(encoded).read();
- }
-
- // Instance methods.
- // ------------------------------------------------------------------------
-
- public void skip (int bytes) throws IOException
- {
- in.skip (bytes);
- }
-
- /**
- * Decode a single value from the input stream, returning it in a new
- * {@link DERValue}. By "single value" we mean any single type in its
- * entirety -- including constructed types such as SEQUENCE and all
- * the values they contain. Usually it is sufficient to call this
- * method once to parse and return the top-level structure, then to
- * inspect the returned value for the proper contents.
- *
- * @return The parsed DER structure.
- * @throws IOException If an error occurs reading from the input
- * stream.
- * @throws DEREncodingException If the input does not represent a
- * valid DER stream.
- */
- public DERValue read() throws IOException
- {
- int tag = in.read();
- if (tag == -1)
- throw new EOFException();
- encBuf.write(tag);
- int len = readLength();
- DERValue value = null;
- if ((tag & CONSTRUCTED) == CONSTRUCTED)
- {
- in.mark(2048);
- byte[] encoded = new byte[len];
- in.read(encoded);
- encBuf.write(encoded);
- value = new DERValue(tag, len, CONSTRUCTED_VALUE, encBuf.toByteArray());
- in.reset();
- encBuf.reset();
- return value;
- }
- switch (tag & 0xC0)
- {
- case UNIVERSAL:
- value = new DERValue(tag, len, readUniversal(tag, len),
- encBuf.toByteArray());
- encBuf.reset();
- break;
- case CONTEXT:
- byte[] encoded = new byte[len];
- in.read(encoded);
- encBuf.write(encoded);
- value = new DERValue(tag, len, encoded, encBuf.toByteArray());
- encBuf.reset();
- break;
- case APPLICATION:
- // This should not be reached, since (I think) APPLICATION is
- // always constructed.
- throw new DEREncodingException("non-constructed APPLICATION data");
- default:
- throw new DEREncodingException("PRIVATE class not supported");
- }
- return value;
- }
-
- protected int readLength() throws IOException
- {
- int i = in.read();
- if (i == -1)
- throw new EOFException();
- encBuf.write(i);
- if ((i & ~0x7F) == 0)
- {
- return i;
- }
- else if (i < 0xFF)
- {
- byte[] octets = new byte[i & 0x7F];
- in.read(octets);
- encBuf.write(octets);
- return new BigInteger(1, octets).intValue();
- }
- throw new DEREncodingException();
- }
-
- // Own methods.
- // ------------------------------------------------------------------------
-
- private Object readUniversal(int tag, int len) throws IOException
- {
- byte[] value = new byte[len];
- in.read(value);
- encBuf.write(value);
- switch (tag & 0x1F)
- {
- case BOOLEAN:
- if (value.length != 1)
- throw new DEREncodingException();
- return Boolean.valueOf(value[0] != 0);
- case NULL:
- if (len != 0)
- throw new DEREncodingException();
- return null;
- case INTEGER:
- case ENUMERATED:
- return new BigInteger(value);
- case BIT_STRING:
- byte[] bits = new byte[len - 1];
- System.arraycopy(value, 1, bits, 0, bits.length);
- return new BitString(bits, value[0] & 0xFF);
- case OCTET_STRING:
- return value;
- case NUMERIC_STRING:
- case PRINTABLE_STRING:
- case T61_STRING:
- case VIDEOTEX_STRING:
- case IA5_STRING:
- case GRAPHIC_STRING:
- case ISO646_STRING:
- case GENERAL_STRING:
- case UNIVERSAL_STRING:
- case BMP_STRING:
- case UTF8_STRING:
- return makeString(tag, value);
- case UTC_TIME:
- case GENERALIZED_TIME:
- return makeTime(tag, value);
- case OBJECT_IDENTIFIER:
- return new OID(value);
- case RELATIVE_OID:
- return new OID(value, true);
- default:
- throw new DEREncodingException("unknown tag " + tag);
- }
- }
-
- private static String makeString(int tag, byte[] value)
- throws IOException
- {
- switch (tag & 0x1F)
- {
- case NUMERIC_STRING:
- case PRINTABLE_STRING:
- case T61_STRING:
- case VIDEOTEX_STRING:
- case IA5_STRING:
- case GRAPHIC_STRING:
- case ISO646_STRING:
- case GENERAL_STRING:
- return fromIso88591(value);
-
- case UNIVERSAL_STRING:
- // XXX The docs say UniversalString is encoded in four bytes
- // per character, but Java has no support (yet) for UTF-32.
- //return new String(buf, "UTF-32");
- case BMP_STRING:
- return fromUtf16Be(value);
-
- case UTF8_STRING:
- return fromUtf8(value);
-
- default:
- throw new DEREncodingException("unknown string tag");
- }
- }
-
- private static String fromIso88591(byte[] bytes)
- {
- StringBuffer str = new StringBuffer(bytes.length);
- for (int i = 0; i < bytes.length; i++)
- str.append((char) (bytes[i] & 0xFF));
- return str.toString();
- }
-
- private static String fromUtf16Be(byte[] bytes) throws IOException
- {
- if ((bytes.length & 0x01) != 0)
- throw new IOException("UTF-16 bytes are odd in length");
- StringBuffer str = new StringBuffer(bytes.length / 2);
- for (int i = 0; i < bytes.length; i += 2)
- {
- char c = (char) ((bytes[i] << 8) & 0xFF);
- c |= (char) (bytes[i+1] & 0xFF);
- str.append(c);
- }
- return str.toString();
- }
-
- private static String fromUtf8(byte[] bytes) throws IOException
- {
- StringBuffer str = new StringBuffer((int)(bytes.length / 1.5));
- for (int i = 0; i < bytes.length; )
- {
- char c = 0;
- if ((bytes[i] & 0xE0) == 0xE0)
- {
- if ((i + 2) >= bytes.length)
- throw new IOException("short UTF-8 input");
- c = (char) ((bytes[i++] & 0x0F) << 12);
- if ((bytes[i] & 0x80) != 0x80)
- throw new IOException("malformed UTF-8 input");
- c |= (char) ((bytes[i++] & 0x3F) << 6);
- if ((bytes[i] & 0x80) != 0x80)
- throw new IOException("malformed UTF-8 input");
- c |= (char) (bytes[i++] & 0x3F);
- }
- else if ((bytes[i] & 0xC0) == 0xC0)
- {
- if ((i + 1) >= bytes.length)
- throw new IOException("short input");
- c = (char) ((bytes[i++] & 0x1F) << 6);
- if ((bytes[i] & 0x80) != 0x80)
- throw new IOException("malformed UTF-8 input");
- c |= (char) (bytes[i++] & 0x3F);
- }
- else if ((bytes[i] & 0xFF) < 0x80)
- {
- c = (char) (bytes[i++] & 0xFF);
- }
- else
- throw new IOException("badly formed UTF-8 sequence");
- str.append(c);
- }
- return str.toString();
- }
-
- private Date makeTime(int tag, byte[] value) throws IOException
- {
- Calendar calendar = Calendar.getInstance();
- String str = makeString(PRINTABLE_STRING, value);
-
- // Classpath's SimpleDateFormat does not work for parsing these
- // types of times, so we do this by hand.
- String date = str;
- String tz = "";
- if (str.indexOf("+") > 0)
- {
- date = str.substring(0, str.indexOf("+"));
- tz = str.substring(str.indexOf("+"));
- }
- else if (str.indexOf("-") > 0)
- {
- date = str.substring(0, str.indexOf("-"));
- tz = str.substring(str.indexOf("-"));
- }
- else if (str.endsWith("Z"))
- {
- date = str.substring(0, str.length()-2);
- tz = "Z";
- }
- if (!tz.equals("Z") && tz.length() > 0)
- calendar.setTimeZone(TimeZone.getTimeZone(tz));
- else
- calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
- if ((tag & 0x1F) == UTC_TIME)
- {
- if (date.length() < 10) // must be at least 10 chars long
- throw new DEREncodingException("cannot parse date");
- // UTCTime is of the form "yyMMddHHmm[ss](Z|(+|-)hhmm)"
- try
- {
- int year = Integer.parseInt(str.substring(0, 2));
- if (year < 50)
- year += 2000;
- else
- year += 1900;
- calendar.set(year,
- Integer.parseInt(str.substring( 2, 4))-1, // month
- Integer.parseInt(str.substring( 4, 6)), // day
- Integer.parseInt(str.substring( 6, 8)), // hour
- Integer.parseInt(str.substring( 8, 10))); // minute
- if (date.length() == 12);
- calendar.set(Calendar.SECOND,
- Integer.parseInt(str.substring(10, 12)));
- }
- catch (NumberFormatException nfe)
- {
- throw new DEREncodingException("cannot parse date");
- }
- }
- else
- {
- if (date.length() < 10) // must be at least 10 chars long
- throw new DEREncodingException("cannot parse date");
- // GeneralTime is of the form "yyyyMMddHH[mm[ss[(.|,)SSSS]]]"
- // followed by "Z" or "(+|-)hh[mm]"
- try
- {
- calendar.set(
- Integer.parseInt(date.substring(0, 4)), // year
- Integer.parseInt(date.substring(4, 6))-1, // month
- Integer.parseInt(date.substring(6, 8)), // day
- Integer.parseInt(date.substring(8, 10)), 0); // hour, min
- switch (date.length())
- {
- case 19:
- case 18:
- case 17:
- case 16:
- calendar.set(Calendar.MILLISECOND,
- Integer.parseInt(date.substring(15)));
- case 14:
- calendar.set(Calendar.SECOND,
- Integer.parseInt(date.substring(12, 14)));
- case 12:
- calendar.set(Calendar.MINUTE,
- Integer.parseInt(date.substring(10, 12)));
- }
- }
- catch (NumberFormatException nfe)
- {
- throw new DEREncodingException("cannot parse date");
- }
- }
- return calendar.getTime();
- }
-}
OpenPOWER on IntegriCloud