/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2009 Sun Microsystems, Inc.
* Portions Copyright 2012 Forgerock AS
*/
/**
* An ASN.1 reader that reads from a {@link ByteSequenceReader}.
*/
{
private final int maxElementSize;
/**
* Creates a new ASN1 reader whose source is the provided byte
* sequence reader and having a user defined maximum BER element
* size.
*
* @param reader
* The byte sequence reader to be read.
* @param maxElementSize
* The maximum BER element size, or <code>0</code> to
* indicate that there is no limit.
*/
{
this.maxElementSize = maxElementSize;
}
/**
* {@inheritDoc}
*/
{
{
// Read just the type.
{
throw new ASN1Exception(message);
}
}
return peekType;
}
/**
* {@inheritDoc}
*/
{
peekType();
{
needFirstLengthByteState(true);
}
return peekLength;
}
/**
* Determines if a complete ASN.1 element is waiting to be read from the
* byte sequence.
*
* @return <code>true</code> if another complete element is available or
* <code>false</code> otherwise.
* @throws ASN1Exception If an error occurs while trying to decode
* an ASN1 element.
*/
{
if(state == ELEMENT_READ_STATE_NEED_TYPE &&
!needTypeState(false)) {
return false;
}
!needFirstLengthByteState(false)) {
return false;
}
}
/**
* Determines if the byte sequence contains at least one ASN.1 element to
* be read.
*
* @return <code>true</code> if another element is available or
* <code>false</code> otherwise.
* @throws ASN1Exception If an error occurs while trying to decode
* an ASN1 element.
*/
{
}
/**
* Internal helper method reading the ASN.1 type byte and transition to
* the next state if successful.
*
* @param throwEofException <code>true</code> to throw an exception when
* the end of the sequence is encountered.
* @return <code>true</code> if the type byte was successfully read
* @throws ASN1Exception If an error occurs while trying to decode
* an ASN1 element.
*/
throws ASN1Exception
{
// Read just the type.
{
{
throw new ASN1Exception(message);
}
return false;
}
return true;
}
/**
* Internal helper method reading the first length bytes and transition to
* the next state if successful.
*
* @param throwEofException <code>true</code> to throw an exception when
* the end of the sequence is encountered.
* @return <code>true</code> if the length bytes was successfully read
* @throws ASN1Exception If an error occurs while trying to decode
* an ASN1 element.
*/
throws ASN1Exception
{
{
{
throw new ASN1Exception(message);
}
return false;
}
if (peekLength != readByte)
{
int lengthBytesNeeded = peekLength;
if (lengthBytesNeeded > 4)
{
throw new ASN1Exception(message);
}
peekLength = 0x00;
{
{
throw new ASN1Exception(message);
}
return false;
}
while(lengthBytesNeeded > 0)
{
}
}
// Make sure that the element is not larger than the maximum allowed
// message size.
{
throw new ASN1Exception(m);
}
return true;
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
if (peekLength != 1)
{
throw new ASN1Exception(message);
}
{
throw new ASN1Exception(message);
}
return readByte != 0x00;
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
{
throw new ASN1Exception(message);
}
// From an implementation point of view, an enumerated value is
// equivalent to an integer.
return (int) readInteger();
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
{
throw new ASN1Exception(message);
}
{
throw new ASN1Exception(message);
}
if(peekLength > 4)
{
long longValue = 0;
for (int i=0; i < peekLength; i++)
{
{
longValue = 0xFFFFFFFFFFFFFFFFL;
}
}
return longValue;
}
else
{
int intValue = 0;
for (int i=0; i < peekLength; i++)
{
{
intValue = 0xFFFFFFFF;
}
}
return intValue;
}
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
// Make sure that the decoded length is exactly zero byte.
if (peekLength != 0)
{
throw new ASN1Exception(message);
}
}
/**
* {@inheritDoc}
*/
// Read the header if haven't done so already
peekLength();
{
throw new ASN1Exception(message);
}
}
/**
* {@inheritDoc}
*/
{
// We could cache the UTF-8 CharSet if performance proves to be an
// issue.
return readOctetStringAsString("UTF-8");
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
{
throw new ASN1Exception(message);
}
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
// Copy the value.
{
throw new ASN1Exception(message);
}
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
{
throw new ASN1Exception(message);
}
.asReader();
// Reset the state
}
/**
* {@inheritDoc}
*/
{
// From an implementation point of view, an explicit tag is equivalent to a
// sequence, as it is a constructed type.
}
/**
* {@inheritDoc}
*/
{
// From an implementation point of view, a set is equivalent to a
// sequence.
}
/**
* {@inheritDoc}
*/
{
if(readerStack.isEmpty())
{
throw new ASN1Exception(message);
}
{
}
// Reset the state
}
/**
* {@inheritDoc}
*/
{
// From an implementation point of view, an explicit tag is equivalent to a
// sequence, as it is also a constructed type.
}
/**
* {@inheritDoc}
*/
{
// From an implementation point of view, a set is equivalent to a
// sequence.
}
/**
* {@inheritDoc}
*/
{
// Read the header if haven't done so already
peekLength();
{
throw new ASN1Exception(message);
}
}
/**
* {@inheritDoc}
*/
{
readerStack.clear();
}
}