| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2012 ForgeRock AS. |
| | | * Portions copyright 2012-2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.asn1; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.*; |
| | | import static com.forgerock.opendj.util.StaticUtils.IO_LOG; |
| | | import static com.forgerock.opendj.util.StaticUtils.byteToHex; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.LinkedList; |
| | | import java.util.logging.Level; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | |
| | | import com.forgerock.opendj.util.SizeLimitInputStream; |
| | | import com.forgerock.opendj.util.StaticUtils; |
| | | |
| | | /** |
| | | * An ASN1Reader that reads from an input stream. |
| | |
| | | throw DecodeException.fatalError(message); |
| | | } |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format( |
| | | "READ ASN.1 BOOLEAN(type=0x%x, length=%d, value=%s)", peekType, peekLength, |
| | | String.valueOf(readByte != 0x00))); |
| | | if (IO_LOG.isTraceEnabled()) { |
| | | IO_LOG.trace("READ ASN.1 BOOLEAN(type=0x{}, length={}, value={})", |
| | | byteToHex(peekType), peekLength, String.valueOf(readByte != 0x00)); |
| | | } |
| | | |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return readByte != 0x00; |
| | | } |
| | |
| | | // Ignore all unused trailing components. |
| | | final SizeLimitInputStream subSq = (SizeLimitInputStream) in; |
| | | if (subSq.getSizeLimit() - subSq.getBytesRead() > 0) { |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE)) { |
| | | StaticUtils.DEBUG_LOG.fine(String.format( |
| | | "Ignoring %d unused trailing bytes in ASN.1 SEQUENCE", subSq.getSizeLimit() |
| | | - subSq.getBytesRead())); |
| | | if (IO_LOG.isTraceEnabled()) { |
| | | IO_LOG.trace("Ignoring {} unused trailing bytes in ASN.1 SEQUENCE", |
| | | subSq.getSizeLimit() - subSq.getBytesRead()); |
| | | } |
| | | |
| | | subSq.skip(subSq.getSizeLimit() - subSq.getBytesRead()); |
| | | } |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format("READ ASN.1 END SEQUENCE")); |
| | | } |
| | | IO_LOG.trace("READ ASN.1 END SEQUENCE"); |
| | | |
| | | in = streamStack.removeFirst(); |
| | | |
| | |
| | | intValue = (intValue << 8) | (readByte & 0xFF); |
| | | } |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format( |
| | | "READ ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", peekType, peekLength, |
| | | intValue)); |
| | | } |
| | | IO_LOG.trace("READ ASN.1 INTEGER(type=0x{}, length={}, value={})", |
| | | byteToHex(peekType), peekLength, intValue); |
| | | |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return intValue; |
| | |
| | | throw DecodeException.fatalError(message); |
| | | } |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format("READ ASN.1 NULL(type=0x%x, length=%d)", |
| | | peekType, peekLength)); |
| | | } |
| | | IO_LOG.trace("READ ASN.1 NULL(type=0x{}, length={})", |
| | | byteToHex(peekType), peekLength); |
| | | |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | } |
| | |
| | | bytesNeeded -= bytesRead; |
| | | } |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format( |
| | | "READ ASN.1 OCTETSTRING(type=0x%x, length=%d)", peekType, peekLength)); |
| | | } |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={})", byteToHex(peekType), peekLength); |
| | | |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return ByteString.wrap(value); |
| | |
| | | bytesNeeded -= bytesRead; |
| | | } |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format( |
| | | "READ ASN.1 OCTETSTRING(type=0x%x, length=%d)", peekType, peekLength)); |
| | | } |
| | | |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={})", byteToHex(peekType), peekLength); |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return builder; |
| | | } |
| | |
| | | String str; |
| | | try { |
| | | str = new String(buffer, 0, peekLength, "UTF-8"); |
| | | } catch (final Exception e) { |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING)) { |
| | | StaticUtils.DEBUG_LOG.warning("Unable to decode ASN.1 OCTETSTRING " |
| | | + "bytes as UTF-8 string: " + e.toString()); |
| | | } |
| | | |
| | | str = new String(buffer, 0, peekLength); |
| | | } catch (final UnsupportedEncodingException e) { |
| | | // TODO: I18N |
| | | throw new RuntimeException("Unable to decode ASN.1 OCTETSTRING bytes as UTF-8 string ", e); |
| | | } |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format( |
| | | "READ ASN.1 OCTETSTRING(type=0x%x, length=%d, value=%s)", peekType, peekLength, |
| | | str)); |
| | | } |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={}, value={})", |
| | | byteToHex(peekType), peekLength, str); |
| | | |
| | | return str; |
| | | } |
| | |
| | | |
| | | final SizeLimitInputStream subStream = new SizeLimitInputStream(in, peekLength); |
| | | |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST)) { |
| | | StaticUtils.DEBUG_LOG.finest(String.format( |
| | | "READ ASN.1 START SEQUENCE(type=0x%x, length=%d)", peekType, peekLength)); |
| | | } |
| | | IO_LOG.trace("READ ASN.1 START SEQUENCE(type=0x{}, length={})", byteToHex(peekType), peekLength); |
| | | |
| | | streamStack.addFirst(in); |
| | | in = subStream; |