|
16 | 16 | */
|
17 | 17 |
|
18 | 18 | import SessionFactory from "./SessionFactory";
|
| 19 | +import SessionCipher from "./SessionCipher"; |
19 | 20 | import {InvalidMessageException} from "./Exceptions";
|
20 | 21 | import Store from "./Store";
|
21 | 22 | import Crypto from "./Crypto";
|
22 | 23 | import co from "co";
|
| 24 | +import axolotlCrypto from "axolotl-crypto"; |
23 | 25 |
|
24 | 26 | /**
|
25 | 27 | * A public/private key pair
|
@@ -90,6 +92,7 @@ function Axolotl(crypto, store) {
|
90 | 92 | var wrappedCrypto = new Crypto(crypto);
|
91 | 93 |
|
92 | 94 | var sessionFactory = new SessionFactory(wrappedCrypto, wrappedStore);
|
| 95 | + var sessionCipher = new SessionCipher(wrappedCrypto); |
93 | 96 |
|
94 | 97 | /**
|
95 | 98 | * Generate an identity key pair. Clients should only do this once, at install time.
|
@@ -176,67 +179,67 @@ function Axolotl(crypto, store) {
|
176 | 179 | });
|
177 | 180 |
|
178 | 181 | /**
|
179 |
| - * Encrypt a message using the session associated with toIdentity. If no such session exists, it will be created. |
| 182 | + * @typedef {Object} PreKeyBundle |
| 183 | + * @property {ArrayBuffer} identityKey - The remote identity's public key. |
| 184 | + * @property {Number} preKeyId - The identifier of the pre-key included in this bundle. |
| 185 | + * @property {ArrayBuffer} preKey - The public half of the pre-key. |
| 186 | + * @property {Number} signedPreKeyId - The identifier of the signed pre-key included in this bundle. |
| 187 | + * @property {ArrayBuffer} signedPreKey - The public half of the signed pre-key. |
| 188 | + * @property {ArrayBuffer} signedPreKeySignature - The signature associated with the `signedPreKey` |
| 189 | + */ |
| 190 | + |
| 191 | + /** |
| 192 | + * Create a session from a pre-key bundle, probably retrieved from a server. |
| 193 | + * @method |
| 194 | + * @type {PreKeyBundle} a pre-key bundle |
| 195 | + * @returns {Promise.<Session, Error>} |
| 196 | + */ |
| 197 | + this.generateSignedPreKeyBundle = sessionFactory.createSessionFromPreKeyBundle; |
| 198 | + |
| 199 | + /** |
| 200 | + * Create a session from a PreKeyWhisperMessage. |
| 201 | + * @method |
| 202 | + * @type {Session} session - a session, if one exists, or null otherwise. |
| 203 | + * @type {ArrayBuffer} preKeyWhisperMessageBytes - the bytes of a PreKeyWhisperMessage. |
| 204 | + * @returns {Promise.<Session, Error>} |
| 205 | + */ |
| 206 | + this.createSessionFromPreKeyWhisperMessage = sessionFactory.createSessionFromPreKeyWhisperMessage; |
| 207 | + |
| 208 | + /** |
| 209 | + * Encrypt a message using the session. |
180 | 210 | * <p>
|
181 |
| - * It is safe to call this method multiple times without waiting for the returned promises to be resolved. In this |
182 |
| - * case, operations may be queued to ensure sessions are in the correct state for each encryption. |
| 211 | + * If this method succeeds, the passed in session should be destroyed. This method must never be called with |
| 212 | + * that session again. |
183 | 213 | *
|
184 | 214 | * @method
|
185 |
| - * @param {Identity} toIdentity - the identity of the intended recipient |
186 |
| - * @param {ArrayBuffer} message - the message bytes to be encrypted |
187 |
| - * @return {Promise.<ArrayBuffer, (InvalidKeyException|UntrustedIdentityException)>} encrypted message bytes if |
188 |
| - * fulfilled. May be rejected if a fresh session is required and the pre key bundle returned from the server is |
189 |
| - * invalid. |
| 215 | + * @param {Session} session |
| 216 | + * @param {ArrayBuffer} message - the message bytes to be encrypted (optionally padded) |
| 217 | + * @return {Promise.<Object, Error>} an object containing the encrypted message bytes as well as a new session |
190 | 218 | */
|
191 |
| - this.encryptMessage = co.wrap(function*(toIdentity, message) { |
192 |
| - var session; |
193 |
| - var hasSession = yield sessionFactory.hasSessionForIdentity(toIdentity); |
194 |
| - if (hasSession) { |
195 |
| - session = yield sessionFactory.getSessionForIdentity(toIdentity); |
196 |
| - } else { |
197 |
| - var preKeyBundle = yield wrappedStore.getRemotePreKeyBundle(toIdentity); |
198 |
| - session = yield sessionFactory.createSessionFromPreKeyBundle(toIdentity, preKeyBundle); |
199 |
| - } |
200 |
| - return yield session.encryptMessage(message); |
201 |
| - }); |
| 219 | + this.encryptMessage = sessionCipher.encryptMessage; |
202 | 220 |
|
203 | 221 | /**
|
204 |
| - * Decrypt a WhisperMessage using the session associated with fromIdentity. |
| 222 | + * Decrypt a WhisperMessage using session. |
205 | 223 | * <p>
|
206 |
| - * It is safe to call this method multiple times without waiting for the returned promises to be resolved. In this |
207 |
| - * case, operations may be queued to ensure sessions are in the correct state for each decryption. |
| 224 | + * If this method succeeds, the passed in session should be destroyed. This method must never be called with |
| 225 | + * that session again. |
208 | 226 | *
|
209 | 227 | * @method
|
210 |
| - * @param {Identity} fromIdentity - the identity of the intended recipient |
211 |
| - * @param {ArrayBuffer} message - the encrypted message bytes |
212 |
| - * @return {Promise.<ArrayBuffer, (InvalidMessageException|DuplicateMessageException)>} decrypted message bytes if |
213 |
| - * fulfilled. May be rejected if a session does not exist, the message is invalid or has been decrypted before. |
| 228 | + * @param {Session} session |
| 229 | + * @param {ArrayBuffer} whisperMessageBytes - the encrypted message bytes |
| 230 | + * @returns {Promise.<Object, InvalidMessageException>} an object containing the decrypted message and a new session |
214 | 231 | */
|
215 |
| - this.decryptWhisperMessage = co.wrap(function*(fromIdentity, message) { |
216 |
| - var hasSession = yield sessionFactory.hasSessionForIdentity(fromIdentity); |
217 |
| - if (!hasSession) { |
218 |
| - throw new InvalidMessageException("No session for message"); |
219 |
| - } |
220 |
| - var session = yield sessionFactory.getSessionForIdentity(fromIdentity); |
221 |
| - return yield session.decryptWhisperMessage(message); |
222 |
| - }); |
| 232 | + this.decryptWhisperMessage = sessionCipher.decryptWhisperMessage; |
223 | 233 |
|
224 | 234 | /**
|
225 |
| - * Decrypt a PreKeyWhisperMessage using the session associated with fromIdentity. |
226 |
| - * <p> |
227 |
| - * It is safe to call this method multiple times without waiting for the returned promises to be resolved. In this |
228 |
| - * case, operations may be queued to ensure sessions are in the correct state for each decryption. |
| 235 | + * Unwrap the WhisperMessage from a PreKeyWhisperMessage and attempt to decrypt it using session. |
229 | 236 | *
|
230 | 237 | * @method
|
231 |
| - * @param {Identity} fromIdentity - the identity of the intended recipient |
232 |
| - * @param {ArrayBuffer} message - the encrypted message bytes |
233 |
| - * @return {Promise.<ArrayBuffer, (InvalidMessageException|DuplicateMessageException)>} decrypted message bytes if |
234 |
| - * fulfilled. May be rejected if the message is invalid or has been decrypted before. |
| 238 | + * @param {Session} session |
| 239 | + * @param {ArrayBuffer} preKeyWhisperMessageBytes - the encrypted message bytes |
| 240 | + * @returns {Promise.<Object, InvalidMessageException>} an object containing the decrypted message and a new session |
235 | 241 | */
|
236 |
| - this.decryptPreKeyWhisperMessage = co.wrap(function*(fromIdentity, message) { |
237 |
| - var session = yield sessionFactory.createSessionFromPreKeyWhisperMessage(fromIdentity, message); |
238 |
| - return yield session.decryptPreKeyWhisperMessage(message); |
239 |
| - }); |
| 242 | + this.decryptPreKeyWhisperMessage = sessionCipher.decryptPreKeyWhisperMessage; |
240 | 243 |
|
241 | 244 | Object.freeze(self);
|
242 | 245 | }
|
|
0 commit comments