|  |  |  | /* global libsignal, textsecure */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* eslint-disable more/no-then */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // eslint-disable-next-line func-names
 | 
					
						
							|  |  |  | (function() { | 
					
						
							|  |  |  |   function ProvisioningCipher() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ProvisioningCipher.prototype = { | 
					
						
							|  |  |  |     decrypt(provisionEnvelope) { | 
					
						
							|  |  |  |       const masterEphemeral = provisionEnvelope.publicKey.toArrayBuffer(); | 
					
						
							|  |  |  |       const message = provisionEnvelope.body.toArrayBuffer(); | 
					
						
							|  |  |  |       if (new Uint8Array(message)[0] !== 1) { | 
					
						
							|  |  |  |         throw new Error('Bad version number on ProvisioningMessage'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const iv = message.slice(1, 16 + 1); | 
					
						
							|  |  |  |       const mac = message.slice(message.byteLength - 32, message.byteLength); | 
					
						
							|  |  |  |       const ivAndCiphertext = message.slice(0, message.byteLength - 32); | 
					
						
							|  |  |  |       const ciphertext = message.slice(16 + 1, message.byteLength - 32); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return libsignal.Curve.async | 
					
						
							|  |  |  |         .calculateAgreement(masterEphemeral, this.keyPair.privKey) | 
					
						
							|  |  |  |         .then(ecRes => | 
					
						
							|  |  |  |           libsignal.HKDF.deriveSecrets( | 
					
						
							|  |  |  |             ecRes, | 
					
						
							|  |  |  |             new ArrayBuffer(32), | 
					
						
							|  |  |  |             'TextSecure Provisioning Message' | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         .then(keys => | 
					
						
							|  |  |  |           libsignal.crypto | 
					
						
							|  |  |  |             .verifyMAC(ivAndCiphertext, keys[1], mac, 32) | 
					
						
							|  |  |  |             .then(() => libsignal.crypto.decrypt(keys[0], ciphertext, iv)) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         .then(plaintext => { | 
					
						
							|  |  |  |           const provisionMessage = textsecure.protobuf.ProvisionMessage.decode( | 
					
						
							|  |  |  |             plaintext | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |           const privKey = provisionMessage.identityKeyPrivate.toArrayBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return libsignal.Curve.async.createKeyPair(privKey).then(keyPair => { | 
					
						
							|  |  |  |             const ret = { | 
					
						
							|  |  |  |               identityKeyPair: keyPair, | 
					
						
							|  |  |  |               number: provisionMessage.number, | 
					
						
							|  |  |  |               provisioningCode: provisionMessage.provisioningCode, | 
					
						
							|  |  |  |               userAgent: provisionMessage.userAgent, | 
					
						
							|  |  |  |               readReceipts: provisionMessage.readReceipts, | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |             if (provisionMessage.profileKey) { | 
					
						
							|  |  |  |               ret.profileKey = provisionMessage.profileKey.toArrayBuffer(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return ret; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     getPublicKey() { | 
					
						
							|  |  |  |       return Promise.resolve() | 
					
						
							|  |  |  |         .then(() => { | 
					
						
							|  |  |  |           if (!this.keyPair) { | 
					
						
							|  |  |  |             return libsignal.Curve.async.generateKeyPair().then(keyPair => { | 
					
						
							|  |  |  |               this.keyPair = keyPair; | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return null; | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .then(() => this.keyPair.pubKey); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   libsignal.ProvisioningCipher = function ProvisioningCipherWrapper() { | 
					
						
							|  |  |  |     const cipher = new ProvisioningCipher(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.decrypt = cipher.decrypt.bind(cipher); | 
					
						
							|  |  |  |     this.getPublicKey = cipher.getPublicKey.bind(cipher); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | })(); |