@ -113,6 +113,8 @@
} ) ( ) ;
; ( function ( ) {
var Internal = { } ;
window . libsignal = { } ;
// The Module object: Our interface to the outside world. We import
// and export values on it, and do the work to get that through
// closure compiler if necessary. There are various ways Module can be used:
@ -25262,7 +25264,7 @@ run();
* /
var Internal = Internal || { } ;
Internal . curve25519 = function ( ) {
( function ( ) {
'use strict' ;
// Insert some bytes into the emscripten memory and return a pointer
@ -25280,38 +25282,35 @@ Internal.curve25519 = function() {
var basepoint = new Uint8Array ( 32 ) ;
basepoint [ 0 ] = 9 ;
return {
Internal . curve25519 = {
keyPair : function ( privKey ) {
return new Promise ( function ( resolve ) {
var priv = new Uint8Array ( privKey ) ;
priv [ 0 ] &= 248 ;
priv [ 31 ] &= 127 ;
priv [ 31 ] |= 64
var priv = new Uint8Array ( privKey ) ;
priv [ 0 ] &= 248 ;
priv [ 31 ] &= 127 ;
priv [ 31 ] |= 64
// Where to store the result
var publicKey _ptr = Module . _malloc ( 32 ) ;
// Get a pointer to the private key
var privateKey _ptr = _allocate ( priv ) ;
// Where to store the result
var publicKey _ptr = Module . _malloc ( 32 ) ;
// The basepoint for generating public keys
var basepoint _ptr = _allocate ( basepoint ) ;
// Get a pointer to the private key
var privateKey _ptr = _allocate ( priv ) ;
// The return value is just 0, the operation is done in place
var err = Module . _curve25519 _donna ( publicKey _ptr ,
privateKey _ptr ,
basepoint _ptr ) ;
// The basepoint for generating public keys
var basepoint _ptr = _allocate ( basepoint ) ;
var res = new Uint8Array ( 32 ) ;
_readBytes ( publicKey _ptr , 32 , res ) ;
// The return value is just 0, the operation is done in place
var err = Module . _curve25519 _donna ( publicKey _ptr ,
privateKey _ptr ,
basepoint _ptr ) ;
Module . _free ( publicKey _ptr ) ;
Module . _free ( privateKey _ptr ) ;
Module . _free ( basepoint _ptr ) ;
var res = new Uint8Array ( 32 ) ;
_readBytes ( publicKey _ptr , 32 , res ) ;
resolve ( { pubKey : res . buffer , privKey : privKey } ) ;
} ) ;
Module . _free ( publicKey _ptr ) ;
Module . _free ( privateKey _ptr ) ;
Module . _free ( basepoint _ptr ) ;
return { pubKey : res . buffer , privKey : priv . buffer } ;
} ,
sharedSecret : function ( pubKey , privKey ) {
// Where to store the result
@ -25336,7 +25335,7 @@ Internal.curve25519 = function() {
Module . _free ( privateKey _ptr ) ;
Module . _free ( basepoint _ptr ) ;
return Promise . resolve ( res . buffer ) ;
return res . buffer ;
} ,
sign : function ( privKey , message ) {
// Where to store the result
@ -25360,7 +25359,7 @@ Internal.curve25519 = function() {
Module . _free ( privateKey _ptr ) ;
Module . _free ( message _ptr ) ;
return Promise . resolve ( res . buffer ) ;
return res . buffer ;
} ,
verify : function ( pubKey , message , sig ) {
// Get a pointer to their public key
@ -25381,36 +25380,55 @@ Internal.curve25519 = function() {
Module . _free ( signature _ptr ) ;
Module . _free ( message _ptr ) ;
return res !== 0 ;
}
} ;
Internal . curve25519 _async = {
keyPair : function ( privKey ) {
return new Promise ( function ( resolve ) {
resolve ( Internal . curve25519 . keyPair ( privKey ) ) ;
} ) ;
} ,
sharedSecret : function ( pubKey , privKey ) {
return new Promise ( function ( resolve ) {
resolve ( Internal . curve25519 . sharedSecret ( pubKey , privKey ) ) ;
} ) ;
} ,
sign : function ( privKey , message ) {
return new Promise ( function ( resolve ) {
resolve ( Internal . curve25519 . sign ( privKey , message ) ) ;
} ) ;
} ,
verify : function ( pubKey , message , sig ) {
return new Promise ( function ( resolve , reject ) {
if ( res !== 0 ) {
if ( Internal. curve25519 . verify ( pubKey , message , sig ) ) {
reject ( new Error ( "Invalid signature" ) ) ;
} else {
resolve ( ) ;
}
} ) ;
}
} ,
} ;
} ( ) ;
} ) ( ) ;
; ( function ( ) {
'use strict' ;
window . libsignal = window . libsignal || { } ;
var Internal = Internal || { } ;
// I am the...workee?
var origCurve25519 = Internal . curve25519 ;
var origCurve25519 = Internal . curve25519 _async ;
Internal . startWorker = function ( url ) {
Internal . stopWorker ( ) ; // there can be only one
Internal . curve25519 = new Curve25519Worker ( url ) ;
Internal . curve25519 _async = new Curve25519Worker ( url ) ;
} ;
Internal . stopWorker = function ( ) {
if ( Internal . curve25519 instanceof Curve25519Worker ) {
var worker = Internal . curve25519 . worker ;
Internal . curve25519 = origCurve25519 ;
if ( Internal . curve25519 _async instanceof Curve25519Worker ) {
var worker = Internal . curve25519 _async . worker ;
Internal . curve25519 _async = origCurve25519 ;
worker . terminate ( ) ;
}
} ;
@ -35208,6 +35226,116 @@ Curve25519Worker.prototype = {
return ProtoBuf ;
} ) ;
( function ( ) {
'use strict' ;
function validatePrivKey ( privKey ) {
if ( privKey === undefined || ! ( privKey instanceof ArrayBuffer ) || privKey . byteLength != 32 ) {
throw new Error ( "Invalid private key" ) ;
}
}
function validatePubKeyFormat ( pubKey ) {
if ( pubKey === undefined || ( ( pubKey . byteLength != 33 || new Uint8Array ( pubKey ) [ 0 ] != 5 ) && pubKey . byteLength != 32 ) ) {
throw new Error ( "Invalid public key" ) ;
}
if ( pubKey . byteLength == 33 ) {
return pubKey . slice ( 1 ) ;
} else {
console . error ( "WARNING: Expected pubkey of length 33, please report the ST and client that generated the pubkey" ) ;
return pubKey ;
}
}
function processKeys ( raw _keys ) {
// prepend version byte
var origPub = new Uint8Array ( raw _keys . pubKey ) ;
var pub = new Uint8Array ( 33 ) ;
pub . set ( origPub , 1 ) ;
pub [ 0 ] = 5 ;
return { pubKey : pub . buffer , privKey : raw _keys . privKey } ;
}
function wrapCurve25519 ( curve25519 ) {
return {
// Curve 25519 crypto
createKeyPair : function ( privKey ) {
validatePrivKey ( privKey ) ;
var raw _keys = curve25519 . keyPair ( privKey ) ;
if ( raw _keys instanceof Promise ) {
return raw _keys . then ( processKeys ) ;
} else {
return processKeys ( raw _keys ) ;
}
} ,
ECDHE : function ( pubKey , privKey ) {
pubKey = validatePubKeyFormat ( pubKey ) ;
validatePrivKey ( privKey ) ;
if ( pubKey === undefined || pubKey . byteLength != 32 ) {
throw new Error ( "Invalid public key" ) ;
}
return curve25519 . sharedSecret ( pubKey , privKey ) ;
} ,
Ed25519Sign : function ( privKey , message ) {
validatePrivKey ( privKey ) ;
if ( message === undefined ) {
throw new Error ( "Invalid message" ) ;
}
return curve25519 . sign ( privKey , message ) ;
} ,
Ed25519Verify : function ( pubKey , msg , sig ) {
pubKey = validatePubKeyFormat ( pubKey ) ;
if ( pubKey === undefined || pubKey . byteLength != 32 ) {
throw new Error ( "Invalid public key" ) ;
}
if ( msg === undefined ) {
throw new Error ( "Invalid message" ) ;
}
if ( sig === undefined || sig . byteLength != 64 ) {
throw new Error ( "Invalid signature" ) ;
}
return curve25519 . verify ( pubKey , msg , sig ) ;
}
} ;
} ;
Internal . Curve = wrapCurve25519 ( Internal . curve25519 ) ;
Internal . Curve . async = wrapCurve25519 ( Internal . curve25519 _async ) ;
function wrapCurve ( curve ) {
return {
generateKeyPair : function ( ) {
var privKey = Internal . crypto . getRandomBytes ( 32 ) ;
return curve . createKeyPair ( privKey ) ;
} ,
createKeyPair : function ( privKey ) {
return curve . createKeyPair ( privKey ) ;
} ,
calculateAgreement : function ( pubKey , privKey ) {
return curve . ECDHE ( pubKey , privKey ) ;
} ,
verifySignature : function ( pubKey , msg , sig ) {
return curve . Ed25519Verify ( pubKey , msg , sig ) ;
} ,
calculateSignature : function ( privKey , message ) {
return curve . Ed25519Sign ( privKey , message ) ;
}
} ;
}
libsignal . Curve = wrapCurve ( Internal . Curve ) ;
libsignal . Curve . async = wrapCurve ( Internal . Curve . async ) ;
} ) ( ) ;
/ * v i m : t s = 4 : s w = 4
*
* This program is free software : you can redistribute it and / or modify
@ -35234,19 +35362,6 @@ var Internal = Internal || {};
throw new Error ( 'WebCrypto not found' ) ;
}
function validatePubKeyFormat ( pubKey ) {
if ( pubKey === undefined || ( ( pubKey . byteLength != 33 || new Uint8Array ( pubKey ) [ 0 ] != 5 ) && pubKey . byteLength != 32 ) ) {
throw new Error ( "Invalid public key" ) ;
}
if ( pubKey . byteLength == 33 ) {
return pubKey . slice ( 1 ) ;
} else {
console . error ( "WARNING: Expected pubkey of length 33, please report the ST and client that generated the pubkey" ) ;
return pubKey ;
}
}
Internal . crypto = {
getRandomBytes : function ( size ) {
var array = new Uint8Array ( size ) ;
@ -35296,62 +35411,20 @@ var Internal = Internal || {};
if ( privKey === undefined ) {
privKey = Internal . crypto . getRandomBytes ( 32 ) ;
}
if ( privKey . byteLength != 32 ) {
throw new Error ( "Invalid private key" ) ;
}
return Internal . curve25519 . keyPair ( privKey ) . then ( function ( raw _keys ) {
// prepend version byte
var origPub = new Uint8Array ( raw _keys . pubKey ) ;
var pub = new Uint8Array ( 33 ) ;
pub . set ( origPub , 1 ) ;
pub [ 0 ] = 5 ;
return { pubKey : pub . buffer , privKey : raw _keys . privKey } ;
} ) ;
return Internal . Curve . async . createKeyPair ( privKey ) ;
} ,
ECDHE : function ( pubKey , privKey ) {
pubKey = validatePubKeyFormat ( pubKey ) ;
if ( privKey === undefined || privKey . byteLength != 32 ) {
throw new Error ( "Invalid private key" ) ;
}
if ( pubKey === undefined || pubKey . byteLength != 32 ) {
throw new Error ( "Invalid public key" ) ;
}
return Internal . curve25519 . sharedSecret ( pubKey , privKey ) ;
return Internal . Curve . async . ECDHE ( pubKey , privKey ) ;
} ,
Ed25519Sign : function ( privKey , message ) {
if ( privKey === undefined || privKey . byteLength != 32 ) {
throw new Error ( "Invalid private key" ) ;
}
if ( message === undefined ) {
throw new Error ( "Invalid message" ) ;
}
return Internal . curve25519 . sign ( privKey , message ) ;
return Internal . Curve . async . Ed25519Sign ( privKey , message ) ;
} ,
Ed25519Verify : function ( pubKey , msg , sig ) {
pubKey = validatePubKeyFormat ( pubKey ) ;
if ( pubKey === undefined || pubKey . byteLength != 32 ) {
throw new Error ( "Invalid public key" ) ;
}
if ( msg === undefined ) {
throw new Error ( "Invalid message" ) ;
}
if ( sig === undefined || sig . byteLength != 64 ) {
throw new Error ( "Invalid signature" ) ;
}
return Internal . curve25519 . verify ( pubKey , msg , sig ) ;
return Internal . Curve . async . Ed25519Verify ( pubKey , msg , sig ) ;
}
} ;
// HKDF for TextSecure has a bit of additional handling - salts always end up being 32 bytes
Internal . HKDF = function ( input , salt , info ) {
if ( salt . byteLength != 32 ) {
@ -35378,24 +35451,6 @@ var Internal = Internal || {};
} ) ;
} ;
libsignal . Curve = {
generateKeyPair : function ( ) {
return Internal . crypto . createKeyPair ( ) ;
} ,
createKeyPair : function ( privKey ) {
return Internal . crypto . createKeyPair ( privKey ) ;
} ,
calculateAgreement : function ( pubKey , privKey ) {
return Internal . crypto . ECDHE ( pubKey , privKey ) ;
} ,
verifySignature : function ( pubKey , msg , sig ) {
return Internal . crypto . Ed25519Verify ( pubKey , msg , sig ) ;
} ,
calculateSignature : function ( privKey , message ) {
return Internal . crypto . Ed25519Sign ( privKey , message ) ;
} ,
} ;
libsignal . HKDF = {
deriveSecrets : function ( input , salt , info ) {
return Internal . HKDF ( input , salt , info ) ;
@ -35895,8 +35950,8 @@ Internal.SessionRecord = function() {
oldestSession = session ;
}
}
console . log ( "Deleting session closed at" , session. indexInfo . closed ) ;
delete this . sessions [ util . toString ( oldestBaseKey ) ] ;
console . log ( "Deleting session closed at" , olde stS ession. indexInfo . closed ) ;
delete sessions [ util . toString ( oldestBaseKey ) ] ;
}
} ,
} ;
@ -36536,7 +36591,7 @@ SessionCipher.prototype = {
libsignal . SessionCipher = function ( storage , remoteAddress ) {
var cipher = new SessionCipher ( storage , remoteAddress ) ;
// returns a Promise that resolves to a ciphertext array buffer
// returns a Promise that resolves to a ciphertext object
this . encrypt = cipher . encrypt . bind ( cipher ) ;
// returns a Promise that inits a session if necessary and resolves
@ -39244,7 +39299,7 @@ ProvisioningCipher.prototype = {
var ivAndCiphertext = message . slice ( 0 , message . byteLength - 32 ) ;
var ciphertext = message . slice ( 16 + 1 , message . byteLength - 32 ) ;
return libsignal . Curve . calculateAgreement (
return libsignal . Curve . async . calculateAgreement (
masterEphemeral , this . keyPair . privKey
) . then ( function ( ecRes ) {
return libsignal . HKDF . deriveSecrets (
@ -39258,7 +39313,7 @@ ProvisioningCipher.prototype = {
var provisionMessage = textsecure . protobuf . ProvisionMessage . decode ( plaintext ) ;
var privKey = provisionMessage . identityKeyPrivate . toArrayBuffer ( ) ;
return libsignal . Curve . createKeyPair ( privKey ) . then ( function ( keyPair ) {
return libsignal . Curve . async . createKeyPair ( privKey ) . then ( function ( keyPair ) {
return {
identityKeyPair : keyPair ,
number : provisionMessage . number ,
@ -39270,7 +39325,7 @@ ProvisioningCipher.prototype = {
getPublicKey : function ( ) {
return Promise . resolve ( ) . then ( function ( ) {
if ( ! this . keyPair ) {
return libsignal . Curve . generateKeyPair ( ) . then ( function ( keyPair ) {
return libsignal . Curve . async . generateKeyPair ( ) . then ( function ( keyPair ) {
this . keyPair = keyPair ;
} . bind ( this ) ) ;
}