Genericify initSession (and break it for alice)
This commit is contained in:
parent
611d5329d3
commit
fe570c754a
4 changed files with 50 additions and 33 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue