Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BERProcessor.java')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BERProcessor.java274
1 files changed, 274 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BERProcessor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BERProcessor.java
new file mode 100644
index 000000000..57b985226
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BERProcessor.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.signedcontent;
+
+import java.math.BigInteger;
+import java.security.SignatureException;
+
+/**
+ * This is a simple class that processes BER structures. This class
+ * uses BER processing as outlined in X.690.
+ */
+public class BERProcessor {
+ /**
+ * This is the buffer that contains the BER structures that are being interrogated.
+ */
+ byte buffer[];
+ /**
+ * The offset into <code>buffer</code> to the start of the structure being interrogated.
+ * If the offset is -1 that means that we have read the last structure.
+ */
+ int offset;
+ /**
+ * The last valid offset in <code>buffer</code>.
+ */
+ int lastOffset;
+ /**
+ * The offset into <code>buffer</code> to the start of the content of the structure
+ * being interrogated.
+ */
+ int contentOffset;
+ /**
+ * The length of the content of the structure being interrogated.
+ */
+ int contentLength;
+ /**
+ * The offset into <code>buffer</code> of the end of the structure being interrogated.
+ */
+ int endOffset;
+ /**
+ * The class of the tag of the current structure.
+ */
+ int classOfTag;
+ static final int UNIVERSAL_TAGCLASS = 0;
+ static final int APPLICATION_TAGCLASS = 1;
+ static final int CONTEXTSPECIFIC_TAGCLASS = 2;
+ static final int PRIVATE_TAGCLASS = 3;
+
+ static final byte BOOLTAG = 1;
+ static final byte INTTAG = 2;
+ static final byte OIDTAG = 6;
+ static final byte SEQTAG = 16;
+ static final byte SETTAG = 17;
+ static final byte NULLTAG = 5;
+
+ /**
+ * Tagnames used in toString()
+ */
+ static final String tagNames[] = {"<null>", "boolean", "int", "bitstring", "octetstring", "null", "objid", "objdesc", "external", "real", "enum", "pdv", "utf8", "relobjid", "resv", "resv", "sequence", "set", "char string"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ //$NON-NLS-17$ //$NON-NLS-18$ //$NON-NLS-19$
+
+ /**
+ * True if this is a structure for a constructed encoding.
+ */
+ public boolean constructed;
+ /**
+ * The tag type. Note that X.690 specifies encodings for tags with values greater than 31,
+ * but currently this class does not handle these kinds of tags.
+ */
+ public byte tag;
+
+ /**
+ * Constructs a BERProcessor to operate on the passed buffer. The first structure in the
+ * buffer will be processed before this method returns.
+ *
+ * @param buffer the buffer containing the BER structures.
+ * @param offset the offset into <code>buffer</code> to the start of the first structure.
+ * @param len the length of the BER structure.
+ * @throws SignatureException
+ */
+ public BERProcessor(byte buffer[], int offset, int len) throws SignatureException {
+ this.buffer = buffer;
+ this.offset = offset;
+ lastOffset = len + offset;
+ processStructure();
+ }
+
+ /**
+ * Parse the structure found at the current <code>offset</code> into <code>buffer</code>.
+ * Most methods, constructor, and stepinto, will call this method automatically. If
+ * <code>offset</code> is modified outside of those methods, this method will need to
+ * be invoked.
+ */
+ public void processStructure() throws SignatureException {
+ // Don't process if we are at the end
+ if (offset == -1)
+ return;
+ endOffset = offset;
+ // section 8.1.2.2
+ classOfTag = (buffer[offset] & 0xff) >> 6;
+ // section 8.1.2.5
+ constructed = (buffer[offset] & 0x20) != 0;
+ // section 8.1.2.3
+ byte tagNumber = (byte) (buffer[offset] & 0x1f);
+ if (tagNumber < 32) {
+ tag = tagNumber;
+ endOffset = offset + 1;
+ } else {
+ throw new SignatureException("Can't handle tags > 32"); //$NON-NLS-1$
+ }
+ if ((buffer[endOffset] & 0x80) == 0) {
+ // section 8.1.3.4 (doing the short form of the length)
+ contentLength = buffer[endOffset];
+ endOffset++;
+ } else {
+ // section 8.1.3.5 (doing the long form of the length)
+ int octetCount = buffer[endOffset] & 0x7f;
+ if (octetCount > 3)
+ throw new SignatureException("ContentLength octet count too large: " + octetCount); //$NON-NLS-1$
+ contentLength = 0;
+ endOffset++;
+ for (int i = 0; i < octetCount; i++) {
+ contentLength <<= 8;
+ contentLength |= buffer[endOffset] & 0xff;
+ endOffset++;
+ }
+ // section 8.1.3.6 (doing the indefinite form
+ if (octetCount == 0)
+ contentLength = -1;
+ }
+ contentOffset = endOffset;
+ if (contentLength != -1)
+ endOffset += contentLength;
+ if (endOffset > lastOffset)
+ throw new SignatureException("Content length too large: " + endOffset + " > " + lastOffset); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Returns a String representation of the current BER structure.
+ * @return a String representation of the current BER structure.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ switch (classOfTag) {
+ case UNIVERSAL_TAGCLASS :
+ sb.append('U');
+ break;
+ case APPLICATION_TAGCLASS :
+ sb.append('A');
+ break;
+ case CONTEXTSPECIFIC_TAGCLASS :
+ sb.append('C');
+ break;
+ case PRIVATE_TAGCLASS :
+ sb.append('P');
+ break;
+ }
+ sb.append(constructed ? 'C' : 'P');
+ sb.append(" tag=" + tag); //$NON-NLS-1$
+ if (tag < tagNames.length) {
+ sb.append("(" + tagNames[tag] + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ sb.append(" len="); //$NON-NLS-1$
+ sb.append(contentLength);
+ switch (tag) {
+ case INTTAG :
+ sb.append(" value=" + getIntValue()); //$NON-NLS-1$
+ break;
+ case OIDTAG :
+ sb.append(" value="); //$NON-NLS-1$
+ int oid[] = getObjId();
+ for (int i = 0; i < oid.length; i++) {
+ if (i > 0)
+ sb.append('.');
+ sb.append(oid[i]);
+ }
+ }
+ if (tag == 12 || (tag >= 18 && tag <= 22) || (tag >= 25 && tag <= 30)) {
+ sb.append(" value="); //$NON-NLS-1$
+ sb.append(getString());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns a BERProcessor for the content of the current structure.
+ * @throws SignatureException
+ */
+ public BERProcessor stepInto() throws SignatureException {
+ return new BERProcessor(buffer, contentOffset, contentLength);
+ }
+
+ public void stepOver() throws SignatureException {
+ offset = endOffset;
+ if (endOffset >= lastOffset) {
+ offset = -1;
+ return;
+ }
+ processStructure();
+ }
+
+ public boolean endOfSequence() {
+ return offset == -1;
+ }
+
+ /**
+ * Gets the content from the current structure as a String.
+ * @return the content from the current structure as a String.
+ */
+ public String getString() {
+ return new String(buffer, contentOffset, contentLength);
+ }
+
+ /**
+ * Gets the content from the current structure as an int.
+ * @return the content from the current structure as an int.
+ */
+ public BigInteger getIntValue() {
+ return new BigInteger(getBytes());
+ }
+
+ /**
+ * Gets the content from the current structure as an object id (int[]).
+ * @return the content from the current structure as an object id (int[]).
+ */
+ public int[] getObjId() {
+ // First count the ids
+ int count = 0;
+ for (int i = 0; i < contentLength; i++) {
+ // section 8.19.2
+ if ((buffer[contentOffset + i] & 0x80) == 0)
+ count++;
+ }
+ count++; // section 8.19.3
+ int oid[] = new int[count];
+ int index = 0;
+ int currentValue = 0;
+ for (int i = 0; i < contentLength; i++) {
+ currentValue <<= 7;
+ currentValue |= buffer[contentOffset + i] & 0x7f;
+ // section 8.19.2
+ if ((buffer[contentOffset + i] & 0x80) == 0) {
+ if (index == 0) {
+ // section 8.19.4 special processing
+ oid[index++] = currentValue / 40;
+ oid[index++] = currentValue % 40;
+ } else {
+ oid[index++] = currentValue;
+ }
+ currentValue = 0;
+ }
+ }
+ return oid;
+ }
+
+ /**
+ * Get a copy of the bytes in the content of the current structure.
+ * @return a copy of the bytes in the content of the current structure.
+ */
+ public byte[] getBytes() {
+ byte v[] = new byte[contentLength];
+ System.arraycopy(buffer, contentOffset, v, 0, contentLength);
+ return v;
+ }
+
+}

Back to the top