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 *** *** 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 ourIdentityPrivKey = crypto_storage.getIdentityPrivKey();
var sharedSecret; var sharedSecret;
@ -545,21 +545,30 @@ var crypto_tests = {};
sharedSecret = getString(ecRes); sharedSecret = getString(ecRes);
function finishInit() { function finishInit() {
ECDHE(theirEphemeralPubKey, ourEphemeralPrivKey, function(ecRes) { ECDHE(theirEphemeralPubKey, ourEphemeralKey.privKey, function(ecRes) {
sharedSecret += getString(ecRes); sharedSecret += getString(ecRes);
var masterKey = HKDF(sharedSecret, '', "WhisperText"); 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) { if (isInitiator) {
ECDHE(theirIdentityPubKey, ourEphemeralPrivKey, function(ecRes) { ECDHE(theirIdentityPubKey, ourEphemeralKey.privKey, function(ecRes) {
sharedSecret = sharedSecret + getString(ecRes); sharedSecret = sharedSecret + getString(ecRes);
finishInit(); finishInit();
}); });
} else { } else {
ECDHE(theirIdentityPubKey, ourEphemeralPrivKey, function(ecRes) { ECDHE(theirIdentityPubKey, ourEphemeralKey.privKey, function(ecRes) {
sharedSecret = getString(ecRes) + sharedSecret; sharedSecret = getString(ecRes) + sharedSecret;
finishInit(); finishInit();
}); });
@ -574,16 +583,7 @@ var crypto_tests = {};
if (preKeyPair === undefined) if (preKeyPair === undefined)
throw "Missing preKey for PreKeyWhisperMessage"; throw "Missing preKey for PreKeyWhisperMessage";
initSession(false, message.identityKey, preKeyPair.privKey, message.baseKey, function(firstRatchet) { initSession(false, preKeyPair, encodedNumber, message.identityKey, message.baseKey, function() {
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);
callback(); 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 // returns decrypted protobuf
var decryptWhisperMessage = function(encodedNumber, messageBytes, callback) { var decryptWhisperMessage = function(encodedNumber, messageBytes, callback) {
var session = crypto_storage.getSession(encodedNumber); var session = crypto_storage.getSession(encodedNumber);
@ -715,9 +707,34 @@ var crypto_tests = {};
} }
} }
crypto.encryptMessageFor = function(deviceObject, message) { // callback(encoded [PreKey]WhisperMessage)
return message + " encrypted to " + deviceObject.encodedNumber + " with relay " + deviceObject.relay + crypto.encryptMessageFor = function(deviceObject, pushMessageContent, callback) {
" with identityKey " + deviceObject.identityKey + " and public key " + deviceObject.publicKey; //TODO 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; var GENERATE_KEYS_KEYS_GENERATED = 100;

View file

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

View file

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

View file

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