package ch.ethz.ssh2.crypto; import java.io.IOException; import net.rim.device.api.crypto.CryptoInteger; import org.bbssh.ssh.v2.BigInteger; /** * SimpleDERReader. * * @author Christian Plattner, plattner@inf.ethz.ch * @version $Id: SimpleDERReader.java,v 1.3 2006/08/11 12:24:00 cplattne Exp $ */ public class SimpleDERReader { byte[] buffer; int pos; int count; public SimpleDERReader(byte[] b) { resetInput(b); } public SimpleDERReader(byte[] b, int off, int len) { resetInput(b, off, len); } public void resetInput(byte[] b) { resetInput(b, 0, b.length); } public void resetInput(byte[] b, int off, int len) { buffer = b; pos = off; count = len; } private byte readByte() throws IOException { if (count <= 0) throw new IOException("DER byte array: out of data"); count--; return buffer[pos++]; } public byte[] readBytes(int len) throws IOException { if (len > count) throw new IOException("DER byte array: out of data"); byte[] b = new byte[len]; System.arraycopy(buffer, pos, b, 0, len); pos += len; count -= len; return b; } public int available() { return count; } private int readLength() throws IOException { int len = readByte() & 0xff; if ((len & 0x80) == 0) return len; int remain = len & 0x7F; if (remain == 0) return -1; len = 0; while (remain > 0) { len = len << 8; len = len | (readByte() & 0xff); remain--; } return len; } public int ignoreNextObject() throws IOException { int type = readByte() & 0xff; int len = readLength(); if ((len < 0) || len > available()) throw new IOException("Illegal len in DER object (" + len + ")"); readBytes(len); return type; } public byte[] readIntAsByte() throws IOException { int type = readByte() & 0xff; if (type != 0x02) throw new IOException("Expected DER Integer, but found type " + type); int len = readLength(); if ((len < 0) || len > available()) throw new IOException("Illegal len in DER object (" + len + ")"); return readBytes(len); } public CryptoInteger readCryptoInt() throws IOException { byte[] b = readIntAsByte(); // remove leading 0s. int x = 0; while (x < b.length && b[x] == 0) { x++; } if (x == b.length) { return new CryptoInteger(0); } return new CryptoInteger(b, x, b.length - x); } public BigInteger readInt() throws IOException { int type = readByte() & 0xff; if (type != 0x02) throw new IOException("Expected DER Integer, but found type " + type); int len = readLength(); if ((len < 0) || len > available()) throw new IOException("Illegal len in DER object (" + len + ")"); byte[] b = readBytes(len); BigInteger bi = new BigInteger(b); return bi; } public byte[] readSequenceAsByteArray() throws IOException { int type = readByte() & 0xff; if (type != 0x30) throw new IOException("Expected DER Sequence, but found type " + type); int len = readLength(); if ((len < 0) || len > available()) throw new IOException("Illegal len in DER object (" + len + ")"); byte[] b = readBytes(len); return b; } public byte[] readOctetString() throws IOException { int type = readByte() & 0xff; if (type != 0x04) throw new IOException("Expected DER Octetstring, but found type " + type); int len = readLength(); if ((len < 0) || len > available()) throw new IOException("Illegal len in DER object (" + len + ")"); byte[] b = readBytes(len); return b; } }