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

org.bouncycastle.asn1.DefiniteLengthInputStream Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for Java 1.8 and later with debug enabled.

The newest version!
package org.bouncycastle.asn1;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;

import org.bouncycastle.util.io.Streams;

/**
 * Parse data stream of expected ASN.1 data expecting definite-length encoding..
 */
class DefiniteLengthInputStream
        extends LimitedInputStream
{
    private static final byte[] EMPTY_BYTES = new byte[0];

    private final int _originalLength;

    private int _remaining;

    DefiniteLengthInputStream(
        InputStream in,
        int         length,
        int         limit)
    {
        super(in, limit);

        if (length <= 0)
        {
            if (length < 0)
            {
                throw new IllegalArgumentException("negative lengths not allowed");
            }

            setParentEofDetect(true);
        }

        this._originalLength = length;
        this._remaining = length;
    }

    int getRemaining()
    {
        return _remaining;
    }

    public int read()
        throws IOException
    {
        if (_remaining == 0)
        {
            return -1;
        }

        int b = _in.read();

        if (b < 0)
        {
            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
        }

        if (--_remaining == 0)
        {
            setParentEofDetect(true);
        }

        return b;
    }

    public int read(byte[] buf, int off, int len)
        throws IOException
    {
        if (_remaining == 0)
        {
            return -1;
        }

        int toRead = Math.min(len, _remaining);
        int numRead = _in.read(buf, off, toRead);

        if (numRead < 0)
        {
            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
        }

        if ((_remaining -= numRead) == 0)
        {
            setParentEofDetect(true);
        }

        return numRead;
    }

    void readAllIntoByteArray(byte[] buf)
        throws IOException
    {
        if (_remaining != buf.length)
        {
            throw new IllegalArgumentException("buffer length not right for data");
        }

        if (_remaining == 0)
        {
            return;
        }

        // make sure it's safe to do this!
        int limit = getLimit();
        if (_remaining >= limit)
        {
            throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
        }

        if ((_remaining -= Streams.readFully(_in, buf, 0, buf.length)) != 0)
        {
            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
        }
        setParentEofDetect(true);
    }

    byte[] toByteArray()
        throws IOException
    {
        if (_remaining == 0)
        {
            return EMPTY_BYTES;
        }

        // make sure it's safe to do this!
        int limit = getLimit();
        if (_remaining >= limit)
        {
            throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
        }

        byte[] bytes = new byte[_remaining];
        if ((_remaining -= Streams.readFully(_in, bytes, 0, bytes.length)) != 0)
        {
            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
        }
        setParentEofDetect(true);
        return bytes;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy