[e-cvs] cvs commit: e/src/jsrc/org/capml/dom Node.java
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Sat, 25 Aug 2001 15:54:02 -0400
markm 01/08/25 15:54:02
Modified: src Makefile
src/jsrc/net/vattp/data DES.java Decrypt3DES.java
Encrypt3DES.java RecvThread.java SendThread.java
StartUpProtocol.java TripleDESKeyConstructor.java
src/jsrc/net/vattp/security ESecureRandom.java
TimerJitterEntropy.java
src/jsrc/net/vattp/vls VatLocationServer.java
src/jsrc/org/capml/dom Node.java
Log:
integrated Bill's VatTP changes
Revision Changes Path
1.109 +2 -2 e/src/Makefile
Index: Makefile
===================================================================
RCS file: /cvs/e/src/Makefile,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -r1.108 -r1.109
--- Makefile 2001/08/24 22:03:06 1.108
+++ Makefile 2001/08/25 19:54:01 1.109
@@ -7,8 +7,8 @@
# Prefix tagging this release's attributes
PREFIX=tl-E
-DOTVER=0.8.9zd
-TAGVER=0_8_9zd
+DOTVER=0.8.9ze
+TAGVER=0_8_9ze
RELEASE=working
TOP=..
1.4 +317 -313 e/src/jsrc/net/vattp/data/DES.java
Index: DES.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/DES.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DES.java 2001/07/14 12:57:21 1.3
+++ DES.java 2001/08/25 19:54:01 1.4
@@ -1,7 +1,10 @@
package net.vattp.data;
-// $Id: DES.java,v 1.3 2001/07/14 12:57:21 markm Exp $
+// $Id: DES.java,v 1.4 2001/08/25 19:54:01 markm Exp $
//
// $Log: DES.java,v $
+// Revision 1.4 2001/08/25 19:54:01 markm
+// integrated Bill's VatTP changes
+//
// Revision 1.3 2001/07/14 12:57:21 markm
// updoc seems to work
//
@@ -127,7 +130,7 @@
* <a href="http://www.systemics.com/docs/cryptix/">Cryptix Development Team</a>.
* <br>All rights reserved.
*
- * <p><b>$Revision: 1.3 $</b>
+ * <p><b>$Revision: 1.4 $</b>
* @author Systemics Ltd
* @author Geoffrey Keating (this Java implementation)
* @author Eric Young
@@ -138,59 +141,59 @@
*/
public final class DES // must be final for security reasons
{
-
- // Debugging methods and vars.
- //...........................................................................
-
- private static final boolean DEBUG = true;
- private static final int debuglevel = DEBUG ? 1 : 0;
-
-
- // Native library linking methods and vars.
- //...........................................................................
-
-
- // DES constants and variables
- //...........................................................................
-
- private static final int
+
+// Debugging methods and vars.
+//...........................................................................
+
+ static private final boolean DEBUG = true;
+ static private final int debuglevel = DEBUG ? 1 : 0;
+
+
+// Native library linking methods and vars.
+//...........................................................................
+
+
+// DES constants and variables
+//...........................................................................
+
+ static private final int
ROUNDS = 16, // number of encryption/decryption rounds
BLOCK_SIZE = 8, // DES block size in bytes
KEY_LENGTH = 8, // DES key length in bytes
INTERNAL_KEY_LENGTH = ROUNDS * 2; // number of elements in key schedule
-
+
/**
* State for encrypt/decrypt/uninitialized.
*/
private int encryptDecryptState = UNINITIALIZED;
- private static final int UNINITIALIZED = 0;
- private static final int ENCRYPT = 1;
- private static final int DECRYPT = 2;
-
+ static private final int UNINITIALIZED = 0;
+ static private final int ENCRYPT = 1;
+ static private final int DECRYPT = 2;
+
/**
* Table for PC2 permutations in key schedule computation.
*/
- private static final int[] SKB = new int[8 * 64]; // blank final
-
+ static private final int[] SKB = new int[8 * 64]; // blank final
+
/**
* The internal key schedule.
*/
private int[] sKey = new int[INTERNAL_KEY_LENGTH];
-
+
/**
* Table for S-boxes and permutations, used in encrypt_base.
*/
- private static final int SP_TRANS[] = new int[8 * 64]; // blank final
-
-
- // Static code
- //...........................................................................
-
+ static private final int SP_TRANS[] = new int[8 * 64]; // blank final
+
+
+// Static code
+//...........................................................................
+
static {
//
// build the SKB table
//
-
+
// represent the bit number that each permutated bit is derived from
// according to FIPS-46
String cd =
@@ -210,13 +213,13 @@
}
}
}
-
+
//
// build the SP_TRANS table
//
-
+
// I'd _really_ like to just say 'SP_TRANS = { ... }', but
- // that would be terribly inefficient (code size + time).
+ // that would be terribly inefficient (code size + time).
// Instead we use a compressed representation --GK
String spt =
"g3H821:80:H03BA0@N1290BAA88::3112aIH8:8282@0@AH0:1W3A8P810@22;22"+
@@ -228,7 +231,7 @@
"001@11<8;@82B01P0a2989B:0AY0912889bD0A1@B1A0A0AB033O91182440A9P8"+
"@I80n@1I03@1J828212A`A8:12B1@19A9@9@8^B:0@H00<82AB030bB840821Q:8"+
"310A302102::A1::20A1;8"; // OK, try to type _that_!
- // [526 chars, 3156 bits]
+ // [526 chars, 3156 bits]
// The theory is that each bit position in each int of SP_TRANS is
// set in exactly 32 entries. We keep track of set bits.
offset = 0;
@@ -271,17 +274,17 @@
}
}
}
-
-
- // Constructor, finalizer, and clone()
- //...........................................................................
-
+
+
+// Constructor, finalizer, and clone()
+//...........................................................................
+
/**
* Constructs a DES cipher object, in the UNINITIALIZED state.
*/
public DES() {
}
-
+
/**
* Always throws a CloneNotSupportedException (cloning of ciphers is not
* supported for security reasons).
@@ -289,18 +292,18 @@
public final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
-
-
- // Implementation of JCE methods
- //...........................................................................
-
+
+
+// Implementation of JCE methods
+//...........................................................................
+
/**
* <b>SPI</b>: Returns the length of an input block, in bytes.
*
* @return the length in bytes of an input block for this cipher.
*/
public int blockSize() { return BLOCK_SIZE; }
-
+
/**
* <b>SPI</b>: Initializes this cipher for encryption, using the
* specified key.
@@ -312,11 +315,11 @@
* </ul>
*/
public void initEncrypt (byte[] key)
- throws InvalidKeyException {
+ throws InvalidKeyException {
makeKey(key);
encryptDecryptState = ENCRYPT;
}
-
+
/**
* <b>SPI</b>: Initializes this cipher for decryption, using the
* specified key.
@@ -328,20 +331,20 @@
* </ul>
*/
public void initDecrypt (byte[] key)
- throws InvalidKeyException {
+ throws InvalidKeyException {
makeKey(key);
encryptDecryptState = DECRYPT;
}
-
+
public byte[] crypt(byte[] data) {
if (data.length != BLOCK_SIZE) {
throw new IllegalArgumentException("data.length != BLOCK_SIZE");
- }
- byte [] ans = new byte[BLOCK_SIZE];
- update(data, 0, BLOCK_SIZE, ans, 0);
- return ans;
+ }
+ byte [] ans = new byte[BLOCK_SIZE];
+ update(data, 0, BLOCK_SIZE, ans, 0);
+ return ans;
}
-
+
/**
* <b>SPI</b>: This is the main method for updating data.
* <p>
@@ -360,9 +363,9 @@
if (inLen < 0) throw new IllegalArgumentException("inLen < 0");
int blockCount = inLen / BLOCK_SIZE;
inLen = blockCount * BLOCK_SIZE;
-
+
boolean doEncrypt = (encryptDecryptState == ENCRYPT);
-
+
// Avoid overlapping input and output regions.
if (in == out && (outOffset >= inOffset && outOffset < (long)inOffset+inLen ||
inOffset >= outOffset && inOffset < (long)outOffset+inLen)) {
@@ -371,7 +374,7 @@
in = newin;
inOffset = 0;
}
-
+
for (int i = 0; i < blockCount; i++) {
des(in, inOffset, out, outOffset, doEncrypt);
inOffset += BLOCK_SIZE;
@@ -379,11 +382,11 @@
}
return inLen;
}
-
-
- // Own methods
- //...........................................................................
-
+
+
+// Own methods
+//...........................................................................
+
/**
* Expands a user-key to a working key schedule.
*
@@ -394,31 +397,31 @@
* </ul>
*/
private void makeKey (byte[] userkey)
- throws InvalidKeyException {
-
+ throws InvalidKeyException {
+
if (userkey == null)
throw new InvalidKeyException(getAlgorithm() + ": Null user key");
-
+
if (userkey.length != KEY_LENGTH)
throw new InvalidKeyException(getAlgorithm() + ": Invalid user key length");
-
+
int i = 0;
int c = (userkey[i++] & 0xFF) |
- (userkey[i++] & 0xFF) << 8 |
- (userkey[i++] & 0xFF) << 16 |
- (userkey[i++] & 0xFF) << 24;
+ (userkey[i++] & 0xFF) << 8 |
+ (userkey[i++] & 0xFF) << 16 |
+ (userkey[i++] & 0xFF) << 24;
int d = (userkey[i++] & 0xFF) |
- (userkey[i++] & 0xFF) << 8 |
- (userkey[i++] & 0xFF) << 16 |
- (userkey[i++] & 0xFF) << 24;
-
+ (userkey[i++] & 0xFF) << 8 |
+ (userkey[i++] & 0xFF) << 16 |
+ (userkey[i++] & 0xFF) << 24;
+
int t = ((d >>> 4) ^ c) & 0x0F0F0F0F;
c ^= t;
d ^= t << 4;
t = ((c << 18) ^ c) & 0xCCCC0000;
- c ^= t ^ t >>> 18;
+ c ^= t ^ t >>> 18;
t = ((d << 18) ^ d) & 0xCCCC0000;
- d ^= t ^ t >>> 18;
+ d ^= t ^ t >>> 18;
t = ((d >>> 1) ^ c) & 0x55555555;
c ^= t;
d ^= t << 1;
@@ -428,16 +431,16 @@
t = ((d >>> 1) ^ c) & 0x55555555;
c ^= t;
d ^= t << 1;
-
+
d = (d & 0x000000FF) << 16 |
(d & 0x0000FF00) |
(d & 0x00FF0000) >>> 16 |
(c & 0xF0000000) >>> 4;
c &= 0x0FFFFFFF;
-
+
int s;
int j = 0;
-
+
for (i = 0; i < ROUNDS; i++) {
if ((0x7EFC >> i & 1) == 1) {
c = (c >>> 2 | c << 26) & 0x0FFFFFFF;
@@ -450,18 +453,18 @@
SKB[0x040 | (((c >>> 6) & 0x03) | ((c >>> 7) & 0x3C))] |
SKB[0x080 | (((c >>> 13) & 0x0F) | ((c >>> 14) & 0x30))] |
SKB[0x0C0 | (((c >>> 20) & 0x01) | ((c >>> 21) & 0x06)
- | ((c >>> 22) & 0x38))];
+ | ((c >>> 22) & 0x38))];
t = SKB[0x100 | ( d & 0x3F )] |
SKB[0x140 | (((d >>> 7) & 0x03) | ((d >>> 8) & 0x3c))] |
SKB[0x180 | ((d >>> 15) & 0x3F )] |
SKB[0x1C0 | (((d >>> 21) & 0x0F) | ((d >>> 22) & 0x30))];
-
+
sKey[j++] = t << 16 | (s & 0x0000FFFF);
s = s >>> 16 | (t & 0xFFFF0000);
sKey[j++] = s << 4 | s >>> 28;
}
}
-
+
/**
* Encrypts/decrypts a block, of length BLOCK_SIZE.
*
@@ -472,7 +475,7 @@
* @param encrypt true to encrypt, false to decrypt
*/
private void
- des (byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
+ des (byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
int[] lr = {
(in[inOffset++] & 0xFF) |
(in[inOffset++] & 0xFF) << 8 |
@@ -482,20 +485,20 @@
(in[inOffset++] & 0xFF) << 8 |
(in[inOffset++] & 0xFF) << 16 |
(in[inOffset ] & 0xFF) << 24};
-
+
initialPermutation(lr);
-
+
// do it!
if (encrypt)
encrypt_base(lr);
else
decrypt_base(lr);
-
+
finalPermutation(lr);
-
+
int R = lr[0];
int L = lr[1];
-
+
out[outOffset++] = (byte) L;
out[outOffset++] = (byte)(L >> 8);
out[outOffset++] = (byte)(L >> 16);
@@ -505,19 +508,19 @@
out[outOffset++] = (byte)(R >> 16);
out[outOffset ] = (byte)(R >> 24);
}
-
+
/** Implements DES encryption without IP and FP. */
private void encrypt_base (int[] io) {
int L = io[0];
int R = io[1];
-
+
// look! we fit all four variables (plus the class itself)
// into short byte-codes!
int u = R << 1 | R >>> 31;
R = L << 1 | L >>> 31;
L = u;
int t;
-
+
for (int i = 0; i < INTERNAL_KEY_LENGTH;) {
u = R ^ sKey[i++];
t = R ^ sKey[i++];
@@ -530,7 +533,7 @@
SP_TRANS[0x080 | ((u >>> 8) & 0x3F)] |
SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] |
SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
-
+
u = L ^ sKey[i++];
t = L ^ sKey[i++];
t = t >>> 4 | t << 28;
@@ -546,19 +549,19 @@
io[0] = R >>> 1 | R << 31;
io[1] = L >>> 1 | L << 31;
}
-
+
/** Implements DES decryption without IP and FP. */
private void decrypt_base (int[] io) {
int L = io[0];
int R = io[1];
-
+
// look! we fit all four variables (plus the class itself)
// into short byte-codes!
int u = R << 1 | R >>> 31;
R = L << 1 | L >>> 31;
L = u;
int t;
-
+
for (int i = INTERNAL_KEY_LENGTH - 1; i > 0;) {
t = R ^ sKey[i--];
u = R ^ sKey[i--];
@@ -571,7 +574,7 @@
SP_TRANS[0x080 | ((u >>> 8) & 0x3F)] |
SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] |
SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
-
+
t = L ^ sKey[i--];
u = L ^ sKey[i--];
t = t >>> 4 | t << 28;
@@ -587,8 +590,8 @@
io[0] = R >>> 1 | R << 31;
io[1] = L >>> 1 | L << 31;
}
-
- private static void initialPermutation (int[] io) {
+
+ static private void initialPermutation (int[] io) {
int L = io[0];
int R = io[1];
int t = ((R >>> 4) ^ L) & 0x0F0F0F0F;
@@ -607,8 +610,8 @@
io[0] = L ^ t;
io[1] = R ^ (t << 1);
}
-
- private static void finalPermutation (int[] io) {
+
+ static private void finalPermutation (int[] io) {
int L = io[1];
int R = io[0];
int t = (R >>> 1 ^ L) & 0x55555555;
@@ -627,244 +630,244 @@
io[1] = L ^ t;
io[0] = R ^ (t << 4);
}
-
- private static String getAlgorithm() { return "DES"; }
-
- // Test methods
- //...........................................................................
-
+
+ static private String getAlgorithm() { return "DES"; }
+
+// Test methods
+//...........................................................................
+
/** Entry point for <code>self_test</code>. */
- public static void main(String[] argv) {
+ static public void main(String[] argv) {
try {
self_test();
// time_test(System.out, "1c587f1c13924fef", "305532286d6f295a", "63fac0d034d9f793");
} catch (Exception e) { e.printStackTrace(); }
}
-
- private static final String[][] tests =
+
+ static private final String[][] tests =
{// KEY PLAINTEXT CIPHERTEXT
{"0101010101010101", "95f8a5e5dd31d900", "8000000000000000"},
{"0101010101010101", "dd7f121ca5015619", "4000000000000000"},
{"0101010101010101", "2e8653104f3834ea", "2000000000000000"},
- /*
- {"0101010101010101", "4bd388ff6cd81d4f", "1000000000000000"},
- {"0101010101010101", "20b9e767b2fb1456", "0800000000000000"},
- {"0101010101010101", "55579380d77138ef", "0400000000000000"},
- {"0101010101010101", "6cc5defaaf04512f", "0200000000000000"},
- {"0101010101010101", "0d9f279ba5d87260", "0100000000000000"},
- {"0101010101010101", "d9031b0271bd5a0a", "0080000000000000"},
- {"0101010101010101", "424250b37c3dd951", "0040000000000000"},
- {"0101010101010101", "b8061b7ecd9a21e5", "0020000000000000"},
- {"0101010101010101", "f15d0f286b65bd28", "0010000000000000"},
- {"0101010101010101", "add0cc8d6e5deba1", "0008000000000000"},
- {"0101010101010101", "e6d5f82752ad63d1", "0004000000000000"},
- {"0101010101010101", "ecbfe3bd3f591a5e", "0002000000000000"},
- {"0101010101010101", "f356834379d165cd", "0001000000000000"},
- {"0101010101010101", "2b9f982f20037fa9", "0000800000000000"},
- {"0101010101010101", "889de068a16f0be6", "0000400000000000"},
- {"0101010101010101", "e19e275d846a1298", "0000200000000000"},
- {"0101010101010101", "329a8ed523d71aec", "0000100000000000"},
- {"0101010101010101", "e7fce22557d23c97", "0000080000000000"},
- {"0101010101010101", "12a9f5817ff2d65d", "0000040000000000"},
- {"0101010101010101", "a484c3ad38dc9c19", "0000020000000000"},
- {"0101010101010101", "fbe00a8a1ef8ad72", "0000010000000000"},
- {"0101010101010101", "750d079407521363", "0000008000000000"},
- {"0101010101010101", "64feed9c724c2faf", "0000004000000000"},
- {"0101010101010101", "f02b263b328e2b60", "0000002000000000"},
- {"0101010101010101", "9d64555a9a10b852", "0000001000000000"},
- {"0101010101010101", "d106ff0bed5255d7", "0000000800000000"},
- {"0101010101010101", "e1652c6b138c64a5", "0000000400000000"},
- {"0101010101010101", "e428581186ec8f46", "0000000200000000"},
- {"0101010101010101", "aeb5f5ede22d1a36", "0000000100000000"},
- {"0101010101010101", "e943d7568aec0c5c", "0000000080000000"},
- {"0101010101010101", "df98c8276f54b04b", "0000000040000000"},
- {"0101010101010101", "b160e4680f6c696f", "0000000020000000"},
- {"0101010101010101", "fa0752b07d9c4ab8", "0000000010000000"},
- {"0101010101010101", "ca3a2b036dbc8502", "0000000008000000"},
- {"0101010101010101", "5e0905517bb59bcf", "0000000004000000"},
- {"0101010101010101", "814eeb3b91d90726", "0000000002000000"},
- {"0101010101010101", "4d49db1532919c9f", "0000000001000000"},
- {"0101010101010101", "25eb5fc3f8cf0621", "0000000000800000"},
- {"0101010101010101", "ab6a20c0620d1c6f", "0000000000400000"},
- {"0101010101010101", "79e90dbc98f92cca", "0000000000200000"},
- {"0101010101010101", "866ecedd8072bb0e", "0000000000100000"},
- {"0101010101010101", "8b54536f2f3e64a8", "0000000000080000"},
- {"0101010101010101", "ea51d3975595b86b", "0000000000040000"},
- {"0101010101010101", "caffc6ac4542de31", "0000000000020000"},
- {"0101010101010101", "8dd45a2ddf90796c", "0000000000010000"},
- {"0101010101010101", "1029d55e880ec2d0", "0000000000008000"},
- {"0101010101010101", "5d86cb23639dbea9", "0000000000004000"},
- {"0101010101010101", "1d1ca853ae7c0c5f", "0000000000002000"},
- {"0101010101010101", "ce332329248f3228", "0000000000001000"},
- {"0101010101010101", "8405d1abe24fb942", "0000000000000800"},
- {"0101010101010101", "e643d78090ca4207", "0000000000000400"},
- {"0101010101010101", "48221b9937748a23", "0000000000000200"},
- {"0101010101010101", "dd7c0bbd61fafd54", "0000000000000100"},
- {"0101010101010101", "2fbc291a570db5c4", "0000000000000080"},
- {"0101010101010101", "e07c30d7e4e26e12", "0000000000000040"},
- {"0101010101010101", "0953e2258e8e90a1", "0000000000000020"},
- {"0101010101010101", "5b711bc4ceebf2ee", "0000000000000010"},
- {"0101010101010101", "cc083f1e6d9e85f6", "0000000000000008"},
- {"0101010101010101", "d2fd8867d50d2dfe", "0000000000000004"},
- {"0101010101010101", "06e7ea22ce92708f", "0000000000000002"},
- {"0101010101010101", "166b40b44aba4bd6", "0000000000000001"},
- {"8001010101010101", "0000000000000000", "95a8d72813daa94d"},
- {"4001010101010101", "0000000000000000", "0eec1487dd8c26d5"},
- {"2001010101010101", "0000000000000000", "7ad16ffb79c45926"},
- {"1001010101010101", "0000000000000000", "d3746294ca6a6cf3"},
- {"0801010101010101", "0000000000000000", "809f5f873c1fd761"},
- {"0401010101010101", "0000000000000000", "c02faffec989d1fc"},
- {"0201010101010101", "0000000000000000", "4615aa1d33e72f10"},
- {"0180010101010101", "0000000000000000", "2055123350c00858"},
- {"0140010101010101", "0000000000000000", "df3b99d6577397c8"},
- {"0120010101010101", "0000000000000000", "31fe17369b5288c9"},
- {"0110010101010101", "0000000000000000", "dfdd3cc64dae1642"},
- {"0108010101010101", "0000000000000000", "178c83ce2b399d94"},
- {"0104010101010101", "0000000000000000", "50f636324a9b7f80"},
- {"0102010101010101", "0000000000000000", "a8468ee3bc18f06d"},
- {"0101800101010101", "0000000000000000", "a2dc9e92fd3cde92"},
- {"0101400101010101", "0000000000000000", "cac09f797d031287"},
- {"0101200101010101", "0000000000000000", "90ba680b22aeb525"},
- {"0101100101010101", "0000000000000000", "ce7a24f350e280b6"},
- {"0101080101010101", "0000000000000000", "882bff0aa01a0b87"},
- {"0101040101010101", "0000000000000000", "25610288924511c2"},
- {"0101020101010101", "0000000000000000", "c71516c29c75d170"},
- {"0101018001010101", "0000000000000000", "5199c29a52c9f059"},
- {"0101014001010101", "0000000000000000", "c22f0a294a71f29f"},
- {"0101012001010101", "0000000000000000", "ee371483714c02ea"},
- {"0101011001010101", "0000000000000000", "a81fbd448f9e522f"},
- {"0101010801010101", "0000000000000000", "4f644c92e192dfed"},
- {"0101010401010101", "0000000000000000", "1afa9a66a6df92ae"},
- {"0101010201010101", "0000000000000000", "b3c1cc715cb879d8"},
- {"0101010180010101", "0000000000000000", "19d032e64ab0bd8b"},
- {"0101010140010101", "0000000000000000", "3cfaa7a7dc8720dc"},
- {"0101010120010101", "0000000000000000", "b7265f7f447ac6f3"},
- {"0101010110010101", "0000000000000000", "9db73b3c0d163f54"},
- {"0101010108010101", "0000000000000000", "8181b65babf4a975"},
- {"0101010104010101", "0000000000000000", "93c9b64042eaa240"},
- {"0101010102010101", "0000000000000000", "5570530829705592"},
- {"0101010101800101", "0000000000000000", "8638809e878787a0"},
- {"0101010101400101", "0000000000000000", "41b9a79af79ac208"},
- {"0101010101200101", "0000000000000000", "7a9be42f2009a892"},
- {"0101010101100101", "0000000000000000", "29038d56ba6d2745"},
- {"0101010101080101", "0000000000000000", "5495c6abf1e5df51"},
- {"0101010101040101", "0000000000000000", "ae13dbd561488933"},
- {"0101010101020101", "0000000000000000", "024d1ffa8904e389"},
- {"0101010101018001", "0000000000000000", "d1399712f99bf02e"},
- {"0101010101014001", "0000000000000000", "14c1d7c1cffec79e"},
- {"0101010101012001", "0000000000000000", "1de5279dae3bed6f"},
- {"0101010101011001", "0000000000000000", "e941a33f85501303"},
- {"0101010101010801", "0000000000000000", "da99dbbc9a03f379"},
- {"0101010101010401", "0000000000000000", "b7fc92f91d8e92e9"},
- {"0101010101010201", "0000000000000000", "ae8e5caa3ca04e85"},
- {"0101010101010180", "0000000000000000", "9cc62df43b6eed74"},
- {"0101010101010140", "0000000000000000", "d863dbb5c59a91a0"},
- {"0101010101010120", "0000000000000000", "a1ab2190545b91d7"},
- {"0101010101010110", "0000000000000000", "0875041e64c570f7"},
- {"0101010101010108", "0000000000000000", "5a594528bebef1cc"},
- {"0101010101010104", "0000000000000000", "fcdb3291de21f0c0"},
- {"0101010101010102", "0000000000000000", "869efd7f9f265a09"},
- {"1046913489980131", "0000000000000000", "88d55e54f54c97b4"},
- {"1007103489988020", "0000000000000000", "0c0cc00c83ea48fd"},
- {"10071034c8980120", "0000000000000000", "83bc8ef3a6570183"},
- {"1046103489988020", "0000000000000000", "df725dcad94ea2e9"},
- {"1086911519190101", "0000000000000000", "e652b53b550be8b0"},
- {"1086911519580101", "0000000000000000", "af527120c485cbb0"},
- {"5107b01519580101", "0000000000000000", "0f04ce393db926d5"},
- {"1007b01519190101", "0000000000000000", "c9f00ffc74079067"},
- {"3107915498080101", "0000000000000000", "7cfd82a593252b4e"},
- {"3107919498080101", "0000000000000000", "cb49a2f9e91363e3"},
- {"10079115b9080140", "0000000000000000", "00b588be70d23f56"},
- {"3107911598090140", "0000000000000000", "406a9a6ab43399ae"},
- {"1007d01589980101", "0000000000000000", "6cb773611dca9ada"},
- {"9107911589980101", "0000000000000000", "67fd21c17dbb5d70"},
- {"9107d01589190101", "0000000000000000", "9592cb4110430787"},
- {"1007d01598980120", "0000000000000000", "a6b7ff68a318ddd3"},
- {"1007940498190101", "0000000000000000", "4d102196c914ca16"},
- {"0107910491190401", "0000000000000000", "2dfa9f4573594965"},
- {"0107910491190101", "0000000000000000", "b46604816c0e0774"},
- {"0107940491190401", "0000000000000000", "6e7e6221a4f34e87"},
- {"19079210981a0101", "0000000000000000", "aa85e74643233199"},
- {"1007911998190801", "0000000000000000", "2e5a19db4d1962d6"},
- {"10079119981a0801", "0000000000000000", "23a866a809d30894"},
- {"1007921098190101", "0000000000000000", "d812d961f017d320"},
- {"100791159819010b", "0000000000000000", "055605816e58608f"},
- {"1004801598190101", "0000000000000000", "abd88e8b1b7716f1"},
- {"1004801598190102", "0000000000000000", "537ac95be69da1e1"},
- {"1004801598190108", "0000000000000000", "aed0f6ae3c25cdd8"},
- {"1002911598100104", "0000000000000000", "b3e35a5ee53e7b8d"},
- {"1002911598190104", "0000000000000000", "61c79c71921a2ef8"},
- {"1002911598100201", "0000000000000000", "e2f5728f0995013c"},
- {"1002911698100101", "0000000000000000", "1aeac39a61f0a464"},
- {"7ca110454a1a6e57", "01a1d6d039776742", "690f5b0d9a26939b"},
- {"0131d9619dc1376e", "5cd54ca83def57da", "7a389d10354bd271"},
- {"07a1133e4a0b2686", "0248d43806f67172", "868ebb51cab4599a"},
- {"3849674c2602319e", "51454b582ddf440a", "7178876e01f19b2a"},
- {"04b915ba43feb5b6", "42fd443059577fa2", "af37fb421f8c4095"},
- {"0113b970fd34f2ce", "059b5e0851cf143a", "86a560f10ec6d85b"},
- {"0170f175468fb5e6", "0756d8e0774761d2", "0cd3da020021dc09"},
- {"43297fad38e373fe", "762514b829bf486a", "ea676b2cb7db2b7a"},
- {"07a7137045da2a16", "3bdd119049372802", "dfd64a815caf1a0f"},
- {"04689104c2fd3b2f", "26955f6835af609a", "5c513c9c4886c088"},
- {"37d06bb516cb7546", "164d5e404f275232", "0a2aeeae3ff4ab77"},
- {"1f08260d1ac2465e", "6b056e18759f5cca", "ef1bf03e5dfa575a"},
- {"584023641aba6176", "004bd6ef09176062", "88bf0db6d70dee56"},
- {"025816164629b007", "480d39006ee762f2", "a1f9915541020b56"},
- {"49793ebc79b3258f", "437540c8698f3cfa", "6fbf1cafcffd0556"},
- {"4fb05e1515ab73a7", "072d43a077075292", "2f22e49bab7ca1ac"},
- {"49e95d6d4ca229bf", "02fe55778117f12a", "5a6b612cc26cce4a"},
- {"018310dc409b26d6", "1d9d5c5018f728c2", "5f4c038ed12b2e41"},
- {"1c587f1c13924fef", "305532286d6f295a", "63fac0d034d9f793"}
- */
+/*
+ {"0101010101010101", "4bd388ff6cd81d4f", "1000000000000000"},
+ {"0101010101010101", "20b9e767b2fb1456", "0800000000000000"},
+ {"0101010101010101", "55579380d77138ef", "0400000000000000"},
+ {"0101010101010101", "6cc5defaaf04512f", "0200000000000000"},
+ {"0101010101010101", "0d9f279ba5d87260", "0100000000000000"},
+ {"0101010101010101", "d9031b0271bd5a0a", "0080000000000000"},
+ {"0101010101010101", "424250b37c3dd951", "0040000000000000"},
+ {"0101010101010101", "b8061b7ecd9a21e5", "0020000000000000"},
+ {"0101010101010101", "f15d0f286b65bd28", "0010000000000000"},
+ {"0101010101010101", "add0cc8d6e5deba1", "0008000000000000"},
+ {"0101010101010101", "e6d5f82752ad63d1", "0004000000000000"},
+ {"0101010101010101", "ecbfe3bd3f591a5e", "0002000000000000"},
+ {"0101010101010101", "f356834379d165cd", "0001000000000000"},
+ {"0101010101010101", "2b9f982f20037fa9", "0000800000000000"},
+ {"0101010101010101", "889de068a16f0be6", "0000400000000000"},
+ {"0101010101010101", "e19e275d846a1298", "0000200000000000"},
+ {"0101010101010101", "329a8ed523d71aec", "0000100000000000"},
+ {"0101010101010101", "e7fce22557d23c97", "0000080000000000"},
+ {"0101010101010101", "12a9f5817ff2d65d", "0000040000000000"},
+ {"0101010101010101", "a484c3ad38dc9c19", "0000020000000000"},
+ {"0101010101010101", "fbe00a8a1ef8ad72", "0000010000000000"},
+ {"0101010101010101", "750d079407521363", "0000008000000000"},
+ {"0101010101010101", "64feed9c724c2faf", "0000004000000000"},
+ {"0101010101010101", "f02b263b328e2b60", "0000002000000000"},
+ {"0101010101010101", "9d64555a9a10b852", "0000001000000000"},
+ {"0101010101010101", "d106ff0bed5255d7", "0000000800000000"},
+ {"0101010101010101", "e1652c6b138c64a5", "0000000400000000"},
+ {"0101010101010101", "e428581186ec8f46", "0000000200000000"},
+ {"0101010101010101", "aeb5f5ede22d1a36", "0000000100000000"},
+ {"0101010101010101", "e943d7568aec0c5c", "0000000080000000"},
+ {"0101010101010101", "df98c8276f54b04b", "0000000040000000"},
+ {"0101010101010101", "b160e4680f6c696f", "0000000020000000"},
+ {"0101010101010101", "fa0752b07d9c4ab8", "0000000010000000"},
+ {"0101010101010101", "ca3a2b036dbc8502", "0000000008000000"},
+ {"0101010101010101", "5e0905517bb59bcf", "0000000004000000"},
+ {"0101010101010101", "814eeb3b91d90726", "0000000002000000"},
+ {"0101010101010101", "4d49db1532919c9f", "0000000001000000"},
+ {"0101010101010101", "25eb5fc3f8cf0621", "0000000000800000"},
+ {"0101010101010101", "ab6a20c0620d1c6f", "0000000000400000"},
+ {"0101010101010101", "79e90dbc98f92cca", "0000000000200000"},
+ {"0101010101010101", "866ecedd8072bb0e", "0000000000100000"},
+ {"0101010101010101", "8b54536f2f3e64a8", "0000000000080000"},
+ {"0101010101010101", "ea51d3975595b86b", "0000000000040000"},
+ {"0101010101010101", "caffc6ac4542de31", "0000000000020000"},
+ {"0101010101010101", "8dd45a2ddf90796c", "0000000000010000"},
+ {"0101010101010101", "1029d55e880ec2d0", "0000000000008000"},
+ {"0101010101010101", "5d86cb23639dbea9", "0000000000004000"},
+ {"0101010101010101", "1d1ca853ae7c0c5f", "0000000000002000"},
+ {"0101010101010101", "ce332329248f3228", "0000000000001000"},
+ {"0101010101010101", "8405d1abe24fb942", "0000000000000800"},
+ {"0101010101010101", "e643d78090ca4207", "0000000000000400"},
+ {"0101010101010101", "48221b9937748a23", "0000000000000200"},
+ {"0101010101010101", "dd7c0bbd61fafd54", "0000000000000100"},
+ {"0101010101010101", "2fbc291a570db5c4", "0000000000000080"},
+ {"0101010101010101", "e07c30d7e4e26e12", "0000000000000040"},
+ {"0101010101010101", "0953e2258e8e90a1", "0000000000000020"},
+ {"0101010101010101", "5b711bc4ceebf2ee", "0000000000000010"},
+ {"0101010101010101", "cc083f1e6d9e85f6", "0000000000000008"},
+ {"0101010101010101", "d2fd8867d50d2dfe", "0000000000000004"},
+ {"0101010101010101", "06e7ea22ce92708f", "0000000000000002"},
+ {"0101010101010101", "166b40b44aba4bd6", "0000000000000001"},
+ {"8001010101010101", "0000000000000000", "95a8d72813daa94d"},
+ {"4001010101010101", "0000000000000000", "0eec1487dd8c26d5"},
+ {"2001010101010101", "0000000000000000", "7ad16ffb79c45926"},
+ {"1001010101010101", "0000000000000000", "d3746294ca6a6cf3"},
+ {"0801010101010101", "0000000000000000", "809f5f873c1fd761"},
+ {"0401010101010101", "0000000000000000", "c02faffec989d1fc"},
+ {"0201010101010101", "0000000000000000", "4615aa1d33e72f10"},
+ {"0180010101010101", "0000000000000000", "2055123350c00858"},
+ {"0140010101010101", "0000000000000000", "df3b99d6577397c8"},
+ {"0120010101010101", "0000000000000000", "31fe17369b5288c9"},
+ {"0110010101010101", "0000000000000000", "dfdd3cc64dae1642"},
+ {"0108010101010101", "0000000000000000", "178c83ce2b399d94"},
+ {"0104010101010101", "0000000000000000", "50f636324a9b7f80"},
+ {"0102010101010101", "0000000000000000", "a8468ee3bc18f06d"},
+ {"0101800101010101", "0000000000000000", "a2dc9e92fd3cde92"},
+ {"0101400101010101", "0000000000000000", "cac09f797d031287"},
+ {"0101200101010101", "0000000000000000", "90ba680b22aeb525"},
+ {"0101100101010101", "0000000000000000", "ce7a24f350e280b6"},
+ {"0101080101010101", "0000000000000000", "882bff0aa01a0b87"},
+ {"0101040101010101", "0000000000000000", "25610288924511c2"},
+ {"0101020101010101", "0000000000000000", "c71516c29c75d170"},
+ {"0101018001010101", "0000000000000000", "5199c29a52c9f059"},
+ {"0101014001010101", "0000000000000000", "c22f0a294a71f29f"},
+ {"0101012001010101", "0000000000000000", "ee371483714c02ea"},
+ {"0101011001010101", "0000000000000000", "a81fbd448f9e522f"},
+ {"0101010801010101", "0000000000000000", "4f644c92e192dfed"},
+ {"0101010401010101", "0000000000000000", "1afa9a66a6df92ae"},
+ {"0101010201010101", "0000000000000000", "b3c1cc715cb879d8"},
+ {"0101010180010101", "0000000000000000", "19d032e64ab0bd8b"},
+ {"0101010140010101", "0000000000000000", "3cfaa7a7dc8720dc"},
+ {"0101010120010101", "0000000000000000", "b7265f7f447ac6f3"},
+ {"0101010110010101", "0000000000000000", "9db73b3c0d163f54"},
+ {"0101010108010101", "0000000000000000", "8181b65babf4a975"},
+ {"0101010104010101", "0000000000000000", "93c9b64042eaa240"},
+ {"0101010102010101", "0000000000000000", "5570530829705592"},
+ {"0101010101800101", "0000000000000000", "8638809e878787a0"},
+ {"0101010101400101", "0000000000000000", "41b9a79af79ac208"},
+ {"0101010101200101", "0000000000000000", "7a9be42f2009a892"},
+ {"0101010101100101", "0000000000000000", "29038d56ba6d2745"},
+ {"0101010101080101", "0000000000000000", "5495c6abf1e5df51"},
+ {"0101010101040101", "0000000000000000", "ae13dbd561488933"},
+ {"0101010101020101", "0000000000000000", "024d1ffa8904e389"},
+ {"0101010101018001", "0000000000000000", "d1399712f99bf02e"},
+ {"0101010101014001", "0000000000000000", "14c1d7c1cffec79e"},
+ {"0101010101012001", "0000000000000000", "1de5279dae3bed6f"},
+ {"0101010101011001", "0000000000000000", "e941a33f85501303"},
+ {"0101010101010801", "0000000000000000", "da99dbbc9a03f379"},
+ {"0101010101010401", "0000000000000000", "b7fc92f91d8e92e9"},
+ {"0101010101010201", "0000000000000000", "ae8e5caa3ca04e85"},
+ {"0101010101010180", "0000000000000000", "9cc62df43b6eed74"},
+ {"0101010101010140", "0000000000000000", "d863dbb5c59a91a0"},
+ {"0101010101010120", "0000000000000000", "a1ab2190545b91d7"},
+ {"0101010101010110", "0000000000000000", "0875041e64c570f7"},
+ {"0101010101010108", "0000000000000000", "5a594528bebef1cc"},
+ {"0101010101010104", "0000000000000000", "fcdb3291de21f0c0"},
+ {"0101010101010102", "0000000000000000", "869efd7f9f265a09"},
+ {"1046913489980131", "0000000000000000", "88d55e54f54c97b4"},
+ {"1007103489988020", "0000000000000000", "0c0cc00c83ea48fd"},
+ {"10071034c8980120", "0000000000000000", "83bc8ef3a6570183"},
+ {"1046103489988020", "0000000000000000", "df725dcad94ea2e9"},
+ {"1086911519190101", "0000000000000000", "e652b53b550be8b0"},
+ {"1086911519580101", "0000000000000000", "af527120c485cbb0"},
+ {"5107b01519580101", "0000000000000000", "0f04ce393db926d5"},
+ {"1007b01519190101", "0000000000000000", "c9f00ffc74079067"},
+ {"3107915498080101", "0000000000000000", "7cfd82a593252b4e"},
+ {"3107919498080101", "0000000000000000", "cb49a2f9e91363e3"},
+ {"10079115b9080140", "0000000000000000", "00b588be70d23f56"},
+ {"3107911598090140", "0000000000000000", "406a9a6ab43399ae"},
+ {"1007d01589980101", "0000000000000000", "6cb773611dca9ada"},
+ {"9107911589980101", "0000000000000000", "67fd21c17dbb5d70"},
+ {"9107d01589190101", "0000000000000000", "9592cb4110430787"},
+ {"1007d01598980120", "0000000000000000", "a6b7ff68a318ddd3"},
+ {"1007940498190101", "0000000000000000", "4d102196c914ca16"},
+ {"0107910491190401", "0000000000000000", "2dfa9f4573594965"},
+ {"0107910491190101", "0000000000000000", "b46604816c0e0774"},
+ {"0107940491190401", "0000000000000000", "6e7e6221a4f34e87"},
+ {"19079210981a0101", "0000000000000000", "aa85e74643233199"},
+ {"1007911998190801", "0000000000000000", "2e5a19db4d1962d6"},
+ {"10079119981a0801", "0000000000000000", "23a866a809d30894"},
+ {"1007921098190101", "0000000000000000", "d812d961f017d320"},
+ {"100791159819010b", "0000000000000000", "055605816e58608f"},
+ {"1004801598190101", "0000000000000000", "abd88e8b1b7716f1"},
+ {"1004801598190102", "0000000000000000", "537ac95be69da1e1"},
+ {"1004801598190108", "0000000000000000", "aed0f6ae3c25cdd8"},
+ {"1002911598100104", "0000000000000000", "b3e35a5ee53e7b8d"},
+ {"1002911598190104", "0000000000000000", "61c79c71921a2ef8"},
+ {"1002911598100201", "0000000000000000", "e2f5728f0995013c"},
+ {"1002911698100101", "0000000000000000", "1aeac39a61f0a464"},
+ {"7ca110454a1a6e57", "01a1d6d039776742", "690f5b0d9a26939b"},
+ {"0131d9619dc1376e", "5cd54ca83def57da", "7a389d10354bd271"},
+ {"07a1133e4a0b2686", "0248d43806f67172", "868ebb51cab4599a"},
+ {"3849674c2602319e", "51454b582ddf440a", "7178876e01f19b2a"},
+ {"04b915ba43feb5b6", "42fd443059577fa2", "af37fb421f8c4095"},
+ {"0113b970fd34f2ce", "059b5e0851cf143a", "86a560f10ec6d85b"},
+ {"0170f175468fb5e6", "0756d8e0774761d2", "0cd3da020021dc09"},
+ {"43297fad38e373fe", "762514b829bf486a", "ea676b2cb7db2b7a"},
+ {"07a7137045da2a16", "3bdd119049372802", "dfd64a815caf1a0f"},
+ {"04689104c2fd3b2f", "26955f6835af609a", "5c513c9c4886c088"},
+ {"37d06bb516cb7546", "164d5e404f275232", "0a2aeeae3ff4ab77"},
+ {"1f08260d1ac2465e", "6b056e18759f5cca", "ef1bf03e5dfa575a"},
+ {"584023641aba6176", "004bd6ef09176062", "88bf0db6d70dee56"},
+ {"025816164629b007", "480d39006ee762f2", "a1f9915541020b56"},
+ {"49793ebc79b3258f", "437540c8698f3cfa", "6fbf1cafcffd0556"},
+ {"4fb05e1515ab73a7", "072d43a077075292", "2f22e49bab7ca1ac"},
+ {"49e95d6d4ca229bf", "02fe55778117f12a", "5a6b612cc26cce4a"},
+ {"018310dc409b26d6", "1d9d5c5018f728c2", "5f4c038ed12b2e41"},
+ {"1c587f1c13924fef", "305532286d6f295a", "63fac0d034d9f793"}
+*/
};
-
- private static void self_test()
- throws Exception {
+
+ static private void self_test()
+ throws Exception {
DES cryptor = new DES();
byte[] userKey;
byte[] tmp, pt, ct;
-
+
for (int i = 0; i < tests.length; i++) {
userKey = hexFromString(tests[i][0]);
pt = hexFromString(tests[i][1]);
ct = hexFromString(tests[i][2]);
-
+
cryptor.initEncrypt(userKey);
tmp = cryptor.crypt(pt);
if (!areEqual(ct, tmp))
- throw new RuntimeException("encrypt #"+ i +" failed");
-
+ throw new RuntimeException("encrypt #"+ i +" failed");
+
cryptor.initDecrypt(userKey);
tmp = cryptor.crypt(ct);
- if (!areEqual(pt, tmp))
+ if (!areEqual(pt, tmp))
throw new RuntimeException("decrypt #"+ i +" failed");
}
- if (DEBUG && debuglevel > 0) System.out.println("Self-test OK");
+if (DEBUG && debuglevel > 0) System.out.println("Self-test OK");
}
-
- private static boolean areEqual(byte[] a, byte[] b) {
- if (a.length != b.length) return false;
- for (int i=0; i<a.length; i++) {
- if (a[i] != b[i]) return false;
- }
- return true;
+
+ static private boolean areEqual(byte[] a, byte[] b) {
+ if (a.length != b.length) return false;
+ for (int i=0; i<a.length; i++) {
+ if (a[i] != b[i]) return false;
+ }
+ return true;
}
-
- private static final String HEXSTR = "0123456789abcdef";
- private static byte[] hexFromString(String s) {
+
+ static private final String HEXSTR = "0123456789abcdef";
+ static private byte[] hexFromString(String s) {
s = s.toLowerCase();
byte[] ans = new byte[s.length()/2];
for (int i=0; i<s.length(); i++) {
- if (0 == (i&1)) {
+ if (0 == (i&1)) {
ans[i/2] = (byte)(HEXSTR.indexOf(s.charAt(i)) * 16);
} else {
ans[i/2] += HEXSTR.indexOf(s.charAt(i));
- }
- }
- return ans;
+ }
+ }
+ return ans;
}
/*
- private static void
+ static private void
time_test(PrintWriter out, String keyStr, String plainStr, String cipherStr)
throws InvalidKeyException {
@@ -918,13 +921,13 @@
*
* Its use is FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are adhered to.
- *
+ *
* Copyright remains Geoffrey Keating's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Geoffrey Keating should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -937,7 +940,7 @@
* must display the following acknowledgement:
* This product includes software developed by Geoffrey Keating
* (geoffk@discus.anu.edu.au)
- *
+ *
* THIS SOFTWARE IS PROVIDED BY GEOFFREY KEATING ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -949,20 +952,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
+ *
*/
/* Parts of this code (in particular, the string representing SP_TRANS)
* are Copyright (C) 1995 Eric Young (eay@mincom.oz.au). All rights reserved.
*
* Its use is FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are adhered to.
- *
+ *
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -974,7 +977,7 @@
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
- *
+ *
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -987,3 +990,4 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
1.3 +7 -6 e/src/jsrc/net/vattp/data/Decrypt3DES.java
Index: Decrypt3DES.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/Decrypt3DES.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Decrypt3DES.java 2001/07/14 12:57:21 1.2
+++ Decrypt3DES.java 2001/08/25 19:54:01 1.3
@@ -71,7 +71,7 @@
return val;
}
- /*package*/ void init() {
+ /*package*/ void init() {
if (null != myCurrentBlock) {
increment(myIV);
} else {
@@ -81,9 +81,9 @@
}
/*package*/ void transform(byte[] buffer, int off, int len) {
-
+
long startTime = Trace.comm.timing ? MicroTime.queryTimer() : 0;
- Assertion.test(0==(len&0x7),
+ Assertion.test(0==(len&0x7),
"Buffer length not a multiple of 8, len = "
+ len);
@@ -98,7 +98,7 @@
System.arraycopy(myCurrentBlock,0, myPreviousBlock,0, 8);
}
if (Trace.comm.timing && Trace.ON) {
- Trace.comm.timingm("Pkt3DESDecrypt(" + buffer.length + "), time "
+ Trace.comm.timingm("Pkt3DESDecrypt(" + buffer.length + "), time "
+ (MicroTime.queryTimer() - startTime) + " microseconds");
}
}
@@ -107,14 +107,14 @@
for (int i=0; i<8; i++) inOut[off+i] ^= in[i];
}
- private void increment(byte[] value) {
+ private void increment(byte[] value) {
for (int i=value.length-1; i>=0; i--) {
byte v = (value[i] += 1);
if (0 != v) break;
}
}
- private static String eightToHex(byte[] b, int offset) {
+ static private String eightToHex(byte[] b, int offset) {
String ret = "";
for (int i=offset; i<offset+8; i++) {
ret += "0123456789abcdef".charAt((b[i]>>4)&0xf);
@@ -123,3 +123,4 @@
return ret;
}
}
+
1.3 +15 -11 e/src/jsrc/net/vattp/data/Encrypt3DES.java
Index: Encrypt3DES.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/Encrypt3DES.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Encrypt3DES.java 2001/07/14 12:57:21 1.2
+++ Encrypt3DES.java 2001/08/25 19:54:01 1.3
@@ -33,15 +33,17 @@
private byte[] myIV;
private byte[] myDESKeys;
+ private boolean myIsStandardCBC;
private final byte[] myPreviousBlock = new byte[8];
private final byte[] myPad = new byte[8];
private DES myDes1, myDes2, myDes3;
- /*package*/ Encrypt3DES(byte[] desKeys, byte[] iv) {
+ /*package*/ Encrypt3DES(byte[] desKeys, byte[] iv, boolean isStandardCBC) {
myDESKeys = desKeys;
myIV = iv;
+ myIsStandardCBC = isStandardCBC;
try {
byte[] key = new byte[8];
System.arraycopy(myDESKeys, 0, key, 0, 8);
@@ -58,18 +60,17 @@
Trace.comm.errorm("Problem initializing DES keys", e);
throw new NestedException("Problem initializing DES keys", e);
}
- init();
- }
-
- /*package*/ void init() { //Only needed if flush not used
System.arraycopy(myIV,0, myPreviousBlock,0, 8);
}
+ /*package*/ void init() {} // NOP
+
/*package*/ byte[] getSuspendInfo() {
if (Trace.comm.debug & Trace.ON) {
Trace.comm.debugm("Returning IV=" + eightToHex(myIV,0));
}
- return myIV;
+ if (myIsStandardCBC) return myPreviousBlock;
+ else return myIV;
}
/*package*/ void transform(byte[] buffer, int off, int len) {
@@ -77,7 +78,10 @@
if (0 != (len&7)) {
Assertion.test(false, "Length must be a multiple of 8, len="+len);
}
- System.arraycopy(myIV,0, myPreviousBlock,0, 8);
+ if (!myIsStandardCBC) {
+ System.arraycopy(myIV,0, myPreviousBlock,0, 8);
+ increment(myIV);
+ }
for (int cursor=off; cursor<off+len; cursor+=8) {
if (Trace.comm.verbose && Trace.ON) {
Trace.comm.verbosem("Plaintext=" + eightToHex(buffer, cursor));
@@ -89,9 +93,8 @@
myDes3.update(buffer, cursor, 8, buffer, cursor);
System.arraycopy(buffer, cursor, myPreviousBlock,0, 8);
}
- increment(myIV);
if (Trace.comm.timing && Trace.ON) {
- Trace.comm.timingm("Pkt3DESEncrypt(" + buffer.length + "), time "
+ Trace.comm.timingm("Pkt3DESEncrypt(" + buffer.length + "), time "
+ (MicroTime.queryTimer() - startTime) + " microseconds");
}
}
@@ -101,14 +104,14 @@
for (int i=0; i<8; i++) inOut[offset+i] ^= in[i];
}
- private void increment(byte[] value) {
+ private void increment(byte[] value) {
for (int i=value.length-1; i>=0; i--) {
byte v = (value[i] += 1);
if (0 != v) break;
}
}
- private static String eightToHex(byte[] b, int offset) {
+ static private String eightToHex(byte[] b, int offset) {
String ret = "";
for (int i=offset; i<offset+8; i++) {
ret += "0123456789abcdef".charAt((b[i]>>4)&0xf);
@@ -117,3 +120,4 @@
return ret;
}
}
+
1.4 +203 -70 e/src/jsrc/net/vattp/data/RecvThread.java
Index: RecvThread.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/RecvThread.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- RecvThread.java 2001/07/14 12:57:21 1.3
+++ RecvThread.java 2001/08/25 19:54:01 1.4
@@ -50,11 +50,17 @@
*/
/*package*/ class RecvThread extends Thread {
// Index: 2=transforming, 1=isDoingMac
- // 0 1 2 3
- static private final int[] theHeaderLengths = {4, 24, -1, 24};
+ static private final int HEADER_INVALID = -1;
+ static private final int HEADER_INT_LENGTH = 0;
+ static private final int HEADER_VLEN_SHA1 = 1;
+ static private final int HEADER_VLEN_HMAC = 2;
+ // Note that the header lengths must be a multiple of the blocksize
+ // of the encryption used (8 for 3DES). AES implementation take warning.
+ // 0 1 2
+ static private final int[] theHeaderLengths = {4, 24, 32};
/** Notify DataPath every NOTIFY_EVERY bytes of receive progress */
- private static final int NOTIFY_EVERY = 10000;
+ static private final int NOTIFY_EVERY = 10000;
private InputStream myInputStream;
private DataPath myDataPath;
@@ -75,9 +81,13 @@
// support for future HTTP tunnelling. It could also be used to
// implement a dynamic table dependent compressiong scheme.
private MsgTransformer myTransform = null;
+ private boolean myIsStandardCBC = false;
// The following fields are for MAC calculation
+ // HASH_BLOCK_SIZE is true for MD5 and SHA1, check others
+ static private final int HASH_BLOCK_SIZE = 64;
private boolean myIsDoingMac = false;
+ private boolean myIsDoingHMAC = false;
private byte[] myMACKey;
private MessageDigest mySHA1;
private byte[] myMAC;
@@ -124,6 +134,8 @@
if (t instanceof VirtualMachineError) throw (VirtualMachineError)t;
if (t instanceof ThreadDeath) throw (ThreadDeath)t;
if (t instanceof LinkageError) throw (LinkageError)t;
+ //XXX if it's not one of these, shouldn't we at least trace it,
+ //and perhaps rethrow it?
}
}
/**
@@ -140,54 +152,69 @@
* suite.
*/
- /*package*/ void changeProtocol(
- AuthSecrets protocolParms) {
+ /*package*/ void changeProtocol(AuthSecrets protocolParms) {
if (Trace.comm.verbose && Trace.ON) {
Trace.comm.verbosem("ProtocolChange, pp="+protocolParms);
}
- Assertion.test(myChangeProtocolIsOk,
- "Must only be called while caller is processing an input message");
- int headerLengthIndex = 0; // For calculating the header length
+ Assertion.test(myChangeProtocolIsOk,
+ "Must only be called while caller is processing an input message");
+ // For calculating the header length
+ int headerLengthIndex = HEADER_INVALID;
if (StartUpProtocol.PROTO_NONE.equals(protocolParms.myProtocolSuite)) {
myIsAggragating = false;
myIsDoingMac = false;
+ mySequence = null;
+ headerLengthIndex = HEADER_INT_LENGTH;
// begin daffE -> E
} else if (StartUpProtocol.PROTO_3DES_SDH_M.equals(
- protocolParms.myProtocolSuite)) {
+ protocolParms.myProtocolSuite)) {
myIsAggragating = true;
MessageDigest md5 = setSHA1(protocolParms);
- headerLengthIndex = 3;
+ headerLengthIndex = HEADER_VLEN_SHA1;
mySequence = null;
- byte[] raw_3des_key = TripleDESKeyConstructor.make(protocolParms.myDHSecret);
- // myTransform = new TripleDESMsgEncryptor(protocolParms.myIncomingSequence, raw_3des_key, false);
- myTransform = new Decrypt3DES(raw_3des_key, protocolParms.myIncomingSequence);
+ byte[] raw_3des_key =
+ TripleDESKeyConstructor.make(protocolParms.myDHSecret);
+ myTransform =
+ new Decrypt3DES(raw_3des_key, protocolParms.myIncomingSequence);
// end daffE -> E
- } else if (StartUpProtocol.PROTO_AUTH_SDH_M.equals(
- protocolParms.myProtocolSuite)) {
- myIsAggragating = true;
- MessageDigest md5 = setSHA1(protocolParms);
- headerLengthIndex = 3;
- mySequence = protocolParms.myIncomingSequence;
- myTransform = null;
- } else if (StartUpProtocol.PROTO_NONE_SDH_M.equals(
- protocolParms.myProtocolSuite)) {
+ // begin improved E protocol
+ } else if (StartUpProtocol.PROTO_3DES_SDH_M2.equals(
+ protocolParms.myProtocolSuite)) {
myIsAggragating = true;
MessageDigest md5 = setSHA1(protocolParms);
- headerLengthIndex = 3;
- myTransform = null;
+ headerLengthIndex = HEADER_VLEN_HMAC;
+ mySequence = new byte[4]; // Assume initialized to zero
+ byte[] raw_3des_key =
+ TripleDESKeyConstructor.make(protocolParms.myDHSecret);
+ myTransform =
+ new Decrypt3DES(raw_3des_key, protocolParms.myIncomingSequence);
+ myTransform.init();
+ myIsStandardCBC = true;
+ myIsDoingHMAC = true;
+ // end improved E protocol
} else {
Assertion.test(false, "Invalid protocol type "+protocolParms);
}
myIsCompressingMsgLengths = myIsAggragating;
int len = theHeaderLengths[headerLengthIndex];
- Assertion.test(len >= 0, "Invalid combination of link options");
+ Assertion.test(len >= 0, "Invalid header length code");
myHeader = new byte[len];
}
+
private byte[] computeMAC(Vector messages) throws IOException {
mySHA1.reset(); //Initialize a new hash
- mySHA1.update(myMACKey); // The MAC key
+ if (myIsDoingHMAC) {
+ /* Calculate sha1(key ^ ipad || data) */
+ byte[] pad = new byte[HASH_BLOCK_SIZE];
+ replicate(pad, (byte)0x36);
+ xor(pad, myMACKey);
+ mySHA1.reset();
+ mySHA1.update(pad);
+ } else {
+ mySHA1.update(myMACKey); // The MAC key
+ }
if (null != mySequence) {
mySHA1.update(mySequence);
increment(mySequence);
@@ -197,12 +224,26 @@
byte[] b = (byte[])(itr.nextElement());
int len = b.length;
byte[] l = new byte[4];
- int lenlen = SendThread.msgLength(len, l, 0, myIsCompressingMsgLengths);
+ int lenlen = SendThread.msgLength(len, l, 0,
+ myIsCompressingMsgLengths);
mySHA1.update(l, 0, lenlen);
mySHA1.update(b); // The message
}
- return mySHA1.digest(myMACKey); // The MAC key again
+ if (myIsDoingHMAC) {
+ byte[] hash = mySHA1.digest();
+
+ /* Calculate sha1(key ^ opad || hash */
+ byte[] pad = new byte[HASH_BLOCK_SIZE];
+ replicate(pad, (byte)0x5c);
+ xor(pad, myMACKey);
+ mySHA1.update(pad);
+ mySHA1.update(hash);
+ return mySHA1.digest();
+ } else {
+ return mySHA1.digest(myMACKey); // The MAC key again
+ }
}
+
private void fillArray(byte[] b, int off, int len) throws IOException {
int offset = off;
while (offset < off + len) {
@@ -216,6 +257,7 @@
callDataPath(new DataCommThunk(myDataPath)); //progress notify
}
}
+
/**
* Get the current message sequence number
*/
@@ -226,26 +268,74 @@
return mySequence;
}
}
+
private void increment(byte[] value) {
for (int i=value.length-1; i>=0; i--) {
byte v = (value[i] += 1);
if (0 != v) break;
}
+ }
+
+
+ /**
+ * isEqual - Compare two byte arrays.
+ *
+ * @param a is the first input array.
+ * @param b is the second input array.
+ * @return is true if the two arrays contain all the same bytes,
+ * else false.
+ */
+ static private boolean isEqual(byte[] a, byte[] b) {
+ int len = a.length;
+ if (len != b.length) return false;
+ for (int i=0; i<len; i++) {
+ if (a[i] != b[i]) return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * xor - Exclusive OR two byte arrays.
+ *
+ * @param a is the input and output array.
+ * @param b is the array which is XORed with a.
+ */
+ static private void xor(byte[] a, byte[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ a[i] ^= b[i];
+ }
+ }
+
+
+ /**
+ * replicate - Copy a single byte to all elements of a byte array.
+ *
+ * @param a is the byte array.
+ * @param v is the byte to be replicated.
+ */
+ static private void replicate(byte[] a, byte v) {
+ for (int i=0; i<a.length; i++) {
+ a[i] = v;
+ }
}
- /**
- * Calculate the MD5 hash of some data with a specific padding.
- * <p>
- * The padding allows different values to be obtained from the same data
- * by varing the padding value. We use it to get the different
- * authentication values from the same Diffie Hellman shared secret.
- *
- * @param pad The int (treated as a byte) to be used to pad the MD5 calculation.
- * @param data The data to be hashed.
- * @param md5 The message digest object to be used.
- *
- * @return A byte array representing the hash.
- */
+
+ /**
+ * Calculate the MD5 hash of some data with a specific padding.
+ * <p>
+ * The padding allows different values to be obtained from the same data
+ * by varing the padding value. We use it to get the different
+ * authentication values from the same Diffie Hellman shared secret.
+ *
+ * @param pad The int (treated as a byte) to be used to pad the MD5
+ * calculation.
+ * @param data The data to be hashed.
+ * @param md5 The message digest object to be used.
+ *
+ * @return A byte array representing the hash.
+ */
private byte[] md5Hash(int pad, byte[] data, MessageDigest md5) {
byte[] mdConst = new byte[16];
for (int i=0; i<mdConst.length; i++) mdConst[i] = (byte)pad;
@@ -265,8 +355,12 @@
fillArray(myHeader, 0, myHeader.length);
if (null != myTransform) {
- if (Trace.comm.timing && Trace.ON) startTime = MicroTime.queryTimer();
- myTransform.init();
+ if (Trace.comm.timing && Trace.ON) {
+ startTime = MicroTime.queryTimer();
+ }
+ if (!myIsStandardCBC) {
+ myTransform.init();
+ }
myTransform.transform(myHeader);
if (Trace.comm.timing && Trace.ON) {
authTime += MicroTime.queryTimer() - startTime;
@@ -278,32 +372,32 @@
}
int length;
- int blockOffset = 0; // Message data read with header
+ int nextItemOffset; // Offset to the next item in the header
if (myIsCompressingMsgLengths) {
int l1 = myHeader[0]; // First byte of the length
if (0 == (l1 & 0x80)) { // len < 128
length = l1;
- blockOffset = 3;
+ nextItemOffset = 1;
} else {
if (0x80 == (l1 & 0xc0)) { // len < 16,384
length = ((l1 & 0x3f) << 8) |
((myHeader[1] & 0xff));
- blockOffset = 2;
+ nextItemOffset = 2;
} else if (0xc0 == (l1 & 0xe0)) { // len < 2,097,152
length = ((l1 & 0x1f) << 16) |
((myHeader[1] & 0xff) << 8) |
((myHeader[2] & 0xff)) ;
- blockOffset = 1;
+ nextItemOffset = 3;
} else if (0xe0 == (l1 & 0xf0)) { // len < 2**28
length = ((l1 & 0x0f) << 24) |
((myHeader[1] & 0xff) << 16) |
((myHeader[2] & 0xff) << 8) |
((myHeader[3] & 0xff)) ;
- // blockOffset = 0; already set
+ nextItemOffset = 4;
} else {
- throw new IOException(
- "Invalid compressed length code"
- + HexStringUtils.byteArrayToReadableHexString(myHeader));
+ throw new IOException
+ ("Invalid compressed length code" +
+ HexStringUtils.byteArrayToReadableHexString(myHeader));
}
}
} else { // Not compressing
@@ -311,6 +405,7 @@
((myHeader[1] & 0xff) << 16) |
((myHeader[2] & 0xff) << 8) |
(myHeader[3] & 0xff) ;
+ nextItemOffset = 4;
}
if (Trace.comm.verbose && Trace.ON) {
Trace.comm.verbosem("incoming packet len = " + length);
@@ -318,37 +413,75 @@
if (length > Msg.MAX_INBOUND_MSG_LENGTH || length < 0) {
throw new IOException("Packet too large: " + length +
" > " + Msg.MAX_INBOUND_MSG_LENGTH);
+ }
+ if (myIsDoingMac) {
+ System.arraycopy(myHeader, nextItemOffset,
+ myMAC, 0, 20); // Save MAC
+ nextItemOffset += 20;
+ }
+ if (null != mySequence) {
+ int seqLen = mySequence.length;
+ byte[] theirSequence = new byte[seqLen];
+ System.arraycopy(myHeader, nextItemOffset,
+ theirSequence, 0,
+ seqLen);
+ if (!isEqual(mySequence, theirSequence)) {
+ if (Trace.comm.error) {
+ traceErrorMessage(theirSequence,
+ 0, theirSequence.length,
+ "sequence error, [remote sequence number]:");
+ traceErrorMessage(mySequence,
+ 0, mySequence.length,
+ "sequence error, [local sequence number]:");
+ }
+ throw new IOException("incoming packet sequence error");
+ }
+ nextItemOffset += seqLen;
+ }
+ // Calculate message length + padding and allocate a buffer
+ // The length required is the length of the data portion plus the
+ // padding length for the original message.
+ // The padding length for the original message is calculated:
+ // msglen = (length_of_length + length_of_headers + length_of_data
+ // padlen = ((msglen + 7) & 0xfffffff8) - msglen
+ // length_of_length + length_of_headers is equal to nextItemOffset
+ // (the amount of data eaten by processing them above).
+ // length_of_data is length.
+ byte[] message;
+ if (myIsCompressingMsgLengths || null != myTransform) {
+ int msglen = nextItemOffset + length;
+ int padlen = ((msglen + 7) & 0xfffffff8) - msglen;
+ message = new byte[length + padlen];
+ } else {
+ message = new byte[length];
}
- byte[] message = new byte[
- (myIsCompressingMsgLengths || null != myTransform)
- ? ((length-blockOffset+7)
- &0xfffffff8)
- + blockOffset
- : length];
- if (blockOffset > 0) {
+ if (nextItemOffset < myHeader.length) {
// Copy compressed data read with header
- System.arraycopy(myHeader,24-blockOffset,
- message,0,
- blockOffset);
+ System.arraycopy(myHeader, nextItemOffset,
+ message, 0,
+ myHeader.length - nextItemOffset);
}
if (Trace.comm.verbose && Trace.ON) {
Trace.comm.verbosem("Initial message: "
+ HexStringUtils.byteArrayToReadableHexString(message));
}
- if (myIsDoingMac) {
- System.arraycopy(myHeader,4-blockOffset,
- myMAC, 0, 20); // Save MAC
- }
// Read rest of message into the buffer allocated for it
- fillArray(message, blockOffset, message.length-blockOffset);
+ fillArray(message,
+ myHeader.length - nextItemOffset,
+ message.length - (myHeader.length - nextItemOffset));
if (null != myTransform) {
- if (Trace.comm.timing && Trace.ON) startTime = MicroTime.queryTimer();
- myTransform.transform(message, blockOffset,
- message.length - blockOffset);
- if (Trace.comm.timing && Trace.ON) authTime += MicroTime.queryTimer() - startTime;
+ if (Trace.comm.timing && Trace.ON) {
+ startTime = MicroTime.queryTimer();
+ }
+ myTransform.transform(message, (myHeader.length-nextItemOffset),
+ message.length - (myHeader.length-nextItemOffset));
+ if (Trace.comm.timing && Trace.ON) {
+ authTime += MicroTime.queryTimer() - startTime;
+ }
}
+
if (Trace.comm.verbose && Trace.ON) {
Trace.comm.verbosem("Full message: "
+ HexStringUtils.byteArrayToReadableHexString(message));
1.4 +180 -95 e/src/jsrc/net/vattp/data/SendThread.java
Index: SendThread.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/SendThread.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- SendThread.java 2001/08/20 05:07:43 1.3
+++ SendThread.java 2001/08/25 19:54:01 1.4
@@ -44,46 +44,47 @@
import java.util.Vector;
/**
- A thread for writing data to an OutputStream that might block.
- Incoming chunks of data are enqueued. The thread dequeues chunks
- and writes them. Exceptions during the actual writing are sent to
- the RawConnection for delivery back into the vat via
- noticeProblem().
-<p>
- This class generates network packets in the following forms:
-
- <p>If no authentication, no mac, no aggragation: (dataLength, data)
-
- <p>If authentication, mac, aggragation:
- (n,commlength) (mac) (msg1len, msg1, msg2len, msg2 ...) (pad)
-
- <p> commLength is the length of the data in the message on the comm link.
-
- <p>If commLength < 128 (2**7) then n == 1. (One high bit zero)
- If commLength < 16,384 (2**14) then n == 2. (Two high bits are 10)
- If commLength < 2,097,152 (2**21) then n == 3. (Three high bits are 110).
- <p>Since the maximum length packet is currently 1024*1024, the above
- encoding is sufficent. If longer packets become supported, then
- If commLength < 2**28 then n == 4. (Four high bits are 1110) and
- If commLength < 2**31 then n == 5. (Five high bits are 11110).
- N.B. In Java, array.length is a 31 bit int, limiting the maximum
- length we must support.
-
- <p>The MAC is always calculated over the aggragated data. N.B. the
- message building logic prepends a 4 byte message length field to each
- message, so the MAC includes the message length(s).
-
- <p> pad is padding to make the actual packet length a multiple of the
- basic block size.
-
- <p>The whole packet is authenticated with the authentication algorthm and mode
- specified when authentication is turned on.
- @author Bill Frantz
+ * A thread for writing data to an OutputStream that might block.
+ * Incoming chunks of data are enqueued. The thread dequeues chunks
+ * and writes them. Exceptions during the actual writing are sent to
+ * the RawConnection for delivery back into the vat via
+ * noticeProblem().
+ * <p>
+ * This class generates network packets in the following forms:
+ * <p>
+ * If no authentication, no mac, no aggragation: (dataLength, data)
+ * <p>
+ * If authentication, mac, aggragation:
+ * (n,commlength) (mac) (msg1len, msg1, msg2len, msg2 ...) (pad)
+ * <p>
+ * commLength is the length of the data in the message on the comm link.
+ * <p>
+ * If commLength < 128 (2**7) then n == 1. (One high bit zero)
+ * If commLength < 16,384 (2**14) then n == 2. (Two high bits are 10)
+ * If commLength < 2,097,152 (2**21) then n == 3. (Three high bits are 110).
+ * <p>
+ * Since the maximum length packet is currently 1024*1024, the above
+ * encoding is sufficent. If longer packets become supported, then
+ * If commLength < 2**28 then n == 4. (Four high bits are 1110) and
+ * If commLength < 2**31 then n == 5. (Five high bits are 11110).
+ * N.B. In Java, array.length is a 31 bit int, limiting the maximum
+ * length we must support.
+ * <p>
+ * The MAC is always calculated over the aggragated data. N.B. the
+ * message building logic prepends a 4 byte message length field to each
+ * message, so the MAC includes the message length(s).
+ * <p>
+ * pad is padding to make the actual packet length a multiple of the
+ * basic block size.
+ * <p>
+ * The whole packet is authenticated with the authentication algorthm and
+ * mode specified when authentication is turned on.
+ * @author Bill Frantz
*/
/*package*/ class SendThread extends Thread {
/** Notify DataPath every NOTIFY_EVERY bytes of send progress */
- private static final int NOTIFY_EVERY = 10000;
+ static private final int NOTIFY_EVERY = 10000;
private OutputStream myOutputStream;
private Socket mySocket;
@@ -100,7 +101,7 @@
private Hashtable myAddressesTried;
// The following fields are for aggragating messages
- private static final int MAX_AGGRAGATION = 1024;
+ static private final int MAX_AGGRAGATION = 1024;
private boolean myIsAggragating = false;
private int myAggragateLength;
private byte[] myAggragation = new byte[MAX_AGGRAGATION];
@@ -111,10 +112,14 @@
// support for future HTTP tunnelling. It could also be used to
// implement a dynamic table dependent compressiong scheme.
private MsgTransformer myTransform = null;
+ private boolean myIsStandardCBC = false;
// The following fields are for MAC calculation
+ // HASH_BLOCK_SIZE is true for MD5 and SHA1, check others
+ static private final int HASH_BLOCK_SIZE = 64;
private boolean myIsDoingMac = false;
- private byte[] myMacKey;
+ private boolean myIsDoingHMAC = false;
+ private byte[] myMACKey;
private MessageDigest mySHA1;
private int myMacLen = 0;
private byte[] mySequence; // Sequence check
@@ -175,6 +180,12 @@
if (null == myRunner) throw new NullPointerException("Bad Runner");
this.start();
}
+
+ /**
+ * Add an element to the aggrated message being constructed.
+ *
+ * @param elem is the element to be added.
+ */
private void addElement(Object elem) throws IOException {
if (elem instanceof byte[]) {
byte[] b = (byte[]) elem;
@@ -182,7 +193,7 @@
Trace.comm.verbosem("to=" + myRemoteAddr
+ " addElement="+b.length);
}
- if (!myIsAggragating
+ if (!myIsAggragating
|| myAggragateLength + b.length+4 > myAggragation.length) {
flushElements();
if (b.length+4 > myAggragation.length) {
@@ -191,10 +202,8 @@
}
}
int len = b.length;
- myAggragateLength = msgLength(len,
- myAggragation,
- myAggragateLength,
- myIsCompressingMsgLengths);
+ myAggragateLength = msgLength(len, myAggragation,
+ myAggragateLength, myIsCompressingMsgLengths);
System.arraycopy(b, 0, myAggragation,
myAggragateLength, len);
myAggragateLength += len;
@@ -206,7 +215,7 @@
Trace.comm.verbosem("to=" + myRemoteAddr
+ " addElement="+b.length);
}
- if (!myIsAggragating
+ if (!myIsAggragating
|| myAggragateLength + b.length+4 > myAggragation.length) {
flushElements();
if (b.length+4 > myAggragation.length) {
@@ -237,7 +246,7 @@
flushElements(); // Write previous stuff under old rules
AuthSecrets c = (AuthSecrets) elem;
if (Trace.comm.debug && Trace.ON) {
- Trace.comm.debugm("to=" + myRemoteAddr
+ Trace.comm.debugm("to=" + myRemoteAddr
+ " doing ProtocolChange, protocolSuite="
+ c.myProtocolSuite);
}
@@ -245,32 +254,33 @@
myIsAggragating = false;
myIsDoingMac = false;
// begin daffE -> E
- } else if (StartUpProtocol.PROTO_3DES_SDH_M.equals(c.myProtocolSuite)) {
+ } else if (StartUpProtocol.PROTO_3DES_SDH_M
+ .equals(c.myProtocolSuite)) {
myIsAggragating = true;
myIsDoingMac = true;
- myMacKey = c.myMacKey;
+ myMACKey = c.myMacKey;
myMacLen = 20;
byte[] raw_3des_key = TripleDESKeyConstructor.make(c.myDHSecret);
- // myTransform = new TripleDESMsgEncryptor(c.myOutgoingSequence, raw_3des_key, true);
- myTransform = new Encrypt3DES(raw_3des_key, c.myOutgoingSequence);
+ myTransform =
+ new Encrypt3DES(raw_3des_key, c.myOutgoingSequence, false);
mySequence = null;
setSHA1();
// end daffE -> E
- } else if (StartUpProtocol.PROTO_AUTH_SDH_M.equals(c.myProtocolSuite)) {
+ // Begin improved E protocol
+ } else if (StartUpProtocol.PROTO_3DES_SDH_M2
+ .equals(c.myProtocolSuite)) {
myIsAggragating = true;
myIsDoingMac = true;
- myMacKey = c.myMacKey;
+ myMACKey = c.myMacKey;
myMacLen = 20;
- myTransform = null;
- mySequence = c.myOutgoingSequence;
- setSHA1();
- } else if (StartUpProtocol.PROTO_NONE_SDH_M.equals(c.myProtocolSuite)) {
- myIsAggragating = true;
- myIsDoingMac = true;
- myMacKey = c.myMacKey;
- myMacLen = 20;
- myTransform = null;
+ myIsDoingHMAC = true;
+ byte[] raw_3des_key = TripleDESKeyConstructor.make(c.myDHSecret);
+ myTransform = new Encrypt3DES(raw_3des_key, c.myOutgoingSequence, true);
+ myTransform.init();
+ myIsStandardCBC = true;
+ mySequence = new byte[4]; // Assume initialized to zero
setSHA1();
+ // end improved E protocol
} else {
throw new IOException(
"Invalid protocol suite type "+c.myProtocolSuite);
@@ -281,14 +291,14 @@
/**
* Call a method in our DataPath
*
- * @param thunk a Thunk that will perform the call. The thunk will
+ * @param thunk a Thunk that will perform the call. The thunk will
* be called after the Vat lock is obtained.
*/
private void callDataPath(DataCommThunk thunk) {
try {
myRunner.now(thunk);
} catch(Throwable t) {
- Trace.comm.errorm("to=" + myRemoteAddr + " Error while calling "
+ Trace.comm.errorm("to=" + myRemoteAddr + " Error while calling "
+ thunk, t);
if (t instanceof VirtualMachineError) throw (VirtualMachineError)t;
if (t instanceof ThreadDeath) throw (ThreadDeath)t;
@@ -298,12 +308,21 @@
private byte[] computeMAC(byte[] b, int off, int len,
/*NilOK*/byte[] lenField) {
if (Trace.comm.verbose && Trace.ON) {
- Trace.comm.verbosem("to=" + myRemoteAddr
+ Trace.comm.verbosem("to=" + myRemoteAddr
+ " Calculating MAC on (length "+len+"):"
+ HexStringUtils.byteArrayToReadableHexString(b, off, len));
}
mySHA1.reset(); //Initialize a new hash
- mySHA1.update(myMacKey); // The MAC key
+ if (myIsDoingHMAC) {
+ /* Calculate sha1(key ^ ipad || data) */
+ byte[] pad = new byte[HASH_BLOCK_SIZE];
+ replicate(pad, (byte)0x36);
+ xor(pad, myMACKey);
+ mySHA1.reset();
+ mySHA1.update(pad);
+ } else {
+ mySHA1.update(myMACKey); // The MAC key
+ }
if (null != mySequence) {
mySHA1.update(mySequence);
increment(mySequence);
@@ -312,7 +331,19 @@
mySHA1.update(lenField);
}
mySHA1.update(b, off, len);
- return mySHA1.digest(myMacKey); // The MAC key again
+ if (myIsDoingHMAC) {
+ byte[] hash = mySHA1.digest();
+
+ /* Calculate sha1(key ^ opad || hash */
+ byte[] pad = new byte[HASH_BLOCK_SIZE];
+ replicate(pad, (byte)0x5c);
+ xor(pad, myMACKey);
+ mySHA1.update(pad);
+ mySHA1.update(hash);
+ return mySHA1.digest();
+ } else {
+ return mySHA1.digest(myMACKey); // The MAC key again
+ }
}
private void flushElements() throws IOException {
if (Trace.comm.verbose && Trace.ON) {
@@ -348,12 +379,39 @@
return mySequence;
}
}
- private void increment(byte[] value) {
+ private void increment(byte[] value) {
for (int i=value.length-1; i>=0; i--) {
byte v = (value[i] += 1);
if (0 != v) break;
}
}
+
+ /**
+ * xor - Exclusive OR two byte arrays.
+ *
+ * @param a is the input and output array.
+ * @param b is the array which is XORed with a.
+ */
+ static private void xor(byte[] a, byte[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ a[i] ^= b[i];
+ }
+ }
+
+
+ /**
+ * replicate - Copy a single byte to all elements of a byte array.
+ *
+ * @param a is the byte array.
+ * @param v is the byte to be replicated.
+ */
+ static private void replicate(byte[] a, byte v) {
+ for (int i=0; i<a.length; i++) {
+ a[i] = v;
+ }
+ }
+
/**
* Calculate the MD5 hash of some data with a specific padding.
* <p>
@@ -375,7 +433,18 @@
md5.update(mdConst);
return md5.digest(data);
}
- static /*package*/ int msgLength(int len, byte[] buf,
+
+ /**
+ * Calculate the message length field for a message.
+ *
+ * @param len is the length of the message to have it's length encoded.
+ * @param buf is the output buffer for the encoded length.
+ * @param off is the offset in the buffer for where to place the encoded length.
+ * @param comprssed is true if compressed lengths are to be used.
+ *
+ * @return is the offset of the byte after the end of the length.
+ */
+ static /*package*/ int msgLength(int len, byte[] buf,
int off, boolean compressed)
throws IOException {
if (compressed) {
@@ -400,6 +469,7 @@
}
return off;
}
+
/**
* Inform the DataPath about a problem
*/
@@ -409,18 +479,17 @@
/**
* Body of the thread. Responsible for dequeueing messages and
* writing them. Also for dequeueing parameter change orders (e.g.
- * authentication changes) and executing them in order.
+ * authentication changes) and executing them in order.
* Calls DataPath.shutdown() before exiting.
* Will exit if a null is dequeued.
*/
- public void run() {
-// First build the connection.
+ public void run() { // First build the connection.
try {
NetAddr remoteNetAddr;
if (null == mySocket) {
if (Trace.comm.debug && Trace.ON) {
- Trace.comm.debugm("Attempting outgoing connection to "
+ Trace.comm.debugm("Attempting outgoing connection to "
+ myRemoteAddr);
}
long startTime = 0;
@@ -428,9 +497,9 @@
startTime = MicroTime.queryTimer();
}
remoteNetAddr = new NetAddr(myRemoteAddr);
- //it's safe to not check optInetAddress() for null, since
+ //it's safe to not check optInetAddress() for null, since
//remoteNetAddr must explicitly have one
- InetAddress remoteInetAddress
+ InetAddress remoteInetAddress
= remoteNetAddr.optInetAddress();
if (null != myAddressesTried.get(remoteInetAddress)) {
throw new NoRouteToHostException("Already failed once");
@@ -456,9 +525,9 @@
}
myLocalAddr = new NetAddr(mySocket.getLocalAddress(),
mySocket.getLocalPort());
-
+
if (Trace.comm.debug && Trace.ON) {
- Trace.comm.debugm("Acquired outgoing connection to "
+ Trace.comm.debugm("Acquired outgoing connection to "
+ myRemoteAddr + " from " + myLocalAddr);
}
try {
@@ -470,16 +539,16 @@
}
myOutputStream = mySocket.getOutputStream();
- RecvThread receiver = new RecvThread(mySocket.getInputStream(),
+ RecvThread receiver = new RecvThread(mySocket.getInputStream(),
myDataPath,
myRemoteAddr,
myRunner);
callDataPath(
- new DataCommThunk(myDataPath,
+ new DataCommThunk(myDataPath,
receiver,
remoteNetAddr,
myLocalAddr));
-
+
} catch (Exception e) {
if (e instanceof IOException) {
Trace.comm.eventm("IOException", e);
@@ -520,9 +589,9 @@
}
flushElements(); // Flush out last queued elements
myOutputStream.flush();
-
+
if (Trace.comm.debug && Trace.ON) {
- Trace.comm.debugm("to=" + myRemoteAddr
+ Trace.comm.debugm("to=" + myRemoteAddr
+ " I've been asked to shutdown");
}
} catch (Exception e) {
@@ -542,12 +611,12 @@
Trace.comm.debugm("to=" + myRemoteAddr + " terminated");
}
//Notify the DataPath that the connection has shut down
- if (null == shutDownReason) shutDownReason
+ if (null == shutDownReason) shutDownReason
= new ConnectionShutDownException("Normal Shutdown");
callDataPath(new DataCommThunk(myDataPath, getSequence(), shutDownReason));
myDataPath = null; // Help GC keep our secrets
myTransform = null;
- myMacKey = null;
+ myMACKey = null;
mySHA1 = null;
}
/**
@@ -574,11 +643,11 @@
lineLen += lenField.length;
}
if (Trace.comm.event && Trace.ON) {
- Trace.comm.eventm("to=" + myRemoteAddr
+ Trace.comm.eventm("to=" + myRemoteAddr
+ " Sending message len=" + len);
}
writeAndRecordProgress(b, off, len);
- callDataPath(new DataCommThunk(myDataPath,
+ callDataPath(new DataCommThunk(myDataPath,
myAggragationCount,
len,
null));
@@ -591,13 +660,16 @@
if (Trace.comm.timing && Trace.ON) startTime = MicroTime.queryTimer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(new byte[myMacLen+4]); // Write space for length + MAC
+ if (null != mySequence) {
+ baos.write(mySequence); // Write separate message sequence number
+ }
if (null != lenField) {
baos.write(lenField);
}
baos.write(b, off, len);
baos.close();
// Get the length and the length of the sent length field
- int commLength = baos.size() - 24;
+ int commLength = baos.size() - 24 - mySequence.length;
int offset = -1;
if (commLength < 128) {
@@ -610,10 +682,10 @@
throw new IOException("Packet too large: " + commLength
+ " >= 2,097,152");
}
- // If not a multiple of 64 bits (8 bytes), pad for authentication
- if ( (myIsCompressingMsgLengths || null != myTransform)
- && 0 != ((commLength-offset) & 7)) {
- byte[] fill = new byte[8 - ((commLength-offset)&7)];
+ // If not a multiple of 64 bits (8 bytes), pad to 8 bytes
+ if ( (myIsCompressingMsgLengths || null != myTransform)
+ && 0 != ((baos.size()-offset) & 7)) {
+ byte[] fill = new byte[8 - ((baos.size()-offset)&7)];
baos.write(fill); // Pad to multiple of 8 bytes
}
byte[] data = baos.toByteArray();
@@ -651,12 +723,14 @@
if (null != myTransform) {
if (Trace.comm.timing && Trace.ON) startTime = MicroTime.queryTimer();
if (Trace.comm.verbose && Trace.ON) {
- Trace.comm.verbosem("to=" + myRemoteAddr + " authenticating "
+ Trace.comm.verbosem("to=" + myRemoteAddr + " authenticating "
+ (data.length-offset) + " bytes: "
- + HexStringUtils.byteArrayToReadableHexString(data,
+ + HexStringUtils.byteArrayToReadableHexString(data,
offset, data.length-offset));
+ }
+ if (!myIsStandardCBC) {
+ myTransform.init();
}
- myTransform.init();
myTransform.transform(data, offset, data.length-offset);
if (Trace.comm.timing && Trace.ON) {
authenticationTime += MicroTime.queryTimer() - startTime;
@@ -684,6 +758,12 @@
null));
return;
}
+
+ /**
+ * Send an aggrating mode message with only a single element in the message.
+ *
+ * @param b is the byte array which is the data of the message
+ */
private void sendBytesWithLength(byte[] b) throws IOException {
if (Trace.comm.verbose && Trace.ON) {
@@ -698,11 +778,15 @@
sendBytes(b, 0, b.length, clen, b.length);
}
+
+ /**
+ * Get an instance of the SHA1 message digest.
+ */
private void setSHA1() {
try {
mySHA1 = MessageDigest.getInstance("SHA");
} catch(NoSuchAlgorithmException e) {
- Trace.comm.errorm("to=" + myRemoteAddr
+ Trace.comm.errorm("to=" + myRemoteAddr
+ " Unable to build SHA", e);
Trace.comm.notifyFatal();
}
@@ -711,8 +795,8 @@
* Write a message in chunks and inform the datapath of progress in the
* write.
*/
-
- private void writeAndRecordProgress(byte[] b, int off, int len)
+
+ private void writeAndRecordProgress(byte[] b, int off, int len)
throws IOException {
int offset = off;
while (0 != len) {
@@ -724,3 +808,4 @@
}
}
}
+
1.2 +144 -174 e/src/jsrc/net/vattp/data/StartUpProtocol.java
Index: StartUpProtocol.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/StartUpProtocol.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- StartUpProtocol.java 2000/12/21 22:15:18 1.1
+++ StartUpProtocol.java 2001/08/25 19:54:01 1.2
@@ -72,60 +72,59 @@
* States for the connection startup state machine. Current state
* is in myState below.
*/
- final /*package*/ static int ST_UNSTARTED = 0;
- final /*package*/ static int ST_INCOMING_EXPECT_IWANT = 1;
- final /*package*/ static int ST_OUTGOING_EXPECT_IAM = 2;
- final /*package*/ static int ST_INCOMING_EXPECT_GIVEINFO = 3;
- final /*package*/ static int ST_OUTGOING_EXPECT_REPLYINFO = 4;
- final /*package*/ static int ST_INCOMING_EXPECT_GO = 5;
- final /*package*/ static int ST_OUTGOING_EXPECT_GOTOO = 6;
- final /*package*/ static int ST_EXPECT_MESSAGE = 7;
- final /*package*/ static int ST_DEAD = 8;
- final /*package*/ static int ST_TRY_NEXT = 9;
+ static /*package*/ final int ST_UNSTARTED = 0;
+ static /*package*/ final int ST_INCOMING_EXPECT_IWANT = 1;
+ static /*package*/ final int ST_OUTGOING_EXPECT_IAM = 2;
+ static /*package*/ final int ST_INCOMING_EXPECT_GIVEINFO = 3;
+ static /*package*/ final int ST_OUTGOING_EXPECT_REPLYINFO = 4;
+ static /*package*/ final int ST_INCOMING_EXPECT_GO = 5;
+ static /*package*/ final int ST_OUTGOING_EXPECT_GOTOO = 6;
+ static /*package*/ final int ST_EXPECT_MESSAGE = 7;
+ static /*package*/ final int ST_DEAD = 8;
+ static /*package*/ final int ST_TRY_NEXT = 9;
/*
* Tokens used for submessage types of the Msg.STARTUP message
*/
- final private static byte TOK_BYE = 1;
- final private static byte TOK_DUP = 2;
- final private static byte TOK_GIVEINFO = 3;
- final private static byte TOK_GO = 4;
- final private static byte TOK_GOTOO = 5;
- final private static byte TOK_IAM = 6;
- final private static byte TOK_IWANT = 7;
- final private static byte TOK_NOT_ME = 8;
- final private static byte TOK_REPLYINFO = 9;
- final private static byte TOK_TRY = 10;
- final private static byte TOK_RESUME = 11;
- final private static byte TOK_YOUCHOSE = 12;
+ static private final byte TOK_BYE = 1;
+ static private final byte TOK_DUP = 2;
+ static private final byte TOK_GIVEINFO = 3;
+ static private final byte TOK_GO = 4;
+ static private final byte TOK_GOTOO = 5;
+ static private final byte TOK_IAM = 6;
+ static private final byte TOK_IWANT = 7;
+ static private final byte TOK_NOT_ME = 8;
+ static private final byte TOK_REPLYINFO = 9;
+ static private final byte TOK_TRY = 10;
+ static private final byte TOK_RESUME = 11;
+ static private final byte TOK_YOUCHOSE = 12;
/* Tokens used to report errors to the remote end.
* All are negative numbers.
*/
- final private static byte TOK_ERR_PROTOCOL = -2;
- final private static byte TOK_ERR_WRONG_ID = -3;
- final private static byte TOK_ERR_INTERNAL = -4;
+ static private final byte TOK_ERR_PROTOCOL = -2;
+ static private final byte TOK_ERR_WRONG_ID = -3;
+ static private final byte TOK_ERR_INTERNAL = -4;
/*
* Values for supported protocol suites:
*/
- final /*package*/ static String PROTO_NONE = "None";
- final /*package*/ static String PROTO_3DES_SDH_M = "3DES_SDH_M";
- final /*package*/ static String PROTO_BLOWFISH56_SDH_M = "BLOWFISH56_SDH_M";
- final /*package*/ static String PROTO_NONE_SDH_M = "NONE_SDH_M";
- final /*package*/ static String PROTO_AUTH_SDH_M = "AUTH_SDH_M";
+ static /*package*/ final String PROTO_NONE = "None";
+ static /*package*/ final String PROTO_3DES_SDH_M = "3DES_SDH_M";
+ static /*package*/ final String PROTO_3DES_SDH_M2 = "3DES_SDH_M2";
/** The protocol negotiation string we send, least desired last */
- private static String TheAuthProtocols;
-
- /** The authentication protocols we support. Excludes none which is a
+ static private String TheAuthProtocols;
+
+ /** The authentication protocols we support. Excludes none which is a
* special case */
- private static String[] TheAuthProtocolTable;
+ static private String[] TheAuthProtocolTable;
static {
TheAuthProtocols = "";
- TheAuthProtocols += PROTO_3DES_SDH_M; // daffE -> E
+ TheAuthProtocols += PROTO_3DES_SDH_M2 + ","; // Improved protocol
+ TheAuthProtocols += PROTO_3DES_SDH_M; // daffE -> E
//'Nothin ain't worth 'nothing, but it's exportable :-)
// daffE -> E TheAuthProtocols += PROTO_AUTH_SDH_M + ",";
//Compatibility with non-sequence checking versions.
@@ -149,16 +148,16 @@
start = end + 1;
}
result[count-1] = TheAuthProtocols.substring(start);
-
+
TheAuthProtocolTable = result;
}
static public String[] authProtocolTable() {
return TheAuthProtocolTable;
}
-
+
/* String names for the Tokens for use in trace messages */
- final private static String[] tokNames = {
+ static private final String[] tokNames = {
"TOK_BYE",
"TOK_DUP",
"TOK_GIVEINFO",
@@ -173,7 +172,7 @@
"TOK_YOUCHOSE"
};
- final private static String[] errTokNames = {
+ static private final String[] errTokNames = {
"***Unassigned***",
"TOK_ERR_PROTOCOL",
"TOK_ERR_WRONG_ID",
@@ -187,20 +186,20 @@
/** Whether we are build for initiating an outbound connection or
* responding to a remote connection */
private boolean myIsIncoming;
-
+
/** The remote vatID we are communicating with */
private String myRemoteVatID;
-
- /** The suspend ID to present to the other end for a reconnect.
+
+ /** The suspend ID to present to the other end for a reconnect.
If it is null, reconnection will not be attempted.
(Outbound connections only)*/
private /*nullOK*/ byte[] myOutgoingSuspendID;
-
+
/** The public key of the remote end */
private PublicKey myHisPublicKey;
-
+
private KeyPair myIdentityKeys;
-
+
/** Entity from which to lookup foreign vatIDs */
private VatLocationLookup myVLS;
@@ -213,17 +212,17 @@
/** Current state of the startup protocol state machine */
private int myState = ST_UNSTARTED;
- /** Set true if we should stop attempting to make a connection
+ /** Set true if we should stop attempting to make a connection
before outgoingSetup has been called.*/
private boolean myStop = false;
-
+
/** The agreed E message protocol version */
private String myEMsgProtocolVersion;
-
+
/** The agreed upon protocol suite */
private String myProtocolSuite;
-
-
+
+
/** The Signature object used for signing and checking signatures */
//WARNING - WARNING - WARNING
// In order to use ESecureRandom to calculate each signature in mySignature
@@ -233,12 +232,12 @@
// I (WSF) think it will be easier to avoid this problem if mySignature
// remains private, and signatures are only calculated one place in the code.
private Signature mySignature;
-
-
+
+
/** Messages I've sent which are to be signed for as part of end point
* authentication. */
private Vector myMessagesToSign = new Vector(5);
-
+
/** Messages I've received whose signature is to be checked as part of
* end point identification. */
private Vector hisMessagesToSign = new Vector(5);
@@ -275,12 +274,12 @@
* @param localFlattenedSearchPath the search path we publish for others
* looking for the local vat in semicolon separated form.
*/
- /*package*/ StartUpProtocol(DataPath path,
+ /*package*/ StartUpProtocol(DataPath path,
boolean isIncoming,
- String /*nullOK*/ remoteVatID,
+ String /*nullOK*/ remoteVatID,
KeyPair identityKeys,
String localVatID,
- byte[] /*nullOK*/ outgoingSuspendID,
+ byte[] /*nullOK*/ outgoingSuspendID,
String localFlattenedSearchPath,
VatLocationLookup vls)
{
@@ -288,17 +287,17 @@
myIsIncoming = isIncoming;
myIdentityKeys = identityKeys;
myLocalFlattenedSearchPath = localFlattenedSearchPath;
-
+
myVLS = vls;
myLocalVatID = localVatID;
-
+
//Register for the startup message types
try {
myDataPath.registerMsgHandler(Msg.STARTUP, this);
myDataPath.registerMsgHandler(Msg.PROTOCOL_VERSION, this);
myDataPath.registerMsgHandler(Msg.PROTOCOL_ACCEPTED, this);
-
+
if (!myIsIncoming) {
myOutgoingSuspendID = outgoingSuspendID;
myRemoteVatID = remoteVatID;
@@ -323,11 +322,11 @@
}
}
}
-// Protocol methods. These methods are presented more or less in the order
+// Protocol methods. These methods are presented more or less in the order
// they will be executed during the startup protocol. Note that the methods
// used by the initator of the connection are interleaved with the methods
// used by the receiver of the connection.
-//
+//
// The whole process is started in the initator's constructor which sends
// two messages, Msg.PROTOCOL_VERSION, and Msg.STARTUP + TOK_IWANT.
@@ -346,7 +345,7 @@
* remote end.
*/
- void checkProtocolVersion(DataInputStream packetIn, byte[] packet)
+ void checkProtocolVersion(DataInputStream packetIn, byte[] packet)
throws IOException {
hisMessagesToSign.addElement(packet);
Vector versions = new Vector(10); // To save their supported versions in case of error
@@ -394,35 +393,30 @@
os.writeByte(Msg.PROTOCOL_ACCEPTED);
os.writeUTF(protocol);
sendMessageForSignature(baos.toByteArray());
-
+
myEMsgProtocolVersion = protocol;
packetIn.close();
}
-
- // Method from the MsgHandler interface.
+// Method from the MsgHandler interface.
/**
* Process a connection failure
*/
public void connectionDead(DataConnection /*nullOK*/willBeNull, Throwable reason) {
// Everything should be handled by the DataPath
}
-
- /**
- * Perform the first calculation in Diffie Hellman key exchange.
- * <p>
- * This method gets a random x and calculate g**x mod p. Return the value
- * as a String base 10.
- *
- * @return A byte array representing the result of the first Diffie
- * Hellman calculation.
- */
+ /**
+ * Perform the first calculation in Diffie Hellman key exchange.
+ * <p>
+ * This method gets a random x and calculate g**x mod p. Return the value
+ * as a String base 10.
+ *
+ * @return A byte array representing the result of the first Diffie
+ * Hellman calculation.
+ */
+
private byte[] firstDH() {
long startTime = Trace.comm.timing ? MicroTime.queryTimer() : 0;
-
- //MSM: should be passed in entropy as a capability
- ESecureRandom entropy = ESecureRandom.getESecureRandom();
-
- x = new BigInteger(256, entropy);
+ x = new BigInteger(256, ESecureRandom.getESecureRandom());
byte[] ans = g.modPow(x,modulus).toByteArray();
if (Trace.comm.timing && Trace.ON) {
Trace.comm.timingm("FirstDiffieHellman time "
@@ -430,12 +424,11 @@
}
return ans;
}
-
/**
* Format a Msg.STARTUP packet for error messages.
*
- * @param packet the byte array which is the complete packet.
- * @return the packet formated as a string.
+ *@param packet the byte array which is the complete packet.
+ *@return the packet formated as a string.
*/
private String formatStartupPacket(byte[] packet) {
String ret = "";
@@ -457,17 +450,16 @@
}
return ret + "\n" + HexStringUtils.byteArrayToReadableHexString(packet);
}
-
- // Method for use by DataPath
+// Method for use by DataPath
/**
* Return the connection startup state
*
* @return The connection startup state code for debugging purposes.
*/
+
/*package*/ int getState() {
return myState;
}
-
/**
* Process expecting an GIVEINFO <remoteVatID> <remotePath> <hisPublicKey>
* -or-
@@ -484,7 +476,7 @@
* notifing the other end.
*/
private void handleStateIncomingExpectGIVEINFO(byte token,
- DataInputStream packetIn,
+ DataInputStream packetIn,
byte[] packet)
throws IOException
{
@@ -526,16 +518,15 @@
}
} else if (token == TOK_DUP) {
myDataPath.duplicatePath(
- "Incoming crossed connections"
+ "Incoming crossed connections"
+ formatStartupPacket(packet), false);
} else if (token == TOK_NOT_ME) {
startupLocalError("Other end tried to connect to self");
} else {
- startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_GIVEINFO)
+ startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_GIVEINFO)
+ " got " + formatStartupPacket(packet));
}
}
-
/**
* Process expecting a GO <auth suite> <DH parameter>
* -or-
@@ -565,7 +556,7 @@
packetIn.read(publicDH);
byte[] sig = new byte[packetIn.readUnsignedShort()];
packetIn.read(sig);
-
+
byte[] dhparm = firstDH();
myProtocolSuite = protocol;
if (!isSecondDHOK(publicDH, sig, token)) {
@@ -601,11 +592,10 @@
"Incoming crossed connections "
+ formatStartupPacket(packet), true);
} else {
- startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_GO)
+ startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_GO)
+ " got " + formatStartupPacket(packet));
}
}
-
/**
* Process expecting a IWANT <localVatID> message.
*
@@ -622,32 +612,36 @@
hisMessagesToSign.addElement(packet);
if (myStop) {
startupError(TOK_DUP, "Stopped connection");
+ return;
+ }
+ if (token != TOK_IWANT) { /* IWANT <id> */
+ startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_IWANT)
+ + " got " + formatStartupPacket(packet));
return;
- } else if (token == TOK_IWANT) { /* IWANT <id> */
- String[] locations;
- String wantedVatID = packetIn.readUTF();
- if (wantedVatID.equals(myLocalVatID) ||
- wantedVatID.equals(VatIdentity.WHOEVER)) {
- sendIAm();
- myState = ST_INCOMING_EXPECT_GIVEINFO;
- } else if (myVLS != null &&
- (locations = myVLS.getLocations(wantedVatID)).length >= 1) {
+ }
+ String wantedVatID = packetIn.readUTF();
+ if (wantedVatID.equals(myLocalVatID) ||
+ wantedVatID.equals(VatIdentity.WHOEVER))
+ {
+ sendIAm();
+ myState = ST_INCOMING_EXPECT_GIVEINFO;
+ return;
+ }
+ if (myVLS != null) {
+ String[] locations = myVLS.getLocations(wantedVatID);
+ if (locations.length >= 1) {
+ //XXX future bug: only uses the first one
sendTry(locations[0]);
- //XXX locations[any >= 1] not processed
myDataPath.tryNext("VLS lookup completed");
- } else {
- if (Trace.comm.debug && Trace.ON) {
- Trace.comm.debugm("got request for " + wantedVatID
- + " when I am " + myLocalVatID);
- }
- startupError(TOK_NOT_ME, "I don't know " + wantedVatID);
+ return;
}
- } else {
- startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_IWANT)
- + " got " + formatStartupPacket(packet));
}
+ if (Trace.comm.debug && Trace.ON) {
+ Trace.comm.debugm("got request for " + wantedVatID
+ + " when I am " + myLocalVatID);
+ }
+ startupError(TOK_NOT_ME, "I don't know " + wantedVatID);
}
-
/*
* GOTOO
* -or-
@@ -693,11 +687,10 @@
} else if (token == TOK_BYE) {
myDataPath.cantResume(formatStartupPacket(packet));
} else {
- startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_GOTOO)
+ startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_GOTOO)
+ " got " + formatStartupPacket(packet));
}
}
-
/**
* Process expecting an IAM <remoteVatID> <myPublicKey>
* -or-
@@ -717,7 +710,7 @@
* is thrown if this MsgConnection should terminate without
* notifing the other end.
*/
- private void handleStateOutgoingExpectIAM(byte token,
+ private void handleStateOutgoingExpectIAM(byte token,
DataInputStream packetIn, byte[] packet)
throws IOException {
hisMessagesToSign.addElement(packet);
@@ -740,7 +733,7 @@
byte[] hisKey = new byte[packetIn.readUnsignedShort()];
packetIn.readFully(hisKey);
if (!isHisPublicKeyOK(remoteVatID, hisKey, token)) return;
-
+
if (myRemoteVatID.equals(VatIdentity.WHOEVER)) {
myRemoteVatID = remoteVatID;
Object orders = myDataPath.identifyOutgoing(
@@ -775,11 +768,10 @@
"outgoing crossed connections"
+ formatStartupPacket(packet), true);
} else {
- startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_IAM)
+ startupError(TOK_ERR_PROTOCOL, "Expected " + tokName(TOK_IAM)
+ " got " + formatStartupPacket(packet));
}
}
-
/**
* Process expecting a REPLYINFO <remotePath>
* -or-
@@ -812,7 +804,7 @@
startupError(TOK_DUP, "Crossed connections");
return;
}
- //ConstList path = EARL.parseSearchPath(remoteSearchPath);
+ //String[] path = EARL.parseSearchPath(remoteSearchPath);
//myDataPath.extendSearchPath(path);
myState = ST_OUTGOING_EXPECT_GOTOO;
if (null != myOutgoingSuspendID) {
@@ -831,7 +823,7 @@
}
if (protocol.equals("")) {
//No agreement
- startupError(TOK_ERR_PROTOCOL,
+ startupError(TOK_ERR_PROTOCOL,
"Can't agree on an authorization protocol");
return;
}
@@ -848,17 +840,16 @@
}
} else if (token == TOK_DUP) {
myDataPath.duplicatePath(
- "Outgoing crossed connections "
+ "Outgoing crossed connections "
+ formatStartupPacket(packet), true);
return;
} else {
- startupError(TOK_ERR_PROTOCOL, "Expected "
- + tokName(TOK_REPLYINFO) + " got "
+ startupError(TOK_ERR_PROTOCOL, "Expected "
+ + tokName(TOK_REPLYINFO) + " got "
+ formatStartupPacket(packet));
return;
}
}
-
/**
* Decode the line form of his public key and check that it is for his
* vatID.
@@ -891,7 +882,6 @@
}
return true;
}
-
/**
* Perform the second calculation in Diffie Hellman key exchange.
* <p>
@@ -902,14 +892,14 @@
* It then takes the resulting dh secret and calculates values for the
* initial sequence numbers (both send path and receive path).
*
- * @param publiddh is a byte array containing the far end's first Diffie
+ * @param publiddh is a byte array containing the far end's first Diffie
* Hellman calculation.
- * @param sig is a byte array containing the far end's DSS signature on
+ * @param sig is a byte array containing the far end's DSS signature on
* the startup protocol.
* @param token The startup protocol token being processed. (For determining
* whether we are the initator or receipent and error reporting.)
*
- * @return is true if the connection attempt should continue,
+ * @return is true if the connection attempt should continue,
* false otherwise.
*/
@@ -948,13 +938,12 @@
myDataPath.setAuthorizationSecrets(dhSecret, sendIV, recvIV);
return true;
}
-
/**
* Check the signature on the data received.
*
* @param data is the data to check.
* @param sig is the signature.
- * @param token is the startup protocol token being processed for error
+ * @param token is the startup protocol token being processed for error
* reporting.
*
* @return is true if the signature is good. False for a bunch of "can't
@@ -962,6 +951,7 @@
* and things like invalid or no public key from the other end, or invalid
* signature.
*/
+
private boolean isSigGood(byte