001: package org.bouncycastle.bcpg;
002:
003: import org.bouncycastle.bcpg.sig.Exportable;
004: import org.bouncycastle.bcpg.sig.IssuerKeyID;
005: import org.bouncycastle.bcpg.sig.KeyExpirationTime;
006: import org.bouncycastle.bcpg.sig.KeyFlags;
007: import org.bouncycastle.bcpg.sig.NotationData;
008: import org.bouncycastle.bcpg.sig.PreferredAlgorithms;
009: import org.bouncycastle.bcpg.sig.PrimaryUserID;
010: import org.bouncycastle.bcpg.sig.Revocable;
011: import org.bouncycastle.bcpg.sig.SignatureCreationTime;
012: import org.bouncycastle.bcpg.sig.SignatureExpirationTime;
013: import org.bouncycastle.bcpg.sig.SignerUserID;
014: import org.bouncycastle.bcpg.sig.TrustSignature;
015:
016: import java.io.EOFException;
017: import java.io.IOException;
018: import java.io.InputStream;
019:
020: /**
021: * reader for signature sub-packets
022: */
023: public class SignatureSubpacketInputStream extends InputStream
024: implements SignatureSubpacketTags {
025: InputStream in;
026:
027: public SignatureSubpacketInputStream(InputStream in) {
028: this .in = in;
029: }
030:
031: public int available() throws IOException {
032: return in.available();
033: }
034:
035: public int read() throws IOException {
036: return in.read();
037: }
038:
039: private void readFully(byte[] buf, int off, int len)
040: throws IOException {
041: if (len > 0) {
042: int b = this .read();
043:
044: if (b < 0) {
045: throw new EOFException();
046: }
047:
048: buf[off] = (byte) b;
049: off++;
050: len--;
051: }
052:
053: while (len > 0) {
054: int l = in.read(buf, off, len);
055:
056: if (l < 0) {
057: throw new EOFException();
058: }
059:
060: off += l;
061: len -= l;
062: }
063: }
064:
065: public SignatureSubpacket readPacket() throws IOException {
066: int l = this .read();
067: int bodyLen = 0;
068:
069: if (l < 0) {
070: return null;
071: }
072:
073: if (l < 192) {
074: bodyLen = l;
075: } else if (l < 223) {
076: bodyLen = ((l - 192) << 8) + (in.read()) + 192;
077: } else if (l == 255) {
078: bodyLen = (in.read() << 24) | (in.read() << 16)
079: | (in.read() << 8) | in.read();
080: }
081:
082: int tag = in.read();
083:
084: if (tag < 0) {
085: throw new EOFException(
086: "unexpected EOF reading signature sub packet");
087: }
088:
089: byte[] data = new byte[bodyLen - 1];
090:
091: this .readFully(data, 0, data.length);
092:
093: boolean isCritical = ((tag & 0x80) != 0);
094: int type = tag & 0x7f;
095:
096: switch (type) {
097: case CREATION_TIME:
098: return new SignatureCreationTime(isCritical, data);
099: case KEY_EXPIRE_TIME:
100: return new KeyExpirationTime(isCritical, data);
101: case EXPIRE_TIME:
102: return new SignatureExpirationTime(isCritical, data);
103: case REVOCABLE:
104: return new Revocable(isCritical, data);
105: case EXPORTABLE:
106: return new Exportable(isCritical, data);
107: case ISSUER_KEY_ID:
108: return new IssuerKeyID(isCritical, data);
109: case TRUST_SIG:
110: return new TrustSignature(isCritical, data);
111: case PREFERRED_COMP_ALGS:
112: case PREFERRED_HASH_ALGS:
113: case PREFERRED_SYM_ALGS:
114: return new PreferredAlgorithms(type, isCritical, data);
115: case KEY_FLAGS:
116: return new KeyFlags(isCritical, data);
117: case PRIMARY_USER_ID:
118: return new PrimaryUserID(isCritical, data);
119: case SIGNER_USER_ID:
120: return new SignerUserID(isCritical, data);
121: case NOTATION_DATA:
122: return new NotationData(isCritical, data);
123: }
124:
125: return new SignatureSubpacket(type, isCritical, data);
126: }
127: }
|