001: package org.bouncycastle.crypto.tls;
002:
003: import org.bouncycastle.crypto.Digest;
004: import org.bouncycastle.crypto.digests.MD5Digest;
005: import org.bouncycastle.crypto.digests.SHA1Digest;
006: import org.bouncycastle.crypto.macs.HMac;
007: import org.bouncycastle.crypto.params.KeyParameter;
008:
009: import java.io.EOFException;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.io.OutputStream;
013:
014: /**
015: * Some helper fuctions for MicroTLS.
016: */
017: public class TlsUtils {
018: static byte[] toByteArray(String str) {
019: char[] chars = str.toCharArray();
020: byte[] bytes = new byte[chars.length];
021:
022: for (int i = 0; i != bytes.length; i++) {
023: bytes[i] = (byte) chars[i];
024: }
025:
026: return bytes;
027: }
028:
029: protected static void writeUint8(short i, OutputStream os)
030: throws IOException {
031: os.write(i);
032: }
033:
034: protected static void writeUint8(short i, byte[] buf, int offset) {
035: buf[offset] = (byte) i;
036: }
037:
038: protected static void writeUint16(int i, OutputStream os)
039: throws IOException {
040: os.write(i >> 8);
041: os.write(i);
042: }
043:
044: protected static void writeUint16(int i, byte[] buf, int offset) {
045: buf[offset] = (byte) (i >> 8);
046: buf[offset + 1] = (byte) i;
047: }
048:
049: protected static void writeUint24(int i, OutputStream os)
050: throws IOException {
051: os.write(i >> 16);
052: os.write(i >> 8);
053: os.write(i);
054: }
055:
056: protected static void writeUint24(int i, byte[] buf, int offset) {
057: buf[offset] = (byte) (i >> 16);
058: buf[offset + 1] = (byte) (i >> 8);
059: buf[offset + 2] = (byte) (i);
060: }
061:
062: protected static void writeUint32(long i, OutputStream os)
063: throws IOException {
064: os.write((int) (i >> 24));
065: os.write((int) (i >> 16));
066: os.write((int) (i >> 8));
067: os.write((int) (i));
068: }
069:
070: protected static void writeUint32(long i, byte[] buf, int offset) {
071: buf[offset] = (byte) (i >> 24);
072: buf[offset + 1] = (byte) (i >> 16);
073: buf[offset + 2] = (byte) (i >> 8);
074: buf[offset + 3] = (byte) (i);
075: }
076:
077: protected static void writeUint64(long i, OutputStream os)
078: throws IOException {
079: os.write((int) (i >> 56));
080: os.write((int) (i >> 48));
081: os.write((int) (i >> 40));
082: os.write((int) (i >> 32));
083: os.write((int) (i >> 24));
084: os.write((int) (i >> 16));
085: os.write((int) (i >> 8));
086: os.write((int) (i));
087: }
088:
089: protected static void writeUint64(long i, byte[] buf, int offset) {
090: buf[offset] = (byte) (i >> 56);
091: buf[offset + 1] = (byte) (i >> 48);
092: buf[offset + 2] = (byte) (i >> 40);
093: buf[offset + 3] = (byte) (i >> 32);
094: buf[offset + 4] = (byte) (i >> 24);
095: buf[offset + 5] = (byte) (i >> 16);
096: buf[offset + 6] = (byte) (i >> 8);
097: buf[offset + 7] = (byte) (i);
098: }
099:
100: protected static short readUint8(InputStream is) throws IOException {
101: int i = is.read();
102: if (i == -1) {
103: throw new EOFException();
104: }
105: return (short) i;
106: }
107:
108: protected static int readUint16(InputStream is) throws IOException {
109: int i1 = is.read();
110: int i2 = is.read();
111: if ((i1 | i2) < 0) {
112: throw new EOFException();
113: }
114: return i1 << 8 | i2;
115: }
116:
117: protected static int readUint24(InputStream is) throws IOException {
118: int i1 = is.read();
119: int i2 = is.read();
120: int i3 = is.read();
121: if ((i1 | i2 | i3) < 0) {
122: throw new EOFException();
123: }
124: return (i1 << 16) | (i2 << 8) | i3;
125: }
126:
127: protected static long readUint32(InputStream is) throws IOException {
128: int i1 = is.read();
129: int i2 = is.read();
130: int i3 = is.read();
131: int i4 = is.read();
132: if ((i1 | i2 | i3 | i4) < 0) {
133: throw new EOFException();
134: }
135: return (((long) i1) << 24) | (((long) i2) << 16)
136: | (((long) i3) << 8) | ((long) i4);
137: }
138:
139: protected static void readFully(byte[] buf, InputStream is)
140: throws IOException {
141: int read = 0;
142: int i = 0;
143: do {
144: i = is.read(buf, read, (buf.length - read));
145: if (i == -1) {
146: throw new EOFException();
147: }
148: read += i;
149: } while (read != buf.length);
150: }
151:
152: protected static void checkVersion(byte[] readVersion,
153: TlsProtocolHandler handler) throws IOException {
154: if ((readVersion[0] != 3) || (readVersion[1] != 1)) {
155: handler.failWithError(TlsProtocolHandler.AL_fatal,
156: TlsProtocolHandler.AP_protocol_version);
157: }
158: }
159:
160: protected static void checkVersion(InputStream is,
161: TlsProtocolHandler handler) throws IOException {
162: int i1 = is.read();
163: int i2 = is.read();
164: if ((i1 != 3) || (i2 != 1)) {
165: handler.failWithError(TlsProtocolHandler.AL_fatal,
166: TlsProtocolHandler.AP_protocol_version);
167: }
168: }
169:
170: protected static void writeVersion(OutputStream os)
171: throws IOException {
172: os.write(3);
173: os.write(1);
174: }
175:
176: private static void hmac_hash(Digest digest, byte[] secret,
177: byte[] seed, byte[] out) {
178: HMac mac = new HMac(digest);
179: KeyParameter param = new KeyParameter(secret);
180: byte[] a = seed;
181: int size = digest.getDigestSize();
182: int iterations = (out.length + size - 1) / size;
183: byte[] buf = new byte[mac.getMacSize()];
184: byte[] buf2 = new byte[mac.getMacSize()];
185: for (int i = 0; i < iterations; i++) {
186: mac.init(param);
187: mac.update(a, 0, a.length);
188: mac.doFinal(buf, 0);
189: a = buf;
190: mac.init(param);
191: mac.update(a, 0, a.length);
192: mac.update(seed, 0, seed.length);
193: mac.doFinal(buf2, 0);
194: System.arraycopy(buf2, 0, out, (size * i), Math.min(size,
195: out.length - (size * i)));
196: }
197: }
198:
199: protected static void PRF(byte[] secret, byte[] label, byte[] seed,
200: byte[] buf) {
201: int s_half = (secret.length + 1) / 2;
202: byte[] s1 = new byte[s_half];
203: byte[] s2 = new byte[s_half];
204: System.arraycopy(secret, 0, s1, 0, s_half);
205: System.arraycopy(secret, secret.length - s_half, s2, 0, s_half);
206:
207: byte[] ls = new byte[label.length + seed.length];
208: System.arraycopy(label, 0, ls, 0, label.length);
209: System.arraycopy(seed, 0, ls, label.length, seed.length);
210:
211: byte[] prf = new byte[buf.length];
212: hmac_hash(new MD5Digest(), s1, ls, prf);
213: hmac_hash(new SHA1Digest(), s2, ls, buf);
214: for (int i = 0; i < buf.length; i++) {
215: buf[i] ^= prf[i];
216: }
217: }
218:
219: }
|