// Program to re-encrypt data written from Java to verify that round-tripping works.

var fs = require('fs');

var keyczar = require('./keyczar');

function readFile(path) {
    return fs.readFileSync(path, {encoding: 'utf-8'});
}

function writeFile(path, contents) {
    return fs.writeFileSync(path, contents, {encoding: 'utf-8'});
}

function encrypt(keyPath, message, outputPath) {
    var key = keyczar.fromJson(readFile(keyPath));
    var encrypted = key.encrypt(message);
    writeFile(outputPath, encrypted);
}

function decrypt(keyPath, encryptedPath, expectedMessage, expectedType) {
    var key = keyczar.fromJson(readFile(keyPath));
    if (key.metadata.type != expectedType) {
        throw new Error('Unexpected key type: ' + key.metadata.type);
    }
    var encrypted = readFile(encryptedPath);
    var decrypted = key.decrypt(encrypted);
    if (expectedMessage !== null) {
        if (decrypted != expectedMessage) {
            process.stderr.write(encryptedPath + ' did not decrypt correctly\n');
            process.exit(1);
        } else {
            console.log(encryptedPath + ' decrypts successfully');
        }
    }
    return decrypted;
}

if (process.argv.length != 4 && process.argv.length != 5) {
    process.stderr.write('node roundtripper.js (mode) (in/out directory) [message to en/decrypt]\n');
    process.exit(1);
}

var mode = process.argv[2];
var dirpath = process.argv[3];
var message = 'Hello this is a longish message from Javascript';
if (process.argv.length == 5) {
    message = process.argv[4];
}

if (mode == 'encrypt') {
    console.log('generating private key ...');
    var privateKey = keyczar.create(keyczar.TYPE_RSA_PRIVATE);
    writeFile(dirpath + '/privatekey.json', privateKey.toJson());

    var publicKey = privateKey.exportPublicKey();
    writeFile(dirpath + '/publickey.json', publicKey.toJson());

    console.log('encrypting message length', message.length);
    encrypt(dirpath + '/publickey.json', message, dirpath + '/publickey_encrypted');

    console.log('generating AES key ...');
    var symmetric = keyczar.create(keyczar.TYPE_AES);
    writeFile(dirpath + '/symmetric.json', symmetric.toJson());
    encrypt(dirpath + '/symmetric.json', message, dirpath + '/symmetric_encrypted');
} else if (mode == 'decrypt') {
    console.log('asymmetric:');
    decrypt(dirpath + '/privatekey.json', dirpath + '/publickey_reencrypted', message, keyczar.TYPE_RSA_PRIVATE);
    console.log('symmetric:');
    decrypt(dirpath + '/symmetric.json', dirpath + '/symmetric_reencrypted', message, keyczar.TYPE_AES);
} else if (mode == 'roundtrip') {
    var decrypted = decrypt(dirpath + '/privatekey.json', dirpath + '/publickey_encrypted', null, keyczar.TYPE_RSA_PRIVATE);
    encrypt(dirpath + '/publickey.json', decrypted, dirpath + '/publickey_reencrypted');

    decrypted = decrypt(dirpath + '/symmetric.json', dirpath + '/symmetric_encrypted', null, keyczar.TYPE_AES);
    encrypt(dirpath + '/symmetric.json', decrypted, dirpath + '/symmetric_reencrypted');

    console.log('JS re-encrypted to', dirpath);
} else {
    process.stderr.write('mode must be encrypt, decrypt, or roundtrip\n');
    process.exit(1);
}

@@ -1161,24 +1161,777 @@
 crypted;%0A%7D%0A%0A
+function makeLonger(input) %7B%0A    while (input.length %3C 1000) %7B%0A        input += input;%0A    %7D%0A    return input;%0A%7D%0A%0Afunction encryptSession(keyPath, message, outputPath) %7B%0A    var key = keyczar.fromJson(readFile(keyPath));%0A    var encrypted = keyczar.encryptWithSession(key, message);%0A    writeFile(outputPath, encrypted);%0A%7D%0A%0Afunction decryptSession(keyPath, encryptedPath, expectedMessage) %7B%0A    var key = keyczar.fromJson(readFile(keyPath));%0A    var encrypted = readFile(encryptedPath);%0A    var decrypted = keyczar.decryptWithSession(key, encrypted);%0A    if (expectedMessage !== null && decrypted != expectedMessage) %7B%0A        process.stderr.write(encryptedPath + ' did not decrypt correctly%5Cn');%0A        process.exit(1);%0A    %7D%0A    return decrypted;%0A%7D%0A%0A
 if (process.
@@ -3004,16 +3004,119 @@
 ypted');
+%0A%0A    encryptSession(dirpath + '/publickey.json', makeLonger(message), dirpath + '/publickey_session');
 %0A%7D else 
@@ -3421,16 +3421,132 @@
 PE_AES);
+%0A%0A    decryptSession(dirpath + '/privatekey.json', dirpath + '/publickey_session_reencrypted', makeLonger(message));
 %0A%7D else 
@@ -3895,24 +3895,24 @@
 .TYPE_AES);%0A
-
     encrypt(
@@ -3981,32 +3981,237 @@
 reencrypted');%0A%0A
+    decrypted = decryptSession(dirpath + '/privatekey.json', dirpath + '/publickey_session', null);%0A    encryptSession(dirpath + '/publickey.json', decrypted, dirpath + '/publickey_session_reencrypted');%0A%0A
     console.log(

Test the session decryption/encryption routines.