Genericify initSession (and break it for alice)

This commit is contained in:
Matt Corallo 2014-03-08 19:08:40 -04:00
parent 611d5329d3
commit fe570c754a
4 changed files with 50 additions and 33 deletions

View file

@ -537,7 +537,7 @@ var crypto_tests = {};
/******************************
*** Ratchet implementation ***
******************************/
var initSession = function(isInitiator, theirIdentityPubKey, ourEphemeralPrivKey, theirEphemeralPubKey, callback) {
var initSession = function(isInitiator, ourEphemeralKey, encodedNumber, theirIdentityPubKey, theirEphemeralPubKey, callback) {
var ourIdentityPrivKey = crypto_storage.getIdentityPrivKey();
var sharedSecret;
@ -545,21 +545,30 @@ var crypto_tests = {};
sharedSecret = getString(ecRes);
function finishInit() {
ECDHE(theirEphemeralPubKey, ourEphemeralPrivKey, function(ecRes) {
ECDHE(theirEphemeralPubKey, ourEphemeralKey.privKey, function(ecRes) {
sharedSecret += getString(ecRes);
var masterKey = HKDF(sharedSecret, '', "WhisperText");
callback({ rootKey: masterKey[0], chainKey: masterKey[1] });
var session = {currentRatchet: { rootKey: masterKey[0], ephemeralKeyPair: ourEphemeralKey,
lastRemoteEphemeralKey: theirEphemeralPubKey },
oldRatchetList: []
};
session[getString(ourEphemeralKey.pubKey)] = { messageKeys: {}, chainKey: { counter: -1, key: masterKey[1] } };
// This isnt an actual ratchet, its just here to make maybeStepRatchet work
session[getString(theirEphemeralPubKey)] = { messageKeys: {}, chainKey: { counter: 0xffffffff, key: '' } };
crypto_storage.saveSession(encodedNumber, session);
callback();
});
}
if (isInitiator) {
ECDHE(theirIdentityPubKey, ourEphemeralPrivKey, function(ecRes) {
ECDHE(theirIdentityPubKey, ourEphemeralKey.privKey, function(ecRes) {
sharedSecret = sharedSecret + getString(ecRes);
finishInit();
});
} else {
ECDHE(theirIdentityPubKey, ourEphemeralPrivKey, function(ecRes) {
ECDHE(theirIdentityPubKey, ourEphemeralKey.privKey, function(ecRes) {
sharedSecret = getString(ecRes) + sharedSecret;
finishInit();
});
@ -574,16 +583,7 @@ var crypto_tests = {};
if (preKeyPair === undefined)
throw "Missing preKey for PreKeyWhisperMessage";
initSession(false, message.identityKey, preKeyPair.privKey, message.baseKey, function(firstRatchet) {
var session = {currentRatchet: { rootKey: firstRatchet.rootKey, ephemeralKeyPair: preKeyPair,
lastRemoteEphemeralKey: message.baseKey },
oldRatchetList: []
};
session[getString(preKeyPair.pubKey)] = { messageKeys: {}, chainKey: { counter: -1, key: firstRatchet.chainKey } };
// This isnt an actual ratchet, its just here to make maybeStepRatchet work
session[getString(message.baseKey)] = { messageKeys: {}, chainKey: { counter: 0xffffffff, key: '' } };
crypto_storage.saveSession(encodedNumber, session);
initSession(false, preKeyPair, encodedNumber, message.identityKey, message.baseKey, function() {
callback();
});
}
@ -633,14 +633,6 @@ var crypto_tests = {};
});
}
var doDecryptWhisperMessage = function(ciphertext, mac, messageKey, counter) {
//TODO keys swapped?
var keys = HKDF(messageKey, '', "WhisperMessageKeys");
verifyMACWithVersionByte(ciphertext, keys[0], mac);
return AES_CTR_NOPADDING(keys[1], CTR = counter, ciphertext);
}
// returns decrypted protobuf
var decryptWhisperMessage = function(encodedNumber, messageBytes, callback) {
var session = crypto_storage.getSession(encodedNumber);
@ -715,9 +707,34 @@ var crypto_tests = {};
}
}
crypto.encryptMessageFor = function(deviceObject, message) {
return message + " encrypted to " + deviceObject.encodedNumber + " with relay " + deviceObject.relay +
" with identityKey " + deviceObject.identityKey + " and public key " + deviceObject.publicKey; //TODO
// callback(encoded [PreKey]WhisperMessage)
crypto.encryptMessageFor = function(deviceObject, pushMessageContent, callback) {
var session = crypto_storage.getSession(deviceObject.encodedNumber);
var doEncryptPushMessageContent = function(callback) {
var msg = new WhisperMessageProtobuf();
var plaintext = pushMessageContent.encode();
//TODO
msg.ciphertext = plaintext;//TODO: WAT?
callback(msg.encode());
}
if (session === undefined) {
var preKeyMsg = new PreKeyWhisperMessageProtobuf();
preKeyMsg.identityKey = getString(crypto_storage.getStoredPubKey("identityKey"));
createNewKeyPair(function(baseKey) {
preKeyMsg.baseKey = getString(baseKey.pubKey);
preKeyMsg.preKeyId = preKey.keyId;
initSession();//TODO
doEncryptPushMessageContent(function(message) {
preKeyMsg.message = getString(message);
callback(getString(preKeyMsg.encode()));
});
});
} else
doEncryptPushMessageContent(function(message) {
callback(getString(message));
});
}
var GENERATE_KEYS_KEYS_GENERATED = 100;

View file

@ -221,12 +221,12 @@ encryptedMessage: hexToArrayBuffer("415733486e6d3165754275487778594d2f4b744a556e
postNaclMessage({command: "privToPub", priv: v.bobPre1}, function(message) {
storage.putEncrypted("25519KeypreKey1", { pubKey: message.res, privKey: v.bobPre1 });
postNaclMessage({command: "privToPub", priv: v.bobLastResort}, function(message) {
storage.putEncrypted("25519KeypreKey16777215", { pubKey: message.res, privKey: v.bobLastResort });
storage.putEncrypted("signaling_key", v.sessionKey);
var aliceToBob = crypto.decryptWebsocketMessage(v.encryptedMessage);
if (getString(aliceToBob) != getString(v.aliceToBob))
callback(false);
storage.putEncrypted("25519KeypreKey16777215", { pubKey: message.res, privKey: v.bobLastResort });
var b64 = base64EncArr(new Uint8Array(v.aliceToBob));
var b64 = base64EncArr(new Uint8Array(toArrayBuffer(aliceToBob)));
crypto.handleIncomingPushMessageProto(IncomingPushMessageProtobuf.decode(b64), function(decrypted_message) {
callback(decrypted_message.body == "Hi Bob!" && decrypted_message.attachments.length == 0);
});
@ -251,5 +251,5 @@ encryptedMessage: hexToArrayBuffer("415733486e6d3165754275487778594d2f4b744a556e
startNextExclusiveTest();
localStorage.clear();
}, 250);
}, 500);
});

View file

@ -9,7 +9,7 @@ message IncomingPushMessageSignal {
optional string relay = 3;
repeated string destinations = 4;
optional uint64 timestamp = 5;
optional bytes message = 6; // Contains an encrypted PushMessageContent
optional bytes message = 6; // Contains an encrypted [PreKey]WhisperMessage
}
message PushMessageContent {
@ -22,4 +22,4 @@ message PushMessageContent {
}
repeated AttachmentPointer attachments = 2;
}
}

View file

@ -7,7 +7,7 @@ message WhisperMessage {
optional bytes ephemeralKey = 1;
optional uint32 counter = 2;
optional uint32 previousCounter = 3;
optional bytes ciphertext = 4;
optional bytes ciphertext = 4; // PushMessageContent
}
message PreKeyWhisperMessage {