Code with Finding: |
class SocialNetworkServer {
/** Gets a user inputted password and tries to get the
* keys from the db
*/
private static void getPassword() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] input = new char[22]; //password is at most 20 characters.
boolean valid = false;
int numRetries = 5;
Connection conn = DBManager.getConnection();
String keystring = DatabaseDBA.fetchKeys(conn);
DBManager.closeConnection(conn);
if (keystring == null) {
System.err.println("Could not fetch initialization string from Database");
System.err.println("Make sure the database is configured correctly.");
System.exit(1);
}
String[] keys = keystring.split(";");
System.out.println("Input passphrase");
while(!valid && numRetries > 0) {
System.out.print(">> ");
EraserThread et = null;
if (!DEBUG) {
et = new EraserThread("");
Thread mask = new Thread(et);
mask.start();
}
int length = br.read(input);
if (br.ready()) { //there is leftover data.
System.out.println("Invalid passphrase. Try again");
numRetries--;
continue;
}
if (!DEBUG) {
et.stopMasking();
}
char[] pwd = Arrays.copyOf(input, length - 2); //get rid of the carriage return
//There are two keys.
for (int i = 0; i < 2; i++) {
//get the salt and iteration count for the key
String[] key = keys[i].split(" ");
int index = Integer.parseInt(key[0]);
byte[] indexArr = ByteBuffer.allocate(4).putInt(index).array();
byte[] salt = CryptoUtil.decode(key[INDEX_SALT]);
int iterations = Integer.parseInt(key[INDEX_ITERATIONS]);
byte[] iterationsArr = ByteBuffer.allocate(4).putInt(iterations).array();
byte[] encKey = CryptoUtil.decode(key[INDEX_ENCKEY]);
byte[] checksum = CryptoUtil.decode(key[INDEX_CHECKSUM]);
byte[] decryptedKey = PasswordBasedEncryption.decrypt(encKey, pwd, salt, iterations);
if (decryptedKey == null) {
break;
}
//checksum is made up of (index, salt, iterations, decryptedKey)
byte[] toBeChecksummed = new byte[indexArr.length + salt.length + iterationsArr.length + decryptedKey.length];
System.arraycopy(indexArr, 0, toBeChecksummed, 0, indexArr.length);
System.arraycopy(salt, 0, toBeChecksummed, indexArr.length, salt.length);
System.arraycopy(iterationsArr, 0, toBeChecksummed, indexArr.length + salt.length, iterationsArr.length);
System.arraycopy(decryptedKey, 0, toBeChecksummed, indexArr.length + salt.length + iterationsArr.length, decryptedKey.length);
if (Arrays.equals(checksum, Hash.generateChecksum(toBeChecksummed))) { //it is the correct key
if (i == 0) { //first key is the private
privk = PublicKeyCryptoServer.serverPrivateKeyRSA(new BigInteger(decryptedKey));
if (privk == null) { /*THIS SHOULD NOT HAPPEN*/
//(checksum was correct, but the key was incorrect!)
System.out.println("Something really bad happened.");
Arrays.fill(decryptedKey, (byte)0x00);
Arrays.fill(toBeChecksummed, (byte)0x00);
break;
}
}
else {
if (!SharedKeyCrypto.initSharedKeyCrypto(decryptedKey)) {
/*THIS SHOULD NOT HAPPEN*/
System.out.println("Something really bad happened.");
Arrays.fill(decryptedKey, (byte)0x00);
Arrays.fill(toBeChecksummed, (byte)0x00);
break;
}
valid = true;
}
//these arrays contain the decrypted key.
Arrays.fill(decryptedKey, (byte)0x00);
Arrays.fill(toBeChecksummed, (byte)0x00);
}
else {
break;
}
}
numRetries--;
}
if (!valid) {
System.err.println("Too many retries");
System.err.println("Shutting down the server.");
System.exit(1);
}
else {
System.out.println("Server successfully started");
}
}
}
|