1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53:
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59:
60:
64: public class IncomingMessage
65: {
66:
67: protected ByteArrayInputStream in;
68:
69: protected int length;
70:
71:
79: public IncomingMessage(byte[] b) throws KeyAgreementException
80: {
81: this();
82:
83: if (b.length < 4)
84: throw new KeyAgreementException("message header too short");
85: length = b[0] << 24
86: | (b[1] & 0xFF) << 16
87: | (b[2] & 0xFF) << 8
88: | (b[3] & 0xFF);
89: if (length > Registry.SASL_BUFFER_MAX_LIMIT || length < 0)
90: throw new KeyAgreementException("message size limit exceeded");
91: in = new ByteArrayInputStream(b, 4, length);
92: }
93:
94:
95: private IncomingMessage()
96: {
97: super();
98: }
99:
100:
110: public static IncomingMessage getInstance(byte[] raw)
111: {
112: return getInstance(raw, 0, raw.length);
113: }
114:
115:
124: public static IncomingMessage getInstance(byte[] raw, int offset, int len)
125: {
126: IncomingMessage result = new IncomingMessage();
127: result.in = new ByteArrayInputStream(raw, offset, len);
128: return result;
129: }
130:
131:
137: public static int twoBytesToLength(byte[] b) throws KeyAgreementException
138: {
139: int result = (b[0] & 0xFF) << 8 | (b[1] & 0xFF);
140: if (result > Registry.SASL_TWO_BYTE_MAX_LIMIT)
141: throw new KeyAgreementException("encoded MPI size limit exceeded");
142: return result;
143: }
144:
145:
151: public static int fourBytesToLength(byte[] b) throws KeyAgreementException
152: {
153: int result = b[0] << 24
154: | (b[1] & 0xFF) << 16
155: | (b[2] & 0xFF) << 8
156: | (b[3] & 0xFF);
157: if (result > Registry.SASL_FOUR_BYTE_MAX_LIMIT || result < 0)
158: throw new KeyAgreementException("encoded entity size limit exceeded");
159: return result;
160: }
161:
162: public boolean hasMoreElements()
163: {
164: return (in.available() > 0);
165: }
166:
167:
176: public PublicKey readPublicKey() throws KeyAgreementException
177: {
178: if (in.available() < 5)
179: throw new KeyAgreementException("not enough bytes for a public key in message");
180: byte[] elementLengthBytes = new byte[4];
181: in.read(elementLengthBytes, 0, 4);
182: int elementLength = fourBytesToLength(elementLengthBytes);
183: if (in.available() < elementLength)
184: throw new KeyAgreementException("illegal public key encoding");
185: int keyTypeAndFormatID = in.read() & 0xFF;
186: elementLength--;
187: byte[] kb = new byte[elementLength];
188: in.read(kb, 0, elementLength);
189:
190: IKeyPairCodec kpc = getKeyPairCodec(keyTypeAndFormatID);
191: return kpc.decodePublicKey(kb);
192: }
193:
194:
203: public PrivateKey readPrivateKey() throws KeyAgreementException
204: {
205: if (in.available() < 5)
206: throw new KeyAgreementException("not enough bytes for a private key in message");
207: byte[] elementLengthBytes = new byte[4];
208: in.read(elementLengthBytes, 0, 4);
209: int elementLength = fourBytesToLength(elementLengthBytes);
210: if (in.available() < elementLength)
211: throw new KeyAgreementException("illegal private key encoding");
212: int keyTypeAndFormatID = in.read() & 0xFF;
213: elementLength--;
214: byte[] kb = new byte[elementLength];
215: in.read(kb, 0, elementLength);
216:
217: IKeyPairCodec kpc = getKeyPairCodec(keyTypeAndFormatID);
218: return kpc.decodePrivateKey(kb);
219: }
220:
221:
228: public BigInteger readMPI() throws KeyAgreementException
229: {
230: if (in.available() < 2)
231: throw new KeyAgreementException("not enough bytes for an MPI in message");
232: byte[] elementLengthBytes = new byte[2];
233: in.read(elementLengthBytes, 0, 2);
234: int elementLength = twoBytesToLength(elementLengthBytes);
235: if (in.available() < elementLength)
236: throw new KeyAgreementException("illegal MPI encoding");
237: byte[] element = new byte[elementLength];
238: in.read(element, 0, element.length);
239: return new BigInteger(1, element);
240: }
241:
242: public String readString() throws KeyAgreementException
243: {
244: if (in.available() < 2)
245: throw new KeyAgreementException("not enough bytes for a text in message");
246: byte[] elementLengthBytes = new byte[2];
247: in.read(elementLengthBytes, 0, 2);
248: int elementLength = twoBytesToLength(elementLengthBytes);
249: if (in.available() < elementLength)
250: throw new KeyAgreementException("illegal text encoding");
251: byte[] element = new byte[elementLength];
252: in.read(element, 0, element.length);
253: String result = null;
254: try
255: {
256: result = new String(element, "UTF8");
257: }
258: catch (UnsupportedEncodingException x)
259: {
260: throw new KeyAgreementException("unxupported UTF8 encoding", x);
261: }
262: return result;
263: }
264:
265: private IKeyPairCodec getKeyPairCodec(int keyTypeAndFormatID)
266: throws KeyAgreementException
267: {
268: int keyType = (keyTypeAndFormatID >>> 4) & 0x0F;
269: int formatID = keyTypeAndFormatID & 0x0F;
270: switch (formatID)
271: {
272: case Registry.RAW_ENCODING_ID:
273: switch (keyType)
274: {
275: case 0:
276: return new DSSKeyPairRawCodec();
277: case 1:
278: return new RSAKeyPairRawCodec();
279: case 2:
280: return new DHKeyPairRawCodec();
281: case 3:
282: return new SRPKeyPairRawCodec();
283: default:
284: throw new KeyAgreementException("Unknown key-type for Raw format: "
285: + keyType);
286: }
287: case Registry.X509_ENCODING_ID:
288: switch (keyType)
289: {
290: case 0:
291: return new DSSKeyPairX509Codec();
292: case 1:
293: return new RSAKeyPairX509Codec();
294: case 2:
295: return new DHKeyPairX509Codec();
296: default:
297: throw new KeyAgreementException("Unknown key-type for X.509 format: "
298: + keyType);
299: }
300: case Registry.PKCS8_ENCODING_ID:
301: switch (keyType)
302: {
303: case 0:
304: return new DSSKeyPairPKCS8Codec();
305: case 1:
306: return new RSAKeyPairPKCS8Codec();
307: case 2:
308: return new DHKeyPairPKCS8Codec();
309: default:
310: throw new KeyAgreementException("Unknown key-type for PKCS#8 format: "
311: + keyType);
312: }
313: default:
314: throw new KeyAgreementException("Unknown format identifier: "
315: + formatID);
316: }
317: }
318: }