All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.mobileconnectors.iot.DerParser Maven / Gradle / Ivy

Go to download

The AWS Android SDK for AWS IoT module holds the client classes that are used for communicating with AWS IoT Service

There is a newer version: 2.6.27
Show newest version
/****************************************************************************
 * Amazon Modifications: Copyright 2016 Amazon.com, Inc. or its affiliates.
 * All Rights Reserved.
 *****************************************************************************
 * Copyright (c) 1998-2010 AOL Inc. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ****************************************************************************/
// http://oauth.googlecode.com/svn/code/branches/jmeter/jmeter/src/main/java/org/apache/jmeter/protocol/oauth/sampler/PrivateKeyReader.java

package com.amazonaws.mobileconnectors.iot;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;

/**
 * A bare-minimum ASN.1 DER decoder, just having enough functions to decode
 * PKCS#1 private keys. Especially, it doesn't handle explicitly tagged types
 * with an outer tag. This parser can only handle one layer. To parse nested
 * constructs, get a new parser for each layer using
 * Asn1Object.getParser(). There are many DER decoders in JRE but
 * using them will tie this program to a specific JCE/JVM.
 */
class DerParser {
    // Classes
    /** UNIVERSAL class. */
    public static final int UNIVERSAL = 0x00;
    /** APPLICATION class. */
    public static final int APPLICATION = 0x40;
    /** CONTEXT class. */
    public static final int CONTEXT = 0x80;
    /** PRIVATE class. */
    public static final int PRIVATE = 0xC0;

    /** Constructed Flag. */
    public static final int CONSTRUCTED = 0x20;

    // Tag and data types
    /** ANY tag/type. */
    public static final int ANY = 0x00;
    /** BOOLEAN tag/type. */
    public static final int BOOLEAN = 0x01;
    /** INTEGER tag/type. */
    public static final int INTEGER = 0x02;
    /** BIT_STRING tag/type. */
    public static final int BIT_STRING = 0x03;
    /** OCTET_STRING tag/type. */
    public static final int OCTET_STRING = 0x04;
    /** NULL tag/type. */
    public static final int NULL = 0x05;
    /** OBJECT_IDENTIFIER tag/type. */
    public static final int OBJECT_IDENTIFIER = 0x06;
    /** REAL tag/type. */
    public static final int REAL = 0x09;
    /** ENUMERATED tag/type. */
    public static final int ENUMERATED = 0x0a;
    /** RELATIVE_OID tag/type. */
    public static final int RELATIVE_OID = 0x0d;
    /** v tag/type. */
    public static final int SEQUENCE = 0x10;
    /** SET tag/type. */
    public static final int SET = 0x11;
    /** NUMERIC_STRING tag/type. */
    public static final int NUMERIC_STRING = 0x12;
    /** PRINTABLE_STRING tag/type. */
    public static final int PRINTABLE_STRING = 0x13;
    /** T61_STRING tag/type. */
    public static final int T61_STRING = 0x14;
    /** VIDEOTEX_STRING tag/type. */
    public static final int VIDEOTEX_STRING = 0x15;
    /** IA5_STRING tag/type. */
    public static final int IA5_STRING = 0x16;
    /** GRAPHIC_STRING tag/type. */
    public static final int GRAPHIC_STRING = 0x19;
    /** ISO646_STRING tag/type. */
    public static final int ISO646_STRING = 0x1A;
    /** GENERAL_STRING tag/type. */
    public static final int GENERAL_STRING = 0x1B;
    /** UTF8_STRING tag/type. */
    public static final int UTF8_STRING = 0x0C;
    /** UNIVERSAL_STRING tag/type. */
    public static final int UNIVERSAL_STRING = 0x1C;
    /** BMP_STRING tag/type. */
    public static final int BMP_STRING = 0x1E;
    /** UTC_TIME tag/type. */
    public static final int UTC_TIME = 0x17;
    /** GENERALIZED_TIME tag/type. */
    public static final int GENERALIZED_TIME = 0x18;

    /** Lower 7 bits mask. */
    public static final byte LOWER_7_BITS = (byte) 0x7F;
    /** Byte max value. */
    public static final int BYTE_MAX = (int) 0xFF;
    /** We can't handle length longer than 4 bytes. */
    public static final int MAX_NUMBER_OF_BYTES = 4;

    /** The DER encoded input stream. */
    private final InputStream in;

    /**
     * Create a new DER decoder from an input stream.
     * 
     * @param in DER encoded stream
     */
    public DerParser(InputStream in) {
        this.in = in;
    }

    /**
     * Create a new DER decoder from a byte array.
     * 
     * @param bytes encoded bytes
     */
    public DerParser(byte[] bytes) {
        this(new ByteArrayInputStream(bytes));
    }

    /**
     * Read next object. If it's constructed, the value holds encoded content
     * and it should be parsed by a new parser from
     * Asn1Object.getParser.
     *
     * @return Asn1Object read
     * @throws IOException if DER parsing error (format).
     */
    public Asn1Object read() throws IOException {
        int tag = in.read();

        if (tag == -1) {
            throw new IOException("Invalid DER: stream too short, missing tag"); //$NON-NLS-1$
        }

        int length = getLength();

        byte[] value = new byte[length];
        int n = in.read(value);
        if (n < length) {
            throw new IOException("Invalid DER: stream too short, missing value"); //$NON-NLS-1$
        }

        Asn1Object o = new Asn1Object(tag, length, value);

        return o;
    }

    /**
     * Decode the length of the field. Can only support length encoding up to 4
     * octets.
     * 

* In BER/DER encoding, length can be encoded in 2 forms, *

    *
  • Short form. One octet. Bit 8 has value "0" and bits 7-1 give the * length. *
  • Long form. Two to 127 octets (only 4 is supported here). Bit 8 of * first octet has value "1" and bits 7-1 give the number of additional * length octets. Second and following octets give the length, base 256, * most significant digit first. *
* * @return The length as integer * @throws IOException if invalid DER. */ private int getLength() throws IOException { int i = in.read(); if (i == -1) { throw new IOException("Invalid DER: length missing"); //$NON-NLS-1$ } // A single byte short length if ((i & ~LOWER_7_BITS) == 0) { return i; } int num = i & LOWER_7_BITS; if (i >= BYTE_MAX || num > MAX_NUMBER_OF_BYTES) { throw new IOException("Invalid DER: length field too big (" + i + ")"); //$NON-NLS-1$ } byte[] bytes = new byte[num]; int n = in.read(bytes); if (n < num) { throw new IOException("Invalid DER: length too short"); //$NON-NLS-1$ } return new BigInteger(1, bytes).intValue(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy