Update libsignal-protocol v0.9.0
* Exposes crypto APIs. * Move worker methods to libsigna.worker. * Move ProvisioningCipher to libtextsecure.
This commit is contained in:
		
					parent
					
						
							
								cd2218ada7
							
						
					
				
			
			
				commit
				
					
						ffa702c934
					
				
			
		
					 7 changed files with 293 additions and 238 deletions
				
			
		| 
						 | 
				
			
			@ -25278,6 +25278,11 @@ Internal.curve25519 = function() {
 | 
			
		|||
    };
 | 
			
		||||
}();
 | 
			
		||||
 | 
			
		||||
;(function() {
 | 
			
		||||
 | 
			
		||||
'use strict';
 | 
			
		||||
window.libsignal = window.libsignal || {};
 | 
			
		||||
 | 
			
		||||
var Internal = Internal || {};
 | 
			
		||||
 | 
			
		||||
// I am the...workee?
 | 
			
		||||
| 
						 | 
				
			
			@ -25287,6 +25292,7 @@ Internal.startWorker = function(url) {
 | 
			
		|||
    Internal.stopWorker(); // there can be only one
 | 
			
		||||
    Internal.curve25519 = new Curve25519Worker(url);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Internal.stopWorker = function() {
 | 
			
		||||
    if (Internal.curve25519 instanceof Curve25519Worker) {
 | 
			
		||||
        var worker = Internal.curve25519.worker;
 | 
			
		||||
| 
						 | 
				
			
			@ -25295,6 +25301,11 @@ Internal.stopWorker = function() {
 | 
			
		|||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
libsignal.worker = {
 | 
			
		||||
  startWorker: Internal.startWorker,
 | 
			
		||||
  stopWorker: Internal.stopWorker,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function Curve25519Worker(url) {
 | 
			
		||||
    this.jobs = {};
 | 
			
		||||
    this.jobId = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -25333,6 +25344,8 @@ Curve25519Worker.prototype = {
 | 
			
		|||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Copyright 2013 Daniel Wirtz <dcode@dcode.io>
 | 
			
		||||
 Copyright 2009 The Closure Library Authors. All Rights Reserved.
 | 
			
		||||
| 
						 | 
				
			
			@ -33916,7 +33929,7 @@ var Internal = Internal || {};
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    var validatePubKeyFormat = function(pubKey) {
 | 
			
		||||
    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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -33925,7 +33938,7 @@ var Internal = Internal || {};
 | 
			
		|||
            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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -34031,7 +34044,66 @@ var Internal = Internal || {};
 | 
			
		|||
            throw new Error("Got salt of incorrect length");
 | 
			
		||||
 | 
			
		||||
        return Internal.crypto.HKDF(input, salt,  util.toArrayBuffer(info));
 | 
			
		||||
    }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Internal.verifyMAC = function(data, key, mac, length) {
 | 
			
		||||
        return Internal.crypto.sign(key, data).then(function(calculated_mac) {
 | 
			
		||||
            if (mac.byteLength != length  || calculated_mac.byteLength < length) {
 | 
			
		||||
                throw new Error("Bad MAC length");
 | 
			
		||||
            }
 | 
			
		||||
            var a = new Uint8Array(calculated_mac);
 | 
			
		||||
            var b = new Uint8Array(mac);
 | 
			
		||||
            var result = 0;
 | 
			
		||||
            for (var i=0; i < mac.byteLength; ++i) {
 | 
			
		||||
                result = result | (a[i] ^ b[i]);
 | 
			
		||||
            }
 | 
			
		||||
            if (result !== 0) {
 | 
			
		||||
                throw new Error("Bad MAC");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    libsignal.crypto = {
 | 
			
		||||
        encrypt: function(key, data, iv) {
 | 
			
		||||
            return Internal.crypto.encrypt(key, data, iv);
 | 
			
		||||
        },
 | 
			
		||||
        decrypt: function(key, data, iv) {
 | 
			
		||||
            return Internal.crypto.decrypt(key, data, iv);
 | 
			
		||||
        },
 | 
			
		||||
        calculateMAC: function(key, data) {
 | 
			
		||||
            return Internal.crypto.sign(key, data);
 | 
			
		||||
        },
 | 
			
		||||
        verifyMAC: function(data, key, mac, length) {
 | 
			
		||||
            return Internal.verifyMAC(data, key, mac, length);
 | 
			
		||||
        },
 | 
			
		||||
        getRandomBytes: function(size) {
 | 
			
		||||
            return Internal.crypto.getRandomBytes(size);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34142,105 +34214,6 @@ var util = (function() {
 | 
			
		|||
    };
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/* vim: ts=4:sw=4
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
;(function() {
 | 
			
		||||
 | 
			
		||||
'use strict';
 | 
			
		||||
window.libsignal = window.libsignal || {};
 | 
			
		||||
 | 
			
		||||
libsignal.protocol = function() {
 | 
			
		||||
    var self = {};
 | 
			
		||||
 | 
			
		||||
    var verifyMAC = function(data, key, mac, length) {
 | 
			
		||||
        return Internal.crypto.sign(key, data).then(function(calculated_mac) {
 | 
			
		||||
            if (mac.byteLength != length  || calculated_mac.byteLength < length) {
 | 
			
		||||
                throw new Error("Bad MAC length");
 | 
			
		||||
            }
 | 
			
		||||
            var a = new Uint8Array(calculated_mac);
 | 
			
		||||
            var b = new Uint8Array(mac);
 | 
			
		||||
            var result = 0;
 | 
			
		||||
            for (var i=0; i < mac.byteLength; ++i) {
 | 
			
		||||
                result = result | (a[i] ^ b[i]);
 | 
			
		||||
            }
 | 
			
		||||
            if (result !== 0) {
 | 
			
		||||
                throw new Error("Bad MAC");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /******************************
 | 
			
		||||
    *** Ratchet implementation ***
 | 
			
		||||
    ******************************/
 | 
			
		||||
    self.createIdentityKeyRecvSocket = function() {
 | 
			
		||||
        var socketInfo = {};
 | 
			
		||||
        var keyPair;
 | 
			
		||||
 | 
			
		||||
        socketInfo.decryptAndHandleDeviceInit = function(deviceInit) {
 | 
			
		||||
            var masterEphemeral = util.toArrayBuffer(deviceInit.publicKey);
 | 
			
		||||
            var message = util.toArrayBuffer(deviceInit.body);
 | 
			
		||||
 | 
			
		||||
            return Internal.crypto.ECDHE(masterEphemeral, keyPair.privKey).then(function(ecRes) {
 | 
			
		||||
                return Internal.HKDF(ecRes, new ArrayBuffer(32), "TextSecure Provisioning Message").then(function(keys) {
 | 
			
		||||
                    if (new Uint8Array(message)[0] != 1)
 | 
			
		||||
                        throw new Error("Bad version number on ProvisioningMessage");
 | 
			
		||||
 | 
			
		||||
                    var iv = message.slice(1, 16 + 1);
 | 
			
		||||
                    var mac = message.slice(message.byteLength - 32, message.byteLength);
 | 
			
		||||
                    var ivAndCiphertext = message.slice(0, message.byteLength - 32);
 | 
			
		||||
                    var ciphertext = message.slice(16 + 1, message.byteLength - 32);
 | 
			
		||||
 | 
			
		||||
                    return verifyMAC(ivAndCiphertext, keys[1], mac, 32).then(function() {
 | 
			
		||||
                        return Internal.crypto.decrypt(keys[0], ciphertext, iv).then(function(plaintext) {
 | 
			
		||||
                            var provisionMessage = Internal.protobuf.ProvisionMessage.decode(plaintext);
 | 
			
		||||
 | 
			
		||||
                            return Internal.crypto.createKeyPair(
 | 
			
		||||
                                provisionMessage.identityKeyPrivate.toArrayBuffer()
 | 
			
		||||
                            ).then(function(identityKeyPair) {
 | 
			
		||||
                                return {
 | 
			
		||||
                                    identityKeyPair  : identityKeyPair,
 | 
			
		||||
                                    number           : provisionMessage.number,
 | 
			
		||||
                                    provisioningCode : provisionMessage.provisioningCode
 | 
			
		||||
                                };
 | 
			
		||||
                            });
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Internal.crypto.createKeyPair().then(function(newKeyPair) {
 | 
			
		||||
            keyPair = newKeyPair;
 | 
			
		||||
            socketInfo.pubKey = keyPair.pubKey;
 | 
			
		||||
            return socketInfo;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    self.startWorker = function(url) {
 | 
			
		||||
        Internal.startWorker(url);
 | 
			
		||||
    };
 | 
			
		||||
    self.stopWorker = function() {
 | 
			
		||||
        Internal.stopWorker();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return self;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
function isNonNegativeInteger(n) {
 | 
			
		||||
    return (typeof n === 'number' && (n % 1) === 0  && n >= 0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -35301,4 +35274,4 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ
 | 
			
		|||
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
})();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue